From b8a8e2280db53b68e405f0e37e45d2c569ad6639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20H=C3=A5land?= Date: Sun, 5 Mar 2017 13:43:01 +0100 Subject: [PATCH 0001/2234] Added deploy script to deploy to the routeros system --- deploy/README.md | 16 +++++++++++ deploy/routeros.sh | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 deploy/routeros.sh diff --git a/deploy/README.md b/deploy/README.md index 4a13e096..65d8cc28 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -72,3 +72,19 @@ export DEPLOY_EXIM4_RELOAD="/etc/init.d/exim4 restart" acme.sh --deploy -d ftp.example.com --deploy-hook exim4 ``` +## 6. Deploy the cert to remote routeros + +```sh +acme.sh --deploy -d ftp.example.com --deploy-hook routeros +``` + +Before you can deploy the certificate to router os, you need to add the id_rsa.pub key to the routeros and assign a user to that key. +The user need to have access to ssh, ftp, read and write. + +Then you need to set the environment variables for the deploy script to work. +```sh +export ROUTER_OS_USERNAME=certuser +export ROUTER_OS_HOST=router.example.com + +acme.sh --deploy -d ftp.example.com --deploy-hook routeros +``` diff --git a/deploy/routeros.sh b/deploy/routeros.sh new file mode 100644 index 00000000..e4e8c464 --- /dev/null +++ b/deploy/routeros.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +#Here is a script to deploy cert to routeros router. + +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +routeros_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if [ -z "$ROUTER_OS_HOST" ]; then + _err "Need to set the env variable ROUTER_OS_HOST" + return 1 + fi + + if [ -z "$ROUTER_OS_USERNAME" ]; then + _err "Need to set the env variable ROUTER_OS_USERNAME" + return 1 + fi + + _info "Trying to push key '$_ckey' to router" + scp $_ckey $ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain".key" + _info "Trying to push cert '$_ccert' to router" + scp $_ccert $ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain".cer" + _info "Trying to push ca cert '$_cca' to router" + scp $_cca $ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain".ca" + + ssh $ROUTER_OS_USERNAME@$ROUTER_OS_HOST bash -c "' + +/certificate remove $_cdomain.cer_0 + +/certificate remove $_cdomain.ca_0 + +delay 1 + +/certificate import file-name=$_cdomain.cer passphrase=\"\" + +/certificate import file-name=$_cdomain.ca passphrase=\"\" + +/certificate import file-name=$_cdomain.key passphrase=\"\" + +delay 1 + +/file remove $_cdomain.cer + +/file remove $_cdomain.key + +delay 2 + +/ip service set www-ssl certificate=$_cdomain.cer_0 + +'" + + + return 0 +} From 8a604bd2a172a15a58420ec401595c6604d8146f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20H=C3=A5land?= Date: Mon, 6 Mar 2017 19:39:55 +0100 Subject: [PATCH 0002/2234] Fixing syntax for schell script checking --- deploy/routeros.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index e4e8c464..9471ba8e 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -31,38 +31,40 @@ routeros_deploy() { fi _info "Trying to push key '$_ckey' to router" - scp $_ckey $ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain".key" + scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" _info "Trying to push cert '$_ccert' to router" - scp $_ccert $ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain".cer" + scp "$_ccert" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" _info "Trying to push ca cert '$_cca' to router" - scp $_cca $ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain".ca" - - ssh $ROUTER_OS_USERNAME@$ROUTER_OS_HOST bash -c "' + scp "$_cca" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.ca" + # shellcheck disable=SC2029 + ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" bash -c "' /certificate remove $_cdomain.cer_0 +/certificate remove $_cdomain.cer_1 + /certificate remove $_cdomain.ca_0 delay 1 /certificate import file-name=$_cdomain.cer passphrase=\"\" -/certificate import file-name=$_cdomain.ca passphrase=\"\" - /certificate import file-name=$_cdomain.key passphrase=\"\" +/certificate import file-name=$_cdomain.ca passphrase=\"\" + delay 1 /file remove $_cdomain.cer /file remove $_cdomain.key +/file remove $_cdomain.ca + delay 2 /ip service set www-ssl certificate=$_cdomain.cer_0 '" - - return 0 } From 861df496707b2837d1972f76ce5c8c1fdf2d19d7 Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 9 Mar 2018 16:29:47 +0100 Subject: [PATCH 0003/2234] Add All-inkl kasserver script. --- README.md | 1 + dnsapi/dns_kas.sh | 153 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100755 dnsapi/dns_kas.sh diff --git a/README.md b/README.md index bfcb477f..ed84f4a7 100644 --- a/README.md +++ b/README.md @@ -328,6 +328,7 @@ You don't have to do anything manually! 1. zonomi.com DNS API 1. DreamHost.com API 1. DirectAdmin API +1. All-inkl/Kasserver API And: diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh new file mode 100755 index 00000000..64a44720 --- /dev/null +++ b/dnsapi/dns_kas.sh @@ -0,0 +1,153 @@ +#!/usr/bin/env sh +######################################################################## +# All-inkl Kasserver hook script for acme.sh +# +# Environment variables: +# +# - $KAS_Login (Kasserver API login name) +# - $KAS_Authtype (Kasserver API auth type. Default: sha1) +# - $KAS_Authdata (Kasserver API auth data.) +# +# Author: Martin Kammerlander, Phlegx Systems OG +# Credits: Inspired by dns_he.sh. Thanks a lot man! +# Git repo: TODO +# TODO: Better Error handling +# TODO: Does not work with Domains that have double endings like i.e. 'co.uk' +# => Get all root zones and compare once the provider offers that. + +KAS_Api="https://kasapi.kasserver.com/dokumentation/formular.php" + +######## Public functions ##################### + +dns_kas_add() { + _full_domain=$1 + _txt_value=$2 + _info "Using DNS-01 All-inkl/Kasserver hook" + _info "Adding or Updating $_full_domain DNS TXT entry on All-inkl/Kasserver" + + _check_and_save + _get_zone "$_full_domain" + _get_record_name "$_full_domain" + _get_record_id + + params="?kas_login=$KAS_Login" + params="$params&kas_auth_type=$KAS_Authtype" + params="$params&kas_auth_data=$KAS_Authdata" + params="$params&var1=record_name" + params="$params&wert1=$_record_name" + params="$params&var2=record_type" + params="$params&wert2=TXT" + params="$params&var3=record_data" + params="$params&wert3=$_txt_value" + params="$params&var4=record_aux" + params="$params&wert4=0" + # If there is no record_id create the record + if [ -z "$_record_id" ]; then + _info "Creating TXT DNS record" + params="$params&kas_action=add_dns_settings" + params="$params&var5=zone_host" + params="$params&wert5=$_zone" + else # Update the existing record + _info "Updating existing TXT DNS record" + params="$params&kas_action=update_dns_settings" + params="$params&var5=record_id" + params="$params&wert5=$_record_id" + fi + + response="$(_get "$KAS_Api$params")" + _debug2 "response" "$response" + + if ! _contains "$response" "TRUE"; then + _err "An unkown error occurred, please check manually." + return 1 + fi + return 0 +} + +dns_kas_rm() { + _full_domain=$1 + _txt_value=$2 + _info "Using DNS-01 All-inkl/Kasserver hook" + _info "Cleaning up after All-inkl/Kasserver hook" + _info "Removing $_full_domain DNS TXT entry on All-inkl/Kasserver" + + _check_and_save + _get_zone "$_full_domain" + _get_record_name "$_full_domain" + _get_record_id + + # If there is a record_id, delete the entry + if [ -n "$_record_id" ]; then + params="?kas_login=$KAS_Login" + params="$params&kas_auth_type=$KAS_Authtype" + params="$params&kas_auth_data=$KAS_Authdata" + params="$params&kas_action=delete_dns_settings" + params="$params&var1=record_id" + params="$params&wert1=$_record_id" + response="$(_get "$KAS_Api$params")" + _debug2 "response" "$response" + if ! _contains "$response" "TRUE"; then + _err "Either the txt record is not found or another error occurred, please check manually." + return 1 + fi + else # Cannot delete or unkown error + _err "No record_id found that can be deleted. Please check manually." + return 1 + fi + + return 0 +} + +########################## PRIVATE FUNCTIONS ########################### + +# Checks for the ENV variables and saves them +_check_and_save() { + KAS_Login="${KAS_Login:-$(_readaccountconf_mutable KAS_Login)}" + KAS_Authtype="${KAS_Authtype:-$(_readaccountconf_mutable KAS_Authtype)}" + KAS_Authdata="${KAS_Authdata:-$(_readaccountconf_mutable KAS_Authdata)}" + + if [ -z "$KAS_Login" ] || [ -z "$KAS_Authtype" ] || [ -z "$KAS_Authdata" ]; then + KAS_Login= + KAS_Authtype= + KAS_Authdata= + _err "No auth details provided. Please set user credentials using the \$KAS_Login, \$KAS_Authtype, and \$KAS_Authdata environment variables." + return 1 + fi + _saveaccountconf_mutable KAS_Login "$KAS_Login" + _saveaccountconf_mutable KAS_Authtype "$KAS_Authtype" + _saveaccountconf_mutable KAS_Authdata "$KAS_Authdata" + return 0 +} + +# Gets back the base domain/zone. +# TODO Get a list of all possible root zones and compare (Currently not possible via provider) +# See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide +_get_zone() { + _zone=$(echo "$1" | rev | cut -d . -f1-2 | rev). +} + +# Removes the domain/subdomain from the entry since kasserver +# cannot handle _full_domain +# TODO Get a list of all possible root zones and compare (Currently not possible via provider) +# See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide +_get_record_name() { + _record_name=$(echo "$1" | rev | cut -d"." -f3- | rev) +} + +# Retrieve the DNS record ID +_get_record_id() { + params="?kas_login=$KAS_Login" + params="$params&kas_auth_type=$KAS_Authtype" + params="$params&kas_auth_data=$KAS_Authdata" + params="$params&kas_action=get_dns_settings" + params="$params&var1=zone_host" + params="$params&wert1=$_zone" + + response="$(_get "$KAS_Api$params")" + _debug2 "response" "$response" + + _record_id="$(echo "$response" | grep -A 4 "$_record_name" | grep "record_id" | cut -f2 -d">" | xargs)" + _debug2 _record_id "$_record_id" + + return 0 +} From 32d7bd5ab1d390d67a2705dfa8c3914e4f43d00a Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 9 Mar 2018 16:33:35 +0100 Subject: [PATCH 0004/2234] Add own github repository URL. --- dnsapi/dns_kas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 64a44720..647a7bb2 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -10,7 +10,7 @@ # # Author: Martin Kammerlander, Phlegx Systems OG # Credits: Inspired by dns_he.sh. Thanks a lot man! -# Git repo: TODO +# Git repo: https://github.com/phlegx/acme.sh # TODO: Better Error handling # TODO: Does not work with Domains that have double endings like i.e. 'co.uk' # => Get all root zones and compare once the provider offers that. From 52351d7dc8f0cccf3139e16ea56e5f1d001e6deb Mon Sep 17 00:00:00 2001 From: martgras Date: Tue, 13 Mar 2018 12:43:07 +0100 Subject: [PATCH 0005/2234] avoid side effects in _printargs A possible fix for https://github.com/Neilpang/acme.sh/issues/1356 --- acme.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/acme.sh b/acme.sh index 2a3138cb..d3dea32a 100755 --- a/acme.sh +++ b/acme.sh @@ -139,6 +139,7 @@ __red() { } _printargs() { + local _exitstatus="$?" if [ -z "$NO_TIMESTAMP" ] || [ "$NO_TIMESTAMP" = "0" ]; then printf -- "%s" "[$(date)] " fi @@ -148,6 +149,8 @@ _printargs() { printf -- "%s" "$1='$2'" fi printf "\n" + # return the saved exit status + return "$_exitstatus" } _dlg_versions() { From 65a7d56957dd9fa9ffd7b341dd1ad4c3368ab2c9 Mon Sep 17 00:00:00 2001 From: martgras Date: Wed, 14 Mar 2018 09:52:58 +0100 Subject: [PATCH 0006/2234] remove local keyword --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d3dea32a..88605b22 100755 --- a/acme.sh +++ b/acme.sh @@ -139,7 +139,7 @@ __red() { } _printargs() { - local _exitstatus="$?" + _exitstatus="$?" if [ -z "$NO_TIMESTAMP" ] || [ "$NO_TIMESTAMP" = "0" ]; then printf -- "%s" "[$(date)] " fi @@ -186,6 +186,7 @@ _dlg_versions() { #class _syslog() { + _exitstatus="$?" if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" = "$SYSLOG_LEVEL_NONE" ]; then return fi @@ -199,6 +200,7 @@ _syslog() { fi fi $__logger_i -t "$PROJECT_NAME" -p "$_logclass" "$(_printargs "$@")" >/dev/null 2>&1 + return "$_exitstatus" } _log() { From cbf0ceacd57fe16f27fa6150ffd2b180d796f3b3 Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 16 Mar 2018 14:51:16 +0100 Subject: [PATCH 0007/2234] Update dnsapi Readme. --- dnsapi/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dnsapi/README.md b/dnsapi/README.md index 8b4a8358..ec6233fc 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -784,6 +784,27 @@ acme.sh --issue --dns dns_da -d example.com -d www.example.com The `DA_Api` and `DA_Api_Insecure` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 42. Use All-inkl Kasserver API + +All-inkl Kasserver API (https://kasapi.kasserver.com/dokumentation) needs you to set your Login credentials like so: + +``` +export KAS_Login="yourusername" +export KAS_Authtype="sha1" +export KAS_Authdata="password" +``` + +Note: Please for now always set the `KAS_Authtype` always simply to `sha1`. + +Then you can issue your certificate: + +``` +acme.sh --issue --dns dns_kas -d example.com -d www.example.com +``` + +The `KAS_Login`, `KAS_Authtype` and `KAS_Authdata` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + +Please report any issues to https://github.com/phlegx/acme.sh. # Use custom API From e431df06ab6457292e9d82e03f4d5ca015d0b85d Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 16 Mar 2018 14:54:08 +0100 Subject: [PATCH 0008/2234] Only create entry. Remove update. --- dnsapi/dns_kas.sh | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 647a7bb2..518b2830 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -30,6 +30,7 @@ dns_kas_add() { _get_record_name "$_full_domain" _get_record_id + _info "Creating TXT DNS record" params="?kas_login=$KAS_Login" params="$params&kas_auth_type=$KAS_Authtype" params="$params&kas_auth_data=$KAS_Authdata" @@ -41,18 +42,9 @@ dns_kas_add() { params="$params&wert3=$_txt_value" params="$params&var4=record_aux" params="$params&wert4=0" - # If there is no record_id create the record - if [ -z "$_record_id" ]; then - _info "Creating TXT DNS record" - params="$params&kas_action=add_dns_settings" - params="$params&var5=zone_host" - params="$params&wert5=$_zone" - else # Update the existing record - _info "Updating existing TXT DNS record" - params="$params&kas_action=update_dns_settings" - params="$params&var5=record_id" - params="$params&wert5=$_record_id" - fi + params="$params&kas_action=add_dns_settings" + params="$params&var5=zone_host" + params="$params&wert5=$_zone" response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" From 11bfb1e5fd679a21477c393f9cfc19004e72d306 Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 16 Mar 2018 15:02:47 +0100 Subject: [PATCH 0009/2234] Fix return values of some functions. --- dnsapi/dns_kas.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 518b2830..dc87bee4 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -116,6 +116,7 @@ _check_and_save() { # See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide _get_zone() { _zone=$(echo "$1" | rev | cut -d . -f1-2 | rev). + return 0 } # Removes the domain/subdomain from the entry since kasserver @@ -124,6 +125,7 @@ _get_zone() { # See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide _get_record_name() { _record_name=$(echo "$1" | rev | cut -d"." -f3- | rev) + return 0 } # Retrieve the DNS record ID From 26b5180bf71f007f55c0264aba76defa0574626c Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 16 Mar 2018 15:49:40 +0100 Subject: [PATCH 0010/2234] Rename full_domain and txt_value variables. --- dnsapi/dns_kas.sh | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index dc87bee4..0eda1d36 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -20,14 +20,14 @@ KAS_Api="https://kasapi.kasserver.com/dokumentation/formular.php" ######## Public functions ##################### dns_kas_add() { - _full_domain=$1 - _txt_value=$2 + _fulldomain=$1 + _txtvalue=$2 _info "Using DNS-01 All-inkl/Kasserver hook" - _info "Adding or Updating $_full_domain DNS TXT entry on All-inkl/Kasserver" + _info "Adding or Updating $_fulldomain DNS TXT entry on All-inkl/Kasserver" _check_and_save - _get_zone "$_full_domain" - _get_record_name "$_full_domain" + _get_zone "$_fulldomain" + _get_record_name "$_fulldomain" _get_record_id _info "Creating TXT DNS record" @@ -39,7 +39,7 @@ dns_kas_add() { params="$params&var2=record_type" params="$params&wert2=TXT" params="$params&var3=record_data" - params="$params&wert3=$_txt_value" + params="$params&wert3=$_txtvalue" params="$params&var4=record_aux" params="$params&wert4=0" params="$params&kas_action=add_dns_settings" @@ -57,15 +57,15 @@ dns_kas_add() { } dns_kas_rm() { - _full_domain=$1 - _txt_value=$2 + _fulldomain=$1 + _txtvalue=$2 _info "Using DNS-01 All-inkl/Kasserver hook" _info "Cleaning up after All-inkl/Kasserver hook" - _info "Removing $_full_domain DNS TXT entry on All-inkl/Kasserver" + _info "Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver" _check_and_save - _get_zone "$_full_domain" - _get_record_name "$_full_domain" + _get_zone "$_fulldomain" + _get_record_name "$_fulldomain" _get_record_id # If there is a record_id, delete the entry @@ -86,7 +86,6 @@ dns_kas_rm() { _err "No record_id found that can be deleted. Please check manually." return 1 fi - return 0 } @@ -120,7 +119,7 @@ _get_zone() { } # Removes the domain/subdomain from the entry since kasserver -# cannot handle _full_domain +# cannot handle _fulldomain # TODO Get a list of all possible root zones and compare (Currently not possible via provider) # See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide _get_record_name() { @@ -141,7 +140,12 @@ _get_record_id() { _debug2 "response" "$response" _record_id="$(echo "$response" | grep -A 4 "$_record_name" | grep "record_id" | cut -f2 -d">" | xargs)" + echo "###########################" + echo "$_record_name" + echo "$_record_id" + echo "###########################" + echo "$response" + echo "###########################" _debug2 _record_id "$_record_id" - return 0 } From cb4a2cf02921d538edc497f0af0d479df04ffb90 Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 16 Mar 2018 16:47:47 +0100 Subject: [PATCH 0011/2234] remove debug output --- dnsapi/dns_kas.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 0eda1d36..c3941d90 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -140,12 +140,6 @@ _get_record_id() { _debug2 "response" "$response" _record_id="$(echo "$response" | grep -A 4 "$_record_name" | grep "record_id" | cut -f2 -d">" | xargs)" - echo "###########################" - echo "$_record_name" - echo "$_record_id" - echo "###########################" - echo "$response" - echo "###########################" _debug2 _record_id "$_record_id" return 0 } From e629985cf494b388fb23cc8dfc8c5a6179a45de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20H=C3=A5land?= Date: Mon, 26 Mar 2018 07:41:56 +0200 Subject: [PATCH 0012/2234] Use _cdomain if ROUTER_OS_HOST is missing --- deploy/routeros.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 9471ba8e..27fc3770 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -21,8 +21,8 @@ routeros_deploy() { _debug _cfullchain "$_cfullchain" if [ -z "$ROUTER_OS_HOST" ]; then - _err "Need to set the env variable ROUTER_OS_HOST" - return 1 + _debug "Using _cdomain as ROUTER_OS_HOST, please set if not correct." + ROUTER_OS_HOST = "$_cdomain" fi if [ -z "$ROUTER_OS_USERNAME" ]; then From 7b327d47c0f2bae9f585030e10e1e847da43bc43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20H=C3=A5land?= Date: Mon, 26 Mar 2018 08:21:31 +0200 Subject: [PATCH 0013/2234] Fix documentation --- deploy/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/README.md b/deploy/README.md index 6ec033f5..fd2a5fcd 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -254,6 +254,7 @@ acme.sh --deploy -d fritzbox.example.com --deploy-hook fritzbox ```sh acme.sh --deploy -d ftp.example.com --deploy-hook strongswan +``` ## 10. Deploy the cert to remote routeros From d698c1093aba8d2c2361e3ad968fe15e25024a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20H=C3=A5land?= Date: Mon, 26 Mar 2018 08:24:04 +0200 Subject: [PATCH 0014/2234] remove spaces around assignment --- deploy/routeros.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 27fc3770..1db74b44 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -22,7 +22,7 @@ routeros_deploy() { if [ -z "$ROUTER_OS_HOST" ]; then _debug "Using _cdomain as ROUTER_OS_HOST, please set if not correct." - ROUTER_OS_HOST = "$_cdomain" + ROUTER_OS_HOST="$_cdomain" fi if [ -z "$ROUTER_OS_USERNAME" ]; then From 8d38cf4d1f7e8e7059cb629b691a99aff88290c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20H=C3=A5land?= Date: Mon, 26 Mar 2018 22:00:01 +0200 Subject: [PATCH 0015/2234] Use allchain instead of ca an cert, add documentation after review --- deploy/README.md | 16 ++++++++++++++++ deploy/routeros.sh | 12 ++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index fd2a5fcd..2693b6e4 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -265,6 +265,8 @@ acme.sh --deploy -d ftp.example.com --deploy-hook routeros Before you can deploy the certificate to router os, you need to add the id_rsa.pub key to the routeros and assign a user to that key. The user need to have access to ssh, ftp, read and write. +There are no need to enable ftp service for the script to work, as they are transmitted over SCP, however ftp is needed to store the files on the router. + Then you need to set the environment variables for the deploy script to work. ```sh export ROUTER_OS_USERNAME=certuser @@ -272,3 +274,17 @@ export ROUTER_OS_HOST=router.example.com acme.sh --deploy -d ftp.example.com --deploy-hook routeros ``` + +The deploy script will remove previously deployed certificates, and it does this with an assumption on how RouterOS names imported certificates, adding a "cer_0" suffix at the end. This is true for versions 6.32 -> 6.41.3, but it is not guaranteed that it will be true for future versions when upgrading. + +If the router have other certificates with the same name as the one beeing deployed, then this script will remove those certificates. + +At the end of the script, the services that use those certificates could be updated. Currently only the www-ssl service is beeing updated, but more services could be added. + +For instance: +``` +/ip service set www-ssl certificate=$_cdomain.cer_0 +/ip service set api-ssl certificate=$_cdomain.cer_0 +``` + +One optional thing to do as well is to create a script that updates all the required services and run that script in a single command. diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 1db74b44..d590bc9a 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -32,10 +32,8 @@ routeros_deploy() { _info "Trying to push key '$_ckey' to router" scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" - _info "Trying to push cert '$_ccert' to router" - scp "$_ccert" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" - _info "Trying to push ca cert '$_cca' to router" - scp "$_cca" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.ca" + _info "Trying to push cert '$_cfullchain' to router" + scp "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" # shellcheck disable=SC2029 ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" bash -c "' @@ -43,24 +41,18 @@ routeros_deploy() { /certificate remove $_cdomain.cer_1 -/certificate remove $_cdomain.ca_0 - delay 1 /certificate import file-name=$_cdomain.cer passphrase=\"\" /certificate import file-name=$_cdomain.key passphrase=\"\" -/certificate import file-name=$_cdomain.ca passphrase=\"\" - delay 1 /file remove $_cdomain.cer /file remove $_cdomain.key -/file remove $_cdomain.ca - delay 2 /ip service set www-ssl certificate=$_cdomain.cer_0 From e36fbd6af5c56b4672077694e7db9adebcb49d25 Mon Sep 17 00:00:00 2001 From: Grant Millar Date: Fri, 20 Apr 2018 09:41:07 +0100 Subject: [PATCH 0016/2234] Fix DNSimple when zone has > 100 records The _get_records function currently returns the first 100 records. As our TXT is added most recently, if you have > 100 records it will not be returned. I've changed the function to sort by ID DESC, so it will always return the latest 100 records. --- dnsapi/dns_dnsimple.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsimple.sh b/dnsapi/dns_dnsimple.sh index 0dd3918a..b2cba584 100644 --- a/dnsapi/dns_dnsimple.sh +++ b/dnsapi/dns_dnsimple.sh @@ -152,7 +152,7 @@ _get_records() { sub_domain=$3 _debug "fetching txt records" - _dnsimple_rest GET "$account_id/zones/$domain/records?per_page=100" + _dnsimple_rest GET "$account_id/zones/$domain/records?per_page=100&sort=id:desc" if ! _contains "$response" "\"id\":"; then _err "failed to retrieve records" From c58465d6304afc7d4e1d052fdf3b70af8ce84a7e Mon Sep 17 00:00:00 2001 From: Vlad Roskov Date: Thu, 3 May 2018 00:57:50 +0300 Subject: [PATCH 0017/2234] fix comparison on empty var --- dnsapi/dns_yandex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index 318dee0c..496fcde4 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -54,7 +54,7 @@ _PDD_get_domain() { _debug2 "res1" "$res1" __found="$(echo "$res1" | sed -n -e 's#.* "found": \([^,]*\),.*#\1#p')" _debug "found: $__found results on page" - if [ "$__found" -lt 20 ]; then + if [ "0$__found" -lt 20 ]; then _debug "last page: $__page" __last=1 fi From f254bb39a541801d136f8e08dc973dbd5d9f3cda Mon Sep 17 00:00:00 2001 From: Vlad Roskov Date: Thu, 3 May 2018 00:58:25 +0300 Subject: [PATCH 0018/2234] bail out on no access --- dnsapi/dns_yandex.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index 496fcde4..fc122f02 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -16,7 +16,7 @@ dns_yandex_add() { _PDD_credentials || return 1 export _H1="PddToken: $PDD_Token" - _PDD_get_domain "$fulldomain" + _PDD_get_domain "$fulldomain" || return 1 _debug "Found suitable domain in pdd: $curDomain" curData="domain=${curDomain}&type=TXT&subdomain=${curSubdomain}&ttl=360&content=${txtvalue}" curUri="https://pddimp.yandex.ru/api2/admin/dns/add" @@ -33,7 +33,7 @@ dns_yandex_rm() { record_id=$(pdd_get_record_id "${fulldomain}") _debug "Result: $record_id" - _PDD_get_domain "$fulldomain" + _PDD_get_domain "$fulldomain" || return 1 _debug "Found suitable domain in pdd: $curDomain" curUri="https://pddimp.yandex.ru/api2/admin/dns/del" From 2f15ad4be091e4cf6ce1ea394f1ee6edb16ada38 Mon Sep 17 00:00:00 2001 From: Vlad Roskov Date: Thu, 3 May 2018 01:00:51 +0300 Subject: [PATCH 0019/2234] fix authentication --- dnsapi/dns_yandex.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index fc122f02..6d928098 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -30,12 +30,13 @@ dns_yandex_rm() { _debug "Calling: dns_yandex_rm() '${fulldomain}'" _PDD_credentials || return 1 export _H1="PddToken: $PDD_Token" - record_id=$(pdd_get_record_id "${fulldomain}") - _debug "Result: $record_id" _PDD_get_domain "$fulldomain" || return 1 _debug "Found suitable domain in pdd: $curDomain" + record_id=$(pdd_get_record_id "${fulldomain}") + _debug "Result: $record_id" + curUri="https://pddimp.yandex.ru/api2/admin/dns/del" curData="domain=${curDomain}&record_id=${record_id}" curResult="$(_post "${curData}" "${curUri}")" From f85348ba949f8a25f5cbdf9ca2252e91e5077c15 Mon Sep 17 00:00:00 2001 From: Vlad Roskov Date: Thu, 3 May 2018 01:01:14 +0300 Subject: [PATCH 0020/2234] fix delete multiple records --- dnsapi/dns_yandex.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index 6d928098..a4f39784 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -37,10 +37,12 @@ dns_yandex_rm() { record_id=$(pdd_get_record_id "${fulldomain}") _debug "Result: $record_id" - curUri="https://pddimp.yandex.ru/api2/admin/dns/del" - curData="domain=${curDomain}&record_id=${record_id}" - curResult="$(_post "${curData}" "${curUri}")" - _debug "Result: $curResult" + for rec_i in $record_id; do + curUri="https://pddimp.yandex.ru/api2/admin/dns/del" + curData="domain=${curDomain}&record_id=${rec_i}" + curResult="$(_post "${curData}" "${curUri}")" + _debug "Result: $curResult" + done } #################### Private functions below ################################## From 6567bb4c12d684f5856a96115777770ae762ccf3 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Thu, 10 May 2018 11:51:59 +0800 Subject: [PATCH 0021/2234] Update haproxy deploy hook Add functionality to add OCSP stapling info (.ocsp file), issuer (.issuer file) and multi-cert bundles (suffix on pem file based on key type). This also corrects the order of key, certificate and intermediate in the PEM file, which although HAProxy does not seem to care, was incorrect in the prior version. --- deploy/haproxy.sh | 256 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 222 insertions(+), 34 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 5c1a40e2..02f6a069 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -1,8 +1,32 @@ #!/usr/bin/env sh -#Here is a script to deploy cert to haproxy server. - -#returns 0 means success, otherwise error. +# Script for acme.sh to deploy certificates to haproxy +# +# The following variables can be exported: +# +# export DEPLOY_HAPROXY_PEM="" +# +# REQUIRED: Defines location of PEM file for HAProxy +# +# export DEPLOY_HAPROXY_RELOAD="systemctl reload haproxy" +# +# OPTIONAL: Reload command used post deploy +# +# export DEPLOY_HAPROXY_ISSUER="no" +# +# OPTIONAL: Places CA file as "${DEPLOY_HAPROXY_PEM}.issuer" +# Note: Required for OCSP stapling to work +# +# export DEPLOY_HAPROXY_BUNDLE="no" +# +# OPTIONAL: Deploy this certificate as part of a multi-cert bundle +# This adds a suffix to the certificate based on the certificate type +# eg RSA certificates will have .rsa as a suffix to the file name +# HAProxy will load all certificates and provide one or the other +# depending on client capabilities +# Note: This functionality requires HAProxy was compiled against +# a version of OpenSSL that supports this. +# ######## Public functions ##################### @@ -14,45 +38,209 @@ haproxy_deploy() { _cca="$4" _cfullchain="$5" - _debug _cdomain "$_cdomain" - _debug _ckey "$_ckey" - _debug _ccert "$_ccert" - _debug _cca "$_cca" - _debug _cfullchain "$_cfullchain" + # Some defaults + DEPLOY_HAPROXY_BUNDLE_DEFAULT="no" + DEPLOY_HAPROXY_ISSUER_DEFAULT="no" + DEPLOY_HAPROXY_RELOAD_DEFAULT="systemctl reload haproxy" - # handle reload preference - DEFAULT_HAPROXY_RELOAD="/usr/sbin/service haproxy restart" - if [ -z "${DEPLOY_HAPROXY_RELOAD}" ]; then - _reload="${DEFAULT_HAPROXY_RELOAD}" - _cleardomainconf DEPLOY_HAPROXY_RELOAD + if [ -f "${DOMAIN_CONF}" ]; then + # shellcheck disable=SC1090 + . "${DOMAIN_CONF}" + fi + + _debug _cdomain "${_cdomain}" + _debug _ckey "${_ckey}" + _debug _ccert "${_ccert}" + _debug _cca "${_cca}" + _debug _cfullchain "${_cfullchain}" + + # CERT is required + if [ -z "${DEPLOY_HAPROXY_PEM}" ]; then + if [ -z "${Le_Deploy_haproxy_pem}" ]; then + _err "{DEPLOY_HAPROXY_PEM} not defined." + return 1 + fi else - _reload="${DEPLOY_HAPROXY_RELOAD}" - _savedomainconf DEPLOY_HAPROXY_RELOAD "$DEPLOY_HAPROXY_RELOAD" + Le_Deploy_haproxy_cert="${DEPLOY_HAPROXY_PEM}" + _savedomainconf Le_Deploy_haproxy_cert "${Le_Deploy_haproxy_pem}" fi - _savedomainconf DEPLOY_HAPROXY_PEM_PATH "$DEPLOY_HAPROXY_PEM_PATH" - # work out the path where the PEM file should go - _pem_path="${DEPLOY_HAPROXY_PEM_PATH}" - if [ -z "$_pem_path" ]; then - _err "Path to save PEM file not found. Please define DEPLOY_HAPROXY_PEM_PATH." - return 1 + # BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" + if [ -n "${DEPLOY_HAPROXY_BUNDLE}" ]; then + Le_Deploy_haproxy_bundle="${DEPLOY_HAPROXY_BUNDLE}" + _savedomainconf Le_Deploy_haproxy_bundle "${Le_Deploy_haproxy_bundle}" + elif [ -z "${Le_Deploy_haproxy_bundle}" ]; then + Le_Deploy_haproxy_bundle="${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" fi - _pem_full_path="$_pem_path/$_cdomain.pem" - _info "Full path to PEM $_pem_full_path" - # combine the key and fullchain into a single pem and install - cat "$_cfullchain" "$_ckey" >"$_pem_full_path" - chmod 600 "$_pem_full_path" - _info "Certificate successfully deployed" + # ISSUER is optional. If not provided then assume "${DEPLOY_HAPROXY_ISSUER_DEFAULT}" + if [ -n "${DEPLOY_HAPROXY_ISSUER}" ]; then + Le_Deploy_haproxy_issuer="${DEPLOY_HAPROXY_ISSUER}" + _savedomainconf Le_Deploy_haproxy_issuer "${Le_Deploy_haproxy_issuer}" + elif [ -z "${Le_Deploy_haproxy_issuer}" ]; then + Le_Deploy_haproxy_issuer="${DEPLOY_HAPROXY_ISSUER_DEFAULT}" + fi - # restart HAProxy - _info "Run reload: $_reload" - if eval "$_reload"; then - _info "Reload success!" - return 0 + # RELOAD is optional. If not provided then assume "${DEPLOY_HAPROXY_RELOAD_DEFAULT}" + if [ -n "${DEPLOY_HAPROXY_RELOAD}" ]; then + Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD}" + _savedomainconf Le_Deploy_haproxy_reload "${Le_Deploy_haproxy_reload}" + elif [ -z "${Le_Deploy_haproxy_reload}" ]; then + Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD_DEFAULT}" + fi + + # Set the suffix depending if we are creating a bundle or not + if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then + _info "Bundle creation requested" + # Initialise $Le_KeyLength if its not already set + if [ -z "${Le_KeyLength}" ]; then + Le_KeyLength="" + fi + if _isEccKey "${Le_KeyLength}"; then + _info "ECC key type so set suffix to .ecc" + _suffix=".ecc" + else + _info "RSA key type so set suffix to .rsa" + _suffix=".rsa" + fi else - _err "Reload error" - return 1 + _suffix="" fi + # Set variables for later + _pem="${Le_Deploy_haproxy_pem}${_suffix}" + _issuer="${_pem}.issuer" + _ocsp="${_pem}.ocsp" + _reload="${Le_Deploy_haproxy_reload}" + + _info "Deploying PEM file" + # Create a temporary PEM file + _temppem="$(_mktemp)" + _debug _temppem "${_temppem}" + cat "${_ckey}" "${_ccert}" "${_cca}" > "${_temppem}" + _ret="$?" + + # Check that we could create the temporary file + if [ "${_ret}" != "0" ]; then + _err "Error code ${_ret} returned during PEM file creation" + [ -f "${_temppem}" ] && rm -f "${_temppem}" + return ${_ret} + fi + + # Move PEM file into place + _info "Moving new certificate into place" + _debug _pem "${_pem}" + cat "${_temppem}" > "${_pem}" + _ret=$? + + # Clean up temp file + [ -f "${_temppem}" ] && rm -f "${_temppem}" + + # Deal with any failure of moving PEM file into place + if [ "${_ret}" != "0" ]; then + _err "Error code ${_ret} returned while moving new certificate into place" + return ${_ret} + fi + + # Update .issuer file if requested + if [ "${Le_Deploy_haproxy_issuer}" = "yes" ]; then + _info "Updating .issuer file" + _debug _issuer "${_issuer}" + cat "${_cca}" > "${_issuer}" + _ret="$?" + + if [ "${_ret}" != "0" ]; then + _err "Error code ${_ret} returned while copying issuer/CA certificate into place" + return ${_ret} + fi + else + [ -f "${_issuer}" ] _err "Issuer file update not requested but .issuer file exists" + fi + + # Update .ocsp file if certificate was requested with --ocsp/--ocsp-must-staple option + if [ -z "${Le_OCSP_Staple}" ]; then + Le_OCSP_Staple="0" + fi + if [ "${Le_OCSP_Staple}" = "1" ]; then + _info "Updating OCSP stapling info" + _debug _ocsp "${_ocsp}" + _info "Extracting OCSP URL" + _ocsp_url=$(openssl x509 -noout -ocsp_uri -in "${_pem}") + _debug _ocsp_url "${_ocsp_url}" + + # Only process OCSP if URL was present + if [ "${_ocsp_url}" != "" ]; then + # Extract the hostname from the OCSP URL + _info "Extracting OCSP URL" + _ocsp_host=$(echo "${_ocsp_url}" | cut -d/ -f3) + _debug _ocsp_host "${_ocsp_host}" + + # Only process the certificate if we have a .issuer file + if [ -r "${_issuer}" ]; then + # Check if issuer cert is also a root CA cert + _subjectdn=$(openssl x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) + _debug _subjectdn "${_subjectdn}" + _issuerdn=$(openssl x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) + _debug _issuerdn "${_issuerdn}" + _info "Requesting OCSP response" + # Request the OCSP response from the issuer and store it + if [ "${_subjectdn}" = "${_issuerdn}" ]; then + # If the issuer is a CA cert then our command line has "-CAfile" added + openssl ocsp \ + -issuer "${_issuer}" \ + -cert "${_pem}" \ + -url "${_ocsp_url}" \ + -header Host "${_ocsp_host}" \ + -respout "${_ocsp}" \ + -verify_other "${_issuer}" \ + -no_nonce \ + -CAfile "${_issuer}" + _ret=$? + else + # Issuer is not a root CA so no "-CAfile" option + openssl ocsp \ + -issuer "${_issuer}" \ + -cert "${_pem}" \ + -url "${_ocsp_url}" \ + -header Host "${_ocsp_host}" \ + -respout "${_ocsp}" \ + -verify_other "${_issuer}" \ + -no_nonce + _ret=$? + fi + else + # Non fatal: No issuer file was present so no OCSP stapling file created + _err "OCSP stapling in use but no .issuer file was present" + fi + else + # Non fatal: No OCSP url was found int the certificate + _err "OCSP update requested but no OCSP URL was found in certificate" + fi + + # Check return code of openssl command + if [ "${_ret}" != "0" ]; then + _err "Updating OCSP stapling failed with return code ${_ret}" + return ${_ret} + fi + else + # An OCSP file was already present but certificate did not have OCSP extension + if [ -f "${_ocsp}" ]; then + _err "OCSP was not requested but .ocsp file exists." + # Should remove the file at this step, although HAProxy just ignores it in this case + # rm -f "${_ocsp}" || _err "Problem removing stale .ocsp file" + fi + fi + + # Reload HAProxy + _debug _reload "${_reload}" + eval "${_reload}" + _ret=$? + if [ "${_ret}" != "0" ]; then + _info "Reload successful" + else + _err "Error code ${_ret} during reload" + return ${_ret} + fi + + return 0 } From 3a95bfb699b602a5ce544f375a2aba5b266a3d94 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Thu, 10 May 2018 12:02:58 +0800 Subject: [PATCH 0022/2234] Document updated haproxy deploy hook --- deploy/README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 181989da..621e15fc 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -258,15 +258,27 @@ acme.sh --deploy -d ftp.example.com --deploy-hook strongswan ## 10. Deploy the cert to HAProxy -You must specify the path where you want the concatenated key and certificate chain written. +You must specify the file where you want the concatenated key and certificate chain written. ```sh -export DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy +export DEPLOY_HAPROXY_PEM=/etc/haproxy/server.pem ``` You may optionally define the command to reload HAProxy. The value shown below will be used as the default if you don't set this environment variable. ```sh -export DEPLOY_HAPROXY_RELOAD="/usr/sbin/service haproxy restart" +export DEPLOY_HAPROXY_RELOAD="systemctl reload haproxy" +``` + +You may optionally specify that the issuer certificate is transferred to "${DEPLOY_HAPROXY_PEM}.issuer". This is a requirement to support OCSP stapling in HAProxy. The value shown below will be used as the default if you don't set this environment variable. + +```sh +export DEPLOY_HAPROXY_ISSUER="no" +``` + +You may optionally specify that you wish to support HAProxy's multi-cert bundle functionality. This allows serving of both RSA and ECC certificates on the same proxy. This adds a ".rsa" or ".ecc" suffix to the files generated (.pem, .ocsp and .issuer). The value shown below will be used as the default if you don't set this environment variable. + +```sh +export DEPLOY_HAPROXY_BUNDLE="no" ``` You can then deploy the certificate as follows From c47e67e52c95f18a0133413763287741c7d02865 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Thu, 10 May 2018 12:06:25 +0800 Subject: [PATCH 0023/2234] Fix variable name --- deploy/haproxy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 02f6a069..06bd74ea 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -61,8 +61,8 @@ haproxy_deploy() { return 1 fi else - Le_Deploy_haproxy_cert="${DEPLOY_HAPROXY_PEM}" - _savedomainconf Le_Deploy_haproxy_cert "${Le_Deploy_haproxy_pem}" + Le_Deploy_haproxy_pem="${DEPLOY_HAPROXY_PEM}" + _savedomainconf Le_Deploy_haproxy_pem "${Le_Deploy_haproxy_pem}" fi # BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" From 707e053949c839073c4b1f46db09a4ebb299aab5 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Thu, 10 May 2018 12:18:03 +0800 Subject: [PATCH 0024/2234] whitespace fixes --- deploy/haproxy.sh | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 06bd74ea..47a935bc 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -117,7 +117,7 @@ haproxy_deploy() { # Create a temporary PEM file _temppem="$(_mktemp)" _debug _temppem "${_temppem}" - cat "${_ckey}" "${_ccert}" "${_cca}" > "${_temppem}" + cat "${_ckey}" "${_ccert}" "${_cca}" >"${_temppem}" _ret="$?" # Check that we could create the temporary file @@ -130,7 +130,7 @@ haproxy_deploy() { # Move PEM file into place _info "Moving new certificate into place" _debug _pem "${_pem}" - cat "${_temppem}" > "${_pem}" + cat "${_temppem}" >"${_pem}" _ret=$? # Clean up temp file @@ -146,7 +146,7 @@ haproxy_deploy() { if [ "${Le_Deploy_haproxy_issuer}" = "yes" ]; then _info "Updating .issuer file" _debug _issuer "${_issuer}" - cat "${_cca}" > "${_issuer}" + cat "${_cca}" >"${_issuer}" _ret="$?" if [ "${_ret}" != "0" ]; then @@ -187,25 +187,25 @@ haproxy_deploy() { if [ "${_subjectdn}" = "${_issuerdn}" ]; then # If the issuer is a CA cert then our command line has "-CAfile" added openssl ocsp \ - -issuer "${_issuer}" \ - -cert "${_pem}" \ - -url "${_ocsp_url}" \ - -header Host "${_ocsp_host}" \ - -respout "${_ocsp}" \ - -verify_other "${_issuer}" \ - -no_nonce \ - -CAfile "${_issuer}" + -issuer "${_issuer}" \ + -cert "${_pem}" \ + -url "${_ocsp_url}" \ + -header Host "${_ocsp_host}" \ + -respout "${_ocsp}" \ + -verify_other "${_issuer}" \ + -no_nonce \ + -CAfile "${_issuer}" _ret=$? else # Issuer is not a root CA so no "-CAfile" option openssl ocsp \ - -issuer "${_issuer}" \ - -cert "${_pem}" \ - -url "${_ocsp_url}" \ - -header Host "${_ocsp_host}" \ - -respout "${_ocsp}" \ - -verify_other "${_issuer}" \ - -no_nonce + -issuer "${_issuer}" \ + -cert "${_pem}" \ + -url "${_ocsp_url}" \ + -header Host "${_ocsp_host}" \ + -respout "${_ocsp}" \ + -verify_other "${_issuer}" \ + -no_nonce _ret=$? fi else @@ -219,8 +219,8 @@ haproxy_deploy() { # Check return code of openssl command if [ "${_ret}" != "0" ]; then - _err "Updating OCSP stapling failed with return code ${_ret}" - return ${_ret} + _err "Updating OCSP stapling failed with return code ${_ret}" + return ${_ret} fi else # An OCSP file was already present but certificate did not have OCSP extension @@ -228,7 +228,7 @@ haproxy_deploy() { _err "OCSP was not requested but .ocsp file exists." # Should remove the file at this step, although HAProxy just ignores it in this case # rm -f "${_ocsp}" || _err "Problem removing stale .ocsp file" - fi + fi fi # Reload HAProxy From ba20af48d32720fa011be9b27c6b5597cb32ff54 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Thu, 10 May 2018 15:25:28 +0800 Subject: [PATCH 0025/2234] Support HAPROXY_DEPLOY_PEM_PATH Adds compatibility to original haproxy deploy hook while still allowing custom PEM file name (via HAPROXY_DEPLOY_PEM_NAME) --- deploy/haproxy.sh | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 47a935bc..cadc8a60 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -4,9 +4,15 @@ # # The following variables can be exported: # -# export DEPLOY_HAPROXY_PEM="" +# export DEPLOY_HAPROXY_PEM_NAME="${domain}.pem" # -# REQUIRED: Defines location of PEM file for HAProxy +# Defines the name of the PEM file. +# Defaults to "domain.pem" +# +# export DEPLOY_HAPROXY_PEM_PATH="/etc/haproxy" +# +# Defines location of PEM file for HAProxy. +# Defaults to /etc/haproxy # # export DEPLOY_HAPROXY_RELOAD="systemctl reload haproxy" # @@ -39,6 +45,8 @@ haproxy_deploy() { _cfullchain="$5" # Some defaults + DEPLOY_HAPROXY_PEM_PATH_DEFAULT="/etc/haproxy" + DEPLOY_HAPROXY_PEM_NAME_DEFAULT="${_cdomain}.pem" DEPLOY_HAPROXY_BUNDLE_DEFAULT="no" DEPLOY_HAPROXY_ISSUER_DEFAULT="no" DEPLOY_HAPROXY_RELOAD_DEFAULT="systemctl reload haproxy" @@ -54,15 +62,28 @@ haproxy_deploy() { _debug _cca "${_cca}" _debug _cfullchain "${_cfullchain}" - # CERT is required - if [ -z "${DEPLOY_HAPROXY_PEM}" ]; then - if [ -z "${Le_Deploy_haproxy_pem}" ]; then - _err "{DEPLOY_HAPROXY_PEM} not defined." - return 1 - fi + # PEM_PATH is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_PATH_DEFAULT}" + if [ -n "${DEPLOY_HAPROXY_PEM_PATH}" ]; then + Le_Deploy_haproxy_pem_path="${DEPLOY_HAPROXY_PEM_PATH}" + _savedomainconf Le_Deploy_haproxy_pem_path "${Le_Deploy_haproxy_pem_path}" + elif [ -z "${Le_Deploy_haproxy_pem_path}" ]; then + Le_Deploy_haproxy_pem_path="${DEPLOY_HAPROXY_PEM_PATH_DEFAULT}" + fi + + # Ensure PEM_PATH exists + if [ -d "${Le_Deploy_haproxy_pem_path}" ]; then + _debug "PEM_PATH ${Le_Deploy_haproxy_pem_path} exists" else - Le_Deploy_haproxy_pem="${DEPLOY_HAPROXY_PEM}" - _savedomainconf Le_Deploy_haproxy_pem "${Le_Deploy_haproxy_pem}" + _err "PEM_PATH ${Le_Deploy_haproxy_pem_path} does not exist" + return 1 + fi + + # PEM_NAME is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}" + if [ -n "${DEPLOY_HAPROXY_PEM_NAME}" ]; then + Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME}" + _savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}" + elif [ -z "${Le_Deploy_haproxy_pem_name}" ]; then + Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}" fi # BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" @@ -108,7 +129,7 @@ haproxy_deploy() { fi # Set variables for later - _pem="${Le_Deploy_haproxy_pem}${_suffix}" + _pem="${Le_Deploy_haproxy_pem_path}/${Le_Deploy_haproxy_pem_name}${_suffix}" _issuer="${_pem}.issuer" _ocsp="${_pem}.ocsp" _reload="${Le_Deploy_haproxy_reload}" From 675e2d25d6f7c75745d866c6b08f9414977134a4 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Thu, 10 May 2018 15:28:54 +0800 Subject: [PATCH 0026/2234] update for new haproxy deploy vars --- deploy/README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 621e15fc..7b058c4d 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -258,9 +258,16 @@ acme.sh --deploy -d ftp.example.com --deploy-hook strongswan ## 10. Deploy the cert to HAProxy -You must specify the file where you want the concatenated key and certificate chain written. +You may specify the directory where you want the concatenated key and certificate chain written. The value shown below will be used as the default if you don't set this environment variable. + ```sh -export DEPLOY_HAPROXY_PEM=/etc/haproxy/server.pem +export DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy +``` + +You may optionally specify the file name where you want the concatenated key and certificate chain written. The value shown below will be used as the default if you don't set this environment variable. + +```sh +export DEPLOY_HAPROXY_PEM_PATH=$domain ``` You may optionally define the command to reload HAProxy. The value shown below will be used as the default if you don't set this environment variable. From 08d29a8342309e4c4a7c9a63c88af9d2dea26735 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Mon, 14 May 2018 10:58:46 +0800 Subject: [PATCH 0027/2234] Fix return from reload --- deploy/haproxy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index cadc8a60..cf5dc329 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -257,10 +257,10 @@ haproxy_deploy() { eval "${_reload}" _ret=$? if [ "${_ret}" != "0" ]; then - _info "Reload successful" - else _err "Error code ${_ret} during reload" return ${_ret} + else + _info "Reload successful" fi return 0 From 733b4e0a342d2bb2096b9e88e8ca7b93ba2449d5 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Mon, 14 May 2018 11:26:03 +0800 Subject: [PATCH 0028/2234] Fix Le_Keylength case --- deploy/haproxy.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index cf5dc329..75e76ef0 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -113,11 +113,11 @@ haproxy_deploy() { # Set the suffix depending if we are creating a bundle or not if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then _info "Bundle creation requested" - # Initialise $Le_KeyLength if its not already set - if [ -z "${Le_KeyLength}" ]; then - Le_KeyLength="" + # Initialise $Le_Keylength if its not already set + if [ -z "${Le_Keylength}" ]; then + Le_Keylength="" fi - if _isEccKey "${Le_KeyLength}"; then + if _isEccKey "${Le_Keylength}"; then _info "ECC key type so set suffix to .ecc" _suffix=".ecc" else From 7d19d784dfd34691cca574c26ef004e6df303e9a Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Mon, 14 May 2018 13:16:56 +0800 Subject: [PATCH 0029/2234] Update cert suffix for bundles .ocsp generation --- deploy/haproxy.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 75e76ef0..0f5874d6 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -118,15 +118,16 @@ haproxy_deploy() { Le_Keylength="" fi if _isEccKey "${Le_Keylength}"; then - _info "ECC key type so set suffix to .ecc" - _suffix=".ecc" + _info "ECC key type detected" + _suffix=".ecdsa" else - _info "RSA key type so set suffix to .rsa" + _info "RSA key type detected" _suffix=".rsa" fi else _suffix="" fi + _debug _suffix "${_suffix}" # Set variables for later _pem="${Le_Deploy_haproxy_pem_path}/${Le_Deploy_haproxy_pem_name}${_suffix}" @@ -215,7 +216,8 @@ haproxy_deploy() { -respout "${_ocsp}" \ -verify_other "${_issuer}" \ -no_nonce \ - -CAfile "${_issuer}" + -CAfile "${_issuer}" | \ + grep -q "${_pem}: good" _ret=$? else # Issuer is not a root CA so no "-CAfile" option @@ -226,7 +228,8 @@ haproxy_deploy() { -header Host "${_ocsp_host}" \ -respout "${_ocsp}" \ -verify_other "${_issuer}" \ - -no_nonce + -no_nonce | \ + grep -q "${_pem}: good" _ret=$? fi else @@ -238,10 +241,9 @@ haproxy_deploy() { _err "OCSP update requested but no OCSP URL was found in certificate" fi - # Check return code of openssl command + # Non fatal: Check return code of openssl command if [ "${_ret}" != "0" ]; then _err "Updating OCSP stapling failed with return code ${_ret}" - return ${_ret} fi else # An OCSP file was already present but certificate did not have OCSP extension From 8d348954a7f9af9418727159f5c4376133c06a60 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Mon, 14 May 2018 13:22:46 +0800 Subject: [PATCH 0030/2234] Whitepspace --- deploy/haproxy.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 0f5874d6..f6e3716f 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -216,8 +216,8 @@ haproxy_deploy() { -respout "${_ocsp}" \ -verify_other "${_issuer}" \ -no_nonce \ - -CAfile "${_issuer}" | \ - grep -q "${_pem}: good" + -CAfile "${_issuer}" \ + | grep -q "${_pem}: good" _ret=$? else # Issuer is not a root CA so no "-CAfile" option @@ -228,8 +228,8 @@ haproxy_deploy() { -header Host "${_ocsp_host}" \ -respout "${_ocsp}" \ -verify_other "${_issuer}" \ - -no_nonce | \ - grep -q "${_pem}: good" + -no_nonce \ + | grep -q "${_pem}: good" _ret=$? fi else From 86276ad17b50227b9b9d7f2d72abd7cdf22f19a8 Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Wed, 1 Aug 2018 16:37:08 +0200 Subject: [PATCH 0031/2234] added hosting.de DNS Plugin * can be used with API of hosting.de * can also be used with ICANN registrar http.net * needs just API key and endpoint * support wildcard certificates --- dnsapi/dns_hostingde.sh | 110 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 dnsapi/dns_hostingde.sh diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh new file mode 100644 index 00000000..a6abc428 --- /dev/null +++ b/dnsapi/dns_hostingde.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env sh + +# hosting.de API + +# Values to export: +# export HOSTINGDE_ENDPOINT='https://secure.hosting.de' +# export HOSTINGDE_APIKEY='xxxxx' + + +######## Public functions ##################### + +dns_hostingde_add() { + fulldomain="${1}" + txtvalue="${2}" + _debug "Calling: _hostingde_addRecord() '${fulldomain}' '${txtvalue}'" + _hostingde_apiKey && _hostingde_getZoneConfig && _hostingde_addRecord +} + +dns_hostingde_rm() { + fulldomain="${1}" + txtvalue="${2}" + _debug "Calling: _hostingde_removeRecord() '${fulldomain}' '${txtvalue}'" + _hostingde_apiKey && _hostingde_getZoneConfig && _hostingde_removeRecord +} + +#################### own Private functions below ################################## + +_hostingde_apiKey() { + HOSTINGDE_APIKEY="${HOSTINGDE_APIKEY:-$(_readaccountconf_mutable HOSTINGDE_APIKEY)}" + if [ -z "$HOSTINGDE_APIKEY" ] || [ -z "$HOSTINGDE_ENDPOINT" ]; then + HOSTINGDE_APIKEY="" + HOSTINGDE_ENDPOINT="" + _err "You haven't specified hosting.de API key or endpoint yet." + _err "Please create your key and try again." + return 1 + fi + + _saveaccountconf_mutable HOSTINGDE_APIKEY "$HOSTINGDE_APIKEY" + _saveaccountconf_mutable HOSTINGDE_ENDPOINT "$HOSTINGDE_ENDPOINT" +} + +_hostingde_getZoneConfig() { + _info "Getting ZoneConfig" + curZone="${fulldomain#*.}" + returnCode=1 + while _contains "${curZone}" "\\."; do + curData="{\"filter\":{\"field\":\"zoneName\",\"value\":\"${curZone}\"},\"limit\":1,\"authToken\":\"${HOSTINGDE_APIKEY}\"}" + curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneConfigsFind")" + _debug "Calling zoneConfigsFind: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneConfigsFind'" + _debug "Result of zoneConfigsFind: '$curResult'" + if _contains "${curResult}" '"status": "error"'; then + if _contains "${curResult}" '"code": 10109'; then + _err "The API-Key is invalid or could not be found" + else + _err "UNKNOWN API ERROR" + fi + returnCode=1 + break; + fi + if _contains "${curResult}" '"totalEntries": 1'; then + _info "Retrieved zone data." + _debug "Zone data: '${curResult}'" + + # read ZoneConfigId for later update + zoneConfigId=$(echo "${curResult}" | _egrep_o '"id":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + _debug "zoneConfigId '${zoneConfigId}'" + returnCode=0 + break + fi + curZone="${curZone#*.}" + done + if [ $returnCode -ne 0 ]; then + _info "ZoneEnd reached, Zone ${curZone} not found in hosting.de API" + fi + return $returnCode +} + +_hostingde_addRecord() { + _info "Adding record to zone" + curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\"},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}" + curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" + _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" + _debug "Result of zoneUpdate: '$curResult'" + if _contains "${curResult}" '"status": "error"'; then + if _contains "${curResult}" '"code": 10109'; then + _err "The API-Key is invalid or could not be found" + else + _err "UNKNOWN API ERROR" + fi + return 1 + fi + return 0 +} + +_hostingde_removeRecord() { + _info "Removing record from zone" + curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\"},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}" + curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" + _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" + _debug "Result of zoneUpdate: '$curResult'" + if _contains "${curResult}" '"status": "error"'; then + if _contains "${curResult}" '"code": 10109'; then + _err "The API-Key is invalid or could not be found" + else + _err "UNKNOWN API ERROR" + fi + return 1 + fi + return 0 +} From 5494e88e08f22400ed7fabc3c9f445eca85334e5 Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Wed, 1 Aug 2018 17:00:22 +0200 Subject: [PATCH 0032/2234] making shfmt happy --- dnsapi/dns_hostingde.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index a6abc428..39bcfb63 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -6,7 +6,6 @@ # export HOSTINGDE_ENDPOINT='https://secure.hosting.de' # export HOSTINGDE_APIKEY='xxxxx' - ######## Public functions ##################### dns_hostingde_add() { @@ -55,7 +54,7 @@ _hostingde_getZoneConfig() { _err "UNKNOWN API ERROR" fi returnCode=1 - break; + break fi if _contains "${curResult}" '"totalEntries": 1'; then _info "Retrieved zone data." @@ -70,7 +69,7 @@ _hostingde_getZoneConfig() { curZone="${curZone#*.}" done if [ $returnCode -ne 0 ]; then - _info "ZoneEnd reached, Zone ${curZone} not found in hosting.de API" + _info "ZoneEnd reached, Zone ${curZone} not found in hosting.de API" fi return $returnCode } From 4162975f9f2db76fbc5fcfbdaa3bea5f0df6e9cc Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Thu, 2 Aug 2018 15:43:40 +0200 Subject: [PATCH 0033/2234] added hosting.de API to README's --- README.md | 1 + dnsapi/README.md | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/README.md b/README.md index c8bebc6f..614476a0 100644 --- a/README.md +++ b/README.md @@ -321,6 +321,7 @@ You don't have to do anything manually! 1. acme-dns (https://github.com/joohoi/acme-dns) 1. TELE3 (https://www.tele3.cz) 1. EUSERV.EU (https://www.euserv.eu) +1. hosting.de (https://www.hosting.de) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index 1f394f92..bce0ffef 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -897,6 +897,29 @@ acme.sh --issue --dns dns_euserv -d example.com -d *.example.com --insecure The `EUSERV_Username` and `EUSERV_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. Please report any issues to https://github.com/initit/acme.sh or to +## 48. Use hosting.de API + +Create an API key in your hosting.de account here: https://secure.hosting.de + +The key needs the following rights: +- DNS_ZONES_EDIT +- DNS_ZONES_LIST + +Set your API Key and endpoint: + +``` +export HOSTINGDE_APIKEY="xxx" +export HOSTINGDE_ENDPOINT="https://secure.hosting.de" +``` + +The plugin can also be used for the http.net API. http.net customers have to set endpoint to https://partner.http.net. + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_hostingde -d example.com -d *.example.com +``` + +The hosting.de API key and endpoint will be saved in `~/.acme.sh/account.conf` and will be reused when needed. # Use custom API If your API is not supported yet, you can write your own DNS API. From ed95509a4f938737957c641a9c5257bda55a1540 Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Thu, 2 Aug 2018 15:47:02 +0200 Subject: [PATCH 0034/2234] hosting.de API keys can contain special chars, so using simple quotes --- dnsapi/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index bce0ffef..01192b13 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -908,8 +908,8 @@ The key needs the following rights: Set your API Key and endpoint: ``` -export HOSTINGDE_APIKEY="xxx" -export HOSTINGDE_ENDPOINT="https://secure.hosting.de" +export HOSTINGDE_APIKEY='xxx' +export HOSTINGDE_ENDPOINT='https://secure.hosting.de' ``` The plugin can also be used for the http.net API. http.net customers have to set endpoint to https://partner.http.net. From 68f66ca101ba04bf3abc3fb97f1f0162d6a2506c Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Thu, 2 Aug 2018 16:20:48 +0200 Subject: [PATCH 0035/2234] Add default delay for the calls to KAS api since they are very restrictive with that. --- dnsapi/dns_kas.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index c3941d90..3b608d43 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -45,7 +45,8 @@ dns_kas_add() { params="$params&kas_action=add_dns_settings" params="$params&var5=zone_host" params="$params&wert5=$_zone" - + _debug2 "Wait for 10 seconds by default before calling KAS API." + sleep 10 response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" @@ -76,6 +77,8 @@ dns_kas_rm() { params="$params&kas_action=delete_dns_settings" params="$params&var1=record_id" params="$params&wert1=$_record_id" + _debug2 "Wait for 10 seconds by default before calling KAS API." + sleep 10 response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" if ! _contains "$response" "TRUE"; then @@ -136,6 +139,8 @@ _get_record_id() { params="$params&var1=zone_host" params="$params&wert1=$_zone" + _debug2 "Wait for 10 seconds by default before calling KAS API." + sleep 10 response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" From 5b7cac100220f4d6354d400d655c2e87d9023999 Mon Sep 17 00:00:00 2001 From: Tom Blauwendraat Date: Wed, 12 Sep 2018 05:34:56 +0200 Subject: [PATCH 0036/2234] [FIX] Delete all occurrences of TXT key, dont fail if there is more than one, [FIX] Respect pagination on domain listing, before only the first page was loaded --- dnsapi/dns_dgon.sh | 159 ++++++++++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 67 deletions(-) diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh index 5d38ef76..e92c7809 100755 --- a/dnsapi/dns_dgon.sh +++ b/dnsapi/dns_dgon.sh @@ -104,48 +104,60 @@ dns_dgon_rm() { ## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}} GURL="https://api.digitalocean.com/v2/domains/$_domain/records" - ## while we dont have a record ID we keep going - while [ -z "$record" ]; do + ## Get all the matching records + while [ true ]; do ## 1) get the URL ## the create request - get ## args: URL, [onlyheader, timeout] domain_list="$(_get "$GURL")" - ## 2) find record - ## check for what we are looing for: "type":"A","name":"$_sub_domain" - record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")" - ## 3) check record and get next page - if [ -z "$record" ]; then - ## find the next page if we dont have a match - nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")" - if [ -z "$nextpage" ]; then - _err "no record and no nextpage in digital ocean DNS removal" - return 1 - fi - _debug2 nextpage "$nextpage" - GURL="$nextpage" + + ## check response + if [ "$?" != "0" ]; then + _err "error in domain_list response: $domain_list" + return 1 fi - ## we break out of the loop when we have a record + _debug2 domain_list "$domain_list" + + ## 2) find records + ## check for what we are looking for: "type":"A","name":"$_sub_domain" + record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")" + + if [ ! -z "$record" ]; then + + ## we found records + rec_ids="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")" + _debug rec_ids "$rec_ids" + if [ ! -z "$rec_ids" ]; then + echo "$rec_ids" | while IFS= read -r rec_id ; do + ## delete the record + ## delete URL for removing the one we dont want + DURL="https://api.digitalocean.com/v2/domains/$_domain/records/$rec_id" + + ## the create request - delete + ## args: BODY, URL, [need64, httpmethod] + response="$(_post "" "$DURL" "" "DELETE")" + + ## check response (sort of) + if [ "$?" != "0" ]; then + _err "error in remove response: $response" + return 1 + fi + _debug2 response "$response" + + done + fi + fi + + ## 3) find the next page + nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")" + if [ -z "$nextpage" ]; then + break + fi + _debug2 nextpage "$nextpage" + GURL="$nextpage" + done - ## we found the record - rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")" - _debug rec_id "$rec_id" - - ## delete the record - ## delete URL for removing the one we dont want - DURL="https://api.digitalocean.com/v2/domains/$_domain/records/$rec_id" - - ## the create request - delete - ## args: BODY, URL, [need64, httpmethod] - response="$(_post "" "$DURL" "" "DELETE")" - - ## check response (sort of) - if [ "$?" != "0" ]; then - _err "error in remove response: $response" - return 1 - fi - _debug2 response "$response" - ## finished correctly return 0 } @@ -178,44 +190,57 @@ _get_base_domain() { export _H2="Authorization: Bearer $DO_API_KEY" _debug DO_API_KEY "$DO_API_KEY" ## get URL for the list of domains - ## havent seen this request paginated, tested with 18 domains (more requires manual requests with DO) + ## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}} DOMURL="https://api.digitalocean.com/v2/domains" - ## get the domain list (DO gives basically a full XFER!) - domain_list="$(_get "$DOMURL")" + ## while we dont have a matching domain we keep going + while [ -z "$found" ]; do + ## get the domain list (current page) + domain_list="$(_get "$DOMURL")" - ## check response - if [ "$?" != "0" ]; then - _err "error in domain_list response: $domain_list" - return 1 - fi - _debug2 domain_list "$domain_list" - - ## for each shortening of our $fulldomain, check if it exists in the $domain_list - ## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge" - i=2 - while [ $i -gt 0 ]; do - ## get next longest domain - _domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM") - ## check we got something back from our cut (or are we at the end) - if [ -z "$_domain" ]; then - ## we got to the end of the domain - invalid domain - _err "domain not found in DigitalOcean account" + ## check response + if [ "$?" != "0" ]; then + _err "error in domain_list response: $domain_list" return 1 fi - ## we got part of a domain back - grep it out - found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")" - ## check if it exists - if [ ! -z "$found" ]; then - ## exists - exit loop returning the parts - sub_point=$(_math $i - 1) - _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point") - _debug _domain "$_domain" - _debug _sub_domain "$_sub_domain" - return 0 + _debug2 domain_list "$domain_list" + + ## for each shortening of our $fulldomain, check if it exists in the $domain_list + ## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge" + i=2 + while [ $i -gt 0 ]; do + ## get next longest domain + _domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM") + ## check we got something back from our cut (or are we at the end) + if [ -z "$_domain" ]; then + break + fi + ## we got part of a domain back - grep it out + found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")" + ## check if it exists + if [ ! -z "$found" ]; then + ## exists - exit loop returning the parts + sub_point=$(_math $i - 1) + _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point") + _debug _domain "$_domain" + _debug _sub_domain "$_sub_domain" + return 0 + fi + ## increment cut point $i + i=$(_math $i + 1) + done + + if [ -z "$found" ]; then + ## find the next page if we dont have a match + nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")" + if [ -z "$nextpage" ]; then + _err "no record and no nextpage in digital ocean DNS removal" + return 1 + fi + _debug2 nextpage "$nextpage" + DOMURL="$nextpage" fi - ## increment cut point $i - i=$(_math $i + 1) + done ## we went through the entire domain zone list and dint find one that matched From 4a18c45e4f34bcc05ecc3891af9ac72f5df2b68f Mon Sep 17 00:00:00 2001 From: Tom Blauwendraat Date: Wed, 12 Sep 2018 05:46:51 +0200 Subject: [PATCH 0037/2234] fixup! [FIX] Delete all occurrences of TXT key, dont fail if there is more than one, [FIX] Respect pagination on domain listing, before only the first page was loaded --- dnsapi/dns_dgon.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh index e92c7809..24e1a9f2 100755 --- a/dnsapi/dns_dgon.sh +++ b/dnsapi/dns_dgon.sh @@ -105,7 +105,7 @@ dns_dgon_rm() { GURL="https://api.digitalocean.com/v2/domains/$_domain/records" ## Get all the matching records - while [ true ]; do + while true; do ## 1) get the URL ## the create request - get ## args: URL, [onlyheader, timeout] @@ -128,7 +128,7 @@ dns_dgon_rm() { rec_ids="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")" _debug rec_ids "$rec_ids" if [ ! -z "$rec_ids" ]; then - echo "$rec_ids" | while IFS= read -r rec_id ; do + echo "$rec_ids" | while IFS= read -r rec_id; do ## delete the record ## delete URL for removing the one we dont want DURL="https://api.digitalocean.com/v2/domains/$_domain/records/$rec_id" From 31d9ba7e02777cfd1492f2cfeea2db1bd78b9867 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Fri, 28 Sep 2018 08:45:18 +0800 Subject: [PATCH 0038/2234] Change default for reload --- deploy/haproxy.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index f6e3716f..0318c23c 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -17,6 +17,9 @@ # export DEPLOY_HAPROXY_RELOAD="systemctl reload haproxy" # # OPTIONAL: Reload command used post deploy +# This defaults to be a no-op (ie "true"). +# It is strongly recommended to set this something that makes sense +# for your distro. # # export DEPLOY_HAPROXY_ISSUER="no" # @@ -249,7 +252,7 @@ haproxy_deploy() { # An OCSP file was already present but certificate did not have OCSP extension if [ -f "${_ocsp}" ]; then _err "OCSP was not requested but .ocsp file exists." - # Should remove the file at this step, although HAProxy just ignores it in this case + # Could remove the file at this step, although HAProxy just ignores it in this case # rm -f "${_ocsp}" || _err "Problem removing stale .ocsp file" fi fi From 0a4e61c1dd421f1e36eb9945891c1e1a0ac2d848 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Fri, 28 Sep 2018 08:46:39 +0800 Subject: [PATCH 0039/2234] Readme update --- deploy/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 7b058c4d..8cefeffa 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -267,13 +267,13 @@ export DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy You may optionally specify the file name where you want the concatenated key and certificate chain written. The value shown below will be used as the default if you don't set this environment variable. ```sh -export DEPLOY_HAPROXY_PEM_PATH=$domain +export DEPLOY_HAPROXY_PEM_NAME=$domain ``` You may optionally define the command to reload HAProxy. The value shown below will be used as the default if you don't set this environment variable. ```sh -export DEPLOY_HAPROXY_RELOAD="systemctl reload haproxy" +export DEPLOY_HAPROXY_RELOAD="true" ``` You may optionally specify that the issuer certificate is transferred to "${DEPLOY_HAPROXY_PEM}.issuer". This is a requirement to support OCSP stapling in HAProxy. The value shown below will be used as the default if you don't set this environment variable. From 454c90820d56db2d62d0315d4232eefecbc2cc8a Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Fri, 28 Sep 2018 08:57:13 +0800 Subject: [PATCH 0040/2234] Actually set reload default --- deploy/haproxy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 0318c23c..2479aebd 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -7,7 +7,7 @@ # export DEPLOY_HAPROXY_PEM_NAME="${domain}.pem" # # Defines the name of the PEM file. -# Defaults to "domain.pem" +# Defaults to ".pem" # # export DEPLOY_HAPROXY_PEM_PATH="/etc/haproxy" # @@ -52,7 +52,7 @@ haproxy_deploy() { DEPLOY_HAPROXY_PEM_NAME_DEFAULT="${_cdomain}.pem" DEPLOY_HAPROXY_BUNDLE_DEFAULT="no" DEPLOY_HAPROXY_ISSUER_DEFAULT="no" - DEPLOY_HAPROXY_RELOAD_DEFAULT="systemctl reload haproxy" + DEPLOY_HAPROXY_RELOAD_DEFAULT="true" if [ -f "${DOMAIN_CONF}" ]; then # shellcheck disable=SC1090 From 475e6e28eb1eb998f37adcfa09f22faa869a7d9a Mon Sep 17 00:00:00 2001 From: Ne-Lexa Date: Fri, 12 Oct 2018 19:04:18 +0300 Subject: [PATCH 0041/2234] Added dns api support for internet.bs --- README.md | 1 + dnsapi/dns_internetbs.sh | 173 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100755 dnsapi/dns_internetbs.sh diff --git a/README.md b/README.md index b9a5cc59..b0c2d02a 100644 --- a/README.md +++ b/README.md @@ -327,6 +327,7 @@ You don't have to do anything manually! 1. netcup DNS API (https://www.netcup.de) 1. GratisDNS.dk (https://gratisdns.dk) 1. Namecheap API (https://www.namecheap.com/) +1. Internet.bs API (https://internetbs.net/) And: diff --git a/dnsapi/dns_internetbs.sh b/dnsapi/dns_internetbs.sh new file mode 100755 index 00000000..bf227e3a --- /dev/null +++ b/dnsapi/dns_internetbs.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env sh + +#This is the Internet.BS api wrapper for acme.sh +# +#Author: Ne-Lexa +#Report Bugs here: https://github.com/Ne-Lexa/acme.sh + +#INTERNETBS_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" +#INTERNETBS_API_PASSWORD="sdfsdfsdfljlbjkljlkjsdfoiwje" +INTERNETBS_API_URL="https://api.internet.bs" + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_internetbs_add() { + fulldomain=$1 + txtvalue=$2 + + if [ -z "$INTERNETBS_API_KEY" ] || [ -z "$INTERNETBS_API_PASSWORD" ]; then + INTERNETBS_API_KEY="" + INTERNETBS_API_PASSWORD="" + _err "You didn't specify the INTERNET.BS api key and password yet." + _err "Please create you key and try again." + return 1 + fi + + _saveaccountconf INTERNETBS_API_KEY "$INTERNETBS_API_KEY" + _saveaccountconf INTERNETBS_API_PASSWORD "$INTERNETBS_API_PASSWORD" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # https://testapi.internet.bs/Domain/DnsRecord/Add?ApiKey=testapi&Password=testpass&FullRecordName=w3.test-api-domain7.net&Type=CNAME&Value=www.internet.bs%&ResponseFormat=json + if _internetbs_rest POST "Domain/DnsRecord/Add" "FullRecordName=${_sub_domain}.${_domain}&Type=TXT&Value=${txtvalue}&ResponseFormat=json"; then + if ! _contains "$response" "\"status\":\"SUCCESS\""; then + _err "ERROR add TXT record" + _err "$response" + _clearaccountconf INTERNETBS_API_KEY + _clearaccountconf INTERNETBS_API_PASSWORD + return 1 + fi + + _info "txt record add success." + return 0 + fi + + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_internetbs_rm() { + fulldomain=$1 + txtvalue=$2 + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + # https://testapi.internet.bs/Domain/DnsRecord/List?ApiKey=testapi&Password=testpass&Domain=test-api-domain7.net&FilterType=CNAME&ResponseFormat=json + _internetbs_rest POST "Domain/DnsRecord/List" "Domain=$_domain&FilterType=TXT&ResponseFormat=json" + + if ! _contains "$response" "\"status\":\"SUCCESS\""; then + _err "ERROR list dns records" + _err "$response" + _clearaccountconf INTERNETBS_API_KEY + _clearaccountconf INTERNETBS_API_PASSWORD + return 1 + fi + + if _contains "$response" "\name\":\"${_sub_domain}.${_domain}\""; then + _info "txt record find." + + # https://testapi.internet.bs/Domain/DnsRecord/Remove?ApiKey=testapi&Password=testpass&FullRecordName=www.test-api-domain7.net&Type=cname&ResponseFormat=json + _internetbs_rest POST "Domain/DnsRecord/Remove" "FullRecordName=${_sub_domain}.${_domain}&Type=TXT&ResponseFormat=json" + + if ! _contains "$response" "\"status\":\"SUCCESS\""; then + _err "ERROR remove dns record" + _err "$response" + _clearaccountconf INTERNETBS_API_KEY + _clearaccountconf INTERNETBS_API_PASSWORD + return 1 + fi + + _info "txt record deleted success." + return 0 + fi + + return 1 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=12345 +_get_root() { + domain=$1 + i=2 + p=1 + + # https://testapi.internet.bs/Domain/List?ApiKey=testapi&Password=testpass&CompactList=yes&ResponseFormat=json + if _internetbs_rest POST "Domain/List" "CompactList=yes&ResponseFormat=json"; then + + if ! _contains "$response" "\"status\":\"SUCCESS\""; then + _err "ERROR fetch domain list" + _err "$response" + _clearaccountconf INTERNETBS_API_KEY + _clearaccountconf INTERNETBS_API_PASSWORD + 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 + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-${p}) + _domain=${h} + return 0 + fi + + p=i + i=$(_math "$i" + 1) + done + fi + return 1 +} + +#Usage: method URI data +_internetbs_rest() { + m="$1" + ep="$2" + data="$3" + url="${INTERNETBS_API_URL}/${ep}" + + _debug url "$url" + + apiKey="$(printf "%s" "${INTERNETBS_API_KEY}" | _url_encode)" + password="$(printf "%s" "${INTERNETBS_API_PASSWORD}" | _url_encode)" + + if [ "$m" = "GET" ]; then + response="$(_get "${url}?ApiKey=${apiKey}&Password=${password}&${data}" | tr -d '\r')" + else + _debug2 data "$data" + response="$(_post "$data" "${url}?ApiKey=${apiKey}&Password=${password}" | tr -d '\r')" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + + _debug2 response "$response" + return 0 +} From fdb9d93b1211b673ddf9589f367343256ba677a3 Mon Sep 17 00:00:00 2001 From: Ne-Lexa Date: Fri, 12 Oct 2018 19:27:41 +0300 Subject: [PATCH 0042/2234] formatted --- dnsapi/dns_internetbs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_internetbs.sh b/dnsapi/dns_internetbs.sh index bf227e3a..ba170836 100755 --- a/dnsapi/dns_internetbs.sh +++ b/dnsapi/dns_internetbs.sh @@ -69,7 +69,7 @@ dns_internetbs_rm() { _debug _domain "$_domain" _debug "Getting txt records" - # https://testapi.internet.bs/Domain/DnsRecord/List?ApiKey=testapi&Password=testpass&Domain=test-api-domain7.net&FilterType=CNAME&ResponseFormat=json + # https://testapi.internet.bs/Domain/DnsRecord/List?ApiKey=testapi&Password=testpass&Domain=test-api-domain7.net&FilterType=CNAME&ResponseFormat=json _internetbs_rest POST "Domain/DnsRecord/List" "Domain=$_domain&FilterType=TXT&ResponseFormat=json" if ! _contains "$response" "\"status\":\"SUCCESS\""; then From a63dc75b43414d0d553cf89ee3a82e613420739d Mon Sep 17 00:00:00 2001 From: Ne-Lexa Date: Mon, 15 Oct 2018 18:20:26 +0300 Subject: [PATCH 0043/2234] Added documentation on using dns api internet.bs --- dnsapi/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dnsapi/README.md b/dnsapi/README.md index 2cecfa5a..0f867580 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1014,6 +1014,22 @@ Now you can issue a certificate. acme.sh --issue --dns dns_namecheap -d example.com -d *.example.com ``` +## 54. Use Internet.bs + +First you need to create/obtain API credentials on your Internet.bs (https://internetbs.net) account. Go to the "Get my API Key" section in the "My Domains" section. + +``` +export INTERNETBS_API_KEY="..." +export INTERNETBS_API_PASSWORD="..." +``` + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_internetbs -d example.com -d www.example.com +``` + +The `INTERNETBS_API_KEY` and `INTERNETBS_API_PASSWORD` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. From fd536d373ebd65eecf8ce8e2f760ef186e5ce74f Mon Sep 17 00:00:00 2001 From: Phil Ross Date: Thu, 18 Oct 2018 17:12:06 +0100 Subject: [PATCH 0044/2234] Skip aliases of already verified domains. When issuing a two-domain certificate using a different alias for each domain, if the first domain is already verified, verification for the second domain would be attempted (unsuccessfully) using the alias of the first domain. Increment the alias index when skipping verified domains so that the correct alias will be used for subsequent domains. --- acme.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acme.sh b/acme.sh index ee238274..8ae6600f 100755 --- a/acme.sh +++ b/acme.sh @@ -2925,6 +2925,7 @@ _clearupdns() { _debug txt "$txt" if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then _debug "$d is already verified, skip $vtype." + _alias_index="$(_math "$_alias_index" + 1)" continue fi @@ -3775,6 +3776,7 @@ $_authorizations_map" _debug d "$d" if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then _debug "$d is already verified, skip $vtype." + _alias_index="$(_math "$_alias_index" + 1)" continue fi From 26421684dc0c7c0cc79ea36f728d44de2fa382f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Thu, 26 Jul 2018 19:59:15 +0200 Subject: [PATCH 0045/2234] Fix inwx account without Mobile TAN --- dnsapi/dns_inwx.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index cd5af91b..f4590cf8 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -158,7 +158,8 @@ _inwx_login() { export _H1 #https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71 - if _contains "$response" "tfa"; then + if _contains "$response" "code1000" \ + && _contains "$response" "tfaGOOGLE-AUTH"; then if [ -z "$INWX_Shared_Secret" ]; then _err "Mobile TAN detected." _err "Please define a shared secret." From 46b3a9158c80ab5f1c76437ed1fb9fad2c13e96a Mon Sep 17 00:00:00 2001 From: LLeny <5269958+LLeny@users.noreply.github.com> Date: Sun, 21 Oct 2018 18:17:23 +0800 Subject: [PATCH 0046/2234] Fixes Neilpang/acme.sh#1888 --- dnsapi/dns_namecheap.sh | 64 +++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 7089c2d0..a6651be6 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -199,9 +199,12 @@ _namecheap_check_config() { _set_namecheap_TXT() { subdomain=$2 txt=$3 - tld=$(echo "$1" | cut -d '.' -f 2) - sld=$(echo "$1" | cut -d '.' -f 1) - request="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld" + + if ! _namecheap_set_tld_sld "$1"; then + return 1 + fi + + request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}" if ! _namecheap_post "$request"; then _err "$error" @@ -231,7 +234,7 @@ EOT _debug hostrequestfinal "$_hostrequest" - request="namecheap.domains.dns.setHosts&SLD=${sld}&TLD=${tld}${_hostrequest}" + request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}" if ! _namecheap_post "$request"; then _err "$error" @@ -244,9 +247,12 @@ EOT _del_namecheap_TXT() { subdomain=$2 txt=$3 - tld=$(echo "$1" | cut -d '.' -f 2) - sld=$(echo "$1" | cut -d '.' -f 1) - request="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld" + + if ! _namecheap_set_tld_sld "$1"; then + return 1 + fi + + request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}" if ! _namecheap_post "$request"; then _err "$error" @@ -286,7 +292,7 @@ EOT _debug hostrequestfinal "$_hostrequest" - request="namecheap.domains.dns.setHosts&SLD=${sld}&TLD=${tld}${_hostrequest}" + request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}" if ! _namecheap_post "$request"; then _err "$error" @@ -306,3 +312,45 @@ _namecheap_add_host() { _hostindex=$(_math "$_hostindex" + 1) _hostrequest=$(printf '%s&HostName%d=%s&RecordType%d=%s&Address%d=%s&MXPref%d=%d&TTL%d=%d' "$_hostrequest" "$_hostindex" "$1" "$_hostindex" "$2" "$_hostindex" "$3" "$_hostindex" "$4" "$_hostindex" "$5") } + +_namecheap_set_tld_sld() { + domain=$1 + _tld="" + _sld="" + + i=2 + + while true; do + + _tld=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug tld "$_tld" + + if [ -z "$_tld" ]; then + _debug "invalid tld" + return 1 + fi + + j=$(_math "$i" - 1) + + _sld=$(printf "%s" "$domain" | cut -d . -f 1-"$j") + _debug sld "$_sld" + + if [ -z "$_sld" ]; then + _debug "invalid sld" + return 1 + fi + + request="namecheap.domains.dns.getHosts&SLD=$_sld&TLD=$_tld" + + if ! _namecheap_post "$request"; then + _debug "sld($_sld)/tld($_tld) not found" + else + _debug "sld($_sld)/tld($_tld) found" + return 0 + fi + + i=$(_math "$i" + 1) + + done + +} From a894b7cc9b374d5588b346a9afde1282b5d067d3 Mon Sep 17 00:00:00 2001 From: hebbet Date: Wed, 24 Oct 2018 16:33:02 +0200 Subject: [PATCH 0047/2234] add link to cloudflare profil for api key --- dnsapi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 2cecfa5a..71ba53b8 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -6,7 +6,7 @@ https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode ## 1. Use CloudFlare domain API to automatically issue cert -First you need to login to your CloudFlare account to get your API key. +First you need to login to your CloudFlare account to get your [API key](https://dash.cloudflare.com/profile). ``` export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" From a207199879a21c58433273f7461bf4a464d7a8f9 Mon Sep 17 00:00:00 2001 From: Ne-Lexa Date: Mon, 29 Oct 2018 15:18:43 +0300 Subject: [PATCH 0048/2234] fixed _get_root() function --- dnsapi/dns_internetbs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_internetbs.sh b/dnsapi/dns_internetbs.sh index ba170836..05a1adae 100755 --- a/dnsapi/dns_internetbs.sh +++ b/dnsapi/dns_internetbs.sh @@ -137,7 +137,7 @@ _get_root() { return 0 fi - p=i + p=${i} i=$(_math "$i" + 1) done fi From 12956679e73e615882fc556518fba00c2d07baf4 Mon Sep 17 00:00:00 2001 From: Joakim Lemb Date: Mon, 5 Nov 2018 14:52:26 +0100 Subject: [PATCH 0049/2234] Added top URI parameter --- dnsapi/dns_azure.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index c6893a0c..ae8aa1ca 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -316,7 +316,7 @@ _get_root() { ## (ZoneListResult with continuation token for the next page of results) ## Per https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits#dns-limits you are limited to 100 Zone/subscriptions anyways ## - _azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?api-version=2017-09-01" "" "$accesstoken" + _azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken" # Find matching domain name is Json response while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From 4b581f37203a8dea1c7c1ef5d25322fed49bb3e8 Mon Sep 17 00:00:00 2001 From: pavelaks Date: Sat, 10 Nov 2018 12:10:06 +0300 Subject: [PATCH 0050/2234] Update README.md Fix VSCALE example (add export before VSCALE_API_KEY) --- dnsapi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 2cecfa5a..9413925b 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -454,7 +454,7 @@ The `Infoblox_Creds` and `Infoblox_Server` will be saved in `~/.acme.sh/account. First you need to create/obtain API tokens on your [settings panel](https://vscale.io/panel/settings/tokens/). ``` -VSCALE_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" +export VSCALE_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" ``` Ok, let's issue a cert now: From 552710ac2a2e5dcb85d31f3d3d4ed5c2a0dbd5ec Mon Sep 17 00:00:00 2001 From: nakermann1973 <35577878+nakermann1973@users.noreply.github.com> Date: Tue, 13 Nov 2018 10:15:38 +0100 Subject: [PATCH 0051/2234] Add missing bind-tools package The bind_tools package is required for dns_nsupdate to work --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 5a64c720..c1a2199b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ RUN apk update -f \ && apk --no-cache add -f \ openssl \ coreutils \ + bind-tools \ curl \ socat \ && rm -rf /var/cache/apk/* From 5fee82ce39e70a301cece87185762f415489b258 Mon Sep 17 00:00:00 2001 From: Thomas Rohlik Date: Mon, 19 Nov 2018 16:09:32 +0100 Subject: [PATCH 0052/2234] Fix dot Very important commit :1st_place_medal: --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index ee238274..0930effd 100755 --- a/acme.sh +++ b/acme.sh @@ -5485,7 +5485,7 @@ Parameters: --server SERVER ACME Directory Resource URI. (default: https://acme-v01.api.letsencrypt.org/directory) --accountconf Specifies a customized account config file. - --home Specifies the home dir for $PROJECT_NAME . + --home Specifies the home dir for $PROJECT_NAME. --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. --config-home Specifies the home dir to save all the configurations. --useragent Specifies the user agent string. it will be saved for future use too. From 137dc1eac0bdc6f664c7fbc3aae9b1cce4c58a85 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 23 Nov 2018 22:53:02 +0800 Subject: [PATCH 0053/2234] fix https://github.com/Neilpang/acme.sh/issues/1912 --- acme.sh | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/acme.sh b/acme.sh index c7138c1b..502b6950 100755 --- a/acme.sh +++ b/acme.sh @@ -124,23 +124,19 @@ if [ -t 1 ]; then fi __green() { - if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then - printf '\033[1;31;32m' + if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then + printf '\033[1;31;32m%b\033[0m' "$1" + return fi printf -- "%b" "$1" - if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then - printf '\033[0m' - fi } __red() { - if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then - printf '\033[1;31;40m' + if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then + printf '\033[1;31;40m%b\033[0m' "$1" + return fi printf -- "%b" "$1" - if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then - printf '\033[0m' - fi } _printargs() { From a6f2110141011c950c6709b083331f0dd933de9b Mon Sep 17 00:00:00 2001 From: epgdatacapbon Date: Sat, 24 Nov 2018 01:58:46 +0900 Subject: [PATCH 0054/2234] Add DNS API support for MyDNS.JP --- dnsapi/README.md | 16 ++++ dnsapi/dns_mydnsjp.sh | 210 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 dnsapi/dns_mydnsjp.sh diff --git a/dnsapi/README.md b/dnsapi/README.md index 2cecfa5a..7362eb2c 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1014,6 +1014,22 @@ Now you can issue a certificate. acme.sh --issue --dns dns_namecheap -d example.com -d *.example.com ``` +## 54. Use MyDNS.JP API + +First, register to MyDNS.JP and get MasterID and Password. + +``` +export MYDNSJP_MasterID=MasterID +export MYDNSJP_Password=Password +``` + +To issue a certificate: + +``` +acme.sh --issue --dns dns_mydnsjp -d example.com -d www.example.com +``` +The `MYDNSJP_MasterID` and `MYDNSJP_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_mydnsjp.sh b/dnsapi/dns_mydnsjp.sh new file mode 100644 index 00000000..d421329c --- /dev/null +++ b/dnsapi/dns_mydnsjp.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env sh + +#Here is a api script for MyDNS.JP. +#This file name is "dns_mydnsjp.sh" +#So, here must be a method dns_mydnsjp_add() +#Which will be called by acme.sh to add the txt record to your api system. +#returns 0 means success, otherwise error. +# +#Author: epgdatacapbon +#Report Bugs here: https://github.com/epgdatacapbon/acme.sh +# +######## Public functions ##################### + +# Export MyDNS.JP MasterID and Password in following variables... +# MYDNSJP_MasterID=MasterID +# MYDNSJP_Password=Password + +MYDNSJP_API="http://www.mydns.jp" + +#Usage: dns_mydnsjp_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_mydnsjp_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Using mydnsjp" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + # Load the credentials from the account conf file + MYDNSJP_MasterID="${MYDNSJP_MasterID:-$(_readaccountconf_mutable MYDNSJP_MasterID)}" + MYDNSJP_Password="${MYDNSJP_Password:-$(_readaccountconf_mutable MYDNSJP_Password)}" + if [ -z "$MYDNSJP_MasterID" ] || [ -z "$MYDNSJP_Password" ]; then + MYDNSJP_MasterID="" + MYDNSJP_Password="" + _err "You don't specify mydnsjp api MasterID and Password yet." + _err "Please export as MYDNSJP_MasterID / MYDNSJP_Password and try again." + return 1 + fi + + # Save the credentials to the account conf file + _saveaccountconf_mutable MYDNSJP_MasterID "$MYDNSJP_MasterID" + _saveaccountconf_mutable MYDNSJP_Password "$MYDNSJP_Password" + + _debug "First detect the root zone." + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + if _mydnsjp_api "REGIST" "$_domain" "$txtvalue"; then + if printf -- "%s" "$response" | grep "OK." >/dev/null; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_mydnsjp_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Removing TXT record" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + # Load the credentials from the account conf file + MYDNSJP_MasterID="${MYDNSJP_MasterID:-$(_readaccountconf_mutable MYDNSJP_MasterID)}" + MYDNSJP_Password="${MYDNSJP_Password:-$(_readaccountconf_mutable MYDNSJP_Password)}" + if [ -z "$MYDNSJP_MasterID" ] || [ -z "$MYDNSJP_Password" ]; then + MYDNSJP_MasterID="" + MYDNSJP_Password="" + _err "You don't specify mydnsjp api MasterID and Password yet." + _err "Please export as MYDNSJP_MasterID / MYDNSJP_Password and try again." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + if _mydnsjp_api "DELETE" "$_domain" "$txtvalue"; then + if printf -- "%s" "$response" | grep "OK." >/dev/null; then + _info "Deleted, OK" + return 0 + else + _err "Delete txt record error." + return 1 + fi + fi + _err "Delete txt record error." + + return 1 +} + +#################### Private functions below ################################## +# _acme-challenge.www.domain.com +# returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + fulldomain=$1 + i=2 + p=1 + + # Get the root domain + _mydnsjp_retrieve_domain + if [ "$?" != "0" ]; then + # not valid + return 1 + fi + + while true; do + _domain=$(printf "%s" "$fulldomain" | cut -d . -f $i-100) + + if [ -z "$_domain" ]; then + # not valid + return 1 + fi + + if [ "$_domain" = "$_root_domain" ]; then + _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-$p) + return 0 + fi + + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} + +# Retrieve the root domain +# returns 0 success +_mydnsjp_retrieve_domain() { + _debug "Login to MyDNS.JP" + + response="$(_post "masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/?MENU=100")" + cookie="$(grep '^Set-Cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)" + + # If cookies is not empty then logon successful + if [ -z "$cookie" ]; then + _err "Fail to get a cookie." + return 1 + fi + + _debug "Retrieve DOMAIN INFO page" + + export _H1="Cookie:${cookie}" + + response="$(_get "$MYDNSJP_API/?MENU=300")" + + if [ "$?" != "0" ]; then + _err "Fail to retrieve DOMAIN INFO." + return 1 + fi + + _root_domain=$(echo "$response" | grep "DNSINFO\[domainname\]" | sed 's/^.*value="\([^"]*\)".*/\1/') + + # Logout + response="$(_get "$MYDNSJP_API/?MENU=090")" + + _debug _root_domain "$_root_domain" + + if [ -z "$_root_domain" ]; then + _err "Fail to get the root domain." + return 1 + fi + + return 0 +} + +_mydnsjp_api() { + cmd=$1 + domain=$2 + txtvalue=$3 + + # Base64 encode the credentials + credentials=$(printf "%s:%s" "$MYDNSJP_MasterID" "$MYDNSJP_Password" | _base64) + + # Construct the HTTP Authorization header + export _H1="Content-Type: application/x-www-form-urlencoded" + export _H2="Authorization: Basic ${credentials}" + + response="$(_post "CERTBOT_DOMAIN=$domain&CERTBOT_VALIDATION=$txtvalue&EDIT_CMD=$cmd" "$MYDNSJP_API/directedit.html")" + + if [ "$?" != "0" ]; then + _err "error $domain" + return 1 + fi + + _debug2 response "$response" + + return 0 +} From 14ad5955b58a48720da0b70bb902900029f9b3f8 Mon Sep 17 00:00:00 2001 From: epgdatacapbon Date: Sat, 24 Nov 2018 01:58:46 +0900 Subject: [PATCH 0055/2234] Add DNS API support for MyDNS.JP --- dnsapi/README.md | 16 ++++ dnsapi/dns_mydnsjp.sh | 210 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 dnsapi/dns_mydnsjp.sh diff --git a/dnsapi/README.md b/dnsapi/README.md index 02e8fd82..f126568b 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1014,6 +1014,22 @@ Now you can issue a certificate. acme.sh --issue --dns dns_namecheap -d example.com -d *.example.com ``` +## 54. Use MyDNS.JP API + +First, register to MyDNS.JP and get MasterID and Password. + +``` +export MYDNSJP_MasterID=MasterID +export MYDNSJP_Password=Password +``` + +To issue a certificate: + +``` +acme.sh --issue --dns dns_mydnsjp -d example.com -d www.example.com +``` +The `MYDNSJP_MasterID` and `MYDNSJP_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_mydnsjp.sh b/dnsapi/dns_mydnsjp.sh new file mode 100644 index 00000000..d421329c --- /dev/null +++ b/dnsapi/dns_mydnsjp.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env sh + +#Here is a api script for MyDNS.JP. +#This file name is "dns_mydnsjp.sh" +#So, here must be a method dns_mydnsjp_add() +#Which will be called by acme.sh to add the txt record to your api system. +#returns 0 means success, otherwise error. +# +#Author: epgdatacapbon +#Report Bugs here: https://github.com/epgdatacapbon/acme.sh +# +######## Public functions ##################### + +# Export MyDNS.JP MasterID and Password in following variables... +# MYDNSJP_MasterID=MasterID +# MYDNSJP_Password=Password + +MYDNSJP_API="http://www.mydns.jp" + +#Usage: dns_mydnsjp_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_mydnsjp_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Using mydnsjp" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + # Load the credentials from the account conf file + MYDNSJP_MasterID="${MYDNSJP_MasterID:-$(_readaccountconf_mutable MYDNSJP_MasterID)}" + MYDNSJP_Password="${MYDNSJP_Password:-$(_readaccountconf_mutable MYDNSJP_Password)}" + if [ -z "$MYDNSJP_MasterID" ] || [ -z "$MYDNSJP_Password" ]; then + MYDNSJP_MasterID="" + MYDNSJP_Password="" + _err "You don't specify mydnsjp api MasterID and Password yet." + _err "Please export as MYDNSJP_MasterID / MYDNSJP_Password and try again." + return 1 + fi + + # Save the credentials to the account conf file + _saveaccountconf_mutable MYDNSJP_MasterID "$MYDNSJP_MasterID" + _saveaccountconf_mutable MYDNSJP_Password "$MYDNSJP_Password" + + _debug "First detect the root zone." + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + if _mydnsjp_api "REGIST" "$_domain" "$txtvalue"; then + if printf -- "%s" "$response" | grep "OK." >/dev/null; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_mydnsjp_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Removing TXT record" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + # Load the credentials from the account conf file + MYDNSJP_MasterID="${MYDNSJP_MasterID:-$(_readaccountconf_mutable MYDNSJP_MasterID)}" + MYDNSJP_Password="${MYDNSJP_Password:-$(_readaccountconf_mutable MYDNSJP_Password)}" + if [ -z "$MYDNSJP_MasterID" ] || [ -z "$MYDNSJP_Password" ]; then + MYDNSJP_MasterID="" + MYDNSJP_Password="" + _err "You don't specify mydnsjp api MasterID and Password yet." + _err "Please export as MYDNSJP_MasterID / MYDNSJP_Password and try again." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + if _mydnsjp_api "DELETE" "$_domain" "$txtvalue"; then + if printf -- "%s" "$response" | grep "OK." >/dev/null; then + _info "Deleted, OK" + return 0 + else + _err "Delete txt record error." + return 1 + fi + fi + _err "Delete txt record error." + + return 1 +} + +#################### Private functions below ################################## +# _acme-challenge.www.domain.com +# returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + fulldomain=$1 + i=2 + p=1 + + # Get the root domain + _mydnsjp_retrieve_domain + if [ "$?" != "0" ]; then + # not valid + return 1 + fi + + while true; do + _domain=$(printf "%s" "$fulldomain" | cut -d . -f $i-100) + + if [ -z "$_domain" ]; then + # not valid + return 1 + fi + + if [ "$_domain" = "$_root_domain" ]; then + _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-$p) + return 0 + fi + + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} + +# Retrieve the root domain +# returns 0 success +_mydnsjp_retrieve_domain() { + _debug "Login to MyDNS.JP" + + response="$(_post "masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/?MENU=100")" + cookie="$(grep '^Set-Cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)" + + # If cookies is not empty then logon successful + if [ -z "$cookie" ]; then + _err "Fail to get a cookie." + return 1 + fi + + _debug "Retrieve DOMAIN INFO page" + + export _H1="Cookie:${cookie}" + + response="$(_get "$MYDNSJP_API/?MENU=300")" + + if [ "$?" != "0" ]; then + _err "Fail to retrieve DOMAIN INFO." + return 1 + fi + + _root_domain=$(echo "$response" | grep "DNSINFO\[domainname\]" | sed 's/^.*value="\([^"]*\)".*/\1/') + + # Logout + response="$(_get "$MYDNSJP_API/?MENU=090")" + + _debug _root_domain "$_root_domain" + + if [ -z "$_root_domain" ]; then + _err "Fail to get the root domain." + return 1 + fi + + return 0 +} + +_mydnsjp_api() { + cmd=$1 + domain=$2 + txtvalue=$3 + + # Base64 encode the credentials + credentials=$(printf "%s:%s" "$MYDNSJP_MasterID" "$MYDNSJP_Password" | _base64) + + # Construct the HTTP Authorization header + export _H1="Content-Type: application/x-www-form-urlencoded" + export _H2="Authorization: Basic ${credentials}" + + response="$(_post "CERTBOT_DOMAIN=$domain&CERTBOT_VALIDATION=$txtvalue&EDIT_CMD=$cmd" "$MYDNSJP_API/directedit.html")" + + if [ "$?" != "0" ]; then + _err "error $domain" + return 1 + fi + + _debug2 response "$response" + + return 0 +} From d55c64c83891e06fef9301c3bbbad54b36de27b2 Mon Sep 17 00:00:00 2001 From: epgdatacapbon Date: Sat, 24 Nov 2018 14:07:50 +0900 Subject: [PATCH 0056/2234] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b9a5cc59..e0f601d3 100644 --- a/README.md +++ b/README.md @@ -327,6 +327,7 @@ You don't have to do anything manually! 1. netcup DNS API (https://www.netcup.de) 1. GratisDNS.dk (https://gratisdns.dk) 1. Namecheap API (https://www.namecheap.com/) +1. MyDNS.JP API (https://www.mydns.jp/) And: From be5085f2052321f0fa1887bd7be7b3ca0de52aa2 Mon Sep 17 00:00:00 2001 From: epgdatacapbon Date: Sun, 25 Nov 2018 18:14:52 +0900 Subject: [PATCH 0057/2234] Increase security using https for MyDNS.JP API --- dnsapi/dns_mydnsjp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 dnsapi/dns_mydnsjp.sh diff --git a/dnsapi/dns_mydnsjp.sh b/dnsapi/dns_mydnsjp.sh old mode 100644 new mode 100755 index d421329c..aab2aabf --- a/dnsapi/dns_mydnsjp.sh +++ b/dnsapi/dns_mydnsjp.sh @@ -15,7 +15,7 @@ # MYDNSJP_MasterID=MasterID # MYDNSJP_Password=Password -MYDNSJP_API="http://www.mydns.jp" +MYDNSJP_API="https://www.mydns.jp" #Usage: dns_mydnsjp_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_mydnsjp_add() { @@ -151,7 +151,7 @@ _mydnsjp_retrieve_domain() { _debug "Login to MyDNS.JP" response="$(_post "masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/?MENU=100")" - cookie="$(grep '^Set-Cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)" + cookie="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)" # If cookies is not empty then logon successful if [ -z "$cookie" ]; then From 7917aa2a7c7012d2d0ee2e5d14924dbee801a3b5 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 2 Dec 2018 19:37:35 +0800 Subject: [PATCH 0058/2234] fix https://github.com/Neilpang/acme.sh/issues/1941 cache dns zones response --- dnsapi/dns_cf.sh | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 3595b9b0..cbebb03a 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -34,6 +34,9 @@ dns_cf_add() { _saveaccountconf_mutable CF_Key "$CF_Key" _saveaccountconf_mutable CF_Email "$CF_Email" + _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '@.' '__')" + _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -58,9 +61,12 @@ dns_cf_add() { # if [ "$count" = "0" ]; then _info "Adding record" if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then - if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then + if _contains "$response" "$fulldomain"; then _info "Added, OK" return 0 + elif _contains "$response" "The record already exists"; then + _info "Already exists, OK" + return 0 else _err "Add txt record error." return 1 @@ -99,11 +105,16 @@ dns_cf_rm() { return 1 fi + _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '@.' '__')" + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then + _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" _err "invalid domain" return 1 fi + _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" + _debug _domain_id "$_domain_id" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" @@ -143,6 +154,21 @@ dns_cf_rm() { # _domain=domain.com # _domain_id=sdjkglgdfewsdfg _get_root() { + + _cf_zones="$(_readdomainconf $_DOMAIN_CF_ZONES_CACHE_NAME_)" + _debug2 "_cf_zones" "$_cf_zones" + if [ -z "$_cf_zones" ]; then + _debug "$_DOMAIN_CF_ZONES_CACHE_NAME_ is none, so get it." + if ! _cf_rest GET "zones"; then + return 1 + fi + _cf_zones="$response" + _savedomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" "$(echo "$_cf_zones" | _base64)" + else + _debug "$_DOMAIN_CF_ZONES_CACHE_NAME_ found" + _cf_zones="$(echo "$_cf_zones" | _dbase64)" + fi + domain=$1 i=2 p=1 @@ -154,12 +180,8 @@ _get_root() { return 1 fi - if ! _cf_rest GET "zones?name=$h"; then - return 1 - fi - - if _contains "$response" "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") + if _contains "$_cf_zones" "\"name\":\"$h\"" >/dev/null; then + _domain_id=$(printf "%s\n" "$_cf_zones" | _egrep_o "\[.\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 9a27b389765ac6d7a256333e9e1f6fe3c4b92e08 Mon Sep 17 00:00:00 2001 From: "Aaron W. Swenson" Date: Sun, 2 Dec 2018 11:18:41 -0500 Subject: [PATCH 0059/2234] Update Linode API to v4 Linode API has made breaking changes that are resolved by this update. No user action is required. Additionally, related README.md entry updated to include new cloud manager interface. --- dnsapi/README.md | 13 +++++++++++-- dnsapi/dns_linode.sh | 39 ++++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index bb0e89d0..5642aa4e 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -264,9 +264,18 @@ when needed. ## 14. Use Linode domain API First you need to login to your Linode account to get your API Key. -[https://manager.linode.com/profile/api](https://manager.linode.com/profile/api) -Then add an API key with label *ACME* and copy the new key. + * [Classic Manager](https://manager.linode.com/profile/api) + + Under "Add an API key", Give the new key a "Label" (we recommend *ACME*), + set the expiry to never, "Create API Key", and copy the new key into the `LINODE_API_KEY` command + below. + + * [Cloud Manager](https://cloud.linode.com/profile/tokens) + + Click on "Add a Personal Access Token". Give the new key a "Label" (we + recommend *ACME*), give it Read/Write access to "Domains". "Submit", and + copy the new key into the `LINODE_API_KEY` command below. ```sh export LINODE_API_KEY="..." diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index ead5b164..d03e6c47 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -2,7 +2,7 @@ #Author: Philipp Grosswiler -LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action=" +LINODE_API_URL="https://api.linode.com/v4/domains" ######## Public functions ##################### @@ -27,10 +27,14 @@ dns_linode_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _parameters="&DomainID=$_domain_id&Type=TXT&Name=$_sub_domain&Target=$txtvalue" + _payload="{ + \"type\": \"TXT\", + \"name\": \"$_sub_domain\", + \"target\": \"$txtvalue\" + }" - if _rest GET "domain.resource.create" "$_parameters" && [ -n "$response" ]; then - _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + if _rest POST "/$_domain_id/records" "$_payload" && [ -n "$response" ]; then + _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) _debug _resource_id "$_resource_id" if [ -z "$_resource_id" ]; then @@ -65,25 +69,21 @@ dns_linode_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _parameters="&DomainID=$_domain_id" - - if _rest GET "domain.resource.list" "$_parameters" && [ -n "$response" ]; then + if _rest GET "/$_domain_id/records" && [ -n "$response" ]; then response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" - resource="$(echo "$response" | _egrep_o "{.*\"NAME\":\s*\"$_sub_domain\".*}")" + resource="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$_sub_domain\".*}")" if [ "$resource" ]; then - _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"RESOURCEID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_resource_id" ]; then _debug _resource_id "$_resource_id" - _parameters="&DomainID=$_domain_id&ResourceID=$_resource_id" + if _rest DELETE "/$_domain_id/records/$_resource_id" && [ -n "$response" ]; then + # On 200/OK, empty set is returned. Check for error, if any. + _error_response=$(printf "%s\n" "$response" | _egrep_o "\"errors\"" | cut -d : -f 2 | tr -d " " | _head_n 1) - if _rest GET "domain.resource.delete" "$_parameters" && [ -n "$response" ]; then - _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) - _debug _resource_id "$_resource_id" - - if [ -z "$_resource_id" ]; then - _err "Error deleting the domain resource." + if [ -n "$_error_response" ]; then + _err "Error deleting the domain resource: $_error_response" return 1 fi @@ -127,7 +127,7 @@ _get_root() { i=2 p=1 - if _rest GET "domain.list"; then + if _rest GET; then response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -137,9 +137,9 @@ _get_root() { return 1 fi - hostedzone="$(echo "$response" | _egrep_o "{.*\"DOMAIN\":\s*\"$h\".*}")" + hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\":\s*\"$h\".*}")" if [ "$hostedzone" ]; then - _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"DOMAINID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -165,6 +165,7 @@ _rest() { export _H1="Accept: application/json" export _H2="Content-Type: application/json" + export _H3="Authorization: Bearer $LINODE_API_KEY" if [ "$mtd" != "GET" ]; then # both POST and DELETE. From 598becf6197d750615f9f62a881f4c383c2f35b2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Dec 2018 20:31:20 +0800 Subject: [PATCH 0060/2234] minor, fix format --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index cbebb03a..944956ad 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -155,7 +155,7 @@ dns_cf_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { - _cf_zones="$(_readdomainconf $_DOMAIN_CF_ZONES_CACHE_NAME_)" + _cf_zones="$(_readdomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_")" _debug2 "_cf_zones" "$_cf_zones" if [ -z "$_cf_zones" ]; then _debug "$_DOMAIN_CF_ZONES_CACHE_NAME_ is none, so get it." From fb08b53f0b4c43db21bc33b804c031c9cc8ae975 Mon Sep 17 00:00:00 2001 From: Adrian Almenar Date: Mon, 3 Dec 2018 18:42:33 +0100 Subject: [PATCH 0061/2234] Add Neodigit.net DNS API --- README.md | 3 +- dnsapi/README.md | 13 +++ dnsapi/dns_neodigit.sh | 181 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 dnsapi/dns_neodigit.sh diff --git a/README.md b/README.md index c4ea5c6e..6dcc8eaf 100644 --- a/README.md +++ b/README.md @@ -329,8 +329,9 @@ You don't have to do anything manually! 1. Namecheap API (https://www.namecheap.com/) 1. MyDNS.JP API (https://www.mydns.jp/) 1. hosting.de (https://www.hosting.de) +1. Neodigit.net API (https://www.neodigit.net) -And: +And: **lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api (DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.)** diff --git a/dnsapi/README.md b/dnsapi/README.md index bb0e89d0..b5f4d2cc 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1054,6 +1054,19 @@ acme.sh --issue --dns dns_hostingde -d example.com -d *.example.com The hosting.de API key and endpoint will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 56. Use Neodigit.net API + +``` +export NEODIGIT_API_TOKEN="eXJxTkdUVUZmcHQ3QWJackQ4ZGlMejRDSklRYmo5VG5zcFFKK2thYnE0WnVnNnMy" +``` + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_neodigit -d example.com -d www.example.com +``` + +Neodigit API Token will be saved in `~/.acme.sh/account.conf` and will be used when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_neodigit.sh b/dnsapi/dns_neodigit.sh new file mode 100644 index 00000000..9835613d --- /dev/null +++ b/dnsapi/dns_neodigit.sh @@ -0,0 +1,181 @@ +#!/usr/bin/env sh + +# +# NEODIGIT_API_TOKEN="jasdfhklsjadhflnhsausdfas" + +# This is Neodigit.net api wrapper for acme.sh +# +# Author: Adrian Almenar +# Report Bugs here: https://github.com/tecnocratica/acme.sh +# +NEODIGIT_API_URL="https://api.neodigit.net/v1" +# +######## Public functions ##################### + +# Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_neodigit_add() { + fulldomain=$1 + txtvalue=$2 + + NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" + if [ -z "$NEODIGIT_API_TOKEN" ]; then + NEODIGIT_API_TOKEN="" + _err "You haven't specified a Token api key." + _err "Please create the key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable NEODIGIT_API_TOKEN "$NEODIGIT_API_TOKEN" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + _debug domain "$_domain" + _debug sub_domain "$_sub_domain" + + _debug "Getting txt records" + _neo_rest GET "dns/zones/${_domain_id}/records?type=TXT&name=$fulldomain" + + _debug _code "$_code" + + if [ "$_code" != "200" ]; then + _err "error retrieving data!" + return 1 + fi + + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + _debug domain "$_domain" + _debug sub_domain "$_sub_domain" + + _info "Adding record" + if _neo_rest POST "dns/zones/$_domain_id/records" "{\"record\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":60}}"; then + if printf -- "%s" "$response" | grep "$_sub_domain" >/dev/null; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 +} + +#fulldomain txtvalue +dns_neodigit_rm() { + fulldomain=$1 + txtvalue=$2 + + NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" + if [ -z "$NEODIGIT_API_TOKEN" ]; then + NEODIGIT_API_TOKEN="" + _err "You haven't specified a Token api key." + _err "Please create the key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable NEODIGIT_API_TOKEN "$NEODIGIT_API_TOKEN" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _neo_rest GET "dns/zones/${_domain_id}/records?type=TXT&name=$fulldomain&content=$txtvalue" + + if [ "$_code" != "200" ]; then + _err "error retrieving data!" + return 1 + fi + + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1) + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _neo_rest DELETE "dns/zones/$_domain_id/records/$record_id"; then + _err "Delete record error." + return 1 + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=dasfdsafsadg5ythd +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _neo_rest GET "dns/zones?name=$h"; then + return 1 + fi + + _debug p "$p" + + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1) + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_neo_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + export _H1="X-TCPanel-Token: $NEODIGIT_API_TOKEN" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$NEODIGIT_API_URL/$ep" "" "$m")" + else + response="$(_get "$NEODIGIT_API_URL/$ep")" + fi + + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From f4ad42bb842e410bd86500cf5bb936d8c3f1e989 Mon Sep 17 00:00:00 2001 From: Adrian Almenar Date: Tue, 4 Dec 2018 14:33:00 +0100 Subject: [PATCH 0062/2234] Changes requested on commit review --- dnsapi/dns_neodigit.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_neodigit.sh b/dnsapi/dns_neodigit.sh index 9835613d..d87845ad 100644 --- a/dnsapi/dns_neodigit.sh +++ b/dnsapi/dns_neodigit.sh @@ -17,7 +17,7 @@ dns_neodigit_add() { fulldomain=$1 txtvalue=$2 - NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" + NEODIGIT_API_TOKEN="$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" if [ -z "$NEODIGIT_API_TOKEN" ]; then NEODIGIT_API_TOKEN="" _err "You haven't specified a Token api key." @@ -73,7 +73,7 @@ dns_neodigit_rm() { fulldomain=$1 txtvalue=$2 - NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" + NEODIGIT_API_TOKEN="$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" if [ -z "$NEODIGIT_API_TOKEN" ]; then NEODIGIT_API_TOKEN="" _err "You haven't specified a Token api key." @@ -102,7 +102,7 @@ dns_neodigit_rm() { return 1 fi - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1) + record_id=$(echo "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1) _debug "record_id" "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id to remove." @@ -140,7 +140,7 @@ _get_root() { _debug p "$p" if _contains "$response" "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1) + _domain_id=$(echo "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1) if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 842f030355ee9013b6ba6861d347ef15a4e546e3 Mon Sep 17 00:00:00 2001 From: Adrian Almenar Date: Tue, 4 Dec 2018 14:36:28 +0100 Subject: [PATCH 0063/2234] Revert change --- dnsapi/dns_neodigit.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_neodigit.sh b/dnsapi/dns_neodigit.sh index d87845ad..64ea8786 100644 --- a/dnsapi/dns_neodigit.sh +++ b/dnsapi/dns_neodigit.sh @@ -17,7 +17,7 @@ dns_neodigit_add() { fulldomain=$1 txtvalue=$2 - NEODIGIT_API_TOKEN="$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" + NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" if [ -z "$NEODIGIT_API_TOKEN" ]; then NEODIGIT_API_TOKEN="" _err "You haven't specified a Token api key." @@ -73,7 +73,7 @@ dns_neodigit_rm() { fulldomain=$1 txtvalue=$2 - NEODIGIT_API_TOKEN="$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" + NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}" if [ -z "$NEODIGIT_API_TOKEN" ]; then NEODIGIT_API_TOKEN="" _err "You haven't specified a Token api key." From 7ff525468f0fda2c29e3aea51e8cc425a1204acc Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Wed, 5 Dec 2018 03:01:50 +0800 Subject: [PATCH 0064/2234] Arch Linux package acme.sh is now in [community] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4ea5c6e..d8069405 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) - [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709) - [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html) - [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297) -- [archlinux](https://aur.archlinux.org/packages/acme.sh-git/) +- [archlinux](https://www.archlinux.org/packages/community/any/acme.sh) - [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient) - [CentOS Web Panel](http://centos-webpanel.com/) - [lnmp.org](https://lnmp.org/) From 9841063df9dd40120d32ed8185defaee9ef8a8e6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 6 Dec 2018 22:05:26 +0800 Subject: [PATCH 0065/2234] fix nginx mode --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 392079fb..ff241e6e 100755 --- a/acme.sh +++ b/acme.sh @@ -2839,7 +2839,7 @@ _isRealNginxConf() { _skip_ssl=1 for _listen_i in $(echo "$_seg_n" | tr "\t" ' ' | grep "^ *listen" | tr -d " "); do if [ "$_listen_i" ]; then - if [ "$(echo "$_listen_i" | _egrep_o "listen.*ssl[ |;]")" ]; then + if [ "$(echo "$_listen_i" | _egrep_o "listen.*ssl")" ]; then _debug2 "$_listen_i is ssl" else _debug2 "$_listen_i is plain text" From c84466b1319f5648b420b5670cf15d686df4646a Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Mon, 10 Dec 2018 16:55:21 +0300 Subject: [PATCH 0066/2234] Write certs in Vault for Fabio load balancer --- deploy/vault_cli.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/deploy/vault_cli.sh b/deploy/vault_cli.sh index 79c25aa2..b93fdd51 100644 --- a/deploy/vault_cli.sh +++ b/deploy/vault_cli.sh @@ -49,9 +49,13 @@ vault_cli_deploy() { return 1 fi - $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 - $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 - $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 - $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 + if [ -n "$FABIO" ]; then + $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1 + else + $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 + $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 + $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 + $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 + fi } From 9f067d7f56eba9c1b301686d2a89419d9e993ea1 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Mon, 10 Dec 2018 18:17:18 +0300 Subject: [PATCH 0067/2234] Deploy to Hashicorp Vault docs --- deploy/README.md | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/deploy/README.md b/deploy/README.md index 5c03ce6a..cec7d773 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -295,4 +295,40 @@ You can then deploy the certificate as follows ```sh acme.sh --deploy -d www.mydomain.com --deploy-hook gitlab -``` \ No newline at end of file +``` + +## 12. Deploy your cert to Hashicorp Vault + +```sh +export VAULT_PREFIX="acme" +``` + +You can then deploy the certificate as follows + +```sh +acme.sh --deploy -d www.mydomain.com --deploy-hook vault_cli +``` + +Your certs will be saved in Vault using this structure: + +```sh +vault write "${VAULT_PREFIX}/${domain}/cert.pem" value=@"..." +vault write "${VAULT_PREFIX}/${domain}/cert.key" value=@"..." +vault write "${VAULT_PREFIX}/${domain}/chain.pem" value=@"..." +vault write "${VAULT_PREFIX}/${domain}/fullchain.pem" value=@"..." +``` + +You might be using Fabio load balancer (which can get certs from +Vault). It needs a bit different structure of your certs in Vault. It +gets certs only from keys that were saved in `prefix/domain`, like this: + +```bash +vault write /www.domain.com cert=@cert.pem key=@key.pem +``` + +If you want to save certs in Vault this way just set "FABIO" env +variable to anything (ex: "1") before running `acme.sh`: + +```sh +export FABIO="1" +``` From a43545c6ea9f79df2acfa1bc10db8f44e803b197 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Dec 2018 19:11:56 +0800 Subject: [PATCH 0068/2234] fix https://github.com/Neilpang/acme.sh/issues/1959 --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 944956ad..f50ab498 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -181,7 +181,7 @@ _get_root() { fi if _contains "$_cf_zones" "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(printf "%s\n" "$_cf_zones" | _egrep_o "\[.\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") + _domain_id=$(echo "$_cf_zones" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "^\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 5431d051685bc6c0d7cd1341dc5111892715ee19 Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Thu, 13 Dec 2018 01:22:44 -0500 Subject: [PATCH 0069/2234] dnsapi nsupdate: Add nsupdate debug option When debug is enabled, also use nsupdate's debug logging so that the user can see potential issues with the nsupdate transaction. Signed-off-by: Daniel F. Dickinson --- dnsapi/dns_nsupdate.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 555f4d29..609785e0 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -14,7 +14,9 @@ dns_nsupdate_add() { _saveaccountconf NSUPDATE_SERVER_PORT "${NSUPDATE_SERVER_PORT}" _saveaccountconf NSUPDATE_KEY "${NSUPDATE_KEY}" _info "adding ${fulldomain}. 60 in txt \"${txtvalue}\"" - nsupdate -k "${NSUPDATE_KEY}" < Date: Thu, 13 Dec 2018 01:23:53 -0500 Subject: [PATCH 0070/2234] dnsapi: Add option to set zone for nsupdate Some DNS servers for which dns_nsupdate.sh is applicable (such as dyn.com's 'Standard DNS' TSIG update mechanism), require that the zone be set during the nsupdate transaction. Therefore we add a new environment variable NSUPDATE_ZONE which is used to set the zone for the DNS TSIG transaction. Signed-off-by: Daniel F. Dickinson --- dnsapi/README.md | 6 +++++- dnsapi/dns_nsupdate.sh | 23 +++++++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index afe1f7f4..30c1be53 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -146,13 +146,17 @@ Finally, make the DNS server and update Key available to `acme.sh` export NSUPDATE_SERVER="dns.example.com" export NSUPDATE_KEY="/path/to/your/nsupdate.key" ``` +and optionally (depending on DNS server) +``` +export NSUPDATE_ZONE="example.com" +``` Ok, let's issue a cert now: ``` acme.sh --issue --dns dns_nsupdate -d example.com -d www.example.com ``` -The `NSUPDATE_SERVER` and `NSUPDATE_KEY` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +The `NSUPDATE_SERVER`, `NSUPDATE_KEY`, and `NSUPDATE_ZONE` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. ## 8. Use LuaDNS domain API diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 609785e0..8b479f98 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -13,14 +13,24 @@ dns_nsupdate_add() { _saveaccountconf NSUPDATE_SERVER "${NSUPDATE_SERVER}" _saveaccountconf NSUPDATE_SERVER_PORT "${NSUPDATE_SERVER_PORT}" _saveaccountconf NSUPDATE_KEY "${NSUPDATE_KEY}" + _saveaccountconf NSUPDATE_ZONE "${NSUPDATE_ZONE}" _info "adding ${fulldomain}. 60 in txt \"${txtvalue}\"" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D" - nsupdate -k "${NSUPDATE_KEY}" $nsdebug < Date: Sun, 16 Dec 2018 21:10:22 +0800 Subject: [PATCH 0071/2234] add more debug info https://github.com/Neilpang/acme.sh/issues/1932 --- acme.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index ff241e6e..5cfcb382 100755 --- a/acme.sh +++ b/acme.sh @@ -1516,7 +1516,8 @@ _calcjwk() { JWK_HEADERPLACE_PART1='{"nonce": "' JWK_HEADERPLACE_PART2='", "alg": "ES'$__ECC_KEY_LEN'"' else - _err "Only RSA or EC key is supported." + _err "Only RSA or EC key is supported. keyfile=$keyfile" + _debug2 "$(cat "$keyfile")" return 1 fi From 2b9ebd666280cc7832bce31d0b282df7f4d276d7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 17 Dec 2018 23:02:02 +0800 Subject: [PATCH 0072/2234] fix showcsr https://github.com/Neilpang/acme.sh/issues/1968 --- acme.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 5cfcb382..6264da01 100755 --- a/acme.sh +++ b/acme.sh @@ -1134,12 +1134,17 @@ _readSubjectAltNamesFromCSR() { if _contains "$_dnsAltnames," "DNS:$_csrsubj,"; then _debug "AltNames contains subject" - _dnsAltnames="$(printf "%s" "$_dnsAltnames," | sed "s/DNS:$_csrsubj,//g")" + _excapedAlgnames="$(echo "$_dnsAltnames" | tr '*' '#')" + _debug _excapedAlgnames "$_excapedAlgnames" + _escapedSubject="$(echo "$_csrsubj" | tr '*' '#')" + _debug _escapedSubject "$_escapedSubject" + _dnsAltnames="$(echo "$_excapedAlgnames," | sed "s/DNS:$_escapedSubject,//g" | tr '#' '*' | sed "s/,\$//g")" + _debug _dnsAltnames "$_dnsAltnames" else _debug "AltNames doesn't contain subject" fi - printf "%s" "$_dnsAltnames" | sed "s/DNS://g" + echo "$_dnsAltnames" | sed "s/DNS://g" } #_csrfile From 08681f4a8b9ea066b00e5f890b47bfbfe3fb5b3e Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 18 Dec 2018 19:28:38 +0800 Subject: [PATCH 0073/2234] support tls-alpn-01 https://github.com/Neilpang/acme.sh/issues/1675#issuecomment-447857756 --- acme.sh | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 6264da01..efd64467 100755 --- a/acme.sh +++ b/acme.sh @@ -37,6 +37,7 @@ VTYPE_HTTP="http-01" VTYPE_DNS="dns-01" VTYPE_TLS="tls-sni-01" VTYPE_TLS2="tls-sni-02" +VTYPE_ALPN="tls-alpn-01" LOCAL_ANY_ADDRESS="0.0.0.0" @@ -48,6 +49,7 @@ NO_VALUE="no" W_TLS="tls" W_DNS="dns" +W_ALPN="alpn" DNS_ALIAS_PREFIX="=" MODE_STATELESS="stateless" @@ -1046,7 +1048,7 @@ _idn() { fi } -#_createcsr cn san_list keyfile csrfile conf +#_createcsr cn san_list keyfile csrfile conf acmeValidationv1 _createcsr() { _debug _createcsr domain="$1" @@ -1054,6 +1056,7 @@ _createcsr() { csrkey="$3" csr="$4" csrconf="$5" + acmeValidationv1="$6" _debug2 domain "$domain" _debug2 domainlist "$domainlist" _debug2 csrkey "$csrkey" @@ -1062,7 +1065,9 @@ _createcsr() { printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment" >"$csrconf" - if [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then + if [ "$acmeValidationv1" ]; then + printf -- "\nsubjectAltName=DNS:$domainlist" >>"$csrconf" + elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then #single domain _info "Single domain" "$domain" printf -- "\nsubjectAltName=DNS:$domain" >>"$csrconf" @@ -1084,6 +1089,10 @@ _createcsr() { printf -- "\nbasicConstraints = CA:FALSE\n1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05" >>"$csrconf" fi + if [ "$acmeValidationv1" ]; then + printf "\n1.3.6.1.5.5.7.1.30.1=critical,DER:04:20:${acmeValidationv1}" >> "${csrconf}" + fi + _csr_cn="$(_idn "$domain")" _debug2 _csr_cn "$_csr_cn" if _contains "$(uname -a)" "MINGW"; then @@ -2107,7 +2116,7 @@ _sleep() { fi } -# _starttlsserver san_a san_b port content _ncaddr +# _starttlsserver san_a san_b port content _ncaddr acmeValidationv1 _starttlsserver() { _info "Starting tls server." san_a="$1" @@ -2115,10 +2124,12 @@ _starttlsserver() { port="$3" content="$4" opaddr="$5" + acmeValidationv1="$6" _debug san_a "$san_a" _debug san_b "$san_b" _debug port "$port" + _debug acmeValidationv1 "$acmeValidationv1" #create key TLS_KEY if ! _createkey "2048" "$TLS_KEY"; then @@ -2131,7 +2142,7 @@ _starttlsserver() { if [ "$san_b" ]; then alt="$alt,$san_b" fi - if ! _createcsr "tls.acme.sh" "$alt" "$TLS_KEY" "$TLS_CSR" "$TLS_CONF"; then + if ! _createcsr "tls.acme.sh" "$alt" "$TLS_KEY" "$TLS_CSR" "$TLS_CONF" "$acmeValidationv1"; then _err "Create tls validation csr error." return 1 fi @@ -2157,6 +2168,10 @@ _starttlsserver() { __S_OPENSSL="$__S_OPENSSL -6" fi + if [ "$acmeValidationv1" ]; then + __S_OPENSSL="$__S_OPENSSL -alpn acme-tls/1" + fi + _debug "$__S_OPENSSL" if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then $__S_OPENSSL -tlsextdebug & @@ -3067,8 +3082,8 @@ _on_before_issue() { _savedomainconf "Le_HTTPPort" "$Le_HTTPPort" fi _checkport="$Le_HTTPPort" - elif [ "$_currentRoot" = "$W_TLS" ]; then - _info "Standalone tls mode." + elif [ "$_currentRoot" = "$W_TLS" ] || [ "$_currentRoot" = "$W_ALPN" ]; then + _info "Standalone tls/alpn mode." if [ -z "$Le_TLSPort" ]; then Le_TLSPort=443 else @@ -3694,6 +3709,10 @@ $_authorizations_map" fi fi + if [ "$_currentRoot" = "$W_ALPN" ]; then + vtype="$VTYPE_ALPN" + fi + if [ "$ACME_VERSION" = "2" ]; then response="$(echo "$_authorizations_map" | grep "^$d," | sed "s/$d,//")" _debug2 "response" "$response" @@ -4007,6 +4026,16 @@ $_authorizations_map" _on_issue_err "$_post_hook" "$vlist" return 1 fi + elif [ "$vtype" = "$VTYPE_ALPN" ]; then + acmevalidationv1="$(printf "%s" "$keyauthorization" | _digest "sha256" "hex")" + _debug acmevalidationv1 "$acmevalidationv1" + if ! _starttlsserver "$d" "" "$Le_TLSPort" "$keyauthorization" "$_ncaddr" "$acmevalidationv1"; then + _err "Start tls server error." + _clearupwebbroot "$_currentRoot" "$removelevel" "$token" + _clearup + _on_issue_err "$_post_hook" "$vlist" + return 1 + fi fi if ! __trigger_validation "$uri" "$keyauthorization"; then @@ -5469,6 +5498,7 @@ Parameters: --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for secure. --webroot, -w /path/to/webroot Specifies the web root folder for web root mode. --standalone Use standalone mode. + --alpn Use standalone alpn mode. --stateless Use stateless mode, see: $_STATELESS_WIKI --apache Use apache mode. --dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api. @@ -5823,6 +5853,14 @@ _process() { _webroot="$_webroot,$wvalue" fi ;; + --alpn) + wvalue="$W_ALPN" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; --stateless) wvalue="$MODE_STATELESS" if [ -z "$_webroot" ]; then From 79a0a66f1f2f547464bec4ee7ab876a664a2ed78 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 18 Dec 2018 20:18:18 +0800 Subject: [PATCH 0074/2234] support --tlsport --- acme.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/acme.sh b/acme.sh index efd64467..5ce97f88 100755 --- a/acme.sh +++ b/acme.sh @@ -5529,6 +5529,7 @@ Parameters: --accountkey Specifies the account key path, only valid for the '--install' command. --days Specifies the days to renew the cert when using '--issue' command. The max value is $MAX_RENEW days. --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. + --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer. --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses. --listraw Only used for '--list' command, list the certs in raw format. --stopRenewOnError, -se Only valid for '--renew-all' command. Stop if one cert has error in renewal. @@ -5985,6 +5986,11 @@ _process() { Le_HTTPPort="$_httpport" shift ;; + --tlsport) + _tlsport="$2" + Le_TLSPort="$_tlsport" + shift + ;; --listraw) _listraw="raw" ;; From f99ca918db8e4587ec1437c6815a32a8de49c42f Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 18 Dec 2018 20:33:33 +0800 Subject: [PATCH 0075/2234] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 5ce97f88..acda4bee 100755 --- a/acme.sh +++ b/acme.sh @@ -1090,7 +1090,7 @@ _createcsr() { fi if [ "$acmeValidationv1" ]; then - printf "\n1.3.6.1.5.5.7.1.30.1=critical,DER:04:20:${acmeValidationv1}" >> "${csrconf}" + printf "\n1.3.6.1.5.5.7.1.30.1=critical,DER:04:20:${acmeValidationv1}" >>"${csrconf}" fi _csr_cn="$(_idn "$domain")" From 67d3e8d04968e8beaaa463639cd5989edf5fd9b7 Mon Sep 17 00:00:00 2001 From: Ivru Date: Thu, 20 Dec 2018 16:07:05 +0100 Subject: [PATCH 0076/2234] Add Exoscape API support for DNSAPI --- README.md | 1 + dnsapi/README.md | 18 +++++ dnsapi/dns_exoscale.sh | 170 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100755 dnsapi/dns_exoscale.sh diff --git a/README.md b/README.md index 033711f3..6a1cf3a4 100644 --- a/README.md +++ b/README.md @@ -330,6 +330,7 @@ You don't have to do anything manually! 1. MyDNS.JP API (https://www.mydns.jp/) 1. hosting.de (https://www.hosting.de) 1. Neodigit.net API (https://www.neodigit.net) +1. Exoscale.com API (https://www.exoscale.com/) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index afe1f7f4..89cf3975 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1076,6 +1076,24 @@ acme.sh --issue --dns dns_neodigit -d example.com -d www.example.com Neodigit API Token will be saved in `~/.acme.sh/account.conf` and will be used when needed. +## 57. Use Exoscale API + +Create an API key and secret key in the Exoscale account section + +Set your API and secret key: + +``` +export EXOSCALE_API_KEY='xxx' +export EXOSCALE_SECRET_KEY='xxx' +``` + +Now, let's issue a cert: +``` +acme.sh --issue --dns dns_netcup -d example.com -d www.example.com +``` + +The `EXOSCALE_API_KEY` and `EXOSCALE_SECRET_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_exoscale.sh b/dnsapi/dns_exoscale.sh new file mode 100755 index 00000000..f9ffff24 --- /dev/null +++ b/dnsapi/dns_exoscale.sh @@ -0,0 +1,170 @@ +#!/usr/bin/env sh + +EXOSCALE_API=https://api.exoscale.com/dns/v1 + + +######## Public functions ##################### + +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record +dns_exoscale_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _checkAuth; then + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + if _exoscale_rest POST "domains/$_domain_id/records" "{\"record\":{\"name\":\"$_sub_domain\",\"record_type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":120}}" "$_domain_token"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + return 0 + fi + fi + _err "Add txt record error." + return 1 + +} + +# Usage: fulldomain txtvalue +# Used to remove the txt record after validation +dns_exoscale_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _checkAuth; then + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _exoscale_rest GET "domains/${_domain_id}/records?type=TXT&name=$_sub_domain" "" "$_domain_token" + if _contains "$response" "\"name\":\"$_sub_domain\"" >/dev/null; then + _record_id=$(echo "$response" | tr '{' "\n" | grep "\"content\":\"$txtvalue\"" | _egrep_o "\"id\":[^,]+" | _head_n 1 | cut -d : -f 2 | tr -d \") + fi + + if [ -z "$_record_id" ] ; then + _err "Can not get record id to remove." + return 1 + fi + + _debug "Deleting record $_record_id" + + if ! _exoscale_rest DELETE "domains/$_domain_id/records/$_record_id" "" "$_domain_token"; then + _err "Delete record error." + return 1 + fi + + return 0 +} + + +#################### Private functions below ################################## + +_checkAuth() { + EXOSCALE_API_KEY="${EXOSCALE_API_KEY:-$(_readaccountconf_mutable EXOSCALE_API_KEY)}" + EXOSCALE_SECRET_KEY="${EXOSCALE_SECRET_KEY:-$(_readaccountconf_mutable EXOSCALE_SECRET_KEY)}" + + if [ -z "$EXOSCALE_API_KEY" ] || [ -z "$EXOSCALE_SECRET_KEY" ]; then + EXOSCALE_API_KEY="" + EXOSCALE_SECRET_KEY="" + _err "You don't specify Exoscale application key and application secret yet." + _err "Please create you key and try again." + return 1 + fi + + _saveaccountconf_mutable EXOSCALE_API_KEY "$EXOSCALE_API_KEY" + _saveaccountconf_mutable EXOSCALE_SECRET_KEY "$EXOSCALE_SECRET_KEY" + + return 0 +} + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=sdjkglgdfewsdfg +# _domain_token=sdjkglgdfewsdfg +_get_root() { + + if ! _exoscale_rest GET "domains"; then + return 1 + fi + + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + _domain_id=$(echo "$response" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "\"id\":[^,]+" | _head_n 1 | cut -d : -f 2 | tr -d \") + _domain_token=$(echo "$response" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "\"token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if [ "$_domain_token" ] && [ "$_domain_id" ] ; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +# returns response +_exoscale_rest() { + method=$1 + path="$2" + data="$3" + token="$4" + request_url="$EXOSCALE_API/$path" + _debug "$path" + + export _H1="Accept: application/json" + + if [ "$token" ]; then + export _H2="X-DNS-Domain-Token: $token" + else + export _H2="X-DNS-Token: $EXOSCALE_API_KEY:$EXOSCALE_SECRET_KEY" + fi + + if [ "$data" ] || [ "$method" = "DELETE" ]; then + _H3="Content-Type: application/json" + _debug data "$data" + response="$(_post "$data" "$request_url" "" "$method")" + else + response="$(_get "$request_url" "" "" "$method")" + fi + + if [ "$?" != "0" ]; then + _err "error $request_url" + return 1 + fi + _debug2 response "$response" + return 0 +} From eea9aaf9404d6f62c722e96c2d064bcab21347b4 Mon Sep 17 00:00:00 2001 From: Ivru Date: Thu, 20 Dec 2018 16:24:08 +0100 Subject: [PATCH 0077/2234] Fix typos --- dnsapi/dns_exoscale.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_exoscale.sh b/dnsapi/dns_exoscale.sh index f9ffff24..a837b79d 100755 --- a/dnsapi/dns_exoscale.sh +++ b/dnsapi/dns_exoscale.sh @@ -61,7 +61,7 @@ dns_exoscale_rm() { _record_id=$(echo "$response" | tr '{' "\n" | grep "\"content\":\"$txtvalue\"" | _egrep_o "\"id\":[^,]+" | _head_n 1 | cut -d : -f 2 | tr -d \") fi - if [ -z "$_record_id" ] ; then + if [ -z "$_record_id" ]; then _err "Can not get record id to remove." return 1 fi @@ -123,7 +123,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\"" >/dev/null; then _domain_id=$(echo "$response" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "\"id\":[^,]+" | _head_n 1 | cut -d : -f 2 | tr -d \") _domain_token=$(echo "$response" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "\"token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") - if [ "$_domain_token" ] && [ "$_domain_id" ] ; then + if [ "$_domain_token" ] && [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h return 0 From 8e43b86f06d244ed6635054cb768c45e86f16bdd Mon Sep 17 00:00:00 2001 From: Ivru Date: Thu, 20 Dec 2018 16:30:02 +0100 Subject: [PATCH 0078/2234] Export header _H3 --- dnsapi/dns_exoscale.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_exoscale.sh b/dnsapi/dns_exoscale.sh index a837b79d..bb433ec3 100755 --- a/dnsapi/dns_exoscale.sh +++ b/dnsapi/dns_exoscale.sh @@ -154,7 +154,7 @@ _exoscale_rest() { fi if [ "$data" ] || [ "$method" = "DELETE" ]; then - _H3="Content-Type: application/json" + export _H3="Content-Type: application/json" _debug data "$data" response="$(_post "$data" "$request_url" "" "$method")" else From 405173a0b4176d8858f7d31aaf570a27cafb1a90 Mon Sep 17 00:00:00 2001 From: Ivru Date: Thu, 20 Dec 2018 16:37:11 +0100 Subject: [PATCH 0079/2234] Remove extraneous blank lines --- dnsapi/dns_exoscale.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_exoscale.sh b/dnsapi/dns_exoscale.sh index bb433ec3..ccf05fc5 100755 --- a/dnsapi/dns_exoscale.sh +++ b/dnsapi/dns_exoscale.sh @@ -2,7 +2,6 @@ EXOSCALE_API=https://api.exoscale.com/dns/v1 - ######## Public functions ##################### # Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -76,7 +75,6 @@ dns_exoscale_rm() { return 0 } - #################### Private functions below ################################## _checkAuth() { From 9a473640fb2341a5c9e56ffcb645200c1725392c Mon Sep 17 00:00:00 2001 From: "Aaron W. Swenson" Date: Thu, 20 Dec 2018 11:00:10 -0500 Subject: [PATCH 0080/2234] Revert "Update Linode API to v4" This reverts commit 9a27b389765ac6d7a256333e9e1f6fe3c4b92e08. Turns out, the Cloud Manager is not backward compatible, nor is the Classic Manager forward compatible. --- dnsapi/README.md | 13 ++----------- dnsapi/dns_linode.sh | 39 +++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 30c1be53..603bd72a 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -268,18 +268,9 @@ when needed. ## 14. Use Linode domain API First you need to login to your Linode account to get your API Key. +[https://manager.linode.com/profile/api](https://manager.linode.com/profile/api) - * [Classic Manager](https://manager.linode.com/profile/api) - - Under "Add an API key", Give the new key a "Label" (we recommend *ACME*), - set the expiry to never, "Create API Key", and copy the new key into the `LINODE_API_KEY` command - below. - - * [Cloud Manager](https://cloud.linode.com/profile/tokens) - - Click on "Add a Personal Access Token". Give the new key a "Label" (we - recommend *ACME*), give it Read/Write access to "Domains". "Submit", and - copy the new key into the `LINODE_API_KEY` command below. +Then add an API key with label *ACME* and copy the new key. ```sh export LINODE_API_KEY="..." diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index d03e6c47..ead5b164 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -2,7 +2,7 @@ #Author: Philipp Grosswiler -LINODE_API_URL="https://api.linode.com/v4/domains" +LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action=" ######## Public functions ##################### @@ -27,14 +27,10 @@ dns_linode_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _payload="{ - \"type\": \"TXT\", - \"name\": \"$_sub_domain\", - \"target\": \"$txtvalue\" - }" + _parameters="&DomainID=$_domain_id&Type=TXT&Name=$_sub_domain&Target=$txtvalue" - if _rest POST "/$_domain_id/records" "$_payload" && [ -n "$response" ]; then - _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + if _rest GET "domain.resource.create" "$_parameters" && [ -n "$response" ]; then + _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) _debug _resource_id "$_resource_id" if [ -z "$_resource_id" ]; then @@ -69,21 +65,25 @@ dns_linode_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - if _rest GET "/$_domain_id/records" && [ -n "$response" ]; then + _parameters="&DomainID=$_domain_id" + + if _rest GET "domain.resource.list" "$_parameters" && [ -n "$response" ]; then response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" - resource="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$_sub_domain\".*}")" + resource="$(echo "$response" | _egrep_o "{.*\"NAME\":\s*\"$_sub_domain\".*}")" if [ "$resource" ]; then - _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"RESOURCEID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_resource_id" ]; then _debug _resource_id "$_resource_id" - if _rest DELETE "/$_domain_id/records/$_resource_id" && [ -n "$response" ]; then - # On 200/OK, empty set is returned. Check for error, if any. - _error_response=$(printf "%s\n" "$response" | _egrep_o "\"errors\"" | cut -d : -f 2 | tr -d " " | _head_n 1) + _parameters="&DomainID=$_domain_id&ResourceID=$_resource_id" - if [ -n "$_error_response" ]; then - _err "Error deleting the domain resource: $_error_response" + if _rest GET "domain.resource.delete" "$_parameters" && [ -n "$response" ]; then + _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + _debug _resource_id "$_resource_id" + + if [ -z "$_resource_id" ]; then + _err "Error deleting the domain resource." return 1 fi @@ -127,7 +127,7 @@ _get_root() { i=2 p=1 - if _rest GET; then + if _rest GET "domain.list"; then response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -137,9 +137,9 @@ _get_root() { return 1 fi - hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\":\s*\"$h\".*}")" + hostedzone="$(echo "$response" | _egrep_o "{.*\"DOMAIN\":\s*\"$h\".*}")" if [ "$hostedzone" ]; then - _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"DOMAINID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -165,7 +165,6 @@ _rest() { export _H1="Accept: application/json" export _H2="Content-Type: application/json" - export _H3="Authorization: Bearer $LINODE_API_KEY" if [ "$mtd" != "GET" ]; then # both POST and DELETE. From c8c1140f15d6c96d83bd3734fcc1604e0caa408e Mon Sep 17 00:00:00 2001 From: "Aaron W. Swenson" Date: Thu, 20 Dec 2018 11:01:34 -0500 Subject: [PATCH 0081/2234] Linode API v4 Redo The Cloud and Classic Manager work with different APIs, and so require a separate module, which we introduce here. The README has also been modified to state that the two are separate and incompatible, and provides instructions on using either. --- dnsapi/README.md | 48 +++++++++-- dnsapi/dns_linode_v4.sh | 185 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+), 5 deletions(-) create mode 100755 dnsapi/dns_linode_v4.sh diff --git a/dnsapi/README.md b/dnsapi/README.md index 603bd72a..df6db111 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -267,16 +267,26 @@ when needed. ## 14. Use Linode domain API -First you need to login to your Linode account to get your API Key. -[https://manager.linode.com/profile/api](https://manager.linode.com/profile/api) +The tokens created in the classic manager and cloud manager are incompatible +with one another. While the classic manager makes an all or nothing API, the +newer cloud manager interface promises to produce API keys with a finer +permission system. However, either way works just fine. -Then add an API key with label *ACME* and copy the new key. +### Classic Manager ### + +Classic Manager: https://manager.linode.com/profile/api + +First you need to login to your Linode account to get your API Key. + +Then add an API key with label *ACME* and copy the new key into the following +command. ```sh export LINODE_API_KEY="..." ``` -Due to the reload time of any changes in the DNS records, we have to use the `dnssleep` option to wait at least 15 minutes for the changes to take effect. +Due to the reload time of any changes in the DNS records, we have to use the +`dnssleep` option to wait at least 15 minutes for the changes to take effect. Ok, let's issue a cert now: @@ -284,7 +294,35 @@ Ok, let's issue a cert now: acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.com ``` -The `LINODE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +The `LINODE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be +reused when needed. + +### Cloud Manager ### + +Cloud Manager: https://cloud.linode.com/profile/tokens + +First you need to login to your Linode account to get your API Key. + + 1. Click on "Add a Personal Access Token". + 2. Give the new key a "Label" (we recommend *ACME*) + 3. Give it Read/Write access to "Domains" + 4. "Submit" and copy the new key into the `LINODE_V4_API_KEY` command below. + +```sh +export LINODE_V4_API_KEY="..." +``` + +Due to the reload time of any changes in the DNS records, we have to use the +`dnssleep` option to wait at least 15 minutes for the changes to take effect. + +Ok, let's issue a cert now: + +```sh +acme.sh --issue --dns dns_linode_v4 --dnssleep 900 -d example.com -d www.example.com +``` + +The `LINODE_V4_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be +reused when needed. ## 15. Use FreeDNS diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh new file mode 100755 index 00000000..dfa1a651 --- /dev/null +++ b/dnsapi/dns_linode_v4.sh @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +#Original Author: Philipp Grosswiler +#v4 Update Author: Aaron W. Swenson + +LINODE_V4_API_URL="https://api.linode.com/v4/domains" + +######## Public functions ##################### + +#Usage: dns_linode_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_linode_add() { + fulldomain="${1}" + txtvalue="${2}" + + if ! _Linode_API; then + return 1 + fi + + _info "Using Linode" + _debug "Calling: dns_linode_add() '${fulldomain}' '${txtvalue}'" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Domain does not exist." + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _payload="{ + \"type\": \"TXT\", + \"name\": \"$_sub_domain\", + \"target\": \"$txtvalue\" + }" + + if _rest POST "/$_domain_id/records" "$_payload" && [ -n "$response" ]; then + _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + _debug _resource_id "$_resource_id" + + if [ -z "$_resource_id" ]; then + _err "Error adding the domain resource." + return 1 + fi + + _info "Domain resource successfully added." + return 0 + fi + + return 1 +} + +#Usage: dns_linode_rm _acme-challenge.www.domain.com +dns_linode_rm() { + fulldomain="${1}" + + if ! _Linode_API; then + return 1 + fi + + _info "Using Linode" + _debug "Calling: dns_linode_rm() '${fulldomain}'" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Domain does not exist." + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + if _rest GET "/$_domain_id/records" && [ -n "$response" ]; then + response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" + + resource="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$_sub_domain\".*}")" + if [ "$resource" ]; then + _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + if [ "$_resource_id" ]; then + _debug _resource_id "$_resource_id" + + if _rest DELETE "/$_domain_id/records/$_resource_id" && [ -n "$response" ]; then + # On 200/OK, empty set is returned. Check for error, if any. + _error_response=$(printf "%s\n" "$response" | _egrep_o "\"errors\"" | cut -d : -f 2 | tr -d " " | _head_n 1) + + if [ -n "$_error_response" ]; then + _err "Error deleting the domain resource: $_error_response" + return 1 + fi + + _info "Domain resource successfully deleted." + return 0 + fi + fi + + return 1 + fi + + return 0 + fi + + return 1 +} + +#################### Private functions below ################################## + +_Linode_API() { + if [ -z "$LINODE_V4_API_KEY" ]; then + LINODE_V4_API_KEY="" + + _err "You didn't specify the Linode v4 API key yet." + _err "Please create your key and try again." + + return 1 + fi + + _saveaccountconf LINODE_V4_API_KEY "$LINODE_V4_API_KEY" +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=12345 +_get_root() { + domain=$1 + i=2 + p=1 + + if _rest GET; then + response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\":\s*\"$h\".*}")" + if [ "$hostedzone" ]; then + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + fi + return 1 +} + +#method method action data +_rest() { + mtd="$1" + ep="$2" + data="$3" + + _debug mtd "$mtd" + _debug ep "$ep" + + export _H1="Accept: application/json" + export _H2="Content-Type: application/json" + export _H3="Authorization: Bearer $LINODE_V4_API_KEY" + + if [ "$mtd" != "GET" ]; then + # both POST and DELETE. + _debug data "$data" + response="$(_post "$data" "$LINODE_V4_API_URL$ep" "" "$mtd")" + else + response="$(_get "$LINODE_V4_API_URL$ep$data")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 0b363a5c98d56df8c45a689ccc55087484f64306 Mon Sep 17 00:00:00 2001 From: Ne-Lexa Date: Mon, 24 Dec 2018 13:33:25 +0300 Subject: [PATCH 0082/2234] removed the _clearaccountconf() call for erroneous requests --- dnsapi/dns_internetbs.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/dnsapi/dns_internetbs.sh b/dnsapi/dns_internetbs.sh index 05a1adae..d25c8324 100755 --- a/dnsapi/dns_internetbs.sh +++ b/dnsapi/dns_internetbs.sh @@ -41,8 +41,6 @@ dns_internetbs_add() { if ! _contains "$response" "\"status\":\"SUCCESS\""; then _err "ERROR add TXT record" _err "$response" - _clearaccountconf INTERNETBS_API_KEY - _clearaccountconf INTERNETBS_API_PASSWORD return 1 fi @@ -75,8 +73,6 @@ dns_internetbs_rm() { if ! _contains "$response" "\"status\":\"SUCCESS\""; then _err "ERROR list dns records" _err "$response" - _clearaccountconf INTERNETBS_API_KEY - _clearaccountconf INTERNETBS_API_PASSWORD return 1 fi @@ -89,8 +85,6 @@ dns_internetbs_rm() { if ! _contains "$response" "\"status\":\"SUCCESS\""; then _err "ERROR remove dns record" _err "$response" - _clearaccountconf INTERNETBS_API_KEY - _clearaccountconf INTERNETBS_API_PASSWORD return 1 fi @@ -118,8 +112,6 @@ _get_root() { if ! _contains "$response" "\"status\":\"SUCCESS\""; then _err "ERROR fetch domain list" _err "$response" - _clearaccountconf INTERNETBS_API_KEY - _clearaccountconf INTERNETBS_API_PASSWORD return 1 fi From b7b94e38ac7c3183d3c6d0bd8709dd9d8fdd589d Mon Sep 17 00:00:00 2001 From: Ne-Lexa Date: Mon, 24 Dec 2018 14:59:14 +0300 Subject: [PATCH 0083/2234] support change account conf from env --- dnsapi/dns_internetbs.sh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_internetbs.sh b/dnsapi/dns_internetbs.sh index d25c8324..ae6b9e1e 100755 --- a/dnsapi/dns_internetbs.sh +++ b/dnsapi/dns_internetbs.sh @@ -7,6 +7,7 @@ #INTERNETBS_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" #INTERNETBS_API_PASSWORD="sdfsdfsdfljlbjkljlkjsdfoiwje" + INTERNETBS_API_URL="https://api.internet.bs" ######## Public functions ##################### @@ -16,6 +17,9 @@ dns_internetbs_add() { fulldomain=$1 txtvalue=$2 + INTERNETBS_API_KEY="${INTERNETBS_API_KEY:-$(_readaccountconf_mutable INTERNETBS_API_KEY)}" + INTERNETBS_API_PASSWORD="${INTERNETBS_API_PASSWORD:-$(_readaccountconf_mutable INTERNETBS_API_PASSWORD)}" + if [ -z "$INTERNETBS_API_KEY" ] || [ -z "$INTERNETBS_API_PASSWORD" ]; then INTERNETBS_API_KEY="" INTERNETBS_API_PASSWORD="" @@ -24,8 +28,8 @@ dns_internetbs_add() { return 1 fi - _saveaccountconf INTERNETBS_API_KEY "$INTERNETBS_API_KEY" - _saveaccountconf INTERNETBS_API_PASSWORD "$INTERNETBS_API_PASSWORD" + _saveaccountconf_mutable INTERNETBS_API_KEY "$INTERNETBS_API_KEY" + _saveaccountconf_mutable INTERNETBS_API_PASSWORD "$INTERNETBS_API_PASSWORD" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -57,6 +61,17 @@ dns_internetbs_rm() { fulldomain=$1 txtvalue=$2 + INTERNETBS_API_KEY="${INTERNETBS_API_KEY:-$(_readaccountconf_mutable INTERNETBS_API_KEY)}" + INTERNETBS_API_PASSWORD="${INTERNETBS_API_PASSWORD:-$(_readaccountconf_mutable INTERNETBS_API_PASSWORD)}" + + if [ -z "$INTERNETBS_API_KEY" ] || [ -z "$INTERNETBS_API_PASSWORD" ]; then + INTERNETBS_API_KEY="" + INTERNETBS_API_PASSWORD="" + _err "You didn't specify the INTERNET.BS api key and password yet." + _err "Please create you key and try again." + return 1 + fi + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" From 2671af13cdfb592f56c5de1ffdbe438f79db72d8 Mon Sep 17 00:00:00 2001 From: Ketil Date: Thu, 27 Dec 2018 15:17:19 +0100 Subject: [PATCH 0084/2234] Bugfix for allowing '+' character in CloudFlare email --- dnsapi/dns_cf.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index f50ab498..021094d8 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -34,7 +34,7 @@ dns_cf_add() { _saveaccountconf_mutable CF_Key "$CF_Key" _saveaccountconf_mutable CF_Email "$CF_Email" - _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '@.' '__')" + _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '+@.' '___')" _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" _debug "First detect the root zone" @@ -105,7 +105,7 @@ dns_cf_rm() { return 1 fi - _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '@.' '__')" + _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '+@.' '___')" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then From 9756adb9336daf7fdfd63ce83dde75aa269708d8 Mon Sep 17 00:00:00 2001 From: Ketil Date: Thu, 27 Dec 2018 15:45:19 +0100 Subject: [PATCH 0085/2234] Fixed spelling of 'tigger' to 'Trigger'. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index acda4bee..c80d8aa3 100755 --- a/acme.sh +++ b/acme.sh @@ -3443,7 +3443,7 @@ __get_domain_new_authz() { #uri keyAuthorization __trigger_validation() { - _debug2 "tigger domain validation." + _debug2 "Trigger domain validation." _t_url="$1" _debug2 _t_url "$_t_url" _t_key_authz="$2" From 920cab6f1206abde5e8ced352bdd3908a2950534 Mon Sep 17 00:00:00 2001 From: Ketil Date: Thu, 27 Dec 2018 16:06:41 +0100 Subject: [PATCH 0086/2234] Added fixes to also use BuyPass Go ACME server --- acme.sh | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/acme.sh b/acme.sh index acda4bee..aa2adc6c 100755 --- a/acme.sh +++ b/acme.sh @@ -13,6 +13,8 @@ _SCRIPT_="$0" _SUB_FOLDERS="dnsapi deploy" +BUYPASS_CA="https://api.buypass.no/acme/directory" + LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory" @@ -1820,9 +1822,12 @@ _send_signed_request() { _debug3 _request_retry_times "$_request_retry_times" if [ -z "$_CACHED_NONCE" ]; then _headers="" - if [ "$ACME_NEW_NONCE" ]; then - _debug2 "Get nonce with HEAD. ACME_NEW_NONCE" "$ACME_NEW_NONCE" + if [ "$ACME_NEW_NONCE" ] || [ "$BUYPASS" ]; then nonceurl="$ACME_NEW_NONCE" + if [ "$BUYPASS" ]; then + nonceurl=$url + fi + _debug2 "Get nonce with HEAD. ACME_NEW_NONCE" "$nonceurl" if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then _headers="$(cat "$HTTP_HEADER")" fi @@ -1875,7 +1880,7 @@ _send_signed_request() { sig="$(printf "%s" "$_sig_t" | _url_replace)" _debug3 sig "$sig" - if [ "$ACME_VERSION" = "2" ]; then + if [ "$ACME_VERSION" = "2" ] || [ "$BUYPASS" ]; then body="{\"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" else body="{\"header\": $JWK_HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" @@ -2330,6 +2335,13 @@ _initAPI() { fi export ACME_AGREEMENT + BUYPASS=$(echo "$_api_server" | _egrep_o 'buypass') + if [ "$BUYPASS" ]; then + BUYPASS=1 + fi + export BUYPASS + _debug "BUYPASS" "$BUYPASS" + _debug "ACME_KEY_CHANGE" "$ACME_KEY_CHANGE" _debug "ACME_NEW_AUTHZ" "$ACME_NEW_AUTHZ" _debug "ACME_NEW_ORDER" "$ACME_NEW_ORDER" @@ -3448,10 +3460,16 @@ __trigger_validation() { _debug2 _t_url "$_t_url" _t_key_authz="$2" _debug2 _t_key_authz "$_t_key_authz" + _t_vtype="$3" + _debug2 _t_vtype "$_t_vtype" if [ "$ACME_VERSION" = "2" ]; then _send_signed_request "$_t_url" "{\"keyAuthorization\": \"$_t_key_authz\"}" else - _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"keyAuthorization\": \"$_t_key_authz\"}" + if [ "$BUYPASS" ]; then + _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"type\": \"$_t_vtype\", \"keyAuthorization\": \"$_t_key_authz\"}" + else + _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"keyAuthorization\": \"$_t_key_authz\"}" + fi fi } @@ -4038,7 +4056,7 @@ $_authorizations_map" fi fi - if ! __trigger_validation "$uri" "$keyauthorization"; then + if ! __trigger_validation "$uri" "$keyauthorization" "$vtype"; then _err "$d:Can not get challenge: $response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup @@ -4047,14 +4065,18 @@ $_authorizations_map" fi if [ "$code" ] && [ "$code" != '202' ]; then - if [ "$ACME_VERSION" = "2" ] && [ "$code" = '200' ]; then + if [ "$BUYPASS" ] && [ "$code" = '200' ]; then _debug "trigger validation code: $code" else - _err "$d:Challenge error: $response" - _clearupwebbroot "$_currentRoot" "$removelevel" "$token" - _clearup - _on_issue_err "$_post_hook" "$vlist" - return 1 + if [ "$ACME_VERSION" = "2" ] && [ "$code" = '200' ]; then + _debug "trigger validation code: $code" + else + _err "$d:Challenge error: $response" + _clearupwebbroot "$_currentRoot" "$removelevel" "$token" + _clearup + _on_issue_err "$_post_hook" "$vlist" + return 1 + fi fi fi From 8bd12ed040c65fcc5b4919c1f81835c579da6314 Mon Sep 17 00:00:00 2001 From: Ketil Date: Fri, 28 Dec 2018 09:22:31 +0100 Subject: [PATCH 0087/2234] Rewrite to remove BuyPass spesific fixes and adapt ACME v1 --- acme.sh | 44 +++++++++++--------------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/acme.sh b/acme.sh index aa2adc6c..0ec08511 100755 --- a/acme.sh +++ b/acme.sh @@ -1822,12 +1822,9 @@ _send_signed_request() { _debug3 _request_retry_times "$_request_retry_times" if [ -z "$_CACHED_NONCE" ]; then _headers="" - if [ "$ACME_NEW_NONCE" ] || [ "$BUYPASS" ]; then + if [ "$ACME_NEW_NONCE" ]; then + _debug2 "Get nonce with HEAD. ACME_NEW_NONCE" "$ACME_NEW_NONCE" nonceurl="$ACME_NEW_NONCE" - if [ "$BUYPASS" ]; then - nonceurl=$url - fi - _debug2 "Get nonce with HEAD. ACME_NEW_NONCE" "$nonceurl" if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then _headers="$(cat "$HTTP_HEADER")" fi @@ -1880,11 +1877,7 @@ _send_signed_request() { sig="$(printf "%s" "$_sig_t" | _url_replace)" _debug3 sig "$sig" - if [ "$ACME_VERSION" = "2" ] || [ "$BUYPASS" ]; then - body="{\"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" - else - body="{\"header\": $JWK_HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" - fi + body="{\"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" _debug3 body "$body" response="$(_post "$body" "$url" "$needbase64" "POST" "$__request_conent_type")" @@ -2335,13 +2328,6 @@ _initAPI() { fi export ACME_AGREEMENT - BUYPASS=$(echo "$_api_server" | _egrep_o 'buypass') - if [ "$BUYPASS" ]; then - BUYPASS=1 - fi - export BUYPASS - _debug "BUYPASS" "$BUYPASS" - _debug "ACME_KEY_CHANGE" "$ACME_KEY_CHANGE" _debug "ACME_NEW_AUTHZ" "$ACME_NEW_AUTHZ" _debug "ACME_NEW_ORDER" "$ACME_NEW_ORDER" @@ -3455,7 +3441,7 @@ __get_domain_new_authz() { #uri keyAuthorization __trigger_validation() { - _debug2 "tigger domain validation." + _debug2 "Trigger domain validation." _t_url="$1" _debug2 _t_url "$_t_url" _t_key_authz="$2" @@ -3465,11 +3451,7 @@ __trigger_validation() { if [ "$ACME_VERSION" = "2" ]; then _send_signed_request "$_t_url" "{\"keyAuthorization\": \"$_t_key_authz\"}" else - if [ "$BUYPASS" ]; then - _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"type\": \"$_t_vtype\", \"keyAuthorization\": \"$_t_key_authz\"}" - else - _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"keyAuthorization\": \"$_t_key_authz\"}" - fi + _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"type\": \"$_t_vtype\", \"keyAuthorization\": \"$_t_key_authz\"}" fi } @@ -4065,18 +4047,14 @@ $_authorizations_map" fi if [ "$code" ] && [ "$code" != '202' ]; then - if [ "$BUYPASS" ] && [ "$code" = '200' ]; then + if [ "$code" = '200' ]; then _debug "trigger validation code: $code" else - if [ "$ACME_VERSION" = "2" ] && [ "$code" = '200' ]; then - _debug "trigger validation code: $code" - else - _err "$d:Challenge error: $response" - _clearupwebbroot "$_currentRoot" "$removelevel" "$token" - _clearup - _on_issue_err "$_post_hook" "$vlist" - return 1 - fi + _err "$d:Challenge error: $response" + _clearupwebbroot "$_currentRoot" "$removelevel" "$token" + _clearup + _on_issue_err "$_post_hook" "$vlist" + return 1 fi fi From 65a2f789dc415c518d16d5c50e9d0d28919eb5ff Mon Sep 17 00:00:00 2001 From: Ketil Date: Fri, 28 Dec 2018 13:26:20 +0100 Subject: [PATCH 0088/2234] Removing BUYPASS_CA variable --- acme.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/acme.sh b/acme.sh index 0ec08511..422383b6 100755 --- a/acme.sh +++ b/acme.sh @@ -13,8 +13,6 @@ _SCRIPT_="$0" _SUB_FOLDERS="dnsapi deploy" -BUYPASS_CA="https://api.buypass.no/acme/directory" - LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory" From b32071ad049e3235adebd87f64b1899bbc3d21f2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 28 Dec 2018 22:12:54 +0800 Subject: [PATCH 0089/2234] remove unused code --- acme.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 422383b6..dd718352 100755 --- a/acme.sh +++ b/acme.sh @@ -36,7 +36,6 @@ _OLD_STAGE_CA_HOST="https://acme-staging.api.letsencrypt.org" VTYPE_HTTP="http-01" VTYPE_DNS="dns-01" VTYPE_TLS="tls-sni-01" -VTYPE_TLS2="tls-sni-02" VTYPE_ALPN="tls-alpn-01" LOCAL_ANY_ADDRESS="0.0.0.0" @@ -3700,11 +3699,7 @@ $_authorizations_map" fi if [ "$_currentRoot" = "$W_TLS" ]; then - if [ "$ACME_VERSION" = "2" ]; then - vtype="$VTYPE_TLS2" - else - vtype="$VTYPE_TLS" - fi + vtype="$VTYPE_TLS" fi if [ "$_currentRoot" = "$W_ALPN" ]; then From 7ba9a5972dd904b1b5834e7ef1a6a3323d1e29aa Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 28 Dec 2018 22:45:40 +0800 Subject: [PATCH 0090/2234] revert fix for https://github.com/Neilpang/acme.sh/issues/1941 1. fix https://github.com/Neilpang/acme.sh/issues/1977 2. The cache is too long to as a line to save in the conf --- dnsapi/dns_cf.sh | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 021094d8..202385fe 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -34,9 +34,6 @@ dns_cf_add() { _saveaccountconf_mutable CF_Key "$CF_Key" _saveaccountconf_mutable CF_Email "$CF_Email" - _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '+@.' '___')" - _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" - _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -105,16 +102,11 @@ dns_cf_rm() { return 1 fi - _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '+@.' '___')" - _debug "First detect the root zone" if ! _get_root "$fulldomain"; then - _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" _err "invalid domain" return 1 fi - _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" - _debug _domain_id "$_domain_id" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" @@ -154,21 +146,6 @@ dns_cf_rm() { # _domain=domain.com # _domain_id=sdjkglgdfewsdfg _get_root() { - - _cf_zones="$(_readdomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_")" - _debug2 "_cf_zones" "$_cf_zones" - if [ -z "$_cf_zones" ]; then - _debug "$_DOMAIN_CF_ZONES_CACHE_NAME_ is none, so get it." - if ! _cf_rest GET "zones"; then - return 1 - fi - _cf_zones="$response" - _savedomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" "$(echo "$_cf_zones" | _base64)" - else - _debug "$_DOMAIN_CF_ZONES_CACHE_NAME_ found" - _cf_zones="$(echo "$_cf_zones" | _dbase64)" - fi - domain=$1 i=2 p=1 @@ -180,8 +157,12 @@ _get_root() { return 1 fi - if _contains "$_cf_zones" "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(echo "$_cf_zones" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "^\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if ! _cf_rest GET "zones?name=$h"; then + return 1 + fi + + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From ec67a1b2c12c4fa1bdb28feb870853652b7bbe07 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 28 Dec 2018 22:52:40 +0800 Subject: [PATCH 0091/2234] Do not limit the renew days to 60, it's just a default value. buypass support 180 days. --- acme.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index dd718352..aae16f07 100755 --- a/acme.sh +++ b/acme.sh @@ -40,7 +40,7 @@ VTYPE_ALPN="tls-alpn-01" LOCAL_ANY_ADDRESS="0.0.0.0" -MAX_RENEW=60 +DEFAULT_RENEW=60 DEFAULT_DNS_SLEEP=120 @@ -4267,8 +4267,8 @@ $_authorizations_map" Le_CertCreateTimeStr=$(date -u) _savedomainconf "Le_CertCreateTimeStr" "$Le_CertCreateTimeStr" - if [ -z "$Le_RenewalDays" ] || [ "$Le_RenewalDays" -lt "0" ] || [ "$Le_RenewalDays" -gt "$MAX_RENEW" ]; then - Le_RenewalDays="$MAX_RENEW" + if [ -z "$Le_RenewalDays" ] || [ "$Le_RenewalDays" -lt "0" ]; then + Le_RenewalDays="$DEFAULT_RENEW" else _savedomainconf "Le_RenewalDays" "$Le_RenewalDays" fi @@ -5520,7 +5520,7 @@ Parameters: --useragent Specifies the user agent string. it will be saved for future use too. --accountemail Specifies the account email, only valid for the '--install' and '--update-account' command. --accountkey Specifies the account key path, only valid for the '--install' command. - --days Specifies the days to renew the cert when using '--issue' command. The max value is $MAX_RENEW days. + --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer. --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses. From c4094c68ee44cd9651fb1effe38ce4a1c97b1cee Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 28 Dec 2018 23:04:40 +0800 Subject: [PATCH 0092/2234] Support BuyPass.com CA --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6a1cf3a4..50d2cfbe 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,10 @@ For all build statuses, check our [weekly build project](https://github.com/Neil https://github.com/Neilpang/acmetest +# Supported CA + +- Letsencrypt.org CA(default) +- [BuyPass.com CA](https://github.com/Neilpang/acme.sh/wiki/BuyPass.com-CA) # Supported modes From c9baca79109de3d55a6ced143b01e4ef7a07729a Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 28 Dec 2018 23:12:16 +0800 Subject: [PATCH 0093/2234] add tls-alpn mode --- README.md | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 50d2cfbe..2d31c678 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ https://github.com/Neilpang/acmetest - Webroot mode - Standalone mode +- Standalone tls-alpn mode - Apache mode - Nginx mode - DNS mode @@ -225,8 +226,20 @@ acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert +# 5. Use Standalone ssl server to issue cert -# 5. Use Apache mode +**(requires you to be root/sudoer or have permission to listen on port 443 (TCP))** + +Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again. + +```bash +acme.sh --issue --alpn -d example.com -d www.example.com -d cp.example.com +``` + +More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert + + +# 6. Use Apache mode **(requires you to be root/sudoer, since it is required to interact with Apache server)** @@ -246,7 +259,7 @@ We don't want to mess your apache server, don't worry.** More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert -# 6. Use Nginx mode +# 7. Use Nginx mode **(requires you to be root/sudoer, since it is required to interact with Nginx server)** @@ -270,7 +283,7 @@ We don't want to mess your nginx server, don't worry.** More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert -# 7. Automatic DNS API integration +# 8. Automatic DNS API integration If your DNS provider supports API access, we can use that API to automatically issue the certs. @@ -348,7 +361,7 @@ If your DNS provider is not on the supported list above, you can write your own For more details: [How to use DNS API](dnsapi) -# 8. Use DNS manual mode: +# 9. Use DNS manual mode: See: https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode first. @@ -384,7 +397,7 @@ Ok, it's done. **Please use dns api mode instead.** -# 9. Issue ECC certificates +# 10. Issue ECC certificates `Let's Encrypt` can now issue **ECDSA** certificates. @@ -416,7 +429,7 @@ Valid values are: -# 10. Issue Wildcard certificates +# 11. Issue Wildcard certificates It's simple, just give a wildcard domain as the `-d` parameter. @@ -426,7 +439,7 @@ acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf -# 11. How to renew the certs +# 12. How to renew the certs No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days. @@ -443,7 +456,7 @@ acme.sh --renew -d example.com --force --ecc ``` -# 12. How to stop cert renewal +# 13. How to stop cert renewal To stop renewal of a cert, you can execute the following to remove the cert from the renewal list: @@ -456,7 +469,7 @@ The cert/key file is not removed from the disk. You can remove the respective directory (e.g. `~/.acme.sh/example.com`) by yourself. -# 13. How to upgrade `acme.sh` +# 14. How to upgrade `acme.sh` acme.sh is in constant development, so it's strongly recommended to use the latest code. @@ -481,25 +494,25 @@ acme.sh --upgrade --auto-upgrade 0 ``` -# 14. Issue a cert from an existing CSR +# 15. Issue a cert from an existing CSR https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR -# 15. Under the Hood +# 16. Under the Hood Speak ACME language using shell, directly to "Let's Encrypt". TODO: -# 16. Acknowledgments +# 17. Acknowledgments 1. Acme-tiny: https://github.com/diafygi/acme-tiny 2. ACME protocol: https://github.com/ietf-wg-acme/acme -# 17. License & Others +# 18. License & Others License is GPLv3 @@ -508,7 +521,7 @@ Please Star and Fork me. [Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome. -# 18. Donate +# 19. Donate Your donation makes **acme.sh** better: 1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/) From 29a5311ae0cb82799d404efb8dc1b4c3cc7ff14d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= Date: Fri, 28 Dec 2018 00:45:51 +0200 Subject: [PATCH 0094/2234] [dnsapi] Support adding / removing multiple TXT values for Gandi Gandi supports setting multiple entries by setting multiple array items for the rrset_values field in their API. Modify the dns_gandi_livedns.sh script so that it checks for existing entries, appends new ones if needed, and removes existing ones individually. This enabled wildcard certificate support on Gandi. Fixes the dns_gandi_livedns part of #1261. Tested for creating a multidomain, multiple wild-card certificate on Gandi and using a test script executing only the dns_gandi_livedns_add and dns_gandi_livedns_rm functions. --- dnsapi/dns_gandi_livedns.sh | 60 ++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) mode change 100755 => 100644 dnsapi/dns_gandi_livedns.sh diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh old mode 100755 new mode 100644 index 7a21aba6..cdda4775 --- a/dnsapi/dns_gandi_livedns.sh +++ b/dnsapi/dns_gandi_livedns.sh @@ -7,6 +7,7 @@ # Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable # #Author: Frédéric Crozat +# Dominik Röttsches #Report Bugs here: https://github.com/fcrozat/acme.sh # ######## Public functions ##################### @@ -36,9 +37,7 @@ dns_gandi_livedns_add() { _debug domain "$_domain" _debug sub_domain "$_sub_domain" - _gandi_livedns_rest PUT "domains/$_domain/records/$_sub_domain/TXT" "{\"rrset_ttl\": 300, \"rrset_values\":[\"$txtvalue\"]}" \ - && _contains "$response" '{"message": "DNS Record Created"}' \ - && _info "Add $(__green "success")" + _dns_gandi_append_record "$_domain" "$_sub_domain" "$txtvalue" } #Usage: fulldomain txtvalue @@ -56,9 +55,23 @@ dns_gandi_livedns_rm() { _debug fulldomain "$fulldomain" _debug domain "$_domain" _debug sub_domain "$_sub_domain" + _debug txtvalue "$txtvalue" - _gandi_livedns_rest DELETE "domains/$_domain/records/$_sub_domain/TXT" "" + if ! _dns_gandi_existing_rrset_values "$_domain" "$_sub_domain"; then + return 1 + fi + _new_rrset_values=$(echo "$_rrset_values" | sed "s/...$txtvalue...//g") + # Cleanup dangling commata. + _new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, ,/ ,/g") + _new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, *\]/\]/g") + _new_rrset_values=$(echo "$_new_rrset_values" | sed "s/\[ *,/\[/g") + _debug "New rrset_values" "$_new_rrset_values" + _gandi_livedns_rest PUT \ + "domains/$_domain/records/$_sub_domain/TXT" \ + "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" \ + && _contains "$response" '{"message": "DNS Record Created"}' \ + && _info "Removing record $(__green "success")" } #################### Private functions below ################################## @@ -98,6 +111,45 @@ _get_root() { return 1 } +_dns_gandi_append_record() { + domain=$1 + sub_domain=$2 + txtvalue=$3 + + if _dns_gandi_existing_rrset_values "$domain" "$sub_domain"; then + _debug "Appending new value" + _rrset_values=$(echo "$_rrset_values" | sed "s/\"]/\",\"$txtvalue\"]/") + else + _debug "Creating new record" "$_rrset_values" + _rrset_values="[\"$txtvalue\"]" + fi + _debug new_rrset_values "$_rrset_values" + _gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \ + "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" \ + && _contains "$response" '{"message": "DNS Record Created"}' \ + && _info "Adding record $(__green "success")" +} + +_dns_gandi_existing_rrset_values() { + domain=$1 + sub_domain=$2 + if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then + return 1 + fi + if ! _contains "$response" '"rrset_type": "TXT"'; then + _debug "Does not have a _acme-challenge TXT record yet." + return 1 + fi + if _contains "$response" '"rrset_values": \[\]'; then + _debug "Empty rrset_values for TXT record, no previous TXT record." + return 1 + fi + _debug "Already has TXT record." + _rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' \ + | _egrep_o '\[".*\"]') + return 0 +} + _gandi_livedns_rest() { m=$1 ep="$2" From 68c5c366f4bc0ab421bd2004e40718b7561c984f Mon Sep 17 00:00:00 2001 From: Ben Edmunds Date: Sun, 30 Dec 2018 03:13:23 +0000 Subject: [PATCH 0095/2234] dnsapi update dynu for api v2 --- dnsapi/dns_dynu.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/dnsapi/dns_dynu.sh b/dnsapi/dns_dynu.sh index 17a1cdb0..506ef53e 100644 --- a/dnsapi/dns_dynu.sh +++ b/dnsapi/dns_dynu.sh @@ -10,7 +10,7 @@ Dynu_Token="" # #Endpoint -Dynu_EndPoint="https://api.dynu.com/v1" +Dynu_EndPoint="https://api.dynu.com/v2" # #Author: Dynu Systems, Inc. #Report Bugs here: https://github.com/shar0119/acme.sh @@ -51,11 +51,11 @@ dns_dynu_add() { _debug _domain_name "$_domain_name" _info "Creating TXT record." - if ! _dynu_rest POST "dns/record/add" "{\"domain_name\":\"$_domain_name\",\"node_name\":\"$_node\",\"record_type\":\"TXT\",\"text_data\":\"$txtvalue\",\"state\":true,\"ttl\":90}"; then + if ! _dynu_rest POST "dns/$dnsId/record" "{\"domainId\":\"$dnsId\",\"nodeName\":\"$_node\",\"recordType\":\"TXT\",\"textData\":\"$txtvalue\",\"state\":true,\"ttl\":90}"; then return 1 fi - if ! _contains "$response" "text_data"; then + if ! _contains "$response" "200"; then _err "Could not add TXT record." return 1 fi @@ -132,11 +132,12 @@ _get_root() { return 1 fi - if ! _dynu_rest GET "dns/get/$h"; then + if ! _dynu_rest GET "dns/getroot/$h"; then return 1 fi - if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + if _contains "$response" "\"domainName\":\"$h\"" >/dev/null; then + dnsId=$(printf "%s" "$response" | tr -d "{}" | cut -d , -f 2 | cut -d : -f 2) _domain_name=$h _node=$(printf "%s" "$domain" | cut -d . -f 1-$p) return 0 @@ -152,7 +153,7 @@ _get_recordid() { fulldomain=$1 txtvalue=$2 - if ! _dynu_rest GET "dns/record/get?hostname=$fulldomain&rrtype=TXT"; then + if ! _dynu_rest GET "dns/$dnsId/record"; then return 1 fi @@ -161,19 +162,18 @@ _get_recordid() { return 0 fi - _dns_record_id=$(printf "%s" "$response" | _egrep_o "{[^}]*}" | grep "\"text_data\":\"$txtvalue\"" | _egrep_o ",[^,]*," | grep ',"id":' | tr -d ",," | cut -d : -f 2) - + _dns_record_id=$(printf "%s" "$response" | sed -e 's/[^{]*\({[^}]*}\)[^{]*/\1\n/g' | grep "\"textData\":\"$txtvalue\"" | sed -e 's/.*"id":\([^,]*\).*/\1/') return 0 } _delete_txt_record() { _dns_record_id=$1 - if ! _dynu_rest GET "dns/record/delete/$_dns_record_id"; then + if ! _dynu_rest DELETE "dns/$dnsId/record/$_dns_record_id"; then return 1 fi - if ! _contains "$response" "true"; then + if ! _contains "$response" "200"; then return 1 fi @@ -189,7 +189,7 @@ _dynu_rest() { export _H1="Authorization: Bearer $Dynu_Token" export _H2="Content-Type: application/json" - if [ "$data" ]; then + if [ "$data" ] || [ "$m" = "DELETE" ]; then _debug data "$data" response="$(_post "$data" "$Dynu_EndPoint/$ep" "" "$m")" else @@ -216,8 +216,8 @@ _dynu_authentication() { _err "Authentication failed." return 1 fi - if _contains "$response" "accessToken"; then - Dynu_Token=$(printf "%s" "$response" | tr -d "[]" | cut -d , -f 2 | cut -d : -f 2 | cut -d '"' -f 2) + if _contains "$response" "access_token"; then + Dynu_Token=$(printf "%s" "$response" | tr -d "{}" | cut -d , -f 1 | cut -d : -f 2 | cut -d '"' -f 2) fi if _contains "$Dynu_Token" "null"; then Dynu_Token="" From cd4f29135b8f66d5dc8a34833712ad90eceefe9f Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Wed, 2 Jan 2019 16:44:11 +0100 Subject: [PATCH 0096/2234] waiting for API zoneStatus active --- dnsapi/dns_hostingde.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 39bcfb63..317ebeda 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -74,8 +74,26 @@ _hostingde_getZoneConfig() { return $returnCode } +_hostingde_getZoneStatus() { + _debug "Checking Zone status" + curData="{\"filter\":{\"field\":\"zoneConfigId\",\"value\":\"${zoneConfigId}\"},\"limit\":1,\"authToken\":\"${HOSTINGDE_APIKEY}\"}" + curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zonesFind")" + _debug "Calling zonesFind '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zonesFind'" + _debug "Result of zonesFind '$curResult'" + zoneStatus=$(echo "${curResult}" | grep -v success | _egrep_o '"status":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + _debug "zoneStatus '${zoneStatus}'" + return 0 +} + _hostingde_addRecord() { _info "Adding record to zone" + _hostingde_getZoneStatus + _debug "Result of zoneStatus: '${zoneStatus}'" + while [ "${zoneStatus}" != "active" ]; do + sleep 5 + _hostingde_getZoneStatus + _debug "Result of zoneStatus: '${zoneStatus}'" + done curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\"},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}" curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" @@ -93,6 +111,13 @@ _hostingde_addRecord() { _hostingde_removeRecord() { _info "Removing record from zone" + _hostingde_getZoneStatus + _debug "Result of zoneStatus: '$zoneStatus'" + while [ "$zoneStatus" != "active" ]; do + sleep 5 + _hostingde_getZoneStatus + _debug "Result of zoneStatus: '$zoneStatus'" + done curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\"},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}" curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" From ecf7dded07144d81aba47addee52eae0c072dbd0 Mon Sep 17 00:00:00 2001 From: Ivru Date: Thu, 3 Jan 2019 08:39:51 +0100 Subject: [PATCH 0097/2234] Fix typo --- dnsapi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 201deeec..9358eb4b 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1122,7 +1122,7 @@ export EXOSCALE_SECRET_KEY='xxx' Now, let's issue a cert: ``` -acme.sh --issue --dns dns_netcup -d example.com -d www.example.com +acme.sh --issue --dns dns_exoscale -d example.com -d www.example.com ``` The `EXOSCALE_API_KEY` and `EXOSCALE_SECRET_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. From 089823785e1aa4b1cb4d3b4725bab2920a97ff02 Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Thu, 3 Jan 2019 10:32:59 +0100 Subject: [PATCH 0098/2234] Using _sleep() instead of sleep --- dnsapi/dns_hostingde.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 317ebeda..74a472d2 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -90,7 +90,7 @@ _hostingde_addRecord() { _hostingde_getZoneStatus _debug "Result of zoneStatus: '${zoneStatus}'" while [ "${zoneStatus}" != "active" ]; do - sleep 5 + _sleep 5 _hostingde_getZoneStatus _debug "Result of zoneStatus: '${zoneStatus}'" done @@ -114,7 +114,7 @@ _hostingde_removeRecord() { _hostingde_getZoneStatus _debug "Result of zoneStatus: '$zoneStatus'" while [ "$zoneStatus" != "active" ]; do - sleep 5 + _sleep 5 _hostingde_getZoneStatus _debug "Result of zoneStatus: '$zoneStatus'" done From 40f0238bb79a14ed884a520b24cb5cbcdbd3aa08 Mon Sep 17 00:00:00 2001 From: Marton Szucs Date: Thu, 3 Jan 2019 11:32:43 +0100 Subject: [PATCH 0099/2234] fix dns_loopia wildcard certificate Checks if a subdomain already exists before creating one. The loopia API clears all records for a subdomain when adding it again. Adding TXT-records instead of updating the existing record when using the add method. Wildcard certificates require multiple TXT-records for the same subdomain. Now you can create wildcard certificates using: `acme.sh --issue -d example.com -d '*.example.com' --dns dns_loopia` Double quoting variables --- dnsapi/dns_loopia.sh | 77 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 5d761187..ece5ef8c 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -38,8 +38,8 @@ dns_loopia_add() { _info "Adding record" - _loopia_add_record "$_domain" "$_sub_domain" - _loopia_update_record "$_domain" "$_sub_domain" "$txtvalue" + _loopia_add_sub_domain "$_domain" "$_sub_domain" + _loopia_add_record "$_domain" "$_sub_domain" "$txtvalue" } @@ -96,6 +96,37 @@ dns_loopia_rm() { #################### Private functions below ################################## +_loopia_get_records() { + domain=$1 + sub_domain=$2 + + xml_content=$(printf ' + + getZoneRecords + + + %s + + + %s + + + %s + + + %s + + + ' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain") + + response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" + if ! _contains "$response" ""; then + _err "Error" + return 1 + fi + return 0 +} + _get_root() { domain=$1 _debug "get root" @@ -137,14 +168,14 @@ _get_root() { } -_loopia_update_record() { +_loopia_add_record() { domain=$1 sub_domain=$2 txtval=$3 xml_content=$(printf ' - updateZoneRecord + addZoneRecord %s @@ -176,10 +207,6 @@ _loopia_update_record() { rdata %s - - record_id - 0 - @@ -194,10 +221,42 @@ _loopia_update_record() { return 0 } -_loopia_add_record() { +_sub_domain_exists() { domain=$1 sub_domain=$2 + xml_content=$(printf ' + + getSubdomains + + + %s + + + %s + + + %s + + + ' $LOOPIA_User $LOOPIA_Password "$domain") + + response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" + + if _contains "$response" "$sub_domain"; then + return 0 + fi + return 1 +} + +_loopia_add_sub_domain() { + domain=$1 + sub_domain=$2 + + if _sub_domain_exists "$domain" "$sub_domain"; then + return 0 + fi + xml_content=$(printf ' addSubdomain From 68d9aad3a26eacb0d57d9c5fe66f59571bddab69 Mon Sep 17 00:00:00 2001 From: hebbet Date: Thu, 3 Jan 2019 14:19:55 +0100 Subject: [PATCH 0100/2234] add link to profile of Cloudflare follow-up for #1893 --- dnsapi/dns_cf.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 202385fe..532199f3 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -19,8 +19,8 @@ dns_cf_add() { if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then CF_Key="" CF_Email="" - _err "You didn't specify a cloudflare api key and email yet." - _err "Please create the key and try again." + _err "You didn't specify a Cloudflare api key and email yet." + _err "You can get yours from here https://dash.cloudflare.com/profile." return 1 fi @@ -97,8 +97,8 @@ dns_cf_rm() { if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then CF_Key="" CF_Email="" - _err "You didn't specify a cloudflare api key and email yet." - _err "Please create the key and try again." + _err "You didn't specify a Cloudflare api key and email yet." + _err "You can get yours from here https://dash.cloudflare.com/profile." return 1 fi From ad613e2437f0cb4cb476af6c61c5975cf1212db8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 4 Jan 2019 22:40:59 +0800 Subject: [PATCH 0101/2234] fix alpn oid. https://github.com/Neilpang/acme.sh/issues/2005 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index aae16f07..8b7fa70b 100755 --- a/acme.sh +++ b/acme.sh @@ -1089,7 +1089,7 @@ _createcsr() { fi if [ "$acmeValidationv1" ]; then - printf "\n1.3.6.1.5.5.7.1.30.1=critical,DER:04:20:${acmeValidationv1}" >>"${csrconf}" + printf "\n1.3.6.1.5.5.7.1.31=critical,DER:04:20:${acmeValidationv1}" >>"${csrconf}" fi _csr_cn="$(_idn "$domain")" From 0483d841e385626e6dc45bc24c8d88a3d5277b62 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Jan 2019 21:05:33 +0800 Subject: [PATCH 0102/2234] Support Post as Get (#2009) * Support POST as GET https://community.letsencrypt.org/t/acme-v2-scheduled-deprecation-of-unauthenticated-resource-gets/74380 * fix PAG, The newline '\n' in response is removed by _send_signed_request(), to keep it, we just use needbase64 * fix PAG, the cert is muti line * fix format * PAG is only for v2 --- acme.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 8b7fa70b..872529f7 100755 --- a/acme.sh +++ b/acme.sh @@ -3651,7 +3651,7 @@ issue() { _authorizations_map="" for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do _debug2 "_authz_url" "$_authz_url" - if ! response="$(_get "$_authz_url")"; then + if ! _send_signed_request "$_authz_url"; then _err "get to authz error." _err "_authorizations_seg" "$_authorizations_seg" _err "_authz_url" "$_authz_url" @@ -4069,7 +4069,11 @@ $_authorizations_map" _debug "sleep 2 secs to verify" sleep 2 _debug "checking" - response="$(_get "$uri")" + if [ "$ACME_VERSION" = "2" ]; then + _send_signed_request "$uri" + else + response="$(_get "$uri")" + fi if [ "$?" != "0" ]; then _err "$d:Verify error:$response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" @@ -4145,13 +4149,16 @@ $_authorizations_map" fi Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" - if ! _get "$Le_LinkCert" >"$CERT_PATH"; then + _tempSignedResponse="$response" + if ! _send_signed_request "$Le_LinkCert" "" "needbase64"; then _err "Sign failed, can not download cert:$Le_LinkCert." _err "$response" _on_issue_err "$_post_hook" return 1 fi + echo "$response" | _dbase64 "multiline" >"$CERT_PATH" + if [ "$(grep -- "$BEGIN_CERT" "$CERT_PATH" | wc -l)" -gt "1" ]; then _debug "Found cert chain" cat "$CERT_PATH" >"$CERT_FULLCHAIN_PATH" @@ -4161,6 +4168,7 @@ $_authorizations_map" _end_n="$(_math $_end_n + 1)" sed -n "${_end_n},9999p" "$CERT_FULLCHAIN_PATH" >"$CA_CERT_PATH" fi + response="$_tempSignedResponse" else if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then _err "Sign failed. $response" @@ -4231,7 +4239,8 @@ $_authorizations_map" while [ "$_link_issuer_retry" -lt "$_MAX_ISSUER_RETRY" ]; do _debug _link_issuer_retry "$_link_issuer_retry" if [ "$ACME_VERSION" = "2" ]; then - if _get "$Le_LinkIssuer" >"$CA_CERT_PATH"; then + if _send_signed_request "$Le_LinkIssuer"; then + echo "$response" >"$CA_CERT_PATH" break fi else @@ -4957,7 +4966,7 @@ _deactivate() { authzUri="$_authorizations_seg" _debug2 "authzUri" "$authzUri" - if ! response="$(_get "$authzUri")"; then + if ! _send_signed_request "$authzUri"; then _err "get to authz error." _err "_authorizations_seg" "$_authorizations_seg" _err "authzUri" "$authzUri" From 72ce37704bbaa04d71623c50b545ef1357e981b3 Mon Sep 17 00:00:00 2001 From: Mike Barnes Date: Tue, 8 Jan 2019 15:49:09 +1100 Subject: [PATCH 0103/2234] Native PointHQ support --- dnsapi/README.md | 19 ++++- dnsapi/dns_pointhq.sh | 164 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 dnsapi/dns_pointhq.sh diff --git a/dnsapi/README.md b/dnsapi/README.md index 9358eb4b..f1bf05e4 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1,12 +1,12 @@ # How to use DNS API -If your dns provider doesn't provide api access, you can use our dns alias mode: +If your dns provider doesn't provide api access, you can use our dns alias mode: https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode ## 1. Use CloudFlare domain API to automatically issue cert -First you need to login to your CloudFlare account to get your [API key](https://dash.cloudflare.com/profile). +First you need to login to your CloudFlare account to get your [API key](https://dash.cloudflare.com/profile). ``` export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" @@ -891,7 +891,7 @@ acme.sh --issue --dns dns_loopia -d example.com -d *.example.com The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed. ## 45. Use ACME DNS API -ACME DNS is a limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely. +ACME DNS is a limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely. https://github.com/joohoi/acme-dns ``` @@ -1056,6 +1056,7 @@ Now you can issue a certificate. acme.sh --issue --dns dns_namecheap -d example.com -d *.example.com ``` +<<<<<<< HEAD ## 54. Use MyDNS.JP API First, register to MyDNS.JP and get MasterID and Password. @@ -1127,6 +1128,18 @@ acme.sh --issue --dns dns_exoscale -d example.com -d www.example.com The `EXOSCALE_API_KEY` and `EXOSCALE_SECRET_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 58. Using PointHQ API to issue certs + +Log into [PointHQ account management](https://app.pointhq.com/profile) and copy the API key from the page there. + +```export PointHQ_Key="apikeystringgoeshere" +exportPointHQ_Email="accountemail@yourdomain.com" +``` + +You can then issue certs by using: +```acme.sh --issue --dns dns_pointhq -d example.com -d www.example.com +``` + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_pointhq.sh b/dnsapi/dns_pointhq.sh new file mode 100644 index 00000000..62313109 --- /dev/null +++ b/dnsapi/dns_pointhq.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env sh + +# +#PointHQ_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" +# +#PointHQ_Email="xxxx@sss.com" + +PointHQ_Api="https://api.pointhq.com" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_pointhq_add() { + fulldomain=$1 + txtvalue=$2 + + PointHQ_Key="${PointHQ_Key:-$(_readaccountconf_mutable PointHQ_Key)}" + PointHQ_Email="${PointHQ_Email:-$(_readaccountconf_mutable PointHQ_Email)}" + if [ -z "$PointHQ_Key" ] || [ -z "$PointHQ_Email" ]; then + PointHQ_Key="" + PointHQ_Email="" + _err "You didn't specify a PointHQ API key and email yet." + _err "Please create the key and try again." + return 1 + fi + + if ! _contains "$PointHQ_Email" "@"; then + _err "It seems that the PointHQ_Email=$PointHQ_Email is not a valid email address." + _err "Please check and retry." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable PointHQ_Key "$PointHQ_Key" + _saveaccountconf_mutable PointHQ_Email "$PointHQ_Email" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + if _pointhq_rest POST "zones/$_domain/records" "{\"zone_record\": {\"name\":\"$_sub_domain\",\"record_type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":3600}}"; then + if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 +} + +#fulldomain txtvalue +dns_pointhq_rm() { + fulldomain=$1 + txtvalue=$2 + + PointHQ_Key="${PointHQ_Key:-$(_readaccountconf_mutable PointHQ_Key)}" + PointHQ_Email="${PointHQ_Email:-$(_readaccountconf_mutable PointHQ_Email)}" + if [ -z "$PointHQ_Key" ] || [ -z "$PointHQ_Email" ]; then + PointHQ_Key="" + PointHQ_Email="" + _err "You didn't specify a PointHQ API key and email yet." + _err "Please create the key and try again." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _pointhq_rest GET "zones/${_domain}/records?record_type=TXT&name=$_sub_domain" + + if ! printf "%s" "$response" | grep "^\[" >/dev/null; then + _err "Error" + return 1 + fi + + if [ "$response" = "[]" ]; then + _info "No records to remove." + else + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | cut -d : -f 2 | tr -d \" | head -n 1) + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _pointhq_rest DELETE "zones/$_domain/records/$record_id"; then + _err "Delete record error." + return 1 + fi + _contains "$response" '"status":"OK"' + fi +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _pointhq_rest GET "zones"; 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 +} + +_pointhq_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + _pointhq_auth=$(printf "%s:%s" "$PointHQ_Email" "$PointHQ_Key" | _base64) + + export _H1="Authorization: Basic $_pointhq_auth" + export _H2="Content-Type: application/json" + export _H3="Accept: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$PointHQ_Api/$ep" "" "$m")" + else + response="$(_get "$PointHQ_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From cd3ef8fa5ac946975704d6bb910b2ddf07314377 Mon Sep 17 00:00:00 2001 From: Mike Barnes Date: Tue, 8 Jan 2019 15:53:53 +1100 Subject: [PATCH 0104/2234] Correct edits to README.md this time --- dnsapi/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index f1bf05e4..fc65748e 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1,12 +1,12 @@ # How to use DNS API -If your dns provider doesn't provide api access, you can use our dns alias mode: +If your dns provider doesn't provide api access, you can use our dns alias mode: https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode ## 1. Use CloudFlare domain API to automatically issue cert -First you need to login to your CloudFlare account to get your [API key](https://dash.cloudflare.com/profile). +First you need to login to your CloudFlare account to get your [API key](https://dash.cloudflare.com/profile). ``` export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" @@ -891,7 +891,7 @@ acme.sh --issue --dns dns_loopia -d example.com -d *.example.com The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed. ## 45. Use ACME DNS API -ACME DNS is a limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely. +ACME DNS is a limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely. https://github.com/joohoi/acme-dns ``` @@ -1056,7 +1056,6 @@ Now you can issue a certificate. acme.sh --issue --dns dns_namecheap -d example.com -d *.example.com ``` -<<<<<<< HEAD ## 54. Use MyDNS.JP API First, register to MyDNS.JP and get MasterID and Password. From 3099c799b25b4eca5de668326b3be297eed12903 Mon Sep 17 00:00:00 2001 From: Mike Barnes Date: Wed, 9 Jan 2019 10:24:28 +1100 Subject: [PATCH 0105/2234] Added PointHQ to supported API list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2d31c678..41ffb694 100644 --- a/README.md +++ b/README.md @@ -348,6 +348,7 @@ You don't have to do anything manually! 1. hosting.de (https://www.hosting.de) 1. Neodigit.net API (https://www.neodigit.net) 1. Exoscale.com API (https://www.exoscale.com/) +1. PointDNS API (https://pointhq.com/) And: From dd068467def09b070dc2e7dcf158cf69d52c5d74 Mon Sep 17 00:00:00 2001 From: Fabio Kruger Date: Thu, 10 Jan 2019 19:33:25 +0100 Subject: [PATCH 0106/2234] 2020 Added a space to improve log readability --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 872529f7..ff472867 100755 --- a/acme.sh +++ b/acme.sh @@ -3901,7 +3901,7 @@ $_authorizations_map" continue fi - _info "Verifying:$d" + _info "Verifying: $d" _debug "d" "$d" _debug "keyauthorization" "$keyauthorization" _debug "uri" "$uri" From e19809d5b510ebd466f1abfd9f8ec4feadae3d92 Mon Sep 17 00:00:00 2001 From: shonenada Date: Fri, 11 Jan 2019 18:17:38 +0800 Subject: [PATCH 0107/2234] Add deployment for qiniu cdn Upload certificate and privkey to Qiniu's CDN service with https://developer.qiniu.com/fusion/api/4248/certificate --- acme.sh | 2 +- deploy/qiniu.sh | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 deploy/qiniu.sh diff --git a/acme.sh b/acme.sh index 872529f7..86b555a3 100755 --- a/acme.sh +++ b/acme.sh @@ -1580,7 +1580,7 @@ _inithttp() { fi if [ -z "$_ACME_CURL" ] && _exists "curl"; then - _ACME_CURL="curl -L --silent --dump-header $HTTP_HEADER " + _ACME_CURL="curl -L --dump-header $HTTP_HEADER " if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _CURL_DUMP="$(_mktemp)" _ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP " diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh new file mode 100644 index 00000000..4fa66ee6 --- /dev/null +++ b/deploy/qiniu.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env sh + +# Script to create certificate to qiniu.com +# +# This deployment required following variables +# export QINIU_AK="QINIUACCESSKEY" +# export QINIU_SK="QINIUSECRETKEY" + +QINIU_API_BASE="https://api.qiniu.com" + +qiniu_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if [ -z "$QINIU_AK" ]; then + if [ -z "$Le_Deploy_Qiniu_AK" ]; then + _err "QINIU_AK is not defined." + return 1 + fi + else + Le_Deploy_Qiniu_AK="$QINIU_AK" + _savedomainconf Le_Deploy_Qiniu_AK "$Le_Deploy_Qiniu_AK" + fi + + if [ -z "$QINIU_SK" ]; then + if [ -z "$Le_Deploy_Qiniu_SK" ]; then + _err "QINIU_SK is not defined." + return 1 + fi + else + Le_Deploy_Qiniu_SK="$QINIU_SK" + _savedomainconf Le_Deploy_Qiniu_SK "$Le_Deploy_Qiniu_SK" + fi + + string_fullchain=$(awk '{printf "%s\\n", $0}' "$_cfullchain") + string_key=$(awk '{printf "%s\\n", $0}' "$_ckey") + + body="{\"name\":\"$_cdomain\",\"common_name\":\"$_cdomain\",\"ca\":\""$string_fullchain"\",\"pri\":\"$string_key\"}" + + create_ssl_url="$QINIU_API_BASE/sslcert" + + ACCESSTOKEN="$(_make_sslcreate_access_token)" + export _H1="Authorization: QBox $ACCESSTOKEN" + + _response=$(_post "$body" "$create_ssl_url" 0 "POST" "application/json" | _dbase64 "multiline") + + success_response="certID" + if test "${_response#*$success_response}" == "$_response"; then + _err "Error in deploying certificate:" + _err "$_response" + return 1 + fi + + _debug response "$_response" + _info "Certificate successfully deployed" + + return 0 +} + +_make_sslcreate_access_token() { + _data="/sslcert\\n" + _token="$(printf "$_data" | openssl sha1 -hmac $Le_Deploy_Qiniu_SK -binary | openssl base64 -e)" + echo "$Le_Deploy_Qiniu_AK:$_token" +} From 3bc6628227dcebc1b788ed0676d51b992ee202cc Mon Sep 17 00:00:00 2001 From: shonenada Date: Fri, 11 Jan 2019 19:19:07 +0800 Subject: [PATCH 0108/2234] Update Qiniu's domain settings after uploading certificate --- acme.sh | 2 +- deploy/qiniu.sh | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/acme.sh b/acme.sh index 86b555a3..872529f7 100755 --- a/acme.sh +++ b/acme.sh @@ -1580,7 +1580,7 @@ _inithttp() { fi if [ -z "$_ACME_CURL" ] && _exists "curl"; then - _ACME_CURL="curl -L --dump-header $HTTP_HEADER " + _ACME_CURL="curl -L --silent --dump-header $HTTP_HEADER " if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _CURL_DUMP="$(_mktemp)" _ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP " diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index 4fa66ee6..070b7f69 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -44,30 +44,53 @@ qiniu_deploy() { string_fullchain=$(awk '{printf "%s\\n", $0}' "$_cfullchain") string_key=$(awk '{printf "%s\\n", $0}' "$_ckey") - body="{\"name\":\"$_cdomain\",\"common_name\":\"$_cdomain\",\"ca\":\""$string_fullchain"\",\"pri\":\"$string_key\"}" + sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$_cdomain\",\"ca\":\""$string_fullchain"\",\"pri\":\"$string_key\"}" create_ssl_url="$QINIU_API_BASE/sslcert" - ACCESSTOKEN="$(_make_sslcreate_access_token)" - export _H1="Authorization: QBox $ACCESSTOKEN" + sslcert_access_token="$(_make_sslcreate_access_token "/sslcert\\n")" + _debug sslcert_access_token "$sslcert_access_token" + export _H1="Authorization: QBox $sslcert_access_token" - _response=$(_post "$body" "$create_ssl_url" 0 "POST" "application/json" | _dbase64 "multiline") + sslcert_response=$(_post "$sslcerl_body" "$create_ssl_url" 0 "POST" "application/json" | _dbase64 "multiline") success_response="certID" - if test "${_response#*$success_response}" == "$_response"; then - _err "Error in deploying certificate:" - _err "$_response" + if test "${sslcert_response#*$success_response}" == "$sslcert_response"; then + _err "Error in creating certificate:" + _err "$sslcert_response" return 1 fi - _debug response "$_response" + _debug sslcert_response "$sslcert_response" + _info "Certificate successfully uploaded, updating domain $_cdomain" + + _certId=$(printf "%s" $sslcert_response | sed -e "s/^.*certID\":\"//" -e "s/\"\}$//") + _debug certId "$_certId" + + update_path="/domain/$_cdomain/httpsconf" + update_url="$QINIU_API_BASE$update_path" + update_body="{\"certid\":\""$_certId"\",\"forceHttps\":true}" + + update_access_token="$(_make_sslcreate_access_token "$update_path\\n")" + _debug update_access_token "$update_access_token" + export _H1="Authorization: QBox $update_access_token" + update_response=$(_post "$update_body" "$update_url" 0 "PUT" "application/json" | _dbase64 "multiline") + + err_response="error" + if test "${update_response#*$err_response}" != "$update_response"; then + _err "Error in updating domain:" + _err "$update_response" + return 1 + fi + + _debug update_response "$update_response" _info "Certificate successfully deployed" return 0 } _make_sslcreate_access_token() { - _data="/sslcert\\n" + _data="$1" _token="$(printf "$_data" | openssl sha1 -hmac $Le_Deploy_Qiniu_SK -binary | openssl base64 -e)" echo "$Le_Deploy_Qiniu_AK:$_token" } From d2a60f3ca42aead53dedbb7afa841919ac75fc83 Mon Sep 17 00:00:00 2001 From: shonenada Date: Sat, 12 Jan 2019 15:54:42 +0800 Subject: [PATCH 0109/2234] lint code --- deploy/qiniu.sh | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index 070b7f69..4f578b27 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -41,18 +41,16 @@ qiniu_deploy() { _savedomainconf Le_Deploy_Qiniu_SK "$Le_Deploy_Qiniu_SK" fi + ## upload certificate string_fullchain=$(awk '{printf "%s\\n", $0}' "$_cfullchain") string_key=$(awk '{printf "%s\\n", $0}' "$_ckey") - sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$_cdomain\",\"ca\":\""$string_fullchain"\",\"pri\":\"$string_key\"}" - - create_ssl_url="$QINIU_API_BASE/sslcert" - - sslcert_access_token="$(_make_sslcreate_access_token "/sslcert\\n")" + sslcert_path="/sslcert" + sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$_cdomain\",\"ca\":\"$string_fullchain\",\"pri\":\"$string_key\"}" + sslcert_access_token="$(_make_sslcreate_access_token "$sslcert_path")" _debug sslcert_access_token "$sslcert_access_token" export _H1="Authorization: QBox $sslcert_access_token" - - sslcert_response=$(_post "$sslcerl_body" "$create_ssl_url" 0 "POST" "application/json" | _dbase64 "multiline") + sslcert_response=$(_post "$sslcerl_body" "$QINIU_API_BASE$sslcert_path" 0 "POST" "application/json" | _dbase64 "multiline") success_response="certID" if test "${sslcert_response#*$success_response}" == "$sslcert_response"; then @@ -64,21 +62,21 @@ qiniu_deploy() { _debug sslcert_response "$sslcert_response" _info "Certificate successfully uploaded, updating domain $_cdomain" - _certId=$(printf "%s" $sslcert_response | sed -e "s/^.*certID\":\"//" -e "s/\"\}$//") + ## extract certId + _certId=$(printf "%s" "$sslcert_response" | sed -e "s/^.*certID\":\"//" -e "s/\"\}$//") _debug certId "$_certId" + ## update domain ssl config update_path="/domain/$_cdomain/httpsconf" - update_url="$QINIU_API_BASE$update_path" - update_body="{\"certid\":\""$_certId"\",\"forceHttps\":true}" - - update_access_token="$(_make_sslcreate_access_token "$update_path\\n")" + update_body="{\"certid\":\"$_certId\",\"forceHttps\":true}" + update_access_token="$(_make_sslcreate_access_token "$update_path")" _debug update_access_token "$update_access_token" export _H1="Authorization: QBox $update_access_token" - update_response=$(_post "$update_body" "$update_url" 0 "PUT" "application/json" | _dbase64 "multiline") + update_response=$(_post "$update_body" "$QINIU_API_BASE$update_body" 0 "PUT" "application/json" | _dbase64 "multiline") err_response="error" if test "${update_response#*$err_response}" != "$update_response"; then - _err "Error in updating domain:" + _err "Error in updating domain httpsconf:" _err "$update_response" return 1 fi @@ -90,7 +88,7 @@ qiniu_deploy() { } _make_sslcreate_access_token() { - _data="$1" - _token="$(printf "$_data" | openssl sha1 -hmac $Le_Deploy_Qiniu_SK -binary | openssl base64 -e)" + _data="$1\\n" + _token="$(printf "%s" "$_data" | openssl sha1 -hmac "$Le_Deploy_Qiniu_SK" -binary | openssl base64 -e)" echo "$Le_Deploy_Qiniu_AK:$_token" } From 4ec39ab707069e8fe87eccffc289dc0432afcc53 Mon Sep 17 00:00:00 2001 From: shonenada Date: Sat, 12 Jan 2019 19:58:57 +0800 Subject: [PATCH 0110/2234] replace with functions defined in acme.sh --- deploy/qiniu.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index 4f578b27..c2306c51 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -72,7 +72,7 @@ qiniu_deploy() { update_access_token="$(_make_sslcreate_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_body" 0 "PUT" "application/json" | _dbase64 "multiline") + update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64 "multiline") err_response="error" if test "${update_response#*$err_response}" != "$update_response"; then @@ -88,7 +88,6 @@ qiniu_deploy() { } _make_sslcreate_access_token() { - _data="$1\\n" - _token="$(printf "%s" "$_data" | openssl sha1 -hmac "$Le_Deploy_Qiniu_SK" -binary | openssl base64 -e)" + _token="$(printf "%s\\n" "$1" | _hmac "sha1" "$(printf "%s" "$Le_Deploy_Qiniu_SK" | _hex_dump | tr -d " ")" | _base64)" echo "$Le_Deploy_Qiniu_AK:$_token" } From 82b11da4caf356f418e12ca5c5fd047bbe21d37e Mon Sep 17 00:00:00 2001 From: shonenada Date: Sat, 12 Jan 2019 21:07:22 +0800 Subject: [PATCH 0111/2234] replace `awk` with `sed` and `tr` --- deploy/qiniu.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index c2306c51..559e59cf 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -42,8 +42,8 @@ qiniu_deploy() { fi ## upload certificate - string_fullchain=$(awk '{printf "%s\\n", $0}' "$_cfullchain") - string_key=$(awk '{printf "%s\\n", $0}' "$_ckey") + string_fullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n') + string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') sslcert_path="/sslcert" sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$_cdomain\",\"ca\":\"$string_fullchain\",\"pri\":\"$string_key\"}" @@ -63,12 +63,12 @@ qiniu_deploy() { _info "Certificate successfully uploaded, updating domain $_cdomain" ## extract certId - _certId=$(printf "%s" "$sslcert_response" | sed -e "s/^.*certID\":\"//" -e "s/\"\}$//") + _certId="$(printf "%s" "$sslcert_response" | _normalizeJson | _egrep_o "certID\":\s*\"[^\"]*\"" | cut -d : -f 2)" _debug certId "$_certId" ## update domain ssl config update_path="/domain/$_cdomain/httpsconf" - update_body="{\"certid\":\"$_certId\",\"forceHttps\":true}" + update_body="{\"certid\":$_certId,\"forceHttps\":true}" update_access_token="$(_make_sslcreate_access_token "$update_path")" _debug update_access_token "$update_access_token" export _H1="Authorization: QBox $update_access_token" From 0cd6afde6f586a3791952f07a3fe99c5f7e45ed3 Mon Sep 17 00:00:00 2001 From: shonenada Date: Sat, 12 Jan 2019 21:15:16 +0800 Subject: [PATCH 0112/2234] Add guidance to deploying cert to qiniu.com --- deploy/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/deploy/README.md b/deploy/README.md index cec7d773..68c1a272 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -332,3 +332,19 @@ variable to anything (ex: "1") before running `acme.sh`: ```sh export FABIO="1" ``` + +## 13. Deploy your certificate to Qiniu.com + +You should create AccessKey/SecretKey pair in https://portal.qiniu.com/user/key before deploying +your certificate. + +```sh +$ export QINIU_AK="foo" +$ export QINIU_SK="bar" +``` + +then you can deploy certificate by following command: + +```sh +$ acme.sh --deploy -d example.com --deploy-hook qiniu +``` From 96efc8c7f025b6b862c9502abf44434fcd6b0693 Mon Sep 17 00:00:00 2001 From: shonenada Date: Sat, 12 Jan 2019 23:11:19 +0800 Subject: [PATCH 0113/2234] lint codes --- deploy/qiniu.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index 559e59cf..e0be60fe 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -52,8 +52,7 @@ qiniu_deploy() { export _H1="Authorization: QBox $sslcert_access_token" sslcert_response=$(_post "$sslcerl_body" "$QINIU_API_BASE$sslcert_path" 0 "POST" "application/json" | _dbase64 "multiline") - success_response="certID" - if test "${sslcert_response#*$success_response}" == "$sslcert_response"; then + if ! _contains "$sslcert_response" "certID"; then _err "Error in creating certificate:" _err "$sslcert_response" return 1 @@ -63,7 +62,7 @@ qiniu_deploy() { _info "Certificate successfully uploaded, updating domain $_cdomain" ## extract certId - _certId="$(printf "%s" "$sslcert_response" | _normalizeJson | _egrep_o "certID\":\s*\"[^\"]*\"" | cut -d : -f 2)" + _certId="$(printf "%s" "$sslcert_response" | _normalizeJson | _egrep_o "certID\": *\"[^\"]*\"" | cut -d : -f 2)" _debug certId "$_certId" ## update domain ssl config @@ -74,8 +73,7 @@ qiniu_deploy() { export _H1="Authorization: QBox $update_access_token" update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64 "multiline") - err_response="error" - if test "${update_response#*$err_response}" != "$update_response"; then + if _contains "$update_response" "error"; then _err "Error in updating domain httpsconf:" _err "$update_response" return 1 @@ -88,6 +86,6 @@ qiniu_deploy() { } _make_sslcreate_access_token() { - _token="$(printf "%s\\n" "$1" | _hmac "sha1" "$(printf "%s" "$Le_Deploy_Qiniu_SK" | _hex_dump | tr -d " ")" | _base64)" + _token="$(printf "%s\n" "$1" | _hmac "sha1" "$(printf "%s" "$Le_Deploy_Qiniu_SK" | _hex_dump | tr -d " ")" | _base64)" echo "$Le_Deploy_Qiniu_AK:$_token" } From 3c6b707353007d476e758932dfca1e7125e534b1 Mon Sep 17 00:00:00 2001 From: shonenada Date: Sun, 13 Jan 2019 12:23:15 +0800 Subject: [PATCH 0114/2234] add `QINIU_CDN_DOMAIN` for wildcard certificate --- deploy/README.md | 14 ++++++++++++-- deploy/qiniu.sh | 6 ++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 68c1a272..fa2d7189 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -335,8 +335,9 @@ export FABIO="1" ## 13. Deploy your certificate to Qiniu.com -You should create AccessKey/SecretKey pair in https://portal.qiniu.com/user/key before deploying -your certificate. +You should create AccessKey/SecretKey pair in https://portal.qiniu.com/user/key +before deploying your certificate, and please ensure you have enabled HTTPS for +your domain name. You can enable it in https://portal.qiniu.com/cdn/domain. ```sh $ export QINIU_AK="foo" @@ -348,3 +349,12 @@ then you can deploy certificate by following command: ```sh $ acme.sh --deploy -d example.com --deploy-hook qiniu ``` + +(Optional), If you are using wildcard certificate, +you may need export `QINIU_CDN_DOMAIN` to specify which domain +you want to update: + +```sh +$ export QINIU_CDN_DOMAIN="cdn.example.com" +$ acme.sh --deploy -d example.com --deploy-hook qiniu +``` diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index e0be60fe..dac1866d 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -5,6 +5,7 @@ # This deployment required following variables # export QINIU_AK="QINIUACCESSKEY" # export QINIU_SK="QINIUSECRETKEY" +# export QINIU_CDN_DOMAIN="cdn.example.com" QINIU_API_BASE="https://api.qiniu.com" @@ -14,6 +15,7 @@ qiniu_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" + _cdndomain="${QINIU_CDN_DOMAIN:-$_cdomain}" _debug _cdomain "$_cdomain" _debug _ckey "$_ckey" @@ -46,7 +48,7 @@ qiniu_deploy() { string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') sslcert_path="/sslcert" - sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$_cdomain\",\"ca\":\"$string_fullchain\",\"pri\":\"$string_key\"}" + sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$_cdndomain\",\"ca\":\"$string_fullchain\",\"pri\":\"$string_key\"}" sslcert_access_token="$(_make_sslcreate_access_token "$sslcert_path")" _debug sslcert_access_token "$sslcert_access_token" export _H1="Authorization: QBox $sslcert_access_token" @@ -66,7 +68,7 @@ qiniu_deploy() { _debug certId "$_certId" ## update domain ssl config - update_path="/domain/$_cdomain/httpsconf" + update_path="/domain/$_cdndomain/httpsconf" update_body="{\"certid\":$_certId,\"forceHttps\":true}" update_access_token="$(_make_sslcreate_access_token "$update_path")" _debug update_access_token "$update_access_token" From 4c1fa9c2422143b164448b6e7c327bb293f808a8 Mon Sep 17 00:00:00 2001 From: shonenada Date: Mon, 14 Jan 2019 22:19:00 +0800 Subject: [PATCH 0115/2234] save CDN Domain with `_savedomainconf` --- deploy/qiniu.sh | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index dac1866d..a97dfbbf 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -15,7 +15,6 @@ qiniu_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" - _cdndomain="${QINIU_CDN_DOMAIN:-$_cdomain}" _debug _cdomain "$_cdomain" _debug _ckey "$_ckey" @@ -43,13 +42,20 @@ qiniu_deploy() { _savedomainconf Le_Deploy_Qiniu_SK "$Le_Deploy_Qiniu_SK" fi + Le_Deploy_Qiniu_Cdn_Domain="${QINIU_CDN_DOMAIN:-$(_readdomainconf Le_Deploy_Qiniu_Cdn_Domain)}" + if [ -z "$Le_Deploy_Qiniu_Cdn_Domain" ]; then + Le_Deploy_Qiniu_Cdn_Domain="$_cdomain" + fi + + _savedomainconf Le_Deploy_Qiniu_Cdn_Domain "$Le_Deploy_Qiniu_Cdn_Domain" + ## upload certificate string_fullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n') string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') sslcert_path="/sslcert" - sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$_cdndomain\",\"ca\":\"$string_fullchain\",\"pri\":\"$string_key\"}" - sslcert_access_token="$(_make_sslcreate_access_token "$sslcert_path")" + sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$Le_Deploy_Qiniu_Cdn_Domain\",\"ca\":\"$string_fullchain\",\"pri\":\"$string_key\"}" + 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") @@ -68,9 +74,9 @@ qiniu_deploy() { _debug certId "$_certId" ## update domain ssl config - update_path="/domain/$_cdndomain/httpsconf" - update_body="{\"certid\":$_certId,\"forceHttps\":true}" - update_access_token="$(_make_sslcreate_access_token "$update_path")" + update_path="/domain/$Le_Deploy_Qiniu_Cdn_Domain/httpsconf" + update_body="{\"certid\":$_certId,\"forceHttps\":false}" + 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") @@ -87,7 +93,7 @@ qiniu_deploy() { return 0 } -_make_sslcreate_access_token() { +_make_access_token() { _token="$(printf "%s\n" "$1" | _hmac "sha1" "$(printf "%s" "$Le_Deploy_Qiniu_SK" | _hex_dump | tr -d " ")" | _base64)" echo "$Le_Deploy_Qiniu_AK:$_token" } From 10ba2cd312fb346a9af32a808ddbfa1d55b83879 Mon Sep 17 00:00:00 2001 From: jim-p Date: Thu, 10 Jan 2019 16:06:46 -0500 Subject: [PATCH 0116/2234] Use a literal space instead of an escaped space. Fixes #2022 --- dnsapi/dns_namecheap.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index a6651be6..2f401bd9 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -161,12 +161,12 @@ _namecheap_parse_host() { _host=$1 _debug _host "$_host" - _hostid=$(echo "$_host" | _egrep_o '\sHostId="[^"]*' | cut -d '"' -f 2) - _hostname=$(echo "$_host" | _egrep_o '\sName="[^"]*' | cut -d '"' -f 2) - _hosttype=$(echo "$_host" | _egrep_o '\sType="[^"]*' | cut -d '"' -f 2) - _hostaddress=$(echo "$_host" | _egrep_o '\sAddress="[^"]*' | cut -d '"' -f 2) - _hostmxpref=$(echo "$_host" | _egrep_o '\sMXPref="[^"]*' | cut -d '"' -f 2) - _hostttl=$(echo "$_host" | _egrep_o '\sTTL="[^"]*' | cut -d '"' -f 2) + _hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2) + _hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2) + _hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2) + _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2) + _hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2) + _hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2) _debug hostid "$_hostid" _debug hostname "$_hostname" From afdb9a63ffa4540dd8d3097492b8940b21b50907 Mon Sep 17 00:00:00 2001 From: shonenada Date: Sat, 19 Jan 2019 23:58:55 +0800 Subject: [PATCH 0117/2234] chore: replece `Le_Deploy_Qiniu_*` with `QINIU_*` --- deploy/qiniu.sh | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index a97dfbbf..aadda53b 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -23,38 +23,31 @@ qiniu_deploy() { _debug _cfullchain "$_cfullchain" if [ -z "$QINIU_AK" ]; then - if [ -z "$Le_Deploy_Qiniu_AK" ]; then - _err "QINIU_AK is not defined." - return 1 - fi + _err "QINIU_AK is not defined." + return 1 else - Le_Deploy_Qiniu_AK="$QINIU_AK" - _savedomainconf Le_Deploy_Qiniu_AK "$Le_Deploy_Qiniu_AK" + _savedomainconf QINIU_AK "$QINIU_AK" fi if [ -z "$QINIU_SK" ]; then - if [ -z "$Le_Deploy_Qiniu_SK" ]; then - _err "QINIU_SK is not defined." - return 1 - fi + _err "QINIU_SK is not defined." + return 1 else - Le_Deploy_Qiniu_SK="$QINIU_SK" - _savedomainconf Le_Deploy_Qiniu_SK "$Le_Deploy_Qiniu_SK" + _savedomainconf QINIU_SK "$QINIU_SK" fi - Le_Deploy_Qiniu_Cdn_Domain="${QINIU_CDN_DOMAIN:-$(_readdomainconf Le_Deploy_Qiniu_Cdn_Domain)}" - if [ -z "$Le_Deploy_Qiniu_Cdn_Domain" ]; then - Le_Deploy_Qiniu_Cdn_Domain="$_cdomain" + if [ -z "$QINIU_CDN_DOMAIN" ]; then + QINIU_CDN_DOMAIN="$_cdomain" fi - _savedomainconf Le_Deploy_Qiniu_Cdn_Domain "$Le_Deploy_Qiniu_Cdn_Domain" + _savedomainconf QINIU_CDN_DOMAIN "$QINIU_CDN_DOMAIN" ## upload certificate string_fullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n') string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') sslcert_path="/sslcert" - sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$Le_Deploy_Qiniu_Cdn_Domain\",\"ca\":\"$string_fullchain\",\"pri\":\"$string_key\"}" + sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$QINIU_CDN_DOMAIN\",\"ca\":\"$string_fullchain\",\"pri\":\"$string_key\"}" sslcert_access_token="$(_make_access_token "$sslcert_path")" _debug sslcert_access_token "$sslcert_access_token" export _H1="Authorization: QBox $sslcert_access_token" @@ -74,7 +67,7 @@ qiniu_deploy() { _debug certId "$_certId" ## update domain ssl config - update_path="/domain/$Le_Deploy_Qiniu_Cdn_Domain/httpsconf" + update_path="/domain/$QINIU_CDN_DOMAIN/httpsconf" update_body="{\"certid\":$_certId,\"forceHttps\":false}" update_access_token="$(_make_access_token "$update_path")" _debug update_access_token "$update_access_token" @@ -94,6 +87,6 @@ qiniu_deploy() { } _make_access_token() { - _token="$(printf "%s\n" "$1" | _hmac "sha1" "$(printf "%s" "$Le_Deploy_Qiniu_SK" | _hex_dump | tr -d " ")" | _base64)" - echo "$Le_Deploy_Qiniu_AK:$_token" + _token="$(printf "%s\n" "$1" | _hmac "sha1" "$(printf "%s" "$QINIU_SK" | _hex_dump | tr -d " ")" | _base64)" + echo "$QINIU_AK:$_token" } From dd6fa4af0075248585202eab93ac89f51b652c0e Mon Sep 17 00:00:00 2001 From: shonenada Date: Sun, 20 Jan 2019 23:58:10 +0800 Subject: [PATCH 0118/2234] Save `QINIU_CDN_DOMAIN` only when defined --- deploy/qiniu.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index aadda53b..8410caa9 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -36,12 +36,12 @@ qiniu_deploy() { _savedomainconf QINIU_SK "$QINIU_SK" fi - if [ -z "$QINIU_CDN_DOMAIN" ]; then - QINIU_CDN_DOMAIN="$_cdomain" + if [ "$QINIU_CDN_DOMAIN" ]; then + _savedomainconf QINIU_CDN_DOMAIN "$QINIU_CDN_DOMAIN" + else + QINIU_CDN_DOMAIN="$_cdomain" fi - _savedomainconf QINIU_CDN_DOMAIN "$QINIU_CDN_DOMAIN" - ## upload certificate string_fullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n') string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') From e8eec2cb41b34bf52fff36647a4861bec23fa653 Mon Sep 17 00:00:00 2001 From: shonenada Date: Mon, 21 Jan 2019 00:08:23 +0800 Subject: [PATCH 0119/2234] add chinese readme --- deploy/README.md | 2 ++ deploy/README_zh.md | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 deploy/README_zh.md diff --git a/deploy/README.md b/deploy/README.md index fa2d7189..a9e28e9e 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -335,6 +335,8 @@ export FABIO="1" ## 13. Deploy your certificate to Qiniu.com +[中文文档](https://github.com/Neilpang/acme.sh/blob/master/deploy/README_zh.md#13-%E9%83%A8%E7%BD%B2%E5%88%B0%E4%B8%83%E7%89%9B%E5%9F%9F%E5%90%8D%E8%AF%81%E4%B9%A6%E6%9C%8D%E5%8A%A1) + You should create AccessKey/SecretKey pair in https://portal.qiniu.com/user/key before deploying your certificate, and please ensure you have enabled HTTPS for your domain name. You can enable it in https://portal.qiniu.com/cdn/domain. diff --git a/deploy/README_zh.md b/deploy/README_zh.md new file mode 100644 index 00000000..4132dcea --- /dev/null +++ b/deploy/README_zh.md @@ -0,0 +1,24 @@ +# Deploy 使用文档 + +## 13. 部署到七牛域名证书服务 + +使用 acme.sh 部署到七牛之前,需要确保部署的域名已打开 HTTPS 功能,您可以访问[融合 CDN - 域名管理](https://portal.qiniu.com/cdn/domain) 设置。 +另外还需要先导出 AK/SK 环境变量,您可以访问[密钥管理](https://portal.qiniu.com/user/key) 获得。 + +```sh +$ export QINIU_AK="foo" +$ export QINIU_SK="bar" +``` + +完成准备工作之后,您就可以通过下面的命令开始部署 SSL 证书到七牛上: + +```sh +$ acme.sh --deploy -d example.com --deploy-hook qiniu +``` + +假如您部署的证书为泛域名证书,您还需要设置 `QINIU_CDN_DOMAIN` 变量,指定实际需要部署的域名: + +```sh +$ export QINIU_CDN_DOMAIN="cdn.example.com" +$ acme.sh --deploy -d example.com --deploy-hook qiniu +``` From c445e70cffe326219b8d597867ba28ae85523ba1 Mon Sep 17 00:00:00 2001 From: shonenada Date: Mon, 21 Jan 2019 14:33:15 +0800 Subject: [PATCH 0120/2234] fix indent --- deploy/qiniu.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index 8410caa9..158b8dbf 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -37,9 +37,9 @@ qiniu_deploy() { fi if [ "$QINIU_CDN_DOMAIN" ]; then - _savedomainconf QINIU_CDN_DOMAIN "$QINIU_CDN_DOMAIN" + _savedomainconf QINIU_CDN_DOMAIN "$QINIU_CDN_DOMAIN" else - QINIU_CDN_DOMAIN="$_cdomain" + QINIU_CDN_DOMAIN="$_cdomain" fi ## upload certificate From a4a53e1355503efa8a550f954f59cc3a2b763935 Mon Sep 17 00:00:00 2001 From: shonenada Date: Mon, 21 Jan 2019 17:31:21 +0800 Subject: [PATCH 0121/2234] Move docs into README.md from README_zh.md --- deploy/README.md | 23 ++++++++++++++++++++++- deploy/README_zh.md | 24 ------------------------ 2 files changed, 22 insertions(+), 25 deletions(-) delete mode 100644 deploy/README_zh.md diff --git a/deploy/README.md b/deploy/README.md index a9e28e9e..091e9feb 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -335,7 +335,28 @@ export FABIO="1" ## 13. Deploy your certificate to Qiniu.com -[中文文档](https://github.com/Neilpang/acme.sh/blob/master/deploy/README_zh.md#13-%E9%83%A8%E7%BD%B2%E5%88%B0%E4%B8%83%E7%89%9B%E5%9F%9F%E5%90%8D%E8%AF%81%E4%B9%A6%E6%9C%8D%E5%8A%A1) +使用 acme.sh 部署到七牛之前,需要确保部署的域名已打开 HTTPS 功能,您可以访问[融合 CDN - 域名管理](https://portal.qiniu.com/cdn/domain) 设置。 +另外还需要先导出 AK/SK 环境变量,您可以访问[密钥管理](https://portal.qiniu.com/user/key) 获得。 + +```sh +$ export QINIU_AK="foo" +$ export QINIU_SK="bar" +``` + +完成准备工作之后,您就可以通过下面的命令开始部署 SSL 证书到七牛上: + +```sh +$ acme.sh --deploy -d example.com --deploy-hook qiniu +``` + +假如您部署的证书为泛域名证书,您还需要设置 `QINIU_CDN_DOMAIN` 变量,指定实际需要部署的域名: + +```sh +$ export QINIU_CDN_DOMAIN="cdn.example.com" +$ acme.sh --deploy -d example.com --deploy-hook qiniu +``` + +### English version You should create AccessKey/SecretKey pair in https://portal.qiniu.com/user/key before deploying your certificate, and please ensure you have enabled HTTPS for diff --git a/deploy/README_zh.md b/deploy/README_zh.md deleted file mode 100644 index 4132dcea..00000000 --- a/deploy/README_zh.md +++ /dev/null @@ -1,24 +0,0 @@ -# Deploy 使用文档 - -## 13. 部署到七牛域名证书服务 - -使用 acme.sh 部署到七牛之前,需要确保部署的域名已打开 HTTPS 功能,您可以访问[融合 CDN - 域名管理](https://portal.qiniu.com/cdn/domain) 设置。 -另外还需要先导出 AK/SK 环境变量,您可以访问[密钥管理](https://portal.qiniu.com/user/key) 获得。 - -```sh -$ export QINIU_AK="foo" -$ export QINIU_SK="bar" -``` - -完成准备工作之后,您就可以通过下面的命令开始部署 SSL 证书到七牛上: - -```sh -$ acme.sh --deploy -d example.com --deploy-hook qiniu -``` - -假如您部署的证书为泛域名证书,您还需要设置 `QINIU_CDN_DOMAIN` 变量,指定实际需要部署的域名: - -```sh -$ export QINIU_CDN_DOMAIN="cdn.example.com" -$ acme.sh --deploy -d example.com --deploy-hook qiniu -``` From 56d70e4ea74d2c1274326ec0ac9c93657d9b4e94 Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Mon, 21 Jan 2019 15:02:09 +0100 Subject: [PATCH 0122/2234] Update to latest API Changes --- dnsapi/dns_hostingde.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 74a472d2..7c185119 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -59,9 +59,22 @@ _hostingde_getZoneConfig() { if _contains "${curResult}" '"totalEntries": 1'; then _info "Retrieved zone data." _debug "Zone data: '${curResult}'" - - # read ZoneConfigId for later update zoneConfigId=$(echo "${curResult}" | _egrep_o '"id":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + zoneConfigName=$(echo "${curResult}" | _egrep_o '"name":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + zoneConfigType=$(echo "${curResult}" | grep -v "FindZoneConfigsResult" | _egrep_o '"type":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + zoneConfigExpire=$(echo "${curResult}" | _egrep_o '"expire":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) + zoneConfigNegativeTtl=$(echo "${curResult}" | _egrep_o '"negativeTtl":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) + zoneConfigRefresh=$(echo "${curResult}" | _egrep_o '"refresh":.*' | cut -d ':' -f 2 | cut -d '"' -f 2| cut -d ',' -f 1) + zoneConfigRetry=$(echo "${curResult}" | _egrep_o '"retry":.*' | cut -d ':' -f 2 | cut -d '"' -f 2| cut -d ',' -f 1) + zoneConfigTtl=$(echo "${curResult}" | _egrep_o '"ttl":.*' | cut -d ':' -f 2 | cut -d '"' -f 2| cut -d ',' -f 1) + zoneConfigDnsServerGroupId=$(echo "${curResult}" | _egrep_o '"dnsServerGroupId":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + zoneConfigEmailAddress=$(echo "${curResult}" | _egrep_o '"emailAddress":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + zoneConfigDnsSecMode=$(echo "${curResult}" | _egrep_o '"dnsSecMode":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + if [ $zoneConfigType != "NATIVE" ]; then + _err "Zone is not native" + returnCode=1 + break + fi _debug "zoneConfigId '${zoneConfigId}'" returnCode=0 break @@ -94,7 +107,7 @@ _hostingde_addRecord() { _hostingde_getZoneStatus _debug "Result of zoneStatus: '${zoneStatus}'" done - curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\"},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}" + curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\",\"name\":\"${zoneConfigName}\",\"type\":\"${zoneConfigType}\",\"dnsServerGroupId\":\"${zoneConfigDnsServerGroupId}\",\"dnsSecMode\":\"${zoneConfigDnsSecMode}\",\"emailAddress\":\"${zoneConfigEmailAddress}\",\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}" curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" _debug "Result of zoneUpdate: '$curResult'" @@ -118,7 +131,7 @@ _hostingde_removeRecord() { _hostingde_getZoneStatus _debug "Result of zoneStatus: '$zoneStatus'" done - curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\"},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}" + curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\",\"name\":\"${zoneConfigName}\",\"type\":\"${zoneConfigType}\",\"dnsServerGroupId\":\"${zoneConfigDnsServerGroupId}\",\"dnsSecMode\":\"${zoneConfigDnsSecMode}\",\"emailAddress\":\"${zoneConfigEmailAddress}\",\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}" curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" _debug "Result of zoneUpdate: '$curResult'" From b15c1ffedcd1d627e6339396179e7691ca83938e Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 21 Jan 2019 22:09:13 +0800 Subject: [PATCH 0123/2234] clean TXT records when error happens. https://github.com/Neilpang/acme.sh/issues/2037 --- acme.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index ff472867..697a14a4 100755 --- a/acme.sh +++ b/acme.sh @@ -2921,7 +2921,10 @@ _clearup() { _clearupdns() { _debug "_clearupdns" - if [ "$dnsadded" != 1 ] || [ -z "$vlist" ]; then + _debug "dnsadded" "$dnsadded" + _debug "vlist" "$vlist" + #dnsadded is "0" or "1" means dns-01 method was used for at least one domain + if [ -z "$dnsadded" ] || [ -z "$vlist" ]; then _debug "skip dns." return fi From 545f23551f09082799f02a159ed6ade2aa4eb36f Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 21 Jan 2019 22:25:23 +0800 Subject: [PATCH 0124/2234] trigger validation before cleanup fix https://github.com/Neilpang/acme.sh/issues/2037 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 697a14a4..d651c4f5 100755 --- a/acme.sh +++ b/acme.sh @@ -3857,8 +3857,8 @@ $_authorizations_map" ) if [ "$?" != "0" ]; then - _clearup _on_issue_err "$_post_hook" "$vlist" + _clearup return 1 fi dnsadded='1' @@ -3869,8 +3869,8 @@ $_authorizations_map" _savedomainconf "Le_Vlist" "$vlist" _debug "Dns record not added yet, so, save to $DOMAIN_CONF and exit." _err "Please add the TXT records to the domains, and re-run with --renew." - _clearup _on_issue_err "$_post_hook" + _clearup return 1 fi From 2dc50e66330c291fafee95d1b8d7183e413df647 Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Mon, 21 Jan 2019 15:45:32 +0100 Subject: [PATCH 0125/2234] making shfmt happy --- dnsapi/dns_hostingde.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 7c185119..7f29d629 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -64,9 +64,9 @@ _hostingde_getZoneConfig() { zoneConfigType=$(echo "${curResult}" | grep -v "FindZoneConfigsResult" | _egrep_o '"type":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) zoneConfigExpire=$(echo "${curResult}" | _egrep_o '"expire":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) zoneConfigNegativeTtl=$(echo "${curResult}" | _egrep_o '"negativeTtl":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) - zoneConfigRefresh=$(echo "${curResult}" | _egrep_o '"refresh":.*' | cut -d ':' -f 2 | cut -d '"' -f 2| cut -d ',' -f 1) - zoneConfigRetry=$(echo "${curResult}" | _egrep_o '"retry":.*' | cut -d ':' -f 2 | cut -d '"' -f 2| cut -d ',' -f 1) - zoneConfigTtl=$(echo "${curResult}" | _egrep_o '"ttl":.*' | cut -d ':' -f 2 | cut -d '"' -f 2| cut -d ',' -f 1) + zoneConfigRefresh=$(echo "${curResult}" | _egrep_o '"refresh":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) + zoneConfigRetry=$(echo "${curResult}" | _egrep_o '"retry":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) + zoneConfigTtl=$(echo "${curResult}" | _egrep_o '"ttl":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) zoneConfigDnsServerGroupId=$(echo "${curResult}" | _egrep_o '"dnsServerGroupId":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) zoneConfigEmailAddress=$(echo "${curResult}" | _egrep_o '"emailAddress":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) zoneConfigDnsSecMode=$(echo "${curResult}" | _egrep_o '"dnsSecMode":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) From b0775f7a580ac534ad2443cd9308fab5b339749f Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Mon, 21 Jan 2019 16:32:45 +0100 Subject: [PATCH 0126/2234] making shftm really happy --- dnsapi/dns_hostingde.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 7f29d629..b61acb7a 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -70,7 +70,7 @@ _hostingde_getZoneConfig() { zoneConfigDnsServerGroupId=$(echo "${curResult}" | _egrep_o '"dnsServerGroupId":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) zoneConfigEmailAddress=$(echo "${curResult}" | _egrep_o '"emailAddress":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) zoneConfigDnsSecMode=$(echo "${curResult}" | _egrep_o '"dnsSecMode":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) - if [ $zoneConfigType != "NATIVE" ]; then + if [ "${zoneConfigType}" != "NATIVE" ]; then _err "Zone is not native" returnCode=1 break From 572adbaad2c8531870753c18c2b313c70faa9a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A1la?= Date: Mon, 31 Dec 2018 20:05:08 +0100 Subject: [PATCH 0127/2234] Add support for Active24.cz --- README.md | 1 + dnsapi/README.md | 18 ++++++ dnsapi/dns_active24.sh | 141 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100755 dnsapi/dns_active24.sh diff --git a/README.md b/README.md index 41ffb694..70abcc6c 100644 --- a/README.md +++ b/README.md @@ -349,6 +349,7 @@ You don't have to do anything manually! 1. Neodigit.net API (https://www.neodigit.net) 1. Exoscale.com API (https://www.exoscale.com/) 1. PointDNS API (https://pointhq.com/) +1. Active24.cz API (https://www.active24.cz/) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index fc65748e..0a9c4925 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1139,6 +1139,24 @@ You can then issue certs by using: ```acme.sh --issue --dns dns_pointhq -d example.com -d www.example.com ``` +## 59. Use Active24 API + +Create an API token in the Active24 account section, documentation on https://faq.active24.com/cz/790131-REST-API-rozhran%C3%AD. + +Set your API token: + +``` +export ACTIVE24_Token='xxx' +``` + +Now, let's issue a cert, set `dnssleep` for propagation new DNS record: +``` +acme.sh --issue --dns dns_active24 -d example.com -d www.example.com --dnssleep 1000 +``` + +The `ACTIVE24_Token` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_active24.sh b/dnsapi/dns_active24.sh new file mode 100755 index 00000000..90ffaf68 --- /dev/null +++ b/dnsapi/dns_active24.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env sh + +#ACTIVE24_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" + +ACTIVE24_Api="https://api.active24.com" + +######## Public functions ##################### + +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record +dns_active24_add() { + fulldomain=$1 + txtvalue=$2 + + _active24_init + + _info "Adding txt record" + if _active24_rest POST "dns/$_domain/txt/v1" "{\"name\":\"$_sub_domain\",\"text\":\"$txtvalue\",\"ttl\":0}"; then + if _contains "$response" "errors"; then + _err "Add txt record error." + return 1 + else + _info "Added, OK" + return 0 + fi + fi + _err "Add txt record error." + return 1 +} + +# Usage: fulldomain txtvalue +# Used to remove the txt record after validation +dns_active24_rm() { + fulldomain=$1 + txtvalue=$2 + + _active24_init + + _debug "Getting txt records" + _active24_rest GET "dns/$_domain/records/v1" + + if _contains "$response" "errors"; then + _err "Error" + return 1 + fi + + hash_ids=$(echo "$response" | _egrep_o "[^{]+${txtvalue}[^}]+" | _egrep_o "hashId\":\"[^\"]+" | cut -c10-) + + for hash_id in $hash_ids; do + _debug "Removing hash_id" "$hash_id" + if _active24_rest DELETE "dns/$_domain/$hash_id/v1" ""; then + if _contains "$response" "errors"; then + _err "Unable to remove txt record." + return 1 + else + _info "Removed txt record." + return 0 + fi + fi + done + + _err "No txt records found." + return 1 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=sdjkglgdfewsdfg +_get_root() { + domain=$1 + + if ! _active24_rest GET "dns/domains/v1"; then + return 1 + fi + + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug "h" "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if _contains "$response" "\"$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 +} + +_active24_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + export _H1="Authorization: Bearer $ACTIVE24_Token" + + if [ "$m" != "GET" ]; then + _debug "data" "$data" + response="$(_post "$data" "$ACTIVE24_Api/$ep" "" "$m" "application/json")" + else + response="$(_get "$ACTIVE24_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} + +_active24_init() { + ACTIVE24_Token="${ACTIVE24_Token:-$(_readaccountconf_mutable ACTIVE24_Token)}" + if [ -z "$ACTIVE24_Token" ]; then + ACTIVE24_Token="" + _err "You didn't specify a Active24 api token yet." + _err "Please create the token and try again." + return 1 + fi + + _saveaccountconf_mutable ACTIVE24_Token "ACTIVE24_Token" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" +} From 127532c226149b991814bd696b1362b079fa8c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20M=C3=A4del?= Date: Thu, 24 Jan 2019 16:53:03 +0100 Subject: [PATCH 0128/2234] Added dns_doapi.sh --- dnsapi/dns_doapi.sh | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100755 dnsapi/dns_doapi.sh diff --git a/dnsapi/dns_doapi.sh b/dnsapi/dns_doapi.sh new file mode 100755 index 00000000..f3d56b68 --- /dev/null +++ b/dnsapi/dns_doapi.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env sh + +# Official Let's Encrypt API for do.de / Domain-Offensive +# +# This is different from the dns_do adapter, because dns_do is only usable for enterprise customers +# This API is also available to private customers/individuals +# +# Provide the required LetsEncrypt token like this: +# DO_LETOKEN="FmD408PdqT1E269gUK57" + +DO_API="https://www.do.de/api/letsencrypt" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_doapi_add() { + fulldomain=$1 + txtvalue=$2 + + DO_LETOKEN="${DO_LETOKEN:-$(_readaccountconf_mutable DO_LETOKEN)}" + if [ -z "$DO_LETOKEN" ]; then + DO_LETOKEN="" + _err "You didn't configure a do.de API token yet." + _err "Please set DO_LETOKEN and try again." + return 1 + fi + _saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN" + + _info "Adding TXT record to ${_domain} as ${fulldomain}" + response="$(_get "$DO_API?token=$DO_LETOKEN&domain=${fulldomain}&value=${txtvalue}")" + if _contains "${response}" 'success'; then + return 0 + fi + _err "Could not create resource record, check logs" + _err $response + return 1 +} + +dns_doapi_rm() { + fulldomain=$1 + + DO_LETOKEN="${DO_LETOKEN:-$(_readaccountconf_mutable DO_LETOKEN)}" + if [ -z "$DO_LETOKEN" ]; then + DO_LETOKEN="" + _err "You didn't configure a do.de API token yet." + _err "Please set DO_LETOKEN and try again." + return 1 + fi + _saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN" + + _info "Deleting resource record $fulldomain" + response="$(_get "$DO_API?token=$DO_LETOKEN&domain=${fulldomain}&action=delete")" + if _contains "${response}" 'success'; then + return 0 + fi + _err "Could not delete resource record, check logs" + _err $response + return 1 +} From ddf77f10e95e6daf22b99a7e5986912d58ff4b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20M=C3=A4del?= Date: Thu, 24 Jan 2019 16:59:36 +0100 Subject: [PATCH 0129/2234] Cleaned up dns_doapi.sh --- dnsapi/dns_doapi.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_doapi.sh b/dnsapi/dns_doapi.sh index f3d56b68..fa2b7d33 100755 --- a/dnsapi/dns_doapi.sh +++ b/dnsapi/dns_doapi.sh @@ -26,13 +26,13 @@ dns_doapi_add() { fi _saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN" - _info "Adding TXT record to ${_domain} as ${fulldomain}" + _info "Adding TXT record to ${fulldomain}" response="$(_get "$DO_API?token=$DO_LETOKEN&domain=${fulldomain}&value=${txtvalue}")" if _contains "${response}" 'success'; then return 0 fi _err "Could not create resource record, check logs" - _err $response + _err "${response}" return 1 } @@ -54,6 +54,6 @@ dns_doapi_rm() { return 0 fi _err "Could not delete resource record, check logs" - _err $response + _err "${response}" return 1 } From 5f9b57d3004831cbd0e4455c0676633c56b5f708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20M=C3=A4del?= Date: Thu, 24 Jan 2019 17:00:37 +0100 Subject: [PATCH 0130/2234] Cleaned up dns_doapi.sh --- dnsapi/dns_doapi.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_doapi.sh b/dnsapi/dns_doapi.sh index fa2b7d33..135f0b03 100755 --- a/dnsapi/dns_doapi.sh +++ b/dnsapi/dns_doapi.sh @@ -24,7 +24,7 @@ dns_doapi_add() { _err "Please set DO_LETOKEN and try again." return 1 fi - _saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN" + _saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN" _info "Adding TXT record to ${fulldomain}" response="$(_get "$DO_API?token=$DO_LETOKEN&domain=${fulldomain}&value=${txtvalue}")" @@ -46,7 +46,7 @@ dns_doapi_rm() { _err "Please set DO_LETOKEN and try again." return 1 fi - _saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN" + _saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN" _info "Deleting resource record $fulldomain" response="$(_get "$DO_API?token=$DO_LETOKEN&domain=${fulldomain}&action=delete")" From e2f1338f941dfca192ebc51c1cb65bb09bf8f6d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20M=C3=A4del?= Date: Thu, 24 Jan 2019 17:05:01 +0100 Subject: [PATCH 0131/2234] Added documentation --- dnsapi/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dnsapi/README.md b/dnsapi/README.md index fc65748e..e0532bcd 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1139,6 +1139,22 @@ You can then issue certs by using: ```acme.sh --issue --dns dns_pointhq -d example.com -d www.example.com ``` +## 59. Use do.de API + +Create an API token in your do.de account. + +Set your API token: +``` +export DO_LETOKEN='FmD408PdqT1E269gUK57' +``` + +To issue a certificate run: +``` +acme.sh --issue --dns dns_doapi -d example.com -d *.example.com +``` + +The API token will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. From c1ec2afeca11ad8afdb8feec5e6e3bba1bf113da Mon Sep 17 00:00:00 2001 From: Grant Millar Date: Fri, 25 Jan 2019 09:27:30 +0000 Subject: [PATCH 0132/2234] Changed records per page to 5000 --- dnsapi/dns_dnsimple.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsimple.sh b/dnsapi/dns_dnsimple.sh index b2cba584..d831eb2b 100644 --- a/dnsapi/dns_dnsimple.sh +++ b/dnsapi/dns_dnsimple.sh @@ -152,7 +152,7 @@ _get_records() { sub_domain=$3 _debug "fetching txt records" - _dnsimple_rest GET "$account_id/zones/$domain/records?per_page=100&sort=id:desc" + _dnsimple_rest GET "$account_id/zones/$domain/records?per_page=5000&sort=id:desc" if ! _contains "$response" "\"id\":"; then _err "failed to retrieve records" From 75fe022f96dce0baeaef6f8fe9c206f8ab094d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20M=C3=A4del?= Date: Fri, 25 Jan 2019 15:26:41 +0100 Subject: [PATCH 0133/2234] Changed order in readme, added do.de --- README.md | 1 + dnsapi/README.md | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 70abcc6c..90a648d5 100644 --- a/README.md +++ b/README.md @@ -350,6 +350,7 @@ You don't have to do anything manually! 1. Exoscale.com API (https://www.exoscale.com/) 1. PointDNS API (https://pointhq.com/) 1. Active24.cz API (https://www.active24.cz/) +1. do.de API (https://www.do.de/) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index dc20ac9c..4f9b4100 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1139,23 +1139,7 @@ You can then issue certs by using: ```acme.sh --issue --dns dns_pointhq -d example.com -d www.example.com ``` -## 59. Use do.de API - -Create an API token in your do.de account. - -Set your API token: -``` -export DO_LETOKEN='FmD408PdqT1E269gUK57' -``` - -To issue a certificate run: -``` -acme.sh --issue --dns dns_doapi -d example.com -d *.example.com -``` - -The API token will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 60. Use Active24 API +## 59. Use Active24 API Create an API token in the Active24 account section, documentation on https://faq.active24.com/cz/790131-REST-API-rozhran%C3%AD. @@ -1172,6 +1156,22 @@ acme.sh --issue --dns dns_active24 -d example.com -d www.example.com --dnssleep The `ACTIVE24_Token` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 60. Use do.de API + +Create an API token in your do.de account. + +Set your API token: +``` +export DO_LETOKEN='FmD408PdqT1E269gUK57' +``` + +To issue a certificate run: +``` +acme.sh --issue --dns dns_doapi -d example.com -d *.example.com +``` + +The API token will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. From 36335984629d07d7c048981cea921bce60e37dbf Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jan 2019 22:39:22 +0800 Subject: [PATCH 0134/2234] Lets start 2.8.1 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d651c4f5..85c17f16 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.0 +VER=2.8.1 PROJECT_NAME="acme.sh" From 43ff787b04b56fb1b8cf73857351c8fbad1c382e Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 26 Jan 2019 18:32:11 +0800 Subject: [PATCH 0135/2234] remove tls-sni --- acme.sh | 44 ++------------------------------------------ 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/acme.sh b/acme.sh index 85c17f16..cfdf5714 100755 --- a/acme.sh +++ b/acme.sh @@ -35,7 +35,6 @@ _OLD_STAGE_CA_HOST="https://acme-staging.api.letsencrypt.org" VTYPE_HTTP="http-01" VTYPE_DNS="dns-01" -VTYPE_TLS="tls-sni-01" VTYPE_ALPN="tls-alpn-01" LOCAL_ANY_ADDRESS="0.0.0.0" @@ -46,7 +45,6 @@ DEFAULT_DNS_SLEEP=120 NO_VALUE="no" -W_TLS="tls" W_DNS="dns" W_ALPN="alpn" DNS_ALIAS_PREFIX="=" @@ -3080,8 +3078,8 @@ _on_before_issue() { _savedomainconf "Le_HTTPPort" "$Le_HTTPPort" fi _checkport="$Le_HTTPPort" - elif [ "$_currentRoot" = "$W_TLS" ] || [ "$_currentRoot" = "$W_ALPN" ]; then - _info "Standalone tls/alpn mode." + elif [ "$_currentRoot" = "$W_ALPN" ]; then + _info "Standalone alpn mode." if [ -z "$Le_TLSPort" ]; then Le_TLSPort=443 else @@ -3701,10 +3699,6 @@ $_authorizations_map" vtype="$VTYPE_DNS" fi - if [ "$_currentRoot" = "$W_TLS" ]; then - vtype="$VTYPE_TLS" - fi - if [ "$_currentRoot" = "$W_ALPN" ]; then vtype="$VTYPE_ALPN" fi @@ -3988,40 +3982,6 @@ $_authorizations_map" fi fi - - elif [ "$vtype" = "$VTYPE_TLS" ]; then - #create A - #_hash_A="$(printf "%s" $token | _digest "sha256" "hex" )" - #_debug2 _hash_A "$_hash_A" - #_x="$(echo $_hash_A | cut -c 1-32)" - #_debug2 _x "$_x" - #_y="$(echo $_hash_A | cut -c 33-64)" - #_debug2 _y "$_y" - #_SAN_A="$_x.$_y.token.acme.invalid" - #_debug2 _SAN_A "$_SAN_A" - - #create B - _hash_B="$(printf "%s" "$keyauthorization" | _digest "sha256" "hex")" - _debug2 _hash_B "$_hash_B" - _x="$(echo "$_hash_B" | cut -c 1-32)" - _debug2 _x "$_x" - _y="$(echo "$_hash_B" | cut -c 33-64)" - _debug2 _y "$_y" - - #_SAN_B="$_x.$_y.ka.acme.invalid" - - _SAN_B="$_x.$_y.acme.invalid" - _debug2 _SAN_B "$_SAN_B" - - _ncaddr="$(_getfield "$_local_addr" "$_ncIndex")" - _ncIndex="$(_math "$_ncIndex" + 1)" - if ! _starttlsserver "$_SAN_B" "$_SAN_A" "$Le_TLSPort" "$keyauthorization" "$_ncaddr"; then - _err "Start tls server error." - _clearupwebbroot "$_currentRoot" "$removelevel" "$token" - _clearup - _on_issue_err "$_post_hook" "$vlist" - return 1 - fi elif [ "$vtype" = "$VTYPE_ALPN" ]; then acmevalidationv1="$(printf "%s" "$keyauthorization" | _digest "sha256" "hex")" _debug acmevalidationv1 "$acmevalidationv1" From cc6159b39b5305778e1f437fcbe2673a3012cb13 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 26 Jan 2019 19:15:13 +0800 Subject: [PATCH 0136/2234] urlencode the existing txt record value fix https://github.com/Neilpang/acme.sh/issues/2052 --- dnsapi/dns_namecheap.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 2f401bd9..27eda3ad 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -3,16 +3,15 @@ # Namecheap API # https://www.namecheap.com/support/api/intro.aspx # -# Requires Namecheap API key set in NAMECHEAP_API_KEY, NAMECHEAP_SOURCEIP and NAMECHEAP_USERNAME set as environment variable +# Requires Namecheap API key set in +#NAMECHEAP_API_KEY, +#NAMECHEAP_USERNAME, +#NAMECHEAP_SOURCEIP # Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise. ######## Public functions ##################### -if [ "$STAGE" -eq 1 ]; then - NAMECHEAP_API="https://api.sandbox.namecheap.com/xml.response" -else - NAMECHEAP_API="https://api.namecheap.com/xml.response" -fi +NAMECHEAP_API="https://api.namecheap.com/xml.response" #Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_namecheap_add() { @@ -144,7 +143,7 @@ _namecheap_set_publicip() { _namecheap_post() { command=$1 data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}" - + _debug2 "_namecheap_post data" "$data" response="$(_post "$data" "$NAMECHEAP_API" "" "POST")" _debug2 response "$response" @@ -224,6 +223,12 @@ _set_namecheap_TXT() { while read -r host; do if _contains "$host" " Date: Sat, 26 Jan 2019 20:27:53 +0800 Subject: [PATCH 0137/2234] fix rm method to urlencode the existing txt records. fix https://github.com/Neilpang/acme.sh/issues/2052 --- dnsapi/dns_namecheap.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 27eda3ad..fbf93c32 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -283,6 +283,7 @@ _del_namecheap_TXT() { _debug "TXT entry found" found=1 else + _hostaddress="$(printf "%s" "$_hostaddress" | _url_encode)" _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl" fi fi From a96464680361dde97e1388b81de275756612ba83 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 28 Jan 2019 19:11:45 +0800 Subject: [PATCH 0138/2234] fix https://github.com/Neilpang/acme.sh/issues/1364#issuecomment-458035330 --- dnsapi/dns_dp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 3cc720aa..6bbf149e 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -63,7 +63,7 @@ dns_dp_rm() { return 0 fi - record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'"$txtvalue"'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \") + record_id=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2) _debug record_id "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id." From 227547f8263a87d9241a8f0a5de84ded1c6aa3d3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 30 Jan 2019 20:13:23 +0800 Subject: [PATCH 0139/2234] fix https://github.com/Neilpang/acme.sh/pull/1979 --- dnsapi/dns_linode_v4.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index dfa1a651..c9a83c77 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -8,7 +8,7 @@ LINODE_V4_API_URL="https://api.linode.com/v4/domains" ######## Public functions ##################### #Usage: dns_linode_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_linode_add() { +dns_linode_v4_add() { fulldomain="${1}" txtvalue="${2}" @@ -51,7 +51,7 @@ dns_linode_add() { } #Usage: dns_linode_rm _acme-challenge.www.domain.com -dns_linode_rm() { +dns_linode_v4_rm() { fulldomain="${1}" if ! _Linode_API; then From 759b75ca482db36b6862dc5ba181c4230893deb7 Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Mon, 4 Feb 2019 11:27:04 +0100 Subject: [PATCH 0140/2234] better parsing of json responses fixes an error if customer does not have access to dns-groups --- dnsapi/dns_hostingde.sh | 50 ++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index b61acb7a..4a7a2141 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -13,6 +13,7 @@ dns_hostingde_add() { txtvalue="${2}" _debug "Calling: _hostingde_addRecord() '${fulldomain}' '${txtvalue}'" _hostingde_apiKey && _hostingde_getZoneConfig && _hostingde_addRecord + return $? } dns_hostingde_rm() { @@ -20,6 +21,7 @@ dns_hostingde_rm() { txtvalue="${2}" _debug "Calling: _hostingde_removeRecord() '${fulldomain}' '${txtvalue}'" _hostingde_apiKey && _hostingde_getZoneConfig && _hostingde_removeRecord + return $? } #################### own Private functions below ################################## @@ -38,6 +40,18 @@ _hostingde_apiKey() { _saveaccountconf_mutable HOSTINGDE_ENDPOINT "$HOSTINGDE_ENDPOINT" } +_hostingde_parse() { + find="${1}" + if [ "${2}" ]; then + notfind="${2}" + fi + if [ "${notfind}" ]; then + _egrep_o \""${find}\":.*" | grep -v "${notfind}" | cut -d ':' -f 2 | cut -d ',' -f 1 | tr -d '[:space:]' + else + _egrep_o \""${find}\":.*" | cut -d ':' -f 2 | cut -d ',' -f 1 | tr -d '[:space:]' + fi +} + _hostingde_getZoneConfig() { _info "Getting ZoneConfig" curZone="${fulldomain#*.}" @@ -59,18 +73,18 @@ _hostingde_getZoneConfig() { if _contains "${curResult}" '"totalEntries": 1'; then _info "Retrieved zone data." _debug "Zone data: '${curResult}'" - zoneConfigId=$(echo "${curResult}" | _egrep_o '"id":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) - zoneConfigName=$(echo "${curResult}" | _egrep_o '"name":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) - zoneConfigType=$(echo "${curResult}" | grep -v "FindZoneConfigsResult" | _egrep_o '"type":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) - zoneConfigExpire=$(echo "${curResult}" | _egrep_o '"expire":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) - zoneConfigNegativeTtl=$(echo "${curResult}" | _egrep_o '"negativeTtl":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) - zoneConfigRefresh=$(echo "${curResult}" | _egrep_o '"refresh":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) - zoneConfigRetry=$(echo "${curResult}" | _egrep_o '"retry":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) - zoneConfigTtl=$(echo "${curResult}" | _egrep_o '"ttl":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1) - zoneConfigDnsServerGroupId=$(echo "${curResult}" | _egrep_o '"dnsServerGroupId":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) - zoneConfigEmailAddress=$(echo "${curResult}" | _egrep_o '"emailAddress":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) - zoneConfigDnsSecMode=$(echo "${curResult}" | _egrep_o '"dnsSecMode":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) - if [ "${zoneConfigType}" != "NATIVE" ]; then + zoneConfigId=$(echo "${curResult}" | _hostingde_parse "id") + zoneConfigName=$(echo "${curResult}" | _hostingde_parse "name") + zoneConfigType=$(echo "${curResult}" | _hostingde_parse "type" "FindZoneConfigsResult") + zoneConfigExpire=$(echo "${curResult}" | _hostingde_parse "expire") + zoneConfigNegativeTtl=$(echo "${curResult}" | _hostingde_parse "negativeTtl") + zoneConfigRefresh=$(echo "${curResult}" | _hostingde_parse "refresh") + zoneConfigRetry=$(echo "${curResult}" | _hostingde_parse "retry") + zoneConfigTtl=$(echo "${curResult}" | _hostingde_parse "ttl") + zoneConfigDnsServerGroupId=$(echo "${curResult}" | _hostingde_parse "dnsServerGroupId") + zoneConfigEmailAddress=$(echo "${curResult}" | _hostingde_parse "emailAddress") + zoneConfigDnsSecMode=$(echo "${curResult}" | _hostingde_parse "dnsSecMode") + if [ ${zoneConfigType} != "\"NATIVE\"" ]; then _err "Zone is not native" returnCode=1 break @@ -89,11 +103,11 @@ _hostingde_getZoneConfig() { _hostingde_getZoneStatus() { _debug "Checking Zone status" - curData="{\"filter\":{\"field\":\"zoneConfigId\",\"value\":\"${zoneConfigId}\"},\"limit\":1,\"authToken\":\"${HOSTINGDE_APIKEY}\"}" + curData="{\"filter\":{\"field\":\"zoneConfigId\",\"value\":${zoneConfigId}},\"limit\":1,\"authToken\":\"${HOSTINGDE_APIKEY}\"}" curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zonesFind")" _debug "Calling zonesFind '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zonesFind'" _debug "Result of zonesFind '$curResult'" - zoneStatus=$(echo "${curResult}" | grep -v success | _egrep_o '"status":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + zoneStatus=$(echo "${curResult}" | _hostingde_parse "status" "success") _debug "zoneStatus '${zoneStatus}'" return 0 } @@ -102,12 +116,12 @@ _hostingde_addRecord() { _info "Adding record to zone" _hostingde_getZoneStatus _debug "Result of zoneStatus: '${zoneStatus}'" - while [ "${zoneStatus}" != "active" ]; do + while [ "${zoneStatus}" != "\"active\"" ]; do _sleep 5 _hostingde_getZoneStatus _debug "Result of zoneStatus: '${zoneStatus}'" done - curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\",\"name\":\"${zoneConfigName}\",\"type\":\"${zoneConfigType}\",\"dnsServerGroupId\":\"${zoneConfigDnsServerGroupId}\",\"dnsSecMode\":\"${zoneConfigDnsSecMode}\",\"emailAddress\":\"${zoneConfigEmailAddress}\",\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}" + curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}" curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" _debug "Result of zoneUpdate: '$curResult'" @@ -126,12 +140,12 @@ _hostingde_removeRecord() { _info "Removing record from zone" _hostingde_getZoneStatus _debug "Result of zoneStatus: '$zoneStatus'" - while [ "$zoneStatus" != "active" ]; do + while [ "$zoneStatus" != "\"active\"" ]; do _sleep 5 _hostingde_getZoneStatus _debug "Result of zoneStatus: '$zoneStatus'" done - curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\",\"name\":\"${zoneConfigName}\",\"type\":\"${zoneConfigType}\",\"dnsServerGroupId\":\"${zoneConfigDnsServerGroupId}\",\"dnsSecMode\":\"${zoneConfigDnsSecMode}\",\"emailAddress\":\"${zoneConfigEmailAddress}\",\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}" + curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}" curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" _debug "Result of zoneUpdate: '$curResult'" From 4eda39a31d7a87ff3d741f39477206fa33554110 Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Mon, 4 Feb 2019 15:40:45 +0100 Subject: [PATCH 0141/2234] making shellcheck happy --- dnsapi/dns_hostingde.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 4a7a2141..56eeec78 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -84,7 +84,7 @@ _hostingde_getZoneConfig() { zoneConfigDnsServerGroupId=$(echo "${curResult}" | _hostingde_parse "dnsServerGroupId") zoneConfigEmailAddress=$(echo "${curResult}" | _hostingde_parse "emailAddress") zoneConfigDnsSecMode=$(echo "${curResult}" | _hostingde_parse "dnsSecMode") - if [ ${zoneConfigType} != "\"NATIVE\"" ]; then + if [ "${zoneConfigType}" != "\"NATIVE\"" ]; then _err "Zone is not native" returnCode=1 break From 1167cdcaec8e21dfd68bd2300412a733658b258d Mon Sep 17 00:00:00 2001 From: Sebastiaan Hoogeveen Date: Tue, 5 Feb 2019 16:32:41 +0100 Subject: [PATCH 0142/2234] Added DNS API support for NederHost (https://www.nederhost.nl/) --- dnsapi/dns_nederhost.sh | 133 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100755 dnsapi/dns_nederhost.sh diff --git a/dnsapi/dns_nederhost.sh b/dnsapi/dns_nederhost.sh new file mode 100755 index 00000000..32357f83 --- /dev/null +++ b/dnsapi/dns_nederhost.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env sh + +#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghjk" + +NederHost_Api="https://api.nederhost.nl/dns/v1" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_nederhost_add() { + fulldomain=$1 + txtvalue=$2 + + NederHost_Key="${NederHost_Key:-$(_readaccountconf_mutable NederHost_Key)}" + if [ -z "$NederHost_Key" ]; then + NederHost_Key="" + _err "You didn't specify a NederHost api key." + _err "You can get yours from https://www.nederhost.nl/mijn_nederhost" + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable NederHost_Key "$NederHost_Key" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + if _nederhost_rest PATCH "zones/$_domain/records/$fulldomain/TXT" "[{\"content\":\"$txtvalue\",\"ttl\":60}]"; then + if _contains "$response" "$fulldomain"; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_nederhost_rm() { + fulldomain=$1 + txtvalue=$2 + + NederHost_Key="${NederHost_Key:-$(_readaccountconf_mutable NederHost_Key)}" + if [ -z "$NederHost_Key" ]; then + NederHost_Key="" + _err "You didn't specify a NederHost api key." + _err "You can get yours from https://www.nederhost.nl/mijn_nederhost" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Removing txt record" + _nederhost_rest DELETE "zones/${_domain}/records/$fulldomain/TXT?content=$txtvalue" + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + _domain=$(printf "%s" "$domain" | cut -d . -f $i-100) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _debug _domain "$_domain" + if [ -z "$_domain" ]; then + #not valid + return 1 + fi + + if _nederhost_rest GET "zones/${_domain}"; then + if [ "${_code}" == "204" ]; then + return 0; + fi + else + return 1; + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_nederhost_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + export _H1="Authorization: Bearer $NederHost_Key" + export _H2="Content-Type: application/json" + + :>$HTTP_HEADER + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$NederHost_Api/$ep" "" "$m")" + else + response="$(_get "$NederHost_Api/$ep")" + fi + + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + _debug "http response code $_code" + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From b3e3e080a9a18c005384942de6616fe076e8a8d4 Mon Sep 17 00:00:00 2001 From: Sebastiaan Hoogeveen Date: Tue, 5 Feb 2019 16:37:08 +0100 Subject: [PATCH 0143/2234] Cleaned up some of the comments from shellcheck. --- dnsapi/dns_nederhost.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_nederhost.sh b/dnsapi/dns_nederhost.sh index 32357f83..0058c848 100755 --- a/dnsapi/dns_nederhost.sh +++ b/dnsapi/dns_nederhost.sh @@ -91,7 +91,7 @@ _get_root() { fi if _nederhost_rest GET "zones/${_domain}"; then - if [ "${_code}" == "204" ]; then + if [ "${_code}" = "204" ]; then return 0; fi else @@ -112,7 +112,7 @@ _nederhost_rest() { export _H1="Authorization: Bearer $NederHost_Key" export _H2="Content-Type: application/json" - :>$HTTP_HEADER + :>"$HTTP_HEADER" if [ "$m" != "GET" ]; then _debug data "$data" From 44dcb0d0a9b0b22f88d3d7942b1aac9004a273b7 Mon Sep 17 00:00:00 2001 From: Sebastiaan Hoogeveen Date: Wed, 6 Feb 2019 11:46:47 +0100 Subject: [PATCH 0144/2234] Make Travis happy; fixed formatting of return statements. --- dnsapi/dns_nederhost.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_nederhost.sh b/dnsapi/dns_nederhost.sh index 0058c848..84c5ecd1 100755 --- a/dnsapi/dns_nederhost.sh +++ b/dnsapi/dns_nederhost.sh @@ -92,10 +92,10 @@ _get_root() { if _nederhost_rest GET "zones/${_domain}"; then if [ "${_code}" = "204" ]; then - return 0; + return 0 fi else - return 1; + return 1 fi p=$i i=$(_math "$i" + 1) From b7e92dbcedf358a2234ed6567662b71bb5ee2953 Mon Sep 17 00:00:00 2001 From: Sebastiaan Hoogeveen Date: Wed, 6 Feb 2019 14:27:26 +0100 Subject: [PATCH 0145/2234] Documentation update. --- README.md | 1 + dnsapi/README.md | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/README.md b/README.md index 90a648d5..4bde4ea4 100644 --- a/README.md +++ b/README.md @@ -351,6 +351,7 @@ You don't have to do anything manually! 1. PointDNS API (https://pointhq.com/) 1. Active24.cz API (https://www.active24.cz/) 1. do.de API (https://www.do.de/) +1. NederHost API (https://www.nederhost.nl/) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index 4f9b4100..a2bf0c18 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1172,6 +1172,20 @@ acme.sh --issue --dns dns_doapi -d example.com -d *.example.com The API token will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 61. Use NederHost API + +Create an API token in Mijn NederHost. + +Set your API key: +``` +export NederHost_Key='xxx' +``` + +To issue a certificate run: +``` +acme.sh --issue --dns dns_nederhost -d example.com -d *.example.com +``` + # Use custom API If your API is not supported yet, you can write your own DNS API. From 84d80e93bcd9dcef9183658a5af4fc47efa8758f Mon Sep 17 00:00:00 2001 From: Frank Laszlo Date: Wed, 6 Feb 2019 10:42:11 -0500 Subject: [PATCH 0146/2234] Add support for Thermo, Nexcess, and Futurehosting DNS APIs --- README.md | 9 +- dnsapi/README.md | 62 +++++++++++++- dnsapi/dns_nw.sh | 211 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 276 insertions(+), 6 deletions(-) create mode 100644 dnsapi/dns_nw.sh diff --git a/README.md b/README.md index 90a648d5..65b83e71 100644 --- a/README.md +++ b/README.md @@ -253,7 +253,7 @@ Just set string "apache" as the second argument and it will force use of apache acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com ``` -**This apache mode is only to issue the cert, it will not change your apache config files. +**This apache mode is only to issue the cert, it will not change your apache config files. You will need to configure your website config files to use the cert by yourself. We don't want to mess your apache server, don't worry.** @@ -277,7 +277,7 @@ So, the config is not changed. acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com ``` -**This nginx mode is only to issue the cert, it will not change your nginx config files. +**This nginx mode is only to issue the cert, it will not change your nginx config files. You will need to configure your website config files to use the cert by yourself. We don't want to mess your nginx server, don't worry.** @@ -351,6 +351,9 @@ You don't have to do anything manually! 1. PointDNS API (https://pointhq.com/) 1. Active24.cz API (https://www.active24.cz/) 1. do.de API (https://www.do.de/) +1. Nexcess API (https://www.nexcess.net) +1. Thermo.io API (https://www.thermo.io) +1. Futurehosting API (https://www.futurehosting.com) And: @@ -528,5 +531,5 @@ Please Star and Fork me. Your donation makes **acme.sh** better: 1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/) - + [Donate List](https://github.com/Neilpang/acme.sh/wiki/Donate-list) diff --git a/dnsapi/README.md b/dnsapi/README.md index 4f9b4100..a9b78ef8 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1,6 +1,6 @@ # How to use DNS API -If your dns provider doesn't provide api access, you can use our dns alias mode: +If your dns provider doesn't provide api access, you can use our dns alias mode: https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode @@ -891,7 +891,7 @@ acme.sh --issue --dns dns_loopia -d example.com -d *.example.com The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed. ## 45. Use ACME DNS API -ACME DNS is a limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely. +ACME DNS is a limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely. https://github.com/joohoi/acme-dns ``` @@ -1011,7 +1011,6 @@ acme.sh --issue --dns dns_netcup -d example.com -d www.example.com ``` The `NC_Apikey`,`NC_Apipw` and `NC_CID` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - ## 52. Use GratisDNS.dk GratisDNS.dk (https://gratisdns.dk/) does not provide an API to update DNS records (other than IPv4 and IPv6 @@ -1172,6 +1171,63 @@ acme.sh --issue --dns dns_doapi -d example.com -d *.example.com The API token will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 61. Use Nexcess API + +First, you'll need to login to the [Nexcess.net Client Portal](https://portal.nexcess.net) and [generate a new API token](https://portal.nexcess.net/api-token). + +Once you have a token, set it in your systems environment: + +``` +export NW_API_TOKEN="YOUR_TOKEN_HERE" +export NW_API_ENDPOINT="https://portal.nexcess.net" +``` + +Finally, we'll issue the certificate: (Nexcess DNS publishes at max every 15 minutes, we recommend setting a 900 second `--dnssleep`) + +``` +acme.sh --issue --dns dns_nw -d example.com --dnssleep 900 +``` + +The `NW_API_TOKEN` and `NW_API_ENDPOINT` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + +## 62. Use Thermo.io API + +First, you'll need to login to the [Thermo.io Client Portal](https://core.thermo.io) and [generate a new API token](https://core.thermo.io/api-token). + +Once you have a token, set it in your systems environment: + +``` +export NW_API_TOKEN="YOUR_TOKEN_HERE" +export NW_API_ENDPOINT="https://core.thermo.io" +``` + +Finally, we'll issue the certificate: (Thermo DNS publishes at max every 15 minutes, we recommend setting a 900 second `--dnssleep`) + +``` +acme.sh --issue --dns dns_nw -d example.com --dnssleep 900 +``` + +The `NW_API_TOKEN` and `NW_API_ENDPOINT` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + +## 63. Use Futurehosting API + +First, you'll need to login to the [Futurehosting Client Portal](https://my.futurehosting.com) and [generate a new API token](https://my.futurehosting.com/api-token). + +Once you have a token, set it in your systems environment: + +``` +export NW_API_TOKEN="YOUR_TOKEN_HERE" +export NW_API_ENDPOINT="https://my.futurehosting.com" +``` + +Finally, we'll issue the certificate: (Futurehosting DNS publishes at max every 15 minutes, we recommend setting a 900 second `--dnssleep`) + +``` +acme.sh --issue --dns dns_nw -d example.com --dnssleep 900 +``` + +The `NW_API_TOKEN` and `NW_API_ENDPOINT` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_nw.sh b/dnsapi/dns_nw.sh new file mode 100644 index 00000000..c57d27c2 --- /dev/null +++ b/dnsapi/dns_nw.sh @@ -0,0 +1,211 @@ +#!/usr/bin/env sh +######################################################################## +# NocWorx script for acme.sh +# +# Handles DNS Updates for the Following vendors: +# - Nexcess.net +# - Thermo.io +# - Futurehosting.com +# +# Environment variables: +# +# - NW_API_TOKEN (Your API Token) +# - NW_API_ENDPOINT (One of the following listed below) +# +# Endpoints: +# - https://portal.nexcess.net (default) +# - https://core.thermo.io +# - https://my.futurehosting.com +# +# Note: If you do not have an API token, one can be generated at one +# of the following URLs: +# - https://portal.nexcess.net/api-token +# - https://core.thermo.io/api-token +# - https://my.futurehosting.com/api-token +# +# Author: Frank Laszlo + +NW_API_VERSION="0" + +# dns_nw_add() - Add TXT record +# Usage: dns_nw_add _acme-challenge.subdomain.domain.com "XyZ123..." +dns_nw_add() { + host="${1}" + txtvalue="${2}" + + _debug host "${host}" + _debug txtvalue "${txtvalue}" + + if ! _check_nw_api_creds; then + return 1 + fi + + _info "Using NocWorx (${NW_API_ENDPOINT})" + _debug "Calling: dns_nw_add() '${host}' '${txtvalue}'" + + _debug "Detecting root zone" + if ! _get_root "${host}"; then + _err "Zone for domain does not exist." + return 1 + fi + _debug _zone_id "${_zone_id}" + _debug _sub_domain "${_sub_domain}" + _debug _domain "${_domain}" + + _post_data="{\"zone_id\": \"${_zone_id}\", \"type\": \"TXT\", \"host\": \"${host}\", \"target\": \"${txtvalue}\", \"ttl\": \"300\"}" + + if _rest POST "dns-record" "${_post_data}" && [ -n "${response}" ]; then + _record_id=$(printf "%s\n" "${response}" | _egrep_o "\"record_id\": *[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + _debug _record_id "${_record_id}" + + if [ -z "$_record_id" ]; then + _err "Error adding the TXT record." + return 1 + fi + + _info "TXT record successfully added." + return 0 + fi + + return 1 +} + +# dns_nw_rm() - Remove TXT record +# Usage: dns_nw_rm _acme-challenge.subdomain.domain.com "XyZ123..." +dns_nw_rm() { + host="${1}" + txtvalue="${2}" + + _debug host "${host}" + _debug txtvalue "${txtvalue}" + + if ! _check_nw_api_creds; then + return 1 + fi + + _info "Using NocWorx (${NW_API_ENDPOINT})" + _debug "Calling: dns_nw_rm() '${host}'" + + _debug "Detecting root zone" + if ! _get_root "${host}"; then + _err "Zone for domain does not exist." + return 1 + fi + _debug _zone_id "${_zone_id}" + _debug _sub_domain "${_sub_domain}" + _debug _domain "${_domain}" + + _parameters="?zone_id=${_zone_id}" + + if _rest GET "dns-record" "${_parameters}" && [ -n "${response}" ]; then + response="$(echo "${response}" | tr -d "\n" | sed 's/^\[\(.*\)\]$/\1/' | sed -e 's/{"record_id":/|"record_id":/g' | sed 's/|/&{/g' | tr "|" "\n")" + _debug response "${response}" + + record="$(echo "${response}" | _egrep_o "{.*\"host\": *\"${_sub_domain}\", *\"target\": *\"${txtvalue}\".*}")" + _debug record "${record}" + + if [ "${record}" ]; then + _record_id=$(printf "%s\n" "${record}" | _egrep_o "\"record_id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + if [ "${_record_id}" ]; then + _debug _record_id "${_record_id}" + + _rest DELETE "dns-record/${_record_id}" + + _info "TXT record successfully deleted." + return 0 + fi + + return 1 + fi + + return 0 + fi + + return 1 +} + +_check_nw_api_creds() { + NW_API_TOKEN="${NW_API_TOKEN:-$(_readaccountconf_mutable NW_API_TOKEN)}" + NW_API_ENDPOINT="${NW_API_ENDPOINT:-$(_readaccountconf_mutable NW_API_ENDPOINT)}" + + if [ -z "${NW_API_ENDPOINT}" ]; then + NW_API_ENDPOINT="https://portal.nexcess.net" + fi + + if [ -z "${NW_API_TOKEN}" ]; then + _err "You have not defined your NW_API_TOKEN." + _err "Please create your token and try again." + _err "If you need to generate a new token, please visit one of the following URLs:" + _err " - https://portal.nexcess.net/api-token" + _err " - https://core.thermo.io/api-token" + _err " - https://my.futurehosting.com/api-token" + + return 1 + fi + + _saveaccountconf_mutable NW_API_TOKEN "${NW_API_TOKEN}" + _saveaccountconf_mutable NW_API_ENDPOINT "${NW_API_ENDPOINT}" +} + +_get_root() { + domain="${1}" + i=2 + p=1 + + if _rest GET "dns-zone"; then + response="$(echo "${response}" | tr -d "\n" | sed 's/^\[\(.*\)\]$/\1/' | sed -e 's/{"zone_id":/|"zone_id":/g' | sed 's/|/&{/g' | tr "|" "\n")" + + _debug response "${response}" + while true; do + h=$(printf "%s" "${domain}" | cut -d . -f $i-100) + _debug h "${h}" + if [ -z "${h}" ]; then + #not valid + return 1 + fi + + hostedzone="$(echo "${response}" | _egrep_o "{.*\"domain\": *\"${h}\".*}")" + if [ "${hostedzone}" ]; then + _zone_id=$(printf "%s\n" "${hostedzone}" | _egrep_o "\"zone_id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + if [ "${_zone_id}" ]; then + _sub_domain=$(printf "%s" "${domain}" | cut -d . -f 1-${p}) + _domain="${h}" + return 0 + fi + return 1 + fi + p=$i + i=$(_math "${i}" + 1) + done + fi + return 1 +} + +_rest() { + method="${1}" + ep="/${2}" + data="${3}" + + _debug method "${method}" + _debug ep "${ep}" + + export _H1="Accept: application/json" + export _H2="Content-Type: application/json" + export _H3="Api-Version: ${NW_API_VERSION}" + export _H4="User-Agent: NW-ACME-CLIENT" + export _H5="Authorization: Bearer ${NW_API_TOKEN}" + + if [ "${method}" != "GET" ]; then + _debug data "${data}" + response="$(_post "${data}" "${NW_API_ENDPOINT}${ep}" "" "${method}")" + else + response="$(_get "${NW_API_ENDPOINT}${ep}${data}")" + fi + + if [ "${?}" != "0" ]; then + _err "error ${ep}" + return 1 + fi + _debug2 response "${response}" + return 0 +} From ebc90f6ab831ab2f35e3c7411bcba41a366583d2 Mon Sep 17 00:00:00 2001 From: Simon Wydooghe Date: Wed, 6 Feb 2019 17:42:50 +0100 Subject: [PATCH 0147/2234] Set NS1 DNS record TTL to 0 Default of a zone might be high, which is annoying when testing with the ACME staging API. I think setting the TTL to 0 makes sense as acme.sh is the only one checking this, so having an always up to date response seems desirable. --- dnsapi/dns_nsone.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_nsone.sh b/dnsapi/dns_nsone.sh index 00e186d2..9a998341 100644 --- a/dnsapi/dns_nsone.sh +++ b/dnsapi/dns_nsone.sh @@ -46,7 +46,7 @@ dns_nsone_add() { if [ "$count" = "0" ]; then _info "Adding record" - if _nsone_rest PUT "zones/$_domain/$fulldomain/TXT" "{\"answers\":[{\"answer\":[\"$txtvalue\"]}],\"type\":\"TXT\",\"domain\":\"$fulldomain\",\"zone\":\"$_domain\"}"; then + if _nsone_rest PUT "zones/$_domain/$fulldomain/TXT" "{\"answers\":[{\"answer\":[\"$txtvalue\"]}],\"type\":\"TXT\",\"domain\":\"$fulldomain\",\"zone\":\"$_domain\",\"ttl\":0}"; then if _contains "$response" "$fulldomain"; then _info "Added" #todo: check if the record takes effect @@ -62,7 +62,7 @@ dns_nsone_add() { prev_txt=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain\",\"short_answers\":\[\"[^,]*\]" | _head_n 1 | cut -d: -f3 | cut -d, -f1) _debug "prev_txt" "$prev_txt" - _nsone_rest POST "zones/$_domain/$fulldomain/TXT" "{\"answers\": [{\"answer\": [\"$txtvalue\"]},{\"answer\": $prev_txt}],\"type\": \"TXT\",\"domain\":\"$fulldomain\",\"zone\": \"$_domain\"}" + _nsone_rest POST "zones/$_domain/$fulldomain/TXT" "{\"answers\": [{\"answer\": [\"$txtvalue\"]},{\"answer\": $prev_txt}],\"type\": \"TXT\",\"domain\":\"$fulldomain\",\"zone\": \"$_domain\",\"ttl\":0}" if [ "$?" = "0" ] && _contains "$response" "$fulldomain"; then _info "Updated!" #todo: check if the record takes effect From 2cf01c23a2b1f09a317e58aa99f8c9fbedb7146d Mon Sep 17 00:00:00 2001 From: Christian Burmeister Date: Sat, 9 Feb 2019 19:38:32 +0100 Subject: [PATCH 0148/2234] Update Dockerfile --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c1a2199b..68385d7d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.6 +FROM alpine:3.9 RUN apk update -f \ && apk --no-cache add -f \ @@ -7,6 +7,7 @@ RUN apk update -f \ bind-tools \ curl \ socat \ + tzdata \ && rm -rf /var/cache/apk/* ENV LE_CONFIG_HOME /acme.sh From 1fa026b9c7315128f60f6a1e9137f44aa01d60bf Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Mon, 11 Feb 2019 11:47:48 +0100 Subject: [PATCH 0149/2234] using ' ' instead of '[:space:]' for tr --- dnsapi/dns_hostingde.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 56eeec78..50aa142f 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -46,9 +46,9 @@ _hostingde_parse() { notfind="${2}" fi if [ "${notfind}" ]; then - _egrep_o \""${find}\":.*" | grep -v "${notfind}" | cut -d ':' -f 2 | cut -d ',' -f 1 | tr -d '[:space:]' + _egrep_o \""${find}\":.*" | grep -v "${notfind}" | cut -d ':' -f 2 | cut -d ',' -f 1 | tr -d ' ' else - _egrep_o \""${find}\":.*" | cut -d ':' -f 2 | cut -d ',' -f 1 | tr -d '[:space:]' + _egrep_o \""${find}\":.*" | cut -d ':' -f 2 | cut -d ',' -f 1 | tr -d ' ' fi } From d30b441ede3d2907c0645cf4dea78d740c2a6f08 Mon Sep 17 00:00:00 2001 From: Tom Cocca Date: Wed, 2 Jan 2019 00:18:25 -0600 Subject: [PATCH 0150/2234] Rackspace Cloud DNS Support Rackspace Cloud DNS This commit is based on the original pull request by tcocca https://github.com/Neilpang/acme.sh/pull/1297 Addtional cleanup was provided by senseisimple in https://github.com/Neilpang/acme.sh/pull/1999 This pull request has squashed the changes for review, fixed a minor (but breaking) problem with the field ordering in the response, and added documenation per the API guide. Co-Author: Chris Co-Author: Ian Wienand --- README.md | 1 + dnsapi/README.md | 15 +++ dnsapi/dns_rackspace.sh | 207 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 dnsapi/dns_rackspace.sh diff --git a/README.md b/README.md index 65b83e71..793df06a 100644 --- a/README.md +++ b/README.md @@ -354,6 +354,7 @@ You don't have to do anything manually! 1. Nexcess API (https://www.nexcess.net) 1. Thermo.io API (https://www.thermo.io) 1. Futurehosting API (https://www.futurehosting.com) +1. Rackspace Cloud DNS (https://www.rackspace.com) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index a9b78ef8..c136ed35 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1228,6 +1228,21 @@ acme.sh --issue --dns dns_nw -d example.com --dnssleep 900 The `NW_API_TOKEN` and `NW_API_ENDPOINT` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 64. Use Rackspace API + +Set username and API key, which is available under "My Profile & Settings" + +``` +export RACKSPACE_Username='username' +export RACKSPACE_Apikey='xxx' +``` + +Now, let's issue a cert: + +``` +acme.sh --issue --dns dns_rackspace -d example.com -d www.example.com +``` + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_rackspace.sh b/dnsapi/dns_rackspace.sh new file mode 100644 index 00000000..3939fd81 --- /dev/null +++ b/dnsapi/dns_rackspace.sh @@ -0,0 +1,207 @@ +#!/usr/bin/env sh +# +# +#RACKSPACE_Username="" +# +#RACKSPACE_Apikey="" + +RACKSPACE_Endpoint="https://dns.api.rackspacecloud.com/v1.0" + +# 20190213 - The name & id fields swapped in the API response; fix sed +# 20190101 - Duplicating file for new pull request to dev branch +# Original - tcocca:rackspace_dnsapi https://github.com/Neilpang/acme.sh/pull/1297 + +######## Public functions ##################### +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_rackspace_add() { + fulldomain="$1" + _debug fulldomain="$fulldomain" + txtvalue="$2" + _debug txtvalue="$txtvalue" + _rackspace_check_auth || return 1 + _rackspace_check_rootzone || return 1 + _info "Creating TXT record." + if ! _rackspace_rest POST "$RACKSPACE_Tenant/domains/$_domain_id/records" "{\"records\":[{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":300}]}"; then + return 1 + fi + _debug2 response "$response" + if ! _contains "$response" "$txtvalue" >/dev/null; then + _err "Could not add TXT record." + return 1 + fi + return 0 +} + +#fulldomain txtvalue +dns_rackspace_rm() { + fulldomain=$1 + _debug fulldomain="$fulldomain" + txtvalue=$2 + _debug txtvalue="$txtvalue" + _rackspace_check_auth || return 1 + _rackspace_check_rootzone || return 1 + _info "Checking for TXT record." + if ! _get_recordid "$_domain_id" "$fulldomain" "$txtvalue"; then + _err "Could not get TXT record id." + return 1 + fi + if [ "$_dns_record_id" = "" ]; then + _err "TXT record not found." + return 1 + fi + _info "Removing TXT record." + if ! _delete_txt_record "$_domain_id" "$_dns_record_id"; then + _err "Could not remove TXT record $_dns_record_id." + 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_zone() { + domain="$1" + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + if ! _rackspace_rest GET "$RACKSPACE_Tenant/domains"; then + return 1 + fi + _debug2 response "$response" + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + # Response looks like: + # {"ttl":300,"accountId":12345,"id":1111111,"name":"example.com","emailAddress": ... + _domain_id=$(echo "$response" | sed -n "s/^.*\"id\":\([^,]*\),\"name\":\"$h\",.*/\1/p") + _debug2 domain_id "$_domain_id" + if [ -n "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_get_recordid() { + domainid="$1" + fulldomain="$2" + txtvalue="$3" + if ! _rackspace_rest GET "$RACKSPACE_Tenant/domains/$domainid/records?name=$fulldomain&type=TXT"; then + return 1 + fi + _debug response "$response" + if ! _contains "$response" "$txtvalue"; then + _dns_record_id=0 + return 0 + fi + _dns_record_id=$(echo "$response" | tr '{' "\n" | grep "\"data\":\"$txtvalue\"" | sed -n 's/^.*"id":"\([^"]*\)".*/\1/p') + _debug _dns_record_id "$_dns_record_id" + return 0 +} + +_delete_txt_record() { + domainid="$1" + _dns_record_id="$2" + if ! _rackspace_rest DELETE "$RACKSPACE_Tenant/domains/$domainid/records?id=$_dns_record_id"; then + return 1 + fi + _debug response "$response" + if ! _contains "$response" "RUNNING"; then + return 1 + fi + return 0 +} + +_rackspace_rest() { + m="$1" + ep="$2" + data="$3" + _debug ep "$ep" + export _H1="Accept: application/json" + export _H2="X-Auth-Token: $RACKSPACE_Token" + export _H3="X-Project-Id: $RACKSPACE_Tenant" + export _H4="Content-Type: application/json" + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$RACKSPACE_Endpoint/$ep" "" "$m")" + retcode=$? + else + _info "Getting $RACKSPACE_Endpoint/$ep" + response="$(_get "$RACKSPACE_Endpoint/$ep")" + retcode=$? + fi + + if [ "$retcode" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} + +_rackspace_authorization() { + export _H1="Content-Type: application/json" + data="{\"auth\":{\"RAX-KSKEY:apiKeyCredentials\":{\"username\":\"$RACKSPACE_Username\",\"apiKey\":\"$RACKSPACE_Apikey\"}}}" + _debug data "$data" + response="$(_post "$data" "https://identity.api.rackspacecloud.com/v2.0/tokens" "" "POST")" + retcode=$? + _debug2 response "$response" + if [ "$retcode" != "0" ]; then + _err "Authentication failed." + return 1 + fi + if _contains "$response" "token"; then + RACKSPACE_Token="$(echo "$response" | _normalizeJson | sed -n 's/^.*"token":{.*,"id":"\([^"]*\)",".*/\1/p')" + RACKSPACE_Tenant="$(echo "$response" | _normalizeJson | sed -n 's/^.*"token":{.*,"id":"\([^"]*\)"}.*/\1/p')" + _debug RACKSPACE_Token "$RACKSPACE_Token" + _debug RACKSPACE_Tenant "$RACKSPACE_Tenant" + fi + return 0 +} + +_rackspace_check_auth() { + # retrieve the rackspace creds + RACKSPACE_Username="${RACKSPACE_Username:-$(_readaccountconf_mutable RACKSPACE_Username)}" + RACKSPACE_Apikey="${RACKSPACE_Apikey:-$(_readaccountconf_mutable RACKSPACE_Apikey)}" + # check their vals for null + if [ -z "$RACKSPACE_Username" ] || [ -z "$RACKSPACE_Apikey" ]; then + RACKSPACE_Username="" + RACKSPACE_Apikey="" + _err "You didn't specify a Rackspace username and api key." + _err "Please set those values and try again." + return 1 + fi + # save the username and api key to the account conf file. + _saveaccountconf_mutable RACKSPACE_Username "$RACKSPACE_Username" + _saveaccountconf_mutable RACKSPACE_Apikey "$RACKSPACE_Apikey" + if [ -z "$RACKSPACE_Token" ]; then + _info "Getting authorization token." + if ! _rackspace_authorization; then + _err "Can not get token." + fi + fi +} + +_rackspace_check_rootzone() { + _debug "First detect the root zone" + if ! _get_root_zone "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" +} From ec5fad433c3cdfb8b9d64ed8197ed445297adc1c Mon Sep 17 00:00:00 2001 From: Augustin-FL Date: Wed, 13 Feb 2019 23:33:54 +0100 Subject: [PATCH 0151/2234] Add online.net DNS API --- README.md | 1 + dnsapi/README.md | 16 ++++ dnsapi/dns_online.sh | 214 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100755 dnsapi/dns_online.sh diff --git a/README.md b/README.md index 793df06a..8d749dcc 100644 --- a/README.md +++ b/README.md @@ -355,6 +355,7 @@ You don't have to do anything manually! 1. Thermo.io API (https://www.thermo.io) 1. Futurehosting API (https://www.futurehosting.com) 1. Rackspace Cloud DNS (https://www.rackspace.com) +1. Online.net API (https://online.net/) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index c136ed35..f022cab0 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1243,6 +1243,22 @@ Now, let's issue a cert: acme.sh --issue --dns dns_rackspace -d example.com -d www.example.com ``` +## 65. Use Online API + +First, you'll need to retrive your API key, which is available under https://console.online.net/en/api/access + +``` +export ONLINE_API_KEY='xxx' +``` + +To issue a cert run: + +``` +acme.sh --issue --dns dns_online -d example.com -d www.example.com +``` + +`ONLINE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh new file mode 100755 index 00000000..02d07dcd --- /dev/null +++ b/dnsapi/dns_online.sh @@ -0,0 +1,214 @@ +#!/usr/bin/env sh + +# Online API +# https://console.online.net/en/api/ +# +# Requires Online API key set in ONLINE_API_KEY + +######## Public functions ##################### + +ONLINE_API="https://api.online.net/api/v1" + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_online_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _online_check_config; then + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug _real_dns_version "$_real_dns_version" + + _info "Creating temporary zone version" + _online_create_temporary_zone_version + _info "Enabling temporary zone version" + _online_enable_zone "$_temporary_dns_version" + + _info "Adding record" + _online_create_TXT_record "$_real_dns_version" "$_sub_domain" "$txtvalue" + _info "Disabling temporary version" + _online_enable_zone "$_real_dns_version" + _info "Destroying temporary version" + _online_destroy_zone "$_temporary_dns_version" + + _info "Record added." + return 0 +} + +#fulldomain +dns_online_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _online_check_config; then + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug _real_dns_version "$_real_dns_version" + + _debug "Getting txt records" + if ! _online_rest GET "domain/$_domain/version/active"; then + return 1 + fi + + rid=$(echo "$response" | _egrep_o "\"id\":[0-9]+,\"name\":\"$_sub_domain\",\"data\":\"\\\u0022$txtvalue\\\u0022\"" | cut -d ':' -f 2 | cut -d ',' -f 1) + _debug rid "$rid" + if [ -z "$rid" ]; then + return 1 + fi + + _info "Creating temporary zone version" + _online_create_temporary_zone_version + _info "Enabling temporary zone version" + _online_enable_zone "$_temporary_dns_version" + + _info "Removing DNS record" + _online_rest DELETE "domain/$_domain/version/$_real_dns_version/zone/$rid" + _info "Disabling temporary version" + _online_enable_zone "$_real_dns_version" + _info "Destroying temporary version" + _online_destroy_zone "$_temporary_dns_version" + + return 0 +} + +#################### Private functions below ################################## + +_online_check_config() { + + if [ -z "$ONLINE_API_KEY" ]; then + _err "No API key specified for Online API." + _err "Create your key and export it as ONLINE_API_KEY" + return 1 + fi + + _saveaccountconf ONLINE_API_KEY "$ONLINE_API_KEY" + + return 0 +} + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + if ! _online_rest GET "domain/$h/version/active"; then + _err "Unable to retrive DNS zone matching this domain" + return 1 + fi + + if ! _contains "$response" "Domain not found" >/dev/null; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + _real_dns_version=$(echo "$response" | _egrep_o '"uuid_ref":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +# this function create a temporary zone version +# as online.net does not allow updating an active version +_online_create_temporary_zone_version() { + + _online_rest POST "domain/$_domain/version" "name=acme.sh" + if [ "$?" != "0" ]; then + return 1 + fi + + _temporary_dns_version=$(echo "$response" | _egrep_o '"uuid_ref":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) + + # Creating a dummy record in this temporary version, because online.net doesn't accept enabling an empty version + _online_create_TXT_record "$_temporary_dns_version" "dummy.acme.sh" "dummy" + + return 0 +} + +_online_destroy_zone() { + version_id=$1 + _online_rest DELETE "domain/$_domain/version/$version_id" + + if [ "$?" != "0" ]; then + return 1 + fi + return 0 +} + +_online_enable_zone() { + version_id=$1 + _online_rest PATCH "domain/$_domain/version/$version_id/enable" + + if [ "$?" != "0" ]; then + return 1 + fi + return 0 +} + +_online_create_TXT_record() { + version=$1 + txt_name=$2 + txt_value=$3 + + _online_rest POST "domain/$_domain/version/$version/zone" "type=TXT&name=$txt_name&data=%22$txt_value%22&ttl=60&priority=0" + + # Note : the normal, expected response SHOULD be "Unknown method". + # this happens because the API HTTP response contains a Location: header, that redirect + # to an unknown online.net endpoint. + if [ "$?" != "0" ] || _contains "$response" "Unknown method"; then + return 0 + else + _err "error $response" + return 1 + fi +} + +_online_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + _online_url="$ONLINE_API/$ep" + _debug2 _online_url "$_online_url" + export _H1="Authorization: Bearer $ONLINE_API_KEY" + export _H2="X-Pretty-JSON: 1" + if [ "$data" ] || [ "$m" = "PATCH" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ] || [ "$m" = "DELETE" ]; then + _debug data "$data" + response="$(_post "$data" "$_online_url" "" "$m")" + else + response="$(_get "$_online_url")" + fi + if [ "$?" != "0" ] || _contains "$response" "invalid_grant" || _contains "$response" "Method not allowed"; then + _err "error $response" + return 1 + fi + _debug2 response "$response" + return 0 +} From 02f6d4cb66c3837490295379a59c67936dcb0b90 Mon Sep 17 00:00:00 2001 From: Augustin-FL Date: Fri, 15 Feb 2019 07:56:13 +0000 Subject: [PATCH 0152/2234] use read/saveconf_mutable, not readconf from OVH --- dnsapi/dns_online.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index 02d07dcd..c6ee485b 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -92,14 +92,18 @@ dns_online_rm() { #################### Private functions below ################################## _online_check_config() { - + ONLINE_API_KEY="${CF_Key:-$(_readaccountconf_mutable ONLINE_API_KEY)}" if [ -z "$ONLINE_API_KEY" ]; then _err "No API key specified for Online API." _err "Create your key and export it as ONLINE_API_KEY" return 1 fi + if [ ! _online_rest GET "domain/" ]; then + _err "Invalid API key specified for Online API." + return 1 + fi - _saveaccountconf ONLINE_API_KEY "$ONLINE_API_KEY" + _saveaccountconf_mutable ONLINE_API_KEY "$ONLINE_API_KEY" return 0 } From 5c94147603b4d9c3d903c01344bde9751095eddc Mon Sep 17 00:00:00 2001 From: Augustin-FL Date: Fri, 15 Feb 2019 08:08:10 +0000 Subject: [PATCH 0153/2234] use read/saveconf_mutable, not readconf from OVH --- dnsapi/dns_online.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index c6ee485b..ee00685b 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -92,13 +92,13 @@ dns_online_rm() { #################### Private functions below ################################## _online_check_config() { - ONLINE_API_KEY="${CF_Key:-$(_readaccountconf_mutable ONLINE_API_KEY)}" + ONLINE_API_KEY="${ONLINE_API_KEY:-$(_readaccountconf_mutable ONLINE_API_KEY)}" if [ -z "$ONLINE_API_KEY" ]; then _err "No API key specified for Online API." _err "Create your key and export it as ONLINE_API_KEY" return 1 fi - if [ ! _online_rest GET "domain/" ]; then + if ! _online_rest GET "domain/"; then _err "Invalid API key specified for Online API." return 1 fi From 841513501a69aab5ae9ec98a9c383df65f1fb8f6 Mon Sep 17 00:00:00 2001 From: Augustin-FL Date: Fri, 15 Feb 2019 07:58:43 +0000 Subject: [PATCH 0154/2234] update get_root --- dnsapi/dns_online.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index ee00685b..8c5a046b 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -122,10 +122,8 @@ _get_root() { #not valid return 1 fi - if ! _online_rest GET "domain/$h/version/active"; then - _err "Unable to retrive DNS zone matching this domain" - return 1 - fi + + _online_rest GET "domain/$h/version/active" if ! _contains "$response" "Domain not found" >/dev/null; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) @@ -136,7 +134,8 @@ _get_root() { p=$i i=$(_math "$i" + 1) done - return 1 + _err "Unable to retrive DNS zone matching this domain" + return 1 } # this function create a temporary zone version From 9ace7db216cdce631475e3df1eb66e2d14f92489 Mon Sep 17 00:00:00 2001 From: Augustin-FL Date: Fri, 15 Feb 2019 08:03:13 +0000 Subject: [PATCH 0155/2234] simplify online_rest --- dnsapi/dns_online.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index 8c5a046b..8831f9af 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -202,7 +202,7 @@ _online_rest() { _debug2 _online_url "$_online_url" export _H1="Authorization: Bearer $ONLINE_API_KEY" export _H2="X-Pretty-JSON: 1" - if [ "$data" ] || [ "$m" = "PATCH" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ] || [ "$m" = "DELETE" ]; then + if [ "$data" ] || [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$_online_url" "" "$m")" else From 63ea3e8d277e8868bcbf5f6a2242a0028a26bb5d Mon Sep 17 00:00:00 2001 From: Augustin-FL Date: Fri, 15 Feb 2019 08:29:00 +0000 Subject: [PATCH 0156/2234] acme.sh does not follow Location: headers when using wget --- dnsapi/dns_online.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index 8831f9af..6f4c40d6 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -185,7 +185,7 @@ _online_create_TXT_record() { # Note : the normal, expected response SHOULD be "Unknown method". # this happens because the API HTTP response contains a Location: header, that redirect # to an unknown online.net endpoint. - if [ "$?" != "0" ] || _contains "$response" "Unknown method"; then + if [ "$?" != "0" ] || _contains "$response" "Unknown method" || _contains "$response" "\$ref"; then return 0 else _err "error $response" From 1ad6742dbc0e0bc9df869afbcbc67959d91452a0 Mon Sep 17 00:00:00 2001 From: Augustin-FL Date: Fri, 15 Feb 2019 08:43:07 +0000 Subject: [PATCH 0157/2234] fix travis --- dnsapi/dns_online.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index 6f4c40d6..0d1fca2a 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -134,7 +134,7 @@ _get_root() { p=$i i=$(_math "$i" + 1) done - _err "Unable to retrive DNS zone matching this domain" + _err "Unable to retrive DNS zone matching this domain" return 1 } From ec6569fbea21bb9eef2397cdcfb66b202cea9671 Mon Sep 17 00:00:00 2001 From: Augustin-FL Date: Fri, 15 Feb 2019 08:56:09 +0000 Subject: [PATCH 0158/2234] fix travis --- dnsapi/dns_online.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index 0d1fca2a..9158c268 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -135,7 +135,7 @@ _get_root() { i=$(_math "$i" + 1) done _err "Unable to retrive DNS zone matching this domain" - return 1 + return 1 } # this function create a temporary zone version From f2acdd27fd0f8d0407058ad05b12137197d99afc Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 17 Feb 2019 14:19:14 +0800 Subject: [PATCH 0159/2234] fix tr err for Mac --- acme.sh | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/acme.sh b/acme.sh index cfdf5714..82c5e502 100755 --- a/acme.sh +++ b/acme.sh @@ -1882,29 +1882,34 @@ _send_signed_request() { _err "Can not post to $url" return 1 fi - _debug2 original "$response" - response="$(echo "$response" | _normalizeJson)" responseHeaders="$(cat "$HTTP_HEADER")" - _debug2 responseHeaders "$responseHeaders" - _debug2 response "$response" + code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")" _debug code "$code" - _CACHED_NONCE="$(echo "$responseHeaders" | grep "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" - - _body="$response" - if [ "$needbase64" ]; then - _body="$(echo "$_body" | _dbase64 | tr -d '\0')" - _debug3 _body "$_body" + _debug2 original "$response" + if echo "$responseHeaders" | grep -i "Content-Type: application/json" >/dev/null 2>&1; then + response="$(echo "$response" | _normalizeJson)" fi + _debug2 response "$response" - if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then - _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." - _CACHED_NONCE="" - _sleep $_sleep_retry_sec - continue + _CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" + + if ! _startswith "$code" "2"; then + _body="$response" + if [ "$needbase64" ]; then + _body="$(echo "$_body" | _dbase64 multiline)" + _debug3 _body "$_body" + fi + + if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then + _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." + _CACHED_NONCE="" + _sleep $_sleep_retry_sec + continue + fi fi break done @@ -4113,14 +4118,14 @@ $_authorizations_map" Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" _tempSignedResponse="$response" - if ! _send_signed_request "$Le_LinkCert" "" "needbase64"; then + if ! _send_signed_request "$Le_LinkCert"; then _err "Sign failed, can not download cert:$Le_LinkCert." _err "$response" _on_issue_err "$_post_hook" return 1 fi - echo "$response" | _dbase64 "multiline" >"$CERT_PATH" + echo "$response" >"$CERT_PATH" if [ "$(grep -- "$BEGIN_CERT" "$CERT_PATH" | wc -l)" -gt "1" ]; then _debug "Found cert chain" From a0ec5b18e79bfa21f22634806e80d0659105b35a Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 17 Feb 2019 14:26:27 +0800 Subject: [PATCH 0160/2234] fx format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 82c5e502..7b094e94 100755 --- a/acme.sh +++ b/acme.sh @@ -1897,7 +1897,7 @@ _send_signed_request() { _CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" - if ! _startswith "$code" "2"; then + if ! _startswith "$code" "2"; then _body="$response" if [ "$needbase64" ]; then _body="$(echo "$_body" | _dbase64 multiline)" From 9ff6d6e7b5bcaf41ccae97ee29d06223cda67455 Mon Sep 17 00:00:00 2001 From: dsc Date: Sun, 17 Feb 2019 23:20:17 +0100 Subject: [PATCH 0161/2234] initial commit --- dnsapi/dns_one.sh | 146 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 dnsapi/dns_one.sh diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh new file mode 100644 index 00000000..185669ce --- /dev/null +++ b/dnsapi/dns_one.sh @@ -0,0 +1,146 @@ +#!/usr/bin/env sh +# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- + +# one.com ui wrapper for acme.sh +# Author: github: @diseq +# Created: 2019-02-17 +# +# export ONECOM_USER="username" +# export ONECOM_PASSWORD="password" +# +# Usage: +# acme.sh --issue --dns dns_one -d example.com +# +# only single domain supported atm + +dns_one_add() { + mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev) + mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev) + txtvalue=$2 + + # get credentials + ONECOM_USER="${ONECOM_USER:-$(_readaccountconf_mutable ONECOM_USER)}" + ONECOM_PASSWORD="${ONECOM_PASSWORD:-$(_readaccountconf_mutable ONECOM_PASSWORD)}" + if [ -z "$ONECOM_USER" ] || [ -z "$ONECOM_PASSWORD" ]; then + ONECOM_USER="" + ONECOM_PASSWORD="" + _err "You didn't specify a one.com username and password yet." + _err "Please create the key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable ONECOM_USER "$ONECOM_USER" + _saveaccountconf_mutable ONECOM_PASSWORD "$ONECOM_PASSWORD" + + + # Login with user and password + postdata="loginDomain=true" + postdata="$postdata&displayUsername=$ONECOM_USER" + postdata="$postdata&username=$ONECOM_USER" + postdata="$postdata&targetDomain=$mydomain" + postdata="$postdata&password1=$ONECOM_PASSWORD" + postdata="$postdata&loginTarget=" + + #_debug postdata "$postdata" + + response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST")" + #_debug response "$response" + + JSESSIONID="$(grep "JSESSIONID=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')" + _debug jsessionid "$JSESSIONID" + + export _H1="Cookie: ${JSESSIONID}" + + + # get entries + response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" + _debug response "$response" + + + CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')" + export _H2="Cookie: ${CSRF_G_TOKEN}" + + + # Update the IP address for domain entry + postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}" + _debug postdata "$postdata" + response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records" "" "POST" "application/json")" + response="$(echo "$response" | _normalizeJson)" + _debug response "$response" + + id=$(printf -- "%s" "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") + + if [ -z "$id" ]; then + _err "Add txt record error." + return 1 + else + _info "Added, OK ($id)" + return 0 + fi + +} + +dns_one_rm() { + mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev) + mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev) + txtvalue=$2 + + # get credentials + ONECOM_USER="${ONECOM_USER:-$(_readaccountconf_mutable ONECOM_USER)}" + ONECOM_PASSWORD="${ONECOM_PASSWORD:-$(_readaccountconf_mutable ONECOM_PASSWORD)}" + if [ -z "$ONECOM_USER" ] || [ -z "$ONECOM_PASSWORD" ]; then + ONECOM_USER="" + ONECOM_PASSWORD="" + _err "You didn't specify a one.com username and password yet." + _err "Please create the key and try again." + return 1 + fi + + + # Login with user and password + postdata="loginDomain=true" + postdata="$postdata&displayUsername=$ONECOM_USER" + postdata="$postdata&username=$ONECOM_USER" + postdata="$postdata&targetDomain=$mydomain" + postdata="$postdata&password1=$ONECOM_PASSWORD" + postdata="$postdata&loginTarget=" + + response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST")" + + JSESSIONID="$(grep "JSESSIONID=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')" + _debug jsessionid "$JSESSIONID" + + export _H1="Cookie: ${JSESSIONID}" + + + # get entries + response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" + response="$(echo "$response" | _normalizeJson)" + _debug response "$response" + + CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')" + export _H2="Cookie: ${CSRF_G_TOKEN}" + + id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}.*/\1/p") + + if [ -z "$id" ]; then + _err "Txt record not found." + return 1 + fi + + # delete entry + response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records/$id" "" "DELETE" "application/json")" + response="$(echo "$response" | _normalizeJson)" + _debug response "$response" + + if [ "$response" = '{"result":null,"metadata":null}' ]; + then + _info "Removed, OK" + return 0 + else + _err "Removing txt record error." + return 1 + fi + +} \ No newline at end of file From 97147b594b185786ef1d69ce0d85b70a91f0ccc9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 18 Feb 2019 20:57:13 +0800 Subject: [PATCH 0162/2234] fix https://github.com/Neilpang/acme.sh/issues/2096 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 7b094e94..5c093e4c 100755 --- a/acme.sh +++ b/acme.sh @@ -1188,7 +1188,7 @@ _ss() { if _exists "netstat"; then _debug "Using: netstat" - if netstat -h 2>&1 | grep "\-p proto" >/dev/null; then + if netstat -help 2>&1 | grep "\-p proto" >/dev/null; then #for windows version netstat tool netstat -an -p tcp | grep "LISTENING" | grep ":$_port " else From b5ca9bbab2a73f11b9336d2ffe10a07add142130 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 19 Feb 2019 21:39:06 +0800 Subject: [PATCH 0163/2234] Doh (#2100) support doh to poll dns status fix https://github.com/Neilpang/acme.sh/issues/2015 --- acme.sh | 192 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 144 insertions(+), 48 deletions(-) diff --git a/acme.sh b/acme.sh index 23bc4f6b..93112a1a 100755 --- a/acme.sh +++ b/acme.sh @@ -2929,42 +2929,38 @@ _clearup() { _clearupdns() { _debug "_clearupdns" - _debug "dnsadded" "$dnsadded" - _debug "vlist" "$vlist" - #dnsadded is "0" or "1" means dns-01 method was used for at least one domain - if [ -z "$dnsadded" ] || [ -z "$vlist" ]; then + _debug "dns_entries" "$dns_entries" + + if [ -z "$dns_entries" ]; then _debug "skip dns." return fi _info "Removing DNS records." - ventries=$(echo "$vlist" | tr ',' ' ') - _alias_index=1 - for ventry in $ventries; do - d=$(echo "$ventry" | cut -d "$sep" -f 1) - keyauthorization=$(echo "$ventry" | cut -d "$sep" -f 2) - vtype=$(echo "$ventry" | cut -d "$sep" -f 4) - _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5) - txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" - _debug txt "$txt" - if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then - _debug "$d is already verified, skip $vtype." - _alias_index="$(_math "$_alias_index" + 1)" - continue - fi - if [ "$vtype" != "$VTYPE_DNS" ]; then - _debug "Skip $d for $vtype" - continue + for entry in $dns_entries; do + d=$(_getfield "$entry" 1) + txtdomain=$(_getfield "$entry" 2) + aliasDomain=$(_getfield "$entry" 3) + txt=$(_getfield "$entry" 5) + d_api=$(_getfield "$entry" 6) + _debug "d" "$d" + _debug "txtdomain" "$txtdomain" + _debug "aliasDomain" "$aliasDomain" + _debug "txt" "$txt" + _debug "d_api" "$d_api" + if [ "$d_api" = "$txt" ]; then + d_api="" fi - d_api="$(_findHook "$d" dnsapi "$_currentRoot")" - _debug d_api "$d_api" - if [ -z "$d_api" ]; then _info "Not Found domain api file: $d_api" continue fi + if [ "$aliasDomain" ]; then + txtdomain="$aliasDomain" + fi + ( if ! . "$d_api"; then _err "Load file $d_api error. Please check your api file and try again." @@ -2977,24 +2973,6 @@ _clearupdns() { return 1 fi - _dns_root_d="$d" - if _startswith "$_dns_root_d" "*."; then - _dns_root_d="$(echo "$_dns_root_d" | sed 's/*.//')" - fi - - _d_alias="$(_getfield "$_challenge_alias" "$_alias_index")" - _alias_index="$(_math "$_alias_index" + 1)" - _debug "_d_alias" "$_d_alias" - if [ "$_d_alias" ]; then - if _startswith "$_d_alias" "$DNS_ALIAS_PREFIX"; then - txtdomain="$(echo "$_d_alias" | sed "s/$DNS_ALIAS_PREFIX//")" - else - txtdomain="_acme-challenge.$_d_alias" - fi - else - txtdomain="_acme-challenge.$_dns_root_d" - fi - if ! $rmcommand "$txtdomain" "$txt"; then _err "Error removing txt for domain:$txtdomain" return 1 @@ -3463,6 +3441,113 @@ __trigger_validation() { fi } +#endpoint domain type +_ns_lookup() { + _ns_ep="$1" + _ns_domain="$2" + _ns_type="$3" + _debug2 "_ns_ep" "$_ns_ep" + _debug2 "_ns_domain" "$_ns_domain" + _debug2 "_ns_type" "$_ns_type" + + response="$(_H1="accept: application/dns-json" _get "$_ns_ep?name=$_ns_domain&type=$_ns_type")" + _ret=$? + _debug2 "response" "$response" + if [ "$_ret" != "0" ]; then + return $_ret + fi + _answers="$(echo "$response" | tr '{}' '<>' | _egrep_o '"Answer":\[[^]]*]' | tr '<>' '\n\n')" + _debug2 "_answers" "$_answers" + echo "$_answers" +} + +#domain, type +_ns_lookup_cf() { + _cf_ld="$1" + _cf_ld_type="$2" + _cf_ep="https://cloudflare-dns.com/dns-query" + _ns_lookup "$_cf_ep" "$_cf_ld" "$_cf_ld_type" +} + +#domain, type +_ns_purge_cf() { + _cf_d="$1" + _cf_d_type="$2" + _debug "Cloudflare purge $_cf_d_type record for domain $_cf_d" + _cf_purl="https://1.1.1.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" + response="$(_post "" "$_cf_purl")" + _debug2 response "$response" +} + +#txtdomain, alias, txt +__check_txt() { + _c_txtdomain="$1" + _c_aliasdomain="$2" + _c_txt="$3" + _debug "_c_txtdomain" "$_c_txtdomain" + _debug "_c_aliasdomain" "$_c_aliasdomain" + _debug "_c_txt" "$_c_txt" + _answers="$(_ns_lookup_cf "$_c_aliasdomain" TXT)" + _contains "$_answers" "$_c_txt" + +} + +#txtdomain +__purge_txt() { + _p_txtdomain="$1" + _debug _p_txtdomain "$_p_txtdomain" + _ns_purge_cf "$_p_txtdomain" "TXT" +} + +#wait and check each dns entries +_check_dns_entries() { + _success_txt="," + _end_time="$(_time)" + _end_time="$(_math "$_end_time" + 1200)" #let's check no more than 20 minutes. + + while [ "$(_time)" -le "$_end_time" ]; do + _left="" + for entry in $dns_entries; do + d=$(_getfield "$entry" 1) + txtdomain=$(_getfield "$entry" 2) + aliasDomain=$(_getfield "$entry" 3) + txt=$(_getfield "$entry" 5) + d_api=$(_getfield "$entry" 6) + _debug "d" "$d" + _debug "txtdomain" "$txtdomain" + _debug "aliasDomain" "$aliasDomain" + _debug "txt" "$txt" + _debug "d_api" "$d_api" + _info "Checking $d for $aliasDomain" + if _contains "$_success_txt" ",$txt,"; then + _info "Already success, continue next one." + continue + fi + + if __check_txt "$txtdomain" "$aliasDomain" "$txt"; then + _info "Domain $d '$aliasDomain' success." + _success_txt="$_success_txt,$txt," + continue + fi + _left=1 + _info "Not valid yet, let's wait 10 seconds and check next one." + _sleep 10 + __purge_txt "$txtdomain" + if [ "$txtdomain" != "$aliasDomain" ]; then + __purge_txt "$aliasDomain" + fi + done + if [ "$_left" ]; then + _info "Let's wait 10 seconds and check again". + _sleep 10 + else + _info "All success, let's return" + break + fi + done + +} + #webroot, domain domainlist keylength issue() { if [ -z "$2" ]; then @@ -3786,6 +3871,7 @@ $_authorizations_map" done _debug vlist "$vlist" #add entry + dns_entries="" dnsadded="" ventries=$(echo "$vlist" | tr "$dvsep" ' ') _alias_index=1 @@ -3816,8 +3902,10 @@ $_authorizations_map" else txtdomain="_acme-challenge.$_d_alias" fi + dns_entries="${dns_entries}${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$txtdomain$dvsep$_currentRoot" else txtdomain="_acme-challenge.$_dns_root_d" + dns_entries="${dns_entries}${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$dvsep$_currentRoot" fi _debug txtdomain "$txtdomain" txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" @@ -3826,7 +3914,9 @@ $_authorizations_map" d_api="$(_findHook "$_dns_root_d" dnsapi "$_currentRoot")" _debug d_api "$d_api" - + dns_entries="$dns_entries$dvsep$txt${dvsep}$d_api +" + _debug2 "$dns_entries" if [ "$d_api" ]; then _info "Found domain api file: $d_api" else @@ -3880,15 +3970,21 @@ $_authorizations_map" fi - if [ "$dnsadded" = '1' ]; then + if [ "$dns_entries" ]; then if [ -z "$Le_DNSSleep" ]; then - Le_DNSSleep="$DEFAULT_DNS_SLEEP" + _info "Let's check each dns records now. Sleep 20 seconds first." + _sleep 20 + if ! _check_dns_entries; then + _err "check dns error." + _on_issue_err "$_post_hook" + _clearup + return 1 + fi else _savedomainconf "Le_DNSSleep" "$Le_DNSSleep" + _info "Sleep $(__green $Le_DNSSleep) seconds for the txt records to take effect" + _sleep "$Le_DNSSleep" fi - - _info "Sleep $(__green $Le_DNSSleep) seconds for the txt records to take effect" - _sleep "$Le_DNSSleep" fi NGINX_RESTORE_VLIST="" From 16a0f40ac27b85180b55a383f8ceebf3a7cc342f Mon Sep 17 00:00:00 2001 From: Marcin Konicki Date: Wed, 20 Feb 2019 02:40:36 +0100 Subject: [PATCH 0164/2234] Support for MyDevil.net (#2076) support mydevil --- README.md | 1 + deploy/README.md | 10 +++++ deploy/mydevil.sh | 59 ++++++++++++++++++++++++++ dnsapi/README.md | 20 +++++++++ dnsapi/dns_mydevil.sh | 97 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 187 insertions(+) create mode 100755 deploy/mydevil.sh create mode 100755 dnsapi/dns_mydevil.sh diff --git a/README.md b/README.md index 8d749dcc..f79b8602 100644 --- a/README.md +++ b/README.md @@ -356,6 +356,7 @@ You don't have to do anything manually! 1. Futurehosting API (https://www.futurehosting.com) 1. Rackspace Cloud DNS (https://www.rackspace.com) 1. Online.net API (https://online.net/) +1. MyDevil.net (https://www.mydevil.net/) And: diff --git a/deploy/README.md b/deploy/README.md index 091e9feb..f290756a 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -381,3 +381,13 @@ you want to update: $ export QINIU_CDN_DOMAIN="cdn.example.com" $ acme.sh --deploy -d example.com --deploy-hook qiniu ``` + +## 14. Deploy your cert on MyDevil.net + +Once you have acme.sh installed and certificate issued (see info in [DNS API](../dnsapi/README.md#61-use-mydevilnet)), you can install it by following command: + +```sh +acme.sh --deploy --deploy-hook mydevil -d example.com +``` + +That will remove old certificate and install new one. diff --git a/deploy/mydevil.sh b/deploy/mydevil.sh new file mode 100755 index 00000000..bd9868aa --- /dev/null +++ b/deploy/mydevil.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env sh + +# MyDevil.net API (2019-02-03) +# +# MyDevil.net already supports automatic Let's Encrypt certificates, +# except for wildcard domains. +# +# This script depends on `devil` command that MyDevil.net provides, +# which means that it works only on server side. +# +# Author: Marcin Konicki +# +######## Public functions ##################### + +# Usage: mydevil_deploy domain keyfile certfile cafile fullchain +mydevil_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + ip="" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if ! _exists "devil"; then + _err "Could not find 'devil' command." + return 1 + fi + + ip=$(mydevil_get_ip "$_cdomain") + if [ -z "$ip" ]; then + _err "Could not find IP for domain $_cdomain." + return 1 + fi + + # Delete old certificate first + _info "Removing old certificate for $_cdomain at $ip" + devil ssl www del "$ip" "$_cdomain" + + # Add new certificate + _info "Adding new certificate for $_cdomain at $ip" + devil ssl www add "$ip" "$_cfullchain" "$_ckey" "$_cdomain" || return 1 + + return 0 +} + +#################### Private functions below ################################## + +# Usage: ip=$(mydevil_get_ip domain.com) +# echo $ip +mydevil_get_ip() { + devil dns list "$1" | cut -w -s -f 3,7 | grep "^A$(printf '\t')" | cut -w -s -f 2 || return 1 + return 0 +} diff --git a/dnsapi/README.md b/dnsapi/README.md index f022cab0..9f176c0d 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1259,6 +1259,26 @@ acme.sh --issue --dns dns_online -d example.com -d www.example.com `ONLINE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 66. Use MyDevil.net + +Make sure that you can execute own binaries: + +```sh +devil binexec on +``` + +Install acme.sh, or simply `git clone` it into some directory on your MyDevil host account (in which case you should link to it from your `~/bin` directory). + +If you're not using private IP and depend on default IP provided by host, you may want to edit `crontab` too, and make sure that `acme.sh --cron` is run also after reboot (you can find out how to do that on their wiki pages). + +To issue a new certificate, run: + +```sh +acme.sh --issue --dns dns_mydevil -d example.com -d *.example.com +``` + +After certificate is ready, you can install it with [deploy command](../deploy/README.md#14-deploy-your-cert-on-mydevilnet). + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_mydevil.sh b/dnsapi/dns_mydevil.sh new file mode 100755 index 00000000..2f398959 --- /dev/null +++ b/dnsapi/dns_mydevil.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env sh + +# MyDevil.net API (2019-02-03) +# +# MyDevil.net already supports automatic Let's Encrypt certificates, +# except for wildcard domains. +# +# This script depends on `devil` command that MyDevil.net provides, +# which means that it works only on server side. +# +# Author: Marcin Konicki +# +######## Public functions ##################### + +#Usage: dns_mydevil_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_mydevil_add() { + fulldomain=$1 + txtvalue=$2 + domain="" + + if ! _exists "devil"; then + _err "Could not find 'devil' command." + return 1 + fi + + _info "Using mydevil" + + domain=$(mydevil_get_domain "$fulldomain") + if [ -z "$domain" ]; then + _err "Invalid domain name: could not find root domain of $fulldomain." + return 1 + fi + + # No need to check if record name exists, `devil` always adds new record. + # In worst case scenario, we end up with multiple identical records. + + _info "Adding $fulldomain record for domain $domain" + if devil dns add "$domain" "$fulldomain" TXT "$txtvalue"; then + _info "Successfully added TXT record, ready for validation." + return 0 + else + _err "Unable to add DNS record." + return 1 + fi +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_mydevil_rm() { + fulldomain=$1 + txtvalue=$2 + domain="" + + if ! _exists "devil"; then + _err "Could not find 'devil' command." + return 1 + fi + + _info "Using mydevil" + + domain=$(mydevil_get_domain "$fulldomain") + if [ -z "$domain" ]; then + _err "Invalid domain name: could not find root domain of $fulldomain." + return 1 + fi + + # catch one or more numbers + num='[0-9][0-9]*' + # catch one or more whitespace + w=$(printf '[\t ][\t ]*') + # catch anything, except newline + any='.*' + # filter to make sure we do not delete other records + 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." + done +} + +#################### Private functions below ################################## + +# Usage: domain=$(mydevil_get_domain "_acme-challenge.www.domain.com" || _err "Invalid domain name") +# echo $domain +mydevil_get_domain() { + fulldomain=$1 + domain="" + + for domain in $(devil dns list | cut -w -s -f 1 | tail -n+2); do + if _endswith "$fulldomain" "$domain"; then + printf -- "%s" "$domain" + return 0 + fi + done + + return 1 +} From 0bb746ba39d2e1cc5fdf732422050f77fb28e513 Mon Sep 17 00:00:00 2001 From: diseq Date: Wed, 20 Feb 2019 09:44:25 +0100 Subject: [PATCH 0165/2234] Update dns_one.sh --- dnsapi/dns_one.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 185669ce..521b034c 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -143,4 +143,4 @@ dns_one_rm() { return 1 fi -} \ No newline at end of file +} From 81ba629b5684e75e450345ae6024987ce8d80a90 Mon Sep 17 00:00:00 2001 From: diseq Date: Wed, 20 Feb 2019 11:27:49 +0100 Subject: [PATCH 0166/2234] allow set-cookie as well as Set-Cookie --- dnsapi/dns_one.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 521b034c..5dc002d5 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -41,13 +41,12 @@ dns_one_add() { postdata="$postdata&targetDomain=$mydomain" postdata="$postdata&password1=$ONECOM_PASSWORD" postdata="$postdata&loginTarget=" - #_debug postdata "$postdata" - response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST")" + response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")" #_debug response "$response" - JSESSIONID="$(grep "JSESSIONID=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')" + JSESSIONID="$(grep "JSESSIONID" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')" _debug jsessionid "$JSESSIONID" export _H1="Cookie: ${JSESSIONID}" @@ -106,9 +105,10 @@ dns_one_rm() { postdata="$postdata&password1=$ONECOM_PASSWORD" postdata="$postdata&loginTarget=" - response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST")" + response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")" + #_debug response "$response" - JSESSIONID="$(grep "JSESSIONID=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')" + JSESSIONID="$(grep "JSESSIONID" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')" _debug jsessionid "$JSESSIONID" export _H1="Cookie: ${JSESSIONID}" From 0499d2b5c4bef6bd105ff64f1bc5df419fd4ab9a Mon Sep 17 00:00:00 2001 From: diseq Date: Wed, 20 Feb 2019 11:51:06 +0100 Subject: [PATCH 0167/2234] remove line break --- dnsapi/dns_one.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 5dc002d5..1bc30ab7 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -134,8 +134,7 @@ dns_one_rm() { response="$(echo "$response" | _normalizeJson)" _debug response "$response" - if [ "$response" = '{"result":null,"metadata":null}' ]; - then + if [ "$response" = '{"result":null,"metadata":null}' ]; then _info "Removed, OK" return 0 else From ed3f2646f0d9188de9cf9b1efe2d6c612ce624ea Mon Sep 17 00:00:00 2001 From: diseq Date: Wed, 20 Feb 2019 11:54:48 +0100 Subject: [PATCH 0168/2234] fix format --- dnsapi/dns_one.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 1bc30ab7..d3ad670f 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -135,11 +135,11 @@ dns_one_rm() { _debug response "$response" if [ "$response" = '{"result":null,"metadata":null}' ]; then - _info "Removed, OK" - return 0 - else - _err "Removing txt record error." - return 1 + _info "Removed, OK" + return 0 + else + _err "Removing txt record error." + return 1 fi } From 472ed721a38312c8bc53b3cfd7764c2ccc8c75ef Mon Sep 17 00:00:00 2001 From: diseq Date: Wed, 20 Feb 2019 21:51:59 +0100 Subject: [PATCH 0169/2234] fix format --- dnsapi/dns_one.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index d3ad670f..c99c9c97 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -33,7 +33,6 @@ dns_one_add() { _saveaccountconf_mutable ONECOM_USER "$ONECOM_USER" _saveaccountconf_mutable ONECOM_PASSWORD "$ONECOM_PASSWORD" - # Login with user and password postdata="loginDomain=true" postdata="$postdata&displayUsername=$ONECOM_USER" @@ -51,16 +50,13 @@ dns_one_add() { export _H1="Cookie: ${JSESSIONID}" - # get entries response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" _debug response "$response" - CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')" export _H2="Cookie: ${CSRF_G_TOKEN}" - # Update the IP address for domain entry postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}" _debug postdata "$postdata" @@ -96,7 +92,6 @@ dns_one_rm() { return 1 fi - # Login with user and password postdata="loginDomain=true" postdata="$postdata&displayUsername=$ONECOM_USER" @@ -113,7 +108,6 @@ dns_one_rm() { export _H1="Cookie: ${JSESSIONID}" - # get entries response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" response="$(echo "$response" | _normalizeJson)" From 23b4c9c667d6aab198cf4f633b9ccc1b05b66640 Mon Sep 17 00:00:00 2001 From: dsc Date: Thu, 21 Feb 2019 08:43:09 +0100 Subject: [PATCH 0170/2234] add docs for one.com --- dnsapi/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dnsapi/README.md b/dnsapi/README.md index f022cab0..cb8ac574 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1280,3 +1280,19 @@ See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide # Use lexicon DNS API https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api + +## 66. Use one.com domain API to automatically issue cert + +Use your one.com credentials as you would login into the control panel. + +``` +export ONECOM_USER="sdfsdfsdfljlbjkljlkjsdfoiwje" +export ONECOM_PASSWORD="xxxx@sss.com" +``` + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_one -d example.com -d www.example.com +``` + +The `ONECOM_USER` and `ONECOM_PASSWORD` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. From ec54074392561f3f697b489fb278445aee34ada5 Mon Sep 17 00:00:00 2001 From: Timothy Nelson Date: Mon, 25 Feb 2019 05:19:36 -0600 Subject: [PATCH 0171/2234] Fix verification for namecheap domains not *owned* by the calling user (#2106) --- dnsapi/dns_namecheap.sh | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index fbf93c32..6553deb6 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -76,6 +76,22 @@ dns_namecheap_rm() { # _sub_domain=_acme-challenge.www # _domain=domain.com _get_root() { + fulldomain=$1 + + if ! _get_root_by_getList "$fulldomain"; then + _debug "Failed domain lookup via domains.getList api call. Trying domain lookup via domains.dns.getHosts api." + # The above "getList" api will only return hosts *owned* by the calling user. However, if the calling + # user is not the owner, but still has administrative rights, we must query the getHosts api directly. + # See this comment and the official namecheap response: http://disq.us/p/1q6v9x9 + if ! _get_root_by_getHosts "$fulldomain"; then + return 1 + fi + fi + + return 0 +} + +_get_root_by_getList() { domain=$1 if ! _namecheap_post "namecheap.domains.getList"; then @@ -94,6 +110,10 @@ _get_root() { #not valid return 1 fi + if ! _contains "$h" "\\."; then + #not valid + return 1 + fi if ! _contains "$response" "$h"; then _debug "$h not found" @@ -108,6 +128,31 @@ _get_root() { return 1 } +_get_root_by_getHosts() { + i=100 + p=99 + + while [ $p -ne 0 ]; do + + h=$(printf "%s" "$1" | cut -d . -f $i-100) + if [ -n "$h" ]; then + if _contains "$h" "\\."; then + _debug h "$h" + if _namecheap_set_tld_sld "$h"; then + _sub_domain=$(printf "%s" "$1" | cut -d . -f 1-$p) + _domain="$h" + return 0 + else + _debug "$h not found" + fi + fi + fi + i="$p" + p=$(_math "$p" - 1) + done + return 1 +} + _namecheap_set_publicip() { if [ -z "$NAMECHEAP_SOURCEIP" ]; then From e7f7e96d589ca757ab91744a97893f83d615c481 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 27 Feb 2019 20:36:13 +0800 Subject: [PATCH 0172/2234] Peb (#2126) * support pebble * support async finalize order --- acme.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 14 deletions(-) diff --git a/acme.sh b/acme.sh index 93112a1a..8ee22479 100755 --- a/acme.sh +++ b/acme.sh @@ -1827,23 +1827,29 @@ _send_signed_request() { nonceurl="$ACME_NEW_NONCE" if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then _headers="$(cat "$HTTP_HEADER")" + _debug2 _headers "$_headers" + _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" fi fi - if [ -z "$_headers" ]; then + if [ -z "$_CACHED_NONCE" ]; then _debug2 "Get nonce with GET. ACME_DIRECTORY" "$ACME_DIRECTORY" nonceurl="$ACME_DIRECTORY" _headers="$(_get "$nonceurl" "onlyheader")" + _debug2 _headers "$_headers" + _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" fi - + if [ -z "$_CACHED_NONCE" ] && [ "$ACME_NEW_NONCE" ]; then + _debug2 "Get nonce with GET. ACME_NEW_NONCE" "$ACME_NEW_NONCE" + nonceurl="$ACME_NEW_NONCE" + _headers="$(_get "$nonceurl" "onlyheader")" + _debug2 _headers "$_headers" + _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" + fi + _debug2 _CACHED_NONCE "$_CACHED_NONCE" if [ "$?" != "0" ]; then _err "Can not connect to $nonceurl to get nonce." return 1 fi - - _debug2 _headers "$_headers" - - _CACHED_NONCE="$(echo "$_headers" | grep "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" - _debug2 _CACHED_NONCE "$_CACHED_NONCE" else _debug2 "Use _CACHED_NONCE" "$_CACHED_NONCE" fi @@ -2060,6 +2066,7 @@ _clearcaconf() { _startserver() { content="$1" ncaddr="$2" + _debug "content" "$content" _debug "ncaddr" "$ncaddr" _debug "startserver: $$" @@ -2086,8 +2093,14 @@ _startserver() { SOCAT_OPTIONS="$SOCAT_OPTIONS,bind=${ncaddr}" fi + _content_len="$(printf "%s" "$content" | wc -c)" + _debug _content_len "$_content_len" _debug "_NC" "$_NC $SOCAT_OPTIONS" - $_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; echo HTTP/1.0 200 OK; echo ; echo $content; echo;" & + $_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; \ +echo 'HTTP/1.0 200 OK'; \ +echo 'Content-Length\: $_content_len'; \ +echo ''; \ +printf '$content';" & serverproc="$!" } @@ -3062,6 +3075,7 @@ _on_before_issue() { _info "Standalone mode." if [ -z "$Le_HTTPPort" ]; then Le_HTTPPort=80 + _cleardomainconf "Le_HTTPPort" else _savedomainconf "Le_HTTPPort" "$Le_HTTPPort" fi @@ -3269,7 +3283,7 @@ _regAccount() { fi _debug2 responseHeaders "$responseHeaders" - _accUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")" + _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")" _debug "_accUri" "$_accUri" if [ -z "$_accUri" ]; then _err "Can not find account id url." @@ -3435,7 +3449,7 @@ __trigger_validation() { _t_vtype="$3" _debug2 _t_vtype "$_t_vtype" if [ "$ACME_VERSION" = "2" ]; then - _send_signed_request "$_t_url" "{\"keyAuthorization\": \"$_t_key_authz\"}" + _send_signed_request "$_t_url" "{}" else _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"type\": \"$_t_vtype\", \"keyAuthorization\": \"$_t_key_authz\"}" fi @@ -4205,20 +4219,66 @@ $_authorizations_map" der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" if [ "$ACME_VERSION" = "2" ]; then + _info "Lets finalize the order, Le_OrderFinalize: $Le_OrderFinalize" if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then _err "Sign failed." _on_issue_err "$_post_hook" return 1 fi if [ "$code" != "200" ]; then - _err "Sign failed, code is not 200." + _err "Sign failed, finalize code is not 200." _err "$response" _on_issue_err "$_post_hook" return 1 fi - Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" + Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)" + if [ -z "$Le_LinkOrder" ]; then + _err "Sign error, can not get order link location header" + _err "responseHeaders" "$responseHeaders" + _on_issue_err "$_post_hook" + return 1 + fi + _savedomainconf "Le_LinkOrder" "$Le_LinkOrder" - _tempSignedResponse="$response" + _link_cert_retry=0 + _MAX_CERT_RETRY=5 + while [ -z "$Le_LinkCert" ] && [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do + if _contains "$response" "\"status\":\"valid\""; then + _debug "Order status is valid." + Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" + _debug Le_LinkCert "$Le_LinkCert" + if [ -z "$Le_LinkCert" ]; then + _err "Sign error, can not find Le_LinkCert" + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + break + elif _contains "$response" "\"processing\""; then + _info "Order status is processing, lets sleep and retry." + _sleep 2 + else + _err "Sign error, wrong status" + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + if ! _send_signed_request "$Le_LinkOrder"; then + _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder." + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + _link_cert_retry="$(_math $_link_cert_retry + 1)" + done + + if [ -z "$Le_LinkCert" ]; then + _err "Sign failed, can not get Le_LinkCert, retry time limit." + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + _info "Download cert, Le_LinkCert: $Le_LinkCert" if ! _send_signed_request "$Le_LinkCert"; then _err "Sign failed, can not download cert:$Le_LinkCert." _err "$response" @@ -4237,7 +4297,7 @@ $_authorizations_map" _end_n="$(_math $_end_n + 1)" sed -n "${_end_n},9999p" "$CERT_FULLCHAIN_PATH" >"$CA_CERT_PATH" fi - response="$_tempSignedResponse" + else if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then _err "Sign failed. $response" From 81f0189d2342069ca74bd942f2d3592c1054232b Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 27 Feb 2019 20:40:10 +0800 Subject: [PATCH 0173/2234] add Pebble --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f79b8602..f68eb002 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ https://github.com/Neilpang/acmetest - Letsencrypt.org CA(default) - [BuyPass.com CA](https://github.com/Neilpang/acme.sh/wiki/BuyPass.com-CA) +- [Pebble strict Mode](https://github.com/letsencrypt/pebble) # Supported modes From 693d692a472e9298c3bf3ee71ffc7d3328451887 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 27 Feb 2019 20:41:50 +0800 Subject: [PATCH 0174/2234] sync (#2127) * Support for MyDevil.net (#2076) support mydevil * Fix verification for namecheap domains not *owned* by the calling user (#2106) * Peb (#2126) * support pebble * support async finalize order * add Pebble --- README.md | 2 + acme.sh | 88 +++++++++++++++++++++++++++++++------ deploy/README.md | 10 +++++ deploy/mydevil.sh | 59 +++++++++++++++++++++++++ dnsapi/README.md | 20 +++++++++ dnsapi/dns_mydevil.sh | 97 +++++++++++++++++++++++++++++++++++++++++ dnsapi/dns_namecheap.sh | 45 +++++++++++++++++++ 7 files changed, 307 insertions(+), 14 deletions(-) create mode 100755 deploy/mydevil.sh create mode 100755 dnsapi/dns_mydevil.sh diff --git a/README.md b/README.md index 8d749dcc..f68eb002 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ https://github.com/Neilpang/acmetest - Letsencrypt.org CA(default) - [BuyPass.com CA](https://github.com/Neilpang/acme.sh/wiki/BuyPass.com-CA) +- [Pebble strict Mode](https://github.com/letsencrypt/pebble) # Supported modes @@ -356,6 +357,7 @@ You don't have to do anything manually! 1. Futurehosting API (https://www.futurehosting.com) 1. Rackspace Cloud DNS (https://www.rackspace.com) 1. Online.net API (https://online.net/) +1. MyDevil.net (https://www.mydevil.net/) And: diff --git a/acme.sh b/acme.sh index 93112a1a..8ee22479 100755 --- a/acme.sh +++ b/acme.sh @@ -1827,23 +1827,29 @@ _send_signed_request() { nonceurl="$ACME_NEW_NONCE" if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then _headers="$(cat "$HTTP_HEADER")" + _debug2 _headers "$_headers" + _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" fi fi - if [ -z "$_headers" ]; then + if [ -z "$_CACHED_NONCE" ]; then _debug2 "Get nonce with GET. ACME_DIRECTORY" "$ACME_DIRECTORY" nonceurl="$ACME_DIRECTORY" _headers="$(_get "$nonceurl" "onlyheader")" + _debug2 _headers "$_headers" + _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" fi - + if [ -z "$_CACHED_NONCE" ] && [ "$ACME_NEW_NONCE" ]; then + _debug2 "Get nonce with GET. ACME_NEW_NONCE" "$ACME_NEW_NONCE" + nonceurl="$ACME_NEW_NONCE" + _headers="$(_get "$nonceurl" "onlyheader")" + _debug2 _headers "$_headers" + _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" + fi + _debug2 _CACHED_NONCE "$_CACHED_NONCE" if [ "$?" != "0" ]; then _err "Can not connect to $nonceurl to get nonce." return 1 fi - - _debug2 _headers "$_headers" - - _CACHED_NONCE="$(echo "$_headers" | grep "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" - _debug2 _CACHED_NONCE "$_CACHED_NONCE" else _debug2 "Use _CACHED_NONCE" "$_CACHED_NONCE" fi @@ -2060,6 +2066,7 @@ _clearcaconf() { _startserver() { content="$1" ncaddr="$2" + _debug "content" "$content" _debug "ncaddr" "$ncaddr" _debug "startserver: $$" @@ -2086,8 +2093,14 @@ _startserver() { SOCAT_OPTIONS="$SOCAT_OPTIONS,bind=${ncaddr}" fi + _content_len="$(printf "%s" "$content" | wc -c)" + _debug _content_len "$_content_len" _debug "_NC" "$_NC $SOCAT_OPTIONS" - $_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; echo HTTP/1.0 200 OK; echo ; echo $content; echo;" & + $_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; \ +echo 'HTTP/1.0 200 OK'; \ +echo 'Content-Length\: $_content_len'; \ +echo ''; \ +printf '$content';" & serverproc="$!" } @@ -3062,6 +3075,7 @@ _on_before_issue() { _info "Standalone mode." if [ -z "$Le_HTTPPort" ]; then Le_HTTPPort=80 + _cleardomainconf "Le_HTTPPort" else _savedomainconf "Le_HTTPPort" "$Le_HTTPPort" fi @@ -3269,7 +3283,7 @@ _regAccount() { fi _debug2 responseHeaders "$responseHeaders" - _accUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")" + _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")" _debug "_accUri" "$_accUri" if [ -z "$_accUri" ]; then _err "Can not find account id url." @@ -3435,7 +3449,7 @@ __trigger_validation() { _t_vtype="$3" _debug2 _t_vtype "$_t_vtype" if [ "$ACME_VERSION" = "2" ]; then - _send_signed_request "$_t_url" "{\"keyAuthorization\": \"$_t_key_authz\"}" + _send_signed_request "$_t_url" "{}" else _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"type\": \"$_t_vtype\", \"keyAuthorization\": \"$_t_key_authz\"}" fi @@ -4205,20 +4219,66 @@ $_authorizations_map" der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" if [ "$ACME_VERSION" = "2" ]; then + _info "Lets finalize the order, Le_OrderFinalize: $Le_OrderFinalize" if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then _err "Sign failed." _on_issue_err "$_post_hook" return 1 fi if [ "$code" != "200" ]; then - _err "Sign failed, code is not 200." + _err "Sign failed, finalize code is not 200." _err "$response" _on_issue_err "$_post_hook" return 1 fi - Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" + Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)" + if [ -z "$Le_LinkOrder" ]; then + _err "Sign error, can not get order link location header" + _err "responseHeaders" "$responseHeaders" + _on_issue_err "$_post_hook" + return 1 + fi + _savedomainconf "Le_LinkOrder" "$Le_LinkOrder" - _tempSignedResponse="$response" + _link_cert_retry=0 + _MAX_CERT_RETRY=5 + while [ -z "$Le_LinkCert" ] && [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do + if _contains "$response" "\"status\":\"valid\""; then + _debug "Order status is valid." + Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" + _debug Le_LinkCert "$Le_LinkCert" + if [ -z "$Le_LinkCert" ]; then + _err "Sign error, can not find Le_LinkCert" + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + break + elif _contains "$response" "\"processing\""; then + _info "Order status is processing, lets sleep and retry." + _sleep 2 + else + _err "Sign error, wrong status" + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + if ! _send_signed_request "$Le_LinkOrder"; then + _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder." + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + _link_cert_retry="$(_math $_link_cert_retry + 1)" + done + + if [ -z "$Le_LinkCert" ]; then + _err "Sign failed, can not get Le_LinkCert, retry time limit." + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + _info "Download cert, Le_LinkCert: $Le_LinkCert" if ! _send_signed_request "$Le_LinkCert"; then _err "Sign failed, can not download cert:$Le_LinkCert." _err "$response" @@ -4237,7 +4297,7 @@ $_authorizations_map" _end_n="$(_math $_end_n + 1)" sed -n "${_end_n},9999p" "$CERT_FULLCHAIN_PATH" >"$CA_CERT_PATH" fi - response="$_tempSignedResponse" + else if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then _err "Sign failed. $response" diff --git a/deploy/README.md b/deploy/README.md index 091e9feb..f290756a 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -381,3 +381,13 @@ you want to update: $ export QINIU_CDN_DOMAIN="cdn.example.com" $ acme.sh --deploy -d example.com --deploy-hook qiniu ``` + +## 14. Deploy your cert on MyDevil.net + +Once you have acme.sh installed and certificate issued (see info in [DNS API](../dnsapi/README.md#61-use-mydevilnet)), you can install it by following command: + +```sh +acme.sh --deploy --deploy-hook mydevil -d example.com +``` + +That will remove old certificate and install new one. diff --git a/deploy/mydevil.sh b/deploy/mydevil.sh new file mode 100755 index 00000000..bd9868aa --- /dev/null +++ b/deploy/mydevil.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env sh + +# MyDevil.net API (2019-02-03) +# +# MyDevil.net already supports automatic Let's Encrypt certificates, +# except for wildcard domains. +# +# This script depends on `devil` command that MyDevil.net provides, +# which means that it works only on server side. +# +# Author: Marcin Konicki +# +######## Public functions ##################### + +# Usage: mydevil_deploy domain keyfile certfile cafile fullchain +mydevil_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + ip="" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if ! _exists "devil"; then + _err "Could not find 'devil' command." + return 1 + fi + + ip=$(mydevil_get_ip "$_cdomain") + if [ -z "$ip" ]; then + _err "Could not find IP for domain $_cdomain." + return 1 + fi + + # Delete old certificate first + _info "Removing old certificate for $_cdomain at $ip" + devil ssl www del "$ip" "$_cdomain" + + # Add new certificate + _info "Adding new certificate for $_cdomain at $ip" + devil ssl www add "$ip" "$_cfullchain" "$_ckey" "$_cdomain" || return 1 + + return 0 +} + +#################### Private functions below ################################## + +# Usage: ip=$(mydevil_get_ip domain.com) +# echo $ip +mydevil_get_ip() { + devil dns list "$1" | cut -w -s -f 3,7 | grep "^A$(printf '\t')" | cut -w -s -f 2 || return 1 + return 0 +} diff --git a/dnsapi/README.md b/dnsapi/README.md index f022cab0..9f176c0d 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1259,6 +1259,26 @@ acme.sh --issue --dns dns_online -d example.com -d www.example.com `ONLINE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 66. Use MyDevil.net + +Make sure that you can execute own binaries: + +```sh +devil binexec on +``` + +Install acme.sh, or simply `git clone` it into some directory on your MyDevil host account (in which case you should link to it from your `~/bin` directory). + +If you're not using private IP and depend on default IP provided by host, you may want to edit `crontab` too, and make sure that `acme.sh --cron` is run also after reboot (you can find out how to do that on their wiki pages). + +To issue a new certificate, run: + +```sh +acme.sh --issue --dns dns_mydevil -d example.com -d *.example.com +``` + +After certificate is ready, you can install it with [deploy command](../deploy/README.md#14-deploy-your-cert-on-mydevilnet). + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_mydevil.sh b/dnsapi/dns_mydevil.sh new file mode 100755 index 00000000..2f398959 --- /dev/null +++ b/dnsapi/dns_mydevil.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env sh + +# MyDevil.net API (2019-02-03) +# +# MyDevil.net already supports automatic Let's Encrypt certificates, +# except for wildcard domains. +# +# This script depends on `devil` command that MyDevil.net provides, +# which means that it works only on server side. +# +# Author: Marcin Konicki +# +######## Public functions ##################### + +#Usage: dns_mydevil_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_mydevil_add() { + fulldomain=$1 + txtvalue=$2 + domain="" + + if ! _exists "devil"; then + _err "Could not find 'devil' command." + return 1 + fi + + _info "Using mydevil" + + domain=$(mydevil_get_domain "$fulldomain") + if [ -z "$domain" ]; then + _err "Invalid domain name: could not find root domain of $fulldomain." + return 1 + fi + + # No need to check if record name exists, `devil` always adds new record. + # In worst case scenario, we end up with multiple identical records. + + _info "Adding $fulldomain record for domain $domain" + if devil dns add "$domain" "$fulldomain" TXT "$txtvalue"; then + _info "Successfully added TXT record, ready for validation." + return 0 + else + _err "Unable to add DNS record." + return 1 + fi +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_mydevil_rm() { + fulldomain=$1 + txtvalue=$2 + domain="" + + if ! _exists "devil"; then + _err "Could not find 'devil' command." + return 1 + fi + + _info "Using mydevil" + + domain=$(mydevil_get_domain "$fulldomain") + if [ -z "$domain" ]; then + _err "Invalid domain name: could not find root domain of $fulldomain." + return 1 + fi + + # catch one or more numbers + num='[0-9][0-9]*' + # catch one or more whitespace + w=$(printf '[\t ][\t ]*') + # catch anything, except newline + any='.*' + # filter to make sure we do not delete other records + 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." + done +} + +#################### Private functions below ################################## + +# Usage: domain=$(mydevil_get_domain "_acme-challenge.www.domain.com" || _err "Invalid domain name") +# echo $domain +mydevil_get_domain() { + fulldomain=$1 + domain="" + + for domain in $(devil dns list | cut -w -s -f 1 | tail -n+2); do + if _endswith "$fulldomain" "$domain"; then + printf -- "%s" "$domain" + return 0 + fi + done + + return 1 +} diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index fbf93c32..6553deb6 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -76,6 +76,22 @@ dns_namecheap_rm() { # _sub_domain=_acme-challenge.www # _domain=domain.com _get_root() { + fulldomain=$1 + + if ! _get_root_by_getList "$fulldomain"; then + _debug "Failed domain lookup via domains.getList api call. Trying domain lookup via domains.dns.getHosts api." + # The above "getList" api will only return hosts *owned* by the calling user. However, if the calling + # user is not the owner, but still has administrative rights, we must query the getHosts api directly. + # See this comment and the official namecheap response: http://disq.us/p/1q6v9x9 + if ! _get_root_by_getHosts "$fulldomain"; then + return 1 + fi + fi + + return 0 +} + +_get_root_by_getList() { domain=$1 if ! _namecheap_post "namecheap.domains.getList"; then @@ -94,6 +110,10 @@ _get_root() { #not valid return 1 fi + if ! _contains "$h" "\\."; then + #not valid + return 1 + fi if ! _contains "$response" "$h"; then _debug "$h not found" @@ -108,6 +128,31 @@ _get_root() { return 1 } +_get_root_by_getHosts() { + i=100 + p=99 + + while [ $p -ne 0 ]; do + + h=$(printf "%s" "$1" | cut -d . -f $i-100) + if [ -n "$h" ]; then + if _contains "$h" "\\."; then + _debug h "$h" + if _namecheap_set_tld_sld "$h"; then + _sub_domain=$(printf "%s" "$1" | cut -d . -f 1-$p) + _domain="$h" + return 0 + else + _debug "$h not found" + fi + fi + fi + i="$p" + p=$(_math "$p" - 1) + done + return 1 +} + _namecheap_set_publicip() { if [ -z "$NAMECHEAP_SOURCEIP" ]; then From af5f7a77796ff03e82bf554675816962d523fe28 Mon Sep 17 00:00:00 2001 From: tianji Date: Thu, 28 Feb 2019 23:43:58 +0800 Subject: [PATCH 0175/2234] fix deploy/qiniu.sh base64 According to the doc (https://developer.qiniu.com/kodo/manual/1231/appendix#1), we should use URL-safe base64 instead of plain base64 for token calculation. --- deploy/qiniu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index 158b8dbf..e46e6fb3 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -87,6 +87,6 @@ qiniu_deploy() { } _make_access_token() { - _token="$(printf "%s\n" "$1" | _hmac "sha1" "$(printf "%s" "$QINIU_SK" | _hex_dump | tr -d " ")" | _base64)" + _token="$(printf "%s\n" "$1" | _hmac "sha1" "$(printf "%s" "$QINIU_SK" | _hex_dump | tr -d " ")" | _base64 | tr -- '+/' '-_')" echo "$QINIU_AK:$_token" } From 22e7b4c91184201225a8dbe52d5cb20efb90e860 Mon Sep 17 00:00:00 2001 From: tianji Date: Thu, 28 Feb 2019 23:51:43 +0800 Subject: [PATCH 0176/2234] fix doc of qiniu deploy script A leading dot should be included when updating wildcard domains. --- deploy/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index f290756a..44d53225 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -349,10 +349,10 @@ $ export QINIU_SK="bar" $ acme.sh --deploy -d example.com --deploy-hook qiniu ``` -假如您部署的证书为泛域名证书,您还需要设置 `QINIU_CDN_DOMAIN` 变量,指定实际需要部署的域名: +假如您部署的证书为泛域名证书,您还需要设置 `QINIU_CDN_DOMAIN` 变量,指定实际需要部署的域名(请注意泛域名前的点): ```sh -$ export QINIU_CDN_DOMAIN="cdn.example.com" +$ export QINIU_CDN_DOMAIN=".cdn.example.com" $ acme.sh --deploy -d example.com --deploy-hook qiniu ``` @@ -375,10 +375,10 @@ $ acme.sh --deploy -d example.com --deploy-hook qiniu (Optional), If you are using wildcard certificate, you may need export `QINIU_CDN_DOMAIN` to specify which domain -you want to update: +you want to update (please note the leading dot): ```sh -$ export QINIU_CDN_DOMAIN="cdn.example.com" +$ export QINIU_CDN_DOMAIN=".cdn.example.com" $ acme.sh --deploy -d example.com --deploy-hook qiniu ``` From b3f6129718bf0e7b7f352344b7149c725cf1576b Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 2 Mar 2019 20:44:08 +0800 Subject: [PATCH 0177/2234] fix https://github.com/Neilpang/acme.sh/issues/2122 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 8ee22479..005b1333 100755 --- a/acme.sh +++ b/acme.sh @@ -4886,7 +4886,7 @@ _installcert() { export CERT_KEY_PATH export CA_CERT_PATH export CERT_FULLCHAIN_PATH - export Le_Domain + export Le_Domain="$_main_domain" cd "$DOMAIN_PATH" && eval "$_reload_cmd" ); then _info "$(__green "Reload success")" From 86fbb5952e2fad1065836f89502ca34aad7f78a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20H=C3=A5land?= Date: Sat, 2 Mar 2019 16:39:41 +0100 Subject: [PATCH 0178/2234] Use env sh --- deploy/routeros.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index d590bc9a..d0d15c5c 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh #Here is a script to deploy cert to routeros router. From 7690f73e815a0b3af86fdf2901cc27519a1b0b33 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 5 Mar 2019 21:05:10 +0800 Subject: [PATCH 0179/2234] base64 encode reloadcmd. fix https://github.com/Neilpang/acme.sh/issues/2134 --- acme.sh | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/acme.sh b/acme.sh index 005b1333..6c42d7ee 100755 --- a/acme.sh +++ b/acme.sh @@ -66,6 +66,9 @@ END_CERT="-----END CERTIFICATE-----" CONTENT_TYPE_JSON="application/jose+json" RENEW_SKIP=2 +B64CONF_START="__ACME_BASE64__START_" +B64CONF_END="__ACME_BASE64__END_" + ECC_SEP="_" ECC_SUFFIX="${ECC_SEP}ecc" @@ -1964,12 +1967,16 @@ _setopt() { _debug3 "$(grep -n "^$__opt$__sep" "$__conf")" } -#_save_conf file key value +#_save_conf file key value base64encode #save to conf _save_conf() { _s_c_f="$1" _sdkey="$2" _sdvalue="$3" + _b64encode="$4" + if [ "$_b64encode" ]; then + _sdvalue="${B64CONF_START}$(printf "%s" "${_sdvalue}" | _base64)${B64CONF_END}" + fi if [ "$_s_c_f" ]; then _setopt "$_s_c_f" "$_sdkey" "=" "'$_sdvalue'" else @@ -1994,19 +2001,20 @@ _read_conf() { _r_c_f="$1" _sdkey="$2" if [ -f "$_r_c_f" ]; then - ( - eval "$(grep "^$_sdkey *=" "$_r_c_f")" - eval "printf \"%s\" \"\$$_sdkey\"" - ) + _sdv="$(grep "^$_sdkey *=" "$_r_c_f" | cut -d = -f 2-1000 | tr -d "'")" + if _startswith "$_sdv" "${B64CONF_START}" && _endswith "$_sdv" "${B64CONF_END}"; then + _sdv="$(echo "$_sdv" | sed "s/${B64CONF_START}//" | sed "s/${B64CONF_END}//" | _dbase64)" + fi + printf "%s" "$_sdv" else _debug "config file is empty, can not read $_sdkey" fi } -#_savedomainconf key value +#_savedomainconf key value base64encode #save to domain.conf _savedomainconf() { - _save_conf "$DOMAIN_CONF" "$1" "$2" + _save_conf "$DOMAIN_CONF" "$@" } #_cleardomainconf key @@ -2019,14 +2027,14 @@ _readdomainconf() { _read_conf "$DOMAIN_CONF" "$1" } -#_saveaccountconf key value +#_saveaccountconf key value base64encode _saveaccountconf() { - _save_conf "$ACCOUNT_CONF_PATH" "$1" "$2" + _save_conf "$ACCOUNT_CONF_PATH" "$@" } -#key value +#key value base64encode _saveaccountconf_mutable() { - _save_conf "$ACCOUNT_CONF_PATH" "SAVED_$1" "$2" + _save_conf "$ACCOUNT_CONF_PATH" "SAVED_$1" "$2" "$3" #remove later _clearaccountconf "$1" } @@ -4455,7 +4463,7 @@ $_authorizations_map" _savedomainconf "Le_RealCertPath" "$_real_cert" _savedomainconf "Le_RealCACertPath" "$_real_ca" _savedomainconf "Le_RealKeyPath" "$_real_key" - _savedomainconf "Le_ReloadCmd" "$_reload_cmd" + _savedomainconf "Le_ReloadCmd" "$_reload_cmd" "base64" _savedomainconf "Le_RealFullChainPath" "$_real_fullchain" if ! _installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"; then return 1 @@ -4522,6 +4530,7 @@ renew() { fi IS_RENEW="1" + Le_ReloadCmd="$(_readdomainconf Le_ReloadCmd)" 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" res="$?" if [ "$res" != "0" ]; then @@ -4802,7 +4811,7 @@ installcert() { _savedomainconf "Le_RealCertPath" "$_real_cert" _savedomainconf "Le_RealCACertPath" "$_real_ca" _savedomainconf "Le_RealKeyPath" "$_real_key" - _savedomainconf "Le_ReloadCmd" "$_reload_cmd" + _savedomainconf "Le_ReloadCmd" "$_reload_cmd" "base64" _savedomainconf "Le_RealFullChainPath" "$_real_fullchain" _installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd" From dfca8c09e046ee157516b6f05dadf4d5240ba2fa Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 5 Mar 2019 21:22:03 +0800 Subject: [PATCH 0180/2234] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 6c42d7ee..c63f2945 100755 --- a/acme.sh +++ b/acme.sh @@ -2001,7 +2001,7 @@ _read_conf() { _r_c_f="$1" _sdkey="$2" if [ -f "$_r_c_f" ]; then - _sdv="$(grep "^$_sdkey *=" "$_r_c_f" | cut -d = -f 2-1000 | tr -d "'")" + _sdv="$(grep "^$_sdkey *=" "$_r_c_f" | cut -d = -f 2-1000 | tr -d "'")" if _startswith "$_sdv" "${B64CONF_START}" && _endswith "$_sdv" "${B64CONF_END}"; then _sdv="$(echo "$_sdv" | sed "s/${B64CONF_START}//" | sed "s/${B64CONF_END}//" | _dbase64)" fi From c7257bcf464d09096b9543e42fef12094fcdf18b Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 5 Mar 2019 21:44:34 +0800 Subject: [PATCH 0181/2234] base64 hooks, fix https://github.com/Neilpang/acme.sh/issues/1969 --- acme.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index c63f2945..408f09cd 100755 --- a/acme.sh +++ b/acme.sh @@ -3650,9 +3650,9 @@ issue() { _savedomainconf "Le_Alt" "$_alt_domains" _savedomainconf "Le_Webroot" "$_web_roots" - _savedomainconf "Le_PreHook" "$_pre_hook" - _savedomainconf "Le_PostHook" "$_post_hook" - _savedomainconf "Le_RenewHook" "$_renew_hook" + _savedomainconf "Le_PreHook" "$_pre_hook" "base64" + _savedomainconf "Le_PostHook" "$_post_hook" "base64" + _savedomainconf "Le_RenewHook" "$_renew_hook" "base64" if [ "$_local_addr" ]; then _savedomainconf "Le_LocalAddress" "$_local_addr" @@ -4531,6 +4531,9 @@ renew() { IS_RENEW="1" Le_ReloadCmd="$(_readdomainconf Le_ReloadCmd)" + Le_PreHook="$(_readdomainconf Le_PreHook)" + Le_PostHook="$(_readdomainconf Le_PostHook)" + Le_RenewHook="$(_readdomainconf Le_RenewHook)" 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" res="$?" if [ "$res" != "0" ]; then From a3d8b9935ab7eb6656d63f95c69ae0423c747cfa Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 8 Mar 2019 14:31:11 +0800 Subject: [PATCH 0182/2234] fix https://github.com/Neilpang/acme.sh/issues/2141 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 408f09cd..d81812fe 100755 --- a/acme.sh +++ b/acme.sh @@ -4250,7 +4250,7 @@ $_authorizations_map" _link_cert_retry=0 _MAX_CERT_RETRY=5 - while [ -z "$Le_LinkCert" ] && [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do + while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do if _contains "$response" "\"status\":\"valid\""; then _debug "Order status is valid." Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" From 110a41d18def8f8305952600c07240e72aba7a67 Mon Sep 17 00:00:00 2001 From: 5ll <5ll@users.noreply.github.com> Date: Fri, 8 Mar 2019 10:33:09 +0100 Subject: [PATCH 0183/2234] initial commit DNS API for acme.sh for Core-Networks (https://beta.api.core-networks.de/doc/) --- dnsapi/dns_cn.sh | 158 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 dnsapi/dns_cn.sh diff --git a/dnsapi/dns_cn.sh b/dnsapi/dns_cn.sh new file mode 100644 index 00000000..b35f81cb --- /dev/null +++ b/dnsapi/dns_cn.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env sh + +# DNS API for acme.sh for Core-Networks (https://beta.api.core-networks.de/doc/). +# created by 5ll and francis + +CN_API="https://beta.api.core-networks.de" + +######## Public functions ##################### + +dns_cn_add(){ + fulldomain=$1 + txtvalue=$2 + + if ! _cn_login; then + _err "login failed" + return 1 + fi + + _debug "First detect the root zone" + if ! _cn_get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug "_sub_domain $_sub_domain" + _debug "_domain $_domain" + + _info "Adding record" + curData="{\"name\":\"$_sub_domain\",\"ttl\":120,\"type\":\"TXT\",\"data\":\"$txtvalue\"}" + curResult="$(_post "${curData}" "${CN_API}/dnszones/${_domain}/records/")" + + _debug "curData $curData" + _debug "curResult $curResult" + + if _contains "$curResult" ""; then + _info "Added, OK" + + if ! _cn_commit; then + _err "commiting changes failed" + return 1 + fi + return 0 + + else + _err "Add txt record error." + _debug "curData is $curData" + _debug "curResult is $curResult" + _err "error adding text record, response was $curResult" + return 1 + fi +} + +dns_cn_rm(){ + fulldomain=$1 + txtvalue=$2 + + if ! _cn_login; then + _err "login failed" + return 1 + fi + + _debug "First detect the root zone" + if ! _cn_get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _info "Deleting record" + curData="{\"name\":\"$_sub_domain\",\"data\":\"$txtvalue\"}" + curResult="$(_post "${curData}" "${CN_API}/dnszones/${_domain}/records/delete")" + _debug curData is "$curData" + + _info "commiting changes" + if ! _cn_commit; then + _err "commiting changes failed" + return 1 + fi + + _info "Deletet txt record" + return 0 +} + + +################### Private functions below ################################## +_cn_login() { + CN_User="${CN_User:-$(_readaccountconf_mutable CN_User)}" + CN_Password="${CN_Password:-$(_readaccountconf_mutable CN_Password)}" + if [ -z "$CN_User" ] || [ -z "$CN_Password" ]; then + CN_User="" + CN_Password="" + _err "You must export variables: CN_User and CN_Password" + return 1 + fi + + #save the config variables to the account conf file. + _saveaccountconf_mutable CN_User "$CN_User" + _saveaccountconf_mutable CN_Password "$CN_Password" + + _info "Getting an AUTH-Token" + curData="{\"login\":\"${CN_User}\",\"password\":\"${CN_Password}\"}" + curResult="$(_post "${curData}" "${CN_API}/auth/token")" + _debug "Calling _CN_login: '${curData}' '${CN_API}/auth/token'" + + if _contains "${curResult}" '"token":"'; then + authToken=$(echo "${curResult}" | cut -d ":" -f2 | cut -d "," -f1 | sed 's/^.\(.*\).$/\1/') + export _H1="Authorization: Bearer $authToken" + _info "Successfully acquired AUTH-Token" + _debug "AUTH-Token: '${authToken}'" + _debug "_H1 '${_H1}'" + else + _err "Couldn't acquire an AUTH-Token" + return 1 + fi +} + +# Commit changes +_cn_commit(){ + _info "Commiting changes" + _post "" "${CN_API}/dnszones/$h/records/commit" +} + +_cn_get_root(){ + domain=$1 + i=2 + p=1 + while true; do + + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + _debug _H1 "${_H1}" + + if [ -z "$h" ]; then + #not valid + return 1 + fi + + _cn_zonelist="$(_get ${CN_API}/dnszones/)" + _debug _cn_zonelist "${_cn_zonelist}" + + if [ "$?" != "0" ]; then + _err "something went wrong while getting the zone list" + return 1 + fi + + if _contains "$_cn_zonelist" "\"name\":\"$h\"" >/dev/null; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + else + _debug "Zonelist does not contain domain - iterating " + fi + p=$i + i=$(_math "$i" + 1) + + done + _err "Zonelist does not contain domain - exiting" + return 1 +} From 1d5967d143ddedddb8831be9e09583c406fd7c16 Mon Sep 17 00:00:00 2001 From: 5ll <5ll@users.noreply.github.com> Date: Fri, 8 Mar 2019 10:45:36 +0100 Subject: [PATCH 0184/2234] Updated README with Core-Networks support --- dnsapi/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dnsapi/README.md b/dnsapi/README.md index 9f176c0d..23620c4a 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1300,3 +1300,22 @@ See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide # Use lexicon DNS API https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api + + +## Use Core-Networks API to automatically issue cert + +First you need to login to your Core-Networks account to to set up an API-User. +Then export username and password to use these credentials. + +``` +export CN_User="user" +export CN_Password="passowrd" +``` + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_cn -d example.com -d www.example.com +``` + +The `CN_User` and `CN_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + From 3d5c75420a517eb199dcd4fb572856e77f1cc549 Mon Sep 17 00:00:00 2001 From: 5ll <5ll@users.noreply.github.com> Date: Fri, 8 Mar 2019 10:46:35 +0100 Subject: [PATCH 0185/2234] Changed Order --- dnsapi/README.md | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 23620c4a..33d724c7 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1279,6 +1279,26 @@ acme.sh --issue --dns dns_mydevil -d example.com -d *.example.com After certificate is ready, you can install it with [deploy command](../deploy/README.md#14-deploy-your-cert-on-mydevilnet). +## 67. Use Core-Networks API to automatically issue cert + +First you need to login to your Core-Networks account to to set up an API-User. +Then export username and password to use these credentials. + +``` +export CN_User="user" +export CN_Password="passowrd" +``` + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_cn -d example.com -d www.example.com +``` + +The `CN_User` and `CN_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + + + + # Use custom API If your API is not supported yet, you can write your own DNS API. @@ -1302,20 +1322,3 @@ See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api -## Use Core-Networks API to automatically issue cert - -First you need to login to your Core-Networks account to to set up an API-User. -Then export username and password to use these credentials. - -``` -export CN_User="user" -export CN_Password="passowrd" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_cn -d example.com -d www.example.com -``` - -The `CN_User` and `CN_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - From 30d0ac0784311d0f55c1737bb035242f58349c0e Mon Sep 17 00:00:00 2001 From: 5ll <5ll@users.noreply.github.com> Date: Fri, 8 Mar 2019 10:48:06 +0100 Subject: [PATCH 0186/2234] Updated README with Core-Networks support --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f68eb002..d0d526d0 100644 --- a/README.md +++ b/README.md @@ -358,7 +358,7 @@ You don't have to do anything manually! 1. Rackspace Cloud DNS (https://www.rackspace.com) 1. Online.net API (https://online.net/) 1. MyDevil.net (https://www.mydevil.net/) - +1. Core-Networks.de (https://core-networks.de) And: **lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api From f5850d0c08bb72c1453043482ac5dd365df1e66b Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 8 Mar 2019 22:20:56 +0800 Subject: [PATCH 0187/2234] fix format --- dnsapi/dns_cn.sh | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_cn.sh b/dnsapi/dns_cn.sh index b35f81cb..e90d7e60 100644 --- a/dnsapi/dns_cn.sh +++ b/dnsapi/dns_cn.sh @@ -7,7 +7,7 @@ CN_API="https://beta.api.core-networks.de" ######## Public functions ##################### -dns_cn_add(){ +dns_cn_add() { fulldomain=$1 txtvalue=$2 @@ -21,17 +21,17 @@ dns_cn_add(){ _err "invalid domain" return 1 fi - + _debug "_sub_domain $_sub_domain" _debug "_domain $_domain" - + _info "Adding record" curData="{\"name\":\"$_sub_domain\",\"ttl\":120,\"type\":\"TXT\",\"data\":\"$txtvalue\"}" curResult="$(_post "${curData}" "${CN_API}/dnszones/${_domain}/records/")" _debug "curData $curData" _debug "curResult $curResult" - + if _contains "$curResult" ""; then _info "Added, OK" @@ -40,7 +40,7 @@ dns_cn_add(){ return 1 fi return 0 - + else _err "Add txt record error." _debug "curData is $curData" @@ -50,7 +50,7 @@ dns_cn_add(){ fi } -dns_cn_rm(){ +dns_cn_rm() { fulldomain=$1 txtvalue=$2 @@ -64,14 +64,14 @@ dns_cn_rm(){ _err "invalid domain" return 1 fi - + _info "Deleting record" curData="{\"name\":\"$_sub_domain\",\"data\":\"$txtvalue\"}" curResult="$(_post "${curData}" "${CN_API}/dnszones/${_domain}/records/delete")" _debug curData is "$curData" _info "commiting changes" - if ! _cn_commit; then + if ! _cn_commit; then _err "commiting changes failed" return 1 fi @@ -80,7 +80,6 @@ dns_cn_rm(){ return 0 } - ################### Private functions below ################################## _cn_login() { CN_User="${CN_User:-$(_readaccountconf_mutable CN_User)}" @@ -100,7 +99,7 @@ _cn_login() { curData="{\"login\":\"${CN_User}\",\"password\":\"${CN_Password}\"}" curResult="$(_post "${curData}" "${CN_API}/auth/token")" _debug "Calling _CN_login: '${curData}' '${CN_API}/auth/token'" - + if _contains "${curResult}" '"token":"'; then authToken=$(echo "${curResult}" | cut -d ":" -f2 | cut -d "," -f1 | sed 's/^.\(.*\).$/\1/') export _H1="Authorization: Bearer $authToken" @@ -114,12 +113,12 @@ _cn_login() { } # Commit changes -_cn_commit(){ +_cn_commit() { _info "Commiting changes" _post "" "${CN_API}/dnszones/$h/records/commit" } -_cn_get_root(){ +_cn_get_root() { domain=$1 i=2 p=1 From 04eaf7f1751149ae0af7c29728996004cf6e1de2 Mon Sep 17 00:00:00 2001 From: Sylvia van Os Date: Fri, 22 Feb 2019 15:10:39 +0100 Subject: [PATCH 0188/2234] Add OpenProvider support --- README.md | 1 + dnsapi/README.md | 17 +++ dnsapi/dns_openprovider.sh | 244 +++++++++++++++++++++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100755 dnsapi/dns_openprovider.sh diff --git a/README.md b/README.md index f79b8602..e7ad4cfb 100644 --- a/README.md +++ b/README.md @@ -357,6 +357,7 @@ You don't have to do anything manually! 1. Rackspace Cloud DNS (https://www.rackspace.com) 1. Online.net API (https://online.net/) 1. MyDevil.net (https://www.mydevil.net/) +1. OpenProvider API (https://www.openprovider.com/) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index 9f176c0d..3cbfe19a 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1279,6 +1279,23 @@ acme.sh --issue --dns dns_mydevil -d example.com -d *.example.com After certificate is ready, you can install it with [deploy command](../deploy/README.md#14-deploy-your-cert-on-mydevilnet). +## 67. Use OpenProvider API + +First, you need to enable API access and retrieve your password hash on https://rcp.openprovider.eu/account/dashboard.php + +``` +export OPENPROVIDER_USER='username' +export OPENPROVIDER_PASSWORDHASH='xxx' +``` + +To issue a cert run: + +``` +acme.sh --issue --dns dns_openprovider -d example.com -d www.example.com +``` + +`OPENPROVIDER_USER` and `OPENPROVIDER_PASSWORDHASH` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh new file mode 100755 index 00000000..3d66dfe4 --- /dev/null +++ b/dnsapi/dns_openprovider.sh @@ -0,0 +1,244 @@ +#!/usr/bin/env sh + +# This is the OpenProvider API wrapper for acme.sh +# +# Author: Sylvia van Os +# Report Bugs here: https://github.com/Neilpang/acme.sh/issues/2104 +# +# export OPENPROVIDER_USER="username" +# export OPENPROVIDER_PASSWORDHASH="hashed_password" +# +# Usage: +# acme.sh --issue --dns dns_openprovider -d example.com + +OPENPROVIDER_API="https://api.openprovider.eu/" +#OPENPROVIDER_API="https://api.cte.openprovider.eu/" # Test API + +######## Public functions ##################### + +#Usage: dns_openprovider_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_openprovider_add() { + fulldomain="$1" + txtvalue="$2" + + OPENPROVIDER_USER="${OPENPROVIDER_USER:-$(_readaccountconf_mutable OPENPROVIDER_USER)}" + OPENPROVIDER_PASSWORDHASH="${OPENPROVIDER_PASSWORDHASH:-$(_readaccountconf_mutable OPENPROVIDER_PASSWORDHASH)}" + + if [ -z "$OPENPROVIDER_USER" ] || [ -z "$OPENPROVIDER_PASSWORDHASH" ]; then + _err "You didn't specify the openprovider user and/or password hash." + return 1 + fi + + # save the username and password to the account conf file. + _saveaccountconf_mutable OPENPROVIDER_USER "$OPENPROVIDER_USER" + _saveaccountconf_mutable OPENPROVIDER_PASSWORDHASH "$OPENPROVIDER_PASSWORDHASH" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _domain_name "$_domain_name" + _debug _domain_extension "$_domain_extension" + + _debug "Getting current records" + existing_items="" + results_retrieved=0 + while true; do + _openprovider_request "$(printf '%s.%s%s' "$_domain_name" "$_domain_extension" "$results_retrieved")" + + items="$response" + while true; do + item="$(printf '%s' "$items" | _egrep_o '.*<\/openXML>' | sed -n -E 's/.*(.*<\/item>).*/\1/p')" + _debug existing_items "$existing_items" + _debug results_retrieved "$results_retrieved" + _debug item "$item" + + if [ -z "$item" ]; then + break + fi + + items="$(printf '%s' "$items" | sed "s$item")" + + results_retrieved=$((results_retrieved + 1)) + new_item="$(printf '%s' "$item" | sed -n -E "s/.*.*((.*)\.$_domain_name\.$_domain_extension<\/name>.*(.*<\/type>).*(.*<\/value>).*(.*<\/prio>).*(.*<\/ttl>)).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p")" + if [ -z "$new_item" ]; then + # Base record + new_item="$(printf '%s' "$item" | sed -n -E "s/.*.*((.*)$_domain_name\.$_domain_extension<\/name>.*(.*<\/type>).*(.*<\/value>).*(.*<\/prio>).*(.*<\/ttl>)).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p")" + fi + + if [ -z "$(printf '%s' "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then + _debug "not an allowed record type, skipping" "$new_item" + continue + fi + + existing_items="$(printf '%s%s' "$existing_items" "$new_item")" + done + + total="$(printf '%s' "$response" | _egrep_o '.*?<\/total>' | sed -n -E 's/.*(.*)<\/total>.*/\1/p')" + + _debug total "$total" + if [ "$results_retrieved" -eq "$total" ]; then + break + fi + done + + _debug "Creating acme record" + acme_record="$(printf '%s' "$fulldomain" | sed -e "s/.$_domain_name.$_domain_extension$//")" + _openprovider_request "$(printf '%s%smaster%s%sTXT%s86400' "$_domain_name" "$_domain_extension" "$existing_items" "$acme_record" "$txtvalue")" + + return 0 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_openprovider_rm() { + fulldomain="$1" + txtvalue="$2" + + OPENPROVIDER_USER="${OPENPROVIDER_USER:-$(_readaccountconf_mutable OPENPROVIDER_USER)}" + OPENPROVIDER_PASSWORDHASH="${OPENPROVIDER_PASSWORDHASH:-$(_readaccountconf_mutable OPENPROVIDER_PASSWORDHASH)}" + + if [ -z "$OPENPROVIDER_USER" ] || [ -z "$OPENPROVIDER_PASSWORDHASH" ]; then + _err "You didn't specify the openprovider user and/or password hash." + return 1 + fi + + # save the username and password to the account conf file. + _saveaccountconf_mutable OPENPROVIDER_USER "$OPENPROVIDER_USER" + _saveaccountconf_mutable OPENPROVIDER_PASSWORDHASH "$OPENPROVIDER_PASSWORDHASH" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _domain_name "$_domain_name" + _debug _domain_extension "$_domain_extension" + + _debug "Getting current records" + existing_items="" + results_retrieved=0 + while true; do + _openprovider_request "$(printf '%s.%s%s' "$_domain_name" "$_domain_extension" "$results_retrieved")" + + # Remove acme records from items + items="$response" + while true; do + item="$(printf '%s' "$items" | _egrep_o '.*<\/openXML>' | sed -n -E 's/.*(.*<\/item>).*/\1/p')" + _debug existing_items "$existing_items" + _debug results_retrieved "$results_retrieved" + _debug item "$item" + + if [ -z "$item" ]; then + break + fi + + items="$(printf '%s' "$items" | sed "s$item")" + + results_retrieved=$((results_retrieved + 1)) + if ! printf '%s' "$item" | grep -v "$fulldomain"; then + _debug "acme record, skipping" "$item" + continue + fi + + new_item="$(printf '%s' "$item" | sed -n -E "s/.*.*((.*)\.$_domain_name\.$_domain_extension<\/name>.*(.*<\/type>).*(.*<\/value>).*(.*<\/prio>).*(.*<\/ttl>)).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p")" + + if [ -z "$new_item" ]; then + # Base record + new_item="$(printf '%s' "$item" | sed -n -E "s/.*.*((.*)$_domain_name\.$_domain_extension<\/name>.*(.*<\/type>).*(.*<\/value>).*(.*<\/prio>).*(.*<\/ttl>)).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p")" + fi + + if [ -z "$(printf '%s' "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then + _debug "not an allowed record type, skipping" "$new_item" + continue + fi + + existing_items="$(printf '%s%s' "$existing_items" "$new_item")" + done + + total="$(printf '%s' "$response" | _egrep_o '.*?<\/total>' | sed -n -E 's/.*(.*)<\/total>.*/\1/p')" + + _debug total "$total" + + if [ "$results_retrieved" -eq "$total" ]; then + break + fi + done + + _debug "Removing acme record" + _openprovider_request "$(printf '%s%smaster%s' "$_domain_name" "$_domain_extension" "$existing_items")" + + return 0 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _domain_name=domain +# _domain_extension=com +_get_root() { + domain=$1 + i=2 + + results_retrieved=0 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + _openprovider_request "$(printf '%s%s' "$(printf "%s" "$h" | cut -d . -f 1)" "$results_retrieved")" + + items="$response" + while true; do + item="$(printf '%s' "$items" | _egrep_o '.*<\/openXML>' | sed -n -E 's/.*(.*<\/domain>).*/\1/p')" + _debug existing_items "$existing_items" + _debug results_retrieved "$results_retrieved" + _debug item "$item" + + if [ -z "$item" ]; then + break + fi + + items="$(printf '%s' "$items" | sed "s$item")" + + results_retrieved=$((results_retrieved + 1)) + + _domain_name="$(printf "%s" "$item" | sed -n -E 's/.*.*(.*)<\/name>.*<\/domain>.*/\1/p')" + _domain_extension="$(printf "%s" "$item" | sed -n -E 's/.*.*(.*)<\/extension>.*<\/domain>.*/\1/p')" + _debug _domain_name "$_domain_name" + _debug _domain_extension "$_domain_extension" + if [ "$(printf "%s.%s" "$_domain_name" "$_domain_extension")" = "$h" ]; then + return 0 + fi + done + + total="$(printf '%s' "$response" | _egrep_o '.*?<\/total>' | sed -n -E 's/.*(.*)<\/total>.*/\1/p')" + + _debug total "$total" + + if [ "$results_retrieved" -eq "$total" ]; then + results_retrieved=0 + i=$(_math "$i" + 1) + fi + done + return 1 +} + +_openprovider_request() { + request_xml=$1 + + xml_prefix=$(printf '') + xml_content=$(printf '%s%s%s' "$OPENPROVIDER_USER" "$OPENPROVIDER_PASSWORDHASH" "$request_xml") + response="$(_post "$(printf "%s%s" "$xml_prefix" "$xml_content" | tr -d '\n')" "$OPENPROVIDER_API" "" "POST" "application/xml")" + _debug response "$response" + if ! _contains "$response" "0.*"; then + _err "API request failed." + return 1 + fi +} From 725addafda8c3ffbad2b0feb2ff03b4ff518abb9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 9 Mar 2019 09:13:49 +0800 Subject: [PATCH 0189/2234] fix format --- dnsapi/dns_cn.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cn.sh b/dnsapi/dns_cn.sh index e90d7e60..38d1f4aa 100644 --- a/dnsapi/dns_cn.sh +++ b/dnsapi/dns_cn.sh @@ -69,7 +69,7 @@ dns_cn_rm() { curData="{\"name\":\"$_sub_domain\",\"data\":\"$txtvalue\"}" curResult="$(_post "${curData}" "${CN_API}/dnszones/${_domain}/records/delete")" _debug curData is "$curData" - + _info "commiting changes" if ! _cn_commit; then _err "commiting changes failed" @@ -132,7 +132,7 @@ _cn_get_root() { #not valid return 1 fi - + _cn_zonelist="$(_get ${CN_API}/dnszones/)" _debug _cn_zonelist "${_cn_zonelist}" From 53c018824862934939ac91c8e06c558c15d469a4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 11 Mar 2019 21:30:24 +0800 Subject: [PATCH 0190/2234] fix https://github.com/Neilpang/acme.sh/issues/2150 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d81812fe..a31cf085 100755 --- a/acme.sh +++ b/acme.sh @@ -1974,7 +1974,7 @@ _save_conf() { _sdkey="$2" _sdvalue="$3" _b64encode="$4" - if [ "$_b64encode" ]; then + if [ "$_sdvalue" ] && [ "$_b64encode" ]; then _sdvalue="${B64CONF_START}$(printf "%s" "${_sdvalue}" | _base64)${B64CONF_END}" fi if [ "$_s_c_f" ]; then From f2add8de94e0ad9646f86dba3ea8666c9e39b348 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 12 Mar 2019 21:16:15 +0800 Subject: [PATCH 0191/2234] use acme v2 as default --- acme.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index a31cf085..b3ccf9ee 100755 --- a/acme.sh +++ b/acme.sh @@ -19,8 +19,8 @@ LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory" LETSENCRYPT_CA_V2="https://acme-v02.api.letsencrypt.org/directory" LETSENCRYPT_STAGING_CA_V2="https://acme-staging-v02.api.letsencrypt.org/directory" -DEFAULT_CA=$LETSENCRYPT_CA_V1 -DEFAULT_STAGING_CA=$LETSENCRYPT_STAGING_CA_V1 +DEFAULT_CA=$LETSENCRYPT_CA_V2 +DEFAULT_STAGING_CA=$LETSENCRYPT_STAGING_CA_V2 DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" DEFAULT_ACCOUNT_EMAIL="" @@ -3665,8 +3665,12 @@ issue() { _cleardomainconf "Le_ChallengeAlias" fi - Le_API="$ACME_DIRECTORY" - _savedomainconf "Le_API" "$Le_API" + if [ "$ACME_DIRECTORY" != "$DEFAULT_CA" ]; then + Le_API="$ACME_DIRECTORY" + _savedomainconf "Le_API" "$Le_API" + else + _cleardomainconf Le_API + fi if [ "$_alt_domains" = "$NO_VALUE" ]; then _alt_domains="" @@ -4500,6 +4504,16 @@ renew() { . "$DOMAIN_CONF" _debug Le_API "$Le_API" + + if [ "$Le_API" = "$LETSENCRYPT_CA_V1" ]; then + _cleardomainconf Le_API + Le_API="$DEFAULT_CA" + fi + if [ "$Le_API" = "$LETSENCRYPT_STAGING_CA_V1" ]; then + _cleardomainconf Le_API + Le_API="$DEFAULT_STAGING_CA" + fi + if [ "$Le_API" ]; then if [ "$_OLD_CA_HOST" = "$Le_API" ]; then export Le_API="$DEFAULT_CA" From db6db6a4e964befb0575030f1703d4e0a37db36a Mon Sep 17 00:00:00 2001 From: Sebastiaan Hoogeveen Date: Tue, 12 Mar 2019 14:36:42 +0100 Subject: [PATCH 0192/2234] Removed overwriting of the HTTP header file before sending a request. --- dnsapi/dns_nederhost.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_nederhost.sh b/dnsapi/dns_nederhost.sh index 84c5ecd1..0954ab65 100755 --- a/dnsapi/dns_nederhost.sh +++ b/dnsapi/dns_nederhost.sh @@ -112,8 +112,6 @@ _nederhost_rest() { export _H1="Authorization: Bearer $NederHost_Key" export _H2="Content-Type: application/json" - :>"$HTTP_HEADER" - if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$NederHost_Api/$ep" "" "$m")" From 77f96b386e9d60380a1dcfc80577c126eadba49c Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 13 Mar 2019 20:42:02 +0800 Subject: [PATCH 0193/2234] support Windows scheduler. fix https://github.com/Neilpang/acme.sh/issues/2145 --- acme.sh | 130 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 20 deletions(-) diff --git a/acme.sh b/acme.sh index b3ccf9ee..ceacd574 100755 --- a/acme.sh +++ b/acme.sh @@ -9,6 +9,9 @@ PROJECT_ENTRY="acme.sh" PROJECT="https://github.com/Neilpang/$PROJECT_NAME" DEFAULT_INSTALL_HOME="$HOME/.$PROJECT_NAME" + +_WINDOWS_SCHEDULER_NAME="$PROJECT_NAME.cron" + _SCRIPT_="$0" _SUB_FOLDERS="dnsapi deploy" @@ -4923,35 +4926,108 @@ _installcert() { } +__read_password() { + unset _pp + prompt="Enter Password:" + while IFS= read -p "$prompt" -r -s -n 1 char + do + if [ "$char" = $'\0' ]; then + break + fi + prompt='*' + _pp="$_pp$char" + done + echo "$_pp" +} + +_install_win_taskscheduler() { + _lesh="$1" + _centry="$2" + _randomminute="$3" + if ! _exists cygpath; then + _err "cygpath not found" + return 1 + fi + if ! _exists schtasks; then + _err "schtasks.exe is not found, are you on Windows?" + return 1 + fi + _winbash="$(cygpath -w $(which bash))" + _debug _winbash "$_winbash" + if [ -z "$_winbash" ]; then + _err "can not find bash path" + return 1 + fi + _myname="$(whoami)" + _debug "_myname" "$_myname" + if [ -z "$_myname" ]; then + _err "can not find my user name" + return 1 + fi + _debug "_lesh" "$_lesh" + + _info "To install scheduler task in your Windows account, you must input your windows password." + _info "$PROJECT_NAME doesn't save your password." + _info "Please input your Windows password for: $(__green "$_myname")" + _password="$(__read_password)" + #SCHTASKS.exe '/create' '/SC' 'DAILY' '/TN' "$_WINDOWS_SCHEDULER_NAME" '/F' '/ST' "00:$_randomminute" '/RU' "$_myname" '/RP' "$_password" '/TR' "$_winbash -l -c '$_lesh --cron --home \"$LE_WORKING_DIR\" $_centry'" >/dev/null + echo SCHTASKS.exe '/create' '/SC' 'DAILY' '/TN' "$_WINDOWS_SCHEDULER_NAME" '/F' '/ST' "00:$_randomminute" '/RU' "$_myname" '/RP' "$_password" '/TR' "\"$_winbash -l -c '$_lesh --cron --home \"$LE_WORKING_DIR\" $_centry'\"" | cmd.exe >/dev/null + echo + +} + +_uninstall_win_taskscheduler() { + if ! _exists schtasks; then + _err "schtasks.exe is not found, are you on Windows?" + return 1 + fi + if ! echo SCHTASKS /query /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null; then + _debug "scheduler $_WINDOWS_SCHEDULER_NAME is not found." + else + _info "Removing $_WINDOWS_SCHEDULER_NAME" + echo SCHTASKS /delete /f /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null + fi +} + #confighome installcronjob() { _c_home="$1" _initpath _CRONTAB="crontab" + if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then + lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY" + else + _err "Can not install cronjob, $PROJECT_ENTRY not found." + return 1 + fi + if [ "$_c_home" ]; then + _c_entry="--config-home \"$_c_home\" " + fi + _t=$(_time) + random_minute=$(_math $_t % 60) + if ! _exists "$_CRONTAB" && _exists "fcrontab"; then _CRONTAB="fcrontab" fi + if ! _exists "$_CRONTAB"; then + if _exists cygpath && _exists schtasks.exe; then + _info "It seems you are on Windows, let's install Windows scheduler task." + if _install_win_taskscheduler "$lesh" "$_c_entry" "$random_minute"; then + _info "Install Windows scheduler task success." + return 0 + else + _err "Install Windows scheduler task failed." + return 1 + fi + fi _err "crontab/fcrontab doesn't exist, so, we can not install cron jobs." _err "All your certs will not be renewed automatically." _err "You must add your own cron job to call '$PROJECT_ENTRY --cron' everyday." return 1 fi - _info "Installing cron job" if ! $_CRONTAB -l | grep "$PROJECT_ENTRY --cron"; then - if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then - lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY" - else - _err "Can not install cronjob, $PROJECT_ENTRY not found." - return 1 - fi - - if [ "$_c_home" ]; then - _c_entry="--config-home \"$_c_home\" " - fi - _t=$(_time) - random_minute=$(_math $_t % 60) if _exists uname && uname -a | grep SunOS >/dev/null; then $_CRONTAB -l | { cat @@ -4979,6 +5055,16 @@ uninstallcronjob() { fi if ! _exists "$_CRONTAB"; then + if _exists cygpath && _exists schtasks.exe; then + _info "It seems you are on Windows, let's uninstall Windows scheduler task." + if _uninstall_win_taskscheduler; then + _info "Uninstall Windows scheduler task success." + return 0 + else + _err "Uninstall Windows scheduler task failed." + return 1 + fi + fi return fi _info "Removing cron job" @@ -5306,13 +5392,17 @@ _precheck() { if [ -z "$_nocron" ]; then if ! _exists "crontab" && ! _exists "fcrontab"; then - _err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'." - _err "We need to set cron job to renew the certs automatically." - _err "Otherwise, your certs will not be able to be renewed automatically." - if [ -z "$FORCE" ]; then - _err "Please add '--force' and try install again to go without crontab." - _err "./$PROJECT_ENTRY --install --force" - return 1 + if _exists cygpath && _exists schtasks.exe; then + _info "It seems you are on Windows, we will install Windows scheduler task." + else + _err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'." + _err "We need to set cron job to renew the certs automatically." + _err "Otherwise, your certs will not be able to be renewed automatically." + if [ -z "$FORCE" ]; then + _err "Please add '--force' and try install again to go without crontab." + _err "./$PROJECT_ENTRY --install --force" + return 1 + fi fi fi fi From 0b04a7f17f467db477fca6588d8d078e2ac017f0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 13 Mar 2019 20:49:26 +0800 Subject: [PATCH 0194/2234] fix format --- acme.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index ceacd574..127b6ab3 100755 --- a/acme.sh +++ b/acme.sh @@ -4929,13 +4929,12 @@ _installcert() { __read_password() { unset _pp prompt="Enter Password:" - while IFS= read -p "$prompt" -r -s -n 1 char - do - if [ "$char" = $'\0' ]; then - break - fi - prompt='*' - _pp="$_pp$char" + while IFS= read -p "$prompt" -r -s -n 1 char; do + if [ "$char" = $'\0' ]; then + break + fi + prompt='*' + _pp="$_pp$char" done echo "$_pp" } @@ -4985,7 +4984,7 @@ _uninstall_win_taskscheduler() { _debug "scheduler $_WINDOWS_SCHEDULER_NAME is not found." else _info "Removing $_WINDOWS_SCHEDULER_NAME" - echo SCHTASKS /delete /f /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null + echo SCHTASKS /delete /f /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null fi } From 4ebad10557d3f05de6b4bddb8c173a2030af4145 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 13 Mar 2019 21:11:59 +0800 Subject: [PATCH 0195/2234] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 127b6ab3..1887bc90 100755 --- a/acme.sh +++ b/acme.sh @@ -4931,7 +4931,7 @@ __read_password() { prompt="Enter Password:" while IFS= read -p "$prompt" -r -s -n 1 char; do if [ "$char" = $'\0' ]; then - break + break fi prompt='*' _pp="$_pp$char" From 532e79c7d0d8dcfcf514195c0d8b2873aa4717ee Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Wed, 13 Mar 2019 14:14:40 +0100 Subject: [PATCH 0196/2234] Fix reading endpoint --- dnsapi/dns_hostingde.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 50aa142f..1819e639 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -28,6 +28,7 @@ dns_hostingde_rm() { _hostingde_apiKey() { HOSTINGDE_APIKEY="${HOSTINGDE_APIKEY:-$(_readaccountconf_mutable HOSTINGDE_APIKEY)}" + HOSTINGDE_ENDPOINT="${HOSTINGDE_ENDPOINT:-$(_readaccountconf_mutable HOSTINGDE_ENDPOINT)}" if [ -z "$HOSTINGDE_APIKEY" ] || [ -z "$HOSTINGDE_ENDPOINT" ]; then HOSTINGDE_APIKEY="" HOSTINGDE_ENDPOINT="" From 0f00862e5efd76cf998fe2b7511432c4893a249f Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 13 Mar 2019 21:28:30 +0800 Subject: [PATCH 0197/2234] support windows scheduler (#2158) * support Windows scheduler. fix https://github.com/Neilpang/acme.sh/issues/2145 --- acme.sh | 129 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 109 insertions(+), 20 deletions(-) diff --git a/acme.sh b/acme.sh index b3ccf9ee..1887bc90 100755 --- a/acme.sh +++ b/acme.sh @@ -9,6 +9,9 @@ PROJECT_ENTRY="acme.sh" PROJECT="https://github.com/Neilpang/$PROJECT_NAME" DEFAULT_INSTALL_HOME="$HOME/.$PROJECT_NAME" + +_WINDOWS_SCHEDULER_NAME="$PROJECT_NAME.cron" + _SCRIPT_="$0" _SUB_FOLDERS="dnsapi deploy" @@ -4923,35 +4926,107 @@ _installcert() { } +__read_password() { + unset _pp + prompt="Enter Password:" + while IFS= read -p "$prompt" -r -s -n 1 char; do + if [ "$char" = $'\0' ]; then + break + fi + prompt='*' + _pp="$_pp$char" + done + echo "$_pp" +} + +_install_win_taskscheduler() { + _lesh="$1" + _centry="$2" + _randomminute="$3" + if ! _exists cygpath; then + _err "cygpath not found" + return 1 + fi + if ! _exists schtasks; then + _err "schtasks.exe is not found, are you on Windows?" + return 1 + fi + _winbash="$(cygpath -w $(which bash))" + _debug _winbash "$_winbash" + if [ -z "$_winbash" ]; then + _err "can not find bash path" + return 1 + fi + _myname="$(whoami)" + _debug "_myname" "$_myname" + if [ -z "$_myname" ]; then + _err "can not find my user name" + return 1 + fi + _debug "_lesh" "$_lesh" + + _info "To install scheduler task in your Windows account, you must input your windows password." + _info "$PROJECT_NAME doesn't save your password." + _info "Please input your Windows password for: $(__green "$_myname")" + _password="$(__read_password)" + #SCHTASKS.exe '/create' '/SC' 'DAILY' '/TN' "$_WINDOWS_SCHEDULER_NAME" '/F' '/ST' "00:$_randomminute" '/RU' "$_myname" '/RP' "$_password" '/TR' "$_winbash -l -c '$_lesh --cron --home \"$LE_WORKING_DIR\" $_centry'" >/dev/null + echo SCHTASKS.exe '/create' '/SC' 'DAILY' '/TN' "$_WINDOWS_SCHEDULER_NAME" '/F' '/ST' "00:$_randomminute" '/RU' "$_myname" '/RP' "$_password" '/TR' "\"$_winbash -l -c '$_lesh --cron --home \"$LE_WORKING_DIR\" $_centry'\"" | cmd.exe >/dev/null + echo + +} + +_uninstall_win_taskscheduler() { + if ! _exists schtasks; then + _err "schtasks.exe is not found, are you on Windows?" + return 1 + fi + if ! echo SCHTASKS /query /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null; then + _debug "scheduler $_WINDOWS_SCHEDULER_NAME is not found." + else + _info "Removing $_WINDOWS_SCHEDULER_NAME" + echo SCHTASKS /delete /f /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null + fi +} + #confighome installcronjob() { _c_home="$1" _initpath _CRONTAB="crontab" + if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then + lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY" + else + _err "Can not install cronjob, $PROJECT_ENTRY not found." + return 1 + fi + if [ "$_c_home" ]; then + _c_entry="--config-home \"$_c_home\" " + fi + _t=$(_time) + random_minute=$(_math $_t % 60) + if ! _exists "$_CRONTAB" && _exists "fcrontab"; then _CRONTAB="fcrontab" fi + if ! _exists "$_CRONTAB"; then + if _exists cygpath && _exists schtasks.exe; then + _info "It seems you are on Windows, let's install Windows scheduler task." + if _install_win_taskscheduler "$lesh" "$_c_entry" "$random_minute"; then + _info "Install Windows scheduler task success." + return 0 + else + _err "Install Windows scheduler task failed." + return 1 + fi + fi _err "crontab/fcrontab doesn't exist, so, we can not install cron jobs." _err "All your certs will not be renewed automatically." _err "You must add your own cron job to call '$PROJECT_ENTRY --cron' everyday." return 1 fi - _info "Installing cron job" if ! $_CRONTAB -l | grep "$PROJECT_ENTRY --cron"; then - if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then - lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY" - else - _err "Can not install cronjob, $PROJECT_ENTRY not found." - return 1 - fi - - if [ "$_c_home" ]; then - _c_entry="--config-home \"$_c_home\" " - fi - _t=$(_time) - random_minute=$(_math $_t % 60) if _exists uname && uname -a | grep SunOS >/dev/null; then $_CRONTAB -l | { cat @@ -4979,6 +5054,16 @@ uninstallcronjob() { fi if ! _exists "$_CRONTAB"; then + if _exists cygpath && _exists schtasks.exe; then + _info "It seems you are on Windows, let's uninstall Windows scheduler task." + if _uninstall_win_taskscheduler; then + _info "Uninstall Windows scheduler task success." + return 0 + else + _err "Uninstall Windows scheduler task failed." + return 1 + fi + fi return fi _info "Removing cron job" @@ -5306,13 +5391,17 @@ _precheck() { if [ -z "$_nocron" ]; then if ! _exists "crontab" && ! _exists "fcrontab"; then - _err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'." - _err "We need to set cron job to renew the certs automatically." - _err "Otherwise, your certs will not be able to be renewed automatically." - if [ -z "$FORCE" ]; then - _err "Please add '--force' and try install again to go without crontab." - _err "./$PROJECT_ENTRY --install --force" - return 1 + if _exists cygpath && _exists schtasks.exe; then + _info "It seems you are on Windows, we will install Windows scheduler task." + else + _err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'." + _err "We need to set cron job to renew the certs automatically." + _err "Otherwise, your certs will not be able to be renewed automatically." + if [ -z "$FORCE" ]; then + _err "Please add '--force' and try install again to go without crontab." + _err "./$PROJECT_ENTRY --install --force" + return 1 + fi fi fi fi From 709d82e7641916da2ad9e9035472e4f5f622dd0d Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 13 Mar 2019 21:32:10 +0800 Subject: [PATCH 0198/2234] sync sync --- dnsapi/dns_hostingde.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 50aa142f..1819e639 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -28,6 +28,7 @@ dns_hostingde_rm() { _hostingde_apiKey() { HOSTINGDE_APIKEY="${HOSTINGDE_APIKEY:-$(_readaccountconf_mutable HOSTINGDE_APIKEY)}" + HOSTINGDE_ENDPOINT="${HOSTINGDE_ENDPOINT:-$(_readaccountconf_mutable HOSTINGDE_ENDPOINT)}" if [ -z "$HOSTINGDE_APIKEY" ] || [ -z "$HOSTINGDE_ENDPOINT" ]; then HOSTINGDE_APIKEY="" HOSTINGDE_ENDPOINT="" From 5048c6c22a19ae31006c3d5fa6a15733045fd4f8 Mon Sep 17 00:00:00 2001 From: tambetliiv <35329231+tambetliiv@users.noreply.github.com> Date: Thu, 14 Mar 2019 14:20:39 +0200 Subject: [PATCH 0199/2234] Add zone.ee (zone.eu) DNS API (#2151) * add zone.ee (zone.eu) dns api --- README.md | 1 + dnsapi/README.md | 16 +++++ dnsapi/dns_zone.sh | 149 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100755 dnsapi/dns_zone.sh diff --git a/README.md b/README.md index fae0bbf5..50466ad7 100644 --- a/README.md +++ b/README.md @@ -360,6 +360,7 @@ You don't have to do anything manually! 1. MyDevil.net (https://www.mydevil.net/) 1. Core-Networks.de (https://core-networks.de) 1. NederHost API (https://www.nederhost.nl/) +1. Zone.ee (zone.eu) API (https://api.zone.eu/v2) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index 7ef1c306..de3148cf 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1310,6 +1310,22 @@ To issue a certificate run: acme.sh --issue --dns dns_nederhost -d example.com -d *.example.com ``` +## 69. Use Zone.ee DNS API + +First, you'll need to retrive your API key. Estonian insructions https://help.zone.eu/kb/zoneid-api-v2/ + +``` +export ZONE_Username=yourusername +export ZONE_Key=keygoeshere +``` + +To issue a cert run: + +``` +acme.sh --issue -d example.com -d www.example.com --dns dns_zone +``` + +`ZONE_Username` and `ZONE_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_zone.sh b/dnsapi/dns_zone.sh new file mode 100755 index 00000000..847e32cd --- /dev/null +++ b/dnsapi/dns_zone.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env sh + +# Zone.ee dns API +# https://help.zone.eu/kb/zoneid-api-v2/ +# required ZONE_Username and ZONE_Key + +ZONE_Api="https://api.zone.eu/v2" +######## Public functions ##################### + +#Usage: dns_zone_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_zone_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using zone.ee dns api" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + ZONE_Username="${ZONE_Username:-$(_readaccountconf_mutable ZONE_Username)}" + ZONE_Key="${ZONE_Key:-$(_readaccountconf_mutable ZONE_Key)}" + if [ -z "$ZONE_Username" ] || [ -z "$ZONE_Key" ]; then + ZONE_Username="" + ZONE_Key="" + _err "Zone api key and username must be present." + return 1 + fi + _saveaccountconf_mutable ZONE_Username "$ZONE_Username" + _saveaccountconf_mutable ZONE_Key "$ZONE_Key" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug "Adding txt record" + + if _zone_rest POST "dns/${_domain}/txt" "{\"name\": \"$fulldomain\", \"destination\": \"$txtvalue\"}"; then + if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then + _info "Added, OK" + return 0 + else + _err "Adding txt record error." + return 1 + fi + else + _err "Adding txt record error." + fi +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_zone_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using zone.ee dns api" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + ZONE_Username="${ZONE_Username:-$(_readaccountconf_mutable ZONE_Username)}" + ZONE_Key="${ZONE_Key:-$(_readaccountconf_mutable ZONE_Key)}" + if [ -z "$ZONE_Username" ] || [ -z "$ZONE_Key" ]; then + ZONE_Username="" + ZONE_Key="" + _err "Zone api key and username must be present." + return 1 + fi + _saveaccountconf_mutable ZONE_Username "$ZONE_Username" + _saveaccountconf_mutable ZONE_Key "$ZONE_Key" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug "Getting txt records" + _debug _domain "$_domain" + + _zone_rest GET "dns/${_domain}/txt" + + if printf "%s" "$response" | grep \"error\" >/dev/null; then + _err "Error" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Nothing to remove." + else + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\",\"resource_url\":\"[^\"]*\",\"name\":\"$fulldomain\"," | cut -d : -f2 | cut -d , -f1 | tr -d \" | _head_n 1) + if [ -z "$record_id" ]; then + _err "No id found to remove." + return 1 + fi + if ! _zone_rest DELETE "dns/${_domain}/txt/$record_id"; then + _err "Record deleting error." + return 1 + fi + _info "Record deleted" + return 0 + fi + +} + +#################### Private functions below ################################## + +_zone_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + realm="$(printf "%s" "$ZONE_Username:$ZONE_Key" | _base64)" + + export _H1="Authorization: Basic $realm" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$ZONE_Api/$ep" "" "$m")" + else + response="$(_get "$ZONE_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} + +_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 + return 1 + fi + if ! _zone_rest GET "dns/$h/a"; then + return 1 + fi + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + _domain=$h + return 0 + fi + i=$(_math "$i" + 1) + done + return 0 +} From 46fbd7f1e1fc355c34c76b6457e6a6959b5a387b Mon Sep 17 00:00:00 2001 From: "Steven M. Miano" Date: Thu, 14 Mar 2019 08:41:13 -0400 Subject: [PATCH 0200/2234] support ultradns.com api (#2117) support ultradns.com api (#2117) --- README.md | 1 + dnsapi/README.md | 24 +++++++ dnsapi/dns_ultra.sh | 164 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 dnsapi/dns_ultra.sh diff --git a/README.md b/README.md index 50466ad7..68d1b57d 100644 --- a/README.md +++ b/README.md @@ -361,6 +361,7 @@ You don't have to do anything manually! 1. Core-Networks.de (https://core-networks.de) 1. NederHost API (https://www.nederhost.nl/) 1. Zone.ee (zone.eu) API (https://api.zone.eu/v2) +1. UltraDNS API (https://portal.ultradns.com) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index de3148cf..3cce294a 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1326,6 +1326,30 @@ acme.sh --issue -d example.com -d www.example.com --dns dns_zone ``` `ZONE_Username` and `ZONE_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + +## 70. Use UltraDNS API + +UltraDNS is a paid for service that provides DNS, as well as Web and Mail forwarding (as well as reporting, auditing, and advanced tools). + +More information can be found here: https://www.security.neustar/lp/ultra20/index.html + +The REST API documentation for this service is found here: https://portal.ultradns.com/static/docs/REST-API_User_Guide.pdf + +Set your UltraDNS User name, and password; these would be the same you would use here: + +https://portal.ultradns.com/ - or if you create an API only user, that username and password would be better utilized. + +``` +export ULTRA_USR="abcd" +export ULTRA_PWD="efgh" + +To issue a cert run: + +acme.sh --issue --dns dns_ultra -d example.com -d www.example.com +``` + +`ULTRA_USR` and `ULTRA_PWD` will be saved in `~/.acme.sh/account.conf` and will be resued when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_ultra.sh b/dnsapi/dns_ultra.sh new file mode 100644 index 00000000..0100b3b7 --- /dev/null +++ b/dnsapi/dns_ultra.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env sh + +# +# ULTRA_USR="your_user_goes_here" +# +# ULTRA_PWD="some_password_goes_here" + +ULTRA_API="https://restapi.ultradns.com/v2/" + +#Usage: add _acme-challenge.www.domain.com "some_long_string_of_characters_go_here_from_lets_encrypt" +dns_ultra_add() { + fulldomain=$1 + txtvalue=$2 + export txtvalue + ULTRA_USR="${ULTRA_USR:-$(_readaccountconf_mutable ULTRA_USR)}" + ULTRA_PWD="${ULTRA_PWD:-$(_readaccountconf_mutable ULTRA_PWD)}" + if [ -z "$ULTRA_USR" ] || [ -z "$ULTRA_PWD" ]; then + ULTRA_USR="" + ULTRA_PWD="" + _err "You didn't specify an UltraDNS username and password yet" + return 1 + fi + # save the username and password to the account conf file. + _saveaccountconf_mutable ULTRA_USR "$ULTRA_USR" + _saveaccountconf_mutable ULTRA_PWD "$ULTRA_PWD" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "${_domain_id}" + _debug _sub_domain "${_sub_domain}" + _debug _domain "${_domain}" + _debug "Getting txt records" + _ultra_rest GET "zones/${_domain_id}/rrsets/TXT?q=value:${fulldomain}" + if printf "%s" "$response" | grep \"totalCount\" >/dev/null; then + _err "Error, it would appear that this record already exists. Please review existing TXT records for this domain." + return 1 + fi + + _info "Adding record" + if _ultra_rest POST "zones/$_domain_id/rrsets/TXT/${_sub_domain}" '{"ttl":300,"rdata":["'"${txtvalue}"'"]}'; then + if _contains "$response" "Successful"; then + _info "Added, OK" + return 0 + elif _contains "$response" "Resource Record of type 16 with these attributes already exists"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + +} + +dns_ultra_rm() { + fulldomain=$1 + txtvalue=$2 + export txtvalue + ULTRA_USR="${ULTRA_USR:-$(_readaccountconf_mutable ULTRA_USR)}" + ULTRA_PWD="${ULTRA_PWD:-$(_readaccountconf_mutable ULTRA_PWD)}" + if [ -z "$ULTRA_USR" ] || [ -z "$ULTRA_PWD" ]; then + ULTRA_USR="" + ULTRA_PWD="" + _err "You didn't specify an UltraDNS username and password yet" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "${_domain_id}" + _debug _sub_domain "${_sub_domain}" + _debug _domain "${domain}" + + _debug "Getting TXT records" + _ultra_rest GET "zones/${_domain_id}/rrsets?q=kind:RECORDS+owner:${_sub_domain}" + + if ! printf "%s" "$response" | grep \"resultInfo\" >/dev/null; then + _err "There was an error in obtaining the resource records for ${_domain_id}" + return 1 + fi + + count=$(echo "$response" | _egrep_o "\"returnedCount\":[^,]*" | cut -d: -f2 | cut -d'}' -f1) + _debug count "${count}" + if [ "${count}" = "" ]; then + _info "Text record is not present, will not delete anything." + else + if ! _ultra_rest DELETE "zones/$_domain_id/rrsets/TXT/${_sub_domain}" '{"ttl":300,"rdata":["'"${txtvalue}"'"]}'; then + _err "Deleting the record did not succeed, please verify/check." + return 1 + fi + _contains "$response" "" + fi + +} + +#################### 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 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + _debug response "$response" + if [ -z "$h" ]; then + #not valid + return 1 + fi + if ! _ultra_rest GET "zones"; then + return 1 + fi + if _contains "${response}" "${h}." >/dev/null; then + _domain_id=$(echo "$response" | _egrep_o "${h}") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="${h}" + _debug sub_domain "${_sub_domain}" + _debug domain "${_domain}" + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_ultra_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + _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}")" + else + 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) + export AUTH_TOKEN +} From dbc44c08df9e06c5db45ee85e797185dea81fd6e Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Mar 2019 13:38:17 +0800 Subject: [PATCH 0201/2234] fix for solaris --- acme.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 1887bc90..f4f51268 100755 --- a/acme.sh +++ b/acme.sh @@ -3751,7 +3751,7 @@ issue() { return 1 fi - Le_OrderFinalize="$(echo "$response" | tr -d '\r\n' | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)" + Le_OrderFinalize="$(echo "$response" | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)" _debug Le_OrderFinalize "$Le_OrderFinalize" if [ -z "$Le_OrderFinalize" ]; then _err "Create new order error. Le_OrderFinalize not found. $response" @@ -3763,7 +3763,7 @@ issue() { #for dns manual mode _savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize" - _authorizations_seg="$(echo "$response" | tr -d '\r\n' | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" + _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" _debug2 _authorizations_seg "$_authorizations_seg" if [ -z "$_authorizations_seg" ]; then _err "_authorizations_seg not found." @@ -3849,7 +3849,7 @@ $_authorizations_map" thumbprint="$(__calc_account_thumbprint)" fi - entry="$(printf "%s\n" "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" + entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" if [ -z "$entry" ]; then _err "Error, can not get domain token entry $d" @@ -3861,7 +3861,7 @@ $_authorizations_map" _on_issue_err "$_post_hook" return 1 fi - token="$(printf "%s\n" "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" + token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" _debug token "$token" if [ -z "$token" ]; then @@ -3871,9 +3871,9 @@ $_authorizations_map" return 1 fi if [ "$ACME_VERSION" = "2" ]; then - uri="$(printf "%s\n" "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" + uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" else - uri="$(printf "%s\n" "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)" + uri="$(echo "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)" fi _debug uri "$uri" From d0d749074e35057aacc020448b700a3af7e4e63f Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Mar 2019 14:00:15 +0800 Subject: [PATCH 0202/2234] fix for solaris --- acme.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index f4f51268..3c7bc6d0 100755 --- a/acme.sh +++ b/acme.sh @@ -4194,7 +4194,7 @@ $_authorizations_map" fi if [ "$status" = "invalid" ]; then - error="$(echo "$response" | tr -d "\r\n" | _egrep_o '"error":\{[^\}]*')" + error="$(echo "$response" | _egrep_o '"error":\{[^\}]*')" _debug2 error "$error" errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)" _debug2 errordetail "$errordetail" @@ -4260,7 +4260,7 @@ $_authorizations_map" while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do if _contains "$response" "\"status\":\"valid\""; then _debug "Order status is valid." - Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" + Le_LinkCert="$(echo "$response" | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" _debug Le_LinkCert "$Le_LinkCert" if [ -z "$Le_LinkCert" ]; then _err "Sign error, can not find Le_LinkCert" @@ -5195,7 +5195,7 @@ _deactivate() { _err "Can not get domain new order." return 1 fi - _authorizations_seg="$(echo "$response" | tr -d '\r\n' | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" + _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" _debug2 _authorizations_seg "$_authorizations_seg" if [ -z "$_authorizations_seg" ]; then _err "_authorizations_seg not found." @@ -5241,16 +5241,16 @@ _deactivate() { fi _debug "Trigger validation." vtype="$VTYPE_DNS" - entry="$(printf "%s\n" "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" + entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" if [ -z "$entry" ]; then _err "Error, can not get domain token $d" return 1 fi - token="$(printf "%s\n" "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" + token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" _debug token "$token" - uri="$(printf "%s\n" "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')" + uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')" _debug uri "$uri" keyauthorization="$token.$thumbprint" @@ -5272,11 +5272,11 @@ _deactivate() { break fi - _vtype="$(printf "%s\n" "$entry" | _egrep_o '"type": *"[^"]*"' | cut -d : -f 2 | tr -d '"')" + _vtype="$(echo "$entry" | _egrep_o '"type": *"[^"]*"' | cut -d : -f 2 | tr -d '"')" _debug _vtype "$_vtype" _info "Found $_vtype" - uri="$(printf "%s\n" "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')" + uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')" _debug uri "$uri" if [ "$_d_type" ] && [ "$_d_type" != "$_vtype" ]; then From 2ffd8637e10d3ed7178769d219a6a85a09d79c63 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Mar 2019 14:28:24 +0800 Subject: [PATCH 0203/2234] fix standalone content --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3c7bc6d0..d9ea4ee5 100755 --- a/acme.sh +++ b/acme.sh @@ -2111,7 +2111,7 @@ _startserver() { echo 'HTTP/1.0 200 OK'; \ echo 'Content-Length\: $_content_len'; \ echo ''; \ -printf '$content';" & +printf -- '$content';" & serverproc="$!" } From 3f35006c264cf002a875b21a9cde97cc67ffccfa Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Mar 2019 14:35:33 +0800 Subject: [PATCH 0204/2234] fix error message --- dnsapi/dns_namecom.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_namecom.sh b/dnsapi/dns_namecom.sh index 254952d6..a9a7ac51 100755 --- a/dnsapi/dns_namecom.sh +++ b/dnsapi/dns_namecom.sh @@ -130,6 +130,8 @@ _namecom_login() { if [ "$retcode" ]; then _info "Successfully logged in." else + _err "$response" + _err "Please add your ip to api whitelist" _err "Logging in failed." return 1 fi From 82b0ebb787ac87d1712a8cc3cc4982e030ed659a Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Mar 2019 14:53:02 +0800 Subject: [PATCH 0205/2234] minor, remove dns records only when it's added success --- acme.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index d9ea4ee5..752b49bc 100755 --- a/acme.sh +++ b/acme.sh @@ -3931,21 +3931,21 @@ $_authorizations_map" else txtdomain="_acme-challenge.$_d_alias" fi - dns_entries="${dns_entries}${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$txtdomain$dvsep$_currentRoot" + dns_entry="${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$txtdomain$dvsep$_currentRoot" else txtdomain="_acme-challenge.$_dns_root_d" - dns_entries="${dns_entries}${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$dvsep$_currentRoot" + dns_entry="${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$dvsep$_currentRoot" fi + _debug txtdomain "$txtdomain" txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" _debug txt "$txt" d_api="$(_findHook "$_dns_root_d" dnsapi "$_currentRoot")" - _debug d_api "$d_api" - dns_entries="$dns_entries$dvsep$txt${dvsep}$d_api -" - _debug2 "$dns_entries" + + dns_entry="$dns_entry$dvsep$txt${dvsep}$d_api" + _debug2 dns_entry "$dns_entry" if [ "$d_api" ]; then _info "Found domain api file: $d_api" else @@ -3984,6 +3984,9 @@ $_authorizations_map" _clearup return 1 fi + dns_entries="$dns_entries$dns_entry +" + _debug2 "$dns_entries" dnsadded='1' fi done From 2b36f4f57f1f9a484c5f6caf8fcff5472636a6a4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Mar 2019 15:07:34 +0800 Subject: [PATCH 0206/2234] update --- dnsapi/dns_namecom.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_namecom.sh b/dnsapi/dns_namecom.sh index a9a7ac51..769a2082 100755 --- a/dnsapi/dns_namecom.sh +++ b/dnsapi/dns_namecom.sh @@ -13,6 +13,8 @@ dns_namecom_add() { fulldomain=$1 txtvalue=$2 + Namecom_Username="${Namecom_Username:-$(_readaccountconf_mutable Namecom_Username)}" + Namecom_Token="${Namecom_Token:-$(_readaccountconf_mutable Namecom_Token)}" # First we need name.com credentials. if [ -z "$Namecom_Username" ]; then Namecom_Username="" @@ -29,8 +31,8 @@ dns_namecom_add() { fi # Save them in configuration. - _saveaccountconf Namecom_Username "$Namecom_Username" - _saveaccountconf Namecom_Token "$Namecom_Token" + _saveaccountconf_mutable Namecom_Username "$Namecom_Username" + _saveaccountconf_mutable Namecom_Token "$Namecom_Token" # Login in using API if ! _namecom_login; then @@ -46,7 +48,7 @@ dns_namecom_add() { # Add TXT record. _namecom_addtxt_json="{\"host\":\"$_sub_domain\",\"type\":\"TXT\",\"answer\":\"$txtvalue\",\"ttl\":\"300\"}" if _namecom_rest POST "domains/$_domain/records" "$_namecom_addtxt_json"; then - _retvalue=$(printf "%s\n" "$response" | _egrep_o "\"$_sub_domain\"") + _retvalue=$(echo "$response" | _egrep_o "\"$_sub_domain\"") if [ "$_retvalue" ]; then _info "Successfully added TXT record, ready for validation." return 0 @@ -63,6 +65,8 @@ dns_namecom_rm() { fulldomain=$1 txtvalue=$2 + Namecom_Username="${Namecom_Username:-$(_readaccountconf_mutable Namecom_Username)}" + Namecom_Token="${Namecom_Token:-$(_readaccountconf_mutable Namecom_Token)}" if ! _namecom_login; then return 1 fi @@ -75,7 +79,7 @@ dns_namecom_rm() { # Get the record id. if _namecom_rest GET "domains/$_domain/records"; then - _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+,\"domainName\":\"$_domain\",\"host\":\"$_sub_domain\",\"fqdn\":\"$fulldomain.\",\"type\":\"TXT\",\"answer\":\"$txtvalue\"" | cut -d \" -f 3 | _egrep_o [0-9]+) + _record_id=$(echo "$response" | _egrep_o "\"id\":[0-9]+,\"domainName\":\"$_domain\",\"host\":\"$_sub_domain\",\"fqdn\":\"$fulldomain.\",\"type\":\"TXT\",\"answer\":\"$txtvalue\"" | cut -d \" -f 3 | _egrep_o [0-9]+) _debug record_id "$_record_id" if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." @@ -126,7 +130,7 @@ _namecom_login() { _namecom_auth=$(printf "%s:%s" "$Namecom_Username" "$Namecom_Token" | _base64) if _namecom_rest GET "hello"; then - retcode=$(printf "%s\n" "$response" | _egrep_o "\"username\"\:\"$Namecom_Username\"") + retcode=$(echo "$response" | _egrep_o "\"username\"\:\"$Namecom_Username\"") if [ "$retcode" ]; then _info "Successfully logged in." else From 653c77e852b879559c3daa338b9f4f247ac97ed2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Mar 2019 15:09:49 +0800 Subject: [PATCH 0207/2234] update --- dnsapi/dns_namecom.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_namecom.sh b/dnsapi/dns_namecom.sh index 769a2082..0d5dd2c4 100755 --- a/dnsapi/dns_namecom.sh +++ b/dnsapi/dns_namecom.sh @@ -29,7 +29,8 @@ dns_namecom_add() { _err "Please specify that in your environment variable." return 1 fi - + _debug Namecom_Username "$Namecom_Username" + _secure_debug Namecom_Token "$Namecom_Token" # Save them in configuration. _saveaccountconf_mutable Namecom_Username "$Namecom_Username" _saveaccountconf_mutable Namecom_Token "$Namecom_Token" From c74d597c84342f14a3f5af9d7c6c2514383a1242 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Mar 2019 18:34:44 +0800 Subject: [PATCH 0208/2234] add debug info --- dnsapi/dns_netcup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 2273eb7c..d5d7c22e 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -8,6 +8,7 @@ end="https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON" client="" dns_netcup_add() { + _debug NC_Apikey "$NC_Apikey" login if [ "$NC_Apikey" = "" ] || [ "$NC_Apipw" = "" ] || [ "$NC_CID" = "" ]; then _err "No Credentials given" From 7decce97180bd1431eb63c6ed027bbb2898bdff1 Mon Sep 17 00:00:00 2001 From: Sylvia van Os Date: Mon, 18 Mar 2019 14:48:01 +0100 Subject: [PATCH 0209/2234] Resolve comments on pull request --- dnsapi/dns_openprovider.sh | 60 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh index 3d66dfe4..a0171e4e 100755 --- a/dnsapi/dns_openprovider.sh +++ b/dnsapi/dns_openprovider.sh @@ -50,7 +50,7 @@ dns_openprovider_add() { items="$response" while true; do - item="$(printf '%s' "$items" | _egrep_o '.*<\/openXML>' | sed -n -E 's/.*(.*<\/item>).*/\1/p')" + item="$(echo "$items" | _egrep_o '.*<\/openXML>' | sed -n 's/.*\(.*<\/item>\).*/\1/p')" _debug existing_items "$existing_items" _debug results_retrieved "$results_retrieved" _debug item "$item" @@ -59,24 +59,24 @@ dns_openprovider_add() { break fi - items="$(printf '%s' "$items" | sed "s$item")" + items="$(echo "$items" | sed "s|${item}||")" - results_retrieved=$((results_retrieved + 1)) - new_item="$(printf '%s' "$item" | sed -n -E "s/.*.*((.*)\.$_domain_name\.$_domain_extension<\/name>.*(.*<\/type>).*(.*<\/value>).*(.*<\/prio>).*(.*<\/ttl>)).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p")" + results_retrieved="$(_math "$results_retrieved" + 1)" + new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)\.'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" if [ -z "$new_item" ]; then # Base record - new_item="$(printf '%s' "$item" | sed -n -E "s/.*.*((.*)$_domain_name\.$_domain_extension<\/name>.*(.*<\/type>).*(.*<\/value>).*(.*<\/prio>).*(.*<\/ttl>)).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p")" + new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" fi - if [ -z "$(printf '%s' "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then + if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then _debug "not an allowed record type, skipping" "$new_item" continue fi - existing_items="$(printf '%s%s' "$existing_items" "$new_item")" + existing_items="$existing_items$new_item" done - total="$(printf '%s' "$response" | _egrep_o '.*?<\/total>' | sed -n -E 's/.*(.*)<\/total>.*/\1/p')" + total="$(echo "$response" | _egrep_o '.*?<\/total>' | sed -n 's/.*\(.*\)<\/total>.*/\1/p')" _debug total "$total" if [ "$results_retrieved" -eq "$total" ]; then @@ -85,7 +85,7 @@ dns_openprovider_add() { done _debug "Creating acme record" - acme_record="$(printf '%s' "$fulldomain" | sed -e "s/.$_domain_name.$_domain_extension$//")" + acme_record="$(echo "$fulldomain" | sed -e "s/.$_domain_name.$_domain_extension$//")" _openprovider_request "$(printf '%s%smaster%s%sTXT%s86400' "$_domain_name" "$_domain_extension" "$existing_items" "$acme_record" "$txtvalue")" return 0 @@ -127,7 +127,7 @@ dns_openprovider_rm() { # Remove acme records from items items="$response" while true; do - item="$(printf '%s' "$items" | _egrep_o '.*<\/openXML>' | sed -n -E 's/.*(.*<\/item>).*/\1/p')" + item="$(echo "$items" | _egrep_o '.*<\/openXML>' | sed -n 's/.*\(.*<\/item>\).*/\1/p')" _debug existing_items "$existing_items" _debug results_retrieved "$results_retrieved" _debug item "$item" @@ -136,30 +136,30 @@ dns_openprovider_rm() { break fi - items="$(printf '%s' "$items" | sed "s$item")" + items="$(echo "$items" | sed "s|${item}||")" - results_retrieved=$((results_retrieved + 1)) - if ! printf '%s' "$item" | grep -v "$fulldomain"; then + results_retrieved="$(_math "$results_retrieved" + 1)" + if ! echo "$item" | grep -v "$fulldomain"; then _debug "acme record, skipping" "$item" continue fi - new_item="$(printf '%s' "$item" | sed -n -E "s/.*.*((.*)\.$_domain_name\.$_domain_extension<\/name>.*(.*<\/type>).*(.*<\/value>).*(.*<\/prio>).*(.*<\/ttl>)).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p")" + new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)\.'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" if [ -z "$new_item" ]; then # Base record - new_item="$(printf '%s' "$item" | sed -n -E "s/.*.*((.*)$_domain_name\.$_domain_extension<\/name>.*(.*<\/type>).*(.*<\/value>).*(.*<\/prio>).*(.*<\/ttl>)).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p")" + new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" fi - if [ -z "$(printf '%s' "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then + if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then _debug "not an allowed record type, skipping" "$new_item" continue fi - existing_items="$(printf '%s%s' "$existing_items" "$new_item")" + existing_items="$existing_items$new_item" done - total="$(printf '%s' "$response" | _egrep_o '.*?<\/total>' | sed -n -E 's/.*(.*)<\/total>.*/\1/p')" + total="$(echo "$response" | _egrep_o '.*?<\/total>' | sed -n 's/.*\(.*\)<\/total>.*/\1/p')" _debug total "$total" @@ -185,18 +185,18 @@ _get_root() { results_retrieved=0 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(echo "$domain" | cut -d . -f $i-100) _debug h "$h" if [ -z "$h" ]; then #not valid return 1 fi - _openprovider_request "$(printf '%s%s' "$(printf "%s" "$h" | cut -d . -f 1)" "$results_retrieved")" + _openprovider_request "$(printf '%s%s' "$(echo "$h" | cut -d . -f 1)" "$results_retrieved")" items="$response" while true; do - item="$(printf '%s' "$items" | _egrep_o '.*<\/openXML>' | sed -n -E 's/.*(.*<\/domain>).*/\1/p')" + item="$(echo "$items" | _egrep_o '.*<\/openXML>' | sed -n 's/.*\(.*<\/domain>\).*/\1/p')" _debug existing_items "$existing_items" _debug results_retrieved "$results_retrieved" _debug item "$item" @@ -205,26 +205,26 @@ _get_root() { break fi - items="$(printf '%s' "$items" | sed "s$item")" + items="$(echo "$items" | sed "s|${item}||")" - results_retrieved=$((results_retrieved + 1)) + results_retrieved="$(_math "$results_retrieved" + 1)" - _domain_name="$(printf "%s" "$item" | sed -n -E 's/.*.*(.*)<\/name>.*<\/domain>.*/\1/p')" - _domain_extension="$(printf "%s" "$item" | sed -n -E 's/.*.*(.*)<\/extension>.*<\/domain>.*/\1/p')" + _domain_name="$(echo "$item" | sed -n 's/.*.*\(.*\)<\/name>.*<\/domain>.*/\1/p')" + _domain_extension="$(echo "$item" | sed -n 's/.*.*\(.*\)<\/extension>.*<\/domain>.*/\1/p')" _debug _domain_name "$_domain_name" _debug _domain_extension "$_domain_extension" - if [ "$(printf "%s.%s" "$_domain_name" "$_domain_extension")" = "$h" ]; then + if [ "$_domain_name.$_domain_extension" = "$h" ]; then return 0 fi done - total="$(printf '%s' "$response" | _egrep_o '.*?<\/total>' | sed -n -E 's/.*(.*)<\/total>.*/\1/p')" + total="$(echo "$response" | _egrep_o '.*?<\/total>' | sed -n 's/.*\(.*\)<\/total>.*/\1/p')" _debug total "$total" if [ "$results_retrieved" -eq "$total" ]; then results_retrieved=0 - i=$(_math "$i" + 1) + i="$(_math "$i" + 1)" fi done return 1 @@ -233,9 +233,9 @@ _get_root() { _openprovider_request() { request_xml=$1 - xml_prefix=$(printf '') + xml_prefix=$(echo '') xml_content=$(printf '%s%s%s' "$OPENPROVIDER_USER" "$OPENPROVIDER_PASSWORDHASH" "$request_xml") - response="$(_post "$(printf "%s%s" "$xml_prefix" "$xml_content" | tr -d '\n')" "$OPENPROVIDER_API" "" "POST" "application/xml")" + response="$(_post "$(echo "$xml_prefix$xml_content" | tr -d '\n')" "$OPENPROVIDER_API" "" "POST" "application/xml")" _debug response "$response" if ! _contains "$response" "0.*"; then _err "API request failed." From 71cfd874aeaa8282efb2f1200666dab5fa6fec68 Mon Sep 17 00:00:00 2001 From: Sylvia van Os Date: Mon, 18 Mar 2019 16:10:58 +0100 Subject: [PATCH 0210/2234] Fix SC2116 --- dnsapi/dns_openprovider.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh index a0171e4e..1b1b760e 100755 --- a/dnsapi/dns_openprovider.sh +++ b/dnsapi/dns_openprovider.sh @@ -233,7 +233,7 @@ _get_root() { _openprovider_request() { request_xml=$1 - xml_prefix=$(echo '') + xml_prefix='' xml_content=$(printf '%s%s%s' "$OPENPROVIDER_USER" "$OPENPROVIDER_PASSWORDHASH" "$request_xml") response="$(_post "$(echo "$xml_prefix$xml_content" | tr -d '\n')" "$OPENPROVIDER_API" "" "POST" "application/xml")" _debug response "$response" From 7679df062c246e72c24ce2a57ca5d58cd02095ca Mon Sep 17 00:00:00 2001 From: Herman Sletteng Date: Tue, 19 Mar 2019 14:16:05 +0100 Subject: [PATCH 0211/2234] dns_gdnsdk: Fixed stupid regex error, want literal "-", not a range --- dnsapi/dns_gdnsdk.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_gdnsdk.sh b/dnsapi/dns_gdnsdk.sh index 7dc7894a..8c4962c0 100755 --- a/dnsapi/dns_gdnsdk.sh +++ b/dnsapi/dns_gdnsdk.sh @@ -137,7 +137,7 @@ _mypost() { _get_domain() { _myget 'action=dns_primarydns' - _domains=$(echo "$_result" | _egrep_o ' domain="[[:alnum:].-_]+' | sed 's/^.*"//') + _domains=$(echo "$_result" | _egrep_o ' domain="[[:alnum:]._-]+' | sed 's/^.*"//') if [ -z "$_domains" ]; then _err "Primary domain list not found!" return 1 From 34be7e99f01c716465f6f3701310ba81f6121d76 Mon Sep 17 00:00:00 2001 From: bz-heilig <35926736+bz-heilig@users.noreply.github.com> Date: Tue, 19 Mar 2019 15:04:37 +0100 Subject: [PATCH 0212/2234] Update README.md Added links for do.de API token creation and documentation of API. --- dnsapi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 3cce294a..a5779a30 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1157,7 +1157,7 @@ The `ACTIVE24_Token` will be saved in `~/.acme.sh/account.conf` and will be reus ## 60. Use do.de API -Create an API token in your do.de account. +Create an API token in your do.de account ([Create token here](https://www.do.de/account/letsencrypt/) | [Documentation](https://www.do.de/wiki/LetsEncrypt_-_Entwickler)). Set your API token: ``` From 307336cfc4ca136514423f43294a1768b727a2a7 Mon Sep 17 00:00:00 2001 From: Valentin Brandl Date: Tue, 19 Mar 2019 18:42:47 +0100 Subject: [PATCH 0213/2234] Add deploy hook for mailcow This hook will copy the key and certificate chain to the specified mailcow installation (as described in https://mailcow.github.io/mailcow-dockerized-docs/firststeps-ssl/#use-own-certificates) and restarts the containers, that are using the certificates. The hook has 2 parameters: * `DEPLOY_MAILCOW_PATH`: The path to the mailcow installation (required) * `DEPLOY_MAILCOW_RELOAD`: The reload command, defaults to `docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow` --- deploy/mailcow.sh | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 deploy/mailcow.sh diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh new file mode 100644 index 00000000..3b38fa85 --- /dev/null +++ b/deploy/mailcow.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env sh + +#Here is a script to deploy cert to mailcow. + +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +mailcow_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + _ssl_path="${DEPLOY_MAILCOW_PATH}/data/assets/ssl/" + if [ ! -d "$_ssl_path"; ] then + _err "Cannot find mailcow ssl path: $_ssl_path" + return 1 + fi + + _info "Copying key and cert" + _real_key="$_ssl_path/key.pem" + if ! cat "$_ckey" >"$_real_key"; then + _err "Error: write key file to: $_real_key" + return 1 + fi + + _real_fullchain="$_ssl_path/cert.pem" + if ! cat "$_cfullchain" >"$_real_fullchain"; then + _err "Error: write cert file to: $_real_fullchain" + return 1 + fi + + DEFAULT_MAILCOW_RELOAD="docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow" + _reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}" + + _info "Run reload: $_reload" + if eval "$_reload"; then + _info "Reload success!" + fi + return 0 + +} From b581a171f0a09870fcae71272ec6fe5b99c4df20 Mon Sep 17 00:00:00 2001 From: Valentin Brandl Date: Tue, 19 Mar 2019 18:43:07 +0100 Subject: [PATCH 0214/2234] Add documentation for mailcow deploy hook --- deploy/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/deploy/README.md b/deploy/README.md index 44d53225..8cced4d8 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -391,3 +391,23 @@ acme.sh --deploy --deploy-hook mydevil -d example.com ``` That will remove old certificate and install new one. + +## 15. Deploy your cert to local mailcow server + +You can install your certificates to a local [mailcow](https://github.com/mailcow/mailcow-dockerized/) instance. The +deploy hook will copy the certificates and reload the containers, that use the certificates (`postfix-mailcow` +`dovecot-mailcow` and `nginx-mailcow`). + +```sh +$ export DEPLOY_MAILCOW_PATH="/path/to/mailcow" +$ acme.sh --deploy -d example.com --deploy-hook mailcow +``` + +The default command to restart is `docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow`, if you want a +custom restart command, specify it by setting `DEPLOY_MAILCOW_RELOAD`: + +```sh +$ export DEPLOY_MAILCOW_PATH="/path/to/mailcow" +$ export DEPLOY_MAILCOW_RELOAD="docker-compose restart" +$ acme.sh --deploy -d example.com --deploy-hook mailcow +``` From d643a2ff13ae642ca16ecc87c04a0c88bb8a63bb Mon Sep 17 00:00:00 2001 From: Valentin Brandl Date: Tue, 19 Mar 2019 19:09:25 +0100 Subject: [PATCH 0215/2234] Check if mailcow path is set and fix directory check --- deploy/mailcow.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index 3b38fa85..bdba3e29 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -20,8 +20,15 @@ mailcow_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _ssl_path="${DEPLOY_MAILCOW_PATH}/data/assets/ssl/" - if [ ! -d "$_ssl_path"; ] then + _mailcow_path="${DEPLOY_MAILCOW_PATH}" + + if [ -z "$_mailcow_path" ]; then + _err "Mailcow path is not found, please define DEPLOY_MAILCOW_PATH." + return 1 + fi + + _ssl_path="${_mailcow_path}/data/assets/ssl/" + if [ ! -d "$_ssl_path" ]; then _err "Cannot find mailcow ssl path: $_ssl_path" return 1 fi @@ -39,7 +46,7 @@ mailcow_deploy() { return 1 fi - DEFAULT_MAILCOW_RELOAD="docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow" + DEFAULT_MAILCOW_RELOAD="cd ${_mailcow_path} && docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow" _reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}" _info "Run reload: $_reload" From d604166194491503a54b5c73be4fc1986fae9456 Mon Sep 17 00:00:00 2001 From: Valentin Brandl Date: Tue, 19 Mar 2019 19:15:31 +0100 Subject: [PATCH 0216/2234] Fix formatting --- deploy/mailcow.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index bdba3e29..3a806e83 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -23,14 +23,14 @@ mailcow_deploy() { _mailcow_path="${DEPLOY_MAILCOW_PATH}" if [ -z "$_mailcow_path" ]; then - _err "Mailcow path is not found, please define DEPLOY_MAILCOW_PATH." - return 1 + _err "Mailcow path is not found, please define DEPLOY_MAILCOW_PATH." + return 1 fi _ssl_path="${_mailcow_path}/data/assets/ssl/" if [ ! -d "$_ssl_path" ]; then - _err "Cannot find mailcow ssl path: $_ssl_path" - return 1 + _err "Cannot find mailcow ssl path: $_ssl_path" + return 1 fi _info "Copying key and cert" From 228c835466b41448897c23c41350dc07a29fe9e1 Mon Sep 17 00:00:00 2001 From: temoffey Date: Wed, 20 Mar 2019 03:03:10 +0300 Subject: [PATCH 0217/2234] gcore_cdn_deploy --- deploy/README.md | 15 +++++ deploy/gcore_cdn.sh | 130 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 deploy/gcore_cdn.sh diff --git a/deploy/README.md b/deploy/README.md index 44d53225..e89add80 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -391,3 +391,18 @@ acme.sh --deploy --deploy-hook mydevil -d example.com ``` That will remove old certificate and install new one. + +## 15. Deploy the cert to G-Core CDN servise + +Deploy the cert to G-Core CDN servise (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). +Uses command line curl for send requests and jq for parse responses. + +Then you can deploy now: + +```sh +export DEPLOY_GCORE_CDN_USERNAME=myusername +export DEPLOY_GCORE_CDN_PASSWORD=mypassword +acme.sh --deploy -d example.com --deploy-hook gcore_cdn +``` + +Please note, need installed jq. diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh new file mode 100644 index 00000000..051226d9 --- /dev/null +++ b/deploy/gcore_cdn.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env sh + +# Here is the script to deploy the cert to G-Core CDN servise (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). +# Uses command line curl for send requests and jq for parse responses. +# Returns 0 when success. +# +# Written by temoffey +# Public domain, 2019 + +#export DEPLOY_GCORE_CDN_USERNAME=myusername +#export DEPLOY_GCORE_CDN_PASSWORD=mypassword + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain + +gcore_cdn_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + _fullchain=$(awk 1 ORS='\\n' "$_cfullchain") + _key=$(awk 1 ORS='\\n' "$_ckey") + + _debug _fullchain "$_fullchain" + _debug _key "$_key" + + if [ -z "$DEPLOY_GCORE_CDN_USERNAME" ]; then + if [ -z "$Le_Deploy_gcore_cdn_username" ]; then + _err "Please define the target username: export DEPLOY_GCORE_CDN_USERNAME=username" + return 1 + else + DEPLOY_GCORE_CDN_USERNAME="$Le_Deploy_gcore_cdn_username" + fi + else + _savedomainconf Le_Deploy_gcore_cdn_username "$DEPLOY_GCORE_CDN_USERNAME" + fi + + if [ -z "$DEPLOY_GCORE_CDN_PASSWORD" ]; then + if [ -z "$Le_Deploy_gcore_cdn_password" ]; then + _err "Please define the target password: export DEPLOY_GCORE_CDN_PASSWORD=password" + return 1 + else + DEPLOY_GCORE_CDN_PASSWORD="$Le_Deploy_gcore_cdn_password" + fi + else + _savedomainconf Le_Deploy_gcore_cdn_password "$DEPLOY_GCORE_CDN_PASSWORD" + fi + + if ! [ -x "$(command -v jq)" ]; then + _err "Please install the package jq: sudo apt-get install jq" + return 1 + fi + + _info "Get authorization token" + _request="{ \"username\": \"$DEPLOY_GCORE_CDN_USERNAME\", \"password\": \"$DEPLOY_GCORE_CDN_PASSWORD\" }" + _debug _request "$_request" + _response=$(curl -s -X POST https://api.gcdn.co/auth/signin -H "Content-Type:application/json" -d "$_request") + _debug _response "$_response" + _token=$(echo "$_response" | jq -r '.token') + _debug _token "$_token" + + if [ "$_token" == "null" ]; then + _err "Error G-Core Labs API authorization" + return 1 + fi + + _info "Find CDN resource with cname $_cdomain" + _response=$(curl -s -X GET https://api.gcdn.co/resources -H "Authorization:Token $_token") + _debug _response "$_response" + _resource=$(echo "$_response" | jq -r ".[] | select(.cname == \"$_cdomain\")") + _debug _resource "$_resource" + _resourceId=$(echo "$_resource" | jq -r '.id') + _sslDataOld=$(echo "$_resource" | jq -r '.sslData') + _originGroup=$(echo "$_resource" | jq -r '.originGroup') + _debug _resourceId "$_resourceId" + _debug _sslDataOld "$_sslDataOld" + _debug _originGroup "$_originGroup" + + if [ -z "$_resourceId" ] || [ "$_resourceId" == "null" ] || [ -z "$_originGroup" ] || [ "$_originGroup" == "null" ]; then + _err "Not found CDN resource with cname $_cdomain" + return 1 + fi + + _info "Add new SSL certificate" + _date=$(date "+%d.%m.%Y %H:%M:%S") + _request="{ \"name\": \"$_cdomain ($_date)\", \"sslCertificate\": \"$_fullchain\n\", \"sslPrivateKey\": \"$_key\n\" }" + _debug _request "$_request" + _response=$(curl -s -X POST https://api.gcdn.co/sslData -H "Content-Type:application/json" -H "Authorization:Token $_token" -d "$_request") + _debug _response "$_response" + _sslDataAdd=$(echo "$_response" | jq -r '.id') + _debug _sslDataAdd "$_sslDataAdd" + + if [ "$_sslDataAdd" == "null" ]; then + _err "Error new SSL certificate add" + return 1 + fi + + _info "Update CDN resource" + _request="{ \"originGroup\": $_originGroup, \"sslData\": $_sslDataAdd }" + _debug _request "$_request" + _response=$(curl -s -X PUT https://api.gcdn.co/resources/$_resourceId -H "Content-Type:application/json" -H "Authorization:Token $_token" -d "$_request") + _debug _response "$_response" + _sslDataNew=$(echo "$_response" | jq -r '.sslData') + _debug _sslDataNew "$_sslDataNew" + + if [ "$_sslDataNew" != "$_sslDataAdd" ]; then + _err "Error CDN resource update" + return 1 + fi + + if [ -z "$_sslDataOld" ] || [ "$_sslDataOld" = "null" ]; then + _info "Not found old SSL certificate" + else + _info "Delete old SSL certificate" + _response=$(curl -s -X DELETE https://api.gcdn.co/sslData/$_sslDataOld -H "Authorization:Token $_token") + _debug _response "$_response" + fi + + _info "Certificate successfully deployed" + return 0 +} \ No newline at end of file From 95cdb4b2bc606e1641850359e9bf55abce2d46f4 Mon Sep 17 00:00:00 2001 From: temoffey Date: Wed, 20 Mar 2019 14:02:11 +0300 Subject: [PATCH 0218/2234] fix syntax --- deploy/README.md | 4 ++-- deploy/gcore_cdn.sh | 26 ++++++++++++-------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index e89add80..76a6cc94 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -392,9 +392,9 @@ acme.sh --deploy --deploy-hook mydevil -d example.com That will remove old certificate and install new one. -## 15. Deploy the cert to G-Core CDN servise +## 15. Deploy the cert to G-Core CDN service -Deploy the cert to G-Core CDN servise (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). +Deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). Uses command line curl for send requests and jq for parse responses. Then you can deploy now: diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 051226d9..621d445b 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Here is the script to deploy the cert to G-Core CDN servise (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). +# Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). # Uses command line curl for send requests and jq for parse responses. # Returns 0 when success. # @@ -37,22 +37,20 @@ gcore_cdn_deploy() { if [ -z "$Le_Deploy_gcore_cdn_username" ]; then _err "Please define the target username: export DEPLOY_GCORE_CDN_USERNAME=username" return 1 - else - DEPLOY_GCORE_CDN_USERNAME="$Le_Deploy_gcore_cdn_username" fi else - _savedomainconf Le_Deploy_gcore_cdn_username "$DEPLOY_GCORE_CDN_USERNAME" + Le_Deploy_gcore_cdn_username="$DEPLOY_GCORE_CDN_USERNAME" + _savedomainconf Le_Deploy_gcore_cdn_username "$Le_Deploy_gcore_cdn_username" fi if [ -z "$DEPLOY_GCORE_CDN_PASSWORD" ]; then if [ -z "$Le_Deploy_gcore_cdn_password" ]; then _err "Please define the target password: export DEPLOY_GCORE_CDN_PASSWORD=password" return 1 - else - DEPLOY_GCORE_CDN_PASSWORD="$Le_Deploy_gcore_cdn_password" fi else - _savedomainconf Le_Deploy_gcore_cdn_password "$DEPLOY_GCORE_CDN_PASSWORD" + Le_Deploy_gcore_cdn_password="$DEPLOY_GCORE_CDN_PASSWORD" + _savedomainconf Le_Deploy_gcore_cdn_password "$Le_Deploy_gcore_cdn_password" fi if ! [ -x "$(command -v jq)" ]; then @@ -61,14 +59,14 @@ gcore_cdn_deploy() { fi _info "Get authorization token" - _request="{ \"username\": \"$DEPLOY_GCORE_CDN_USERNAME\", \"password\": \"$DEPLOY_GCORE_CDN_PASSWORD\" }" + _request="{ \"username\": \"$Le_Deploy_gcore_cdn_username\", \"password\": \"$Le_Deploy_gcore_cdn_password\" }" _debug _request "$_request" _response=$(curl -s -X POST https://api.gcdn.co/auth/signin -H "Content-Type:application/json" -d "$_request") _debug _response "$_response" _token=$(echo "$_response" | jq -r '.token') _debug _token "$_token" - if [ "$_token" == "null" ]; then + if [ "$_token" = "null" ]; then _err "Error G-Core Labs API authorization" return 1 fi @@ -85,7 +83,7 @@ gcore_cdn_deploy() { _debug _sslDataOld "$_sslDataOld" _debug _originGroup "$_originGroup" - if [ -z "$_resourceId" ] || [ "$_resourceId" == "null" ] || [ -z "$_originGroup" ] || [ "$_originGroup" == "null" ]; then + if [ -z "$_resourceId" ] || [ "$_resourceId" = "null" ] || [ -z "$_originGroup" ] || [ "$_originGroup" = "null" ]; then _err "Not found CDN resource with cname $_cdomain" return 1 fi @@ -107,7 +105,7 @@ gcore_cdn_deploy() { _info "Update CDN resource" _request="{ \"originGroup\": $_originGroup, \"sslData\": $_sslDataAdd }" _debug _request "$_request" - _response=$(curl -s -X PUT https://api.gcdn.co/resources/$_resourceId -H "Content-Type:application/json" -H "Authorization:Token $_token" -d "$_request") + _response=$(curl -s -X PUT "https://api.gcdn.co/resources/$_resourceId" -H "Content-Type:application/json" -H "Authorization:Token $_token" -d "$_request") _debug _response "$_response" _sslDataNew=$(echo "$_response" | jq -r '.sslData') _debug _sslDataNew "$_sslDataNew" @@ -118,13 +116,13 @@ gcore_cdn_deploy() { fi if [ -z "$_sslDataOld" ] || [ "$_sslDataOld" = "null" ]; then - _info "Not found old SSL certificate" + _info "Not found old SSL certificate" else _info "Delete old SSL certificate" - _response=$(curl -s -X DELETE https://api.gcdn.co/sslData/$_sslDataOld -H "Authorization:Token $_token") + _response=$(curl -s -X DELETE "https://api.gcdn.co/sslData/$_sslDataOld" -H "Authorization:Token $_token") _debug _response "$_response" fi _info "Certificate successfully deployed" return 0 -} \ No newline at end of file +} From 89989adcadd31cbd162beff2ca7ab746c3928324 Mon Sep 17 00:00:00 2001 From: temoffey Date: Wed, 20 Mar 2019 14:05:18 +0300 Subject: [PATCH 0219/2234] fix syntax --- deploy/gcore_cdn.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 621d445b..18d137a6 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -65,7 +65,7 @@ gcore_cdn_deploy() { _debug _response "$_response" _token=$(echo "$_response" | jq -r '.token') _debug _token "$_token" - + if [ "$_token" = "null" ]; then _err "Error G-Core Labs API authorization" return 1 @@ -97,7 +97,7 @@ gcore_cdn_deploy() { _sslDataAdd=$(echo "$_response" | jq -r '.id') _debug _sslDataAdd "$_sslDataAdd" - if [ "$_sslDataAdd" == "null" ]; then + if [ "$_sslDataAdd" = "null" ]; then _err "Error new SSL certificate add" return 1 fi From fbdc5a0eb540865b52d4647ac5eda84ecaa9a0be Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 20 Mar 2019 22:52:40 +0800 Subject: [PATCH 0220/2234] fix https://github.com/Neilpang/acme.sh/issues/2179 --- acme.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 752b49bc..f47a5ebb 100755 --- a/acme.sh +++ b/acme.sh @@ -3750,7 +3750,8 @@ issue() { _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)" _debug Le_OrderFinalize "$Le_OrderFinalize" if [ -z "$Le_OrderFinalize" ]; then @@ -4249,13 +4250,10 @@ $_authorizations_map" _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)" if [ -z "$Le_LinkOrder" ]; then - _err "Sign error, can not get order link location header" - _err "responseHeaders" "$responseHeaders" - _on_issue_err "$_post_hook" - return 1 + Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)" fi + _savedomainconf "Le_LinkOrder" "$Le_LinkOrder" _link_cert_retry=0 @@ -4281,6 +4279,14 @@ $_authorizations_map" _on_issue_err "$_post_hook" return 1 fi + #the order is processing, so we are going to poll order status + if [ -z "$Le_LinkOrder" ]; then + _err "Sign error, can not get order link location header" + _err "responseHeaders" "$responseHeaders" + _on_issue_err "$_post_hook" + return 1 + fi + _info "Polling order status: $Le_LinkOrder" if ! _send_signed_request "$Le_LinkOrder"; then _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder." _err "$response" From 0629c2a086e390b5fc502ad5c0e6bdb8d11ac470 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 20 Mar 2019 23:01:24 +0800 Subject: [PATCH 0221/2234] move to wiki --- dnsapi/README.md | 1373 +--------------------------------------------- 1 file changed, 2 insertions(+), 1371 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index a5779a30..d9ab46fa 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1,1375 +1,6 @@ # How to use DNS API +DNS api usage: -If your dns provider doesn't provide api access, you can use our dns alias mode: - -https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode - -## 1. Use CloudFlare domain API to automatically issue cert - -First you need to login to your CloudFlare account to get your [API key](https://dash.cloudflare.com/profile). - -``` -export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -export CF_Email="xxxx@sss.com" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_cf -d example.com -d www.example.com -``` - -The `CF_Key` and `CF_Email` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - - -## 2. Use DNSPod.cn domain API to automatically issue cert - -First you need to login to your DNSPod account to get your API Key and ID. - -``` -export DP_Id="1234" -export DP_Key="sADDsdasdgdsf" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_dp -d example.com -d www.example.com -``` - -The `DP_Id` and `DP_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - - -## 3. Use CloudXNS.com domain API to automatically issue cert - -First you need to login to your CloudXNS account to get your API Key and Secret. - -``` -export CX_Key="1234" -export CX_Secret="sADDsdasdgdsf" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_cx -d example.com -d www.example.com -``` - -The `CX_Key` and `CX_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - - -## 4. Use GoDaddy.com domain API to automatically issue cert - -First you need to login to your GoDaddy account to get your API Key and Secret. - -https://developer.godaddy.com/keys/ - -Please create a Production key, instead of a Test key. - -``` -export GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -export GD_Secret="asdfsdafdsfdsfdsfdsfdsafd" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_gd -d example.com -d www.example.com -``` - -The `GD_Key` and `GD_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - - -## 5. Use PowerDNS embedded API to automatically issue cert - -First you need to login to your PowerDNS account to enable the API and set your API-Token in the configuration. - -https://doc.powerdns.com/md/httpapi/README/ - -``` -export PDNS_Url="http://ns.example.com:8081" -export PDNS_ServerId="localhost" -export PDNS_Token="0123456789ABCDEF" -export PDNS_Ttl=60 -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_pdns -d example.com -d www.example.com -``` - -The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - - -## 6. Use OVH/kimsufi/soyoustart/runabove API to automatically issue cert - -https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api - - -## 7. Use nsupdate to automatically issue cert - -First, generate a key for updating the zone -``` -b=$(dnssec-keygen -a hmac-sha512 -b 512 -n USER -K /tmp foo) -cat > /etc/named/keys/update.key < /etc/knot/acme.key -``` - -Include this key in your knot configuration file. - -``` -include: /etc/knot/acme.key -``` - -Next, configure your zone to allow dynamic updates. - -Dynamic updates for the zone are allowed via proper ACL rule with the `update` action. For in-depth instructions, please see [Knot DNS's documentation](https://www.knot-dns.cz/documentation/). - -``` -acl: - - id: acme_acl - address: 192.168.1.0/24 - key: acme_key - action: update - -zone: - - domain: example.com - file: example.com.zone - acl: acme_acl -``` - -Finally, make the DNS server and TSIG Key available to `acme.sh` - -``` -export KNOT_SERVER="dns.example.com" -export KNOT_KEY=`grep \# /etc/knot/acme.key | cut -d' ' -f2` -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_knot -d example.com -d www.example.com -``` - -The `KNOT_SERVER` and `KNOT_KEY` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 20. Use DigitalOcean API (native) - -You need to obtain a read and write capable API key from your DigitalOcean account. See: https://www.digitalocean.com/help/api/ - -``` -export DO_API_KEY="75310dc4ca779ac39a19f6355db573b49ce92ae126553ebd61ac3a3ae34834cc" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_dgon -d example.com -d www.example.com -``` - -## 21. Use ClouDNS.net API - -You need to set the HTTP API user ID and password credentials. See: https://www.cloudns.net/wiki/article/42/. For security reasons, it's recommended to use a sub user ID that only has access to the necessary zones, as a regular API user has access to your entire account. - -``` -# Use this for a sub auth ID -export CLOUDNS_SUB_AUTH_ID=XXXXX -# Use this for a regular auth ID -#export CLOUDNS_AUTH_ID=XXXXX -export CLOUDNS_AUTH_PASSWORD="YYYYYYYYY" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_cloudns -d example.com -d www.example.com -``` -The `CLOUDNS_AUTH_ID` and `CLOUDNS_AUTH_PASSWORD` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 22. Use Infoblox API - -First you need to create/obtain API credentials on your Infoblox appliance. - -``` -export Infoblox_Creds="username:password" -export Infoblox_Server="ip or fqdn of infoblox appliance" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_infoblox -d example.com -d www.example.com -``` - -Note: This script will automatically create and delete the ephemeral txt record. -The `Infoblox_Creds` and `Infoblox_Server` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - - -## 23. Use VSCALE API - -First you need to create/obtain API tokens on your [settings panel](https://vscale.io/panel/settings/tokens/). - -``` -export VSCALE_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_vscale -d example.com -d www.example.com -``` - -## 24. Use Dynu API - -First you need to create/obtain API credentials from your Dynu account. See: https://www.dynu.com/resources/api/documentation - -``` -export Dynu_ClientId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -export Dynu_Secret="yyyyyyyyyyyyyyyyyyyyyyyyy" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_dynu -d example.com -d www.example.com -``` - -The `Dynu_ClientId` and `Dynu_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 25. Use DNSimple API - -First you need to login to your DNSimple account and generate a new oauth token. - -https://dnsimple.com/a/{your account id}/account/access_tokens - -Note that this is an _account_ token and not a user token. The account token is -needed to infer the `account_id` used in requests. A user token will not be able -to determine the correct account to use. - -``` -export DNSimple_OAUTH_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje" -``` - -To issue the cert just specify the `dns_dnsimple` API. - -``` -acme.sh --issue --dns dns_dnsimple -d example.com -``` - -The `DNSimple_OAUTH_TOKEN` will be saved in `~/.acme.sh/account.conf` and will -be reused when needed. - -If you have any issues with this integration please report them to -https://github.com/pho3nixf1re/acme.sh/issues. - -## 26. Use NS1.com API - -``` -export NS1_Key="fdmlfsdklmfdkmqsdfk" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_nsone -d example.com -d www.example.com -``` - -## 27. Use DuckDNS.org API - -``` -export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" -``` - -Please note that since DuckDNS uses StartSSL as their cert provider, thus ---insecure may need to be used when issuing certs: -``` -acme.sh --insecure --issue --dns dns_duckdns -d mydomain.duckdns.org -``` - -For issues, please report to https://github.com/raidenii/acme.sh/issues. - -## 28. Use Name.com API - -Create your API token here: https://www.name.com/account/settings/api - -Note: `Namecom_Username` should be your Name.com username and not the token name. If you accidentally run the script with the token name as the username see `~/.acme.sh/account.conf` to fix the issue - -``` -export Namecom_Username="testuser" -export Namecom_Token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -``` - -And now you can issue certs with: - -``` -acme.sh --issue --dns dns_namecom -d example.com -d www.example.com -``` - -For issues, please report to https://github.com/raidenii/acme.sh/issues. - -## 29. Use Dyn Managed DNS API to automatically issue cert - -First, login to your Dyn Managed DNS account: https://portal.dynect.net/login/ - -It is recommended to add a new user specific for API access. - -The minimum "Zones & Records Permissions" required are: -``` -RecordAdd -RecordUpdate -RecordDelete -RecordGet -ZoneGet -ZoneAddNode -ZoneRemoveNode -ZonePublish -``` - -Pass the API user credentials to the environment: -``` -export DYN_Customer="customer" -export DYN_Username="apiuser" -export DYN_Password="secret" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_dyn -d example.com -d www.example.com -``` - -The `DYN_Customer`, `DYN_Username` and `DYN_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 30. Use pdd.yandex.ru API - -``` -export PDD_Token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -``` - -Follow these instructions to get the token for your domain https://tech.yandex.com/domain/doc/concepts/access-docpage/ -``` -acme.sh --issue --dns dns_yandex -d mydomain.example.org -``` - -For issues, please report to https://github.com/non7top/acme.sh/issues. - -## 31. Use Hurricane Electric - -Hurricane Electric (https://dns.he.net/) doesn't have an API so just set your login credentials like so: - -``` -export HE_Username="yourusername" -export HE_Password="password" -``` - -Then you can issue your certificate: - -``` -acme.sh --issue --dns dns_he -d example.com -d www.example.com -``` - -The `HE_Username` and `HE_Password` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -Please report any issues to https://github.com/angel333/acme.sh or to . - -## 32. Use UnoEuro API to automatically issue cert - -First you need to login to your UnoEuro account to get your API key. - -``` -export UNO_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -export UNO_User="UExxxxxx" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_unoeuro -d example.com -d www.example.com -``` - -The `UNO_Key` and `UNO_User` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 33. Use INWX - -[INWX](https://www.inwx.de/) offers an [xmlrpc api](https://www.inwx.de/de/help/apidoc) with your standard login credentials, set them like so: - -``` -export INWX_User="yourusername" -export INWX_Password="password" -``` - -Then you can issue your certificates with: - -``` -acme.sh --issue --dns dns_inwx -d example.com -d www.example.com -``` - -The `INWX_User` and `INWX_Password` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -If your account is secured by mobile tan you have also defined the shared secret. - -``` -export INWX_Shared_Secret="shared secret" -``` - -You may need to re-enable the mobile tan to gain the shared secret. - -## 34. User Servercow API v1 - -Create a new user from the servercow control center. Don't forget to activate **DNS API** for this user. - -``` -export SERVERCOW_API_Username=username -export SERVERCOW_API_Password=password -``` - -Now you cann issue a cert: - -``` -acme.sh --issue --dns dns_servercow -d example.com -d www.example.com -``` -Both, `SERVERCOW_API_Username` and `SERVERCOW_API_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 35. Use Namesilo.com API - -You'll need to generate an API key at https://www.namesilo.com/account_api.php -Optionally you may restrict the access to an IP range there. - -``` -export Namesilo_Key="xxxxxxxxxxxxxxxxxxxxxxxx" -``` - -And now you can issue certs with: - -``` -acme.sh --issue --dns dns_namesilo --dnssleep 900 -d example.com -d www.example.com -``` - -## 36. Use autoDNS (InternetX) - -[InternetX](https://www.internetx.com/) offers an [xml api](https://help.internetx.com/display/API/AutoDNS+XML-API) with your standard login credentials, set them like so: - -``` -export AUTODNS_USER="yourusername" -export AUTODNS_PASSWORD="password" -export AUTODNS_CONTEXT="context" -``` - -Then you can issue your certificates with: - -``` -acme.sh --issue --dns dns_autodns -d example.com -d www.example.com -``` - -The `AUTODNS_USER`, `AUTODNS_PASSWORD` and `AUTODNS_CONTEXT` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 37. Use Azure DNS - -You have to create a service principal first. See:[How to use Azure DNS](../../../wiki/How-to-use-Azure-DNS) - -``` -export AZUREDNS_SUBSCRIPTIONID="12345678-9abc-def0-1234-567890abcdef" -export AZUREDNS_TENANTID="11111111-2222-3333-4444-555555555555" -export AZUREDNS_APPID="3b5033b5-7a66-43a5-b3b9-a36b9e7c25ed" -export AZUREDNS_CLIENTSECRET="1b0224ef-34d4-5af9-110f-77f527d561bd" -``` - -Then you can issue your certificates with: - -``` -acme.sh --issue --dns dns_azure -d example.com -d www.example.com -``` - -`AZUREDNS_SUBSCRIPTIONID`, `AZUREDNS_TENANTID`,`AZUREDNS_APPID` and `AZUREDNS_CLIENTSECRET` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 38. Use selectel.com(selectel.ru) domain API to automatically issue cert - -First you need to login to your account to get your API key from: https://my.selectel.ru/profile/apikeys. - -```sh -export SL_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" - -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_selectel -d example.com -d www.example.com -``` - -The `SL_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 39. Use zonomi.com domain API to automatically issue cert - -First you need to login to your account to find your API key from: http://zonomi.com/app/dns/dyndns.jsp - -Your will find your api key in the example urls: - -```sh -https://zonomi.com/app/dns/dyndns.jsp?host=example.com&api_key=1063364558943540954358668888888888 -``` - -```sh -export ZM_Key="1063364558943540954358668888888888" - -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_zonomi -d example.com -d www.example.com -``` - -The `ZM_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 40. Use DreamHost DNS API - -DNS API keys may be created at https://panel.dreamhost.com/?tree=home.api. -Ensure the created key has add and remove privelages. - -``` -export DH_API_KEY="" -acme.sh --issue --dns dns_dreamhost -d example.com -d www.example.com -``` - -The 'DH_API_KEY' will be saved in `~/.acme.sh/account.conf` and will -be reused when needed. - -## 41. Use DirectAdmin API -The DirectAdmin interface has it's own Let's encrypt functionality, but this -script can be used to generate certificates for names which are not hosted on -DirectAdmin - -User must provide login data and URL to the DirectAdmin incl. port. -You can create an user which only has access to - -- CMD_API_DNS_CONTROL -- CMD_API_SHOW_DOMAINS - -By using the Login Keys function. -See also https://www.directadmin.com/api.php and https://www.directadmin.com/features.php?id=1298 - -``` -export DA_Api="https://remoteUser:remotePassword@da.domain.tld:8443" -export DA_Api_Insecure=1 -``` -Set `DA_Api_Insecure` to 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_da -d example.com -d www.example.com -``` - -The `DA_Api` and `DA_Api_Insecure` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 42. Use KingHost DNS API - -API access must be enabled at https://painel.kinghost.com.br/painel.api.php - -``` -export KINGHOST_Username="yourusername" -export KINGHOST_Password="yourpassword" -acme.sh --issue --dns dns_kinghost -d example.com -d *.example.com -``` - -The `KINGHOST_username` and `KINGHOST_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 43. Use Zilore DNS API - -First, get your API key at https://my.zilore.com/account/api - -``` -export Zilore_Key="5dcad3a2-36cb-50e8-cb92-000002f9" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_zilore -d example.com -d *.example.com -``` - -The `Zilore_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 44. Use Loopia.se API -User must provide login credentials to the Loopia API. -The user needs the following permissions: - -- addSubdomain -- updateZoneRecord -- getDomains -- removeSubdomain - -Set the login credentials: -``` -export LOOPIA_User="user@loopiaapi" -export LOOPIA_Password="password" -``` - -And to issue a cert: -``` -acme.sh --issue --dns dns_loopia -d example.com -d *.example.com -``` - -The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -## 45. Use ACME DNS API - -ACME DNS is a limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely. -https://github.com/joohoi/acme-dns - -``` -export ACMEDNS_UPDATE_URL="https://auth.acme-dns.io/update" -export ACMEDNS_USERNAME="" -export ACMEDNS_PASSWORD="" -export ACMEDNS_SUBDOMAIN="" - -acme.sh --issue --dns dns_acmedns -d example.com -d www.example.com -``` - -The credentials will be saved in `~/.acme.sh/account.conf` and will -be reused when needed. -## 46. Use TELE3 API - -First you need to login to your TELE3 account to set your API-KEY. -https://www.tele3.cz/system-acme-api.html - -``` -export TELE3_Key="MS2I4uPPaI..." -export TELE3_Secret="kjhOIHGJKHg" - -acme.sh --issue --dns dns_tele3 -d example.com -d *.example.com -``` - -The TELE3_Key and TELE3_Secret will be saved in ~/.acme.sh/account.conf and will be reused when needed. - -## 47. Use Euserv.eu API - -First you need to login to your euserv.eu account and activate your API Administration (API Verwaltung). -[https://support.euserv.com](https://support.euserv.com) - -Once you've activate, login to your API Admin Interface and create an API account. -Please specify the scope (active groups: domain) and assign the allowed IPs. - -``` -export EUSERV_Username="99999.user123" -export EUSERV_Password="Asbe54gHde" -``` - -Ok, let's issue a cert now: (Be aware to use the `--insecure` flag, cause euserv.eu is still using self-signed certificates!) -``` -acme.sh --issue --dns dns_euserv -d example.com -d *.example.com --insecure -``` - -The `EUSERV_Username` and `EUSERV_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -Please report any issues to https://github.com/initit/acme.sh or to - -## 48. Use DNSPod.com domain API to automatically issue cert - -First you need to get your API Key and ID by this [get-the-user-token](https://www.dnspod.com/docs/info.html#get-the-user-token). - -``` -export DPI_Id="1234" -export DPI_Key="sADDsdasdgdsf" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_dpi -d example.com -d www.example.com -``` - -The `DPI_Id` and `DPI_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 49. Use Google Cloud DNS API to automatically issue cert - -First you need to authenticate to gcloud. - -``` -gcloud init -``` - -**The `dns_gcloud` script uses the active gcloud configuration and credentials.** -There is no logic inside `dns_gcloud` to override the project and other settings. -If needed, create additional [gcloud configurations](https://cloud.google.com/sdk/gcloud/reference/topic/configurations). -You can change the configuration being used without *activating* it; simply set the `CLOUDSDK_ACTIVE_CONFIG_NAME` environment variable. - -To issue a certificate you can: -``` -export CLOUDSDK_ACTIVE_CONFIG_NAME=default # see the note above -acme.sh --issue --dns dns_gcloud -d example.com -d '*.example.com' -``` - -`dns_gcloud` also supports [DNS alias mode](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode). - -## 50. Use ConoHa API - -First you need to login to your ConoHa account to get your API credentials. - -``` -export CONOHA_Username="xxxxxx" -export CONOHA_Password="xxxxxx" -export CONOHA_TenantId="xxxxxx" -export CONOHA_IdentityServiceApi="https://identity.xxxx.conoha.io/v2.0" -``` - -To issue a cert: -``` -acme.sh --issue --dns dns_conoha -d example.com -d www.example.com -``` - -The `CONOHA_Username`, `CONOHA_Password`, `CONOHA_TenantId` and `CONOHA_IdentityServiceApi` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 51. Use netcup DNS API to automatically issue cert - -First you need to login in your CCP account to get your API Key and API Password. -``` -export NC_Apikey="" -export NC_Apipw="" -export NC_CID="" -``` - -Now, let's issue a cert: -``` -acme.sh --issue --dns dns_netcup -d example.com -d www.example.com -``` - -The `NC_Apikey`,`NC_Apipw` and `NC_CID` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -## 52. Use GratisDNS.dk - -GratisDNS.dk (https://gratisdns.dk/) does not provide an API to update DNS records (other than IPv4 and IPv6 -dynamic DNS addresses). The acme.sh plugin therefore retrieves and updates domain TXT records by logging -into the GratisDNS website to read the HTML and posting updates as HTTP. The plugin needs to know your -userid and password for the GratisDNS website. - -```sh -export GDNSDK_Username="..." -export GDNSDK_Password="..." -``` -The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - - -Now you can issue a certificate. - -Note: It usually takes a few minutes (usually 3-4 minutes) before the changes propagates to gratisdns.dk nameservers (ns3.gratisdns.dk often are slow), -and in rare cases I have seen over 5 minutes before google DNS catches it. Therefor a DNS sleep of at least 300 seconds are recommended- - -```sh -acme.sh --issue --dns dns_gdnsdk --dnssleep 300 -d example.com -d *.example.com -``` - -## 53. Use Namecheap - -You will need your namecheap username, API KEY (https://www.namecheap.com/support/api/intro.aspx) and your external IP address (or an URL to get it), this IP will need to be whitelisted at Namecheap. -Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise. - -```sh -export NAMECHEAP_USERNAME="..." -export NAMECHEAP_API_KEY="..." -export NAMECHEAP_SOURCEIP="..." -``` - -NAMECHEAP_SOURCEIP can either be an IP address or an URL to provide it (e.g. https://ifconfig.co/ip). - -The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -Now you can issue a certificate. - -```sh -acme.sh --issue --dns dns_namecheap -d example.com -d *.example.com -``` - -## 54. Use MyDNS.JP API - -First, register to MyDNS.JP and get MasterID and Password. - -``` -export MYDNSJP_MasterID=MasterID -export MYDNSJP_Password=Password -``` - -To issue a certificate: - -``` -acme.sh --issue --dns dns_mydnsjp -d example.com -d www.example.com -``` -The `MYDNSJP_MasterID` and `MYDNSJP_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 55. Use hosting.de API - -Create an API key in your hosting.de account here: https://secure.hosting.de - -The key needs the following rights: -- DNS_ZONES_EDIT -- DNS_ZONES_LIST - -Set your API Key and endpoint: - -``` -export HOSTINGDE_APIKEY='xxx' -export HOSTINGDE_ENDPOINT='https://secure.hosting.de' -``` - -The plugin can also be used for the http.net API. http.net customers have to set endpoint to https://partner.http.net. - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_hostingde -d example.com -d *.example.com -``` - -The hosting.de API key and endpoint will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 56. Use Neodigit.net API - -``` -export NEODIGIT_API_TOKEN="eXJxTkdUVUZmcHQ3QWJackQ4ZGlMejRDSklRYmo5VG5zcFFKK2thYnE0WnVnNnMy" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_neodigit -d example.com -d www.example.com -``` - -Neodigit API Token will be saved in `~/.acme.sh/account.conf` and will be used when needed. - -## 57. Use Exoscale API - -Create an API key and secret key in the Exoscale account section - -Set your API and secret key: - -``` -export EXOSCALE_API_KEY='xxx' -export EXOSCALE_SECRET_KEY='xxx' -``` - -Now, let's issue a cert: -``` -acme.sh --issue --dns dns_exoscale -d example.com -d www.example.com -``` - -The `EXOSCALE_API_KEY` and `EXOSCALE_SECRET_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 58. Using PointHQ API to issue certs - -Log into [PointHQ account management](https://app.pointhq.com/profile) and copy the API key from the page there. - -```export PointHQ_Key="apikeystringgoeshere" -exportPointHQ_Email="accountemail@yourdomain.com" -``` - -You can then issue certs by using: -```acme.sh --issue --dns dns_pointhq -d example.com -d www.example.com -``` - -## 59. Use Active24 API - -Create an API token in the Active24 account section, documentation on https://faq.active24.com/cz/790131-REST-API-rozhran%C3%AD. - -Set your API token: - -``` -export ACTIVE24_Token='xxx' -``` - -Now, let's issue a cert, set `dnssleep` for propagation new DNS record: -``` -acme.sh --issue --dns dns_active24 -d example.com -d www.example.com --dnssleep 1000 -``` - -The `ACTIVE24_Token` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 60. Use do.de API - -Create an API token in your do.de account ([Create token here](https://www.do.de/account/letsencrypt/) | [Documentation](https://www.do.de/wiki/LetsEncrypt_-_Entwickler)). - -Set your API token: -``` -export DO_LETOKEN='FmD408PdqT1E269gUK57' -``` - -To issue a certificate run: -``` -acme.sh --issue --dns dns_doapi -d example.com -d *.example.com -``` - -The API token will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 61. Use Nexcess API - -First, you'll need to login to the [Nexcess.net Client Portal](https://portal.nexcess.net) and [generate a new API token](https://portal.nexcess.net/api-token). - -Once you have a token, set it in your systems environment: - -``` -export NW_API_TOKEN="YOUR_TOKEN_HERE" -export NW_API_ENDPOINT="https://portal.nexcess.net" -``` - -Finally, we'll issue the certificate: (Nexcess DNS publishes at max every 15 minutes, we recommend setting a 900 second `--dnssleep`) - -``` -acme.sh --issue --dns dns_nw -d example.com --dnssleep 900 -``` - -The `NW_API_TOKEN` and `NW_API_ENDPOINT` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 62. Use Thermo.io API - -First, you'll need to login to the [Thermo.io Client Portal](https://core.thermo.io) and [generate a new API token](https://core.thermo.io/api-token). - -Once you have a token, set it in your systems environment: - -``` -export NW_API_TOKEN="YOUR_TOKEN_HERE" -export NW_API_ENDPOINT="https://core.thermo.io" -``` - -Finally, we'll issue the certificate: (Thermo DNS publishes at max every 15 minutes, we recommend setting a 900 second `--dnssleep`) - -``` -acme.sh --issue --dns dns_nw -d example.com --dnssleep 900 -``` - -The `NW_API_TOKEN` and `NW_API_ENDPOINT` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 63. Use Futurehosting API - -First, you'll need to login to the [Futurehosting Client Portal](https://my.futurehosting.com) and [generate a new API token](https://my.futurehosting.com/api-token). - -Once you have a token, set it in your systems environment: - -``` -export NW_API_TOKEN="YOUR_TOKEN_HERE" -export NW_API_ENDPOINT="https://my.futurehosting.com" -``` - -Finally, we'll issue the certificate: (Futurehosting DNS publishes at max every 15 minutes, we recommend setting a 900 second `--dnssleep`) - -``` -acme.sh --issue --dns dns_nw -d example.com --dnssleep 900 -``` - -The `NW_API_TOKEN` and `NW_API_ENDPOINT` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 64. Use Rackspace API - -Set username and API key, which is available under "My Profile & Settings" - -``` -export RACKSPACE_Username='username' -export RACKSPACE_Apikey='xxx' -``` - -Now, let's issue a cert: - -``` -acme.sh --issue --dns dns_rackspace -d example.com -d www.example.com -``` - -## 65. Use Online API - -First, you'll need to retrive your API key, which is available under https://console.online.net/en/api/access - -``` -export ONLINE_API_KEY='xxx' -``` - -To issue a cert run: - -``` -acme.sh --issue --dns dns_online -d example.com -d www.example.com -``` - -`ONLINE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 66. Use MyDevil.net - -Make sure that you can execute own binaries: - -```sh -devil binexec on -``` - -Install acme.sh, or simply `git clone` it into some directory on your MyDevil host account (in which case you should link to it from your `~/bin` directory). - -If you're not using private IP and depend on default IP provided by host, you may want to edit `crontab` too, and make sure that `acme.sh --cron` is run also after reboot (you can find out how to do that on their wiki pages). - -To issue a new certificate, run: - -```sh -acme.sh --issue --dns dns_mydevil -d example.com -d *.example.com -``` - -After certificate is ready, you can install it with [deploy command](../deploy/README.md#14-deploy-your-cert-on-mydevilnet). - -## 67. Use Core-Networks API to automatically issue cert - -First you need to login to your Core-Networks account to to set up an API-User. -Then export username and password to use these credentials. - -``` -export CN_User="user" -export CN_Password="passowrd" -``` - -Ok, let's issue a cert now: -``` -acme.sh --issue --dns dns_cn -d example.com -d www.example.com -``` - -The `CN_User` and `CN_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 68. Use NederHost API - -Create an API token in Mijn NederHost. - -Set your API key: -``` -export NederHost_Key='xxx' -``` - -To issue a certificate run: -``` -acme.sh --issue --dns dns_nederhost -d example.com -d *.example.com -``` - -## 69. Use Zone.ee DNS API - -First, you'll need to retrive your API key. Estonian insructions https://help.zone.eu/kb/zoneid-api-v2/ - -``` -export ZONE_Username=yourusername -export ZONE_Key=keygoeshere -``` - -To issue a cert run: - -``` -acme.sh --issue -d example.com -d www.example.com --dns dns_zone -``` - -`ZONE_Username` and `ZONE_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. - -## 70. Use UltraDNS API - -UltraDNS is a paid for service that provides DNS, as well as Web and Mail forwarding (as well as reporting, auditing, and advanced tools). - -More information can be found here: https://www.security.neustar/lp/ultra20/index.html - -The REST API documentation for this service is found here: https://portal.ultradns.com/static/docs/REST-API_User_Guide.pdf - -Set your UltraDNS User name, and password; these would be the same you would use here: - -https://portal.ultradns.com/ - or if you create an API only user, that username and password would be better utilized. - -``` -export ULTRA_USR="abcd" -export ULTRA_PWD="efgh" - -To issue a cert run: - -acme.sh --issue --dns dns_ultra -d example.com -d www.example.com -``` - -`ULTRA_USR` and `ULTRA_PWD` will be saved in `~/.acme.sh/account.conf` and will be resued when needed. - -# Use custom API - -If your API is not supported yet, you can write your own DNS API. - -Let's assume you want to name it 'myapi': - -1. Create a bash script named `~/.acme.sh/dns_myapi.sh`, -2. In the script you must have a function named `dns_myapi_add()` which will be called by acme.sh to add the DNS records. -3. Then you can use your API to issue cert like this: - -``` -acme.sh --issue --dns dns_myapi -d example.com -d www.example.com -``` - -For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh) - -See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide - -# Use lexicon DNS API - -https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api +https://github.com/Neilpang/acme.sh/wiki/dnsapi From 61bcd67a5d34e0183b421c5d941fa602706e3394 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 20 Mar 2019 23:03:49 +0800 Subject: [PATCH 0222/2234] move to wiki --- deploy/README.md | 411 +---------------------------------------------- 1 file changed, 2 insertions(+), 409 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 8cced4d8..fc633ad7 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,413 +1,6 @@ # Using deploy api -Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert). +deploy hook usage: -Here are the scripts to deploy the certs/key to the server/services. +https://github.com/Neilpang/acme.sh/wiki/deployhooks -## 1. Deploy the certs to your cpanel host - -If you want to deploy using cpanel UAPI see 7. - -(cpanel deploy hook is not finished yet, this is just an example.) - - - -Then you can deploy now: - -```sh -export DEPLOY_CPANEL_USER=myusername -export DEPLOY_CPANEL_PASSWORD=PASSWORD -acme.sh --deploy -d example.com --deploy-hook cpanel -``` - -## 2. Deploy ssl cert on kong proxy engine based on api - -Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert). -Currently supports Kong-v0.10.x. - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook kong -``` - -## 3. Deploy the cert to remote server through SSH access - -The ssh deploy plugin allows you to deploy certificates to a remote host -using SSH command to connect to the remote server. The ssh plugin is invoked -with the following command... - -```sh -acme.sh --deploy -d example.com --deploy-hook ssh -``` -Prior to running this for the first time you must tell the plugin where -and how to deploy the certificates. This is done by exporting the following -environment variables. This is not required for subsequent runs as the -values are stored by acme.sh in the domain configuration files. - -Required... -``` -export DEPLOY_SSH_USER=username -``` -Optional... -``` -export DEPLOY_SSH_CMD=custom ssh command -export DEPLOY_SSH_SERVER=url or ip address of remote host -export DEPLOY_SSH_KEYFILE=filename for private key -export DEPLOY_SSH_CERTFILE=filename for certificate file -export DEPLOY_SSH_CAFILE=filename for intermediate CA file -export DEPLOY_SSH_FULLCHAIN=filename for fullchain file -export DEPLOY_SSH_REMOTE_CMD=command to execute on remote host -export DEPLOY_SSH_BACKUP=yes or no -``` - -**DEPLOY_SSH_USER** -Username at the remote host that SSH will login with. Note that -SSH must be able to login to remote host without a password... SSH Keys -must have been exchanged with the remote host. Validate and test that you -can login to USER@URL from the host running acme.sh before using this script. - -The USER@URL at the remote server must also have has permissions to write to -the target location of the certificate files and to execute any commands -(e.g. to stop/start services). - -**DEPLOY_SSH_CMD** -You can customize the ssh command used to connect to the remote host. For example -if you need to connect to a specific port at the remote server you can set this -to, for example, "ssh -p 22" or to use `sshpass` to provide password inline -instead of exchanging ssh keys (this is not recommended, using keys is -more secure). - -**DEPLOY_SSH_SERVER** -URL or IP Address of the remote server. If not provided then the domain -name provided on the acme.sh --deploy command line is used. - -**DEPLOY_SSH_KEYFILE** -Target filename for the private key issued by LetsEncrypt. - -**DEPLOY_SSH_CERTFILE** -Target filename for the certificate issued by LetsEncrypt. -If this is the same as the previous filename (for keyfile) then it is -appended to the same file. - -**DEPLOY_SSH_CAFILE** -Target filename for the CA intermediate certificate issued by LetsEncrypt. -If this is the same as a previous filename (for keyfile or certfile) then -it is appended to the same file. - -**DEPLOY_SSH_FULLCHAIN** -Target filename for the fullchain certificate issued by LetsEncrypt. -If this is the same as a previous filename (for keyfile, certfile or -cafile) then it is appended to the same file. - -**DEPLOY_SSH_REMOTE_CMD** -Command to execute on the remote server after copying any certificates. This -could be any additional command required for example to stop and restart -the service. - -**DEPLOY_SSH_BACKUP** -Before writing a certificate file to the remote server the existing -certificate will be copied to a backup directory on the remote server. -These are placed in a hidden directory in the home directory of the SSH -user -```sh -~/.acme_ssh_deploy/[domain name]-backup-[timestamp] -``` -Any backups older than 180 days will be deleted when new certificates -are deployed. This defaults to "yes" set to "no" to disable backup. - -###Examples using SSH deploy -The following example illustrates deploying certificates to a QNAP NAS -(tested with QTS version 4.2.3) - -```sh -export DEPLOY_SSH_USER="admin" -export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem" -export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem" -export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem" -export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" - -acme.sh --deploy -d qnap.example.com --deploy-hook ssh -``` -Note how in this example both the private key and certificate point to -the same file. This will result in the certificate being appended -to the same file as the private key... a common requirement of several -services. - -The next example illustrates deploying certificates to a Unifi -Controller (tested with version 5.4.11). - -```sh -export DEPLOY_SSH_USER="root" -export DEPLOY_SSH_KEYFILE="/var/lib/unifi/unifi.example.com.key" -export DEPLOY_SSH_FULLCHAIN="/var/lib/unifi/unifi.example.com.cer" -export DEPLOY_SSH_REMOTE_CMD="openssl pkcs12 -export \ - -inkey /var/lib/unifi/unifi.example.com.key \ - -in /var/lib/unifi/unifi.example.com.cer \ - -out /var/lib/unifi/unifi.example.com.p12 \ - -name ubnt -password pass:temppass \ - && keytool -importkeystore -deststorepass aircontrolenterprise \ - -destkeypass aircontrolenterprise \ - -destkeystore /var/lib/unifi/keystore \ - -srckeystore /var/lib/unifi/unifi.example.com.p12 \ - -srcstoretype PKCS12 -srcstorepass temppass -alias ubnt -noprompt \ - && service unifi restart" - -acme.sh --deploy -d unifi.example.com --deploy-hook ssh -``` -In this example we execute several commands on the remote host -after the certificate files have been copied... to generate a pkcs12 file -compatible with Unifi, to import it into the Unifi keystore and then finally -to restart the service. - -Note also that once the certificate is imported -into the keystore the individual certificate files are no longer -required. We could if we desired delete those files immediately. If we -do that then we should disable backup at the remote host (as there are -no files to backup -- they were erased during deployment). For example... -```sh -export DEPLOY_SSH_BACKUP=no -# modify the end of the remote command... -&& rm /var/lib/unifi/unifi.example.com.key \ - /var/lib/unifi/unifi.example.com.cer \ - /var/lib/unifi/unifi.example.com.p12 \ -&& service unifi restart -``` - -## 4. Deploy the cert to local vsftpd server - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd -``` - -The default vsftpd conf file is `/etc/vsftpd.conf`, if your vsftpd conf is not in the default location, you can specify one: - -```sh -export DEPLOY_VSFTPD_CONF="/etc/vsftpd.conf" - -acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd -``` - -The default command to restart vsftpd server is `service vsftpd restart`, if it doesn't work, you can specify one: - -```sh -export DEPLOY_VSFTPD_RELOAD="/etc/init.d/vsftpd restart" - -acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd -``` - -## 5. Deploy the cert to local exim4 server - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook exim4 -``` - -The default exim4 conf file is `/etc/exim/exim.conf`, if your exim4 conf is not in the default location, you can specify one: - -```sh -export DEPLOY_EXIM4_CONF="/etc/exim4/exim4.conf.template" - -acme.sh --deploy -d ftp.example.com --deploy-hook exim4 -``` - -The default command to restart exim4 server is `service exim4 restart`, if it doesn't work, you can specify one: - -```sh -export DEPLOY_EXIM4_RELOAD="/etc/init.d/exim4 restart" - -acme.sh --deploy -d ftp.example.com --deploy-hook exim4 -``` - -## 6. Deploy the cert to OSX Keychain - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook keychain -``` - -## 7. Deploy to cpanel host using UAPI - -This hook is using UAPI and works in cPanel & WHM version 56 or newer. -``` -acme.sh --deploy -d example.com --deploy-hook cpanel_uapi -``` -DEPLOY_CPANEL_USER is required only if you run the script as root and it should contain cpanel username. -```sh -export DEPLOY_CPANEL_USER=username -acme.sh --deploy -d example.com --deploy-hook cpanel_uapi -``` -Please note, that the cpanel_uapi hook will deploy only the first domain when your certificate will automatically renew. Therefore you should issue a separate certificate for each domain. - -## 8. Deploy the cert to your FRITZ!Box router - -You must specify the credentials that have administrative privileges on the FRITZ!Box in order to deploy the certificate, plus the URL of your FRITZ!Box, through the following environment variables: -```sh -$ export DEPLOY_FRITZBOX_USERNAME=my_username -$ export DEPLOY_FRITZBOX_PASSWORD=the_password -$ export DEPLOY_FRITZBOX_URL=https://fritzbox.example.com -``` - -After the first deployment, these values will be stored in your $HOME/.acme.sh/account.conf. You may now deploy the certificate like this: - -```sh -acme.sh --deploy -d fritzbox.example.com --deploy-hook fritzbox -``` - -## 9. Deploy the cert to strongswan - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook strongswan -``` - -## 10. Deploy the cert to HAProxy - -You must specify the path where you want the concatenated key and certificate chain written. -```sh -export DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy -``` - -You may optionally define the command to reload HAProxy. The value shown below will be used as the default if you don't set this environment variable. - -```sh -export DEPLOY_HAPROXY_RELOAD="/usr/sbin/service haproxy restart" -``` - -You can then deploy the certificate as follows -```sh -acme.sh --deploy -d haproxy.example.com --deploy-hook haproxy -``` - -The path for the PEM file will be stored with the domain configuration and will be available when renewing, so that deploy will happen automatically when renewed. - -## 11. Deploy your cert to Gitlab pages - -You must define the API key and the informations for the project and Gitlab page you are updating the certificate for. - -```sh -# The token can be created in your user settings under "Access Tokens" -export GITLAB_TOKEN="xxxxxxxxxxx" - -# The project ID is displayed on the home page of the project -export GITLAB_PROJECT_ID=12345678 - -# The domain must match the one defined for the Gitlab page, without "https://" -export GITLAB_DOMAIN="www.mydomain.com" -``` - -You can then deploy the certificate as follows - -```sh -acme.sh --deploy -d www.mydomain.com --deploy-hook gitlab -``` - -## 12. Deploy your cert to Hashicorp Vault - -```sh -export VAULT_PREFIX="acme" -``` - -You can then deploy the certificate as follows - -```sh -acme.sh --deploy -d www.mydomain.com --deploy-hook vault_cli -``` - -Your certs will be saved in Vault using this structure: - -```sh -vault write "${VAULT_PREFIX}/${domain}/cert.pem" value=@"..." -vault write "${VAULT_PREFIX}/${domain}/cert.key" value=@"..." -vault write "${VAULT_PREFIX}/${domain}/chain.pem" value=@"..." -vault write "${VAULT_PREFIX}/${domain}/fullchain.pem" value=@"..." -``` - -You might be using Fabio load balancer (which can get certs from -Vault). It needs a bit different structure of your certs in Vault. It -gets certs only from keys that were saved in `prefix/domain`, like this: - -```bash -vault write /www.domain.com cert=@cert.pem key=@key.pem -``` - -If you want to save certs in Vault this way just set "FABIO" env -variable to anything (ex: "1") before running `acme.sh`: - -```sh -export FABIO="1" -``` - -## 13. Deploy your certificate to Qiniu.com - -使用 acme.sh 部署到七牛之前,需要确保部署的域名已打开 HTTPS 功能,您可以访问[融合 CDN - 域名管理](https://portal.qiniu.com/cdn/domain) 设置。 -另外还需要先导出 AK/SK 环境变量,您可以访问[密钥管理](https://portal.qiniu.com/user/key) 获得。 - -```sh -$ export QINIU_AK="foo" -$ export QINIU_SK="bar" -``` - -完成准备工作之后,您就可以通过下面的命令开始部署 SSL 证书到七牛上: - -```sh -$ acme.sh --deploy -d example.com --deploy-hook qiniu -``` - -假如您部署的证书为泛域名证书,您还需要设置 `QINIU_CDN_DOMAIN` 变量,指定实际需要部署的域名(请注意泛域名前的点): - -```sh -$ export QINIU_CDN_DOMAIN=".cdn.example.com" -$ acme.sh --deploy -d example.com --deploy-hook qiniu -``` - -### English version - -You should create AccessKey/SecretKey pair in https://portal.qiniu.com/user/key -before deploying your certificate, and please ensure you have enabled HTTPS for -your domain name. You can enable it in https://portal.qiniu.com/cdn/domain. - -```sh -$ export QINIU_AK="foo" -$ export QINIU_SK="bar" -``` - -then you can deploy certificate by following command: - -```sh -$ acme.sh --deploy -d example.com --deploy-hook qiniu -``` - -(Optional), If you are using wildcard certificate, -you may need export `QINIU_CDN_DOMAIN` to specify which domain -you want to update (please note the leading dot): - -```sh -$ export QINIU_CDN_DOMAIN=".cdn.example.com" -$ acme.sh --deploy -d example.com --deploy-hook qiniu -``` - -## 14. Deploy your cert on MyDevil.net - -Once you have acme.sh installed and certificate issued (see info in [DNS API](../dnsapi/README.md#61-use-mydevilnet)), you can install it by following command: - -```sh -acme.sh --deploy --deploy-hook mydevil -d example.com -``` - -That will remove old certificate and install new one. - -## 15. Deploy your cert to local mailcow server - -You can install your certificates to a local [mailcow](https://github.com/mailcow/mailcow-dockerized/) instance. The -deploy hook will copy the certificates and reload the containers, that use the certificates (`postfix-mailcow` -`dovecot-mailcow` and `nginx-mailcow`). - -```sh -$ export DEPLOY_MAILCOW_PATH="/path/to/mailcow" -$ acme.sh --deploy -d example.com --deploy-hook mailcow -``` - -The default command to restart is `docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow`, if you want a -custom restart command, specify it by setting `DEPLOY_MAILCOW_RELOAD`: - -```sh -$ export DEPLOY_MAILCOW_PATH="/path/to/mailcow" -$ export DEPLOY_MAILCOW_RELOAD="docker-compose restart" -$ acme.sh --deploy -d example.com --deploy-hook mailcow -``` From 16b0704acc635a5e43033d199c3f7ba0208cfbaa Mon Sep 17 00:00:00 2001 From: temoffey Date: Wed, 20 Mar 2019 18:10:53 +0300 Subject: [PATCH 0223/2234] remove readme --- deploy/README.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 76a6cc94..44d53225 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -391,18 +391,3 @@ acme.sh --deploy --deploy-hook mydevil -d example.com ``` That will remove old certificate and install new one. - -## 15. Deploy the cert to G-Core CDN service - -Deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). -Uses command line curl for send requests and jq for parse responses. - -Then you can deploy now: - -```sh -export DEPLOY_GCORE_CDN_USERNAME=myusername -export DEPLOY_GCORE_CDN_PASSWORD=mypassword -acme.sh --deploy -d example.com --deploy-hook gcore_cdn -``` - -Please note, need installed jq. From 236acbd6e8c45f68d0cecc648cd124796ae4427f Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 20 Mar 2019 23:11:13 +0800 Subject: [PATCH 0224/2234] move to wiki --- README.md | 84 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 68d1b57d..6682c556 100644 --- a/README.md +++ b/README.md @@ -290,90 +290,10 @@ If your DNS provider supports API access, we can use that API to automatically i You don't have to do anything manually! -### Currently acme.sh supports: +### Currently acme.sh supports most of the dns providers: -1. CloudFlare.com API -1. DNSPod.cn API -1. CloudXNS.com API -1. GoDaddy.com API -1. PowerDNS.com API -1. OVH, kimsufi, soyoustart and runabove API -1. nsupdate API -1. LuaDNS.com API -1. DNSMadeEasy.com API -1. AWS Route 53 -1. aliyun.com(阿里云) API -1. ISPConfig 3.1 API -1. Alwaysdata.com API -1. Linode.com API -1. FreeDNS (https://freedns.afraid.org/) -1. cyon.ch -1. Domain-Offensive/Resellerinterface/Domainrobot API -1. Gandi LiveDNS API -1. Knot DNS API -1. DigitalOcean API (native) -1. ClouDNS.net API -1. Infoblox NIOS API (https://www.infoblox.com/) -1. VSCALE (https://vscale.io/) -1. Dynu API (https://www.dynu.com) -1. DNSimple API -1. NS1.com API -1. DuckDNS.org API -1. Name.com API -1. Dyn Managed DNS API -1. Yandex PDD API (https://pdd.yandex.ru) -1. Hurricane Electric DNS service (https://dns.he.net) -1. UnoEuro API (https://www.unoeuro.com/) -1. INWX (https://www.inwx.de/) -1. Servercow (https://servercow.de) -1. Namesilo (https://www.namesilo.com) -1. InternetX autoDNS API (https://internetx.com) -1. Azure DNS -1. selectel.com(selectel.ru) DNS API -1. zonomi.com DNS API -1. DreamHost.com API -1. DirectAdmin API -1. KingHost (https://www.kinghost.com.br/) -1. Zilore (https://zilore.com) -1. Loopia.se API -1. acme-dns (https://github.com/joohoi/acme-dns) -1. TELE3 (https://www.tele3.cz) -1. EUSERV.EU (https://www.euserv.eu) -1. DNSPod.com API (https://www.dnspod.com) -1. Google Cloud DNS API -1. ConoHa (https://www.conoha.jp) -1. netcup DNS API (https://www.netcup.de) -1. GratisDNS.dk (https://gratisdns.dk) -1. Namecheap API (https://www.namecheap.com/) -1. MyDNS.JP API (https://www.mydns.jp/) -1. hosting.de (https://www.hosting.de) -1. Neodigit.net API (https://www.neodigit.net) -1. Exoscale.com API (https://www.exoscale.com/) -1. PointDNS API (https://pointhq.com/) -1. Active24.cz API (https://www.active24.cz/) -1. do.de API (https://www.do.de/) -1. Nexcess API (https://www.nexcess.net) -1. Thermo.io API (https://www.thermo.io) -1. Futurehosting API (https://www.futurehosting.com) -1. Rackspace Cloud DNS (https://www.rackspace.com) -1. Online.net API (https://online.net/) -1. MyDevil.net (https://www.mydevil.net/) -1. Core-Networks.de (https://core-networks.de) -1. NederHost API (https://www.nederhost.nl/) -1. Zone.ee (zone.eu) API (https://api.zone.eu/v2) -1. UltraDNS API (https://portal.ultradns.com) +https://github.com/Neilpang/acme.sh/wiki/dnsapi -And: - -**lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api - (DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.)** - - -**More APIs coming soon...** - -If your DNS provider is not on the supported list above, you can write your own DNS API script easily. If you do, please consider submitting a [Pull Request](https://github.com/Neilpang/acme.sh/pulls) and contribute it to the project. - -For more details: [How to use DNS API](dnsapi) # 9. Use DNS manual mode: From 92477800738ceb8d465395ae2365a5404a3e64e2 Mon Sep 17 00:00:00 2001 From: Maximilian Hippler Date: Wed, 20 Mar 2019 22:34:50 +0100 Subject: [PATCH 0225/2234] Added oathtool to Dockerfile --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 68385d7d..5aa8da1a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,7 @@ RUN apk update -f \ curl \ socat \ tzdata \ + && apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing oath-toolkit-oathtool \ && rm -rf /var/cache/apk/* ENV LE_CONFIG_HOME /acme.sh From 3bb97b81ded2d7528cd432d2219df69af5de2870 Mon Sep 17 00:00:00 2001 From: James Qian Date: Thu, 14 Mar 2019 13:26:58 +0800 Subject: [PATCH 0226/2234] dnsapi: add deSEC.io api support Signed-off-by: James Qian --- dnsapi/dns_desec.sh | 204 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 dnsapi/dns_desec.sh diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh new file mode 100644 index 00000000..6488b7fb --- /dev/null +++ b/dnsapi/dns_desec.sh @@ -0,0 +1,204 @@ +#!/usr/bin/env sh +# +# deSEC.io Domain API +# +# Author: Zheng Qian +# +# deSEC API doc +# https://desec.readthedocs.io/en/latest/ + +REST_API="https://desec.io/api/v1/domains" + +######## Public functions ##################### + +#Usage: dns_desec_add _acme-challenge.foobar.dedyn.io "d41d8cd98f00b204e9800998ecf8427e" +dns_desec_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using desec.io api" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + DEDYN_TOKEN="${DEDYN_TOKEN:-$(_readaccountconf_mutable DEDYN_TOKEN)}" + DEDYN_NAME="${DEDYN_NAME:-$(_readaccountconf_mutable DEDYN_NAME)}" + + if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then + DEDYN_TOKEN="" + DEDYN_NAME="" + _err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet." + _err "Please create you key and try again." + _err "e.g." + _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" + _err "export DEDYN_NAME=foobar.dedyn.io" + return 1 + fi + #save the api token and name to the account conf file. + _saveaccountconf_mutable DEDYN_TOKEN "$DEDYN_TOKEN" + _saveaccountconf_mutable DEDYN_NAME "$DEDYN_NAME" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain" "$REST_API/"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # Get existing TXT record + _debug "Getting txt records" + txtvalues="\"\\\"$txtvalue\\\"\"" + _desec_rest GET "$REST_API/$DEDYN_NAME/rrsets/$_sub_domain/TXT/" + + if [ "$_code" = "200" ]; then + oldtxtvalues="$(echo "$response" | _egrep_o "\"records\":\\[\"\\S*\"\\]" | cut -d : -f 2 | tr -d "[]\\\\\"" | sed "s/,/ /g")" + _debug "existing TXT found" + _debug oldtxtvalues "$oldtxtvalues" + if [ -n "$oldtxtvalues" ]; then + for oldtxtvalue in $oldtxtvalues; do + txtvalues="$txtvalues, \"\\\"$oldtxtvalue\\\"\"" + done + fi + fi + _debug txtvalues "$txtvalues" + _info "Adding record" + body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]" + + if _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + + _err "Add txt record error." + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_desec_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using desec.io api" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + DEDYN_TOKEN="${DEDYN_TOKEN:-$(_readaccountconf_mutable DEDYN_TOKEN)}" + DEDYN_NAME="${DEDYN_NAME:-$(_readaccountconf_mutable DEDYN_NAME)}" + + if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then + DEDYN_TOKEN="" + DEDYN_NAME="" + _err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet." + _err "Please create you key and try again." + _err "e.g." + _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" + _err "export DEDYN_NAME=foobar.dedyn.io" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain" "$REST_API/"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # Get existing TXT record + _debug "Getting txt records" + txtvalues="" + _desec_rest GET "$REST_API/$DEDYN_NAME/rrsets/$_sub_domain/TXT/" + + if [ "$_code" = "200" ]; then + oldtxtvalues="$(echo "$response" | _egrep_o "\"records\":\\[\"\\S*\"\\]" | cut -d : -f 2 | tr -d "[]\\\\\"" | sed "s/,/ /g")" + _debug "existing TXT found" + _debug oldtxtvalues "$oldtxtvalues" + if [ -n "$oldtxtvalues" ]; then + for oldtxtvalue in $oldtxtvalues; do + if [ "$txtvalue" != "$oldtxtvalue" ]; then + txtvalues="$txtvalues, \"\\\"$oldtxtvalue\\\"\"" + fi + done + fi + fi + txtvalues="$(echo "$txtvalues" | cut -c3-)" + _debug txtvalues "$txtvalues" + + _info "Deleting record" + body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]" + _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body" + if [ "$_code" = "200" ]; then + _info "Deleted, OK" + return 0 + fi + + _err "Delete txt record error." + return 1 +} + +#################### Private functions below ################################## + +_desec_rest() { + m="$1" + ep="$2" + data="$3" + + export _H1="Authorization: Token $DEDYN_TOKEN" + export _H2="Accept: application/json" + export _H3="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _secure_debug2 data "$data" + response="$(_post "$data" "$ep" "" "$m")" + else + response="$(_get "$ep")" + 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 +} + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain="$1" + ep="$2" + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _desec_rest GET "$ep"; 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 +} From b8489464b3d9600d9f06f363c484256f97140d09 Mon Sep 17 00:00:00 2001 From: temoffey Date: Fri, 22 Mar 2019 03:41:26 +0300 Subject: [PATCH 0227/2234] remove use awk, jq, curl --- deploy/gcore_cdn.sh | 52 +++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 18d137a6..31f8db68 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -27,8 +27,8 @@ gcore_cdn_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _fullchain=$(awk 1 ORS='\\n' "$_cfullchain") - _key=$(awk 1 ORS='\\n' "$_ckey") + _fullchain=$(while read line; do printf "%s" "$line\n"; done < "$_cfullchain") + _key=$(while read line; do printf "%s" "$line\n"; done < "$_ckey") _debug _fullchain "$_fullchain" _debug _key "$_key" @@ -61,43 +61,57 @@ gcore_cdn_deploy() { _info "Get authorization token" _request="{ \"username\": \"$Le_Deploy_gcore_cdn_username\", \"password\": \"$Le_Deploy_gcore_cdn_password\" }" _debug _request "$_request" - _response=$(curl -s -X POST https://api.gcdn.co/auth/signin -H "Content-Type:application/json" -d "$_request") + _H1="Content-Type:application/json" + _response=$(_post "$_request" "https://api.gcdn.co/auth/signin") _debug _response "$_response" - _token=$(echo "$_response" | jq -r '.token') + _regex="\"token\":\"([^\"]+)\"" + _debug _regex "$_regex" + _token=$(if [[ $_response =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) _debug _token "$_token" - if [ "$_token" = "null" ]; then + if [ -z "$_token" ]; then _err "Error G-Core Labs API authorization" return 1 fi _info "Find CDN resource with cname $_cdomain" - _response=$(curl -s -X GET https://api.gcdn.co/resources -H "Authorization:Token $_token") + _H2="Authorization:Token $_token" + _response=$(_get "https://api.gcdn.co/resources") _debug _response "$_response" - _resource=$(echo "$_response" | jq -r ".[] | select(.cname == \"$_cdomain\")") + _regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})" + _debug _regex "$_regex" + _resource=$(if [[ $_response =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) _debug _resource "$_resource" - _resourceId=$(echo "$_resource" | jq -r '.id') - _sslDataOld=$(echo "$_resource" | jq -r '.sslData') - _originGroup=$(echo "$_resource" | jq -r '.originGroup') + _regex="\"id\":([0-9]+)" + _debug _regex "$_regex" + _resourceId=$(if [[ $_resource =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) _debug _resourceId "$_resourceId" + _regex="\"sslData\":([0-9]+|null)" + _debug _regex "$_regex" + _sslDataOld=$(if [[ $_resource =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) _debug _sslDataOld "$_sslDataOld" + _regex="\"originGroup\":([0-9]+)" + _debug _regex "$_regex" + _originGroup=$(if [[ $_resource =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) _debug _originGroup "$_originGroup" - if [ -z "$_resourceId" ] || [ "$_resourceId" = "null" ] || [ -z "$_originGroup" ] || [ "$_originGroup" = "null" ]; then + if [ -z "$_resourceId" ] || [ -z "$_originGroup" ]; then _err "Not found CDN resource with cname $_cdomain" return 1 fi _info "Add new SSL certificate" _date=$(date "+%d.%m.%Y %H:%M:%S") - _request="{ \"name\": \"$_cdomain ($_date)\", \"sslCertificate\": \"$_fullchain\n\", \"sslPrivateKey\": \"$_key\n\" }" + _request="{ \"name\": \"$_cdomain ($_date)\", \"sslCertificate\": \"$_fullchain\", \"sslPrivateKey\": \"$_key\" }" _debug _request "$_request" - _response=$(curl -s -X POST https://api.gcdn.co/sslData -H "Content-Type:application/json" -H "Authorization:Token $_token" -d "$_request") + _response=$(_post "$_request" "https://api.gcdn.co/sslData") _debug _response "$_response" - _sslDataAdd=$(echo "$_response" | jq -r '.id') + _regex="\"id\":([0-9]+)" + _debug _regex "$_regex" + _sslDataAdd=$(if [[ $_response =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) _debug _sslDataAdd "$_sslDataAdd" - if [ "$_sslDataAdd" = "null" ]; then + if [ -z "$_sslDataAdd" ]; then _err "Error new SSL certificate add" return 1 fi @@ -105,9 +119,11 @@ gcore_cdn_deploy() { _info "Update CDN resource" _request="{ \"originGroup\": $_originGroup, \"sslData\": $_sslDataAdd }" _debug _request "$_request" - _response=$(curl -s -X PUT "https://api.gcdn.co/resources/$_resourceId" -H "Content-Type:application/json" -H "Authorization:Token $_token" -d "$_request") + _response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") _debug _response "$_response" - _sslDataNew=$(echo "$_response" | jq -r '.sslData') + _regex="\"sslData\":([0-9]+)" + _debug _regex "$_regex" + _sslDataNew=$(if [[ $_response =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) _debug _sslDataNew "$_sslDataNew" if [ "$_sslDataNew" != "$_sslDataAdd" ]; then @@ -119,7 +135,7 @@ gcore_cdn_deploy() { _info "Not found old SSL certificate" else _info "Delete old SSL certificate" - _response=$(curl -s -X DELETE "https://api.gcdn.co/sslData/$_sslDataOld" -H "Authorization:Token $_token") + _response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE") _debug _response "$_response" fi From d289b0b450a3c4c3a4645ddefb136560f9125deb Mon Sep 17 00:00:00 2001 From: temoffey Date: Fri, 22 Mar 2019 04:21:41 +0300 Subject: [PATCH 0228/2234] fix syntax --- deploy/gcore_cdn.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 31f8db68..439508c2 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -27,8 +27,8 @@ gcore_cdn_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _fullchain=$(while read line; do printf "%s" "$line\n"; done < "$_cfullchain") - _key=$(while read line; do printf "%s" "$line\n"; done < "$_ckey") + _fullchain=$(while read -r line; do printf "%s" "$line\n"; done <"$_cfullchain") + _key=$(while read -r line; do printf "%s" "$line\n"; done <"$_ckey") _debug _fullchain "$_fullchain" _debug _key "$_key" @@ -66,7 +66,7 @@ gcore_cdn_deploy() { _debug _response "$_response" _regex="\"token\":\"([^\"]+)\"" _debug _regex "$_regex" - _token=$(if [[ $_response =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) + _token=$(if [[ $_response =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) _debug _token "$_token" if [ -z "$_token" ]; then @@ -80,19 +80,19 @@ gcore_cdn_deploy() { _debug _response "$_response" _regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})" _debug _regex "$_regex" - _resource=$(if [[ $_response =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) + _resource=$(if [[ $_response =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) _debug _resource "$_resource" _regex="\"id\":([0-9]+)" _debug _regex "$_regex" - _resourceId=$(if [[ $_resource =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) + _resourceId=$(if [[ $_resource =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) _debug _resourceId "$_resourceId" _regex="\"sslData\":([0-9]+|null)" _debug _regex "$_regex" - _sslDataOld=$(if [[ $_resource =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) + _sslDataOld=$(if [[ $_resource =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) _debug _sslDataOld "$_sslDataOld" _regex="\"originGroup\":([0-9]+)" _debug _regex "$_regex" - _originGroup=$(if [[ $_resource =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) + _originGroup=$(if [[ $_resource =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) _debug _originGroup "$_originGroup" if [ -z "$_resourceId" ] || [ -z "$_originGroup" ]; then @@ -108,7 +108,7 @@ gcore_cdn_deploy() { _debug _response "$_response" _regex="\"id\":([0-9]+)" _debug _regex "$_regex" - _sslDataAdd=$(if [[ $_response =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) + _sslDataAdd=$(if [[ $_response =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) _debug _sslDataAdd "$_sslDataAdd" if [ -z "$_sslDataAdd" ]; then @@ -123,7 +123,7 @@ gcore_cdn_deploy() { _debug _response "$_response" _regex="\"sslData\":([0-9]+)" _debug _regex "$_regex" - _sslDataNew=$(if [[ $_response =~ $_regex ]]; then printf "${BASH_REMATCH[1]}"; fi) + _sslDataNew=$(if [[ $_response =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) _debug _sslDataNew "$_sslDataNew" if [ "$_sslDataNew" != "$_sslDataAdd" ]; then From 0ecb5a3fec0b14e410ac4cc6682eae7051651510 Mon Sep 17 00:00:00 2001 From: temoffey Date: Fri, 22 Mar 2019 04:31:58 +0300 Subject: [PATCH 0229/2234] fix syntax --- deploy/gcore_cdn.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 439508c2..2655cbc4 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -61,8 +61,7 @@ gcore_cdn_deploy() { _info "Get authorization token" _request="{ \"username\": \"$Le_Deploy_gcore_cdn_username\", \"password\": \"$Le_Deploy_gcore_cdn_password\" }" _debug _request "$_request" - _H1="Content-Type:application/json" - _response=$(_post "$_request" "https://api.gcdn.co/auth/signin") + _response=$(_H1="Content-Type:application/json" && _post "$_request" "https://api.gcdn.co/auth/signin") _debug _response "$_response" _regex="\"token\":\"([^\"]+)\"" _debug _regex "$_regex" @@ -75,8 +74,7 @@ gcore_cdn_deploy() { fi _info "Find CDN resource with cname $_cdomain" - _H2="Authorization:Token $_token" - _response=$(_get "https://api.gcdn.co/resources") + _response=$(_H1="Content-Type:application/json" && _H2="Authorization:Token $_token" && _get "https://api.gcdn.co/resources") _debug _response "$_response" _regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})" _debug _regex "$_regex" @@ -104,7 +102,7 @@ gcore_cdn_deploy() { _date=$(date "+%d.%m.%Y %H:%M:%S") _request="{ \"name\": \"$_cdomain ($_date)\", \"sslCertificate\": \"$_fullchain\", \"sslPrivateKey\": \"$_key\" }" _debug _request "$_request" - _response=$(_post "$_request" "https://api.gcdn.co/sslData") + _response=$(_H1="Content-Type:application/json" && _H2="Authorization:Token $_token" && _post "$_request" "https://api.gcdn.co/sslData") _debug _response "$_response" _regex="\"id\":([0-9]+)" _debug _regex "$_regex" @@ -119,7 +117,7 @@ gcore_cdn_deploy() { _info "Update CDN resource" _request="{ \"originGroup\": $_originGroup, \"sslData\": $_sslDataAdd }" _debug _request "$_request" - _response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") + _response=$(_H1="Content-Type:application/json" && _H2="Authorization:Token $_token" && _post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") _debug _response "$_response" _regex="\"sslData\":([0-9]+)" _debug _regex "$_regex" @@ -135,7 +133,7 @@ gcore_cdn_deploy() { _info "Not found old SSL certificate" else _info "Delete old SSL certificate" - _response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE") + _response=$(_H1="Content-Type:application/json" && _H2="Authorization:Token $_token" && _post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE") _debug _response "$_response" fi From 8896642e2541265a4627792b922204129d6c9cca Mon Sep 17 00:00:00 2001 From: temoffey Date: Fri, 22 Mar 2019 20:01:39 +0300 Subject: [PATCH 0230/2234] fix syntax --- deploy/gcore_cdn.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 2655cbc4..f9ed6c7d 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -61,7 +61,8 @@ gcore_cdn_deploy() { _info "Get authorization token" _request="{ \"username\": \"$Le_Deploy_gcore_cdn_username\", \"password\": \"$Le_Deploy_gcore_cdn_password\" }" _debug _request "$_request" - _response=$(_H1="Content-Type:application/json" && _post "$_request" "https://api.gcdn.co/auth/signin") + export _H1="Content-Type:application/json" + _response=$(_post "$_request" "https://api.gcdn.co/auth/signin") _debug _response "$_response" _regex="\"token\":\"([^\"]+)\"" _debug _regex "$_regex" @@ -74,7 +75,8 @@ gcore_cdn_deploy() { fi _info "Find CDN resource with cname $_cdomain" - _response=$(_H1="Content-Type:application/json" && _H2="Authorization:Token $_token" && _get "https://api.gcdn.co/resources") + export _H2="Authorization:Token $_token" + _response=$(_get "https://api.gcdn.co/resources") _debug _response "$_response" _regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})" _debug _regex "$_regex" @@ -102,7 +104,7 @@ gcore_cdn_deploy() { _date=$(date "+%d.%m.%Y %H:%M:%S") _request="{ \"name\": \"$_cdomain ($_date)\", \"sslCertificate\": \"$_fullchain\", \"sslPrivateKey\": \"$_key\" }" _debug _request "$_request" - _response=$(_H1="Content-Type:application/json" && _H2="Authorization:Token $_token" && _post "$_request" "https://api.gcdn.co/sslData") + _response=$(_post "$_request" "https://api.gcdn.co/sslData") _debug _response "$_response" _regex="\"id\":([0-9]+)" _debug _regex "$_regex" @@ -117,7 +119,7 @@ gcore_cdn_deploy() { _info "Update CDN resource" _request="{ \"originGroup\": $_originGroup, \"sslData\": $_sslDataAdd }" _debug _request "$_request" - _response=$(_H1="Content-Type:application/json" && _H2="Authorization:Token $_token" && _post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") + _response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") _debug _response "$_response" _regex="\"sslData\":([0-9]+)" _debug _regex "$_regex" @@ -133,7 +135,7 @@ gcore_cdn_deploy() { _info "Not found old SSL certificate" else _info "Delete old SSL certificate" - _response=$(_H1="Content-Type:application/json" && _H2="Authorization:Token $_token" && _post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE") + _response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE") _debug _response "$_response" fi From 4b6e7e6c371a7945e2b3304ff7241bf05691d453 Mon Sep 17 00:00:00 2001 From: temoffey Date: Fri, 22 Mar 2019 20:02:59 +0300 Subject: [PATCH 0231/2234] remove use while, [[ ]], array --- deploy/gcore_cdn.sh | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index f9ed6c7d..f0cc43ec 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -27,8 +27,8 @@ gcore_cdn_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _fullchain=$(while read -r line; do printf "%s" "$line\n"; done <"$_cfullchain") - _key=$(while read -r line; do printf "%s" "$line\n"; done <"$_ckey") + _fullchain=$(cat "$_cfullchain" | tr '\n\r' '@#' | sed 's/@/\\n/g;s/#/\\r/g') + _key=$(cat "$_ckey" | tr '\n\r' '@#' | sed 's/@/\\n/g;s/#/\\r/g') _debug _fullchain "$_fullchain" _debug _key "$_key" @@ -59,14 +59,14 @@ gcore_cdn_deploy() { fi _info "Get authorization token" - _request="{ \"username\": \"$Le_Deploy_gcore_cdn_username\", \"password\": \"$Le_Deploy_gcore_cdn_password\" }" + _request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}" _debug _request "$_request" export _H1="Content-Type:application/json" _response=$(_post "$_request" "https://api.gcdn.co/auth/signin") _debug _response "$_response" - _regex="\"token\":\"([^\"]+)\"" + _regex=".*\"token\":\"\([-._0-9A-Za-z]*\)\".*$" _debug _regex "$_regex" - _token=$(if [[ $_response =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) + _token=$(echo "$_response" | sed -n "s/$_regex/\1/p") _debug _token "$_token" if [ -z "$_token" ]; then @@ -79,20 +79,21 @@ gcore_cdn_deploy() { _response=$(_get "https://api.gcdn.co/resources") _debug _response "$_response" _regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})" + _regex="\"cname\":\"$_cdomain\"" _debug _regex "$_regex" - _resource=$(if [[ $_response =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) + _resource=$(echo "$_response" | sed 's/},{/},\n{/g' | grep -E "$_regex") _debug _resource "$_resource" - _regex="\"id\":([0-9]+)" + _regex=".*\"id\":\([0-9]*\),.*$" _debug _regex "$_regex" - _resourceId=$(if [[ $_resource =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) + _resourceId=$(echo "$_resource" | sed -n "s/$_regex/\1/p") _debug _resourceId "$_resourceId" - _regex="\"sslData\":([0-9]+|null)" + _regex=".*\"sslData\":\([0-9]*\)}.*$" _debug _regex "$_regex" - _sslDataOld=$(if [[ $_resource =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) + _sslDataOld=$(echo "$_resource" | sed -n "s/$_regex/\1/p") _debug _sslDataOld "$_sslDataOld" - _regex="\"originGroup\":([0-9]+)" + _regex=".*\"originGroup\":\([0-9]*\),.*$" _debug _regex "$_regex" - _originGroup=$(if [[ $_resource =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) + _originGroup=$(echo "$_resource" | sed -n "s/$_regex/\1/p") _debug _originGroup "$_originGroup" if [ -z "$_resourceId" ] || [ -z "$_originGroup" ]; then @@ -102,13 +103,13 @@ gcore_cdn_deploy() { _info "Add new SSL certificate" _date=$(date "+%d.%m.%Y %H:%M:%S") - _request="{ \"name\": \"$_cdomain ($_date)\", \"sslCertificate\": \"$_fullchain\", \"sslPrivateKey\": \"$_key\" }" + _request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}" _debug _request "$_request" _response=$(_post "$_request" "https://api.gcdn.co/sslData") _debug _response "$_response" - _regex="\"id\":([0-9]+)" + _regex=".*\"id\":\([0-9]*\),.*$" _debug _regex "$_regex" - _sslDataAdd=$(if [[ $_response =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) + _sslDataAdd=$(echo "$_response" | sed -n "s/$_regex/\1/p") _debug _sslDataAdd "$_sslDataAdd" if [ -z "$_sslDataAdd" ]; then @@ -117,13 +118,13 @@ gcore_cdn_deploy() { fi _info "Update CDN resource" - _request="{ \"originGroup\": $_originGroup, \"sslData\": $_sslDataAdd }" + _request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}" _debug _request "$_request" _response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") _debug _response "$_response" - _regex="\"sslData\":([0-9]+)" + _regex=".*\"sslData\":\([0-9]*\)}.*$" _debug _regex "$_regex" - _sslDataNew=$(if [[ $_response =~ $_regex ]]; then printf "%s" "${BASH_REMATCH[1]}"; fi) + _sslDataNew=$(echo "$_response" | sed -n "s/$_regex/\1/p") _debug _sslDataNew "$_sslDataNew" if [ "$_sslDataNew" != "$_sslDataAdd" ]; then From bd1bb7a71bf79daa70db446995c9ca54517f57e2 Mon Sep 17 00:00:00 2001 From: temoffey Date: Fri, 22 Mar 2019 20:08:35 +0300 Subject: [PATCH 0232/2234] fix syntax --- deploy/gcore_cdn.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index f0cc43ec..40fbf480 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -27,8 +27,8 @@ gcore_cdn_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _fullchain=$(cat "$_cfullchain" | tr '\n\r' '@#' | sed 's/@/\\n/g;s/#/\\r/g') - _key=$(cat "$_ckey" | tr '\n\r' '@#' | sed 's/@/\\n/g;s/#/\\r/g') + _fullchain=$(tr '\n\r' '@#' <"$_cfullchain" | sed 's/@/\\n/g;s/#/\\r/g') + _key=$(tr '\n\r' '@#' <"$_ckey" | sed 's/@/\\n/g;s/#/\\r/g') _debug _fullchain "$_fullchain" _debug _key "$_key" From df9174577a503811973c5d185abc5f3000736a2a Mon Sep 17 00:00:00 2001 From: temoffey Date: Fri, 22 Mar 2019 23:00:47 +0300 Subject: [PATCH 0233/2234] remove check jq --- deploy/gcore_cdn.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 40fbf480..b38226f4 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -53,11 +53,6 @@ gcore_cdn_deploy() { _savedomainconf Le_Deploy_gcore_cdn_password "$Le_Deploy_gcore_cdn_password" fi - if ! [ -x "$(command -v jq)" ]; then - _err "Please install the package jq: sudo apt-get install jq" - return 1 - fi - _info "Get authorization token" _request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}" _debug _request "$_request" From 189a7766d4fc4684ba971147474a7dd3187a29dd Mon Sep 17 00:00:00 2001 From: Charles Surett Date: Fri, 22 Mar 2019 18:43:06 -0400 Subject: [PATCH 0234/2234] Made dns_dgon.sh use _lower_case Fixed private function which breaks on embedded systems before. --- dnsapi/dns_dgon.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh index 24e1a9f2..c176afd3 100755 --- a/dnsapi/dns_dgon.sh +++ b/dnsapi/dns_dgon.sh @@ -178,7 +178,7 @@ dns_dgon_rm() { ## _domain="domain.com" _get_base_domain() { # args - fulldomain="$(echo "$1" | tr '[:upper:]' '[:lower:]')" + fulldomain="$(echo "$1" | _lower_case)" _debug fulldomain "$fulldomain" # domain max legal length = 253 From bea52aa7435d57733be37fe45bd06938c8ffab0f Mon Sep 17 00:00:00 2001 From: temoffey Date: Sat, 23 Mar 2019 16:29:33 +0300 Subject: [PATCH 0235/2234] remove use grep -E --- deploy/gcore_cdn.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index b38226f4..56ca9afd 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -74,9 +74,9 @@ gcore_cdn_deploy() { _response=$(_get "https://api.gcdn.co/resources") _debug _response "$_response" _regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})" - _regex="\"cname\":\"$_cdomain\"" + _regex="^.*\"cname\":\"$_cdomain\".*$" _debug _regex "$_regex" - _resource=$(echo "$_response" | sed 's/},{/},\n{/g' | grep -E "$_regex") + _resource=$(echo "$_response" | sed 's/},{/},\n{/g' | _egrep_o "$_regex") _debug _resource "$_resource" _regex=".*\"id\":\([0-9]*\),.*$" _debug _regex "$_regex" From 978ec91107db6adb140a33141577de2119db5822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Toki=C4=87?= Date: Tue, 5 Mar 2019 20:16:54 +0100 Subject: [PATCH 0236/2234] Extract configuration loading code to function --- dnsapi/dns_loopia.sh | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index ece5ef8c..a66a443a 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -14,13 +14,7 @@ dns_loopia_add() { fulldomain=$1 txtvalue=$2 - LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}" - LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}" - if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then - LOOPIA_User="" - LOOPIA_Password="" - _err "You don't specify loopia user and password yet." - _err "Please create you key and try again." + if ! _loopia_load_config; then return 1 fi @@ -47,13 +41,7 @@ dns_loopia_rm() { fulldomain=$1 txtvalue=$2 - LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}" - LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}" - if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then - LOOPIA_User="" - LOOPIA_Password="" - _err "You don't specify LOOPIA user and password yet." - _err "Please create you key and try again." + if ! _loopia_load_config; then return 1 fi @@ -96,6 +84,23 @@ dns_loopia_rm() { #################### Private functions below ################################## +_loopia_load_config() { + LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}" + LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}" + + if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then + LOOPIA_User="" + LOOPIA_Password="" + + _err "You don't specify loopia user and password yet." + _err "Please create you key and try again." + + return 1 + fi + + return 0 +} + _loopia_get_records() { domain=$1 sub_domain=$2 From a7d614616997d6e109b30711c804d194d5a68fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Toki=C4=87?= Date: Tue, 5 Mar 2019 20:21:14 +0100 Subject: [PATCH 0237/2234] Extract configuration saving code to function --- dnsapi/dns_loopia.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index a66a443a..92556e7e 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -18,9 +18,7 @@ dns_loopia_add() { return 1 fi - #save the api key and email to the account conf file. - _saveaccountconf_mutable LOOPIA_User "$LOOPIA_User" - _saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password" + _loopia_save_config _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -45,9 +43,7 @@ dns_loopia_rm() { return 1 fi - #save the api key and email to the account conf file. - _saveaccountconf_mutable LOOPIA_User "$LOOPIA_User" - _saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password" + _loopia_save_config _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -101,6 +97,11 @@ _loopia_load_config() { return 0 } +_loopia_save_config() { + _saveaccountconf_mutable LOOPIA_User "$LOOPIA_User" + _saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password" +} + _loopia_get_records() { domain=$1 sub_domain=$2 From 85be2b85fd9103efc391f0c08de73d59638aa7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Toki=C4=87?= Date: Tue, 5 Mar 2019 21:10:11 +0100 Subject: [PATCH 0238/2234] Fix error message language --- dnsapi/dns_loopia.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 92556e7e..e8d19d15 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -88,8 +88,8 @@ _loopia_load_config() { LOOPIA_User="" LOOPIA_Password="" - _err "You don't specify loopia user and password yet." - _err "Please create you key and try again." + _err "A valid Loopia API user and password not provided." + _err "Please provide a valid API user and try again." return 1 fi From 0daa225e2641da94d0045e4974b6af9ba91effc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Toki=C4=87?= Date: Tue, 5 Mar 2019 20:56:34 +0100 Subject: [PATCH 0239/2234] Make the Loopia API endpoint configurable Loopia provides hosting in several countries. Each hosting location has it's own API endpoint, such as "https://api.loopia./RPCSERV", where is one of: com, no, rs, se. The current LOOPIA_Api variable is hard-coded to ".se". This prevents using the Loopia DNS API on other hosting locations. This commit makes the LOOPIA_Api variable configurable and it falls back to ".se" TLD if LOOPIA_Api is not set. References: - https://www.loopia.com/api/authentication/ - https://www.loopia.no/api/authentication/ - https://www.loopia.rs/api/authentication/ - https://www.loopia.se/api/authentication/ --- dnsapi/dns_loopia.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index e8d19d15..109507ca 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -4,8 +4,10 @@ #LOOPIA_User="username" # #LOOPIA_Password="password" +# +#LOOPIA_Api="https://api.loopia./RPCSERV" -LOOPIA_Api="https://api.loopia.se/RPCSERV" +LOOPIA_Api_Default="https://api.loopia.se/RPCSERV" ######## Public functions ##################### @@ -81,9 +83,14 @@ dns_loopia_rm() { #################### Private functions below ################################## _loopia_load_config() { + LOOPIA_Api="${LOOPIA_Api:-$(_readaccountconf_mutable LOOPIA_Api)}" LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}" LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}" + if [ -z "$LOOPIA_Api" ]; then + LOOPIA_Api="$LOOPIA_Api_Default" + fi + if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then LOOPIA_User="" LOOPIA_Password="" @@ -98,6 +105,9 @@ _loopia_load_config() { } _loopia_save_config() { + if [ "$LOOPIA_Api" != "$LOOPIA_Api_Default" ]; then + _saveaccountconf_mutable LOOPIA_Api "$LOOPIA_Api" + fi _saveaccountconf_mutable LOOPIA_User "$LOOPIA_User" _saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password" } From aec9c3c9a4820dbd05660bffc074c95f3aee77a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Toki=C4=87?= Date: Thu, 28 Mar 2019 16:34:13 +0100 Subject: [PATCH 0240/2234] Double quote unquoted variables Double quote unquoted variables to prevent globbing and word splitting. --- dnsapi/dns_loopia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 109507ca..1316a274 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -70,7 +70,7 @@ dns_loopia_rm() { %s - ' $LOOPIA_User $LOOPIA_Password "$_domain" "$_sub_domain") + ' "$LOOPIA_User" "$LOOPIA_Password" "$_domain" "$_sub_domain") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" From 16db9a7337ffbcfa5c8610a13fdedd66a5f4b956 Mon Sep 17 00:00:00 2001 From: Stephane Moser Date: Fri, 29 Mar 2019 14:12:34 +0000 Subject: [PATCH 0241/2234] Add --dnsslowrate arg --- acme.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index f47a5ebb..47d11002 100755 --- a/acme.sh +++ b/acme.sh @@ -3974,9 +3974,16 @@ $_authorizations_map" return 1 fi - if ! $addcommand "$txtdomain" "$txt"; then - _err "Error add txt for domain:$txtdomain" - return 1 + if [ "$addcommand" = "dns_aws_add" -a -n "$_dnsslowrate" ] ; then + if ! $addcommand "$txtdomain" "$txt" "$_dnsslowrate"; then + _err "Error add txt for domain:$txtdomain" + return 1 + fi + else + if ! $addcommand "$txtdomain" "$txt"; then + _err "Error add txt for domain:$txtdomain" + return 1 + fi fi ) @@ -5919,6 +5926,7 @@ _process() { _httpport="" _tlsport="" _dnssleep="" + _dnsslowrate="" _listraw="" _stopRenewOnError="" #_insecure="" @@ -6158,6 +6166,12 @@ _process() { _webroot="$_webroot,$wvalue" fi ;; + + --dnsslowrate) + _dnsslowrate="$2" + shift + ;; + --dnssleep) _dnssleep="$2" Le_DNSSleep="$_dnssleep" From 3021c5cfadcf815c312857d9f27003071d331bdf Mon Sep 17 00:00:00 2001 From: Stephane Moser Date: Fri, 29 Mar 2019 14:12:50 +0000 Subject: [PATCH 0242/2234] Use dnsslowrate arg --- dnsapi/dns_aws.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 2ad3c819..35781eb1 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -18,6 +18,7 @@ AWS_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API dns_aws_add() { fulldomain=$1 txtvalue=$2 + slowrateslepp=$3 AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}" AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}" @@ -72,6 +73,10 @@ dns_aws_add() { if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then _info "TXT record updated successfully." + if [ -n "$slowrateslepp" ]; then + _info "Slow rate activated: sleeping for $slowrateslepp seconds" + sleep $slowrateslepp + fi return 0 fi From 8902a5c5cd558a18b2d4a0beb5b23fc013e9f459 Mon Sep 17 00:00:00 2001 From: Stephane Moser Date: Fri, 29 Mar 2019 14:33:15 +0000 Subject: [PATCH 0243/2234] Revert "Add --dnsslowrate arg" This reverts commit 16db9a7337ffbcfa5c8610a13fdedd66a5f4b956. --- acme.sh | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/acme.sh b/acme.sh index 47d11002..f47a5ebb 100755 --- a/acme.sh +++ b/acme.sh @@ -3974,16 +3974,9 @@ $_authorizations_map" return 1 fi - if [ "$addcommand" = "dns_aws_add" -a -n "$_dnsslowrate" ] ; then - if ! $addcommand "$txtdomain" "$txt" "$_dnsslowrate"; then - _err "Error add txt for domain:$txtdomain" - return 1 - fi - else - if ! $addcommand "$txtdomain" "$txt"; then - _err "Error add txt for domain:$txtdomain" - return 1 - fi + if ! $addcommand "$txtdomain" "$txt"; then + _err "Error add txt for domain:$txtdomain" + return 1 fi ) @@ -5926,7 +5919,6 @@ _process() { _httpport="" _tlsport="" _dnssleep="" - _dnsslowrate="" _listraw="" _stopRenewOnError="" #_insecure="" @@ -6166,12 +6158,6 @@ _process() { _webroot="$_webroot,$wvalue" fi ;; - - --dnsslowrate) - _dnsslowrate="$2" - shift - ;; - --dnssleep) _dnssleep="$2" Le_DNSSleep="$_dnssleep" From ea6a3c0963f3f7c2edff82691d05f92f6406302a Mon Sep 17 00:00:00 2001 From: Stephane Moser Date: Fri, 29 Mar 2019 14:39:32 +0000 Subject: [PATCH 0244/2234] Use AWS_DNS_SLOWRATE env variable instead of arg --- dnsapi/dns_aws.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 35781eb1..91bc7d09 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -18,7 +18,7 @@ AWS_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API dns_aws_add() { fulldomain=$1 txtvalue=$2 - slowrateslepp=$3 + slowrateslepp=$AWS_DNS_SLOWRATE AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}" AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}" @@ -87,6 +87,7 @@ dns_aws_add() { dns_aws_rm() { fulldomain=$1 txtvalue=$2 + slowrateslepp=$AWS_DNS_SLOWRATE AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}" AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}" @@ -121,6 +122,10 @@ dns_aws_rm() { if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then _info "TXT record deleted successfully." + if [ -n "$slowrateslepp" ]; then + _info "Slow rate activated: sleeping for $slowrateslepp seconds" + sleep $slowrateslepp + fi return 0 fi From c2d0d4d28c86b3edeb2321f6ea98e9ffbd22fccf Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 31 Mar 2019 21:46:14 +0800 Subject: [PATCH 0245/2234] root domain as dns alias mode --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 532199f3..96731435 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -147,7 +147,7 @@ dns_cf_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From aeed2871223b39eecf59917e19e1155e634588f2 Mon Sep 17 00:00:00 2001 From: Stephane Moser Date: Tue, 2 Apr 2019 10:27:22 +0100 Subject: [PATCH 0246/2234] Add Double quote to slowrateslepp --- 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 91bc7d09..cb4de878 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -75,7 +75,7 @@ dns_aws_add() { _info "TXT record updated successfully." if [ -n "$slowrateslepp" ]; then _info "Slow rate activated: sleeping for $slowrateslepp seconds" - sleep $slowrateslepp + sleep "$slowrateslepp" fi return 0 fi @@ -124,7 +124,7 @@ dns_aws_rm() { _info "TXT record deleted successfully." if [ -n "$slowrateslepp" ]; then _info "Slow rate activated: sleeping for $slowrateslepp seconds" - sleep $slowrateslepp + sleep "$slowrateslepp" fi return 0 fi From 6e917d156c0abcf7f3ebc0c8d008af44a8cba45f Mon Sep 17 00:00:00 2001 From: Gorbachev Date: Tue, 2 Apr 2019 18:05:52 +0300 Subject: [PATCH 0247/2234] Trim double quotes for email and key Currently dns_cf generates headers like this: 'X-Auth-Email: "sample@mail.com"'. Cloudflare API responses 400 BadRequest for quoted headers with message "Invalid format for X-Auth-Email header". --- dnsapi/dns_cf.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 532199f3..73089978 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -182,8 +182,11 @@ _cf_rest() { data="$3" _debug "$ep" - export _H1="X-Auth-Email: $CF_Email" - export _H2="X-Auth-Key: $CF_Key" + email_trimmed=$(echo $CF_Email | tr -d '"') + key_trimmed=$(echo $CF_Key | tr -d '"') + + export _H1="X-Auth-Email: $email_trimmed" + export _H2="X-Auth-Key: $key_trimmed" export _H3="Content-Type: application/json" if [ "$m" != "GET" ]; then From 987f95221c66abcd2a439102096d87510004de74 Mon Sep 17 00:00:00 2001 From: Kimmax Date: Tue, 2 Apr 2019 23:08:39 +0000 Subject: [PATCH 0248/2234] Added missing "templateValues" object to "zoneConfig" on "_hostingde_getZoneConfig" --- dnsapi/dns_hostingde.sh | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 1819e639..4cfe33fb 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -53,6 +53,18 @@ _hostingde_parse() { fi } +_hostingde_parse_no_strip_whitespace() { + find="${1}" + if [ "${2}" ]; then + notfind="${2}" + fi + if [ "${notfind}" ]; then + _egrep_o \""${find}\":.*" | grep -v "${notfind}" | cut -d ':' -f 2 | cut -d ',' -f 1 + else + _egrep_o \""${find}\":.*" | cut -d ':' -f 2 | cut -d ',' -f 1 + fi +} + _hostingde_getZoneConfig() { _info "Getting ZoneConfig" curZone="${fulldomain#*.}" @@ -85,6 +97,22 @@ _hostingde_getZoneConfig() { zoneConfigDnsServerGroupId=$(echo "${curResult}" | _hostingde_parse "dnsServerGroupId") zoneConfigEmailAddress=$(echo "${curResult}" | _hostingde_parse "emailAddress") zoneConfigDnsSecMode=$(echo "${curResult}" | _hostingde_parse "dnsSecMode") + zoneConfigTemplateValues=$(echo "${curResult}" | _hostingde_parse_object "templateValues") + + if [ "$zoneConfigTemplateValues" != "null" ]; then + _debug "Zone is tied to a template." + zoneConfigTemplateValuesTemplateId=$(echo "${curResult}" | _hostingde_parse "templateId") + zoneConfigTemplateValuesTemplateName=$(echo "${curResult}" | _hostingde_parse_no_strip_whitespace "templateName") + zoneConfigTemplateValuesTemplateReplacementsIPv4=$(echo "${curResult}" | _hostingde_parse "ipv4Replacement") + zoneConfigTemplateValuesTemplateReplacementsIPv6=$(echo "${curResult}" | _hostingde_parse "ipv6Replacement") + zoneConfigTemplateValuesTemplateReplacementsMailIPv4=$(echo "${curResult}" | _hostingde_parse "mailIpv4Replacement") + zoneConfigTemplateValuesTemplateReplacementsMailIPv6=$(echo "${curResult}" | _hostingde_parse "mailIpv6Replacement") + zoneConfigTemplateValuesTemplateTieToTemplate=$(echo "${curResult}" | _hostingde_parse "tieToTemplate") + + zoneConfigTemplateValues="{\"templateId\":${zoneConfigTemplateValuesTemplateId},\"templateName\":${zoneConfigTemplateValuesTemplateName},\"templateReplacements\":{\"ipv4Replacement\":${zoneConfigTemplateValuesTemplateReplacementsIPv4},\"ipv6Replacement\":${zoneConfigTemplateValuesTemplateReplacementsIPv6},\"mailIpv4Replacement\":${zoneConfigTemplateValuesTemplateReplacementsMailIPv4},\"mailIpv6Replacement\":${zoneConfigTemplateValuesTemplateReplacementsMailIPv6}},\"tieToTemplate\":${zoneConfigTemplateValuesTemplateTieToTemplate}}" + _debug "Template values: '{$zoneConfigTemplateValues}'" + fi + if [ "${zoneConfigType}" != "\"NATIVE\"" ]; then _err "Zone is not native" returnCode=1 @@ -122,7 +150,7 @@ _hostingde_addRecord() { _hostingde_getZoneStatus _debug "Result of zoneStatus: '${zoneStatus}'" done - curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}" + curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}},\"templateValues\":${zoneConfigTemplateValues}},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}" curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" _debug "Result of zoneUpdate: '$curResult'" From 64e53927880732978cf3702b6afa792156ae4db3 Mon Sep 17 00:00:00 2001 From: Kimmax Date: Tue, 2 Apr 2019 23:29:58 +0000 Subject: [PATCH 0249/2234] Zone delete also needs new "templateValues" field --- dnsapi/dns_hostingde.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 4cfe33fb..1aa70394 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -97,7 +97,7 @@ _hostingde_getZoneConfig() { zoneConfigDnsServerGroupId=$(echo "${curResult}" | _hostingde_parse "dnsServerGroupId") zoneConfigEmailAddress=$(echo "${curResult}" | _hostingde_parse "emailAddress") zoneConfigDnsSecMode=$(echo "${curResult}" | _hostingde_parse "dnsSecMode") - zoneConfigTemplateValues=$(echo "${curResult}" | _hostingde_parse_object "templateValues") + zoneConfigTemplateValues=$(echo "${curResult}" | _hostingde_parse_no_strip_whitespace "templateValues") if [ "$zoneConfigTemplateValues" != "null" ]; then _debug "Zone is tied to a template." @@ -174,7 +174,7 @@ _hostingde_removeRecord() { _hostingde_getZoneStatus _debug "Result of zoneStatus: '$zoneStatus'" done - curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}" + curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}},\"templateValues\":${zoneConfigTemplateValues}},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}" curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")" _debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'" _debug "Result of zoneUpdate: '$curResult'" From eda321954dfb31ecf18dbe41e0123dd329592cd1 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 6 Apr 2019 16:05:08 +0800 Subject: [PATCH 0250/2234] fix https://github.com/Neilpang/acme.sh/issues/2208 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index f47a5ebb..14b23de1 100755 --- a/acme.sh +++ b/acme.sh @@ -2004,7 +2004,7 @@ _read_conf() { _r_c_f="$1" _sdkey="$2" if [ -f "$_r_c_f" ]; then - _sdv="$(grep "^$_sdkey *=" "$_r_c_f" | cut -d = -f 2-1000 | tr -d "'")" + _sdv="$(eval "$(grep "^$_sdkey *=" "$_r_c_f")" ; eval "printf \"%s\" \"\$$_sdkey\"")" if _startswith "$_sdv" "${B64CONF_START}" && _endswith "$_sdv" "${B64CONF_END}"; then _sdv="$(echo "$_sdv" | sed "s/${B64CONF_START}//" | sed "s/${B64CONF_END}//" | _dbase64)" fi From c97e43dcd6b4d6447f69402d31522d4f02586813 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 6 Apr 2019 16:45:58 +0800 Subject: [PATCH 0251/2234] fix format --- acme.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 14b23de1..7994cc22 100755 --- a/acme.sh +++ b/acme.sh @@ -2004,7 +2004,10 @@ _read_conf() { _r_c_f="$1" _sdkey="$2" if [ -f "$_r_c_f" ]; then - _sdv="$(eval "$(grep "^$_sdkey *=" "$_r_c_f")" ; eval "printf \"%s\" \"\$$_sdkey\"")" + _sdv="$( + eval "$(grep "^$_sdkey *=" "$_r_c_f")" + eval "printf \"%s\" \"\$$_sdkey\"" + )" if _startswith "$_sdv" "${B64CONF_START}" && _endswith "$_sdv" "${B64CONF_END}"; then _sdv="$(echo "$_sdv" | sed "s/${B64CONF_START}//" | sed "s/${B64CONF_END}//" | _dbase64)" fi From 0cfeee4ded53a34db628af4eefd4372e8a6e3d1b Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 6 Apr 2019 16:48:17 +0800 Subject: [PATCH 0252/2234] fix format --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 7994cc22..77f84a25 100755 --- a/acme.sh +++ b/acme.sh @@ -2004,9 +2004,9 @@ _read_conf() { _r_c_f="$1" _sdkey="$2" if [ -f "$_r_c_f" ]; then - _sdv="$( - eval "$(grep "^$_sdkey *=" "$_r_c_f")" - eval "printf \"%s\" \"\$$_sdkey\"" + _sdv="$( + eval "$(grep "^$_sdkey *=" "$_r_c_f")" + eval "printf \"%s\" \"\$$_sdkey\"" )" if _startswith "$_sdv" "${B64CONF_START}" && _endswith "$_sdv" "${B64CONF_END}"; then _sdv="$(echo "$_sdv" | sed "s/${B64CONF_START}//" | sed "s/${B64CONF_END}//" | _dbase64)" From 98d27c4a6a780ff333a99201166e899b017259ae Mon Sep 17 00:00:00 2001 From: Matthew R Chase Date: Sun, 7 Apr 2019 15:04:03 -0400 Subject: [PATCH 0253/2234] Fix most-specific zone match Most specific zone selected by deepest sub-domain (how many '.' in the domain) rather than seemingly irrelevant count of the number of characters within the zone. --- 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 99fbf410..87aceaad 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -134,12 +134,12 @@ _dns_gcloud_find_zone() { filter="$filter)" _debug filter "$filter" - # List domains and find the longest match (in case of some levels of delegation) + # List domains and find the zone with the deepest sub-domain (in case of some levels of delegation) if ! match=$(gcloud dns managed-zones list \ --format="value(name, dnsName)" \ --filter="$filter" \ | while read -r dnsName name; do - printf "%s\t%s\t%s\n" "${#dnsName}" "$dnsName" "$name" + printf "%s\t%s\t%s\n" "$(awk -F"." '{print NF-1}' <<< "$name")" "$dnsName" "$name" done \ | sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then _err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?" From f23b0aacd79b249382f73029850e11b03107afb0 Mon Sep 17 00:00:00 2001 From: chasefox <49169974+chasefox@users.noreply.github.com> Date: Mon, 8 Apr 2019 07:11:08 -0400 Subject: [PATCH 0254/2234] Remove here string CI doesn't want here strings --- dnsapi/dns_gcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index 87aceaad..9dfc5743 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -139,7 +139,7 @@ _dns_gcloud_find_zone() { --format="value(name, dnsName)" \ --filter="$filter" \ | while read -r dnsName name; do - printf "%s\t%s\t%s\n" "$(awk -F"." '{print NF-1}' <<< "$name")" "$dnsName" "$name" + printf "%s\t%s\t%s\n" "$(echo $name | awk -F"." '{print NF-1}')" "$dnsName" "$name" done \ | sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then _err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?" From 2d72b25c4393716efabd4b241c729efa50794845 Mon Sep 17 00:00:00 2001 From: chasefox <49169974+chasefox@users.noreply.github.com> Date: Mon, 8 Apr 2019 07:44:41 -0400 Subject: [PATCH 0255/2234] CI wanted double-quote --- dnsapi/dns_gcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index 9dfc5743..919223ab 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -139,7 +139,7 @@ _dns_gcloud_find_zone() { --format="value(name, dnsName)" \ --filter="$filter" \ | while read -r dnsName name; do - printf "%s\t%s\t%s\n" "$(echo $name | awk -F"." '{print NF-1}')" "$dnsName" "$name" + printf "%s\t%s\t%s\n" "$(echo "$name" | awk -F"." '{print NF-1}')" "$dnsName" "$name" done \ | sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then _err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?" From 4aa488f48b68f5271ba90e6f04673f0f234d06d1 Mon Sep 17 00:00:00 2001 From: chasefox <49169974+chasefox@users.noreply.github.com> Date: Mon, 8 Apr 2019 07:51:39 -0400 Subject: [PATCH 0256/2234] Formatting - indentation I think this is what CI wants.... --- dnsapi/dns_gcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index 919223ab..c2ead9a9 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -141,7 +141,7 @@ _dns_gcloud_find_zone() { | while read -r dnsName name; do printf "%s\t%s\t%s\n" "$(echo "$name" | awk -F"." '{print NF-1}')" "$dnsName" "$name" done \ - | sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then + | sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then _err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?" return 1 fi From 79e2f8a2e5ebd9d070903ca1e5294a1b24f03d06 Mon Sep 17 00:00:00 2001 From: dim0x69 Date: Wed, 17 Apr 2019 14:51:07 +0200 Subject: [PATCH 0257/2234] implement account update for acmev2 --- acme.sh | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 77f84a25..2fe9acb6 100755 --- a/acme.sh +++ b/acme.sh @@ -3218,11 +3218,6 @@ _on_issue_success() { } -updateaccount() { - _initpath - _regAccount -} - registeraccount() { _reg_length="$1" _initpath @@ -3320,6 +3315,61 @@ _regAccount() { _info "ACCOUNT_THUMBPRINT" "$ACCOUNT_THUMBPRINT" } +#implement updateaccount +updateaccount() { + _initpath + + if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then + _info "mv $_OLD_ACCOUNT_KEY to $ACCOUNT_KEY_PATH" + mv "$_OLD_ACCOUNT_KEY" "$ACCOUNT_KEY_PATH" + fi + + if [ ! -f "$ACCOUNT_JSON_PATH" ] && [ -f "$_OLD_ACCOUNT_JSON" ]; then + _info "mv $_OLD_ACCOUNT_JSON to $ACCOUNT_JSON_PATH" + mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH" + fi + + if [ ! -f "$ACCOUNT_KEY_PATH" ]; then + _err "Account key is not found at: $ACCOUNT_KEY_PATH" + return 1 + fi + + _accUri=$(_readcaconf "ACCOUNT_URL") + _debug _accUri "$_accUri" + + if [ -z "$_accUri" ]; then + _err "The account url is empty, please run '--update-account' first to update the account info first," + _err "Then try again." + return 1 + fi + + if ! _calcjwk "$ACCOUNT_KEY_PATH"; then + return 1 + fi + _initAPI + + if [ "$ACME_VERSION" = "2" ]; then + if [ "$ACCOUNT_EMAIL" ]; then + updjson='{"contact": ["mailto: '$ACCOUNT_EMAIL'"]}' + fi + else + # ACMEv1: Updates happen the same way a registration is done. + # https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-6.3 + _regAccount + return + fi + + # this part handles ACMEv2 account updates. + _send_signed_request "$_accUri" "$updjson" + + if [ "$code" = '200' ]; then + _info "account update success for $_accUri." + else + _info "Error. The account was not updated." + return 1 + fi +} + #Implement deactivate account deactivateaccount() { _initpath From 61556a54e2955d0ab913422489e0e9e90adcf885 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Fri, 19 Apr 2019 17:27:32 +0200 Subject: [PATCH 0258/2234] feat: add `--noprofile` option to `install` command --- acme.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 77f84a25..7adda616 100755 --- a/acme.sh +++ b/acme.sh @@ -5795,6 +5795,7 @@ Parameters: --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. + --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' @@ -5928,6 +5929,7 @@ _process() { _ca_bundle="" _ca_path="" _nocron="" + _noprofile="" _ecc="" _csr="" _pre_hook="" @@ -6272,6 +6274,9 @@ _process() { --nocron) _nocron="1" ;; + --noprofile) + _noprofile="1" + ;; --no-color) export ACME_NO_COLOR=1 ;; @@ -6430,7 +6435,7 @@ _process() { fi case "${_CMD}" in - install) install "$_nocron" "$_confighome" ;; + install) install "$_nocron" "$_confighome" "$_noprofile" ;; uninstall) uninstall "$_nocron" ;; upgrade) upgrade ;; issue) From 9c9fed749aef146c63afe5ff16e9b1115d13d0da Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 20 Apr 2019 12:49:51 +0800 Subject: [PATCH 0259/2234] fix https://github.com/Neilpang/acme.sh/issues/2225 make NSUPDATE_SERVER can be overwritten --- dnsapi/dns_nsupdate.sh | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 8b479f98..dfb3672a 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -6,14 +6,22 @@ dns_nsupdate_add() { fulldomain=$1 txtvalue=$2 + NSUPDATE_SERVER="${NSUPDATE_SERVER:-$(_readaccountconf_mutable NSUPDATE_SERVER)}" + NSUPDATE_SERVER_PORT="${NSUPDATE_SERVER_PORT:-$(_readaccountconf_mutable NSUPDATE_SERVER_PORT)}" + NSUPDATE_KEY="${NSUPDATE_KEY:-$(_readaccountconf_mutable NSUPDATE_KEY)}" + NSUPDATE_ZONE="${NSUPDATE_ZONE:-$(_readaccountconf_mutable NSUPDATE_ZONE)}" + _checkKeyFile || return 1 + + # save the dns server and key to the account conf file. + _saveaccountconf_mutable NSUPDATE_SERVER "${NSUPDATE_SERVER}" + _saveaccountconf_mutable NSUPDATE_SERVER_PORT "${NSUPDATE_SERVER_PORT}" + _saveaccountconf_mutable NSUPDATE_KEY "${NSUPDATE_KEY}" + _saveaccountconf_mutable NSUPDATE_ZONE "${NSUPDATE_ZONE}" + [ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost" [ -n "${NSUPDATE_SERVER_PORT}" ] || NSUPDATE_SERVER_PORT=53 - # save the dns server and key to the account conf file. - _saveaccountconf NSUPDATE_SERVER "${NSUPDATE_SERVER}" - _saveaccountconf NSUPDATE_SERVER_PORT "${NSUPDATE_SERVER_PORT}" - _saveaccountconf NSUPDATE_KEY "${NSUPDATE_KEY}" - _saveaccountconf NSUPDATE_ZONE "${NSUPDATE_ZONE}" + _info "adding ${fulldomain}. 60 in txt \"${txtvalue}\"" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D" @@ -42,6 +50,12 @@ EOF #Usage: dns_nsupdate_rm _acme-challenge.www.domain.com dns_nsupdate_rm() { fulldomain=$1 + + NSUPDATE_SERVER="${NSUPDATE_SERVER:-$(_readaccountconf_mutable NSUPDATE_SERVER)}" + NSUPDATE_SERVER_PORT="${NSUPDATE_SERVER_PORT:-$(_readaccountconf_mutable NSUPDATE_SERVER_PORT)}" + NSUPDATE_KEY="${NSUPDATE_KEY:-$(_readaccountconf_mutable NSUPDATE_KEY)}" + NSUPDATE_ZONE="${NSUPDATE_ZONE:-$(_readaccountconf_mutable NSUPDATE_ZONE)}" + _checkKeyFile || return 1 [ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost" [ -n "${NSUPDATE_SERVER_PORT}" ] || NSUPDATE_SERVER_PORT=53 From 4f1888d2ea755332b83f955a2dde1a52624bff40 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 21 Apr 2019 12:23:06 +0800 Subject: [PATCH 0260/2234] fix https://github.com/Neilpang/acme.sh/issues/2192 --- acme.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 77f84a25..ff6f8e4b 100755 --- a/acme.sh +++ b/acme.sh @@ -1312,13 +1312,19 @@ _create_account_key() { _initpath mkdir -p "$CA_DIR" - if [ -f "$ACCOUNT_KEY_PATH" ]; then + if [ -s "$ACCOUNT_KEY_PATH" ]; then _info "Account key exists, skip" - return + return 0 else #generate account key - _createkey "$length" "$ACCOUNT_KEY_PATH" - chmod 600 "$ACCOUNT_KEY_PATH" + if _createkey "$length" "$ACCOUNT_KEY_PATH"; then + chmod 600 "$ACCOUNT_KEY_PATH" + _info "Create account key ok." + return 0 + else + _err "Create account key error." + return 1 + fi fi } @@ -1341,11 +1347,14 @@ createDomainKey() { _initpath "$domain" "$_cdl" - if [ ! -f "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then + if [ ! -f "$CERT_KEY_PATH" ] || [ ! -s "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then if _createkey "$_cdl" "$CERT_KEY_PATH"; then _savedomainconf Le_Keylength "$_cdl" _info "The domain key is here: $(__green $CERT_KEY_PATH)" return 0 + else + _err "Can not domain key" + return 1 fi else if [ "$IS_RENEW" ]; then From e6df1828d9029f278a74798eac81f4a3c86a052d Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 21 Apr 2019 12:37:26 +0800 Subject: [PATCH 0261/2234] fix https://github.com/Neilpang/acme.sh/issues/2192 --- acme.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index c004934f..9d5b6e54 100755 --- a/acme.sh +++ b/acme.sh @@ -1006,10 +1006,20 @@ _createkey() { if _isEccKey "$length"; then _debug "Using ec name: $eccname" - ${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null >"$f" + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then + echo "$_opkey" >"$f" + else + _err "error ecc key name: $eccname" + return 1 + fi else _debug "Using RSA: $length" - ${ACME_OPENSSL_BIN:-openssl} genrsa "$length" 2>/dev/null >"$f" + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa "$length" 2>/dev/null)"; then + echo "$_opkey" >"$f" + else + _err "error rsa key: $length" + return 1 + fi fi if [ "$?" != "0" ]; then From d1030eb0b2939a0748cd1208442bafdc1fd39a46 Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Wed, 24 Apr 2019 14:03:54 +0200 Subject: [PATCH 0262/2234] Create DDNSS API based on the work of helbgd --- dnsapi/dns_ddnss.sh | 133 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 dnsapi/dns_ddnss.sh diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh new file mode 100644 index 00000000..f2e9947e --- /dev/null +++ b/dnsapi/dns_ddnss.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env sh + +#Created by RaidenII, to use DuckDNS's API to add/remove text records +#06/27/201 +#modified by helbgd @ 03/13/2018 to support ddnss.de +#modified by mod242 @ 04/24/2018 to support different ddnss domains +#Please note: the Wildcard Feature must be turned on for the Host record +#and the checkbox for TXT needs to be enabled + + +# Pass credentials before "acme.sh --issue --dns dns_ddnss ..." +# -- +# export DDNSS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" +# -- +# + + +DDNSS_DNS_API="https://ddnss.de/upd.php" + +######## Public functions ##################### + +#Usage: dns_ddnss_add _acme-challenge.domain.ddnss.de "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_ddnss_add() { + fulldomain=$1 + txtvalue=$2 + + DDNSS_Token="${DDNSS_Token:-$(_readaccountconf_mutable DDNSS_Token)}" + if [ -z "$DDNSS_Token" ]; then + _err "You must export variable: DDNSS_Token" + _err "The token for your DDNSS account is necessary." + _err "You can look it up in your DDNSS account." + return 1 + fi + + # Now save the credentials. + _saveaccountconf_mutable DDNSS_Token "$DDNSS_Token" + + # Unfortunately, DDNSS does not seems to support lookup domain through API + # So I assume your credentials (which are your domain and token) are correct + # If something goes wrong, we will get a KO response from DDNSS + + if ! _ddnss_get_domain; then + return 1 + fi + + # Now add the TXT record to DDNSS DNS + _info "Trying to add TXT record" + if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=1&txt=$txtvalue"; then + if [ "$response" = "Updated 1 hostname." ]; then + _info "TXT record has been successfully added to your DDNSS domain." + _info "Note that all subdomains under this domain uses the same TXT record." + return 0 + else + _err "Errors happened during adding the TXT record, response=$response" + return 1 + fi + else + _err "Errors happened during adding the TXT record." + return 1 + fi +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_ddnss_rm() { + fulldomain=$1 + txtvalue=$2 + + DDNSS_Token="${DDNSS_Token:-$(_readaccountconf_mutable DDNSS_Token)}" + if [ -z "$DDNSS_Token" ]; then + _err "You must export variable: DDNSS_Token" + _err "The token for your DDNSS account is necessary." + _err "You can look it up in your DDNSS account." + return 1 + fi + + if ! _ddnss_get_domain; then + return 1 + fi + + # Now remove the TXT record from DDNS DNS + _info "Trying to remove TXT record" + if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=1&txt=."; then + if [ "$response" = "Updated 1 hostname." ]; then + _info "TXT record has been successfully removed from your DDNSS domain." + return 0 + else + _err "Errors happened during removing the TXT record, response=$response" + return 1 + fi + else + _err "Errors happened during removing the TXT record." + return 1 + fi +} + +#################### Private functions below ################################## + +#fulldomain=_acme-challenge.domain.ddnss.de +#returns +# _ddnss_domain=domain +_ddnss_get_domain() { + + # We'll extract the domain/username from full domain + _ddnss_domain="$(echo "$fulldomain" | _lower_case | _egrep_o '[.][^.][^.]*[.](ddnss|dyn-ip24|dyndns|dyn|dyndns1|home-webserver|myhome-server|dynip)\..*' | cut -d . -f 2-)" + + if [ -z "$_ddnss_domain" ]; then + _err "Error extracting the domain." + return 1 + fi + + return 0 +} + +#Usage: method URI +_ddnss_rest() { + method=$1 + param="$2" + _debug param "$param" + url="$DDNSS_DNS_API?$param" + _debug url "$url" + + # DDNSS uses GET to update domain info + if [ "$method" = "GET" ]; then + response="$(_get "$url" | sed -e :a -e 's/<[^>]*>//g;/ Date: Wed, 24 Apr 2019 14:57:48 +0200 Subject: [PATCH 0263/2234] Removed -e and changed tail to funktion --- dnsapi/dns_ddnss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index f2e9947e..711936df 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -122,7 +122,7 @@ _ddnss_rest() { # DDNSS uses GET to update domain info if [ "$method" = "GET" ]; then - response="$(_get "$url" | sed -e :a -e 's/<[^>]*>//g;/]*>//g;/ Date: Wed, 24 Apr 2019 16:05:44 +0200 Subject: [PATCH 0264/2234] Update dns_ddnss.sh --- dnsapi/dns_ddnss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index 711936df..f0cf04f2 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -122,7 +122,7 @@ _ddnss_rest() { # DDNSS uses GET to update domain info if [ "$method" = "GET" ]; then - response="$(_get "$url" | sed :a -e 's/<[^>]*>//g;/]*>//g;/ Date: Wed, 24 Apr 2019 16:15:01 +0200 Subject: [PATCH 0265/2234] Cleanup according to styleguide --- dnsapi/dns_ddnss.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index f0cf04f2..53665ad1 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -7,14 +7,12 @@ #Please note: the Wildcard Feature must be turned on for the Host record #and the checkbox for TXT needs to be enabled - # Pass credentials before "acme.sh --issue --dns dns_ddnss ..." # -- # export DDNSS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" # -- # - DDNSS_DNS_API="https://ddnss.de/upd.php" ######## Public functions ##################### From 20af1ceb7d4cdadcc9fae50914159fff716bc7f9 Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Wed, 24 Apr 2019 19:38:07 +0200 Subject: [PATCH 0266/2234] Cleanup comment --- dnsapi/dns_ddnss.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index 53665ad1..c38e6c7b 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -1,7 +1,6 @@ #!/usr/bin/env sh #Created by RaidenII, to use DuckDNS's API to add/remove text records -#06/27/201 #modified by helbgd @ 03/13/2018 to support ddnss.de #modified by mod242 @ 04/24/2018 to support different ddnss domains #Please note: the Wildcard Feature must be turned on for the Host record From 52f556412212040fbaeb8aa1cb6e5cb6a58a74c9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 25 Apr 2019 20:58:13 +0800 Subject: [PATCH 0267/2234] fix image links --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 28859825..8d40d51a 100644 --- a/README.md +++ b/README.md @@ -45,25 +45,25 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) | NO | Status| Platform| |----|-------|---------| -|1|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu -|2|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/debian-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Debian -|3|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/centos-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|CentOS -|4|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/windows-cygwin.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) -|5|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/freebsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|FreeBSD -|6|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/pfsense.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|pfsense -|7|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/opensuse-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|openSUSE -|8|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/alpine-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Alpine Linux (with curl) -|9|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/base-archlinux.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Archlinux -|10|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/fedora-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|fedora -|11|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/kalilinux-kali-linux-docker.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Kali Linux -|12|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/oraclelinux-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Oracle Linux -|13|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/proxmox.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh +|1|[![](https://neilpang.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu +|2|[![](https://neilpang.github.io/acmetest/status/debian-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Debian +|3|[![](https://neilpang.github.io/acmetest/status/centos-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|CentOS +|4|[![](https://neilpang.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) +|5|[![](https://neilpang.github.io/acmetest/status/freebsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|FreeBSD +|6|[![](https://neilpang.github.io/acmetest/status/pfsense.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|pfsense +|7|[![](https://neilpang.github.io/acmetest/status/opensuse-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|openSUSE +|8|[![](https://neilpang.github.io/acmetest/status/alpine-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Alpine Linux (with curl) +|9|[![](https://neilpang.github.io/acmetest/status/base-archlinux.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Archlinux +|10|[![](https://neilpang.github.io/acmetest/status/fedora-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|fedora +|11|[![](https://neilpang.github.io/acmetest/status/kalilinux-kali-linux-docker.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Kali Linux +|12|[![](https://neilpang.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Oracle Linux +|13|[![](https://neilpang.github.io/acmetest/status/proxmox.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh |14|-----| Cloud Linux https://github.com/Neilpang/le/issues/111 -|15|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/openbsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|OpenBSD -|16|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia +|15|[![](https://neilpang.github.io/acmetest/status/openbsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|OpenBSD +|16|[![](https://neilpang.github.io/acmetest/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia |17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT) -|18|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris -|19|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux +|18|[![](https://neilpang.github.io/acmetest/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris +|19|[![](https://neilpang.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux |20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX For all build statuses, check our [weekly build project](https://github.com/Neilpang/acmetest): From bb703281a289531643cf47331a8fa829f81f5f3d Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Thu, 25 Apr 2019 16:18:52 +0200 Subject: [PATCH 0268/2234] Update dns_ddnss.sh --- dnsapi/dns_ddnss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index c38e6c7b..dfe6dcb7 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -119,7 +119,7 @@ _ddnss_rest() { # DDNSS uses GET to update domain info if [ "$method" = "GET" ]; then - response="$(_get "$url" | sed :a -e 's/<[^>]*>//g;/]*>//g;/ Date: Fri, 26 Apr 2019 23:44:25 +0800 Subject: [PATCH 0269/2234] fix idn issues --- acme.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 9d5b6e54..5c9bf0c6 100755 --- a/acme.sh +++ b/acme.sh @@ -1084,11 +1084,12 @@ _createcsr() { printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment" >"$csrconf" if [ "$acmeValidationv1" ]; then + domainlist="$(_idn "$domainlist")" printf -- "\nsubjectAltName=DNS:$domainlist" >>"$csrconf" elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then #single domain _info "Single domain" "$domain" - printf -- "\nsubjectAltName=DNS:$domain" >>"$csrconf" + printf -- "\nsubjectAltName=DNS:$(_idn $domain)" >>"$csrconf" else domainlist="$(_idn "$domainlist")" _debug2 domainlist "$domainlist" @@ -3557,7 +3558,9 @@ _check_dns_entries() { for entry in $dns_entries; do d=$(_getfield "$entry" 1) txtdomain=$(_getfield "$entry" 2) + txtdomain=$(_idn $txtdomain) aliasDomain=$(_getfield "$entry" 3) + aliasDomain=$(_idn $aliasDomain) txt=$(_getfield "$entry" 5) d_api=$(_getfield "$entry" 6) _debug "d" "$d" @@ -3754,7 +3757,7 @@ issue() { if [ -z "$vlist" ]; then if [ "$ACME_VERSION" = "2" ]; then #make new order request - _identifiers="{\"type\":\"dns\",\"value\":\"$_main_domain\"}" + _identifiers="{\"type\":\"dns\",\"value\":\"$(_idn $_main_domain)\"}" _w_index=1 while true; do d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")" @@ -3851,7 +3854,7 @@ $_authorizations_map" fi if [ "$ACME_VERSION" = "2" ]; then - response="$(echo "$_authorizations_map" | grep "^$d," | sed "s/$d,//")" + response="$(echo "$_authorizations_map" | grep "^$(_idn $d)," | sed "s/$d,//")" _debug2 "response" "$response" if [ -z "$response" ]; then _err "get to authz error." From 47ff768b70aa8ab40ea7966b5a8fa90c4f2e6e2c Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 26 Apr 2019 23:57:40 +0800 Subject: [PATCH 0270/2234] fix https://github.com/Neilpang/acme.sh/issues/2195 --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 96731435..78250842 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -58,7 +58,7 @@ dns_cf_add() { # if [ "$count" = "0" ]; then _info "Adding record" if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then - if _contains "$response" "$fulldomain"; then + if _contains "$response" "$txtvalue"; then _info "Added, OK" return 0 elif _contains "$response" "The record already exists"; then From a7420ca3d4e0c73b315df3c746c78b10aaf7f74b Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 27 Apr 2019 09:17:26 +0800 Subject: [PATCH 0271/2234] typo --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 6694aede..93ad83d6 100755 --- a/acme.sh +++ b/acme.sh @@ -1364,7 +1364,7 @@ createDomainKey() { _info "The domain key is here: $(__green $CERT_KEY_PATH)" return 0 else - _err "Can not domain key" + _err "Can not create domain key" return 1 fi else From 1b062ab929f4e3b62d72a61dbe77b17c0252d405 Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Sun, 28 Apr 2019 15:58:08 +0200 Subject: [PATCH 0272/2234] Correct sed parsing error --- dnsapi/dns_ddnss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index dfe6dcb7..903b9619 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -119,7 +119,7 @@ _ddnss_rest() { # DDNSS uses GET to update domain info if [ "$method" = "GET" ]; then - response="$(_get "$url" | sed 's/<[^>]*>//g;/]*>//g' | _tail_n 1)" else _err "Unsupported method" return 1 From 5b1b5cc8f2c76c31859cf2047c230730707689d3 Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Mon, 29 Apr 2019 10:43:16 +0200 Subject: [PATCH 0273/2234] Create dns_schlundtech.sh --- dnsapi/dns_schlundtech.sh | 261 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 dnsapi/dns_schlundtech.sh diff --git a/dnsapi/dns_schlundtech.sh b/dnsapi/dns_schlundtech.sh new file mode 100644 index 00000000..202b3469 --- /dev/null +++ b/dnsapi/dns_schlundtech.sh @@ -0,0 +1,261 @@ +#!/usr/bin/env sh +# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- + +# Schlundtech DNS API +# Author: mod242 +# Created: 2019-40-29 +# Completly based on the autoDNS xml api wrapper by auerswald@gmail.com +# +# export SCHLUNDTECH_USER="username" +# export SCHLUNDTECH_PASSWORD="password" +# +# Usage: +# acme.sh --issue --dns dns_autodns -d example.com + +AUTODNS_API="https://gateway.schlundtech.de" + +# Arguments: +# txtdomain +# txt +dns_schlundtech_add() { + fulldomain="$1" + txtvalue="$2" + + SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable AUTODNS_USER)}" + SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable AUTODNS_PASSWORD)}" + + if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then + _err "You didn't specify schlundtech user and password." + return 1 + fi + + _saveaccountconf_mutable SCHLUNDTECH_USER "$SCHLUNDTECH_USER" + _saveaccountconf_mutable SCHLUNDTECH_PASSWORD "$SCHLUNDTECH_PASSWORD" + + _debug "First detect the root zone" + + if ! _get_autodns_zone "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _zone "$_zone" + _debug _system_ns "$_system_ns" + + _info "Adding TXT record" + + autodns_response="$(_autodns_zone_update "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")" + + if [ "$?" -eq "0" ]; then + _info "Added, OK" + return 0 + fi + + return 1 +} + +# Arguments: +# txtdomain +# txt +dns_schlundtech_rm() { + fulldomain="$1" + txtvalue="$2" + + SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable AUTODNS_USER)}" + SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable AUTODNS_PASSWORD)}" + + if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then + _err "You didn't specify schlundtech user and password." + return 1 + fi + + _debug "First detect the root zone" + + if ! _get_autodns_zone "$fulldomain"; then + _err "zone not found" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _zone "$_zone" + _debug _system_ns "$_system_ns" + + _info "Delete TXT record" + + autodns_response="$(_autodns_zone_cleanup "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")" + + if [ "$?" -eq "0" ]; then + _info "Deleted, OK" + return 0 + fi + + return 1 +} + +#################### Private functions below ################################## + +# Arguments: +# fulldomain +# Returns: +# _sub_domain=_acme-challenge.www +# _zone=domain.com +# _system_ns +_get_autodns_zone() { + domain="$1" + + i=2 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + + if [ -z "$h" ]; then + # not valid + return 1 + fi + + autodns_response="$(_autodns_zone_inquire "$h")" + + if [ "$?" -ne "0" ]; then + _err "invalid domain" + return 1 + fi + + if _contains "$autodns_response" "1" >/dev/null; then + _zone="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" + _system_ns="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + return 0 + fi + + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} + +_build_request_auth_xml() { + printf " + %s + %s + 10 + " "$SCHLUNDTECH_USER" "$SCHLUNDTECH_PASSWORD" +} + +# Arguments: +# zone +_build_zone_inquire_xml() { + printf " + + %s + + 0205 + + 1 + 1 + + + name + eq + %s + + + " "$(_build_request_auth_xml)" "$1" +} + +# Arguments: +# zone +# subdomain +# txtvalue +# system_ns +_build_zone_update_xml() { + printf " + + %s + + 0202001 + + + %s + 600 + TXT + %s + + + + %s + %s + + + " "$(_build_request_auth_xml)" "$2" "$3" "$1" "$4" +} + +# Arguments: +# zone +_autodns_zone_inquire() { + request_data="$(_build_zone_inquire_xml "$1")" + autodns_response="$(_autodns_api_call "$request_data")" + ret="$?" + + printf "%s" "$autodns_response" + return "$ret" +} + +# Arguments: +# zone +# subdomain +# txtvalue +# system_ns +_autodns_zone_update() { + request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")" + autodns_response="$(_autodns_api_call "$request_data")" + ret="$?" + + printf "%s" "$autodns_response" + return "$ret" +} + +# Arguments: +# zone +# subdomain +# txtvalue +# system_ns +_autodns_zone_cleanup() { + request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")" + # replace 'rr_add>' with 'rr_rem>' in request_data + request_data="$(printf -- "%s" "$request_data" | sed 's/rr_add>/rr_rem>/g')" + autodns_response="$(_autodns_api_call "$request_data")" + ret="$?" + + printf "%s" "$autodns_response" + return "$ret" +} + +# Arguments: +# request_data +_autodns_api_call() { + request_data="$1" + + _debug request_data "$request_data" + + autodns_response="$(_post "$request_data" "$AUTODNS_API")" + ret="$?" + + _debug autodns_response "$autodns_response" + + if [ "$ret" -ne "0" ]; then + _err "error" + return 1 + fi + + if _contains "$autodns_response" "success" >/dev/null; then + _info "success" + printf "%s" "$autodns_response" + return 0 + fi + + return 1 +} From 345d6c5687e48dae07494565d735a367f6faa7af Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Mon, 29 Apr 2019 10:44:23 +0200 Subject: [PATCH 0274/2234] Update dns_schlundtech.sh --- dnsapi/dns_schlundtech.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_schlundtech.sh b/dnsapi/dns_schlundtech.sh index 202b3469..c5e7d630 100644 --- a/dnsapi/dns_schlundtech.sh +++ b/dnsapi/dns_schlundtech.sh @@ -21,8 +21,8 @@ dns_schlundtech_add() { fulldomain="$1" txtvalue="$2" - SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable AUTODNS_USER)}" - SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable AUTODNS_PASSWORD)}" + SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable SCHLUNDTECH_USER)}" + SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable SCHLUNDTECH_PASSWORD)}" if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then _err "You didn't specify schlundtech user and password." From 9b68a3ef4acb7112119d01182965394cd653c761 Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Mon, 29 Apr 2019 12:13:40 +0200 Subject: [PATCH 0275/2234] Update dns_schlundtech.sh --- dnsapi/dns_schlundtech.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_schlundtech.sh b/dnsapi/dns_schlundtech.sh index c5e7d630..efb021ae 100644 --- a/dnsapi/dns_schlundtech.sh +++ b/dnsapi/dns_schlundtech.sh @@ -62,8 +62,8 @@ dns_schlundtech_rm() { fulldomain="$1" txtvalue="$2" - SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable AUTODNS_USER)}" - SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable AUTODNS_PASSWORD)}" + SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable SCHLUNDTECH_USER)}" + SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable SCHLUNDTECH_PASSWORD)}" if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then _err "You didn't specify schlundtech user and password." From 175b56b43c05ed0ed2ec432e3e1ead2f12f78414 Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Mon, 29 Apr 2019 12:18:05 +0200 Subject: [PATCH 0276/2234] Update dns_schlundtech.sh --- dnsapi/dns_schlundtech.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_schlundtech.sh b/dnsapi/dns_schlundtech.sh index efb021ae..12408633 100644 --- a/dnsapi/dns_schlundtech.sh +++ b/dnsapi/dns_schlundtech.sh @@ -10,9 +10,9 @@ # export SCHLUNDTECH_PASSWORD="password" # # Usage: -# acme.sh --issue --dns dns_autodns -d example.com +# acme.sh --issue --dns dns_schlundtech -d example.com -AUTODNS_API="https://gateway.schlundtech.de" +SCHLUNDTECH_API="https://gateway.schlundtech.de" # Arguments: # txtdomain @@ -241,7 +241,7 @@ _autodns_api_call() { _debug request_data "$request_data" - autodns_response="$(_post "$request_data" "$AUTODNS_API")" + autodns_response="$(_post "$request_data" "$SCHLUNDTECH_API")" ret="$?" _debug autodns_response "$autodns_response" From d10f40f109d417ba9810eefd482662ba44fec208 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 29 Apr 2019 21:44:25 +0800 Subject: [PATCH 0277/2234] fix idn issue. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 93ad83d6..0ce42ff5 100755 --- a/acme.sh +++ b/acme.sh @@ -1032,7 +1032,7 @@ _createkey() { _is_idn() { _is_idn_d="$1" _debug2 _is_idn_d "$_is_idn_d" - _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '0-9' | tr -d 'a-z' | tr -d 'A-Z' | tr -d '*.,-') + _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '0-9' | tr -d 'a-z' | tr -d 'A-Z' | tr -d '*.,-_') _debug2 _idn_temp "$_idn_temp" [ "$_idn_temp" ] } From a89d50d34ee8d20ca7365f6aa6d1e6465f2f626c Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 29 Apr 2019 21:52:22 +0800 Subject: [PATCH 0278/2234] use mutable --- dnsapi/dns_cx.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index d07d8e0c..c287d507 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -16,6 +16,8 @@ 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="" @@ -27,8 +29,8 @@ dns_cx_add() { REST_API="$CX_Api" #save the api key and email to the account conf file. - _saveaccountconf CX_Key "$CX_Key" - _saveaccountconf CX_Secret "$CX_Secret" + _saveaccountconf_mutable CX_Key "$CX_Key" + _saveaccountconf_mutable CX_Secret "$CX_Secret" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -43,6 +45,8 @@ dns_cx_add() { 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="" From b7a04430913063b8801fba50a8647ae51aefabc3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 29 Apr 2019 22:11:25 +0800 Subject: [PATCH 0279/2234] lets start 2.8.2 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 0ce42ff5..153b953f 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.1 +VER=2.8.2 PROJECT_NAME="acme.sh" From b50e701caefed9fdde1bd2c388e7f3a0011ebb54 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 29 Apr 2019 22:13:54 +0800 Subject: [PATCH 0280/2234] Add notification (#2241) * add cron notify * fix format * fix format --- acme.sh | 270 ++++++++++++++++++++++++++++++++++++++++++--- notify/mail.sh | 15 +++ notify/mailgun.sh | 123 +++++++++++++++++++++ notify/pop.sh | 15 +++ notify/sendgrid.sh | 56 ++++++++++ notify/smtp.sh | 15 +++ 6 files changed, 481 insertions(+), 13 deletions(-) create mode 100644 notify/mail.sh create mode 100644 notify/mailgun.sh create mode 100644 notify/pop.sh create mode 100644 notify/sendgrid.sh create mode 100644 notify/smtp.sh diff --git a/acme.sh b/acme.sh index 153b953f..dc110a0f 100755 --- a/acme.sh +++ b/acme.sh @@ -14,7 +14,11 @@ _WINDOWS_SCHEDULER_NAME="$PROJECT_NAME.cron" _SCRIPT_="$0" -_SUB_FOLDERS="dnsapi deploy" +_SUB_FOLDER_NOTIFY="notify" +_SUB_FOLDER_DNSAPI="dnsapi" +_SUB_FOLDER_DEPLOY="deploy" + +_SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY" LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory" @@ -107,6 +111,18 @@ SYSLOG_LEVEL_DEFAULT=$SYSLOG_LEVEL_ERROR #none SYSLOG_LEVEL_NONE=0 +NOTIFY_LEVEL_DISABLE=0 +NOTIFY_LEVEL_ERROR=1 +NOTIFY_LEVEL_RENEW=2 +NOTIFY_LEVEL_SKIP=3 + +NOTIFY_LEVEL_DEFAULT=$NOTIFY_LEVEL_RENEW + +NOTIFY_MODE_BULK=0 +NOTIFY_MODE_CERT=1 + +NOTIFY_MODE_DEFAULT=$NOTIFY_MODE_BULK + _DEBUG_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh" _PREPARE_LINK="https://github.com/Neilpang/acme.sh/wiki/Install-preparations" @@ -117,6 +133,8 @@ _DNS_ALIAS_WIKI="https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode" _DNS_MANUAL_WIKI="https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode" +_NOTIFY_WIKI="https://github.com/Neilpang/acme.sh/wiki/notify" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -784,6 +802,13 @@ _url_encode() { done } +_json_encode() { + _j_str="$(sed 's/"/\\"/g' | sed "s/\r/\\r/g")" + _debug3 "_json_encode" + _debug3 "_j_str" "$_j_str" + echo "$_j_str" | _hex_dump | _lower_case | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n" +} + #options file _sed_i() { options="$1" @@ -3168,6 +3193,14 @@ _on_issue_err() { _err "See: $_DEBUG_WIKI" fi + if [ "$IN_CRON" ]; then + if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_ERROR ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $_main_domain error" "There is an error." "$NOTIFY_HOOK" 1 + fi + fi + fi + #run the post hook if [ "$_chk_post_hook" ]; then _info "Run post hook:'$_chk_post_hook'" @@ -3210,6 +3243,13 @@ _on_issue_success() { _chk_post_hook="$1" _chk_renew_hook="$2" _debug _on_issue_success + if [ "$IN_CRON" ]; then + if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_RENEW ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $_main_domain success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 + fi + fi + fi #run the post hook if [ "$_chk_post_hook" ]; then _info "Run post hook:'$_chk_post_hook'" @@ -3467,9 +3507,9 @@ _findHook() { d_api="$_SCRIPT_HOME/$_hookcat/$_hookname" elif [ -f "$_SCRIPT_HOME/$_hookcat/$_hookname.sh" ]; then d_api="$_SCRIPT_HOME/$_hookcat/$_hookname.sh" - elif [ -f "$LE_WORKING_DIR/$_hookdomain/$_hookname" ]; then + elif [ "$_hookdomain" ] && [ -f "$LE_WORKING_DIR/$_hookdomain/$_hookname" ]; then d_api="$LE_WORKING_DIR/$_hookdomain/$_hookname" - elif [ -f "$LE_WORKING_DIR/$_hookdomain/$_hookname.sh" ]; then + elif [ "$_hookdomain" ] && [ -f "$LE_WORKING_DIR/$_hookdomain/$_hookname.sh" ]; then d_api="$LE_WORKING_DIR/$_hookdomain/$_hookname.sh" elif [ -f "$LE_WORKING_DIR/$_hookname" ]; then d_api="$LE_WORKING_DIR/$_hookname" @@ -4017,7 +4057,7 @@ $_authorizations_map" txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" _debug txt "$txt" - d_api="$(_findHook "$_dns_root_d" dnsapi "$_currentRoot")" + d_api="$(_findHook "$_dns_root_d" $_SUB_FOLDER_DNSAPI "$_currentRoot")" _debug d_api "$d_api" dns_entry="$dns_entry$dvsep$txt${dvsep}$d_api" @@ -4622,6 +4662,15 @@ renew() { if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then _info "Skip, Next renewal time is: $(__green "$Le_NextRenewTimeStr")" _info "Add '$(__red '--force')' to force to renew." + + if [ "$IN_CRON" = "1" ]; then + if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_SKIP ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $Le_Domain skipped" "Good, the cert next renewal time is $Le_NextRenewTimeStr." "$NOTIFY_HOOK" "$RENEW_SKIP" + fi + fi + fi + return "$RENEW_SKIP" fi @@ -4657,7 +4706,9 @@ renewAll() { _stopRenewOnError="$1" _debug "_stopRenewOnError" "$_stopRenewOnError" _ret="0" - + _success_msg="" + _error_msg="" + _skipped_msg="" for di in "${CERT_HOME}"/*.*/; do _debug di "$di" if ! [ -d "$di" ]; then @@ -4678,15 +4729,49 @@ renewAll() { if [ "$rc" != "0" ]; then if [ "$rc" = "$RENEW_SKIP" ]; then _info "Skipped $d" - elif [ "$_stopRenewOnError" ]; then - _err "Error renew $d, stop now." - return "$rc" + _skipped_msg="${_skipped_msg} $d +" else - _ret="$rc" - _err "Error renew $d." + _error_msg="${_error_msg} $d +" + if [ "$_stopRenewOnError" ]; then + _err "Error renew $d, stop now." + _ret="$rc" + break + else + _ret="$rc" + _err "Error renew $d." + fi fi + else + _success_msg="${_success_msg} $d +" fi done + + if [ "$IN_CRON" = "1" ]; then + if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then + _msg_subject="Renew" + if [ "$_error_msg" ]; then + _msg_subject="${_msg_subject} Error" + fi + if [ "$_success_msg" ]; then + _msg_subject="${_msg_subject} Success" + fi + if [ "$_skipped_msg" ]; then + _msg_subject="${_msg_subject} Skipped" + fi + _msg_data="Error certs: +${_error_msg} +Success certs: +${_success_msg} +Skipped certs: +$_skipped_msg +" + _send_notify "$_msg_subject" "$_msg_data" "$NOTIFY_HOOK" 0 + fi + fi + return "$_ret" } @@ -4835,7 +4920,7 @@ _deploy() { _hooks="$2" for _d_api in $(echo "$_hooks" | tr ',' " "); do - _deployApi="$(_findHook "$_d" deploy "$_d_api")" + _deployApi="$(_findHook "$_d" $_SUB_FOLDER_DEPLOY "$_d_api")" if [ -z "$_deployApi" ]; then _err "The deploy hook $_d_api is not found." return 1 @@ -5785,6 +5870,113 @@ version() { echo "v$VER" } +# subject content hooks code +_send_notify() { + _nsubject="$1" + _ncontent="$2" + _nhooks="$3" + _nerror="$4" + + if [ "$NOTIFY_LEVEL" = "$NOTIFY_LEVEL_DISABLE" ]; then + _debug "The NOTIFY_LEVEL is $NOTIFY_LEVEL, disabled, just return." + return 0 + fi + + if [ -z "$_nhooks" ]; then + _debug "The NOTIFY_HOOK is empty, just return." + return 0 + fi + + _send_err=0 + for _n_hook in $(echo "$_nhooks" | tr ',' " "); do + _n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")" + _info "Found $_n_hook_file" + + if ! ( + if ! . "$_n_hook_file"; then + _err "Load file $_n_hook_file error. Please check your api file and try again." + return 1 + fi + + d_command="${_n_hook}_send" + if ! _exists "$d_command"; then + _err "It seems that your api file is not correct, it must have a function named: $d_command" + return 1 + fi + + if ! $d_command "$_nsubject" "$_ncontent" "$_nerror"; then + _err "Error send message by $d_command" + return 1 + fi + + return 0 + ); then + _err "Set $_n_hook_file error." + _send_err=1 + else + _info "$_n_hook $(__green Success)" + fi + done + return $_send_err + +} + +# hook +_set_notify_hook() { + _nhooks="$1" + + _test_subject="Hello, this is notification from $PROJECT_NAME" + _test_content="If you receive this email, your notification works." + + _send_notify "$_test_subject" "$_test_content" "$_nhooks" 0 + +} + +#[hook] [level] [mode] +setnotify() { + _nhook="$1" + _nlevel="$2" + _nmode="$3" + + _initpath + + if [ -z "$_nhook$_nlevel$_nmode" ]; then + _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook mailgun] [--notify-level $NOTIFY_LEVEL_DEFAULT] [--notify-mode $NOTIFY_MODE_DEFAULT]" + _usage "$_NOTIFY_WIKI" + return 1 + fi + + if [ "$_nlevel" ]; then + _info "Set notify level to: $_nlevel" + export "NOTIFY_LEVEL=$_nlevel" + _saveaccountconf "NOTIFY_LEVEL" "$NOTIFY_LEVEL" + fi + + if [ "$_nmode" ]; then + _info "Set notify mode to: $_nmode" + export "NOTIFY_MODE=$_nmode" + _saveaccountconf "NOTIFY_MODE" "$NOTIFY_MODE" + fi + + if [ "$_nhook" ]; then + _info "Set notify hook to: $_nhook" + if [ "$_nhook" = "$NO_VALUE" ]; then + _info "Clear notify hook" + _clearaccountconf "NOTIFY_HOOK" + else + if _set_notify_hook "$_nhook"; then + export NOTIFY_HOOK="$_nhook" + _saveaccountconf "NOTIFY_HOOK" "$NOTIFY_HOOK" + return 0 + else + _err "Can not set notify hook to: $_nhook" + return 1 + fi + fi + fi + +} + showhelp() { _initpath version @@ -5817,6 +6009,8 @@ Commands: --create-domain-key Create an domain private key, professional use. --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. + --set-notify Set the cron notification hook, level or mode. + Parameters: --domain, -d domain.tld Specifies a domain, used to issue, renew or revoke etc. @@ -5885,7 +6079,18 @@ Parameters: --use-wget Force to use wget, if you have both curl and wget installed. --yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode: $_DNS_MANUAL_WIKI --branch, -b Only valid for '--upgrade' command, specifies the branch name to upgrade to. - " + + --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. + 0: disabled, no notification will be sent. + 1: send notification only when there is an error. No news is good news. + 2: send notification when a cert is successfully renewed, or there is an error + 3: send notification when a cert is skipped, renewdd, or error + --notify-mode 0|1 Set notification mode. Default value is $NOTIFY_MODE_DEFAULT. + 0: Bulk mode. Send all the domain's notifications in one message(mail) + 1: Cert mode. Send a message for every single cert. + --notify-hook [hookname] Set the notify hook + +" } # nocron noprofile @@ -6019,6 +6224,9 @@ _process() { _syslog="" _use_wget="" _server="" + _notify_hook="" + _notify_level="" + _notify_mode="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -6105,6 +6313,9 @@ _process() { --deactivate-account) _CMD="deactivateaccount" ;; + --set-notify) + _CMD="setnotify" + ;; --domain | -d) _dvalue="$2" @@ -6453,6 +6664,37 @@ _process() { export BRANCH="$2" shift ;; + --notify-hook) + _nhook="$2" + if _startswith "$_nhook" "-"; then + _err "'$_nhook' is not a hook name for '$1'" + return 1 + fi + if [ "$_notify_hook" ]; then + _notify_hook="$_notify_hook,$_nhook" + else + _notify_hook="$_nhook" + fi + shift + ;; + --notify-level) + _nlevel="$2" + if _startswith "$_nlevel" "-"; then + _err "'$_nlevel' is not a integer for '$1'" + return 1 + fi + _notify_level="$_nlevel" + shift + ;; + --notify-mode) + _nmode="$2" + if _startswith "$_nmode" "-"; then + _err "'$_nmode' is not a integer for '$1'" + return 1 + fi + _notify_mode="$_nmode" + shift + ;; *) _err "Unknown parameter : $1" return 1 @@ -6570,7 +6812,9 @@ _process() { createCSR) createCSR "$_domain" "$_altdomains" "$_ecc" ;; - + setnotify) + setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" + ;; *) if [ "$_CMD" ]; then _err "Invalid command: $_CMD" diff --git a/notify/mail.sh b/notify/mail.sh new file mode 100644 index 00000000..3dfef0be --- /dev/null +++ b/notify/mail.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh + +# support local mail app + +mail_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + _err "Not implemented yet." + return 1 +} diff --git a/notify/mailgun.sh b/notify/mailgun.sh new file mode 100644 index 00000000..1689a0b9 --- /dev/null +++ b/notify/mailgun.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env sh + +#Support mailgun.com api + +#MAILGUN_API_KEY="xxxx" +#MAILGUN_TO="yyyy@gmail.com" + +#MAILGUN_REGION="us|eu" #optional, use "us" as default +#MAILGUN_API_DOMAIN="xxxxxx.com" #optional, use the default sandbox domain +#MAILGUN_FROM="xxx@xxxxx.com" #optional, use the default sendbox account + +_MAILGUN_BASE="https://api.mailgun.net/v3" + +# subject content statusCode +mailgun_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + MAILGUN_API_KEY="${MAILGUN_API_KEY:-$(_readaccountconf_mutable MAILGUN_API_KEY)}" + if [ -z "$MAILGUN_API_KEY" ]; then + MAILGUN_API_KEY="" + _err "You didn't specify a mailgun api key MAILGUN_API_KEY yet ." + _err "You can get yours from here https://mailgun.com" + return 1 + fi + _saveaccountconf_mutable MAILGUN_API_KEY "$MAILGUN_API_KEY" + + MAILGUN_REGION="${MAILGUN_REGION:-$(_readaccountconf_mutable MAILGUN_REGION)}" + if [ -z "$MAILGUN_REGION" ]; then + MAILGUN_REGION="" + _info "The MAILGUN_REGION is not set, so use the default us region." + _MAILGUN_BASE="https://api.mailgun.net/v3" + else + _saveaccountconf_mutable MAILGUN_REGION "$MAILGUN_REGION" + _MAILGUN_BASE="https://api.eu.mailgun.net/v3" + fi + + MAILGUN_TO="${MAILGUN_TO:-$(_readaccountconf_mutable MAILGUN_TO)}" + if [ -z "$MAILGUN_TO" ]; then + MAILGUN_TO="" + _err "You didn't specify an email to MAILGUN_TO receive messages." + return 1 + fi + _saveaccountconf_mutable MAILGUN_TO "$MAILGUN_TO" + + MAILGUN_API_DOMAIN="${MAILGUN_API_DOMAIN:-$(_readaccountconf_mutable MAILGUN_API_DOMAIN)}" + if [ -z "$MAILGUN_API_DOMAIN" ]; then + _info "The MAILGUN_API_DOMAIN is not set, try to get the default sending sandbox domain for you." + if ! _mailgun_rest GET "/domains"; then + _err "Can not get sandbox domain." + return 1 + fi + _sendboxDomain="$(echo "$response" | _egrep_o '"name": *"sandbox.*.mailgun.org"' | cut -d : -f 2 | tr -d '" ')" + _debug _sendboxDomain "$_sendboxDomain" + MAILGUN_API_DOMAIN="$_sendboxDomain" + if [ -z "$MAILGUN_API_DOMAIN" ]; then + _err "Can not get sandbox domain for MAILGUN_API_DOMAIN" + return 1 + fi + + _info "$(__green "When using sandbox domain, you must verify your email first.")" + #todo: add recepient + fi + if [ -z "$MAILGUN_API_DOMAIN" ]; then + _err "Can not get MAILGUN_API_DOMAIN" + return 1 + fi + _saveaccountconf_mutable MAILGUN_API_DOMAIN "$MAILGUN_API_DOMAIN" + + MAILGUN_FROM="${MAILGUN_FROM:-$(_readaccountconf_mutable MAILGUN_FROM)}" + if [ -z "$MAILGUN_FROM" ]; then + MAILGUN_FROM="$PROJECT_NAME@$MAILGUN_API_DOMAIN" + _info "The MAILGUN_FROM is not set, so use the default value: $MAILGUN_FROM" + else + _debug MAILGUN_FROM "$MAILGUN_FROM" + _saveaccountconf_mutable MAILGUN_FROM "$MAILGUN_FROM" + fi + + #send from url + _msg="/$MAILGUN_API_DOMAIN/messages?from=$(printf "%s" "$MAILGUN_FROM" | _url_encode)&to=$(printf "%s" "$MAILGUN_TO" | _url_encode)&subject=$(printf "%s" "$_subject" | _url_encode)&text=$(printf "%s" "$_content" | _url_encode)" + _debug "_msg" "$_msg" + _mailgun_rest POST "$_msg" + if _contains "$response" "Queued. Thank you."; then + _info "mailgun send success." + return 0 + else + _err "mailgun send error" + _err "$response" + return 1 + fi + +} + +# method uri data +_mailgun_rest() { + _method="$1" + _mguri="$2" + _mgdata="$3" + _debug _mguri "$_mguri" + _mgurl="$_MAILGUN_BASE$_mguri" + _debug _mgurl "$_mgurl" + + _auth="$(printf "%s" "api:$MAILGUN_API_KEY" | _base64)" + export _H1="Authorization: Basic $_auth" + export _H2="Content-Type: application/json" + + if [ "$_method" = "GET" ]; then + response="$(_get "$_mgurl")" + else + _debug _mgdata "$_mgdata" + response="$(_post "$_mgdata" "$_mgurl" "" "$_method")" + fi + if [ "$?" != "0" ]; then + _err "Error: $_mguri" + _err "$response" + return 1 + fi + _debug2 response "$response" + return 0 + +} diff --git a/notify/pop.sh b/notify/pop.sh new file mode 100644 index 00000000..f118d79b --- /dev/null +++ b/notify/pop.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh + +# support pop + +pop_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + _err "Not implemented yet." + return 1 +} diff --git a/notify/sendgrid.sh b/notify/sendgrid.sh new file mode 100644 index 00000000..5c5bfdba --- /dev/null +++ b/notify/sendgrid.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env sh + +#Support SENDGRID.com api + +#SENDGRID_API_KEY="" +#SENDGRID_TO="xxxx@xxx.com" +#SENDGRID_FROM="xxxx@cccc.com" + +sendgrid_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + SENDGRID_API_KEY="${SENDGRID_API_KEY:-$(_readaccountconf_mutable SENDGRID_API_KEY)}" + if [ -z "$SENDGRID_API_KEY" ]; then + SENDGRID_API_KEY="" + _err "You didn't specify a sendgrid api key SENDGRID_API_KEY yet ." + _err "You can get yours from here https://sendgrid.com" + return 1 + fi + _saveaccountconf_mutable SENDGRID_API_KEY "$SENDGRID_API_KEY" + + SENDGRID_TO="${SENDGRID_TO:-$(_readaccountconf_mutable SENDGRID_TO)}" + if [ -z "$SENDGRID_TO" ]; then + SENDGRID_TO="" + _err "You didn't specify an email to SENDGRID_TO receive messages." + return 1 + fi + _saveaccountconf_mutable SENDGRID_TO "$SENDGRID_TO" + + SENDGRID_FROM="${SENDGRID_FROM:-$(_readaccountconf_mutable SENDGRID_FROM)}" + if [ -z "$SENDGRID_FROM" ]; then + SENDGRID_FROM="" + _err "You didn't specify an email to SENDGRID_FROM receive messages." + return 1 + fi + _saveaccountconf_mutable SENDGRID_FROM "$SENDGRID_FROM" + + export _H1="Authorization: Bearer $SENDGRID_API_KEY" + export _H2="Content-Type: application/json" + + _content="$(echo "$_content" | _json_encode)" + _data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}" + response="" #just make shellcheck happy + if _post "$_data" "https://api.sendgrid.com/v3/mail/send"; then + if [ -z "$response" ]; then + _info "sendgrid send sccess." + return 0 + fi + fi + _err "sendgrid send error." + _err "$response" + return 1 + +} diff --git a/notify/smtp.sh b/notify/smtp.sh new file mode 100644 index 00000000..6aa37ca3 --- /dev/null +++ b/notify/smtp.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh + +# support smtp + +smtp_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + _err "Not implemented yet." + return 1 +} From d7be2c5b8a4eb49da47faea5ded8da66d30f98b6 Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Mon, 29 Apr 2019 16:17:24 +0200 Subject: [PATCH 0281/2234] Remove from Master Branch --- dnsapi/dns_schlundtech.sh | 261 -------------------------------------- 1 file changed, 261 deletions(-) delete mode 100644 dnsapi/dns_schlundtech.sh diff --git a/dnsapi/dns_schlundtech.sh b/dnsapi/dns_schlundtech.sh deleted file mode 100644 index 12408633..00000000 --- a/dnsapi/dns_schlundtech.sh +++ /dev/null @@ -1,261 +0,0 @@ -#!/usr/bin/env sh -# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- - -# Schlundtech DNS API -# Author: mod242 -# Created: 2019-40-29 -# Completly based on the autoDNS xml api wrapper by auerswald@gmail.com -# -# export SCHLUNDTECH_USER="username" -# export SCHLUNDTECH_PASSWORD="password" -# -# Usage: -# acme.sh --issue --dns dns_schlundtech -d example.com - -SCHLUNDTECH_API="https://gateway.schlundtech.de" - -# Arguments: -# txtdomain -# txt -dns_schlundtech_add() { - fulldomain="$1" - txtvalue="$2" - - SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable SCHLUNDTECH_USER)}" - SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable SCHLUNDTECH_PASSWORD)}" - - if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then - _err "You didn't specify schlundtech user and password." - return 1 - fi - - _saveaccountconf_mutable SCHLUNDTECH_USER "$SCHLUNDTECH_USER" - _saveaccountconf_mutable SCHLUNDTECH_PASSWORD "$SCHLUNDTECH_PASSWORD" - - _debug "First detect the root zone" - - if ! _get_autodns_zone "$fulldomain"; then - _err "invalid domain" - return 1 - fi - - _debug _sub_domain "$_sub_domain" - _debug _zone "$_zone" - _debug _system_ns "$_system_ns" - - _info "Adding TXT record" - - autodns_response="$(_autodns_zone_update "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")" - - if [ "$?" -eq "0" ]; then - _info "Added, OK" - return 0 - fi - - return 1 -} - -# Arguments: -# txtdomain -# txt -dns_schlundtech_rm() { - fulldomain="$1" - txtvalue="$2" - - SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable SCHLUNDTECH_USER)}" - SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable SCHLUNDTECH_PASSWORD)}" - - if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then - _err "You didn't specify schlundtech user and password." - return 1 - fi - - _debug "First detect the root zone" - - if ! _get_autodns_zone "$fulldomain"; then - _err "zone not found" - return 1 - fi - - _debug _sub_domain "$_sub_domain" - _debug _zone "$_zone" - _debug _system_ns "$_system_ns" - - _info "Delete TXT record" - - autodns_response="$(_autodns_zone_cleanup "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")" - - if [ "$?" -eq "0" ]; then - _info "Deleted, OK" - return 0 - fi - - return 1 -} - -#################### Private functions below ################################## - -# Arguments: -# fulldomain -# Returns: -# _sub_domain=_acme-challenge.www -# _zone=domain.com -# _system_ns -_get_autodns_zone() { - domain="$1" - - i=2 - p=1 - - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug h "$h" - - if [ -z "$h" ]; then - # not valid - return 1 - fi - - autodns_response="$(_autodns_zone_inquire "$h")" - - if [ "$?" -ne "0" ]; then - _err "invalid domain" - return 1 - fi - - if _contains "$autodns_response" "1" >/dev/null; then - _zone="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" - _system_ns="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - return 0 - fi - - p=$i - i=$(_math "$i" + 1) - done - - return 1 -} - -_build_request_auth_xml() { - printf " - %s - %s - 10 - " "$SCHLUNDTECH_USER" "$SCHLUNDTECH_PASSWORD" -} - -# Arguments: -# zone -_build_zone_inquire_xml() { - printf " - - %s - - 0205 - - 1 - 1 - - - name - eq - %s - - - " "$(_build_request_auth_xml)" "$1" -} - -# Arguments: -# zone -# subdomain -# txtvalue -# system_ns -_build_zone_update_xml() { - printf " - - %s - - 0202001 - - - %s - 600 - TXT - %s - - - - %s - %s - - - " "$(_build_request_auth_xml)" "$2" "$3" "$1" "$4" -} - -# Arguments: -# zone -_autodns_zone_inquire() { - request_data="$(_build_zone_inquire_xml "$1")" - autodns_response="$(_autodns_api_call "$request_data")" - ret="$?" - - printf "%s" "$autodns_response" - return "$ret" -} - -# Arguments: -# zone -# subdomain -# txtvalue -# system_ns -_autodns_zone_update() { - request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")" - autodns_response="$(_autodns_api_call "$request_data")" - ret="$?" - - printf "%s" "$autodns_response" - return "$ret" -} - -# Arguments: -# zone -# subdomain -# txtvalue -# system_ns -_autodns_zone_cleanup() { - request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")" - # replace 'rr_add>' with 'rr_rem>' in request_data - request_data="$(printf -- "%s" "$request_data" | sed 's/rr_add>/rr_rem>/g')" - autodns_response="$(_autodns_api_call "$request_data")" - ret="$?" - - printf "%s" "$autodns_response" - return "$ret" -} - -# Arguments: -# request_data -_autodns_api_call() { - request_data="$1" - - _debug request_data "$request_data" - - autodns_response="$(_post "$request_data" "$SCHLUNDTECH_API")" - ret="$?" - - _debug autodns_response "$autodns_response" - - if [ "$ret" -ne "0" ]; then - _err "error" - return 1 - fi - - if _contains "$autodns_response" "success" >/dev/null; then - _info "success" - printf "%s" "$autodns_response" - return 0 - fi - - return 1 -} From 37ef0a0cb62cc70c0b4ef6158d21946576e56fac Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Tue, 30 Apr 2019 15:32:36 +0800 Subject: [PATCH 0282/2234] Fix README.md confict --- deploy/README.md | 294 +---------------------------------------------- 1 file changed, 2 insertions(+), 292 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 8cefeffa..fc633ad7 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,296 +1,6 @@ # Using deploy api -Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert). +deploy hook usage: -Here are the scripts to deploy the certs/key to the server/services. +https://github.com/Neilpang/acme.sh/wiki/deployhooks -## 1. Deploy the certs to your cpanel host - -If you want to deploy using cpanel UAPI see 7. - -(cpanel deploy hook is not finished yet, this is just an example.) - - - -Then you can deploy now: - -```sh -export DEPLOY_CPANEL_USER=myusername -export DEPLOY_CPANEL_PASSWORD=PASSWORD -acme.sh --deploy -d example.com --deploy-hook cpanel -``` - -## 2. Deploy ssl cert on kong proxy engine based on api - -Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert). -Currently supports Kong-v0.10.x. - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook kong -``` - -## 3. Deploy the cert to remote server through SSH access - -The ssh deploy plugin allows you to deploy certificates to a remote host -using SSH command to connect to the remote server. The ssh plugin is invoked -with the following command... - -```sh -acme.sh --deploy -d example.com --deploy-hook ssh -``` -Prior to running this for the first time you must tell the plugin where -and how to deploy the certificates. This is done by exporting the following -environment variables. This is not required for subsequent runs as the -values are stored by acme.sh in the domain configuration files. - -Required... -``` -export DEPLOY_SSH_USER=username -``` -Optional... -``` -export DEPLOY_SSH_CMD=custom ssh command -export DEPLOY_SSH_SERVER=url or ip address of remote host -export DEPLOY_SSH_KEYFILE=filename for private key -export DEPLOY_SSH_CERTFILE=filename for certificate file -export DEPLOY_SSH_CAFILE=filename for intermediate CA file -export DEPLOY_SSH_FULLCHAIN=filename for fullchain file -export DEPLOY_SSH_REMOTE_CMD=command to execute on remote host -export DEPLOY_SSH_BACKUP=yes or no -``` - -**DEPLOY_SSH_USER** -Username at the remote host that SSH will login with. Note that -SSH must be able to login to remote host without a password... SSH Keys -must have been exchanged with the remote host. Validate and test that you -can login to USER@URL from the host running acme.sh before using this script. - -The USER@URL at the remote server must also have has permissions to write to -the target location of the certificate files and to execute any commands -(e.g. to stop/start services). - -**DEPLOY_SSH_CMD** -You can customize the ssh command used to connect to the remote host. For example -if you need to connect to a specific port at the remote server you can set this -to, for example, "ssh -p 22" or to use `sshpass` to provide password inline -instead of exchanging ssh keys (this is not recommended, using keys is -more secure). - -**DEPLOY_SSH_SERVER** -URL or IP Address of the remote server. If not provided then the domain -name provided on the acme.sh --deploy command line is used. - -**DEPLOY_SSH_KEYFILE** -Target filename for the private key issued by LetsEncrypt. - -**DEPLOY_SSH_CERTFILE** -Target filename for the certificate issued by LetsEncrypt. -If this is the same as the previous filename (for keyfile) then it is -appended to the same file. - -**DEPLOY_SSH_CAFILE** -Target filename for the CA intermediate certificate issued by LetsEncrypt. -If this is the same as a previous filename (for keyfile or certfile) then -it is appended to the same file. - -**DEPLOY_SSH_FULLCHAIN** -Target filename for the fullchain certificate issued by LetsEncrypt. -If this is the same as a previous filename (for keyfile, certfile or -cafile) then it is appended to the same file. - -**DEPLOY_SSH_REMOTE_CMD** -Command to execute on the remote server after copying any certificates. This -could be any additional command required for example to stop and restart -the service. - -**DEPLOY_SSH_BACKUP** -Before writing a certificate file to the remote server the existing -certificate will be copied to a backup directory on the remote server. -These are placed in a hidden directory in the home directory of the SSH -user -```sh -~/.acme_ssh_deploy/[domain name]-backup-[timestamp] -``` -Any backups older than 180 days will be deleted when new certificates -are deployed. This defaults to "yes" set to "no" to disable backup. - -###Examples using SSH deploy -The following example illustrates deploying certificates to a QNAP NAS -(tested with QTS version 4.2.3) - -```sh -export DEPLOY_SSH_USER="admin" -export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem" -export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem" -export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem" -export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" - -acme.sh --deploy -d qnap.example.com --deploy-hook ssh -``` -Note how in this example both the private key and certificate point to -the same file. This will result in the certificate being appended -to the same file as the private key... a common requirement of several -services. - -The next example illustrates deploying certificates to a Unifi -Controller (tested with version 5.4.11). - -```sh -export DEPLOY_SSH_USER="root" -export DEPLOY_SSH_KEYFILE="/var/lib/unifi/unifi.example.com.key" -export DEPLOY_SSH_FULLCHAIN="/var/lib/unifi/unifi.example.com.cer" -export DEPLOY_SSH_REMOTE_CMD="openssl pkcs12 -export \ - -inkey /var/lib/unifi/unifi.example.com.key \ - -in /var/lib/unifi/unifi.example.com.cer \ - -out /var/lib/unifi/unifi.example.com.p12 \ - -name ubnt -password pass:temppass \ - && keytool -importkeystore -deststorepass aircontrolenterprise \ - -destkeypass aircontrolenterprise \ - -destkeystore /var/lib/unifi/keystore \ - -srckeystore /var/lib/unifi/unifi.example.com.p12 \ - -srcstoretype PKCS12 -srcstorepass temppass -alias ubnt -noprompt \ - && service unifi restart" - -acme.sh --deploy -d unifi.example.com --deploy-hook ssh -``` -In this example we execute several commands on the remote host -after the certificate files have been copied... to generate a pkcs12 file -compatible with Unifi, to import it into the Unifi keystore and then finally -to restart the service. - -Note also that once the certificate is imported -into the keystore the individual certificate files are no longer -required. We could if we desired delete those files immediately. If we -do that then we should disable backup at the remote host (as there are -no files to backup -- they were erased during deployment). For example... -```sh -export DEPLOY_SSH_BACKUP=no -# modify the end of the remote command... -&& rm /var/lib/unifi/unifi.example.com.key \ - /var/lib/unifi/unifi.example.com.cer \ - /var/lib/unifi/unifi.example.com.p12 \ -&& service unifi restart -``` - -## 4. Deploy the cert to local vsftpd server - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd -``` - -The default vsftpd conf file is `/etc/vsftpd.conf`, if your vsftpd conf is not in the default location, you can specify one: - -```sh -export DEPLOY_VSFTPD_CONF="/etc/vsftpd.conf" - -acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd -``` - -The default command to restart vsftpd server is `service vsftpd restart`, if it doesn't work, you can specify one: - -```sh -export DEPLOY_VSFTPD_RELOAD="/etc/init.d/vsftpd restart" - -acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd -``` - -## 5. Deploy the cert to local exim4 server - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook exim4 -``` - -The default exim4 conf file is `/etc/exim/exim.conf`, if your exim4 conf is not in the default location, you can specify one: - -```sh -export DEPLOY_EXIM4_CONF="/etc/exim4/exim4.conf.template" - -acme.sh --deploy -d ftp.example.com --deploy-hook exim4 -``` - -The default command to restart exim4 server is `service exim4 restart`, if it doesn't work, you can specify one: - -```sh -export DEPLOY_EXIM4_RELOAD="/etc/init.d/exim4 restart" - -acme.sh --deploy -d ftp.example.com --deploy-hook exim4 -``` - -## 6. Deploy the cert to OSX Keychain - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook keychain -``` - -## 7. Deploy to cpanel host using UAPI - -This hook is using UAPI and works in cPanel & WHM version 56 or newer. -``` -acme.sh --deploy -d example.com --deploy-hook cpanel_uapi -``` -DEPLOY_CPANEL_USER is required only if you run the script as root and it should contain cpanel username. -```sh -export DEPLOY_CPANEL_USER=username -acme.sh --deploy -d example.com --deploy-hook cpanel_uapi -``` -Please note, that the cpanel_uapi hook will deploy only the first domain when your certificate will automatically renew. Therefore you should issue a separate certificate for each domain. - -## 8. Deploy the cert to your FRITZ!Box router - -You must specify the credentials that have administrative privileges on the FRITZ!Box in order to deploy the certificate, plus the URL of your FRITZ!Box, through the following environment variables: -```sh -$ export DEPLOY_FRITZBOX_USERNAME=my_username -$ export DEPLOY_FRITZBOX_PASSWORD=the_password -$ export DEPLOY_FRITZBOX_URL=https://fritzbox.example.com -``` - -After the first deployment, these values will be stored in your $HOME/.acme.sh/account.conf. You may now deploy the certificate like this: - -```sh -acme.sh --deploy -d fritzbox.example.com --deploy-hook fritzbox -``` - -## 9. Deploy the cert to strongswan - -```sh -acme.sh --deploy -d ftp.example.com --deploy-hook strongswan -``` - -## 10. Deploy the cert to HAProxy - -You may specify the directory where you want the concatenated key and certificate chain written. The value shown below will be used as the default if you don't set this environment variable. - -```sh -export DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy -``` - -You may optionally specify the file name where you want the concatenated key and certificate chain written. The value shown below will be used as the default if you don't set this environment variable. - -```sh -export DEPLOY_HAPROXY_PEM_NAME=$domain -``` - -You may optionally define the command to reload HAProxy. The value shown below will be used as the default if you don't set this environment variable. - -```sh -export DEPLOY_HAPROXY_RELOAD="true" -``` - -You may optionally specify that the issuer certificate is transferred to "${DEPLOY_HAPROXY_PEM}.issuer". This is a requirement to support OCSP stapling in HAProxy. The value shown below will be used as the default if you don't set this environment variable. - -```sh -export DEPLOY_HAPROXY_ISSUER="no" -``` - -You may optionally specify that you wish to support HAProxy's multi-cert bundle functionality. This allows serving of both RSA and ECC certificates on the same proxy. This adds a ".rsa" or ".ecc" suffix to the files generated (.pem, .ocsp and .issuer). The value shown below will be used as the default if you don't set this environment variable. - -```sh -export DEPLOY_HAPROXY_BUNDLE="no" -``` - -You can then deploy the certificate as follows -```sh -acme.sh --deploy -d haproxy.example.com --deploy-hook haproxy -``` - -The path for the PEM file will be stored with the domain configuration and will be available when renewing, so that deploy will happen automatically when renewed. From 388ff75260ea86e6f24f4326b5a0ba5e8e003d93 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 30 Apr 2019 20:43:10 +0800 Subject: [PATCH 0283/2234] --- Auto-Git Commit --- --- .gitignore | 1 + test.sh | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 .gitignore create mode 100644 test.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..427ec6be --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.autogit \ No newline at end of file diff --git a/test.sh b/test.sh new file mode 100644 index 00000000..d976bfe4 --- /dev/null +++ b/test.sh @@ -0,0 +1,8 @@ + + +_data='aaaaa +bbb"bb +ccccc +ddddd +' + From 522b7c51f74298a11beea2e20a9f8e69b31c76fe Mon Sep 17 00:00:00 2001 From: Jakub Filo Date: Wed, 1 May 2019 01:53:51 +0200 Subject: [PATCH 0284/2234] Adding NLnetLabs NSD API --- dnsapi/dns_nsd.sh | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 dnsapi/dns_nsd.sh diff --git a/dnsapi/dns_nsd.sh b/dnsapi/dns_nsd.sh new file mode 100644 index 00000000..2c5b64ce --- /dev/null +++ b/dnsapi/dns_nsd.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env sh + +#Nsd_ZoneFile="/etc/nsd/zones/example.com.zone" +#Nsd_Command="sudo nsd-control reload" + +# args: fulldomain txtvalue +dns_nsd_add() +{ + fulldomain=$1 + txtvalue=$2 + ttlvalue=300 + + Nsd_ZoneFile="${Nsd_ZoneFile:-$(_readdomainconf Nsd_ZoneFile)}" + Nsd_Command="${Nsd_Command:-$(_readdomainconf Nsd_Command)}" + + # Arg checks + if [ -z "$Nsd_ZoneFile" ] || [ -z "$Nsd_Command" ]; then + Nsd_ZoneFile="" + Nsd_Command="" + _err "Specify ENV vars Nsd_ZoneFile and Nsd_Command" + return 1 + fi + + if [ ! -f "$Nsd_ZoneFile" ]; then + Nsd_ZoneFile="" + Nsd_Command="" + _err "No such file: $Nsd_ZoneFile" + return 1 + fi + + _savedomainconf Nsd_ZoneFile "$Nsd_ZoneFile" + _savedomainconf Nsd_Command "$Nsd_Command" + + echo "$fulldomain. $ttlvalue IN TXT \"$txtvalue\"" >> "$Nsd_ZoneFile" + _info "Added TXT record for $fulldomain" + _debug "Running $Nsd_Command" + if eval "$Nsd_Command"; then + _info "Successfully updated the zone" + return 0 + else + _err "Problem updating the zone" + return 1 + fi +} + +# args: fulldomain txtvalue +dns_nsd_rm() +{ + fulldomain=$1 + txtvalue=$2 + ttlvalue=300 + + Nsd_ZoneFile="${Nsd_ZoneFile:-$(_readdomainconf Nsd_ZoneFile)}" + Nsd_Command="${Nsd_Command:-$(_readdomainconf Nsd_Command)}" + + sed -i "/$fulldomain. $ttlvalue IN TXT \"$txtvalue\"/d" "$Nsd_ZoneFile" + _info "Removed TXT record for $fulldomain" + _debug "Running $Nsd_Command" + if eval "$Nsd_Command"; then + _info "Successfully reloaded NSD " + return 0 + else + _err "Problem reloading NSD" + return 1 + fi +} + From 63407041738634e16b761542bc1de163cfa8b7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B8=D0=BC=D1=83=D1=80=20=D0=AF=D1=85=D0=B8=D0=BD?= Date: Wed, 1 May 2019 10:11:39 +0300 Subject: [PATCH 0285/2234] fixed line breaks for support api gcore_cdn (#2237) --- deploy/gcore_cdn.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 56ca9afd..e0921bcb 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -27,8 +27,8 @@ gcore_cdn_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _fullchain=$(tr '\n\r' '@#' <"$_cfullchain" | sed 's/@/\\n/g;s/#/\\r/g') - _key=$(tr '\n\r' '@#' <"$_ckey" | sed 's/@/\\n/g;s/#/\\r/g') + _fullchain=$(tr '\r\n' '*#' <"$_cfullchain" | sed 's/*#/#/g;s/##/#/g;s/#/\\n/g') + _key=$(tr '\r\n' '*#' <"$_ckey" | sed 's/*#/#/g;s/#/\\n/g') _debug _fullchain "$_fullchain" _debug _key "$_key" From 040ca5320d4a409b9c5787940f47796443158cbe Mon Sep 17 00:00:00 2001 From: Jakub Filo Date: Wed, 1 May 2019 12:17:54 +0200 Subject: [PATCH 0286/2234] Fixed style to match upstream --- dnsapi/dns_nsd.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_nsd.sh b/dnsapi/dns_nsd.sh index 2c5b64ce..a7416708 100644 --- a/dnsapi/dns_nsd.sh +++ b/dnsapi/dns_nsd.sh @@ -4,8 +4,7 @@ #Nsd_Command="sudo nsd-control reload" # args: fulldomain txtvalue -dns_nsd_add() -{ +dns_nsd_add() { fulldomain=$1 txtvalue=$2 ttlvalue=300 @@ -31,7 +30,7 @@ dns_nsd_add() _savedomainconf Nsd_ZoneFile "$Nsd_ZoneFile" _savedomainconf Nsd_Command "$Nsd_Command" - echo "$fulldomain. $ttlvalue IN TXT \"$txtvalue\"" >> "$Nsd_ZoneFile" + echo "$fulldomain. $ttlvalue IN TXT \"$txtvalue\"" >>"$Nsd_ZoneFile" _info "Added TXT record for $fulldomain" _debug "Running $Nsd_Command" if eval "$Nsd_Command"; then @@ -44,8 +43,7 @@ dns_nsd_add() } # args: fulldomain txtvalue -dns_nsd_rm() -{ +dns_nsd_rm() { fulldomain=$1 txtvalue=$2 ttlvalue=300 From d1ef039e39fe246c0b7ec26eb656b6ee62f81648 Mon Sep 17 00:00:00 2001 From: Jakub Filo Date: Wed, 1 May 2019 12:25:46 +0200 Subject: [PATCH 0287/2234] Removed trailing line --- dnsapi/dns_nsd.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_nsd.sh b/dnsapi/dns_nsd.sh index a7416708..83cc4cac 100644 --- a/dnsapi/dns_nsd.sh +++ b/dnsapi/dns_nsd.sh @@ -62,4 +62,3 @@ dns_nsd_rm() { return 1 fi } - From 096ce1a20749ddd9e7738f5fd2a614c0d89002da Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Thu, 2 May 2019 12:18:16 +0200 Subject: [PATCH 0288/2234] Create DNS API for Schlundtech --- dnsapi/dns_schlundtech.sh | 261 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 dnsapi/dns_schlundtech.sh diff --git a/dnsapi/dns_schlundtech.sh b/dnsapi/dns_schlundtech.sh new file mode 100644 index 00000000..399c50e0 --- /dev/null +++ b/dnsapi/dns_schlundtech.sh @@ -0,0 +1,261 @@ +#!/usr/bin/env sh +# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- + +# Schlundtech DNS API +# Author: mod242 +# Created: 2019-40-29 +# Completly based on the autoDNS xml api wrapper by auerswald@gmail.com +# +# export SCHLUNDTECH_USER="username" +# export SCHLUNDTECH_PASSWORD="password" +# +# Usage: +# acme.sh --issue --dns dns_schlundtech -d example.com + +SCHLUNDTECH_API="https://gateway.schlundtech.de" + +# Arguments: +# txtdomain +# txt +dns_schlundtech_add() { + fulldomain="$1" + txtvalue="$2" + + SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable SCHLUNDTECH_USER)}" + SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable SCHLUNDTECH_PASSWORD)}" + + if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then + _err "You didn't specify schlundtech user and password." + return 1 + fi + + _saveaccountconf_mutable SCHLUNDTECH_USER "$SCHLUNDTECH_USER" + _saveaccountconf_mutable SCHLUNDTECH_PASSWORD "$SCHLUNDTECH_PASSWORD" + + _debug "First detect the root zone" + + if ! _get_autodns_zone "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _zone "$_zone" + _debug _system_ns "$_system_ns" + + _info "Adding TXT record" + + autodns_response="$(_autodns_zone_update "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")" + + if [ "$?" -eq "0" ]; then + _info "Added, OK" + return 0 + fi + + return 1 +} + +# Arguments: +# txtdomain +# txt +dns_schlundtech_rm() { + fulldomain="$1" + txtvalue="$2" + + SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable SCHLUNDTECH_USER)}" + SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable SCHLUNDTECH_PASSWORD)}" + + if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then + _err "You didn't specify schlundtech user and password." + return 1 + fi + + _debug "First detect the root zone" + + if ! _get_autodns_zone "$fulldomain"; then + _err "zone not found" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _zone "$_zone" + _debug _system_ns "$_system_ns" + + _info "Delete TXT record" + + autodns_response="$(_autodns_zone_cleanup "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")" + + if [ "$?" -eq "0" ]; then + _info "Deleted, OK" + return 0 + fi + + return 1 +} + +#################### Private functions below ################################## + +# Arguments: +# fulldomain +# Returns: +# _sub_domain=_acme-challenge.www +# _zone=domain.com +# _system_ns +_get_autodns_zone() { + domain="$1" + + i=2 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + + if [ -z "$h" ]; then + # not valid + return 1 + fi + + autodns_response="$(_autodns_zone_inquire "$h")" + + if [ "$?" -ne "0" ]; then + _err "invalid domain" + return 1 + fi + + if _contains "$autodns_response" "1" >/dev/null; then + _zone="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" + _system_ns="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + return 0 + fi + + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} + +_build_request_auth_xml() { + printf " + %s + %s + 10 + " "$SCHLUNDTECH_USER" "$SCHLUNDTECH_PASSWORD" +} + +# Arguments: +# zone +_build_zone_inquire_xml() { + printf " + + %s + + 0205 + + 1 + 1 + + + name + eq + %s + + + " "$(_build_request_auth_xml)" "$1" +} + +# Arguments: +# zone +# subdomain +# txtvalue +# system_ns +_build_zone_update_xml() { + printf " + + %s + + 0202001 + + + %s + 600 + TXT + %s + + + + %s + %s + + + " "$(_build_request_auth_xml)" "$2" "$3" "$1" "$4" +} + +# Arguments: +# zone +_autodns_zone_inquire() { + request_data="$(_build_zone_inquire_xml "$1")" + autodns_response="$(_autodns_api_call "$request_data")" + ret="$?" + + printf "%s" "$autodns_response" + return "$ret" +} + +# Arguments: +# zone +# subdomain +# txtvalue +# system_ns +_autodns_zone_update() { + request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")" + autodns_response="$(_autodns_api_call "$request_data")" + ret="$?" + + printf "%s" "$autodns_response" + return "$ret" +} + +# Arguments: +# zone +# subdomain +# txtvalue +# system_ns +_autodns_zone_cleanup() { + request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")" + # replace 'rr_add>' with 'rr_rem>' in request_data + request_data="$(printf -- "%s" "$request_data" | sed 's/rr_add>/rr_rem>/g')" + autodns_response="$(_autodns_api_call "$request_data")" + ret="$?" + + printf "%s" "$autodns_response" + return "$ret" +} + +# Arguments: +# request_data +_autodns_api_call() { + request_data="$1" + + _debug request_data "$request_data" + + autodns_response="$(_post "$request_data" "$SCHLUNDTECH_API")" + ret="$?" + + _debug autodns_response "$autodns_response" + + if [ "$ret" -ne "0" ]; then + _err "error" + return 1 + fi + + if _contains "$autodns_response" "success" >/dev/null; then + _info "success" + printf "%s" "$autodns_response" + return 0 + fi + + return 1 +} From dac75a1dda7681df3e9cfae93675d93ceca7f574 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 3 May 2019 20:50:42 +0800 Subject: [PATCH 0289/2234] rename --- dnsapi/dns_one.sh | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index c99c9c97..94ac49c6 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -5,8 +5,8 @@ # Author: github: @diseq # Created: 2019-02-17 # -# export ONECOM_USER="username" -# export ONECOM_PASSWORD="password" +# export ONECOM_User="username" +# export ONECOM_Password="password" # # Usage: # acme.sh --issue --dns dns_one -d example.com @@ -19,26 +19,26 @@ dns_one_add() { txtvalue=$2 # get credentials - ONECOM_USER="${ONECOM_USER:-$(_readaccountconf_mutable ONECOM_USER)}" - ONECOM_PASSWORD="${ONECOM_PASSWORD:-$(_readaccountconf_mutable ONECOM_PASSWORD)}" - if [ -z "$ONECOM_USER" ] || [ -z "$ONECOM_PASSWORD" ]; then - ONECOM_USER="" - ONECOM_PASSWORD="" + ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" + ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" + if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then + ONECOM_User="" + ONECOM_Password="" _err "You didn't specify a one.com username and password yet." _err "Please create the key and try again." return 1 fi #save the api key and email to the account conf file. - _saveaccountconf_mutable ONECOM_USER "$ONECOM_USER" - _saveaccountconf_mutable ONECOM_PASSWORD "$ONECOM_PASSWORD" + _saveaccountconf_mutable ONECOM_User "$ONECOM_User" + _saveaccountconf_mutable ONECOM_Password "$ONECOM_Password" # Login with user and password postdata="loginDomain=true" - postdata="$postdata&displayUsername=$ONECOM_USER" - postdata="$postdata&username=$ONECOM_USER" + postdata="$postdata&displayUsername=$ONECOM_User" + postdata="$postdata&username=$ONECOM_User" postdata="$postdata&targetDomain=$mydomain" - postdata="$postdata&password1=$ONECOM_PASSWORD" + postdata="$postdata&password1=$ONECOM_Password" postdata="$postdata&loginTarget=" #_debug postdata "$postdata" @@ -64,7 +64,7 @@ dns_one_add() { response="$(echo "$response" | _normalizeJson)" _debug response "$response" - id=$(printf -- "%s" "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") + id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") if [ -z "$id" ]; then _err "Add txt record error." @@ -82,11 +82,11 @@ dns_one_rm() { txtvalue=$2 # get credentials - ONECOM_USER="${ONECOM_USER:-$(_readaccountconf_mutable ONECOM_USER)}" - ONECOM_PASSWORD="${ONECOM_PASSWORD:-$(_readaccountconf_mutable ONECOM_PASSWORD)}" - if [ -z "$ONECOM_USER" ] || [ -z "$ONECOM_PASSWORD" ]; then - ONECOM_USER="" - ONECOM_PASSWORD="" + ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" + ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" + if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then + ONECOM_User="" + ONECOM_Password="" _err "You didn't specify a one.com username and password yet." _err "Please create the key and try again." return 1 @@ -94,10 +94,10 @@ dns_one_rm() { # Login with user and password postdata="loginDomain=true" - postdata="$postdata&displayUsername=$ONECOM_USER" - postdata="$postdata&username=$ONECOM_USER" + postdata="$postdata&displayUsername=$ONECOM_User" + postdata="$postdata&username=$ONECOM_User" postdata="$postdata&targetDomain=$mydomain" - postdata="$postdata&password1=$ONECOM_PASSWORD" + postdata="$postdata&password1=$ONECOM_Password" postdata="$postdata&loginTarget=" response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")" From 621d4745b4a65ea63658ad82c93aa0e185e80b07 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 4 May 2019 10:18:42 +0800 Subject: [PATCH 0290/2234] fix idn --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index dc110a0f..727e35ed 100755 --- a/acme.sh +++ b/acme.sh @@ -3856,7 +3856,7 @@ issue() { if [ -z "$d" ]; then break fi - _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$d\"}" + _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$$(_idn $d)\"}" done _debug2 _identifiers "$_identifiers" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then From 6198e43fe69ca87c2f0eed639d2b8f098d11f039 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 4 May 2019 10:21:15 +0800 Subject: [PATCH 0291/2234] fix idn --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 727e35ed..e84619fd 100755 --- a/acme.sh +++ b/acme.sh @@ -3856,7 +3856,7 @@ issue() { if [ -z "$d" ]; then break fi - _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$$(_idn $d)\"}" + _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn $d)\"}" done _debug2 _identifiers "$_identifiers" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then From a77f2fa4246ef4de4859924dbe563a67516608df Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 4 May 2019 10:32:01 +0800 Subject: [PATCH 0292/2234] remove test file --- test.sh | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 test.sh diff --git a/test.sh b/test.sh deleted file mode 100644 index d976bfe4..00000000 --- a/test.sh +++ /dev/null @@ -1,8 +0,0 @@ - - -_data='aaaaa -bbb"bb -ccccc -ddddd -' - From 0f866510895e1130fcdc22cffcd5464e9e966841 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 4 May 2019 10:43:39 +0800 Subject: [PATCH 0293/2234] fix idn --- .gitignore | 1 - acme.sh | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 427ec6be..00000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.autogit \ No newline at end of file diff --git a/acme.sh b/acme.sh index e84619fd..0397e5d2 100755 --- a/acme.sh +++ b/acme.sh @@ -1119,9 +1119,9 @@ _createcsr() { domainlist="$(_idn "$domainlist")" _debug2 domainlist "$domainlist" if _contains "$domainlist" ","; then - alt="DNS:$domain,DNS:$(echo "$domainlist" | sed "s/,,/,/g" | sed "s/,/,DNS:/g")" + alt="DNS:$(_idn $domain),DNS:$(echo "$domainlist" | sed "s/,,/,/g" | sed "s/,/,DNS:/g")" else - alt="DNS:$domain,DNS:$domainlist" + alt="DNS:$(_idn $domain),DNS:$domainlist" fi #multi _info "Multi domain" "$alt" From acae0ac2a647c7b3c59b8e7bb4d41bfd40b89b73 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 4 May 2019 10:59:00 +0800 Subject: [PATCH 0294/2234] fix RENEW_SKIP code --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 0397e5d2..19af5b01 100755 --- a/acme.sh +++ b/acme.sh @@ -4622,7 +4622,7 @@ renew() { _info "$(__green "Renew: '$Le_Domain'")" if [ ! -f "$DOMAIN_CONF" ]; then _info "'$Le_Domain' is not a issued domain, skip." - return 0 + return $RENEW_SKIP fi if [ "$Le_RenewalDays" ]; then @@ -4676,7 +4676,7 @@ renew() { if [ "$IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then _info "Skip invalid cert for: $Le_Domain" - return 0 + return $RENEW_SKIP fi IS_RENEW="1" From 83768f0531432a3d0de05264240485871f2b8703 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 4 May 2019 11:02:10 +0800 Subject: [PATCH 0295/2234] reduce info message --- notify/mailgun.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/mailgun.sh b/notify/mailgun.sh index 1689a0b9..7f5c914a 100644 --- a/notify/mailgun.sh +++ b/notify/mailgun.sh @@ -30,7 +30,7 @@ mailgun_send() { MAILGUN_REGION="${MAILGUN_REGION:-$(_readaccountconf_mutable MAILGUN_REGION)}" if [ -z "$MAILGUN_REGION" ]; then MAILGUN_REGION="" - _info "The MAILGUN_REGION is not set, so use the default us region." + _debug "The MAILGUN_REGION is not set, so use the default us region." _MAILGUN_BASE="https://api.mailgun.net/v3" else _saveaccountconf_mutable MAILGUN_REGION "$MAILGUN_REGION" @@ -83,7 +83,7 @@ mailgun_send() { _debug "_msg" "$_msg" _mailgun_rest POST "$_msg" if _contains "$response" "Queued. Thank you."; then - _info "mailgun send success." + _debug "mailgun send success." return 0 else _err "mailgun send error" From 5d468f7ca5cbf82982bc4d07e4a5762157e2c2c6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 4 May 2019 11:06:25 +0800 Subject: [PATCH 0296/2234] add notifications --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8d40d51a..ab3412c1 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ - DOES NOT require `root/sudoer` access. - Docker friendly - IPv6 support +- Cron job notifications for renewal or error etc. It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt. @@ -432,20 +433,25 @@ acme.sh --upgrade --auto-upgrade 0 https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR -# 16. Under the Hood +# 16. Send notifications in cronjob + +https://github.com/Neilpang/acme.sh/wiki/notify + + +# 17. Under the Hood Speak ACME language using shell, directly to "Let's Encrypt". TODO: -# 17. Acknowledgments +# 18. Acknowledgments 1. Acme-tiny: https://github.com/diafygi/acme-tiny 2. ACME protocol: https://github.com/ietf-wg-acme/acme -# 18. License & Others +# 19. License & Others License is GPLv3 @@ -454,7 +460,7 @@ Please Star and Fork me. [Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome. -# 19. Donate +# 20. Donate Your donation makes **acme.sh** better: 1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/) From 2b765fdedb84532052918a5524da5090604dbe18 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 4 May 2019 11:54:59 +0800 Subject: [PATCH 0297/2234] add set-notify --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 68385d7d..0e8b58d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,6 +48,7 @@ RUN for verb in help \ createCSR \ deactivate \ deactivate-account \ + set-notify \ ; do \ printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \ ; done From b8f4fa359cea941397b6aa867efb57e082025eed Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Mon, 6 May 2019 17:12:50 +0200 Subject: [PATCH 0298/2234] Add acmeproxy provider --- dnsapi/dns_acmeproxy.sh | 85 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 dnsapi/dns_acmeproxy.sh diff --git a/dnsapi/dns_acmeproxy.sh b/dnsapi/dns_acmeproxy.sh new file mode 100644 index 00000000..762f8652 --- /dev/null +++ b/dnsapi/dns_acmeproxy.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env sh + +## API integration by Jason Keller and Elijah Tenai +## +## Report any bugs via https://github.com/jasonkeller/acme.sh + +dns_acmeproxy_add() { + fulldomain="${1}" + txtvalue="${2}" + action="present" + + _debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'" + _acmeproxy_request $fulldomain $txtvalue $action +} + +dns_acmeproxy_rm() { + fulldomain="${1}" + txtvalue="${2}" + action="cleanup" + + _debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'" + _acmeproxy_request $fulldomain $txtvalue $action +} + +_acmeproxy_request() { + + ## Nothing to see here, just some housekeeping + fulldomain=$1 + txtvalue=$2 + action=$3 + + _info "Using acmeproxy" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + ACMEPROXY_ENDPOINT="${ACMEPROXY_ENDPOINT:-$(_readaccountconf_mutable ACMEPROXY_ENDPOINT)}" + ACMEPROXY_USERNAME="${ACMEPROXY_USERNAME:-$(_readaccountconf_mutable ACMEPROXY_USERNAME)}" + ACMEPROXY_PASSWORD="${ACMEPROXY_PASSWORD:-$(_readaccountconf_mutable ACMEPROXY_PASSWORD)}" + + ## Check for the endpoint + if [ -z "ACMEPROXY_ENDPOINT" ]; then + ACMEPROXY_ENDPOINT="" + _err "You didn't specify the endpoint" + _err "Please set them via 'export ACMEPROXY_ENDPOINT=https://ip:port' and try again." + return 1 + fi + + ## Check for the credentials + if [ -z "$ACMEPROXY_USERNAME" ] || [ -z "$ACMEPROXY_PASSWORD" ]; then + ACMEPROXY_USERNAME="" + ACMEPROXY_PASSWORD="" + _err "You didn't set username and password" + _err "Please set them via 'export ACMEPROXY_USERNAME=...' and 'export ACMEPROXY_PASSWORD=...' and try again." + return 1 + fi + + ## Save the credentials to the account file + _saveaccountconf_mutable ACMEPROXY_ENDPOINT "$ACMEPROXY_ENDPOINT" + _saveaccountconf_mutable ACMEPROXY_USERNAME "$ACMEPROXY_USERNAME" + _saveaccountconf_mutable ACMEPROXY_PASSWORD "$ACMEPROXY_PASSWORD" + + ## Base64 encode the credentials + credentials=$(printf "%b" "$ACMEPROXY_USERNAME:$ACMEPROXY_PASSWORD" | _base64) + + ## Construct the HTTP Authorization header + export _H1="Authorization: Basic $credentials" + export _H2="Accept: application/json" + export _H3="Content-Type: application/json" + + ## Add the challenge record to the acmeproxy grid member + response="$(_post "{\"fqdn\": \"$fulldomain.\", \"value\": \"$txtvalue\"}" "$ACMEPROXY_ENDPOINT/$action" "" "POST")" + + ## Let's see if we get something intelligible back from the unit + if echo "$response" | grep "\"$txtvalue\"" > /dev/null; then + _info "Successfully created the txt record" + return 0 + else + _err "Error encountered during record addition" + _err "$response" + return 1 + fi + +} + +#################### Private functions below ################################## From 68142c9835d77e9b564056460ff1116b1636395f Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Mon, 6 May 2019 17:14:31 +0200 Subject: [PATCH 0299/2234] Update description --- dnsapi/dns_acmeproxy.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_acmeproxy.sh b/dnsapi/dns_acmeproxy.sh index 762f8652..36bfc00c 100644 --- a/dnsapi/dns_acmeproxy.sh +++ b/dnsapi/dns_acmeproxy.sh @@ -1,8 +1,9 @@ #!/usr/bin/env sh -## API integration by Jason Keller and Elijah Tenai +## Acmeproxy DNS provider to be used with acmeproxy (http://github.com/mdbraber/acmeproxy) +## API integration by Maarten den Braber ## -## Report any bugs via https://github.com/jasonkeller/acme.sh +## Report any bugs via https://github.com/mdbraber/acme.sh dns_acmeproxy_add() { fulldomain="${1}" From c297aff99bd1abca6b0b554d7681bc073af45e33 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Mon, 6 May 2019 18:31:58 +0200 Subject: [PATCH 0300/2234] Improved logging description --- dnsapi/dns_acmeproxy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_acmeproxy.sh b/dnsapi/dns_acmeproxy.sh index 36bfc00c..7f17ae6f 100644 --- a/dnsapi/dns_acmeproxy.sh +++ b/dnsapi/dns_acmeproxy.sh @@ -73,7 +73,7 @@ _acmeproxy_request() { ## Let's see if we get something intelligible back from the unit if echo "$response" | grep "\"$txtvalue\"" > /dev/null; then - _info "Successfully created the txt record" + _info "Successfully updated the txt record" return 0 else _err "Error encountered during record addition" From 585ef998d0ee5fe752484ddef13b92a3ce7dca88 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Tue, 7 May 2019 16:47:23 +0200 Subject: [PATCH 0301/2234] Fixed CI errors --- dnsapi/dns_acmeproxy.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_acmeproxy.sh b/dnsapi/dns_acmeproxy.sh index 7f17ae6f..656e3104 100644 --- a/dnsapi/dns_acmeproxy.sh +++ b/dnsapi/dns_acmeproxy.sh @@ -11,7 +11,7 @@ dns_acmeproxy_add() { action="present" _debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'" - _acmeproxy_request $fulldomain $txtvalue $action + _acmeproxy_request "$fulldomain" "$txtvalue" "$action" } dns_acmeproxy_rm() { @@ -20,7 +20,7 @@ dns_acmeproxy_rm() { action="cleanup" _debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'" - _acmeproxy_request $fulldomain $txtvalue $action + _acmeproxy_request "$fulldomain" "$txtvalue" "$action" } _acmeproxy_request() { @@ -39,7 +39,7 @@ _acmeproxy_request() { ACMEPROXY_PASSWORD="${ACMEPROXY_PASSWORD:-$(_readaccountconf_mutable ACMEPROXY_PASSWORD)}" ## Check for the endpoint - if [ -z "ACMEPROXY_ENDPOINT" ]; then + if [ -z "$ACMEPROXY_ENDPOINT" ]; then ACMEPROXY_ENDPOINT="" _err "You didn't specify the endpoint" _err "Please set them via 'export ACMEPROXY_ENDPOINT=https://ip:port' and try again." @@ -72,7 +72,7 @@ _acmeproxy_request() { response="$(_post "{\"fqdn\": \"$fulldomain.\", \"value\": \"$txtvalue\"}" "$ACMEPROXY_ENDPOINT/$action" "" "POST")" ## Let's see if we get something intelligible back from the unit - if echo "$response" | grep "\"$txtvalue\"" > /dev/null; then + if echo "$response" | grep "\"$txtvalue\"" >/dev/null; then _info "Successfully updated the txt record" return 0 else From 11ecbd27be9fd92143c05ed22294d7059284419f Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 8 May 2019 22:07:27 +0800 Subject: [PATCH 0302/2234] fix punycode domain --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 6898eb1a..cd93189f 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -161,7 +161,7 @@ _get_root() { return 1 fi - if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) From 1a126b700feb18f780a826d943e92cdb3165ce37 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 8 May 2019 22:13:33 +0800 Subject: [PATCH 0303/2234] fix https://github.com/Neilpang/acme.sh/issues/2252 --- deploy/haproxy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 2479aebd..836c5182 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -179,7 +179,7 @@ haproxy_deploy() { return ${_ret} fi else - [ -f "${_issuer}" ] _err "Issuer file update not requested but .issuer file exists" + [ -f "${_issuer}" ] && _err "Issuer file update not requested but .issuer file exists" fi # Update .ocsp file if certificate was requested with --ocsp/--ocsp-must-staple option From f9e3a2132f1d957b0190243cc703a472eb20ee7a Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Thu, 9 May 2019 21:14:26 +0200 Subject: [PATCH 0304/2234] Username/password no longer required --- dnsapi/dns_acmeproxy.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dnsapi/dns_acmeproxy.sh b/dnsapi/dns_acmeproxy.sh index 656e3104..8ca3eb0a 100644 --- a/dnsapi/dns_acmeproxy.sh +++ b/dnsapi/dns_acmeproxy.sh @@ -46,15 +46,6 @@ _acmeproxy_request() { return 1 fi - ## Check for the credentials - if [ -z "$ACMEPROXY_USERNAME" ] || [ -z "$ACMEPROXY_PASSWORD" ]; then - ACMEPROXY_USERNAME="" - ACMEPROXY_PASSWORD="" - _err "You didn't set username and password" - _err "Please set them via 'export ACMEPROXY_USERNAME=...' and 'export ACMEPROXY_PASSWORD=...' and try again." - return 1 - fi - ## Save the credentials to the account file _saveaccountconf_mutable ACMEPROXY_ENDPOINT "$ACMEPROXY_ENDPOINT" _saveaccountconf_mutable ACMEPROXY_USERNAME "$ACMEPROXY_USERNAME" From d9ef8c17792f4dcf4bd40b9dae5890f47e23d087 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 12 May 2019 00:25:36 +0200 Subject: [PATCH 0305/2234] add sendmail notify --- notify/sendmail.sh | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 notify/sendmail.sh diff --git a/notify/sendmail.sh b/notify/sendmail.sh new file mode 100644 index 00000000..3964e904 --- /dev/null +++ b/notify/sendmail.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env sh + +#Support sendmail + +#SENDMAIL_BIN="sendmail" +#SENDMAIL_FROM="yyyy@gmail.com" +#SENDMAIL_TO="yyyy@gmail.com" + +sendmail_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + SENDMAIL_BIN="${SENDMAIL_BIN:-$(_readaccountconf_mutable SENDMAIL_BIN)}" + if [ -z "$SENDMAIL_BIN" ]; then + SENDMAIL_BIN="sendmail" + _info "The SENDMAIL_BIN is not set, so use the default value: $SENDMAIL_BIN" + fi + if ! _exists "$SENDMAIL_BIN"; then + _err "Please install sendmail first." + return 1 + fi + _saveaccountconf_mutable SENDMAIL_BIN "$SENDMAIL_BIN" + + SENDMAIL_FROM="${SENDMAIL_FROM:-$(_readaccountconf_mutable SENDMAIL_FROM)}" + if [ -z "$SENDMAIL_FROM" ]; then + SENDMAIL_FROM="$USER@$HOSTNAME" + _info "The SENDMAIL_FROM is not set, so use the default value: $SENDMAIL_FROM" + fi + _saveaccountconf_mutable SENDMAIL_FROM "$SENDMAIL_FROM" + + SENDMAIL_TO="${SENDMAIL_TO:-$(_readaccountconf_mutable SENDMAIL_TO)}" + if [ -z "$SENDMAIL_TO" ]; then + SENDMAIL_TO="$(_readaccountconf ACCOUNT_EMAIL)" + _info "The SENDMAIL_TO is not set, so use the account email: $SENDMAIL_TO" + fi + _saveaccountconf_mutable SENDMAIL_TO "$SENDMAIL_TO" + + subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" + error=$( { echo "From: $SENDMAIL_FROM +To: $SENDMAIL_TO +Subject: $subject +Content-Type: text/plain; charset=utf-8 + +$_content +" | "$SENDMAIL_BIN" -f "$SENDMAIL_FROM" "$SENDMAIL_TO"; } 2>&1 ) + + if [ $? -ne 0 ]; then + _debug "sendmail send error." + _err "$error" + return 1 + fi + + _debug "sendmail send success." + return 0 +} From 773e1d4e059fce80bb92bd43f3c23ab5c764b2d0 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 12 May 2019 00:34:46 +0200 Subject: [PATCH 0306/2234] use hostname function instead of HOSTNAME env variable --- notify/sendmail.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/sendmail.sh b/notify/sendmail.sh index 3964e904..162b5393 100644 --- a/notify/sendmail.sh +++ b/notify/sendmail.sh @@ -27,7 +27,7 @@ sendmail_send() { SENDMAIL_FROM="${SENDMAIL_FROM:-$(_readaccountconf_mutable SENDMAIL_FROM)}" if [ -z "$SENDMAIL_FROM" ]; then - SENDMAIL_FROM="$USER@$HOSTNAME" + SENDMAIL_FROM="$USER@$(hostname -f)" _info "The SENDMAIL_FROM is not set, so use the default value: $SENDMAIL_FROM" fi _saveaccountconf_mutable SENDMAIL_FROM "$SENDMAIL_FROM" From 4f0354860885807fe3c29321a4400cce0eb721e5 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 12 May 2019 00:35:47 +0200 Subject: [PATCH 0307/2234] typos --- notify/sendmail.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/sendmail.sh b/notify/sendmail.sh index 162b5393..7c253e9c 100644 --- a/notify/sendmail.sh +++ b/notify/sendmail.sh @@ -40,13 +40,13 @@ sendmail_send() { _saveaccountconf_mutable SENDMAIL_TO "$SENDMAIL_TO" subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" - error=$( { echo "From: $SENDMAIL_FROM + error=$({ echo "From: $SENDMAIL_FROM To: $SENDMAIL_TO Subject: $subject Content-Type: text/plain; charset=utf-8 $_content -" | "$SENDMAIL_BIN" -f "$SENDMAIL_FROM" "$SENDMAIL_TO"; } 2>&1 ) +" | "$SENDMAIL_BIN" -f "$SENDMAIL_FROM" "$SENDMAIL_TO"; } 2>&1) if [ $? -ne 0 ]; then _debug "sendmail send error." From a4b83895a37750801c5fbf250bc69386a896146e Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 12 May 2019 15:34:58 +0800 Subject: [PATCH 0308/2234] fix https://github.com/Neilpang/acme.sh/issues/2258 --- notify/mailgun.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/notify/mailgun.sh b/notify/mailgun.sh index 7f5c914a..4b6ee3ba 100644 --- a/notify/mailgun.sh +++ b/notify/mailgun.sh @@ -9,7 +9,10 @@ #MAILGUN_API_DOMAIN="xxxxxx.com" #optional, use the default sandbox domain #MAILGUN_FROM="xxx@xxxxx.com" #optional, use the default sendbox account -_MAILGUN_BASE="https://api.mailgun.net/v3" +_MAILGUN_BASE_US="https://api.mailgun.net/v3" +_MAILGUN_BASE_EU="https://api.eu.mailgun.net/v3" + +_MAILGUN_BASE="$_MAILGUN_BASE_US" # subject content statusCode mailgun_send() { @@ -31,12 +34,17 @@ mailgun_send() { if [ -z "$MAILGUN_REGION" ]; then MAILGUN_REGION="" _debug "The MAILGUN_REGION is not set, so use the default us region." - _MAILGUN_BASE="https://api.mailgun.net/v3" + _MAILGUN_BASE="$_MAILGUN_BASE_US" else + MAILGUN_REGION="$(echo "$MAILGUN_REGION" | _lower_case)" _saveaccountconf_mutable MAILGUN_REGION "$MAILGUN_REGION" - _MAILGUN_BASE="https://api.eu.mailgun.net/v3" + if [ "$MAILGUN_REGION" = "us" ]; then + _MAILGUN_BASE="$_MAILGUN_BASE_US" + else + _MAILGUN_BASE="$_MAILGUN_BASE_EU" + fi fi - + _debug _MAILGUN_BASE "$_MAILGUN_BASE" MAILGUN_TO="${MAILGUN_TO:-$(_readaccountconf_mutable MAILGUN_TO)}" if [ -z "$MAILGUN_TO" ]; then MAILGUN_TO="" From f6f6d89e0683422338c55d2a6b8b3c97fe66b403 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 12 May 2019 10:41:32 +0200 Subject: [PATCH 0309/2234] move sendmail notify to mail notify --- notify/mail.sh | 64 +++++++++++++++++++++++++++++++++++++++++++--- notify/sendmail.sh | 59 ------------------------------------------ 2 files changed, 61 insertions(+), 62 deletions(-) delete mode 100644 notify/sendmail.sh diff --git a/notify/mail.sh b/notify/mail.sh index 3dfef0be..949e8b5c 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -1,6 +1,9 @@ #!/usr/bin/env sh -# support local mail app +#Support local mail app + +#MAIL_FROM="yyyy@gmail.com" +#MAIL_TO="yyyy@gmail.com" mail_send() { _subject="$1" @@ -10,6 +13,61 @@ mail_send() { _debug "_content" "$_content" _debug "_statusCode" "$_statusCode" - _err "Not implemented yet." - return 1 + if _exists "sendmail"; then + _MAIL_BIN="sendmail" + elif _exists "mail"; then + _MAIL_BIN="mail" + else + _err "Please install mail or sendmail first." + return 1 + fi + + MAIL_FROM="${MAIL_FROM:-$(_readaccountconf_mutable MAIL_FROM)}" + if [ -z "$MAIL_FROM" ]; then + MAIL_FROM="$USER@$(hostname -f)" + _info "The MAIL_FROM is not set, so use the default value: $MAIL_FROM" + fi + _saveaccountconf_mutable MAIL_FROM "$MAIL_FROM" + + MAIL_TO="${MAIL_TO:-$(_readaccountconf_mutable MAIL_TO)}" + if [ -z "$MAIL_TO" ]; then + MAIL_TO="$(_readaccountconf ACCOUNT_EMAIL)" + _info "The MAIL_TO is not set, so use the account email: $MAIL_TO" + fi + _saveaccountconf_mutable MAIL_TO "$MAIL_TO" + + subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" + result=$({ _mail_body | _mail_send; } 2>&1) + + if [ $? -ne 0 ]; then + _debug "mail send error." + _err "$result" + return 1 + fi + + _debug "mail send success." + return 0 +} + +_mail_send() { + case "$_MAIL_BIN" in + sendmail) + sendmail -f "$MAIL_FROM" "$MAIL_TO" + ;; + mail) + mail -s "$subject" -a "From:$MAIL_FROM" -a "Content-Type:text/plain; charset=utf-8" "$MAIL_TO" + ;; + esac +} + +_mail_body() { + if [ "$_MAIL_BIN" = "sendmail" ]; then + echo "From: $MAIL_FROM" + echo "To: $MAIL_TO" + echo "Subject: =?UTF-8?B?$(echo "$_subject" | _base64)?=" + echo "Content-Type: text/plain; charset=utf-8" + echo + fi + + echo "$_content" } diff --git a/notify/sendmail.sh b/notify/sendmail.sh deleted file mode 100644 index 7c253e9c..00000000 --- a/notify/sendmail.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env sh - -#Support sendmail - -#SENDMAIL_BIN="sendmail" -#SENDMAIL_FROM="yyyy@gmail.com" -#SENDMAIL_TO="yyyy@gmail.com" - -sendmail_send() { - _subject="$1" - _content="$2" - _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped - _debug "_subject" "$_subject" - _debug "_content" "$_content" - _debug "_statusCode" "$_statusCode" - - SENDMAIL_BIN="${SENDMAIL_BIN:-$(_readaccountconf_mutable SENDMAIL_BIN)}" - if [ -z "$SENDMAIL_BIN" ]; then - SENDMAIL_BIN="sendmail" - _info "The SENDMAIL_BIN is not set, so use the default value: $SENDMAIL_BIN" - fi - if ! _exists "$SENDMAIL_BIN"; then - _err "Please install sendmail first." - return 1 - fi - _saveaccountconf_mutable SENDMAIL_BIN "$SENDMAIL_BIN" - - SENDMAIL_FROM="${SENDMAIL_FROM:-$(_readaccountconf_mutable SENDMAIL_FROM)}" - if [ -z "$SENDMAIL_FROM" ]; then - SENDMAIL_FROM="$USER@$(hostname -f)" - _info "The SENDMAIL_FROM is not set, so use the default value: $SENDMAIL_FROM" - fi - _saveaccountconf_mutable SENDMAIL_FROM "$SENDMAIL_FROM" - - SENDMAIL_TO="${SENDMAIL_TO:-$(_readaccountconf_mutable SENDMAIL_TO)}" - if [ -z "$SENDMAIL_TO" ]; then - SENDMAIL_TO="$(_readaccountconf ACCOUNT_EMAIL)" - _info "The SENDMAIL_TO is not set, so use the account email: $SENDMAIL_TO" - fi - _saveaccountconf_mutable SENDMAIL_TO "$SENDMAIL_TO" - - subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" - error=$({ echo "From: $SENDMAIL_FROM -To: $SENDMAIL_TO -Subject: $subject -Content-Type: text/plain; charset=utf-8 - -$_content -" | "$SENDMAIL_BIN" -f "$SENDMAIL_FROM" "$SENDMAIL_TO"; } 2>&1) - - if [ $? -ne 0 ]; then - _debug "sendmail send error." - _err "$error" - return 1 - fi - - _debug "sendmail send success." - return 0 -} From a89a62071b3728e1e6ad885fe3e9441cfb0b78bd Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 12 May 2019 13:03:01 +0200 Subject: [PATCH 0310/2234] cleanup, lint --- notify/mail.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index 949e8b5c..6c6ef4e2 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -18,7 +18,7 @@ mail_send() { elif _exists "mail"; then _MAIL_BIN="mail" else - _err "Please install mail or sendmail first." + _err "Please install sendmail or mail first." return 1 fi @@ -36,6 +36,7 @@ mail_send() { fi _saveaccountconf_mutable MAIL_TO "$MAIL_TO" + contenttype="text/plain; charset=utf-8" subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" result=$({ _mail_body | _mail_send; } 2>&1) @@ -52,10 +53,10 @@ mail_send() { _mail_send() { case "$_MAIL_BIN" in sendmail) - sendmail -f "$MAIL_FROM" "$MAIL_TO" + "$_MAIL_BIN" -f "$MAIL_FROM" "$MAIL_TO" ;; mail) - mail -s "$subject" -a "From:$MAIL_FROM" -a "Content-Type:text/plain; charset=utf-8" "$MAIL_TO" + "$_MAIL_BIN" -s "$subject" -a "From:$MAIL_FROM" -a "Content-Type:$contenttype" "$MAIL_TO" ;; esac } @@ -64,8 +65,8 @@ _mail_body() { if [ "$_MAIL_BIN" = "sendmail" ]; then echo "From: $MAIL_FROM" echo "To: $MAIL_TO" - echo "Subject: =?UTF-8?B?$(echo "$_subject" | _base64)?=" - echo "Content-Type: text/plain; charset=utf-8" + echo "Subject: $subject" + echo "Content-Type: $contenttype" echo fi From 10801bfb255a3dd0894ca8db1694ee019fcc4018 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 12 May 2019 13:06:45 +0200 Subject: [PATCH 0311/2234] use mutt if installed --- notify/mail.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/notify/mail.sh b/notify/mail.sh index 6c6ef4e2..cfd381fc 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -15,6 +15,8 @@ mail_send() { if _exists "sendmail"; then _MAIL_BIN="sendmail" + elif _exists "mutt"; then + _MAIL_BIN="mutt" elif _exists "mail"; then _MAIL_BIN="mail" else @@ -55,6 +57,9 @@ _mail_send() { sendmail) "$_MAIL_BIN" -f "$MAIL_FROM" "$MAIL_TO" ;; + mutt) + "$_MAIL_BIN" -s "$subject" -e "my_hdr From:$MAIL_FROM" -e "my_hdr Content-Type:$contenttype" "$MAIL_TO" + ;; mail) "$_MAIL_BIN" -s "$subject" -a "From:$MAIL_FROM" -a "Content-Type:$contenttype" "$MAIL_TO" ;; From f6ca92337b62801222ee643cfb9def25742153b9 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 12 May 2019 20:24:02 +0200 Subject: [PATCH 0312/2234] remove unsupported options from mail and mutt command --- notify/mail.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index cfd381fc..cd926270 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -57,11 +57,8 @@ _mail_send() { sendmail) "$_MAIL_BIN" -f "$MAIL_FROM" "$MAIL_TO" ;; - mutt) - "$_MAIL_BIN" -s "$subject" -e "my_hdr From:$MAIL_FROM" -e "my_hdr Content-Type:$contenttype" "$MAIL_TO" - ;; - mail) - "$_MAIL_BIN" -s "$subject" -a "From:$MAIL_FROM" -a "Content-Type:$contenttype" "$MAIL_TO" + mutt|mail) + "$_MAIL_BIN" -s "$_subject" "$MAIL_TO" ;; esac } From 91c09dd0a076ff4d037dc3fc65a39d799fe4e903 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 12 May 2019 20:26:31 +0200 Subject: [PATCH 0313/2234] ssmtp --- notify/mail.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index cd926270..6bb7520b 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -15,12 +15,14 @@ mail_send() { if _exists "sendmail"; then _MAIL_BIN="sendmail" + elif _exists "ssmtp"; then + _MAIL_BIN="ssmtp" elif _exists "mutt"; then _MAIL_BIN="mutt" elif _exists "mail"; then _MAIL_BIN="mail" else - _err "Please install sendmail or mail first." + _err "Please install sendmail, ssmtp, mutt or mail first." return 1 fi @@ -57,6 +59,9 @@ _mail_send() { sendmail) "$_MAIL_BIN" -f "$MAIL_FROM" "$MAIL_TO" ;; + ssmtp) + "$_MAIL_BIN" "$MAIL_TO" + ;; mutt|mail) "$_MAIL_BIN" -s "$_subject" "$MAIL_TO" ;; @@ -64,7 +69,7 @@ _mail_send() { } _mail_body() { - if [ "$_MAIL_BIN" = "sendmail" ]; then + if [ "$_MAIL_BIN" = "sendmail" ] || [ "$_MAIL_BIN" = "ssmtp" ]; then echo "From: $MAIL_FROM" echo "To: $MAIL_TO" echo "Subject: $subject" From d180f01b458d607559d28b853a2d42af2e42063a Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 12 May 2019 22:28:37 +0200 Subject: [PATCH 0314/2234] typos --- notify/mail.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/mail.sh b/notify/mail.sh index 6bb7520b..034fc03c 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -62,7 +62,7 @@ _mail_send() { ssmtp) "$_MAIL_BIN" "$MAIL_TO" ;; - mutt|mail) + mutt | mail) "$_MAIL_BIN" -s "$_subject" "$MAIL_TO" ;; esac From 5e165819a1df9d6eef5f55bd6fd464f231cec570 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Mon, 13 May 2019 08:45:57 +0200 Subject: [PATCH 0315/2234] Update authentication logic / info --- dnsapi/dns_acmeproxy.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_acmeproxy.sh b/dnsapi/dns_acmeproxy.sh index 8ca3eb0a..d4a0e172 100644 --- a/dnsapi/dns_acmeproxy.sh +++ b/dnsapi/dns_acmeproxy.sh @@ -51,13 +51,19 @@ _acmeproxy_request() { _saveaccountconf_mutable ACMEPROXY_USERNAME "$ACMEPROXY_USERNAME" _saveaccountconf_mutable ACMEPROXY_PASSWORD "$ACMEPROXY_PASSWORD" - ## Base64 encode the credentials - credentials=$(printf "%b" "$ACMEPROXY_USERNAME:$ACMEPROXY_PASSWORD" | _base64) + if [ -z "$ACMEPROXY_USERNAME" ] || [ -z "$ACMEPROXY_PASSWORD" ]; then + _info "ACMEPROXY_USERNAME and/or ACMEPROXY_PASSWORD not set - using without client authentication! Make sure you're using server authentication (e.g. IP-based)" + export _H1="Accept: application/json" + export _H2="Content-Type: application/json" + else + ## Base64 encode the credentials + credentials=$(printf "%b" "$ACMEPROXY_USERNAME:$ACMEPROXY_PASSWORD" | _base64) - ## Construct the HTTP Authorization header - export _H1="Authorization: Basic $credentials" - export _H2="Accept: application/json" - export _H3="Content-Type: application/json" + ## Construct the HTTP Authorization header + export _H1="Authorization: Basic $credentials" + export _H2="Accept: application/json" + export _H3="Content-Type: application/json" + fi ## Add the challenge record to the acmeproxy grid member response="$(_post "{\"fqdn\": \"$fulldomain.\", \"value\": \"$txtvalue\"}" "$ACMEPROXY_ENDPOINT/$action" "" "POST")" From d509ef7581789697164a38e2bdd5ae12617dfb7c Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Mon, 13 May 2019 16:06:24 +0200 Subject: [PATCH 0316/2234] make MAIL_FROM not required --- notify/mail.sh | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index 034fc03c..33ed8fe9 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -27,11 +27,14 @@ mail_send() { fi MAIL_FROM="${MAIL_FROM:-$(_readaccountconf_mutable MAIL_FROM)}" - if [ -z "$MAIL_FROM" ]; then - MAIL_FROM="$USER@$(hostname -f)" - _info "The MAIL_FROM is not set, so use the default value: $MAIL_FROM" + if [ -n "$MAIL_FROM" ]; then + if ! _contains "$MAIL_FROM" "@"; then + _err "It seems that the MAIL_FROM=$MAIL_FROM is not a valid email address." + return 1 + fi + + _saveaccountconf_mutable MAIL_FROM "$MAIL_FROM" fi - _saveaccountconf_mutable MAIL_FROM "$MAIL_FROM" MAIL_TO="${MAIL_TO:-$(_readaccountconf_mutable MAIL_TO)}" if [ -z "$MAIL_TO" ]; then @@ -57,7 +60,11 @@ mail_send() { _mail_send() { case "$_MAIL_BIN" in sendmail) - "$_MAIL_BIN" -f "$MAIL_FROM" "$MAIL_TO" + if [ -n "$MAIL_FROM" ]; then + "$_MAIL_BIN" -f "$MAIL_FROM" "$MAIL_TO" + else + "$_MAIL_BIN" "$MAIL_TO" + fi ;; ssmtp) "$_MAIL_BIN" "$MAIL_TO" @@ -70,7 +77,10 @@ _mail_send() { _mail_body() { if [ "$_MAIL_BIN" = "sendmail" ] || [ "$_MAIL_BIN" = "ssmtp" ]; then - echo "From: $MAIL_FROM" + if [ -n "$MAIL_FROM" ]; then + echo "From: $MAIL_FROM" + fi + echo "To: $MAIL_TO" echo "Subject: $subject" echo "Content-Type: $contenttype" From 0093dc3d32cf26e2815ddb476e3bd3398604c985 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 13 May 2019 23:30:31 +0800 Subject: [PATCH 0317/2234] fix https://github.com/Neilpang/acme.sh/issues/2256 --- acme.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index 19af5b01..4c1e45d6 100755 --- a/acme.sh +++ b/acme.sh @@ -1114,14 +1114,14 @@ _createcsr() { elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then #single domain _info "Single domain" "$domain" - printf -- "\nsubjectAltName=DNS:$(_idn $domain)" >>"$csrconf" + printf -- "\nsubjectAltName=DNS:$(_idn "$domain")" >>"$csrconf" else domainlist="$(_idn "$domainlist")" _debug2 domainlist "$domainlist" if _contains "$domainlist" ","; then - alt="DNS:$(_idn $domain),DNS:$(echo "$domainlist" | sed "s/,,/,/g" | sed "s/,/,DNS:/g")" + alt="DNS:$(_idn "$domain"),DNS:$(echo "$domainlist" | sed "s/,,/,/g" | sed "s/,/,DNS:/g")" else - alt="DNS:$(_idn $domain),DNS:$domainlist" + alt="DNS:$(_idn "$domain"),DNS:$domainlist" fi #multi _info "Multi domain" "$alt" @@ -3648,9 +3648,9 @@ _check_dns_entries() { for entry in $dns_entries; do d=$(_getfield "$entry" 1) txtdomain=$(_getfield "$entry" 2) - txtdomain=$(_idn $txtdomain) + txtdomain=$(_idn "$txtdomain") aliasDomain=$(_getfield "$entry" 3) - aliasDomain=$(_idn $aliasDomain) + aliasDomain=$(_idn "$aliasDomain") txt=$(_getfield "$entry" 5) d_api=$(_getfield "$entry" 6) _debug "d" "$d" @@ -3847,7 +3847,7 @@ issue() { if [ -z "$vlist" ]; then if [ "$ACME_VERSION" = "2" ]; then #make new order request - _identifiers="{\"type\":\"dns\",\"value\":\"$(_idn $_main_domain)\"}" + _identifiers="{\"type\":\"dns\",\"value\":\"$(_idn "$_main_domain")\"}" _w_index=1 while true; do d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")" @@ -3856,7 +3856,7 @@ issue() { if [ -z "$d" ]; then break fi - _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn $d)\"}" + _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn "$d")\"}" done _debug2 _identifiers "$_identifiers" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then @@ -3944,7 +3944,7 @@ $_authorizations_map" fi if [ "$ACME_VERSION" = "2" ]; then - response="$(echo "$_authorizations_map" | grep "^$(_idn $d)," | sed "s/$d,//")" + response="$(echo "$_authorizations_map" | grep "^$(_idn "$d")," | sed "s/$d,//")" _debug2 "response" "$response" if [ -z "$response" ]; then _err "get to authz error." From 7b6ebc5c989350c113ee3516d47192dffaaac128 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Mon, 13 May 2019 17:42:07 +0200 Subject: [PATCH 0318/2234] try to use ACCOUNT_MAIL if MAIL_FROM is not set --- notify/mail.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index 33ed8fe9..a1970c0a 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -37,11 +37,21 @@ mail_send() { fi MAIL_TO="${MAIL_TO:-$(_readaccountconf_mutable MAIL_TO)}" - if [ -z "$MAIL_TO" ]; then + if [ -n "$MAIL_TO" ]; then + if ! _contains "$MAIL_TO" "@"; then + _err "It seems that the MAIL_TO=$MAIL_TO is not a valid email address." + return 1 + fi + + _saveaccountconf_mutable MAIL_TO "$MAIL_TO" + else MAIL_TO="$(_readaccountconf ACCOUNT_EMAIL)" - _info "The MAIL_TO is not set, so use the account email: $MAIL_TO" + + if [ -z "$MAIL_TO" ]; then + _err "It seems that account email is empty." + return 1 + fi fi - _saveaccountconf_mutable MAIL_TO "$MAIL_TO" contenttype="text/plain; charset=utf-8" subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" From e3052c8c57279f5732d849e63530efba90cd5af6 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Mon, 13 May 2019 17:44:04 +0200 Subject: [PATCH 0319/2234] expose MAIL_BIN variable --- notify/mail.sh | 54 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index a1970c0a..44148d99 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -2,6 +2,7 @@ #Support local mail app +#MAIL_BIN="sendmail" #MAIL_FROM="yyyy@gmail.com" #MAIL_TO="yyyy@gmail.com" @@ -13,18 +14,18 @@ mail_send() { _debug "_content" "$_content" _debug "_statusCode" "$_statusCode" - if _exists "sendmail"; then - _MAIL_BIN="sendmail" - elif _exists "ssmtp"; then - _MAIL_BIN="ssmtp" - elif _exists "mutt"; then - _MAIL_BIN="mutt" - elif _exists "mail"; then - _MAIL_BIN="mail" - else - _err "Please install sendmail, ssmtp, mutt or mail first." + unset -f _MAIL_BIN _MAIL_BODY _MAIL_CMD + + MAIL_BIN="${MAIL_BIN:-$(_readaccountconf_mutable MAIL_BIN)}" + if [ -n "$MAIL_BIN" ] && ! _exists "$MAIL_BIN"; then + _err "It seems that the command $MAIL_BIN is not in path." return 1 fi + _MAIL_CMD=$(_mail_cmnd) + if [ -n "$MAIL_BIN" ]; then + _saveaccountconf_mutable MAIL_BIN "$MAIL_BIN" + fi + _MAIL_BODY=$(_mail_body) MAIL_FROM="${MAIL_FROM:-$(_readaccountconf_mutable MAIL_FROM)}" if [ -n "$MAIL_FROM" ]; then @@ -47,6 +48,8 @@ mail_send() { else MAIL_TO="$(_readaccountconf ACCOUNT_EMAIL)" + echo "MAIL_TO: $MAIL_TO" + if [ -z "$MAIL_TO" ]; then _err "It seems that account email is empty." return 1 @@ -55,7 +58,7 @@ mail_send() { contenttype="text/plain; charset=utf-8" subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" - result=$({ _mail_body | _mail_send; } 2>&1) + result=$({ echo "$_MAIL_BODY" | eval "$_MAIL_CMD"; } 2>&1) if [ $? -ne 0 ]; then _debug "mail send error." @@ -67,20 +70,39 @@ mail_send() { return 0 } -_mail_send() { +_mail_cmnd() { + if [ -n "$MAIL_BIN" ]; then + _MAIL_BIN=$(basename "$MAIL_BIN") + elif _exists "sendmail"; then + _MAIL_BIN="sendmail" + elif _exists "ssmtp"; then + _MAIL_BIN="ssmtp" + elif _exists "mutt"; then + _MAIL_BIN="mutt" + elif _exists "mail"; then + _MAIL_BIN="mail" + else + _err "Please install sendmail, ssmtp, mutt or mail first." + return 1 + fi + case "$_MAIL_BIN" in sendmail) if [ -n "$MAIL_FROM" ]; then - "$_MAIL_BIN" -f "$MAIL_FROM" "$MAIL_TO" + echo "'$_MAIL_BIN' -f '$MAIL_FROM' '$MAIL_TO'" else - "$_MAIL_BIN" "$MAIL_TO" + echo "'$_MAIL_BIN' '$MAIL_TO'" fi ;; ssmtp) - "$_MAIL_BIN" "$MAIL_TO" + echo "'$_MAIL_BIN' '$MAIL_TO'" ;; mutt | mail) - "$_MAIL_BIN" -s "$_subject" "$MAIL_TO" + echo "'$_MAIL_BIN' -s '$_subject' '$MAIL_TO'" + ;; + *) + _err "Command $MAIL_BIN is not supported, use sendmail, ssmtp, mutt or mail." + return 1 ;; esac } From 30f2c2bd7781149e3a51368f1be1fcebd273d78c Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Mon, 13 May 2019 18:11:44 +0200 Subject: [PATCH 0320/2234] prevent _MAIL_BIN modification --- notify/mail.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index 44148d99..3aa05366 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -72,7 +72,7 @@ mail_send() { _mail_cmnd() { if [ -n "$MAIL_BIN" ]; then - _MAIL_BIN=$(basename "$MAIL_BIN") + _MAIL_BIN="$MAIL_BIN" elif _exists "sendmail"; then _MAIL_BIN="sendmail" elif _exists "ssmtp"; then @@ -86,7 +86,7 @@ _mail_cmnd() { return 1 fi - case "$_MAIL_BIN" in + case $(basename "$_MAIL_BIN") in sendmail) if [ -n "$MAIL_FROM" ]; then echo "'$_MAIL_BIN' -f '$MAIL_FROM' '$MAIL_TO'" From 7625d662599f01fabbcfbd8c72034591e94743ce Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Mon, 13 May 2019 18:58:28 +0200 Subject: [PATCH 0321/2234] wip --- notify/slack.sh | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 notify/slack.sh diff --git a/notify/slack.sh b/notify/slack.sh new file mode 100644 index 00000000..00d38b2e --- /dev/null +++ b/notify/slack.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env sh + +#Support Slack webhooks + +#SLACK_WEBHOOK_URL="" + +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" + + export _H1="Content-Type: application/json" + + _content="$(echo "$_subject: $_content" | _json_encode)" + _data="{\"text\": \"$_content\"}" + +echo "$_content" +echo "$_data" + + if _post "$_data" "$SLACK_WEBHOOK_URL"; then + # shellcheck disable=SC2154 + if [ -z "$response" ]; then + _info "slack send sccess." + return 0 + fi + fi + _err "slack send error." + _err "$response" + return 1 + +} From fc5e3a0aec38c9108322489dd16ff72cec8b55b6 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Mon, 13 May 2019 18:59:58 +0200 Subject: [PATCH 0322/2234] remove echo command --- notify/mail.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index 3aa05366..73f180df 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -47,9 +47,6 @@ mail_send() { _saveaccountconf_mutable MAIL_TO "$MAIL_TO" else MAIL_TO="$(_readaccountconf ACCOUNT_EMAIL)" - - echo "MAIL_TO: $MAIL_TO" - if [ -z "$MAIL_TO" ]; then _err "It seems that account email is empty." return 1 From 73bbe25d2692dd8e5e2a5985becaf69d416e8f34 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Mon, 13 May 2019 19:49:16 +0200 Subject: [PATCH 0323/2234] add slack notify --- notify/slack.sh | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/notify/slack.sh b/notify/slack.sh index 00d38b2e..cc1ed765 100644 --- a/notify/slack.sh +++ b/notify/slack.sh @@ -3,6 +3,8 @@ #Support Slack webhooks #SLACK_WEBHOOK_URL="" +#SLACK_CHANNEL="" +#SLACK_USERNAME="" slack_send() { _subject="$1" @@ -18,23 +20,36 @@ slack_send() { 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="$(echo "$_subject: $_content" | _json_encode)" - _data="{\"text\": \"$_content\"}" - -echo "$_content" -echo "$_data" + _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 [ -z "$response" ]; then - _info "slack send sccess." + if [ "$response" = "ok" ]; then + _info "slack send success." return 0 fi fi _err "slack send error." _err "$response" return 1 - } From a180b95ccaeda85769e413ed6ce54dd0a6f54c9e Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 17 May 2019 20:16:26 +0800 Subject: [PATCH 0324/2234] add more debug info --- acme.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 4c1e45d6..60580f83 100755 --- a/acme.sh +++ b/acme.sh @@ -3044,11 +3044,12 @@ _clearupdns() { _err "It seems that your api file doesn't define $rmcommand" return 1 fi - + _info "Removing txt: $txt for domain: $txtdomain" if ! $rmcommand "$txtdomain" "$txt"; then _err "Error removing txt for domain:$txtdomain" return 1 fi + _info "Removed: Success" ) done @@ -4063,7 +4064,7 @@ $_authorizations_map" dns_entry="$dns_entry$dvsep$txt${dvsep}$d_api" _debug2 dns_entry "$dns_entry" if [ "$d_api" ]; then - _info "Found domain api file: $d_api" + _debug "Found domain api file: $d_api" else if [ "$_currentRoot" != "$W_DNS" ]; then _err "Can not find dns api hook for: $_currentRoot" @@ -4088,11 +4089,12 @@ $_authorizations_map" _err "It seems that your api file is not correct, it must have a function named: $addcommand" return 1 fi - + _info "Adding txt value: $txt for domain: $txtdomain" if ! $addcommand "$txtdomain" "$txt"; then _err "Error add txt for domain:$txtdomain" return 1 fi + _info "The txt record is added: Success." ) if [ "$?" != "0" ]; then From ace947e6b3fce69ecd97881daaaf22917dafc9a6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 18 May 2019 21:00:39 +0800 Subject: [PATCH 0325/2234] add dns_durabledns.sh --- dnsapi/dns_durabledns.sh | 182 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 dnsapi/dns_durabledns.sh diff --git a/dnsapi/dns_durabledns.sh b/dnsapi/dns_durabledns.sh new file mode 100644 index 00000000..5de1eaaa --- /dev/null +++ b/dnsapi/dns_durabledns.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env sh + + +#DD_API_User="xxxxx" +#DD_API_Key="xxxxxx" + +_DD_BASE="https://durabledns.com/services/dns" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_durabledns_add() { + fulldomain=$1 + txtvalue=$2 + + DD_API_User="${DD_API_User:-$(_readaccountconf_mutable DD_API_User)}" + DD_API_Key="${DD_API_Key:-$(_readaccountconf_mutable DD_API_Key)}" + if [ -z "$DD_API_User" ] || [ -z "$DD_API_Key" ]; then + DD_API_User="" + DD_API_Key="" + _err "You didn't specify a durabledns api user or key yet." + _err "You can get yours from here https://durabledns.com/dashboard/index.php" + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable DD_API_User "$DD_API_User" + _saveaccountconf_mutable DD_API_Key "$DD_API_Key" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _dd_soap createRecord string zonename "$_domain." string name "$_sub_domain" string type "TXT" string data "$txtvalue" int aux 0 int ttl 10 string ddns_enabled N + _contains "$response" "createRecordResponse" +} + + +dns_durabledns_rm() { + fulldomain=$1 + txtvalue=$2 + + DD_API_User="${DD_API_User:-$(_readaccountconf_mutable DD_API_User)}" + DD_API_Key="${DD_API_Key:-$(_readaccountconf_mutable DD_API_Key)}" + if [ -z "$DD_API_User" ] || [ -z "$DD_API_Key" ]; then + DD_API_User="" + DD_API_Key="" + _err "You didn't specify a durabledns api user or key yet." + _err "You can get yours from here https://durabledns.com/dashboard/index.php" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Find record id" + if ! _dd_soap listRecords string zonename "$_domain."; then + _err "can not listRecords" + return 1 + fi + + subtxt="$(echo "$txtvalue" | cut -c 1-30)" + record="$(echo "$response" | sed 's//#/g' | tr '#' '\n' | grep ">$subtxt")" + _debug record "$record" + if [ -z "$record" ]; then + _err "can not find record for txtvalue" "$txtvalue" + _err "$response" + return 1 + fi + + recordid="$(echo "$record" | _egrep_o '[0-9]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" + _debug recordid "$recordid" + if [ -z "$recordid" ]; then + _err "can not find record id" + return 1 + fi + + if ! _dd_soap deleteRecord string zonename "$_domain." int id "$recordid"; then + _err "delete error" + return 1 + fi + + _contains "$response" "Success" +} + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + if ! _dd_soap "listZones"; then + return 1 + fi + + i=1 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if _contains "$response" ">$h."; 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 + +} + + +#method +_dd_soap() { + _method="$1" + shift + _urn="${_method}wsdl" + # put the parameters to xml + body=" + $DD_API_User + $DD_API_Key + " + while [ "$1" ]; do + _t="$1" + shift + _k="$1" + shift + _v="$1" + shift + body="$body<$_k xsi:type=\"xsd:$_t\">$_v" + done + body="$body" + _debug2 "SOAP request ${body}" + + # build SOAP XML + _xml=' + + '"$body"' +' + + _debug2 _xml "$_xml" + # set SOAP headers + _action="SOAPAction: \"urn:$_urn#$_method\"" + _debug2 "_action" "$_action" + export _H1="$_action" + export _H2="Content-Type: text/xml; charset=utf-8" + + _url="$_DD_BASE/$_method.php" + _debug "_url" "$_url" + if ! response="$(_post "${_xml}" "${_url}")"; then + _err "Error <$1>" + return 1 + fi + _debug2 "response" "$response" + response="$(echo "$response" | tr -d "\r\n" | _egrep_o ":${_method}Response .*:${_method}Response><")" + _debug2 "response" "$response" + return 0 +} + + + From 9a7c9e8d989fb8f0cfea976fb7e5b14f1a7d4743 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sat, 18 May 2019 18:20:16 +0200 Subject: [PATCH 0326/2234] remove unset --- notify/mail.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index 73f180df..5ad8e883 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -14,8 +14,6 @@ mail_send() { _debug "_content" "$_content" _debug "_statusCode" "$_statusCode" - unset -f _MAIL_BIN _MAIL_BODY _MAIL_CMD - MAIL_BIN="${MAIL_BIN:-$(_readaccountconf_mutable MAIL_BIN)}" if [ -n "$MAIL_BIN" ] && ! _exists "$MAIL_BIN"; then _err "It seems that the command $MAIL_BIN is not in path." From d83c9da8308decbdbd9cbab5b551189423c2004a Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sat, 18 May 2019 18:21:19 +0200 Subject: [PATCH 0327/2234] add clearaccountconf MAIL_BIN --- notify/mail.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/notify/mail.sh b/notify/mail.sh index 5ad8e883..dbecc3a5 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -22,6 +22,8 @@ mail_send() { _MAIL_CMD=$(_mail_cmnd) if [ -n "$MAIL_BIN" ]; then _saveaccountconf_mutable MAIL_BIN "$MAIL_BIN" + else + _clearaccountconf "MAIL_BIN" fi _MAIL_BODY=$(_mail_body) From cf4c603362acee171e2786476a0b02ff2e1f3619 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 19 May 2019 08:05:40 +0800 Subject: [PATCH 0328/2234] fix format --- dnsapi/dns_durabledns.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dnsapi/dns_durabledns.sh b/dnsapi/dns_durabledns.sh index 5de1eaaa..9a05eb32 100644 --- a/dnsapi/dns_durabledns.sh +++ b/dnsapi/dns_durabledns.sh @@ -1,6 +1,5 @@ #!/usr/bin/env sh - #DD_API_User="xxxxx" #DD_API_Key="xxxxxx" @@ -40,7 +39,6 @@ dns_durabledns_add() { _contains "$response" "createRecordResponse" } - dns_durabledns_rm() { fulldomain=$1 txtvalue=$2 @@ -125,7 +123,6 @@ _get_root() { } - #method _dd_soap() { _method="$1" @@ -177,6 +174,3 @@ xmlns:xsd="http://www.w3.org/2001/XMLSchema"> _debug2 "response" "$response" return 0 } - - - From f6d6658de7e5c9b762f944e22ce583c94168e9f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A1la?= Date: Sun, 19 May 2019 11:47:19 +0200 Subject: [PATCH 0329/2234] Fix saving token for DNS Active24 --- dnsapi/dns_active24.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_active24.sh b/dnsapi/dns_active24.sh index 90ffaf68..862f734f 100755 --- a/dnsapi/dns_active24.sh +++ b/dnsapi/dns_active24.sh @@ -129,7 +129,7 @@ _active24_init() { return 1 fi - _saveaccountconf_mutable ACTIVE24_Token "ACTIVE24_Token" + _saveaccountconf_mutable ACTIVE24_Token "$ACTIVE24_Token" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then From 68b42a00e07f7e35bc777fd41a6b147233918a38 Mon Sep 17 00:00:00 2001 From: der-berni Date: Mon, 20 May 2019 17:40:43 +0200 Subject: [PATCH 0330/2234] updated to work with one.com rev command not found on OpenWrt CURL does not work, using wget JSESSIONID replaced with OneSIDCrmAdmin CSRF_G_TOKEN not needed --- dnsapi/dns_one.sh | 139 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 105 insertions(+), 34 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 94ac49c6..6049ca11 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -4,9 +4,11 @@ # one.com ui wrapper for acme.sh # Author: github: @diseq # Created: 2019-02-17 +# Fixed by: @der-berni +# Modified: 2019-05-20 # -# export ONECOM_User="username" -# export ONECOM_Password="password" +# export ONECOM_USER="username" +# export ONECOM_PASSWORD="password" # # Usage: # acme.sh --issue --dns dns_one -d example.com @@ -14,38 +16,56 @@ # only single domain supported atm dns_one_add() { - mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev) - mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev) + #rev command not found on OpenWrt + #mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev) + #mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev) + + fulldomain=$1 txtvalue=$2 + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + mysubdomain=$_sub_domain + mydomain=$_domain + _debug mysubdomain "$mysubdomain" + _debug mydomain "$mydomain" # get credentials - ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" - ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" - if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then - ONECOM_User="" - ONECOM_Password="" + ONECOM_USER="${ONECOM_USER:-$(_readaccountconf_mutable ONECOM_USER)}" + ONECOM_PASSWORD="${ONECOM_PASSWORD:-$(_readaccountconf_mutable ONECOM_PASSWORD)}" + if [ -z "$ONECOM_USER" ] || [ -z "$ONECOM_PASSWORD" ]; then + ONECOM_USER="" + ONECOM_PASSWORD="" _err "You didn't specify a one.com username and password yet." _err "Please create the key and try again." return 1 fi #save the api key and email to the account conf file. - _saveaccountconf_mutable ONECOM_User "$ONECOM_User" - _saveaccountconf_mutable ONECOM_Password "$ONECOM_Password" + _saveaccountconf_mutable ONECOM_USER "$ONECOM_USER" + _saveaccountconf_mutable ONECOM_PASSWORD "$ONECOM_PASSWORD" # Login with user and password postdata="loginDomain=true" - postdata="$postdata&displayUsername=$ONECOM_User" - postdata="$postdata&username=$ONECOM_User" + postdata="$postdata&displayUsername=$ONECOM_USER" + postdata="$postdata&username=$ONECOM_USER" postdata="$postdata&targetDomain=$mydomain" - postdata="$postdata&password1=$ONECOM_Password" + postdata="$postdata&password1=$ONECOM_PASSWORD" postdata="$postdata&loginTarget=" #_debug postdata "$postdata" - + + #CURL does not work + local tmp_USE_WGET=$ACME_USE_WGET + ACME_USE_WGET=1 + response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")" #_debug response "$response" - JSESSIONID="$(grep "JSESSIONID" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')" + JSESSIONID="$(grep "OneSIDCrmAdmin" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'OneSIDCrmAdmin=[^;]*;' | tr -d ';')" _debug jsessionid "$JSESSIONID" export _H1="Cookie: ${JSESSIONID}" @@ -54,8 +74,8 @@ dns_one_add() { response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" _debug response "$response" - CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')" - export _H2="Cookie: ${CSRF_G_TOKEN}" + #CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')" + #export _H2="Cookie: ${CSRF_G_TOKEN}" # Update the IP address for domain entry postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}" @@ -65,7 +85,9 @@ dns_one_add() { _debug response "$response" id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") - + + ACME_USE_WGET=$tmp_USE_WGET + if [ -z "$id" ]; then _err "Add txt record error." return 1 @@ -77,16 +99,30 @@ dns_one_add() { } dns_one_rm() { - mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev) - mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev) + #rev command not found on OpenWrt + #mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev) + #mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev) + + fulldomain=$1 txtvalue=$2 + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + mysubdomain=$_sub_domain + mydomain=$_domain + _debug mysubdomain "$mysubdomain" + _debug mydomain "$mydomain" # get credentials - ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" - ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" - if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then - ONECOM_User="" - ONECOM_Password="" + ONECOM_USER="${ONECOM_USER:-$(_readaccountconf_mutable ONECOM_USER)}" + ONECOM_PASSWORD="${ONECOM_PASSWORD:-$(_readaccountconf_mutable ONECOM_PASSWORD)}" + if [ -z "$ONECOM_USER" ] || [ -z "$ONECOM_PASSWORD" ]; then + ONECOM_USER="" + ONECOM_PASSWORD="" _err "You didn't specify a one.com username and password yet." _err "Please create the key and try again." return 1 @@ -94,16 +130,20 @@ dns_one_rm() { # Login with user and password postdata="loginDomain=true" - postdata="$postdata&displayUsername=$ONECOM_User" - postdata="$postdata&username=$ONECOM_User" + postdata="$postdata&displayUsername=$ONECOM_USER" + postdata="$postdata&username=$ONECOM_USER" postdata="$postdata&targetDomain=$mydomain" - postdata="$postdata&password1=$ONECOM_Password" + postdata="$postdata&password1=$ONECOM_PASSWORD" postdata="$postdata&loginTarget=" - + + #CURL does not work + local tmp_USE_WGET=$ACME_USE_WGET + ACME_USE_WGET=1 + response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")" #_debug response "$response" - JSESSIONID="$(grep "JSESSIONID" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')" + JSESSIONID="$(grep "OneSIDCrmAdmin" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'OneSIDCrmAdmin=[^;]*;' | tr -d ';')" _debug jsessionid "$JSESSIONID" export _H1="Cookie: ${JSESSIONID}" @@ -113,13 +153,14 @@ dns_one_rm() { response="$(echo "$response" | _normalizeJson)" _debug response "$response" - CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')" - export _H2="Cookie: ${CSRF_G_TOKEN}" + #CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')" + #export _H2="Cookie: ${CSRF_G_TOKEN}" id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}.*/\1/p") if [ -z "$id" ]; then _err "Txt record not found." + ACME_USE_WGET=$tmp_USE_WGET return 1 fi @@ -127,7 +168,9 @@ dns_one_rm() { response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records/$id" "" "DELETE" "application/json")" response="$(echo "$response" | _normalizeJson)" _debug response "$response" - + + ACME_USE_WGET=$tmp_USE_WGET + if [ "$response" = '{"result":null,"metadata":null}' ]; then _info "Removed, OK" return 0 @@ -137,3 +180,31 @@ dns_one_rm() { fi } + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if [ "$(printf "%s" "$h" | tr '.' ' ' | wc -w)" = "2" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + _err "Unable to parse this domain" + return 1 +} From 688fe131c93c23ecc2a1510034a7c973201d2356 Mon Sep 17 00:00:00 2001 From: mjthompson Date: Tue, 21 May 2019 18:21:54 +0800 Subject: [PATCH 0331/2234] Fix typo --- 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 2ad3c819..246f4774 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -49,7 +49,7 @@ dns_aws_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _info "Geting existing records for $fulldomain" + _info "Getting existing records for $fulldomain" if ! aws_rest GET "2013-04-01$_domain_id/rrset" "name=$fulldomain&type=TXT"; then return 1 fi From 49bdcad4b60da9f8efec18eff7b8fc81bcb0a4e0 Mon Sep 17 00:00:00 2001 From: Maximilian Hippler Date: Tue, 21 May 2019 18:50:12 +0200 Subject: [PATCH 0332/2234] Updated oathtoolkit from edge/testing to edge/community --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5aa8da1a..f9d7b1bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ RUN apk update -f \ curl \ socat \ tzdata \ - && apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing oath-toolkit-oathtool \ + && apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/community oath-toolkit-oathtool \ && rm -rf /var/cache/apk/* ENV LE_CONFIG_HOME /acme.sh @@ -22,7 +22,7 @@ RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/ RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null##' | crontab - -RUN for verb in help \ +RUN for verb in help \ version \ install \ uninstall \ From c2dd7e0f6ed2a3e099bd6409b37cfd9a84f5f752 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Wed, 22 May 2019 22:00:39 +0800 Subject: [PATCH 0333/2234] Create LICENSE.md --- LICENSE.md | 674 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From 0e9ba9a0047fcbac58edb2e01d1db7ff9c7175c7 Mon Sep 17 00:00:00 2001 From: Oliver Dick Date: Wed, 22 May 2019 16:20:28 +0200 Subject: [PATCH 0334/2234] remove _hostingde_parse_no_strip_whitespace function as this breaks API requests --- dnsapi/dns_hostingde.sh | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 1aa70394..9e3e5664 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -53,18 +53,6 @@ _hostingde_parse() { fi } -_hostingde_parse_no_strip_whitespace() { - find="${1}" - if [ "${2}" ]; then - notfind="${2}" - fi - if [ "${notfind}" ]; then - _egrep_o \""${find}\":.*" | grep -v "${notfind}" | cut -d ':' -f 2 | cut -d ',' -f 1 - else - _egrep_o \""${find}\":.*" | cut -d ':' -f 2 | cut -d ',' -f 1 - fi -} - _hostingde_getZoneConfig() { _info "Getting ZoneConfig" curZone="${fulldomain#*.}" @@ -97,12 +85,12 @@ _hostingde_getZoneConfig() { zoneConfigDnsServerGroupId=$(echo "${curResult}" | _hostingde_parse "dnsServerGroupId") zoneConfigEmailAddress=$(echo "${curResult}" | _hostingde_parse "emailAddress") zoneConfigDnsSecMode=$(echo "${curResult}" | _hostingde_parse "dnsSecMode") - zoneConfigTemplateValues=$(echo "${curResult}" | _hostingde_parse_no_strip_whitespace "templateValues") + zoneConfigTemplateValues=$(echo "${curResult}" | _hostingde_parse "templateValues") if [ "$zoneConfigTemplateValues" != "null" ]; then _debug "Zone is tied to a template." zoneConfigTemplateValuesTemplateId=$(echo "${curResult}" | _hostingde_parse "templateId") - zoneConfigTemplateValuesTemplateName=$(echo "${curResult}" | _hostingde_parse_no_strip_whitespace "templateName") + zoneConfigTemplateValuesTemplateName=$(echo "${curResult}" | _hostingde_parse "templateName") zoneConfigTemplateValuesTemplateReplacementsIPv4=$(echo "${curResult}" | _hostingde_parse "ipv4Replacement") zoneConfigTemplateValuesTemplateReplacementsIPv6=$(echo "${curResult}" | _hostingde_parse "ipv6Replacement") zoneConfigTemplateValuesTemplateReplacementsMailIPv4=$(echo "${curResult}" | _hostingde_parse "mailIpv4Replacement") From 50d5c4b9ca9c639d121caa6bfcbf2b8729bcea0b Mon Sep 17 00:00:00 2001 From: devNan0 Date: Wed, 22 May 2019 17:01:11 +0200 Subject: [PATCH 0335/2234] Fix sessionid parsing on BSD --- dnsapi/dns_netcup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index d5d7c22e..6e179257 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -117,7 +117,7 @@ dns_netcup_rm() { login() { tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") - sid=$(_getfield "$tmp" "8" | sed s/\"responsedata\":\{\"apisessionid\":\"//g | sed 's/\"\}\}//g') + sid=$(echo "$tmp" | tr '{}' '\n\n' | grep apisessionid | cut -d '"' -f 4) _debug "$tmp" if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then _err "$msg" From 09fb9dcd92d56d3552177ae86a466157cb908fb8 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Wed, 22 May 2019 22:16:46 -0400 Subject: [PATCH 0336/2234] Fix bug preventing multipart TLD names to work. And simplify/cleanup the code. --- dnsapi/dns_freedns.sh | 299 ++++++++++++++++++++++++------------------ 1 file changed, 172 insertions(+), 127 deletions(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 7262755e..e6c6ba52 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -46,76 +46,34 @@ dns_freedns_add() { _saveaccountconf FREEDNS_COOKIE "$FREEDNS_COOKIE" - # split our full domain name into two parts... - i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)" - i="$(_math "$i" - 1)" - top_domain="$(echo "$fulldomain" | cut -d. -f "$i"-100)" - i="$(_math "$i" - 1)" - sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")" + # We may have to cycle through the domain name to find the + # TLD that we own... + i=1 + wmax="$(echo "$fulldomain" | tr '.' ' ' | wc -w)" + while [ "$i" -lt "$wmax" ]; do + # split our full domain name into two parts... + sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")" + i="$(_math "$i" + 1)" + top_domain="$(echo "$fulldomain" | cut -d. -f "$i"-100)" + _debug "sub_domain: $sub_domain" + _debug "top_domain: $top_domain" - _debug "top_domain: $top_domain" - _debug "sub_domain: $sub_domain" - - # Sometimes FreeDNS does not return the subdomain page but rather - # returns a page regarding becoming a premium member. This usually - # happens after a period of inactivity. Immediately trying again - # returns the correct subdomain page. So, we will try twice to - # load the page and obtain our domain ID - attempts=2 - while [ "$attempts" -gt "0" ]; do - attempts="$(_math "$attempts" - 1)" - - htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")" - if [ "$?" != "0" ]; then - if [ "$using_cached_cookies" = "true" ]; then - _err "Has your FreeDNS username and password changed? If so..." - _err "Please export as FREEDNS_User / FREEDNS_Password and try again." - fi - return 1 - fi - - subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '
' | sed 's//@/g' | tr '@' '\n' | grep edit.php | grep "$top_domain")" - _debug3 "subdomain_csv: $subdomain_csv" - - # The above beauty ends with striping out rows that do not have an - # href to edit.php and do not have the top domain we are looking for. - # So all we should be left with is CSV of table of subdomains we are - # interested in. - - # Now we have to read through this table and extract the data we need - lines="$(echo "$subdomain_csv" | wc -l)" - i=0 - found=0 - DNSdomainid="" - while [ "$i" -lt "$lines" ]; do - i="$(_math "$i" + 1)" - line="$(echo "$subdomain_csv" | sed -n "${i}p")" - _debug2 "line: $line" - if [ $found = 0 ] && _contains "$line" "$top_domain"; then - # this line will contain DNSdomainid for the top_domain - DNSdomainid="$(echo "$line" | _egrep_o "edit_domain_id *= *.*>" | cut -d = -f 2 | cut -d '>' -f 1)" - _debug2 "DNSdomainid: $DNSdomainid" - found=1 - break - fi - done - - if [ -z "$DNSdomainid" ]; then - # If domain ID is empty then something went wrong (top level - # domain not found at FreeDNS). - if [ "$attempts" = "0" ]; then - # exhausted maximum retry attempts - _err "Domain $top_domain not found at FreeDNS" - return 1 - fi - else - # break out of the 'retry' loop... we have found our domain ID + DNSdomainid="$(_freedns_domain_id $top_domain)" + if [ "$?" = "0" ]; then + _info "Domain $top_domain found at FreeDNS, domain_id $DNSdomainid" break + else + _info "Domain $top_domain not found at FreeDNS, try with next level of TLD" fi - _info "Domain $top_domain not found at FreeDNS" - _info "Retry loading subdomain page ($attempts attempts remaining)" done + if [ -z "$DNSdomainid" ]; then + # If domain ID is empty then something went wrong (top level + # domain not found at FreeDNS). + _err "Domain $top_domain not found at FreeDNS" + return 1 + fi + # Add in new TXT record with the value provided _debug "Adding TXT record for $fulldomain, $txtvalue" _freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue" @@ -138,76 +96,44 @@ dns_freedns_rm() { FREEDNS_COOKIE="$(_read_conf "$ACCOUNT_CONF_PATH" "FREEDNS_COOKIE")" _debug "FreeDNS login cookies: $FREEDNS_COOKIE" - # Sometimes FreeDNS does not return the subdomain page but rather - # returns a page regarding becoming a premium member. This usually - # happens after a period of inactivity. Immediately trying again - # returns the correct subdomain page. So, we will try twice to - # load the page and obtain our TXT record. - attempts=2 - while [ "$attempts" -gt "0" ]; do - attempts="$(_math "$attempts" - 1)" + TXTdataid="$(_freedns_data_id "$fulldomain" "TXT")" + if [ "$?" != "0" ]; then + _info "Cannot delete TXT record for $fulldomain, record does not exist at FreeDNS" + return 1 + fi + _debug "Data ID's found, $TXTdataid" - htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")" + # now we have one (or more) TXT record data ID's. Load the page + # for that record and search for the record txt value. If match + # then we can delete it. + lines="$(echo "$TXTdataid" | wc -l)" + _debug "Found $lines TXT data records for $fulldomain" + i=0 + while [ "$i" -lt "$lines" ]; do + i="$(_math "$i" + 1)" + dataid="$(echo "$TXTdataid" | sed -n "${i}p")" + _debug "$dataid" + + htmlpage="$(_freedns_retrieve_data_page "$FREEDNS_COOKIE" "$dataid")" if [ "$?" != "0" ]; then + if [ "$using_cached_cookies" = "true" ]; then + _err "Has your FreeDNS username and password changed? If so..." + _err "Please export as FREEDNS_User / FREEDNS_Password and try again." + fi return 1 fi - subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '' | sed 's//@/g' | tr '@' '\n' | grep edit.php | grep "$fulldomain")" - _debug3 "subdomain_csv: $subdomain_csv" - - # The above beauty ends with striping out rows that do not have an - # href to edit.php and do not have the domain name we are looking for. - # So all we should be left with is CSV of table of subdomains we are - # interested in. - - # Now we have to read through this table and extract the data we need - lines="$(echo "$subdomain_csv" | wc -l)" - i=0 - found=0 - DNSdataid="" - while [ "$i" -lt "$lines" ]; do - i="$(_math "$i" + 1)" - line="$(echo "$subdomain_csv" | sed -n "${i}p")" - _debug3 "line: $line" - DNSname="$(echo "$line" | _egrep_o 'edit.php.*' | cut -d '>' -f 2 | cut -d '<' -f 1)" - _debug2 "DNSname: $DNSname" - if [ "$DNSname" = "$fulldomain" ]; then - DNStype="$(echo "$line" | sed 's/' -f 2 | cut -d '<' -f 1)" - _debug2 "DNStype: $DNStype" - if [ "$DNStype" = "TXT" ]; then - DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)" - _debug2 "DNSdataid: $DNSdataid" - DNSvalue="$(echo "$line" | sed 's/' -f 2 | cut -d '<' -f 1)" - if _startswith "$DNSvalue" """; then - # remove the quotation from the start - DNSvalue="$(echo "$DNSvalue" | cut -c 7-)" - fi - if _endswith "$DNSvalue" "..."; then - # value was truncated, remove the dot dot dot from the end - DNSvalue="$(echo "$DNSvalue" | sed 's/...$//')" - elif _endswith "$DNSvalue" """; then - # else remove the closing quotation from the end - DNSvalue="$(echo "$DNSvalue" | sed 's/......$//')" - fi - _debug2 "DNSvalue: $DNSvalue" - - if [ -n "$DNSdataid" ] && _startswith "$txtvalue" "$DNSvalue"; then - # Found a match. But note... Website is truncating the - # value field so we are only testing that part that is not - # truncated. This should be accurate enough. - _debug "Deleting TXT record for $fulldomain, $txtvalue" - _freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid" - return $? - fi - - fi - fi - done + echo "$htmlpage" | grep "value=\""$txtvalue"\"" >/dev/null + if [ "$?" = "0" ]; then + # Found a match... delete the record and return + _info "Deleting TXT record for $fulldomain, $txtvalue" + _freedns_delete_txt_record "$FREEDNS_COOKIE" "$dataid" + return $? + fi done - # If we get this far we did not find a match (after two attempts) + # If we get this far we did not find a match # Not necessarily an error, but log anyway. - _debug3 "$subdomain_csv" _info "Cannot delete TXT record for $fulldomain, $txtvalue. Does not exist at FreeDNS" return 0 } @@ -271,6 +197,33 @@ _freedns_retrieve_subdomain_page() { return 0 } +# usage _freedns_retrieve_data_page login_cookies data_id +# echo page retrieved (html) +# returns 0 success +_freedns_retrieve_data_page() { + export _H1="Cookie:$1" + export _H2="Accept-Language:en-US" + data_id="$2" + url="https://freedns.afraid.org/subdomain/edit.php?data_id=$2" + + _debug "Retrieve data page for ID $data_id from FreeDNS" + + htmlpage="$(_get "$url")" + + if [ "$?" != "0" ]; then + _err "FreeDNS retrieve data page failed bad RC from _get" + return 1 + elif [ -z "$htmlpage" ]; then + _err "FreeDNS returned empty data page" + return 1 + fi + + _debug3 "htmlpage: $htmlpage" + + printf "%s" "$htmlpage" + return 0 +} + # usage _freedns_add_txt_record login_cookies domain_id subdomain value # returns 0 success _freedns_add_txt_record() { @@ -324,3 +277,95 @@ _freedns_delete_txt_record() { _info "Deleted acme challenge TXT record for $fulldomain at FreeDNS" return 0 } + +# usage _freedns_domain_id domain_name +# echo the domain_id if found +# return 0 success +_freedns_domain_id() { + # Start by escaping the dots in the domain name + search_domain="$(echo "$1" | sed 's/\./\\./g')" + + # Sometimes FreeDNS does not return the subdomain page but rather + # returns a page regarding becoming a premium member. This usually + # happens after a period of inactivity. Immediately trying again + # returns the correct subdomain page. So, we will try twice to + # load the page and obtain our domain ID + attempts=2 + while [ "$attempts" -gt "0" ]; do + attempts="$(_math "$attempts" - 1)" + + htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")" + if [ "$?" != "0" ]; then + if [ "$using_cached_cookies" = "true" ]; then + _err "Has your FreeDNS username and password changed? If so..." + _err "Please export as FREEDNS_User / FREEDNS_Password and try again." + fi + return 1 + fi + + domain_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ + | grep "$search_domain\|$search_domain(.*)" \ + | _egrep_o "edit\.php\?edit_domain_id=[0-9a-zA-Z]+" \ + | cut -d = -f 2 )" + # The above beauty extracts domain ID from the html page... + # strip out all blank space and new lines. Then insert newlines + # before each table row + # search for the domain within each row (which may or may not have + # a text string in brackets (.*) after it. + # And finally extract the domain ID. + if [ -n "$domain_id" ]; then + printf "%s" "$domain_id" + return 0 + fi + _debug "Domain $search_domain not found. Retry loading subdomain page ($attempts attempts remaining)" + done + _debug "Domain $search_domain not found after retry" + return 1 +} + +# usage _freedns_data_id domain_name record_type +# echo the data_id(s) if found +# return 0 success +_freedns_data_id() { + # Start by escaping the dots in the domain name + search_domain="$(echo "$1" | sed 's/\./\\./g')" + record_type="$2" + + # Sometimes FreeDNS does not return the subdomain page but rather + # returns a page regarding becoming a premium member. This usually + # happens after a period of inactivity. Immediately trying again + # returns the correct subdomain page. So, we will try twice to + # load the page and obtain our domain ID + attempts=2 + while [ "$attempts" -gt "0" ]; do + attempts="$(_math "$attempts" - 1)" + + htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")" + if [ "$?" != "0" ]; then + if [ "$using_cached_cookies" = "true" ]; then + _err "Has your FreeDNS username and password changed? If so..." + _err "Please export as FREEDNS_User / FREEDNS_Password and try again." + fi + return 1 + fi + + data_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ + | grep "$record_type" \ + | grep "$search_domain" \ + | _egrep_o "edit\.php\?data_id=[0-9a-zA-Z]+" \ + | cut -d = -f 2)" + # The above beauty extracts data ID from the html page... + # strip out all blank space and new lines. Then insert newlines + # before each table row + # search for the record type withing each row (e.g. TXT) + # search for the domain within each row (which is within a + # anchor. And finally extract the domain ID. + if [ -n "$data_id" ]; then + printf "%s" "$data_id" + return 0 + fi + _debug "Domain $search_domain not found. Retry loading subdomain page ($attempts attempts remaining)" + done + _debug "Domain $search_domain not found after retry" + return 1 +} From 66c39a953ae170e5cb64ab57f8cd2d51987a1f7d Mon Sep 17 00:00:00 2001 From: David Kerr Date: Wed, 22 May 2019 22:50:26 -0400 Subject: [PATCH 0337/2234] Fix warnings from Travis build --- dnsapi/dns_freedns.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index e6c6ba52..d1f3d418 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -58,7 +58,7 @@ dns_freedns_add() { _debug "sub_domain: $sub_domain" _debug "top_domain: $top_domain" - DNSdomainid="$(_freedns_domain_id $top_domain)" + DNSdomainid="$(_freedns_domain_id "$top_domain")" if [ "$?" = "0" ]; then _info "Domain $top_domain found at FreeDNS, domain_id $DNSdomainid" break @@ -304,9 +304,9 @@ _freedns_domain_id() { fi domain_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ - | grep "$search_domain\|$search_domain(.*)" \ - | _egrep_o "edit\.php\?edit_domain_id=[0-9a-zA-Z]+" \ - | cut -d = -f 2 )" + | grep "$search_domain\|$search_domain(.*)" \ + | _egrep_o "edit\.php\?edit_domain_id=[0-9a-zA-Z]+" \ + | cut -d = -f 2 )" # The above beauty extracts domain ID from the html page... # strip out all blank space and new lines. Then insert newlines # before each table row @@ -319,7 +319,7 @@ _freedns_domain_id() { fi _debug "Domain $search_domain not found. Retry loading subdomain page ($attempts attempts remaining)" done - _debug "Domain $search_domain not found after retry" + _debug "Domain $search_domain not found after retry" return 1 } @@ -350,10 +350,10 @@ _freedns_data_id() { fi data_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ - | grep "$record_type" \ - | grep "$search_domain" \ - | _egrep_o "edit\.php\?data_id=[0-9a-zA-Z]+" \ - | cut -d = -f 2)" + | grep "$record_type" \ + | grep "$search_domain" \ + | _egrep_o "edit\.php\?data_id=[0-9a-zA-Z]+" \ + | cut -d = -f 2)" # The above beauty extracts data ID from the html page... # strip out all blank space and new lines. Then insert newlines # before each table row @@ -366,6 +366,6 @@ _freedns_data_id() { fi _debug "Domain $search_domain not found. Retry loading subdomain page ($attempts attempts remaining)" done - _debug "Domain $search_domain not found after retry" + _debug "Domain $search_domain not found after retry" return 1 } From a18ce275ab91a88149cf580a964e237897f85cf6 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Wed, 22 May 2019 22:54:56 -0400 Subject: [PATCH 0338/2234] Another Travis CI warning fixed. --- dnsapi/dns_freedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index d1f3d418..e92cf618 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -306,7 +306,7 @@ _freedns_domain_id() { domain_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ | grep "$search_domain\|$search_domain(.*)" \ | _egrep_o "edit\.php\?edit_domain_id=[0-9a-zA-Z]+" \ - | cut -d = -f 2 )" + | cut -d = -f 2)" # The above beauty extracts domain ID from the html page... # strip out all blank space and new lines. Then insert newlines # before each table row From 10994d65bed6039aa32adfa39cf454fe3619eb2c Mon Sep 17 00:00:00 2001 From: David Kerr Date: Wed, 22 May 2019 23:01:23 -0400 Subject: [PATCH 0339/2234] Even blank lines (with spaces) give Travis heartache. Sigh. --- dnsapi/dns_freedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index e92cf618..71c6aa85 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -348,7 +348,7 @@ _freedns_data_id() { fi return 1 fi - + data_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ | grep "$record_type" \ | grep "$search_domain" \ From 05b6afcd172cd7e15909c6162094f1a00595bf77 Mon Sep 17 00:00:00 2001 From: devNan0 Date: Thu, 23 May 2019 08:15:03 +0200 Subject: [PATCH 0340/2234] Make travis happy. (SC2020) --- dnsapi/dns_netcup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 6e179257..d519e4f7 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -117,7 +117,7 @@ dns_netcup_rm() { login() { tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") - sid=$(echo "$tmp" | tr '{}' '\n\n' | grep apisessionid | cut -d '"' -f 4) + sid=$(echo "$tmp" | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4) _debug "$tmp" if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then _err "$msg" From e340593ad1c313d178ef1b425bd66831b5f425be Mon Sep 17 00:00:00 2001 From: der-berni Date: Thu, 23 May 2019 09:39:54 +0200 Subject: [PATCH 0341/2234] Revert parameter changes Revert ONECOM_PASSWORD back to ONECOM_Password and ONECOM_USER back to ONECOM_User --- dnsapi/dns_one.sh | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 6049ca11..a237a0d8 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -7,8 +7,8 @@ # Fixed by: @der-berni # Modified: 2019-05-20 # -# export ONECOM_USER="username" -# export ONECOM_PASSWORD="password" +# export ONECOM_User="username" +# export ONECOM_Password="password" # # Usage: # acme.sh --issue --dns dns_one -d example.com @@ -35,26 +35,26 @@ dns_one_add() { _debug mydomain "$mydomain" # get credentials - ONECOM_USER="${ONECOM_USER:-$(_readaccountconf_mutable ONECOM_USER)}" - ONECOM_PASSWORD="${ONECOM_PASSWORD:-$(_readaccountconf_mutable ONECOM_PASSWORD)}" - if [ -z "$ONECOM_USER" ] || [ -z "$ONECOM_PASSWORD" ]; then - ONECOM_USER="" - ONECOM_PASSWORD="" + ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" + ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" + if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then + ONECOM_User="" + ONECOM_Password="" _err "You didn't specify a one.com username and password yet." _err "Please create the key and try again." return 1 fi #save the api key and email to the account conf file. - _saveaccountconf_mutable ONECOM_USER "$ONECOM_USER" - _saveaccountconf_mutable ONECOM_PASSWORD "$ONECOM_PASSWORD" + _saveaccountconf_mutable ONECOM_User "$ONECOM_User" + _saveaccountconf_mutable ONECOM_Password "$ONECOM_Password" # Login with user and password postdata="loginDomain=true" - postdata="$postdata&displayUsername=$ONECOM_USER" - postdata="$postdata&username=$ONECOM_USER" + postdata="$postdata&displayUsername=$ONECOM_User" + postdata="$postdata&username=$ONECOM_User" postdata="$postdata&targetDomain=$mydomain" - postdata="$postdata&password1=$ONECOM_PASSWORD" + postdata="$postdata&password1=$ONECOM_Password" postdata="$postdata&loginTarget=" #_debug postdata "$postdata" @@ -118,11 +118,11 @@ dns_one_rm() { _debug mydomain "$mydomain" # get credentials - ONECOM_USER="${ONECOM_USER:-$(_readaccountconf_mutable ONECOM_USER)}" - ONECOM_PASSWORD="${ONECOM_PASSWORD:-$(_readaccountconf_mutable ONECOM_PASSWORD)}" - if [ -z "$ONECOM_USER" ] || [ -z "$ONECOM_PASSWORD" ]; then - ONECOM_USER="" - ONECOM_PASSWORD="" + ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" + ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" + if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then + ONECOM_User="" + ONECOM_Password="" _err "You didn't specify a one.com username and password yet." _err "Please create the key and try again." return 1 @@ -130,10 +130,10 @@ dns_one_rm() { # Login with user and password postdata="loginDomain=true" - postdata="$postdata&displayUsername=$ONECOM_USER" - postdata="$postdata&username=$ONECOM_USER" + postdata="$postdata&displayUsername=$ONECOM_User" + postdata="$postdata&username=$ONECOM_User" postdata="$postdata&targetDomain=$mydomain" - postdata="$postdata&password1=$ONECOM_PASSWORD" + postdata="$postdata&password1=$ONECOM_Password" postdata="$postdata&loginTarget=" #CURL does not work From 93740c997c5ea74fe198c37223bba13e4e777b36 Mon Sep 17 00:00:00 2001 From: andreasschulze Date: Thu, 23 May 2019 16:19:08 +0200 Subject: [PATCH 0342/2234] fix for https://github.com/Neilpang/acme.sh/issues/2286 --- acme.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acme.sh b/acme.sh index 60580f83..eb2194aa 100755 --- a/acme.sh +++ b/acme.sh @@ -4338,6 +4338,8 @@ $_authorizations_map" if [ "$status" = "pending" ]; then _info "Pending" + elif [ "$status" = "processing" ]; then + _info "Processing" else _err "$d:Verify error:$response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" From 2cb0b00e3acb6f1530a811b2e0eda32d628771b6 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Thu, 23 May 2019 18:11:25 -0400 Subject: [PATCH 0343/2234] replace _read_conf() with _readaccountconf() --- dnsapi/dns_freedns.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 71c6aa85..59288372 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -92,8 +92,7 @@ dns_freedns_rm() { # Need to read cookie from conf file again in case new value set # during login to FreeDNS when TXT record was created. - # acme.sh does not have a _readaccountconf() function - FREEDNS_COOKIE="$(_read_conf "$ACCOUNT_CONF_PATH" "FREEDNS_COOKIE")" + FREEDNS_COOKIE="$(_readaccountconf "FREEDNS_COOKIE")" _debug "FreeDNS login cookies: $FREEDNS_COOKIE" TXTdataid="$(_freedns_data_id "$fulldomain" "TXT")" From a3089a719f8dcd2be92ee8c236671cfc7d5ac5f6 Mon Sep 17 00:00:00 2001 From: der-berni Date: Fri, 24 May 2019 09:44:13 +0200 Subject: [PATCH 0344/2234] Updated to work with curl Now works with curl. Check the root domain. --- dnsapi/dns_one.sh | 153 ++++++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 92 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index a237a0d8..a77603e8 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -16,16 +16,17 @@ # only single domain supported atm dns_one_add() { - #rev command not found on OpenWrt - #mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev) - #mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev) - fulldomain=$1 txtvalue=$2 - _debug "First detect the root zone" + if ! _dns_one_login; then + _err "login failed" + return 1 + fi + + _debug "detect the root domain" if ! _get_root "$fulldomain"; then - _err "invalid domain" + _err "root domain not found" return 1 fi @@ -33,50 +34,11 @@ dns_one_add() { mydomain=$_domain _debug mysubdomain "$mysubdomain" _debug mydomain "$mydomain" - - # get credentials - ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" - ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" - if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then - ONECOM_User="" - ONECOM_Password="" - _err "You didn't specify a one.com username and password yet." - _err "Please create the key and try again." - return 1 - fi - - #save the api key and email to the account conf file. - _saveaccountconf_mutable ONECOM_User "$ONECOM_User" - _saveaccountconf_mutable ONECOM_Password "$ONECOM_Password" - - # Login with user and password - postdata="loginDomain=true" - postdata="$postdata&displayUsername=$ONECOM_User" - postdata="$postdata&username=$ONECOM_User" - postdata="$postdata&targetDomain=$mydomain" - postdata="$postdata&password1=$ONECOM_Password" - postdata="$postdata&loginTarget=" - #_debug postdata "$postdata" - #CURL does not work - local tmp_USE_WGET=$ACME_USE_WGET - ACME_USE_WGET=1 - - response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")" - #_debug response "$response" - - JSESSIONID="$(grep "OneSIDCrmAdmin" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'OneSIDCrmAdmin=[^;]*;' | tr -d ';')" - _debug jsessionid "$JSESSIONID" - - export _H1="Cookie: ${JSESSIONID}" - # get entries response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" _debug response "$response" - #CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')" - #export _H2="Cookie: ${CSRF_G_TOKEN}" - # Update the IP address for domain entry postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}" _debug postdata "$postdata" @@ -86,8 +48,6 @@ dns_one_add() { id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") - ACME_USE_WGET=$tmp_USE_WGET - if [ -z "$id" ]; then _err "Add txt record error." return 1 @@ -99,16 +59,17 @@ dns_one_add() { } dns_one_rm() { - #rev command not found on OpenWrt - #mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev) - #mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev) - fulldomain=$1 txtvalue=$2 - _debug "First detect the root zone" + if ! _dns_one_login; then + _err "login failed" + return 1 + fi + + _debug "detect the root domain" if ! _get_root "$fulldomain"; then - _err "invalid domain" + _err "root domain not found" return 1 fi @@ -116,51 +77,16 @@ dns_one_rm() { mydomain=$_domain _debug mysubdomain "$mysubdomain" _debug mydomain "$mydomain" - - # get credentials - ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" - ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" - if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then - ONECOM_User="" - ONECOM_Password="" - _err "You didn't specify a one.com username and password yet." - _err "Please create the key and try again." - return 1 - fi - - # Login with user and password - postdata="loginDomain=true" - postdata="$postdata&displayUsername=$ONECOM_User" - postdata="$postdata&username=$ONECOM_User" - postdata="$postdata&targetDomain=$mydomain" - postdata="$postdata&password1=$ONECOM_Password" - postdata="$postdata&loginTarget=" - #CURL does not work - local tmp_USE_WGET=$ACME_USE_WGET - ACME_USE_WGET=1 - - response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")" - #_debug response "$response" - - JSESSIONID="$(grep "OneSIDCrmAdmin" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'OneSIDCrmAdmin=[^;]*;' | tr -d ';')" - _debug jsessionid "$JSESSIONID" - - export _H1="Cookie: ${JSESSIONID}" - # get entries response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" response="$(echo "$response" | _normalizeJson)" _debug response "$response" - #CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')" - #export _H2="Cookie: ${CSRF_G_TOKEN}" - id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}.*/\1/p") if [ -z "$id" ]; then _err "Txt record not found." - ACME_USE_WGET=$tmp_USE_WGET return 1 fi @@ -169,8 +95,6 @@ dns_one_rm() { response="$(echo "$response" | _normalizeJson)" _debug response "$response" - ACME_USE_WGET=$tmp_USE_WGET - if [ "$response" = '{"result":null,"metadata":null}' ]; then _info "Removed, OK" return 0 @@ -196,8 +120,10 @@ _get_root() { #not valid return 1 fi - - if [ "$(printf "%s" "$h" | tr '.' ' ' | wc -w)" = "2" ]; then + + response="$(_get "https://www.one.com/admin/api/domains/$h/dns/custom_records")" + + if ! _contains "$response" "CRMRST_000302" ; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" return 0 @@ -208,3 +134,46 @@ _get_root() { _err "Unable to parse this domain" return 1 } + +_dns_one_login() { + + # get credentials + ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" + ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" + if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then + ONECOM_User="" + ONECOM_Password="" + _err "You didn't specify a one.com username and password yet." + _err "Please create the key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable ONECOM_User "$ONECOM_User" + _saveaccountconf_mutable ONECOM_Password "$ONECOM_Password" + + # Login with user and password + postdata="loginDomain=true" + postdata="$postdata&displayUsername=$ONECOM_User" + postdata="$postdata&username=$ONECOM_User" + postdata="$postdata&targetDomain=" + postdata="$postdata&password1=$ONECOM_Password" + postdata="$postdata&loginTarget=" + #_debug postdata "$postdata" + + response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")" + #_debug response "$response" + + # Get SessionID + JSESSIONID="$(grep "OneSIDCrmAdmin" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _head_n 1 | _egrep_o 'OneSIDCrmAdmin=[^;]*;' | tr -d ';')" + _debug jsessionid "$JSESSIONID" + + if [ -z "$JSESSIONID" ]; then + _err "error sessionid cookie not found" + return 1 + fi + + export _H1="Cookie: ${JSESSIONID}" + + return 0 + } From 815230943543fe74205e1a23ddbf1e575a30e6e5 Mon Sep 17 00:00:00 2001 From: Awal Garg Date: Tue, 26 Mar 2019 12:18:53 +0530 Subject: [PATCH 0345/2234] Add support for MaraDNS MaraDNS is a lightweight self-hosting DNS server. This patch adds support for adding records to zone files stored on the server in the format expected by MaraDNS. Path to the file should be exported in MARA_ZONE_FILE environment variable. To reload the configuration automatically, the user must provide path to the pid file of duende (the daemonization tool that ships with MaraDNS) in MARA_DUENDE_PID_PATH (--pid argument to duende). --- dnsapi/dns_maradns.sh | 69 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 dnsapi/dns_maradns.sh diff --git a/dnsapi/dns_maradns.sh b/dnsapi/dns_maradns.sh new file mode 100755 index 00000000..4ff6ca2d --- /dev/null +++ b/dnsapi/dns_maradns.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env sh + +#Usage: dns_maradns_add _acme-challenge.www.domain.com "token" +dns_maradns_add() { + fulldomain="$1" + txtvalue="$2" + + MARA_ZONE_FILE="${MARA_ZONE_FILE:-$(_readaccountconf_mutable MARA_ZONE_FILE)}" + MARA_DUENDE_PID_PATH="${MARA_DUENDE_PID_PATH:-$(_readaccountconf_mutable MARA_DUENDE_PID_PATH)}" + + _check_zone_file "$MARA_ZONE_FILE" || return 1 + _check_duende_pid_path "$MARA_DUENDE_PID_PATH" || return 1 + + _saveaccountconf_mutable MARA_ZONE_FILE "$MARA_ZONE_FILE" + _saveaccountconf_mutable MARA_DUENDE_PID_PATH "$MARA_DUENDE_PID_PATH" + + printf "%s. TXT '%s' ~\n" "$fulldomain" "$txtvalue" >>"$MARA_ZONE_FILE" + _reload_maradns "$MARA_DUENDE_PID_PATH" || return 1 +} + +#Usage: dns_maradns_rm _acme-challenge.www.domain.com "token" +dns_maradns_rm() { + fulldomain="$1" + txtvalue="$2" + + MARA_ZONE_FILE="${MARA_ZONE_FILE:-$(_readaccountconf_mutable MARA_ZONE_FILE)}" + MARA_DUENDE_PID_PATH="${MARA_DUENDE_PID_PATH:-$(_readaccountconf_mutable MARA_DUENDE_PID_PATH)}" + + _check_zone_file "$MARA_ZONE_FILE" || return 1 + _check_duende_pid_path "$MARA_DUENDE_PID_PATH" || return 1 + + _saveaccountconf_mutable MARA_ZONE_FILE "$MARA_ZONE_FILE" + _saveaccountconf_mutable MARA_DUENDE_PID_PATH "$MARA_DUENDE_PID_PATH" + + _sed_i "/^$fulldomain.\+TXT '$txtvalue' ~/d" "$MARA_ZONE_FILE" + _reload_maradns "$MARA_DUENDE_PID_PATH" || return 1 +} + +_check_zone_file() { + zonefile="$1" + if [ -z "$zonefile" ]; then + _err "MARA_ZONE_FILE not passed!" + return 1 + elif [ ! -w "$zonefile" ]; then + _err "MARA_ZONE_FILE not writable: $zonefile" + return 1 + fi +} + +_check_duende_pid_path() { + pidpath="$1" + if [ -z "$pidpath" ]; then + _err "MARA_DUENDE_PID_PATH not passed!" + return 1 + fi + if [ ! -r "$pidpath" ]; then + _err "MARA_DUENDE_PID_PATH not readable: $pidpath" + return 1 + fi +} + +_reload_maradns() { + pidpath="$1" + kill -s HUP -- "$(cat "$pidpath")" + if [ $? -ne 0 ]; then + _err "Unable to reload MaraDNS, kill returned $?" + return 1 + fi +} From 0cddc8a154ea137c2e49193a91e9bf72d86356f6 Mon Sep 17 00:00:00 2001 From: Charlie Garrison Date: Sun, 26 May 2019 01:32:13 +1000 Subject: [PATCH 0346/2234] change to routeros native script rather than bash multiline commands --- deploy/routeros.sh | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index b22c64f8..aa7f9760 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -86,29 +86,23 @@ routeros_deploy() { _info "Trying to push cert '$_cfullchain' to router" scp "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" # shellcheck disable=SC2029 - ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" bash -c "' + ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=\ + ftp,read,write,password,sensitive source=\"## generated by routeros deploy script in acme.sh \\r\ + \n/certificate remove [ find name=$_cdomain.cer_0 ]\\r\ + \n/certificate remove [ find name=$_cdomain.cer_1 ]\\r\ + \ndelay 1\\r\ + \n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\"\\r\ + \n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\"\\r\ + \ndelay 1\\r\ + \n/file remove $_cdomain.cer\\r\ + \n/file remove $_cdomain.key\\r\ + \ndelay 2\\r\ + \n/ip service set www-ssl certificate=$_cdomain.cer_0\\r\ + \n$ROUTER_OS_ADDITIONAL_SERVICES\\r\ + \n\" + " + ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\"" + ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\"" -/certificate remove $_cdomain.cer_0 - -/certificate remove $_cdomain.cer_1 - -delay 1 - -/certificate import file-name=$_cdomain.cer passphrase=\"\" - -/certificate import file-name=$_cdomain.key passphrase=\"\" - -delay 1 - -/file remove $_cdomain.cer - -/file remove $_cdomain.key - -delay 2 - -/ip service set www-ssl certificate=$_cdomain.cer_0 -$ROUTER_OS_ADDITIONAL_SERVICES - -'" return 0 } From 89e73594eb04dbc3ca4eaed3acacc0b59b4e5a60 Mon Sep 17 00:00:00 2001 From: der-berni Date: Sat, 25 May 2019 17:35:40 +0200 Subject: [PATCH 0347/2234] fixed error in CI --- dnsapi/dns_one.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index a77603e8..74db40b9 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -123,7 +123,7 @@ _get_root() { response="$(_get "https://www.one.com/admin/api/domains/$h/dns/custom_records")" - if ! _contains "$response" "CRMRST_000302" ; then + if ! _contains "$response" "CRMRST_000302"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" return 0 From 51447961cbc7350a77052d3fab12381986573832 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Mon, 27 May 2019 16:45:44 +0200 Subject: [PATCH 0348/2234] Notify mail update (#2293) * feat: disable e-mail validation if MAIL_NOVALIDATE is set * fix: expose _MAIL_BIN variable * fix: call _mail_body and _mail_cmnd directly to make sure that all used variables are exposed * fix: update notify/mail.sh Co-Authored-By: Matej Mihevc * fix: remove useless echo, quote eval --- notify/mail.sh | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index dbecc3a5..ec9aa0de 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -5,6 +5,7 @@ #MAIL_BIN="sendmail" #MAIL_FROM="yyyy@gmail.com" #MAIL_TO="yyyy@gmail.com" +#MAIL_NOVALIDATE="" mail_send() { _subject="$1" @@ -14,22 +15,28 @@ mail_send() { _debug "_content" "$_content" _debug "_statusCode" "$_statusCode" + MAIL_NOVALIDATE="${MAIL_NOVALIDATE:-$(_readaccountconf_mutable MAIL_NOVALIDATE)}" + if [ -n "$MAIL_NOVALIDATE" ]; then + _saveaccountconf_mutable MAIL_NOVALIDATE 1 + else + _clearaccountconf "MAIL_NOVALIDATE" + fi + MAIL_BIN="${MAIL_BIN:-$(_readaccountconf_mutable MAIL_BIN)}" if [ -n "$MAIL_BIN" ] && ! _exists "$MAIL_BIN"; then _err "It seems that the command $MAIL_BIN is not in path." return 1 fi - _MAIL_CMD=$(_mail_cmnd) + _MAIL_BIN=$(_mail_bin) if [ -n "$MAIL_BIN" ]; then _saveaccountconf_mutable MAIL_BIN "$MAIL_BIN" else _clearaccountconf "MAIL_BIN" fi - _MAIL_BODY=$(_mail_body) MAIL_FROM="${MAIL_FROM:-$(_readaccountconf_mutable MAIL_FROM)}" if [ -n "$MAIL_FROM" ]; then - if ! _contains "$MAIL_FROM" "@"; then + if ! _mail_valid "$MAIL_FROM"; then _err "It seems that the MAIL_FROM=$MAIL_FROM is not a valid email address." return 1 fi @@ -39,7 +46,7 @@ mail_send() { MAIL_TO="${MAIL_TO:-$(_readaccountconf_mutable MAIL_TO)}" if [ -n "$MAIL_TO" ]; then - if ! _contains "$MAIL_TO" "@"; then + if ! _mail_valid "$MAIL_TO"; then _err "It seems that the MAIL_TO=$MAIL_TO is not a valid email address." return 1 fi @@ -55,8 +62,9 @@ mail_send() { contenttype="text/plain; charset=utf-8" subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" - result=$({ echo "$_MAIL_BODY" | eval "$_MAIL_CMD"; } 2>&1) + result=$({ _mail_body | eval "$(_mail_cmnd)"; } 2>&1) + # shellcheck disable=SC2181 if [ $? -ne 0 ]; then _debug "mail send error." _err "$result" @@ -67,7 +75,7 @@ mail_send() { return 0 } -_mail_cmnd() { +_mail_bin() { if [ -n "$MAIL_BIN" ]; then _MAIL_BIN="$MAIL_BIN" elif _exists "sendmail"; then @@ -83,6 +91,10 @@ _mail_cmnd() { return 1 fi + echo "$_MAIL_BIN" +} + +_mail_cmnd() { case $(basename "$_MAIL_BIN") in sendmail) if [ -n "$MAIL_FROM" ]; then @@ -105,16 +117,22 @@ _mail_cmnd() { } _mail_body() { - if [ "$_MAIL_BIN" = "sendmail" ] || [ "$_MAIL_BIN" = "ssmtp" ]; then - if [ -n "$MAIL_FROM" ]; then - echo "From: $MAIL_FROM" - fi + case $(basename "$_MAIL_BIN") in + sendmail | ssmtp) + if [ -n "$MAIL_FROM" ]; then + echo "From: $MAIL_FROM" + fi - echo "To: $MAIL_TO" - echo "Subject: $subject" - echo "Content-Type: $contenttype" - echo - fi + echo "To: $MAIL_TO" + echo "Subject: $subject" + echo "Content-Type: $contenttype" + echo + ;; + esac echo "$_content" } + +_mail_valid() { + [ -n "$MAIL_NOVALIDATE" ] || _contains "$1" "@" +} From 09bce5e6d6be6b97b3c843b815087874e3e44a21 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Tue, 28 May 2019 08:47:33 +0800 Subject: [PATCH 0349/2234] sync (#2297) * Create LICENSE.md * remove _hostingde_parse_no_strip_whitespace function as this breaks API requests * Fix sessionid parsing on BSD * Make travis happy. (SC2020) * fix for https://github.com/Neilpang/acme.sh/issues/2286 * Notify mail update (#2293) * feat: disable e-mail validation if MAIL_NOVALIDATE is set * fix: expose _MAIL_BIN variable * fix: call _mail_body and _mail_cmnd directly to make sure that all used variables are exposed * fix: update notify/mail.sh Co-Authored-By: Matej Mihevc * fix: remove useless echo, quote eval --- LICENSE.md | 674 ++++++++++++++++++++++++++++++++++++++++ acme.sh | 2 + dnsapi/dns_hostingde.sh | 16 +- dnsapi/dns_netcup.sh | 2 +- notify/mail.sh | 48 ++- 5 files changed, 712 insertions(+), 30 deletions(-) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/acme.sh b/acme.sh index 60580f83..eb2194aa 100755 --- a/acme.sh +++ b/acme.sh @@ -4338,6 +4338,8 @@ $_authorizations_map" if [ "$status" = "pending" ]; then _info "Pending" + elif [ "$status" = "processing" ]; then + _info "Processing" else _err "$d:Verify error:$response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 1aa70394..9e3e5664 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -53,18 +53,6 @@ _hostingde_parse() { fi } -_hostingde_parse_no_strip_whitespace() { - find="${1}" - if [ "${2}" ]; then - notfind="${2}" - fi - if [ "${notfind}" ]; then - _egrep_o \""${find}\":.*" | grep -v "${notfind}" | cut -d ':' -f 2 | cut -d ',' -f 1 - else - _egrep_o \""${find}\":.*" | cut -d ':' -f 2 | cut -d ',' -f 1 - fi -} - _hostingde_getZoneConfig() { _info "Getting ZoneConfig" curZone="${fulldomain#*.}" @@ -97,12 +85,12 @@ _hostingde_getZoneConfig() { zoneConfigDnsServerGroupId=$(echo "${curResult}" | _hostingde_parse "dnsServerGroupId") zoneConfigEmailAddress=$(echo "${curResult}" | _hostingde_parse "emailAddress") zoneConfigDnsSecMode=$(echo "${curResult}" | _hostingde_parse "dnsSecMode") - zoneConfigTemplateValues=$(echo "${curResult}" | _hostingde_parse_no_strip_whitespace "templateValues") + zoneConfigTemplateValues=$(echo "${curResult}" | _hostingde_parse "templateValues") if [ "$zoneConfigTemplateValues" != "null" ]; then _debug "Zone is tied to a template." zoneConfigTemplateValuesTemplateId=$(echo "${curResult}" | _hostingde_parse "templateId") - zoneConfigTemplateValuesTemplateName=$(echo "${curResult}" | _hostingde_parse_no_strip_whitespace "templateName") + zoneConfigTemplateValuesTemplateName=$(echo "${curResult}" | _hostingde_parse "templateName") zoneConfigTemplateValuesTemplateReplacementsIPv4=$(echo "${curResult}" | _hostingde_parse "ipv4Replacement") zoneConfigTemplateValuesTemplateReplacementsIPv6=$(echo "${curResult}" | _hostingde_parse "ipv6Replacement") zoneConfigTemplateValuesTemplateReplacementsMailIPv4=$(echo "${curResult}" | _hostingde_parse "mailIpv4Replacement") diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index d5d7c22e..d519e4f7 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -117,7 +117,7 @@ dns_netcup_rm() { login() { tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") - sid=$(_getfield "$tmp" "8" | sed s/\"responsedata\":\{\"apisessionid\":\"//g | sed 's/\"\}\}//g') + sid=$(echo "$tmp" | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4) _debug "$tmp" if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then _err "$msg" diff --git a/notify/mail.sh b/notify/mail.sh index dbecc3a5..ec9aa0de 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -5,6 +5,7 @@ #MAIL_BIN="sendmail" #MAIL_FROM="yyyy@gmail.com" #MAIL_TO="yyyy@gmail.com" +#MAIL_NOVALIDATE="" mail_send() { _subject="$1" @@ -14,22 +15,28 @@ mail_send() { _debug "_content" "$_content" _debug "_statusCode" "$_statusCode" + MAIL_NOVALIDATE="${MAIL_NOVALIDATE:-$(_readaccountconf_mutable MAIL_NOVALIDATE)}" + if [ -n "$MAIL_NOVALIDATE" ]; then + _saveaccountconf_mutable MAIL_NOVALIDATE 1 + else + _clearaccountconf "MAIL_NOVALIDATE" + fi + MAIL_BIN="${MAIL_BIN:-$(_readaccountconf_mutable MAIL_BIN)}" if [ -n "$MAIL_BIN" ] && ! _exists "$MAIL_BIN"; then _err "It seems that the command $MAIL_BIN is not in path." return 1 fi - _MAIL_CMD=$(_mail_cmnd) + _MAIL_BIN=$(_mail_bin) if [ -n "$MAIL_BIN" ]; then _saveaccountconf_mutable MAIL_BIN "$MAIL_BIN" else _clearaccountconf "MAIL_BIN" fi - _MAIL_BODY=$(_mail_body) MAIL_FROM="${MAIL_FROM:-$(_readaccountconf_mutable MAIL_FROM)}" if [ -n "$MAIL_FROM" ]; then - if ! _contains "$MAIL_FROM" "@"; then + if ! _mail_valid "$MAIL_FROM"; then _err "It seems that the MAIL_FROM=$MAIL_FROM is not a valid email address." return 1 fi @@ -39,7 +46,7 @@ mail_send() { MAIL_TO="${MAIL_TO:-$(_readaccountconf_mutable MAIL_TO)}" if [ -n "$MAIL_TO" ]; then - if ! _contains "$MAIL_TO" "@"; then + if ! _mail_valid "$MAIL_TO"; then _err "It seems that the MAIL_TO=$MAIL_TO is not a valid email address." return 1 fi @@ -55,8 +62,9 @@ mail_send() { contenttype="text/plain; charset=utf-8" subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" - result=$({ echo "$_MAIL_BODY" | eval "$_MAIL_CMD"; } 2>&1) + result=$({ _mail_body | eval "$(_mail_cmnd)"; } 2>&1) + # shellcheck disable=SC2181 if [ $? -ne 0 ]; then _debug "mail send error." _err "$result" @@ -67,7 +75,7 @@ mail_send() { return 0 } -_mail_cmnd() { +_mail_bin() { if [ -n "$MAIL_BIN" ]; then _MAIL_BIN="$MAIL_BIN" elif _exists "sendmail"; then @@ -83,6 +91,10 @@ _mail_cmnd() { return 1 fi + echo "$_MAIL_BIN" +} + +_mail_cmnd() { case $(basename "$_MAIL_BIN") in sendmail) if [ -n "$MAIL_FROM" ]; then @@ -105,16 +117,22 @@ _mail_cmnd() { } _mail_body() { - if [ "$_MAIL_BIN" = "sendmail" ] || [ "$_MAIL_BIN" = "ssmtp" ]; then - if [ -n "$MAIL_FROM" ]; then - echo "From: $MAIL_FROM" - fi + case $(basename "$_MAIL_BIN") in + sendmail | ssmtp) + if [ -n "$MAIL_FROM" ]; then + echo "From: $MAIL_FROM" + fi - echo "To: $MAIL_TO" - echo "Subject: $subject" - echo "Content-Type: $contenttype" - echo - fi + echo "To: $MAIL_TO" + echo "Subject: $subject" + echo "Content-Type: $contenttype" + echo + ;; + esac echo "$_content" } + +_mail_valid() { + [ -n "$MAIL_NOVALIDATE" ] || _contains "$1" "@" +} From 145b1f4fb3cbeafa167d86f8f6004df194e5cd55 Mon Sep 17 00:00:00 2001 From: Kay Roepke Date: Tue, 28 May 2019 13:46:19 +0200 Subject: [PATCH 0350/2234] Improve compatibility with *BSD xargs The --no-run-if-empty option is a GNU extension and the long version isn't supported by *BSD variants. Instead use the short version (-r) which is present, but ignored as it is the default behavior, in at least FreeBSD: https://www.freebsd.org/cgi/man.cgi?xargs --- 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 c2ead9a9..ebbeecf2 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -93,7 +93,7 @@ _dns_gcloud_execute_tr() { } _dns_gcloud_remove_rrs() { - if ! xargs --no-run-if-empty gcloud dns record-sets transaction remove \ + if ! xargs -r gcloud dns record-sets transaction remove \ --name="$fulldomain." \ --ttl="$ttl" \ --type=TXT \ @@ -108,7 +108,7 @@ _dns_gcloud_remove_rrs() { _dns_gcloud_add_rrs() { ttl=60 - if ! xargs --no-run-if-empty gcloud dns record-sets transaction add \ + if ! xargs -r gcloud dns record-sets transaction add \ --name="$fulldomain." \ --ttl="$ttl" \ --type=TXT \ From 03a407d4dfefb41eb35693c74d45a49d125df83a Mon Sep 17 00:00:00 2001 From: Charlie Garrison Date: Wed, 29 May 2019 14:05:20 +1000 Subject: [PATCH 0351/2234] Added additional `shellcheck` ignores for client-side evaluation warning Should pass CI tests now --- deploy/routeros.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index aa7f9760..035e13ac 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -101,7 +101,9 @@ routeros_deploy() { \n$ROUTER_OS_ADDITIONAL_SERVICES\\r\ \n\" " + # shellcheck disable=SC2029 ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\"" + # shellcheck disable=SC2029 ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\"" return 0 From 937d5b5472a85f998177a00547327f144d2b7fcd Mon Sep 17 00:00:00 2001 From: der-berni Date: Fri, 31 May 2019 08:26:48 +0200 Subject: [PATCH 0352/2234] try to remove errors in travis-ci --- dnsapi/dns_one.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 74db40b9..68f54ed0 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -5,7 +5,7 @@ # Author: github: @diseq # Created: 2019-02-17 # Fixed by: @der-berni -# Modified: 2019-05-20 +# Modified: 2019-05-31 # # export ONECOM_User="username" # export ONECOM_Password="password" @@ -18,7 +18,7 @@ dns_one_add() { fulldomain=$1 txtvalue=$2 - + if ! _dns_one_login; then _err "login failed" return 1 @@ -29,12 +29,12 @@ dns_one_add() { _err "root domain not found" return 1 fi - + mysubdomain=$_sub_domain mydomain=$_domain _debug mysubdomain "$mysubdomain" _debug mydomain "$mydomain" - + # get entries response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" _debug response "$response" @@ -47,7 +47,7 @@ dns_one_add() { _debug response "$response" id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") - + if [ -z "$id" ]; then _err "Add txt record error." return 1 @@ -61,7 +61,7 @@ dns_one_add() { dns_one_rm() { fulldomain=$1 txtvalue=$2 - + if ! _dns_one_login; then _err "login failed" return 1 @@ -72,12 +72,12 @@ dns_one_rm() { _err "root domain not found" return 1 fi - + mysubdomain=$_sub_domain mydomain=$_domain _debug mysubdomain "$mysubdomain" _debug mydomain "$mydomain" - + # get entries response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" response="$(echo "$response" | _normalizeJson)" @@ -94,7 +94,7 @@ dns_one_rm() { response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records/$id" "" "DELETE" "application/json")" response="$(echo "$response" | _normalizeJson)" _debug response "$response" - + if [ "$response" = '{"result":null,"metadata":null}' ]; then _info "Removed, OK" return 0 @@ -176,4 +176,4 @@ _dns_one_login() { export _H1="Cookie: ${JSESSIONID}" return 0 - } +} From 1a5279bd6e8773786b388fc31def1c21da6ec2c7 Mon Sep 17 00:00:00 2001 From: der-berni Date: Fri, 31 May 2019 08:55:21 +0200 Subject: [PATCH 0354/2234] cleanup according to styleguide --- dnsapi/dns_one.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 68f54ed0..0fdc3d5e 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -110,19 +110,19 @@ dns_one_rm() { # _sub_domain=_acme-challenge.www # _domain=domain.com _get_root() { - domain=$1 + domain="$1" i=2 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) - + if [ -z "$h" ]; then #not valid return 1 fi - + response="$(_get "https://www.one.com/admin/api/domains/$h/dns/custom_records")" - + if ! _contains "$response" "CRMRST_000302"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" @@ -160,20 +160,20 @@ _dns_one_login() { postdata="$postdata&password1=$ONECOM_Password" postdata="$postdata&loginTarget=" #_debug postdata "$postdata" - + response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")" #_debug response "$response" - + # Get SessionID JSESSIONID="$(grep "OneSIDCrmAdmin" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _head_n 1 | _egrep_o 'OneSIDCrmAdmin=[^;]*;' | tr -d ';')" _debug jsessionid "$JSESSIONID" - + if [ -z "$JSESSIONID" ]; then _err "error sessionid cookie not found" return 1 fi - + export _H1="Cookie: ${JSESSIONID}" - + return 0 } From 561803c0a75a73abe3a392c080d6678b84a31891 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 1 Jun 2019 22:30:25 +0800 Subject: [PATCH 0355/2234] add deploy hook to docker containers --- Dockerfile | 1 + deploy/docker.sh | 264 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 265 insertions(+) create mode 100755 deploy/docker.sh diff --git a/Dockerfile b/Dockerfile index 0e8b58d0..8a7fd039 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,7 @@ RUN apk update -f \ curl \ socat \ tzdata \ + tar \ && rm -rf /var/cache/apk/* ENV LE_CONFIG_HOME /acme.sh diff --git a/deploy/docker.sh b/deploy/docker.sh new file mode 100755 index 00000000..57081cc1 --- /dev/null +++ b/deploy/docker.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env sh + +#DEPLOY_DOCKER_CONTAINER_LABEL="xxxxxxx" +#DOCKER_HOST=/var/run/docker.sock | tcp://localhost:8888 + + +#DEPLOY_DOCKER_CONTAINER_KEY_FILE="/path/to/key.pem" +#DEPLOY_DOCKER_CONTAINER_CERT_FILE="/path/to/cert.pem" +#DEPLOY_DOCKER_CONTAINER_CA_FILE="/path/to/ca.pem" +#DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/path/to/fullchain.pem" +#DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload" + +_DEPLOY_DOCKER_WIKI="http://xxxxxx" + +_DOCKER_HOST_DEFAULT="/var/run/docker.sock" + +docker_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then + _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container." + _err "See: $_DEPLOY_DOCKER_WIKI" + fi + + _savedomainconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL" + + if [ "$DOCKER_HOST" ]; then + _saveaccountconf DOCKER_HOST "$DOCKER_HOST" + fi + + if _exists docker && docker version | grep -i docker >/dev/null; then + _info "Using docker command" + export _USE_DOCKER_COMMAND=1 + else + export _USE_DOCKER_COMMAND= + fi + + export _USE_UNIX_SOCKET= + if [ -z "$_USE_DOCKER_COMMAND" ]; then + export _USE_REST= + if [ "$DOCKER_HOST" ]; then + _debug "Try use docker host: $DOCKER_HOST" + export _USE_REST=1 + else + export _DOCKER_SOCK="$_DOCKER_HOST_DEFAULT" + _debug "Try use $_DOCKER_SOCK" + if [ ! -e "$_DOCKER_SOCK" ] || [ ! -w "$_DOCKER_SOCK" ]; then + _err "$_DOCKER_SOCK is not available" + return 1 + fi + export _USE_UNIX_SOCKET=1 + if ! _exists "curl"; then + _err "Please install curl first." + _err "We need curl to work." + return 1 + fi + if ! _check_curl_version; then + return 1 + fi + fi + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then + _savedomainconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then + _savedomainconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then + _savedomainconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE" + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then + _savedomainconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then + _savedomainconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" + fi + + _cid="$(_get_id "$DEPLOY_DOCKER_CONTAINER_LABEL")" + _info "Container id: $_cid" + if [ -z "$_cid" ]; then + _err "can not find container id" + return 1 + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then + if ! _docker_cp "$_cid" "$_ckey" "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"; then + return 1 + fi + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then + if ! _docker_cp "$_cid" "$_ccert" "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"; then + return 1 + fi + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then + if ! _docker_cp "$_cid" "$_cca" "$DEPLOY_DOCKER_CONTAINER_CA_FILE"; then + return 1 + fi + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then + if ! _docker_cp "$_cid" "$_cfullchain" "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"; then + return 1 + fi + fi + + if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then + if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then + return 1 + fi + fi + return 0 +} + +#label +_get_id() { + _label="$1" + if [ "$_USE_DOCKER_COMMAND" ]; then + docker ps -f label="$_label" --format "{{.ID}}" + elif [ "$_USE_REST" ]; then + _err "Not implemented yet." + return 1 + elif [ "$_USE_UNIX_SOCKET" ]; then + _req="{\"label\":[\"$_label\"]}" + _debug2 _req "$_req" + _req="$(printf "%s" "$_req" | _url_encode)" + _debug2 _req "$_req" + listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")" + _debug2 "listjson" "$listjson" + echo "$listjson" | tr '{,' '\n' | grep -i '"id":' | _head_n 1 | cut -d '"' -f 4 + else + _err "Not implemented yet." + return 1 + fi +} + +#id cmd +_docker_exec() { + _eargs="$@" + _debug2 "_docker_exec $_eargs" + _dcid="$1" + shift + if [ "$_USE_DOCKER_COMMAND" ]; then + docker exec -i "$_dcid" $@ + elif [ "$_USE_REST" ]; then + _err "Not implemented yet." + return 1 + elif [ "$_USE_UNIX_SOCKET" ]; then + _cmd="$@" + _cmd="$(printf "$_cmd" | sed 's/ /","/g')" + _debug2 _cmd "$_cmd" + #create exec instance: + cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"$_cmd\"]}")"; + _debug2 cjson "$cjson" + execid="$(echo "$cjson" | cut -d '"' -f 4)" + _debug execid "$execid" + ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")"; + _debug2 ejson "$ejson" + else + _err "Not implemented yet." + return 1 + fi +} + +#id from to +_docker_cp() { + _dcid="$1" + _from="$2" + _to="$3" + _info "Copying file from $_from to $_to" + _dir="$(dirname "$_to")" + _docker_exec "$_dcid" mkdir -p "$_dir" + if [ "$_USE_DOCKER_COMMAND" ]; then + cat "$_from" | _docker_exec "$_dcid" tee "$_to" >/dev/null + if [ "$?" = "0" ]; then + _info "Success" + return 0 + else + _info "Error" + return 1 + fi + elif [ "$_USE_REST" ]; then + _err "Not implemented yet." + return 1 + elif [ "$_USE_UNIX_SOCKET" ]; then + _frompath="$_from" + if _startswith "$_frompath" '/'; then + _frompath="$(echo "$_from" | cut -b 2- )" #remove the first '/' char + fi + _debug2 "_frompath" "$_frompath" + _toname="$(basename "$_to")" + _debug2 "_toname" "$_toname" + if ! tar --transform="s,$_frompath,$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then + _err "copy error" + return 1 + fi + return 0 + else + _err "Not implemented yet." + return 1 + fi + +} + +#sock method endpoint data content-type +_curl_unix_sock() { + _socket="$1" + _method="$2" + _endpoint="$3" + _data="$4" + _ctype="$5" + if [ -z "$_ctype" ]; then + _ctype="Content-Type: application/json" + fi + _debug _data "$_data" + _debug2 "url" "http://localhost$_endpoint" + if [ "$_CURL_NO_HOST" ]; then + _cux_url="http:$_endpoint" + else + _cux_url="http://localhost$_endpoint" + fi + + if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then + curl -vvv --silent --unix-socket "$_socket" -X $_method --data-binary "$_data" --header "$_ctype" "$_cux_url" + else + curl --silent --unix-socket "$_socket" -X $_method --data-binary "$_data" --header "$_ctype" "$_cux_url" + fi + +} + +_check_curl_version() { + _cversion="$(curl -V | grep '^curl ' | cut -d ' ' -f 2)" + _debug2 "_cversion" "$_cversion" + + _major="$(_getfield "$_cversion" 1 '.')" + _debug2 "_major" "$_major" + + _minor="$(_getfield "$_cversion" 2 '.')" + _debug2 "_minor" "$_minor" + + if [ "$_major$_minor" -lt "740" ]; then + _err "curl v$_cversion doesn't support unit socket" + return 1 + fi + if [ "$_major$_minor" -lt "750" ]; then + _debug "Use short host name" + export _CURL_NO_HOST=1 + else + export _CURL_NO_HOST= + fi + return 0 +} + From 0bbaa51945f882c1197f64ccb8c4522cd4d3b304 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 2 Jun 2019 10:05:24 +0800 Subject: [PATCH 0356/2234] fix format --- deploy/docker.sh | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/deploy/docker.sh b/deploy/docker.sh index 57081cc1..0e22ddc8 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -1,8 +1,6 @@ #!/usr/bin/env sh #DEPLOY_DOCKER_CONTAINER_LABEL="xxxxxxx" -#DOCKER_HOST=/var/run/docker.sock | tcp://localhost:8888 - #DEPLOY_DOCKER_CONTAINER_KEY_FILE="/path/to/key.pem" #DEPLOY_DOCKER_CONTAINER_CERT_FILE="/path/to/cert.pem" @@ -10,7 +8,7 @@ #DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/path/to/fullchain.pem" #DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload" -_DEPLOY_DOCKER_WIKI="http://xxxxxx" +_DEPLOY_DOCKER_WIKI="https://github.com/Neilpang/acme.sh/wiki/deploy-to-docker-containers" _DOCKER_HOST_DEFAULT="/var/run/docker.sock" @@ -20,7 +18,7 @@ docker_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" - + _debug _cdomain "$_cdomain" if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container." _err "See: $_DEPLOY_DOCKER_WIKI" @@ -136,7 +134,7 @@ _get_id() { _debug2 _req "$_req" _req="$(printf "%s" "$_req" | _url_encode)" _debug2 _req "$_req" - listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")" + listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")" _debug2 "listjson" "$listjson" echo "$listjson" | tr '{,' '\n' | grep -i '"id":' | _head_n 1 | cut -d '"' -f 4 else @@ -147,25 +145,25 @@ _get_id() { #id cmd _docker_exec() { - _eargs="$@" + _eargs="$*" _debug2 "_docker_exec $_eargs" _dcid="$1" shift if [ "$_USE_DOCKER_COMMAND" ]; then - docker exec -i "$_dcid" $@ + docker exec -i "$_dcid" "$@" elif [ "$_USE_REST" ]; then _err "Not implemented yet." return 1 elif [ "$_USE_UNIX_SOCKET" ]; then - _cmd="$@" - _cmd="$(printf "$_cmd" | sed 's/ /","/g')" + _cmd="$*" + _cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')" _debug2 _cmd "$_cmd" #create exec instance: - cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"$_cmd\"]}")"; + cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"$_cmd\"]}")" _debug2 cjson "$cjson" execid="$(echo "$cjson" | cut -d '"' -f 4)" _debug execid "$execid" - ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")"; + ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")" _debug2 ejson "$ejson" else _err "Not implemented yet." @@ -182,7 +180,11 @@ _docker_cp() { _dir="$(dirname "$_to")" _docker_exec "$_dcid" mkdir -p "$_dir" if [ "$_USE_DOCKER_COMMAND" ]; then - cat "$_from" | _docker_exec "$_dcid" tee "$_to" >/dev/null + if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then + _docker_exec "$_dcid" tee "$_to" <"$_from" + else + _docker_exec "$_dcid" tee "$_to" <"$_from" >/dev/null + fi if [ "$?" = "0" ]; then _info "Success" return 0 @@ -196,7 +198,7 @@ _docker_cp() { elif [ "$_USE_UNIX_SOCKET" ]; then _frompath="$_from" if _startswith "$_frompath" '/'; then - _frompath="$(echo "$_from" | cut -b 2- )" #remove the first '/' char + _frompath="$(echo "$_from" | cut -b 2-)" #remove the first '/' char fi _debug2 "_frompath" "$_frompath" _toname="$(basename "$_to")" @@ -232,9 +234,9 @@ _curl_unix_sock() { fi if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then - curl -vvv --silent --unix-socket "$_socket" -X $_method --data-binary "$_data" --header "$_ctype" "$_cux_url" + curl -vvv --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url" else - curl --silent --unix-socket "$_socket" -X $_method --data-binary "$_data" --header "$_ctype" "$_cux_url" + curl --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url" fi } @@ -261,4 +263,3 @@ _check_curl_version() { fi return 0 } - From 64928b28bcb77165e9630355b37e85574da3fe65 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 2 Jun 2019 11:11:34 +0800 Subject: [PATCH 0357/2234] trim quotation marks --- deploy/docker.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/deploy/docker.sh b/deploy/docker.sh index 0e22ddc8..18a9d429 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -19,6 +19,7 @@ docker_deploy() { _cca="$4" _cfullchain="$5" _debug _cdomain "$_cdomain" + DEPLOY_DOCKER_CONTAINER_LABEL="$(echo "$DEPLOY_DOCKER_CONTAINER_LABEL" | tr -d '"')" if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container." _err "See: $_DEPLOY_DOCKER_WIKI" @@ -62,22 +63,27 @@ docker_deploy() { fi fi + DEPLOY_DOCKER_CONTAINER_KEY_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" | tr -d '"')" if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" fi + DEPLOY_DOCKER_CONTAINER_CERT_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" | tr -d '"')" if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" fi + DEPLOY_DOCKER_CONTAINER_CA_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_CA_FILE" | tr -d '"')" if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE" fi + DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" | tr -d '"')" if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" fi + DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="$(echo "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" | tr -d '"')" if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" fi From a18c3ff07d83a28dad3bf4391633a3e86cf6721d Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 2 Jun 2019 15:21:08 +0800 Subject: [PATCH 0358/2234] use `sh -c` --- deploy/docker.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/deploy/docker.sh b/deploy/docker.sh index 18a9d429..d2dc70bc 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -156,21 +156,25 @@ _docker_exec() { _dcid="$1" shift if [ "$_USE_DOCKER_COMMAND" ]; then - docker exec -i "$_dcid" "$@" + docker exec -i "$_dcid" sh -c "$*" elif [ "$_USE_REST" ]; then _err "Not implemented yet." return 1 elif [ "$_USE_UNIX_SOCKET" ]; then _cmd="$*" - _cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')" + #_cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')" _debug2 _cmd "$_cmd" #create exec instance: - cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"$_cmd\"]}")" + cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"sh\", \"-c\", \"$_cmd\"]}")" _debug2 cjson "$cjson" execid="$(echo "$cjson" | cut -d '"' -f 4)" _debug execid "$execid" ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")" _debug2 ejson "$ejson" + if [ "$ejson" ]; then + _err "$ejson" + return 1 + fi else _err "Not implemented yet." return 1 From aec6636205d539eae83f54b4fa4f868f5079d55b Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 2 Jun 2019 19:36:11 +0800 Subject: [PATCH 0359/2234] add _getdeployconf --- acme.sh | 17 +++++++++++++++++ deploy/docker.sh | 24 ++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index eb2194aa..45f0ea86 100755 --- a/acme.sh +++ b/acme.sh @@ -2078,6 +2078,23 @@ _readdomainconf() { _read_conf "$DOMAIN_CONF" "$1" } +#key value base64encode +_savedeployconf() { + _savedomainconf "SAVED_$1" "$2" "$3" + #remove later + _clearaccountconf "$1" +} + +#key +_getdeployconf() { + _rac_key="$1" + if [ "$(eval echo \$"$_rac_key")" ]; then + return 0 # do nothing + fi + _saved=$(_readdomainconf "SAVED_$_rac_key") + eval "export $_rac_key=$_saved" +} + #_saveaccountconf key value base64encode _saveaccountconf() { _save_conf "$ACCOUNT_CONF_PATH" "$@" diff --git a/deploy/docker.sh b/deploy/docker.sh index d2dc70bc..6f3a2718 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -19,13 +19,13 @@ docker_deploy() { _cca="$4" _cfullchain="$5" _debug _cdomain "$_cdomain" - DEPLOY_DOCKER_CONTAINER_LABEL="$(echo "$DEPLOY_DOCKER_CONTAINER_LABEL" | tr -d '"')" + _getdeployconf DEPLOY_DOCKER_CONTAINER_LABEL if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container." _err "See: $_DEPLOY_DOCKER_WIKI" fi - _savedomainconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL" + _savedeployconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL" if [ "$DOCKER_HOST" ]; then _saveaccountconf DOCKER_HOST "$DOCKER_HOST" @@ -63,29 +63,29 @@ docker_deploy() { fi fi - DEPLOY_DOCKER_CONTAINER_KEY_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" | tr -d '"')" + _getdeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then - _savedomainconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" + _savedeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" fi - DEPLOY_DOCKER_CONTAINER_CERT_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" | tr -d '"')" + _getdeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then - _savedomainconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" + _savedeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" fi - DEPLOY_DOCKER_CONTAINER_CA_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_CA_FILE" | tr -d '"')" + _getdeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then - _savedomainconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE" + _savedeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE" fi - DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" | tr -d '"')" + _getdeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then - _savedomainconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" + _savedeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" fi - DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="$(echo "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" | tr -d '"')" + _getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then - _savedomainconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" + _savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" fi _cid="$(_get_id "$DEPLOY_DOCKER_CONTAINER_LABEL")" From dc5eda7ebb53ba9dadb631d703829b37a3879be7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 2 Jun 2019 20:04:36 +0800 Subject: [PATCH 0360/2234] fix savedeployconf --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 45f0ea86..4c856dbd 100755 --- a/acme.sh +++ b/acme.sh @@ -2082,7 +2082,7 @@ _readdomainconf() { _savedeployconf() { _savedomainconf "SAVED_$1" "$2" "$3" #remove later - _clearaccountconf "$1" + _cleardomainconf "$1" } #key From 924e0261f9431be00e24d08080bd7774ee0e4de0 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sun, 2 Jun 2019 13:09:57 -0400 Subject: [PATCH 0361/2234] Update dns_freedns.sh --- dnsapi/dns_freedns.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 59288372..e76e6495 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -7,6 +7,7 @@ # #Author: David Kerr #Report Bugs here: https://github.com/dkerr64/acme.sh +#or here... https://github.com/Neilpang/acme.sh/issues/2305 # ######## Public functions ##################### From 51099bf1487a3637f00ccd2ba033128afab0416c Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Mon, 3 Jun 2019 01:54:04 +0200 Subject: [PATCH 0362/2234] Add postmark notify --- notify/postmark.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 notify/postmark.sh diff --git a/notify/postmark.sh b/notify/postmark.sh new file mode 100644 index 00000000..6523febe --- /dev/null +++ b/notify/postmark.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env sh + +#Support postmarkapp.com API (https://postmarkapp.com/developer/user-guide/sending-email/sending-with-api) + +#POSTMARK_TOKEN="" +#POSTMARK_TO="xxxx@xxx.com" +#POSTMARK_FROM="xxxx@cccc.com" + +postmark_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + POSTMARK_TOKEN="${POSTMARK_TOKEN:-$(_readaccountconf_mutable POSTMARK_TOKEN)}" + if [ -z "$POSTMARK_TOKEN" ]; then + POSTMARK_TOKEN="" + _err "You didn't specify a POSTMARK api token POSTMARK_TOKEN yet ." + _err "You can get yours from here https://account.postmarkapp.com" + return 1 + fi + _saveaccountconf_mutable POSTMARK_TOKEN "$POSTMARK_TOKEN" + + POSTMARK_TO="${POSTMARK_TO:-$(_readaccountconf_mutable POSTMARK_TO)}" + if [ -z "$POSTMARK_TO" ]; then + POSTMARK_TO="" + _err "You didn't specify an email to POSTMARK_TO receive messages." + return 1 + fi + _saveaccountconf_mutable POSTMARK_TO "$POSTMARK_TO" + + POSTMARK_FROM="${POSTMARK_FROM:-$(_readaccountconf_mutable POSTMARK_FROM)}" + if [ -z "$POSTMARK_FROM" ]; then + POSTMARK_FROM="" + _err "You didn't specify an email from POSTMARK_FROM receive messages." + return 1 + fi + _saveaccountconf_mutable POSTMARK_FROM "$POSTMARK_FROM" + + export _H1="Accept: application/json" + export _H2="Content-Type: application/json" + export _H3="X-Postmark-Server-Token: $POSTMARK_TOKEN" + + _content="$(echo "$_content" | _json_encode)" + _data="{\"To\": \"$POSTMARK_TO\", \"From\": \"$POSTMARK_FROM\", \"Subject\": \"$_subject\", \"TextBody\": \"$_content\"}" + if _post "$_data" "https://api.postmarkapp.com/email"; then + # shellcheck disable=SC2154 + _message=$(printf "%s\n" "$response" | _lower_case | _egrep_o "\"message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + if [ "$_message" = "ok" ]; then + _info "postmark send success." + return 0 + fi + fi + _err "postmark send error." + _err "$response" + return 1 + +} From c42dbbfec841aee2c515821e02a73cc3c0b80702 Mon Sep 17 00:00:00 2001 From: Charlie Garrison Date: Mon, 3 Jun 2019 11:38:39 +1000 Subject: [PATCH 0363/2234] reformatted RouterOS script for shfmt checks --- deploy/routeros.sh | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 035e13ac..21c9196f 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -85,22 +85,23 @@ routeros_deploy() { scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" _info "Trying to push cert '$_cfullchain' to router" scp "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" + DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=ftp,read,write,password,sensitive +source=\"## generated by routeros deploy script in acme.sh +\n/certificate remove [ find name=$_cdomain.cer_0 ] +\n/certificate remove [ find name=$_cdomain.cer_1 ] +\ndelay 1 +\n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\" +\n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\" +\ndelay 1 +\n/file remove $_cdomain.cer +\n/file remove $_cdomain.key +\ndelay 2 +\n/ip service set www-ssl certificate=$_cdomain.cer_0 +\n$ROUTER_OS_ADDITIONAL_SERVICES +\n\" +" # shellcheck disable=SC2029 - ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=\ - ftp,read,write,password,sensitive source=\"## generated by routeros deploy script in acme.sh \\r\ - \n/certificate remove [ find name=$_cdomain.cer_0 ]\\r\ - \n/certificate remove [ find name=$_cdomain.cer_1 ]\\r\ - \ndelay 1\\r\ - \n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\"\\r\ - \n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\"\\r\ - \ndelay 1\\r\ - \n/file remove $_cdomain.cer\\r\ - \n/file remove $_cdomain.key\\r\ - \ndelay 2\\r\ - \n/ip service set www-ssl certificate=$_cdomain.cer_0\\r\ - \n$ROUTER_OS_ADDITIONAL_SERVICES\\r\ - \n\" - " + ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD" # shellcheck disable=SC2029 ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\"" # shellcheck disable=SC2029 From 2e3ddd3a61da8a412d0926520e9a0006bd48857f Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jun 2019 20:55:22 +0800 Subject: [PATCH 0364/2234] trim quotation marks --- acme.sh | 7 ++++++- deploy/docker.sh | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 4c856dbd..42988acc 100755 --- a/acme.sh +++ b/acme.sh @@ -2088,7 +2088,12 @@ _savedeployconf() { #key _getdeployconf() { _rac_key="$1" - if [ "$(eval echo \$"$_rac_key")" ]; then + _rac_value="$(eval echo \$"$_rac_key")" + if [ "$_rac_value" ]; then + if _startswith "$_rac_value" '"' && _endswith "$_rac_value" '"'; then + _debug2 "trim quotation marks" + eval "export $_rac_key=$_rac_value" + fi return 0 # do nothing fi _saved=$(_readdomainconf "SAVED_$_rac_key") diff --git a/deploy/docker.sh b/deploy/docker.sh index 6f3a2718..dc3c0108 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -20,6 +20,7 @@ docker_deploy() { _cfullchain="$5" _debug _cdomain "$_cdomain" _getdeployconf DEPLOY_DOCKER_CONTAINER_LABEL + _debug2 DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL" if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container." _err "See: $_DEPLOY_DOCKER_WIKI" @@ -64,26 +65,31 @@ docker_deploy() { fi _getdeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE + _debug2 DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then _savedeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" fi _getdeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE + _debug2 DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then _savedeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" fi _getdeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE + _debug2 DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE" if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then _savedeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE" fi _getdeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE + _debug2 DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then _savedeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" fi _getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD + _debug2 DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then _savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" fi @@ -188,6 +194,7 @@ _docker_cp() { _to="$3" _info "Copying file from $_from to $_to" _dir="$(dirname "$_to")" + _debug2 _dir "$_dir" _docker_exec "$_dcid" mkdir -p "$_dir" if [ "$_USE_DOCKER_COMMAND" ]; then if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then From 951bd3a5172945d36344428d6710e211157ad50b Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jun 2019 21:03:03 +0800 Subject: [PATCH 0365/2234] minor, check for mkdir --- deploy/docker.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/deploy/docker.sh b/deploy/docker.sh index dc3c0108..4e550991 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -195,7 +195,10 @@ _docker_cp() { _info "Copying file from $_from to $_to" _dir="$(dirname "$_to")" _debug2 _dir "$_dir" - _docker_exec "$_dcid" mkdir -p "$_dir" + if ! _docker_exec "$_dcid" mkdir -p "$_dir"; then + _err "Can not create dir: $_dir" + return 1 + fi if [ "$_USE_DOCKER_COMMAND" ]; then if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _docker_exec "$_dcid" tee "$_to" <"$_from" From 1ef7fd36590068fd83631318c13b79bf384e0046 Mon Sep 17 00:00:00 2001 From: Dominic Jonas Date: Wed, 5 Jun 2019 11:38:41 +0200 Subject: [PATCH 0366/2234] support to delete multiple entries --- dnsapi/dns_kas.sh | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 3b608d43..14c0b378 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -69,27 +69,33 @@ dns_kas_rm() { _get_record_name "$_fulldomain" _get_record_id - # If there is a record_id, delete the entry + # If there is a record_id, delete the entry if [ -n "$_record_id" ]; then params="?kas_login=$KAS_Login" params="$params&kas_auth_type=$KAS_Authtype" params="$params&kas_auth_data=$KAS_Authdata" params="$params&kas_action=delete_dns_settings" - params="$params&var1=record_id" - params="$params&wert1=$_record_id" - _debug2 "Wait for 10 seconds by default before calling KAS API." - sleep 10 - response="$(_get "$KAS_Api$params")" - _debug2 "response" "$response" - if ! _contains "$response" "TRUE"; then - _err "Either the txt record is not found or another error occurred, please check manually." - return 1 - fi + + # split it into a seperated list, if there where multiples entries made + records=($_record_id) + for i in "${records[@]}" + do + params2="$params&var1=record_id" + params2="$params2&wert1=$i" + _debug2 "Wait for 10 seconds by default before calling KAS API." + sleep 10 + response="$(_get "$KAS_Api$params2")" + _debug2 "response" "$response" + if ! _contains "$response" "TRUE"; then + _err "Either the txt record is not found or another error occurred, please check manually." + return 1 + fi + done else # Cannot delete or unkown error _err "No record_id found that can be deleted. Please check manually." return 1 fi - return 0 +return 0 } ########################## PRIVATE FUNCTIONS ########################### @@ -147,4 +153,4 @@ _get_record_id() { _record_id="$(echo "$response" | grep -A 4 "$_record_name" | grep "record_id" | cut -f2 -d">" | xargs)" _debug2 _record_id "$_record_id" return 0 -} +} \ No newline at end of file From 10d1361a2c4baa57dc7db17af3a1ac42300c9af2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 10 Jun 2019 22:35:55 +0800 Subject: [PATCH 0367/2234] add guide link --- dnsapi/dns_myapi.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_myapi.sh b/dnsapi/dns_myapi.sh index 6bf62508..2451d193 100755 --- a/dnsapi/dns_myapi.sh +++ b/dnsapi/dns_myapi.sh @@ -11,6 +11,8 @@ # ######## Public functions ##################### +# Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide + #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_myapi_add() { fulldomain=$1 From 465ece5d2529f38f44c147a7b554a52884bd001c Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 10 Jun 2019 22:40:14 +0800 Subject: [PATCH 0368/2234] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 42988acc..7aa500e3 100755 --- a/acme.sh +++ b/acme.sh @@ -2092,7 +2092,7 @@ _getdeployconf() { if [ "$_rac_value" ]; then if _startswith "$_rac_value" '"' && _endswith "$_rac_value" '"'; then _debug2 "trim quotation marks" - eval "export $_rac_key=$_rac_value" + eval "export $_rac_key=$_rac_value" fi return 0 # do nothing fi From e05ef230a7b62fff63865843d0ed182305a43ef4 Mon Sep 17 00:00:00 2001 From: AndreyIsakov Date: Tue, 11 Jun 2019 19:37:39 +0300 Subject: [PATCH 0369/2234] test CI error --- dnsapi/dns_regru.sh | 205 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 dnsapi/dns_regru.sh diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh new file mode 100644 index 00000000..cd93189f --- /dev/null +++ b/dnsapi/dns_regru.sh @@ -0,0 +1,205 @@ +#!/usr/bin/env sh + +# +#CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" +# +#CF_Email="xxxx@sss.com" + +CF_Api="https://api.cloudflare.com/client/v4" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_cf_add() { + fulldomain=$1 + txtvalue=$2 + + CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" + CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" + if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then + CF_Key="" + CF_Email="" + _err "You didn't specify a Cloudflare api key and email yet." + _err "You can get yours from here https://dash.cloudflare.com/profile." + return 1 + fi + + if ! _contains "$CF_Email" "@"; then + _err "It seems that the CF_Email=$CF_Email is not a valid email address." + _err "Please check and retry." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable CF_Key "$CF_Key" + _saveaccountconf_mutable CF_Email "$CF_Email" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain" + + if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then + _err "Error" + return 1 + fi + + # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so + # we can not use updating anymore. + # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + # _debug count "$count" + # if [ "$count" = "0" ]; then + _info "Adding record" + if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + return 0 + elif _contains "$response" "The record already exists"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + # else + # _info "Updating record" + # record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + # _debug "record_id" "$record_id" + # + # _cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}" + # if [ "$?" = "0" ]; then + # _info "Updated, OK" + # return 0 + # fi + # _err "Update error" + # return 1 + # fi + +} + +#fulldomain txtvalue +dns_cf_rm() { + fulldomain=$1 + txtvalue=$2 + + CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" + CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" + if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then + CF_Key="" + CF_Email="" + _err "You didn't specify a Cloudflare api key and email yet." + _err "You can get yours from here https://dash.cloudflare.com/profile." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain&content=$txtvalue" + + if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then + _err "Error" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _cf_rest DELETE "zones/$_domain_id/dns_records/$record_id"; then + _err "Delete record error." + return 1 + fi + _contains "$response" '"success":true' + fi + +} + +#################### 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=1 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _cf_rest GET "zones?name=$h"; then + return 1 + fi + + if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then + _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_cf_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + email_trimmed=$(echo $CF_Email | tr -d '"') + key_trimmed=$(echo $CF_Key | tr -d '"') + + export _H1="X-Auth-Email: $email_trimmed" + export _H2="X-Auth-Key: $key_trimmed" + export _H3="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$CF_Api/$ep" "" "$m")" + else + response="$(_get "$CF_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 6151debeab598245fc86cb711b759f1816a88b89 Mon Sep 17 00:00:00 2001 From: AndreyIsakov Date: Tue, 11 Jun 2019 19:59:02 +0300 Subject: [PATCH 0370/2234] dnsapi for regru: CI linter ok --- dnsapi/dns_regru.sh | 217 ++++++++------------------------------------ 1 file changed, 39 insertions(+), 178 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index cd93189f..4efec569 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -1,205 +1,66 @@ #!/usr/bin/env sh # -#CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" +# REGRU_API_Username="test" # -#CF_Email="xxxx@sss.com" +# REGRU_API_Password="test" +# +_domain=$_domain -CF_Api="https://api.cloudflare.com/client/v4" +REGRU_API_URL="https://api.reg.ru/api/regru2" ######## Public functions ##################### -#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_cf_add() { +dns_regru_add() { fulldomain=$1 txtvalue=$2 - CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" - CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then - CF_Key="" - CF_Email="" - _err "You didn't specify a Cloudflare api key and email yet." - _err "You can get yours from here https://dash.cloudflare.com/profile." + REGRU_API_Username="${REGRU_API_Username:-$(_readaccountconf_mutable REGRU_API_Username)}" + REGRU_API_Password="${REGRU_API_Password:-$(_readaccountconf_mutable REGRU_API_Password)}" + if [ -z "$REGRU_API_Username" ] || [ -z "$REGRU_API_Password" ]; then + REGRU_API_Username="" + REGRU_API_Password="" + _err "You don't specify regru password or username." return 1 fi - if ! _contains "$CF_Email" "@"; then - _err "It seems that the CF_Email=$CF_Email is not a valid email address." - _err "Please check and retry." - return 1 + + _saveaccountconf_mutable REGRU_API_Username "$REGRU_API_Username" + _saveaccountconf_mutable REGRU_API_Password "$REGRU_API_Password" + + _info "Adding TXT record to ${fulldomain}" + response="$(_get "$REGRU_API_URL/zone/add_txt?input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json")" + + if _contains "${response}" 'success'; then + return 0 fi - - #save the api key and email to the account conf file. - _saveaccountconf_mutable CF_Key "$CF_Key" - _saveaccountconf_mutable CF_Email "$CF_Email" - - _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - _debug _domain_id "$_domain_id" - _debug _sub_domain "$_sub_domain" - _debug _domain "$_domain" - - _debug "Getting txt records" - _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain" - - if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then - _err "Error" - return 1 - fi - - # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so - # we can not use updating anymore. - # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) - # _debug count "$count" - # if [ "$count" = "0" ]; then - _info "Adding record" - if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then - if _contains "$response" "$txtvalue"; then - _info "Added, OK" - return 0 - elif _contains "$response" "The record already exists"; then - _info "Already exists, OK" - return 0 - else - _err "Add txt record error." - return 1 - fi - fi - _err "Add txt record error." + _err "Could not create resource record, check logs" + _err "${response}" return 1 - # else - # _info "Updating record" - # record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) - # _debug "record_id" "$record_id" - # - # _cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}" - # if [ "$?" = "0" ]; then - # _info "Updated, OK" - # return 0 - # fi - # _err "Update error" - # return 1 - # fi - } -#fulldomain txtvalue -dns_cf_rm() { +dns_regru_rm() { fulldomain=$1 txtvalue=$2 + echo 'RM-ONE '"$1" + echo 'RM-TWO '"$2" - CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" - CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then - CF_Key="" - CF_Email="" - _err "You didn't specify a Cloudflare api key and email yet." - _err "You can get yours from here https://dash.cloudflare.com/profile." + REGRU_API_Username="${REGRU_API_Username:-$(_readaccountconf_mutable REGRU_API_Username)}" + REGRU_API_Password="${REGRU_API_Password:-$(_readaccountconf_mutable REGRU_API_Password)}" + if [ -z "$REGRU_API_Username" ] || [ -z "$REGRU_API_Password" ]; then + REGRU_API_Username="" + REGRU_API_Password="" + _err "You don't specify regru password or username." return 1 fi - _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 + _info "Deleting resource record $fulldomain" + response="$(_get "$REGRU_API_URL/zone/remove_record?input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json")" + + if _contains "${response}" 'success'; then + return 0 fi - _debug _domain_id "$_domain_id" - _debug _sub_domain "$_sub_domain" - _debug _domain "$_domain" - - _debug "Getting txt records" - _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain&content=$txtvalue" - - if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then - _err "Error" - return 1 - fi - - count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) - _debug count "$count" - if [ "$count" = "0" ]; then - _info "Don't need to remove." - else - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) - _debug "record_id" "$record_id" - if [ -z "$record_id" ]; then - _err "Can not get record id to remove." - return 1 - fi - if ! _cf_rest DELETE "zones/$_domain_id/dns_records/$record_id"; then - _err "Delete record error." - return 1 - fi - _contains "$response" '"success":true' - fi - -} - -#################### 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=1 - p=1 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug h "$h" - if [ -z "$h" ]; then - #not valid - return 1 - fi - - if ! _cf_rest GET "zones?name=$h"; then - return 1 - fi - - if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then - _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") - if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _domain=$h - return 0 - fi - return 1 - fi - p=$i - i=$(_math "$i" + 1) - done + _err "Could not delete resource record, check logs" + _err "${response}" return 1 } - -_cf_rest() { - m=$1 - ep="$2" - data="$3" - _debug "$ep" - - email_trimmed=$(echo $CF_Email | tr -d '"') - key_trimmed=$(echo $CF_Key | tr -d '"') - - export _H1="X-Auth-Email: $email_trimmed" - export _H2="X-Auth-Key: $key_trimmed" - export _H3="Content-Type: application/json" - - if [ "$m" != "GET" ]; then - _debug data "$data" - response="$(_post "$data" "$CF_Api/$ep" "" "$m")" - else - response="$(_get "$CF_Api/$ep")" - fi - - if [ "$?" != "0" ]; then - _err "error $ep" - return 1 - fi - _debug2 response "$response" - return 0 -} From 487d2a9221802f5c4287c3a4637245f8ce1e329c Mon Sep 17 00:00:00 2001 From: AndreyIsakov Date: Tue, 11 Jun 2019 20:13:48 +0300 Subject: [PATCH 0371/2234] dnsapi for regru: CI linter remove empty line --- dnsapi/dns_regru.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index 4efec569..4c9dc9f8 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -24,7 +24,6 @@ dns_regru_add() { return 1 fi - _saveaccountconf_mutable REGRU_API_Username "$REGRU_API_Username" _saveaccountconf_mutable REGRU_API_Password "$REGRU_API_Password" From 9b564431b08bc433e34c4d4b1cdac45eb333c4c5 Mon Sep 17 00:00:00 2001 From: Endre Szabo Date: Thu, 13 Jun 2019 12:39:38 +0200 Subject: [PATCH 0372/2234] Help text suggests bad practice. Please remove the phrase `No news is good news.` as it suggests to decide to go on with a bad operational habit. Why I am stating this is because that `no news` also could mean that: - your `cron` daemon stopped working, - your MTA has issues (in case or mail notifications of course), - anything in between the host running `acme.sh` and your client went wrong. (... and probably you will not notice in time if `acme.sh` would otherwise send an error notification (if it runs anyway)) If you expect a daily mail (using `--notify-level 3`) you can always be sure that `acme.sh` has ran successfully before. You can also tick the `acme.sh` checkbox in the daily operational report of your enterprise. ;) --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 7aa500e3..9bcab813 100755 --- a/acme.sh +++ b/acme.sh @@ -6108,7 +6108,7 @@ Parameters: --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. 0: disabled, no notification will be sent. - 1: send notification only when there is an error. No news is good news. + 1: send notification only when there is an error. 2: send notification when a cert is successfully renewed, or there is an error 3: send notification when a cert is skipped, renewdd, or error --notify-mode 0|1 Set notification mode. Default value is $NOTIFY_MODE_DEFAULT. From f2c6e3f65b41e66257744afb8c8baca89c2d18cf Mon Sep 17 00:00:00 2001 From: AndreyIsakov Date: Thu, 13 Jun 2019 19:31:44 +0300 Subject: [PATCH 0373/2234] dnsapi for regru: replace echo by _info() --- dnsapi/dns_regru.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index 4c9dc9f8..ff4443b1 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -41,8 +41,8 @@ dns_regru_add() { dns_regru_rm() { fulldomain=$1 txtvalue=$2 - echo 'RM-ONE '"$1" - echo 'RM-TWO '"$2" + _info 'RM-ONE '"$1" + _info 'RM-TWO '"$2" REGRU_API_Username="${REGRU_API_Username:-$(_readaccountconf_mutable REGRU_API_Username)}" REGRU_API_Password="${REGRU_API_Password:-$(_readaccountconf_mutable REGRU_API_Password)}" From d883a870e183a5f5679a0d3be597b38745c359c5 Mon Sep 17 00:00:00 2001 From: AndreyIsakov Date: Thu, 13 Jun 2019 19:56:40 +0300 Subject: [PATCH 0374/2234] dnsapi for regru: remove debug info --- dnsapi/dns_regru.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index ff4443b1..369f62ad 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -41,8 +41,6 @@ dns_regru_add() { dns_regru_rm() { fulldomain=$1 txtvalue=$2 - _info 'RM-ONE '"$1" - _info 'RM-TWO '"$2" REGRU_API_Username="${REGRU_API_Username:-$(_readaccountconf_mutable REGRU_API_Username)}" REGRU_API_Password="${REGRU_API_Password:-$(_readaccountconf_mutable REGRU_API_Password)}" From 882ac74a0c0dfa1e389dd54e6ce8180eddcfda91 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 14 Jun 2019 22:41:28 +0800 Subject: [PATCH 0375/2234] fix issue: clear Le_Vlist earlier --- acme.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 9bcab813..70425335 100755 --- a/acme.sh +++ b/acme.sh @@ -3863,7 +3863,7 @@ issue() { _savedomainconf "Le_Keylength" "$_key_length" vlist="$Le_Vlist" - + _cleardomainconf "Le_Vlist" _info "Getting domain auth token for each domain" sep='#' dvsep=',' @@ -4512,8 +4512,6 @@ $_authorizations_map" fi fi - _cleardomainconf "Le_Vlist" - if [ "$ACME_VERSION" = "2" ]; then _debug "v2 chain." else From c6b6855131108ca16c94e25349e24c1243d7703b Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 14 Jun 2019 23:55:59 +0800 Subject: [PATCH 0376/2234] fix https://github.com/Neilpang/acme.sh/issues/2321 https://github.com/Neilpang/acme.sh/issues/2291 --- acme.sh | 135 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 61 deletions(-) diff --git a/acme.sh b/acme.sh index 70425335..bcc88ef0 100755 --- a/acme.sh +++ b/acme.sh @@ -2450,7 +2450,7 @@ _initpath() { . "$ACCOUNT_CONF_PATH" fi - if [ "$IN_CRON" ]; then + if [ "$ACME_IN_CRON" ]; then if [ ! "$_USER_PATH_EXPORTED" ]; then _USER_PATH_EXPORTED=1 export PATH="$USER_PATH:$PATH" @@ -3216,14 +3216,6 @@ _on_issue_err() { _err "See: $_DEBUG_WIKI" fi - if [ "$IN_CRON" ]; then - if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_ERROR ]; then - if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then - _send_notify "Renew $_main_domain error" "There is an error." "$NOTIFY_HOOK" 1 - fi - fi - fi - #run the post hook if [ "$_chk_post_hook" ]; then _info "Run post hook:'$_chk_post_hook'" @@ -3266,13 +3258,7 @@ _on_issue_success() { _chk_post_hook="$1" _chk_renew_hook="$2" _debug _on_issue_success - if [ "$IN_CRON" ]; then - if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_RENEW ]; then - if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then - _send_notify "Renew $_main_domain success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 - fi - fi - fi + #run the post hook if [ "$_chk_post_hook" ]; then _info "Run post hook:'$_chk_post_hook'" @@ -4506,7 +4492,7 @@ $_authorizations_map" _info "Your cert key is in $(__green " $CERT_KEY_PATH ")" fi - if [ ! "$USER_PATH" ] || [ ! "$IN_CRON" ]; then + if [ ! "$USER_PATH" ] || [ ! "$ACME_IN_CRON" ]; then USER_PATH="$PATH" _saveaccountconf "USER_PATH" "$USER_PATH" fi @@ -4686,19 +4672,10 @@ renew() { if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then _info "Skip, Next renewal time is: $(__green "$Le_NextRenewTimeStr")" _info "Add '$(__red '--force')' to force to renew." - - if [ "$IN_CRON" = "1" ]; then - if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_SKIP ]; then - if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then - _send_notify "Renew $Le_Domain skipped" "Good, the cert next renewal time is $Le_NextRenewTimeStr." "$NOTIFY_HOOK" "$RENEW_SKIP" - fi - fi - fi - return "$RENEW_SKIP" fi - if [ "$IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then + if [ "$ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then _info "Skip invalid cert for: $Le_Domain" return $RENEW_SKIP fi @@ -4733,6 +4710,8 @@ renewAll() { _success_msg="" _error_msg="" _skipped_msg="" + _error_level=$NOTIFY_LEVEL_SKIP + _notify_code=$RENEW_SKIP for di in "${CERT_HOME}"/*.*/; do _debug di "$di" if ! [ -d "$di" ]; then @@ -4750,49 +4729,83 @@ renewAll() { ) rc="$?" _debug "Return code: $rc" - if [ "$rc" != "0" ]; then - if [ "$rc" = "$RENEW_SKIP" ]; then - _info "Skipped $d" - _skipped_msg="${_skipped_msg} $d -" - else - _error_msg="${_error_msg} $d -" - if [ "$_stopRenewOnError" ]; then - _err "Error renew $d, stop now." - _ret="$rc" - break - else - _ret="$rc" - _err "Error renew $d." + if [ "$rc" = "0" ]; then + if [ $_error_level -gt $NOTIFY_LEVEL_RENEW ]; then + _error_level="$NOTIFY_LEVEL_RENEW" + _notify_code=0 + fi + if [ "$ACME_IN_CRON" ]; then + if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_RENEW ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 + fi fi fi - else _success_msg="${_success_msg} $d " + elif [ "$rc" = "$RENEW_SKIP" ]; then + if [ $_error_level -gt $NOTIFY_LEVEL_SKIP ]; then + _error_level="$NOTIFY_LEVEL_SKIP" + _notify_code=$RENEW_SKIP + fi + if [ "$ACME_IN_CRON" ]; then + if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_SKIP ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" + fi + fi + fi + _info "Skipped $d" + _skipped_msg="${_skipped_msg} $d +" + else + if [ $_error_level -gt $NOTIFY_LEVEL_ERROR ]; then + _error_level="$NOTIFY_LEVEL_ERROR" + _notify_code=1 + fi + if [ "$ACME_IN_CRON" ]; then + if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_ERROR ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 + fi + fi + fi + _error_msg="${_error_msg} $d +" + if [ "$_stopRenewOnError" ]; then + _err "Error renew $d, stop now." + _ret="$rc" + break + else + _ret="$rc" + _err "Error renew $d." + fi fi done - - if [ "$IN_CRON" = "1" ]; then + _debug _error_level "$_error_level" + if [ "$ACME_IN_CRON" ] && [ $_error_level -le $NOTIFY_LEVEL ]; then if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then _msg_subject="Renew" if [ "$_error_msg" ]; then _msg_subject="${_msg_subject} Error" + _msg_data="Error certs: +${_error_msg} +" fi if [ "$_success_msg" ]; then _msg_subject="${_msg_subject} Success" + _msg_data="${_msg_data}Success certs: +${_success_msg} +" fi if [ "$_skipped_msg" ]; then _msg_subject="${_msg_subject} Skipped" - fi - _msg_data="Error certs: -${_error_msg} -Success certs: -${_success_msg} -Skipped certs: -$_skipped_msg + _msg_data="${_msg_data}Skipped certs: +${_skipped_msg} " - _send_notify "$_msg_subject" "$_msg_data" "$NOTIFY_HOOK" 0 + fi + + _send_notify "$_msg_subject" "$_msg_data" "$NOTIFY_HOOK" "$_notify_code" fi fi @@ -5708,7 +5721,7 @@ install() { _debug "Skip install cron job" fi - if [ "$IN_CRON" != "1" ]; then + if [ "$ACME_IN_CRON" != "1" ]; then if ! _precheck "$_nocron"; then _err "Pre-check failed, can not install." return 1 @@ -5765,7 +5778,7 @@ install() { _info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY" - if [ "$IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then + if [ "$ACME_IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then _installalias "$_c_home" fi @@ -5863,7 +5876,7 @@ _uninstallalias() { } cron() { - export IN_CRON=1 + export ACME_IN_CRON=1 _initpath _info "$(__green "===Starting cron===")" if [ "$AUTO_UPGRADE" = "1" ]; then @@ -5884,7 +5897,7 @@ cron() { fi renewAll _ret="$?" - IN_CRON="" + ACME_IN_CRON="" _info "$(__green "===End cron===")" exit $_ret } @@ -6106,11 +6119,11 @@ Parameters: --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. 0: disabled, no notification will be sent. - 1: send notification only when there is an error. - 2: send notification when a cert is successfully renewed, or there is an error - 3: send notification when a cert is skipped, renewdd, or error + 1: send notifications only when there is an error. + 2: send notifications when a cert is successfully renewed, or there is an error. + 3: send notifications when a cert is skipped, renewed, or error. --notify-mode 0|1 Set notification mode. Default value is $NOTIFY_MODE_DEFAULT. - 0: Bulk mode. Send all the domain's notifications in one message(mail) + 0: Bulk mode. Send all the domain's notifications in one message(mail). 1: Cert mode. Send a message for every single cert. --notify-hook [hookname] Set the notify hook From f803c6c0bf3988efd9579832cf1f108a21d06316 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 15 Jun 2019 08:33:16 +0800 Subject: [PATCH 0377/2234] fix https://github.com/Neilpang/acme.sh/issues/2341 --- acme.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index bcc88ef0..c9f65ec2 100755 --- a/acme.sh +++ b/acme.sh @@ -4712,6 +4712,8 @@ renewAll() { _skipped_msg="" _error_level=$NOTIFY_LEVEL_SKIP _notify_code=$RENEW_SKIP + _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} + _debug "_set_level" "$_set_level" for di in "${CERT_HOME}"/*.*/; do _debug di "$di" if ! [ -d "$di" ]; then @@ -4735,7 +4737,7 @@ renewAll() { _notify_code=0 fi if [ "$ACME_IN_CRON" ]; then - if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_RENEW ]; then + if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 fi @@ -4749,7 +4751,7 @@ renewAll() { _notify_code=$RENEW_SKIP fi if [ "$ACME_IN_CRON" ]; then - if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_SKIP ]; then + if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then _send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" fi @@ -4764,7 +4766,7 @@ renewAll() { _notify_code=1 fi if [ "$ACME_IN_CRON" ]; then - if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_ERROR ]; then + if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 fi @@ -4783,7 +4785,7 @@ renewAll() { fi done _debug _error_level "$_error_level" - if [ "$ACME_IN_CRON" ] && [ $_error_level -le $NOTIFY_LEVEL ]; then + if [ "$ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then _msg_subject="Renew" if [ "$_error_msg" ]; then From c83f2f98bd2edde3c602bfdf7cc9f9bfd061d4b8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 19 Jun 2019 21:49:42 +0800 Subject: [PATCH 0378/2234] fix https://github.com/Neilpang/acme.sh/issues/2300 --- dnsapi/dns_ovh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 2669cc86..65567efd 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -121,7 +121,7 @@ _initAuth() { _info "Checking authentication" - if ! _ovh_rest GET "domain" || _contains "$response" "INVALID_CREDENTIAL"; then + if ! _ovh_rest GET "domain" || _contains "$response" "INVALID_CREDENTIAL" || _contains "$response" "NOT_CREDENTIAL"; then _err "The consumer key is invalid: $OVH_CK" _err "Please retry to create a new one." _clearaccountconf OVH_CK From a2738e8599918f3e7309237d686e7e1cbd28982d Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 19 Jun 2019 21:50:41 +0800 Subject: [PATCH 0379/2234] minor, add debug info --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index c9f65ec2..67fcdcb5 100755 --- a/acme.sh +++ b/acme.sh @@ -4785,6 +4785,7 @@ renewAll() { fi done _debug _error_level "$_error_level" + _debug _set_level "$_set_level" if [ "$ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then _msg_subject="Renew" From e0d4115ed7c45dd31f46cf3ff68d1b03e7f545a9 Mon Sep 17 00:00:00 2001 From: Maximilian Hippler Date: Fri, 21 Jun 2019 23:43:32 +0200 Subject: [PATCH 0380/2234] Finally added oathtool --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index f9d7b1bf..752692cf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.9 +FROM alpine:3.10 RUN apk update -f \ && apk --no-cache add -f \ @@ -8,7 +8,7 @@ RUN apk update -f \ curl \ socat \ tzdata \ - && apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/community oath-toolkit-oathtool \ + oath-toolkit-oathtool \ && rm -rf /var/cache/apk/* ENV LE_CONFIG_HOME /acme.sh From 971a85a6f82a72d74ab3bf29e4c80d9b05318b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Berlamont?= Date: Sat, 29 Jun 2019 18:14:34 +0200 Subject: [PATCH 0381/2234] dns_azure : Multiple domains with same ending bug We have a few domains that ends the same. For example : iperfony.com perfony.com The problem was in the _get_root functions, when getting the domain_id : only the first result "iperfony.com" was returned, because "perfony.com" is contained in the "iperfony.com" string. The correction consist of being strict in the regex, adding a slash (/) so that it will only match on ".*/(perfony.com).*" and not ".*(perfony.com).*". --- dnsapi/dns_azure.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index ae8aa1ca..8b52dee7 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -317,7 +317,7 @@ _get_root() { ## Per https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits#dns-limits you are limited to 100 Zone/subscriptions anyways ## _azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken" - # Find matching domain name is Json response + # Find matching domain name in Json response while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug2 "Checking domain: $h" @@ -328,7 +328,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(echo "$response" | _egrep_o "\\{\"id\":\"[^\"]*$h\"" | head -n 1 | cut -d : -f 2 | tr -d \") + _domain_id=$(echo "$response" | _egrep_o "\\{\"id\":\"[^\"]*\\/$h\"" | head -n 1 | cut -d : -f 2 | 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 d694ee8651a25b585cae76377e8d0e622f170b0b Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 30 Jun 2019 10:48:21 +0800 Subject: [PATCH 0382/2234] update --- .github/ISSUE_TEMPLATE.md | 4 +++- .github/PULL_REQUEST_TEMPLATE.md | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index f7d4d1d7..189155e1 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,5 +1,7 @@ \ No newline at end of file From ae66c6f0b484ce5c451ff8c195f382115b3d15a0 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Thu, 11 Jul 2019 15:46:17 -0400 Subject: [PATCH 0383/2234] Fix bug (in egrep regex) reported by @maks2018 in issue 2305 Fix bug reported by @maks2018 in issue https://github.com/Neilpang/acme.sh/issues/2305 by updating the regex in egrep of the subdomain html page. --- dnsapi/dns_freedns.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index e76e6495..ec845f89 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -305,7 +305,7 @@ _freedns_domain_id() { domain_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ | grep "$search_domain\|$search_domain(.*)" \ - | _egrep_o "edit\.php\?edit_domain_id=[0-9a-zA-Z]+" \ + | _egrep_o "edit\.php?edit_domain_id=[0-9a-zA-Z]*" \ | cut -d = -f 2)" # The above beauty extracts domain ID from the html page... # strip out all blank space and new lines. Then insert newlines @@ -352,7 +352,7 @@ _freedns_data_id() { data_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ | grep "$record_type" \ | grep "$search_domain" \ - | _egrep_o "edit\.php\?data_id=[0-9a-zA-Z]+" \ + | _egrep_o "edit\.php?data_id=[0-9a-zA-Z]*" \ | cut -d = -f 2)" # The above beauty extracts data ID from the html page... # strip out all blank space and new lines. Then insert newlines From 2ce9fb976024373850bb1de1e9ed939a995d3378 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Thu, 11 Jul 2019 18:06:56 -0400 Subject: [PATCH 0384/2234] Work around bug in _egrep_o() function _egrep_o() function accepts extended regex and on systems that do not have egrep uses sed to emulate egrep. This is failing on the specific regex I was using before my last commit... https://github.com/dkerr64/acme.sh/commit/ae66c6f0b484ce5c451ff8c195f382115b3d15a0 The problem is that I fixed it by passing in non-extended regex which then fails on systems that do have egrep. So I am no longer using _egrep_o. --- dnsapi/dns_freedns.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index ec845f89..8a48cf77 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -305,7 +305,7 @@ _freedns_domain_id() { domain_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ | grep "$search_domain\|$search_domain(.*)" \ - | _egrep_o "edit\.php?edit_domain_id=[0-9a-zA-Z]*" \ + | grep -o "edit\.php?edit_domain_id=[0-9a-zA-Z]*" \ | cut -d = -f 2)" # The above beauty extracts domain ID from the html page... # strip out all blank space and new lines. Then insert newlines @@ -352,7 +352,7 @@ _freedns_data_id() { data_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ | grep "$record_type" \ | grep "$search_domain" \ - | _egrep_o "edit\.php?data_id=[0-9a-zA-Z]*" \ + | grep -o "edit\.php?data_id=[0-9a-zA-Z]*" \ | cut -d = -f 2)" # The above beauty extracts data ID from the html page... # strip out all blank space and new lines. Then insert newlines From bd9af86de152697f3dbc8532ee813dad01566c10 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 13 Jul 2019 17:33:04 +0800 Subject: [PATCH 0385/2234] support jdcloud.com --- dnsapi/dns_jd.sh | 305 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 dnsapi/dns_jd.sh diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh new file mode 100644 index 00000000..28ac7dcf --- /dev/null +++ b/dnsapi/dns_jd.sh @@ -0,0 +1,305 @@ +#!/usr/bin/env sh + +# +#JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" +#JD_ACCESS_KEY_SECRET="xxxxxxx" +#JD_REGION="cn-north-1" +#JD_PACK_ID=0 + + +_JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey" + +_JD_PROD="clouddnsservice" +_JD_API="jdcloud-api.com" + +_JD_API_VERSION="v1" +_JD_DEFAULT_REGION="cn-north-1" + +_JD_HOST="$_JD_PROD.$_JD_API" + +_JD_PACK_FREE=0 +_JD_PACK_ENTERPRISE=1 +_JD_PACK_PREMIUM=2 + + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_jd_add() { + fulldomain=$1 + txtvalue=$2 + + JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" + JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" + JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" + JD_PACK_ID="${JD_PACK_ID:-$(_readaccountconf_mutable JD_PACK_ID)}" + + if [ -z "$JD_ACCESS_KEY_ID" ] || [ -z "$JD_ACCESS_KEY_SECRET" ]; then + JD_ACCESS_KEY_ID="" + JD_ACCESS_KEY_SECRET="" + _err "You haven't specifed the jdcloud api key id or api key secret yet." + _err "Please create your key and try again. see $(__green $_JD_ACCOUNT)" + return 1 + fi + + _saveaccountconf_mutable JD_ACCESS_KEY_ID "$JD_ACCESS_KEY_ID" + _saveaccountconf_mutable JD_ACCESS_KEY_SECRET "$JD_ACCESS_KEY_SECRET" + if [ -z "$JD_REGION" ]; then + _debug "Using default region: $_JD_DEFAULT_REGION" + JD_REGION="$_JD_DEFAULT_REGION" + else + _saveaccountconf_mutable JD_REGION "$JD_REGION" + fi + _JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION" + + if [ -z "$JD_PACK_ID" ]; then + _debug "Using default free pack: $_JD_PACK_FREE" + JD_PACK_ID=$_JD_PACK_FREE + else + _saveaccountconf_mutable JD_PACK_ID "$JD_PACK_ID" + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + #_debug "Getting getViewTree" + + _debug "Adding records" + + _addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":120,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" + #_addrr='{"req":{"hostRecord":"xx","hostValue":"\"value4\"","jcloudRes":false,"mxPriority":null,"port":null,"ttl":300,"type":"TXT","weight":null,"viewValue":-1},"regionId":"cn-north-1","domainId":"8824"}' + if jd_rest POST "domain/$_domain_id/RRAdd" "" "$_addrr"; then + _rid="$(echo "$response" | tr '{},' '\n' | grep '"id":' | cut -d : -f 2)" + if [ -z "$_rid" ]; then + _err "Can not find record id from the result." + return 1 + fi + _info "TXT record added successfully." + _srid="$(_readdomainconf "JD_CLOUD_RIDS")" + if [ "$_srid" ]; then + _rid="$_srid,$_rid" + fi + _savedomainconf "JD_CLOUD_RIDS" "$_rid" + return 0 + fi + + return 1 +} + + +dns_jd_rm() { + fulldomain=$1 + txtvalue=$2 + + JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" + JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" + JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" + JD_PACK_ID="${JD_PACK_ID:-$(_readaccountconf_mutable JD_PACK_ID)}" + if [ -z "$JD_REGION" ]; then + _debug "Using default region: $_JD_DEFAULT_REGION" + JD_REGION="$_JD_DEFAULT_REGION" + fi + + _JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION" + + _info "Getting existing records for $fulldomain" + _srid="$(_readdomainconf "JD_CLOUD_RIDS")" + _debug _srid "$_srid" + + if [ -z "$_srid" ]; then + _err "Not rid skip" + return 0 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _cleardomainconf JD_CLOUD_RIDS + + _aws_tmpl_xml="{\"ids\":[$_srid],\"action\":\"del\",\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" + + if jd_rest POST "domain/$_domain_id/RROperate" "" "$_aws_tmpl_xml" && _contains "$response" "\"code\":\"OK\""; then + _info "TXT record deleted successfully." + return 0 + fi + return 1 + +} + + +#################### Private functions below ################################## + +_get_root() { + domain=$1 + i=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug2 "Checking domain: $h" + if ! jd_rest GET "domain"; then + _err "error get domain list" + return 1 + fi + if [ -z "$h" ]; then + #not valid + _err "Invalid domain" + return 1 + fi + + if _contains "$response" "\"domainName\":\"$h\""; then + hostedzone="$(echo "$response" | tr '{}' '\n' | grep "\"domainName\":\"$h\"")" + _debug hostedzone "$hostedzone" + if [ "$hostedzone" ]; then + _domain_id="$(echo "$hostedzone" | tr ',' '\n' | grep "\"id\":" | cut -d : -f 2)" + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + fi + _err "Can't find domain with id: $h" + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} + + +#method uri qstr data +jd_rest() { + mtd="$1" + ep="$2" + qsr="$3" + data="$4" + + _debug mtd "$mtd" + _debug ep "$ep" + _debug qsr "$qsr" + _debug data "$data" + + CanonicalURI="/$_JD_BASE_URI/$ep" + _debug2 CanonicalURI "$CanonicalURI" + + CanonicalQueryString="$qsr" + _debug2 CanonicalQueryString "$CanonicalQueryString" + + RequestDate="$(date -u +"%Y%m%dT%H%M%SZ")" + #RequestDate="20190713T082155Z" ###################################################### + _debug2 RequestDate "$RequestDate" + export _H1="X-Jdcloud-Date: $RequestDate" + + RequestNonce="2bd0852a-8bae-4087-b2d5-$(_time)" + #RequestNonce="894baff5-72d4-4244-883a-7b2eb51e7fbe" ################################# + _debug2 RequestNonce "$RequestNonce" + export _H2="X-Jdcloud-Nonce: $RequestNonce" + + if [ "$data" ]; then + CanonicalHeaders="content-type:application/json\n" + SignedHeaders="content-type;" + else + CanonicalHeaders="" + SignedHeaders="" + fi + CanonicalHeaders="${CanonicalHeaders}host:$_JD_HOST\nx-jdcloud-date:$RequestDate\nx-jdcloud-nonce:$RequestNonce\n" + SignedHeaders="${SignedHeaders}host;x-jdcloud-date;x-jdcloud-nonce" + + _debug2 CanonicalHeaders "$CanonicalHeaders" + _debug2 SignedHeaders "$SignedHeaders" + + Hash="sha256" + + RequestPayload="$data" + _debug2 RequestPayload "$RequestPayload" + + RequestPayloadHash="$(printf "%s" "$RequestPayload" | _digest "$Hash" hex | _lower_case)" + _debug2 RequestPayloadHash "$RequestPayloadHash" + + CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$RequestPayloadHash" + _debug2 CanonicalRequest "$CanonicalRequest" + + HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)" + _debug2 HashedCanonicalRequest "$HashedCanonicalRequest" + + Algorithm="JDCLOUD2-HMAC-SHA256" + _debug2 Algorithm "$Algorithm" + + RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8)" + _debug2 RequestDateOnly "$RequestDateOnly" + + Region="$JD_REGION" + Service="$_JD_PROD" + + CredentialScope="$RequestDateOnly/$Region/$Service/jdcloud2_request" + _debug2 CredentialScope "$CredentialScope" + + StringToSign="$Algorithm\n$RequestDate\n$CredentialScope\n$HashedCanonicalRequest" + + _debug2 StringToSign "$StringToSign" + + kSecret="JDCLOUD2$JD_ACCESS_KEY_SECRET" + + _secure_debug2 kSecret "$kSecret" + + kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")" + _secure_debug2 kSecretH "$kSecretH" + + kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" + _debug2 kDateH "$kDateH" + + kRegionH="$(printf "$Region%s" | _hmac "$Hash" "$kDateH" hex)" + _debug2 kRegionH "$kRegionH" + + kServiceH="$(printf "$Service%s" | _hmac "$Hash" "$kRegionH" hex)" + _debug2 kServiceH "$kServiceH" + + kSigningH="$(printf "%s" "jdcloud2_request" | _hmac "$Hash" "$kServiceH" hex)" + _debug2 kSigningH "$kSigningH" + + signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)" + _debug2 signature "$signature" + + Authorization="$Algorithm Credential=$JD_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature" + _debug2 Authorization "$Authorization" + + _H3="Authorization: $Authorization" + _debug _H3 "$_H3" + + url="https://$_JD_HOST$CanonicalURI" + if [ "$qsr" ]; then + url="https://$_JD_HOST$CanonicalURI?$qsr" + fi + + if [ "$mtd" = "GET" ]; then + response="$(_get "$url")" + else + response="$(_post "$data" "$url" "" "$mtd" "application/json")" + fi + + _ret="$?" + _debug2 response "$response" + if [ "$_ret" = "0" ]; then + if _contains "$response" "\"error\""; then + _err "Response error:$response" + return 1 + fi + fi + + return "$_ret" +} + From 57b16e3ac2f18401cecceef1ca32d818c3b11bf0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 13 Jul 2019 17:42:01 +0800 Subject: [PATCH 0386/2234] fix format --- dnsapi/dns_jd.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh index 28ac7dcf..2efc91a3 100644 --- a/dnsapi/dns_jd.sh +++ b/dnsapi/dns_jd.sh @@ -6,7 +6,6 @@ #JD_REGION="cn-north-1" #JD_PACK_ID=0 - _JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey" _JD_PROD="clouddnsservice" @@ -21,7 +20,6 @@ _JD_PACK_FREE=0 _JD_PACK_ENTERPRISE=1 _JD_PACK_PREMIUM=2 - ######## Public functions ##################### #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -92,7 +90,6 @@ dns_jd_add() { return 1 } - dns_jd_rm() { fulldomain=$1 txtvalue=$2 @@ -138,7 +135,6 @@ dns_jd_rm() { } - #################### Private functions below ################################## _get_root() { @@ -180,7 +176,6 @@ _get_root() { return 1 } - #method uri qstr data jd_rest() { mtd="$1" @@ -302,4 +297,3 @@ jd_rest() { return "$_ret" } - From 42497028c458053f9fba1cb9fe43e3c03a3701b4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 13 Jul 2019 19:35:55 +0800 Subject: [PATCH 0387/2234] ttl 3000 --- dnsapi/dns_jd.sh | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh index 2efc91a3..d0f2a501 100644 --- a/dnsapi/dns_jd.sh +++ b/dnsapi/dns_jd.sh @@ -4,7 +4,6 @@ #JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" #JD_ACCESS_KEY_SECRET="xxxxxxx" #JD_REGION="cn-north-1" -#JD_PACK_ID=0 _JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey" @@ -16,10 +15,6 @@ _JD_DEFAULT_REGION="cn-north-1" _JD_HOST="$_JD_PROD.$_JD_API" -_JD_PACK_FREE=0 -_JD_PACK_ENTERPRISE=1 -_JD_PACK_PREMIUM=2 - ######## Public functions ##################### #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -30,7 +25,6 @@ dns_jd_add() { JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" - JD_PACK_ID="${JD_PACK_ID:-$(_readaccountconf_mutable JD_PACK_ID)}" if [ -z "$JD_ACCESS_KEY_ID" ] || [ -z "$JD_ACCESS_KEY_SECRET" ]; then JD_ACCESS_KEY_ID="" @@ -50,13 +44,6 @@ dns_jd_add() { fi _JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION" - if [ -z "$JD_PACK_ID" ]; then - _debug "Using default free pack: $_JD_PACK_FREE" - JD_PACK_ID=$_JD_PACK_FREE - else - _saveaccountconf_mutable JD_PACK_ID "$JD_PACK_ID" - fi - _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -70,7 +57,7 @@ dns_jd_add() { _debug "Adding records" - _addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":120,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" + _addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":300,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" #_addrr='{"req":{"hostRecord":"xx","hostValue":"\"value4\"","jcloudRes":false,"mxPriority":null,"port":null,"ttl":300,"type":"TXT","weight":null,"viewValue":-1},"regionId":"cn-north-1","domainId":"8824"}' if jd_rest POST "domain/$_domain_id/RRAdd" "" "$_addrr"; then _rid="$(echo "$response" | tr '{},' '\n' | grep '"id":' | cut -d : -f 2)" @@ -97,7 +84,7 @@ dns_jd_rm() { JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" - JD_PACK_ID="${JD_PACK_ID:-$(_readaccountconf_mutable JD_PACK_ID)}" + if [ -z "$JD_REGION" ]; then _debug "Using default region: $_JD_DEFAULT_REGION" JD_REGION="$_JD_DEFAULT_REGION" From 5f944743304976a55c1e974c5835c5b2996c2ce2 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Sat, 13 Jul 2019 20:01:06 +0800 Subject: [PATCH 0388/2234] support jdcloud.com (#2390) fix https://github.com/Neilpang/acme.sh/pull/2390 --- dnsapi/dns_jd.sh | 286 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 dnsapi/dns_jd.sh diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh new file mode 100644 index 00000000..d0f2a501 --- /dev/null +++ b/dnsapi/dns_jd.sh @@ -0,0 +1,286 @@ +#!/usr/bin/env sh + +# +#JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" +#JD_ACCESS_KEY_SECRET="xxxxxxx" +#JD_REGION="cn-north-1" + +_JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey" + +_JD_PROD="clouddnsservice" +_JD_API="jdcloud-api.com" + +_JD_API_VERSION="v1" +_JD_DEFAULT_REGION="cn-north-1" + +_JD_HOST="$_JD_PROD.$_JD_API" + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_jd_add() { + fulldomain=$1 + txtvalue=$2 + + JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" + JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" + JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" + + if [ -z "$JD_ACCESS_KEY_ID" ] || [ -z "$JD_ACCESS_KEY_SECRET" ]; then + JD_ACCESS_KEY_ID="" + JD_ACCESS_KEY_SECRET="" + _err "You haven't specifed the jdcloud api key id or api key secret yet." + _err "Please create your key and try again. see $(__green $_JD_ACCOUNT)" + return 1 + fi + + _saveaccountconf_mutable JD_ACCESS_KEY_ID "$JD_ACCESS_KEY_ID" + _saveaccountconf_mutable JD_ACCESS_KEY_SECRET "$JD_ACCESS_KEY_SECRET" + if [ -z "$JD_REGION" ]; then + _debug "Using default region: $_JD_DEFAULT_REGION" + JD_REGION="$_JD_DEFAULT_REGION" + else + _saveaccountconf_mutable JD_REGION "$JD_REGION" + fi + _JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + #_debug "Getting getViewTree" + + _debug "Adding records" + + _addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":300,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" + #_addrr='{"req":{"hostRecord":"xx","hostValue":"\"value4\"","jcloudRes":false,"mxPriority":null,"port":null,"ttl":300,"type":"TXT","weight":null,"viewValue":-1},"regionId":"cn-north-1","domainId":"8824"}' + if jd_rest POST "domain/$_domain_id/RRAdd" "" "$_addrr"; then + _rid="$(echo "$response" | tr '{},' '\n' | grep '"id":' | cut -d : -f 2)" + if [ -z "$_rid" ]; then + _err "Can not find record id from the result." + return 1 + fi + _info "TXT record added successfully." + _srid="$(_readdomainconf "JD_CLOUD_RIDS")" + if [ "$_srid" ]; then + _rid="$_srid,$_rid" + fi + _savedomainconf "JD_CLOUD_RIDS" "$_rid" + return 0 + fi + + return 1 +} + +dns_jd_rm() { + fulldomain=$1 + txtvalue=$2 + + JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" + JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" + JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" + + if [ -z "$JD_REGION" ]; then + _debug "Using default region: $_JD_DEFAULT_REGION" + JD_REGION="$_JD_DEFAULT_REGION" + fi + + _JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION" + + _info "Getting existing records for $fulldomain" + _srid="$(_readdomainconf "JD_CLOUD_RIDS")" + _debug _srid "$_srid" + + if [ -z "$_srid" ]; then + _err "Not rid skip" + return 0 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _cleardomainconf JD_CLOUD_RIDS + + _aws_tmpl_xml="{\"ids\":[$_srid],\"action\":\"del\",\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" + + if jd_rest POST "domain/$_domain_id/RROperate" "" "$_aws_tmpl_xml" && _contains "$response" "\"code\":\"OK\""; then + _info "TXT record deleted successfully." + return 0 + fi + return 1 + +} + +#################### Private functions below ################################## + +_get_root() { + domain=$1 + i=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug2 "Checking domain: $h" + if ! jd_rest GET "domain"; then + _err "error get domain list" + return 1 + fi + if [ -z "$h" ]; then + #not valid + _err "Invalid domain" + return 1 + fi + + if _contains "$response" "\"domainName\":\"$h\""; then + hostedzone="$(echo "$response" | tr '{}' '\n' | grep "\"domainName\":\"$h\"")" + _debug hostedzone "$hostedzone" + if [ "$hostedzone" ]; then + _domain_id="$(echo "$hostedzone" | tr ',' '\n' | grep "\"id\":" | cut -d : -f 2)" + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + fi + _err "Can't find domain with id: $h" + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} + +#method uri qstr data +jd_rest() { + mtd="$1" + ep="$2" + qsr="$3" + data="$4" + + _debug mtd "$mtd" + _debug ep "$ep" + _debug qsr "$qsr" + _debug data "$data" + + CanonicalURI="/$_JD_BASE_URI/$ep" + _debug2 CanonicalURI "$CanonicalURI" + + CanonicalQueryString="$qsr" + _debug2 CanonicalQueryString "$CanonicalQueryString" + + RequestDate="$(date -u +"%Y%m%dT%H%M%SZ")" + #RequestDate="20190713T082155Z" ###################################################### + _debug2 RequestDate "$RequestDate" + export _H1="X-Jdcloud-Date: $RequestDate" + + RequestNonce="2bd0852a-8bae-4087-b2d5-$(_time)" + #RequestNonce="894baff5-72d4-4244-883a-7b2eb51e7fbe" ################################# + _debug2 RequestNonce "$RequestNonce" + export _H2="X-Jdcloud-Nonce: $RequestNonce" + + if [ "$data" ]; then + CanonicalHeaders="content-type:application/json\n" + SignedHeaders="content-type;" + else + CanonicalHeaders="" + SignedHeaders="" + fi + CanonicalHeaders="${CanonicalHeaders}host:$_JD_HOST\nx-jdcloud-date:$RequestDate\nx-jdcloud-nonce:$RequestNonce\n" + SignedHeaders="${SignedHeaders}host;x-jdcloud-date;x-jdcloud-nonce" + + _debug2 CanonicalHeaders "$CanonicalHeaders" + _debug2 SignedHeaders "$SignedHeaders" + + Hash="sha256" + + RequestPayload="$data" + _debug2 RequestPayload "$RequestPayload" + + RequestPayloadHash="$(printf "%s" "$RequestPayload" | _digest "$Hash" hex | _lower_case)" + _debug2 RequestPayloadHash "$RequestPayloadHash" + + CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$RequestPayloadHash" + _debug2 CanonicalRequest "$CanonicalRequest" + + HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)" + _debug2 HashedCanonicalRequest "$HashedCanonicalRequest" + + Algorithm="JDCLOUD2-HMAC-SHA256" + _debug2 Algorithm "$Algorithm" + + RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8)" + _debug2 RequestDateOnly "$RequestDateOnly" + + Region="$JD_REGION" + Service="$_JD_PROD" + + CredentialScope="$RequestDateOnly/$Region/$Service/jdcloud2_request" + _debug2 CredentialScope "$CredentialScope" + + StringToSign="$Algorithm\n$RequestDate\n$CredentialScope\n$HashedCanonicalRequest" + + _debug2 StringToSign "$StringToSign" + + kSecret="JDCLOUD2$JD_ACCESS_KEY_SECRET" + + _secure_debug2 kSecret "$kSecret" + + kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")" + _secure_debug2 kSecretH "$kSecretH" + + kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" + _debug2 kDateH "$kDateH" + + kRegionH="$(printf "$Region%s" | _hmac "$Hash" "$kDateH" hex)" + _debug2 kRegionH "$kRegionH" + + kServiceH="$(printf "$Service%s" | _hmac "$Hash" "$kRegionH" hex)" + _debug2 kServiceH "$kServiceH" + + kSigningH="$(printf "%s" "jdcloud2_request" | _hmac "$Hash" "$kServiceH" hex)" + _debug2 kSigningH "$kSigningH" + + signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)" + _debug2 signature "$signature" + + Authorization="$Algorithm Credential=$JD_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature" + _debug2 Authorization "$Authorization" + + _H3="Authorization: $Authorization" + _debug _H3 "$_H3" + + url="https://$_JD_HOST$CanonicalURI" + if [ "$qsr" ]; then + url="https://$_JD_HOST$CanonicalURI?$qsr" + fi + + if [ "$mtd" = "GET" ]; then + response="$(_get "$url")" + else + response="$(_post "$data" "$url" "" "$mtd" "application/json")" + fi + + _ret="$?" + _debug2 response "$response" + if [ "$_ret" = "0" ]; then + if _contains "$response" "\"error\""; then + _err "Response error:$response" + return 1 + fi + fi + + return "$_ret" +} From 28a9df669d80e696677ef5ca0248e2801a7bfc0e Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sat, 13 Jul 2019 14:35:09 +0200 Subject: [PATCH 0389/2234] Escape slashes (#2375) --- dnsapi/dns_namecheap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 6553deb6..a82e12d7 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -164,7 +164,7 @@ _namecheap_set_publicip() { _debug sourceip "$NAMECHEAP_SOURCEIP" ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') - addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*') + addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https):\/\/.*') _debug2 ip "$ip" _debug2 addr "$addr" From 3cdfa4051d98a0bbc1dab64d8028556324b1e0a4 Mon Sep 17 00:00:00 2001 From: Jeff Wang <3102114+wangqiliang@users.noreply.github.com> Date: Sat, 13 Jul 2019 23:05:30 +0800 Subject: [PATCH 0390/2234] Change 1.1.1.1 to 1.0.0.1 to probe compatibility (#2330) As we can see, 1.1.1.1 is not routed or routed to an Intranet devices due to historical reason. Change 1.1.1.1 to 1.0.0.1 will have a better compatibility. I found this problem on my Tencent Cloud server. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 67fcdcb5..d168b566 100755 --- a/acme.sh +++ b/acme.sh @@ -3621,7 +3621,7 @@ _ns_purge_cf() { _cf_d="$1" _cf_d_type="$2" _debug "Cloudflare purge $_cf_d_type record for domain $_cf_d" - _cf_purl="https://1.1.1.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" + _cf_purl="https://1.0.0.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" response="$(_post "" "$_cf_purl")" _debug2 response "$response" } From 28cadc5e06f9d79ba315636e240514c197656bf6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 18 Jul 2019 21:05:59 +0800 Subject: [PATCH 0391/2234] check empty id --- dnsapi/dns_namesilo.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index dc1a4fda..15e4f21d 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -59,9 +59,14 @@ dns_namesilo_rm() { if _namesilo_rest GET "dnsListRecords?version=1&type=xml&key=$Namesilo_Key&domain=$_domain"; then retcode=$(printf "%s\n" "$response" | _egrep_o "300") if [ "$retcode" ]; then - _record_id=$(printf "%s\n" "$response" | _egrep_o "([^<]*)TXT$fulldomain" | _egrep_o "([^<]*)" | sed -r "s/([^<]*)<\/record_id>/\1/" | tail -n 1) + _record_id=$(echo "$response" | _egrep_o "([^<]*)TXT$fulldomain" | _egrep_o "([^<]*)" | sed -r "s/([^<]*)<\/record_id>/\1/" | tail -n 1) _debug record_id "$_record_id" - _info "Successfully retrieved the record id for ACME challenge." + if [ "$record_id" ]; then + _info "Successfully retrieved the record id for ACME challenge." + else + _info "Empty record id, it seems no such record." + return 0 + fi else _err "Unable to retrieve the record id." return 1 From 5c09788ec4cacc85a426f3444436b5b374976cff Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 18 Jul 2019 22:20:51 +0800 Subject: [PATCH 0392/2234] fix error --- dnsapi/dns_namesilo.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index 15e4f21d..ed6d0e08 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -60,8 +60,8 @@ dns_namesilo_rm() { retcode=$(printf "%s\n" "$response" | _egrep_o "300") if [ "$retcode" ]; then _record_id=$(echo "$response" | _egrep_o "([^<]*)TXT$fulldomain" | _egrep_o "([^<]*)" | sed -r "s/([^<]*)<\/record_id>/\1/" | tail -n 1) - _debug record_id "$_record_id" - if [ "$record_id" ]; then + _debug _record_id "$_record_id" + if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." else _info "Empty record id, it seems no such record." From 8d393ff13722bf7acfac84879363b8d50a04c7b7 Mon Sep 17 00:00:00 2001 From: Yuri S Date: Sat, 20 Jul 2019 09:26:23 +0500 Subject: [PATCH 0393/2234] Add dnsapi for Vultr (#2370) * Add Vultr dns api --- dnsapi/dns_vultr.sh | 163 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 dnsapi/dns_vultr.sh diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh new file mode 100644 index 00000000..f15e7c49 --- /dev/null +++ b/dnsapi/dns_vultr.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env sh + +# +#VULTR_API_KEY=000011112222333344445555666677778888 + +VULTR_Api="https://api.vultr.com/v1" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_vultr_add() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}" + if test -z "$VULTR_API_KEY"; then + VULTR_API_KEY='' + _err 'VULTR_API_KEY was not exported' + return 1 + fi + + _saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug 'Getting txt records' + _vultr_rest GET "dns/records?domain=$_domain" + + if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then + _err 'Error' + return 1 + fi + + if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + return 0 +} + +#fulldomain txtvalue +dns_vultr_rm() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}" + if test -z "$VULTR_API_KEY"; then + VULTR_API_KEY="" + _err 'VULTR_API_KEY was not exported' + return 1 + fi + + _saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug 'Getting txt records' + _vultr_rest GET "dns/records?domain=$_domain" + + if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then + _err 'Error' + return 1 + fi + + _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)" + _debug _record_id "$_record_id" + if [ "$_record_id" ]; then + _info "Successfully retrieved the record id for ACME challenge." + else + _info "Empty record id, it seems no such record." + return 0 + fi + + if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + 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=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + return 1 + fi + + if ! _vultr_rest GET "dns/list"; then + return 1 + fi + + if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then + if _contains "$response" "\"domain\":\"$_domain\""; then + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" + _domain=$_domain + return 0 + else + _err 'Invalid domain' + return 1 + fi + else + _err "$response" + return 1 + fi + i=$(_math "$i" + 1) + done + + return 1 +} + +_vultr_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"') + + export _H1="Api-Key: $api_key_trimmed" + export _H2='Content-Type: application/x-www-form-urlencoded' + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$VULTR_Api/$ep" "" "$m")" + else + response="$(_get "$VULTR_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "Error $ep" + return 1 + fi + + _debug2 response "$response" + return 0 +} From b8e6287774b64ca42de3b301df7d5b57a3e216af Mon Sep 17 00:00:00 2001 From: tdk1069 Date: Sat, 20 Jul 2019 05:30:56 +0100 Subject: [PATCH 0394/2234] PushOver notifications (#2325) * PushOver notifications, using AppToken, UserKey, and optional sounds --- notify/pushover.sh | 67 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 notify/pushover.sh diff --git a/notify/pushover.sh b/notify/pushover.sh new file mode 100644 index 00000000..70eba733 --- /dev/null +++ b/notify/pushover.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env sh + +#Support for pushover.net's api. Push notification platform for multiple platforms +#PUSHOVER_TOKEN="" Required, pushover application token +#PUSHOVER_USER="" Required, pushover userkey +#PUSHOVER_DEVICE="" Optional, Specific device or devices by hostnames, joining multiples with a comma (such as device=iphone,nexus5) +#PUSHOVER_PRIORITY="" Optional, Lowest Priority (-2), Low Priority (-1), Normal Priority (0), High Priority (1) + +PUSHOVER_URI="https://api.pushover.net/1/messages.json" + +pushover_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + PUSHOVER_TOKEN="${PUSHOVER_TOKEN:-$(_readaccountconf_mutable PUSHOVER_TOKEN)}" + if [ -z "$PUSHOVER_TOKEN" ]; then + PUSHOVER_TOKEN="" + _err "You didn't specify a PushOver application token yet." + return 1 + fi + _saveaccountconf_mutable PUSHOVER_TOKEN "$PUSHOVER_TOKEN" + + PUSHOVER_USER="${PUSHOVER_USER:-$(_readaccountconf_mutable PUSHOVER_USER)}" + if [ -z "$PUSHOVER_USER" ]; then + PUSHOVER_USER="" + _err "You didn't specify a PushOver UserKey yet." + return 1 + fi + _saveaccountconf_mutable PUSHOVER_USER "$PUSHOVER_USER" + + PUSHOVER_DEVICE="${PUSHOVER_DEVICE:-$(_readaccountconf_mutable PUSHOVER_DEVICE)}" + if [ -z "$PUSHOVER_DEVICE" ]; then + PUSHOVER_DEVICE="" + fi + _saveaccountconf_mutable PUSHOVER_DEVICE "$PUSHOVER_DEVICE" + + PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-$(_readaccountconf_mutable PUSHOVER_PRIORITY)}" + if [ -z "$PUSHOVER_PRIORITY" ]; then + PUSHOVER_PRIORITY="0" + fi + _saveaccountconf_mutable PUSHOVER_PRIORITY "$PUSHOVER_PRIORITY" + + + PUSHOVER_SOUND="${PUSHOVER_SOUND:-$(_readaccountconf_mutable PUSHOVER_SOUND)}" + if [ -z "$PUSHOVER_SOUND" ]; then + PUSHOVER_SOUND="" # Play default if not specified. + fi + _saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND" + + export _H1="Content-Type: application/json" + _content="$(printf "*%s*\n" "$_content" | _json_encode)" + _subject="$(printf "*%s*\n" "$_subject" | _json_encode)" + _data="{\"token\": \"$PUSHOVER_TOKEN\",\"user\": \"$PUSHOVER_USER\",\"title\": \"$_subject\",\"message\": \"$_content\",\"sound\": \"$PUSHOVER_SOUND\", \"device\": \"$PUSHOVER_DEVICE\", \"priority\": \"$PUSHOVER_PRIORITY\"}" + + response="" #just make shellcheck happy + if _post "$_data" "$PUSHOVER_URI"; then + if _contains "$response" "{\"status\":1"; then + _info "PUSHOVER send sccess." + return 0 + fi + fi + _err "PUSHOVER send error." + _err "$response" + return 1 +} From 28c153a0a2dd667f2eb2e810d4f2a3cea4471506 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 20 Jul 2019 12:36:28 +0800 Subject: [PATCH 0395/2234] fix errors --- notify/pushover.sh | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/notify/pushover.sh b/notify/pushover.sh index 70eba733..309b3907 100644 --- a/notify/pushover.sh +++ b/notify/pushover.sh @@ -31,23 +31,20 @@ pushover_send() { _saveaccountconf_mutable PUSHOVER_USER "$PUSHOVER_USER" PUSHOVER_DEVICE="${PUSHOVER_DEVICE:-$(_readaccountconf_mutable PUSHOVER_DEVICE)}" - if [ -z "$PUSHOVER_DEVICE" ]; then - PUSHOVER_DEVICE="" + if [ "$PUSHOVER_DEVICE" ]; then + _saveaccountconf_mutable PUSHOVER_DEVICE "$PUSHOVER_DEVICE" fi - _saveaccountconf_mutable PUSHOVER_DEVICE "$PUSHOVER_DEVICE" PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-$(_readaccountconf_mutable PUSHOVER_PRIORITY)}" - if [ -z "$PUSHOVER_PRIORITY" ]; then - PUSHOVER_PRIORITY="0" + if [ "$PUSHOVER_PRIORITY" ]; then + _saveaccountconf_mutable PUSHOVER_PRIORITY "$PUSHOVER_PRIORITY" fi - _saveaccountconf_mutable PUSHOVER_PRIORITY "$PUSHOVER_PRIORITY" - PUSHOVER_SOUND="${PUSHOVER_SOUND:-$(_readaccountconf_mutable PUSHOVER_SOUND)}" - if [ -z "$PUSHOVER_SOUND" ]; then + if [ "$PUSHOVER_SOUND" ]; then PUSHOVER_SOUND="" # Play default if not specified. + _saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND" fi - _saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND" export _H1="Content-Type: application/json" _content="$(printf "*%s*\n" "$_content" | _json_encode)" From ccc2142b452a5b86e483fc5d80ff658f91d14146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szil=C3=A1rd=20Pfeiffer?= Date: Sat, 20 Jul 2019 10:00:38 +0200 Subject: [PATCH 0396/2234] added dns api support for hexonet (#1776) --- dnsapi/dns_hexonet.sh | 156 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100755 dnsapi/dns_hexonet.sh diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh new file mode 100755 index 00000000..ccd201eb --- /dev/null +++ b/dnsapi/dns_hexonet.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env sh + +# +# Hexonet_Username="username" +# +# Hexonet_Password="password" + +Hexonet_Api="https://coreapi.1api.net/api/call.cgi" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_hexonet_add() { + fulldomain=$1 + txtvalue=$2 + + Hexonet_Username="${Hexonet_Username:-$(_readaccountconf_mutable Hexonet_Username)}" + Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" + if [ -z "$Hexonet_Username" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Username="" + Hexonet_Password="" + _err "You must export variables: Hexonet_Username and Hexonet_Password" + return 1 + fi + + if ! _contains "$Hexonet_Username" "!"; then + _err "It seems that the Hexonet_Username=$Hexonet_Username is not a restrivteed user." + _err "Please check and retry." + return 1 + fi + + #save the username and password to the account conf file. + _saveaccountconf_mutable Hexonet_Username "$Hexonet_Username" + _saveaccountconf_mutable Hexonet_Password "$Hexonet_Password" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT" + + if ! _contains "$response" "CODE=200"; then + _err "Error" + return 1 + fi + + _info "Adding record" + if _hexonet_rest "command=UpdateDNSZone&dnszone=${_domain}.&addrr0=${_sub_domain}%20IN%20TXT%20${txtvalue}"; then + if _contains "$response" "CODE=200"; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_hexonet_rm() { + fulldomain=$1 + txtvalue=$2 + + Hexonet_Username="${Hexonet_Username:-$(_readaccountconf_mutable Hexonet_Username)}" + Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" + if [ -z "$Hexonet_Username" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Username="" + Hexonet_Password="" + _err "You must export variables: Hexonet_Username and Hexonet_Password" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT&RR=${txtvalue}" + + if ! _contains "$response" "CODE=200"; then + _err "Error" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "PROPERTY[TOTAL][0]=" | cut -d = -f 2) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + if ! _hexonet_rest "&command=UpdateDNSZone&dnszone=${_domain}.&delrr0='${_sub_domain}%20IN%20TXT%20\"${txtvalue}\""; then + _err "Delete record error." + return 1 + fi + _contains "$response" "CODE=200" + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}."; then + return 1 + fi + + if _contains "$response" "CODE=200"; 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 +} + +_hexonet_rest() { + query_params="$1" + _debug "$query_params" + + response="$(_get "${Hexonet_Api}?s_login=${Hexonet_Username}&s_pw=${Hexonet_Password}&${query_params}")" + + if [ "$?" != "0" ]; then + _err "error $query_params" + return 1 + fi + _debug2 response "$response" + return 0 +} From 93d29a9733169437cbc5df4a65a8636edbde2c8e Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 20 Jul 2019 17:09:36 +0800 Subject: [PATCH 0397/2234] update --- dnsapi/dns_hexonet.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh index ccd201eb..f1503118 100755 --- a/dnsapi/dns_hexonet.sh +++ b/dnsapi/dns_hexonet.sh @@ -1,9 +1,9 @@ #!/usr/bin/env sh # -# Hexonet_Username="username" +# Hexonet_Login="username!roleId" # -# Hexonet_Password="password" +# Hexonet_Password="rolePassword" Hexonet_Api="https://coreapi.1api.net/api/call.cgi" @@ -14,23 +14,23 @@ dns_hexonet_add() { fulldomain=$1 txtvalue=$2 - Hexonet_Username="${Hexonet_Username:-$(_readaccountconf_mutable Hexonet_Username)}" + Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}" Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" - if [ -z "$Hexonet_Username" ] || [ -z "$Hexonet_Password" ]; then - Hexonet_Username="" + if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Login="" Hexonet_Password="" - _err "You must export variables: Hexonet_Username and Hexonet_Password" + _err "You must export variables: Hexonet_Login and Hexonet_Password" return 1 fi - if ! _contains "$Hexonet_Username" "!"; then - _err "It seems that the Hexonet_Username=$Hexonet_Username is not a restrivteed user." + if ! _contains "$Hexonet_Login" "!"; then + _err "It seems that the Hexonet_Login=$Hexonet_Login is not a restrivteed user." _err "Please check and retry." return 1 fi #save the username and password to the account conf file. - _saveaccountconf_mutable Hexonet_Username "$Hexonet_Username" + _saveaccountconf_mutable Hexonet_Login "$Hexonet_Login" _saveaccountconf_mutable Hexonet_Password "$Hexonet_Password" _debug "First detect the root zone" @@ -69,12 +69,12 @@ dns_hexonet_rm() { fulldomain=$1 txtvalue=$2 - Hexonet_Username="${Hexonet_Username:-$(_readaccountconf_mutable Hexonet_Username)}" + Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}" Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" - if [ -z "$Hexonet_Username" ] || [ -z "$Hexonet_Password" ]; then - Hexonet_Username="" + if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Login="" Hexonet_Password="" - _err "You must export variables: Hexonet_Username and Hexonet_Password" + _err "You must export variables: Hexonet_Login and Hexonet_Password" return 1 fi @@ -145,7 +145,7 @@ _hexonet_rest() { query_params="$1" _debug "$query_params" - response="$(_get "${Hexonet_Api}?s_login=${Hexonet_Username}&s_pw=${Hexonet_Password}&${query_params}")" + response="$(_get "${Hexonet_Api}?s_login=${Hexonet_Login}&s_pw=${Hexonet_Password}&${query_params}")" if [ "$?" != "0" ]; then _err "error $query_params" From 80af3d6ada23098bb68e3be63e72e0cfd4406ce1 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 22 Jul 2019 21:26:47 +0800 Subject: [PATCH 0398/2234] minor --- notify/pushover.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/notify/pushover.sh b/notify/pushover.sh index 309b3907..a07cbd3d 100644 --- a/notify/pushover.sh +++ b/notify/pushover.sh @@ -42,7 +42,6 @@ pushover_send() { PUSHOVER_SOUND="${PUSHOVER_SOUND:-$(_readaccountconf_mutable PUSHOVER_SOUND)}" if [ "$PUSHOVER_SOUND" ]; then - PUSHOVER_SOUND="" # Play default if not specified. _saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND" fi @@ -54,7 +53,7 @@ pushover_send() { response="" #just make shellcheck happy if _post "$_data" "$PUSHOVER_URI"; then if _contains "$response" "{\"status\":1"; then - _info "PUSHOVER send sccess." + _info "PUSHOVER send success." return 0 fi fi From c25947d5447ac03ac0fae56b338e8821d49d61ac Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 22 Jul 2019 22:25:50 +0800 Subject: [PATCH 0399/2234] support new Cloudflare Token format fix https://github.com/Neilpang/acme.sh/issues/2398 --- dnsapi/dns_cf.sh | 83 +++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index cd93189f..d4266d18 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -5,6 +5,9 @@ # #CF_Email="xxxx@sss.com" +#CF_Token="xxxx" +#CF_Account_ID="xxxx" + CF_Api="https://api.cloudflare.com/client/v4" ######## Public functions ##################### @@ -14,26 +17,33 @@ dns_cf_add() { fulldomain=$1 txtvalue=$2 + CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" + CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then - CF_Key="" - CF_Email="" - _err "You didn't specify a Cloudflare api key and email yet." - _err "You can get yours from here https://dash.cloudflare.com/profile." - return 1 - fi + + if [ "$CF_Token" ]; then + _saveaccountconf_mutable CF_Token "$CF_Token" + _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" + else + if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then + CF_Key="" + CF_Email="" + _err "You didn't specify a Cloudflare api key and email yet." + _err "You can get yours from here https://dash.cloudflare.com/profile." + return 1 + fi - if ! _contains "$CF_Email" "@"; then - _err "It seems that the CF_Email=$CF_Email is not a valid email address." - _err "Please check and retry." - return 1 + if ! _contains "$CF_Email" "@"; then + _err "It seems that the CF_Email=$CF_Email is not a valid email address." + _err "Please check and retry." + return 1 + fi + #save the api key and email to the account conf file. + _saveaccountconf_mutable CF_Key "$CF_Key" + _saveaccountconf_mutable CF_Email "$CF_Email" fi - #save the api key and email to the account conf file. - _saveaccountconf_mutable CF_Key "$CF_Key" - _saveaccountconf_mutable CF_Email "$CF_Email" - _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -71,19 +81,6 @@ dns_cf_add() { fi _err "Add txt record error." return 1 - # else - # _info "Updating record" - # record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) - # _debug "record_id" "$record_id" - # - # _cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}" - # if [ "$?" = "0" ]; then - # _info "Updated, OK" - # return 0 - # fi - # _err "Update error" - # return 1 - # fi } @@ -92,15 +89,10 @@ dns_cf_rm() { fulldomain=$1 txtvalue=$2 + CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" + CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then - CF_Key="" - CF_Email="" - _err "You didn't specify a Cloudflare api key and email yet." - _err "You can get yours from here https://dash.cloudflare.com/profile." - return 1 - fi _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -157,8 +149,14 @@ _get_root() { return 1 fi - if ! _cf_rest GET "zones?name=$h"; then - return 1 + if [ "$CF_Account_ID" ]; then + if ! _cf_rest GET "zones?name=$h&account.id=$CF_Account_ID"; then + return 1 + fi + else + if ! _cf_rest GET "zones?name=$h"; then + return 1 + fi fi if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then @@ -184,10 +182,15 @@ _cf_rest() { email_trimmed=$(echo $CF_Email | tr -d '"') key_trimmed=$(echo $CF_Key | tr -d '"') + token_trimmed=$(echo $CF_Token | tr -d '"') - export _H1="X-Auth-Email: $email_trimmed" - export _H2="X-Auth-Key: $key_trimmed" - export _H3="Content-Type: application/json" + export _H1="Content-Type: application/json" + if [ "$token_trimmed" ]; then + export _H2="Authorization: Bearer $token_trimmed" + else + export _H2="X-Auth-Email: $email_trimmed" + export _H3="X-Auth-Key: $key_trimmed" + fi if [ "$m" != "GET" ]; then _debug data "$data" From 54e189616c0e96288a42e5fb24ae7fa2846e16d0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 23 Jul 2019 21:36:42 +0800 Subject: [PATCH 0400/2234] fix wildcard domain name --- deploy/docker.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deploy/docker.sh b/deploy/docker.sh index 4e550991..44bb044b 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -223,7 +223,8 @@ _docker_cp() { _debug2 "_frompath" "$_frompath" _toname="$(basename "$_to")" _debug2 "_toname" "$_toname" - if ! tar --transform="s,$_frompath,$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then + _debug2 "_from" "$_from" + if ! tar --transform="s,$(printf "%s" "$_frompath" | tr '*' .),$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then _err "copy error" return 1 fi From 45e8bb03e438892d974153b5326b06aece628a56 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 23 Jul 2019 21:43:00 +0800 Subject: [PATCH 0401/2234] add more info --- deploy/docker.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/docker.sh b/deploy/docker.sh index 44bb044b..05333b3f 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -126,6 +126,7 @@ docker_deploy() { fi if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then + _info "Reloading: $DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then return 1 fi From 9a733a57e73fbb09f300f8eac5004aafef6e61d6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 24 Jul 2019 21:49:26 +0800 Subject: [PATCH 0402/2234] fix https://github.com/Neilpang/acme.sh/issues/2377 --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d168b566..891d2e1e 100755 --- a/acme.sh +++ b/acme.sh @@ -3035,11 +3035,13 @@ _clearupdns() { d=$(_getfield "$entry" 1) txtdomain=$(_getfield "$entry" 2) aliasDomain=$(_getfield "$entry" 3) + _currentRoot=$(_getfield "$entry" 4) txt=$(_getfield "$entry" 5) d_api=$(_getfield "$entry" 6) _debug "d" "$d" _debug "txtdomain" "$txtdomain" _debug "aliasDomain" "$aliasDomain" + _debug "_currentRoot" "$_currentRoot" _debug "txt" "$txt" _debug "d_api" "$d_api" if [ "$d_api" = "$txt" ]; then @@ -6787,7 +6789,7 @@ _process() { _debug "Using server: $_server" fi fi - + _debug "Running cmd: ${_CMD}" case "${_CMD}" in install) install "$_nocron" "$_confighome" "$_noprofile" ;; uninstall) uninstall "$_nocron" ;; From 72e7eb6777d14097961422959eaa0e9ecb3becfc Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 27 Jul 2019 10:49:11 +0800 Subject: [PATCH 0403/2234] fix format --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index d4266d18..f1725bd7 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -21,7 +21,7 @@ dns_cf_add() { CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - + if [ "$CF_Token" ]; then _saveaccountconf_mutable CF_Token "$CF_Token" _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" From 41c951811e38002df1d7efad8b1197368aed4697 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 27 Jul 2019 11:09:13 +0800 Subject: [PATCH 0404/2234] fix format --- dnsapi/dns_cf.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index f1725bd7..62e40caf 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -180,9 +180,9 @@ _cf_rest() { data="$3" _debug "$ep" - email_trimmed=$(echo $CF_Email | tr -d '"') - key_trimmed=$(echo $CF_Key | tr -d '"') - token_trimmed=$(echo $CF_Token | tr -d '"') + email_trimmed=$(echo "$CF_Email" | tr -d '"') + key_trimmed=$(echo "$CF_Key" | tr -d '"') + token_trimmed=$(echo "$CF_Token" | tr -d '"') export _H1="Content-Type: application/json" if [ "$token_trimmed" ]; then From 55dea4ee9d2187912ecf97689e12a6e8183a1091 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Sat, 27 Jul 2019 11:48:29 +0800 Subject: [PATCH 0405/2234] sync (#2404) * support jdcloud.com * fix format * ttl 3000 * Escape slashes (#2375) * Change 1.1.1.1 to 1.0.0.1 to probe compatibility (#2330) As we can see, 1.1.1.1 is not routed or routed to an Intranet devices due to historical reason. Change 1.1.1.1 to 1.0.0.1 will have a better compatibility. I found this problem on my Tencent Cloud server. * check empty id * fix error * Add dnsapi for Vultr (#2370) * Add Vultr dns api * PushOver notifications (#2325) * PushOver notifications, using AppToken, UserKey, and optional sounds * fix errors * added dns api support for hexonet (#1776) * update * minor * support new Cloudflare Token format fix https://github.com/Neilpang/acme.sh/issues/2398 * fix wildcard domain name * add more info * fix https://github.com/Neilpang/acme.sh/issues/2377 * fix format * fix format --- acme.sh | 6 +- deploy/docker.sh | 4 +- dnsapi/dns_cf.sh | 87 ++++++++++----------- dnsapi/dns_hexonet.sh | 156 ++++++++++++++++++++++++++++++++++++++ dnsapi/dns_namecheap.sh | 2 +- dnsapi/dns_namesilo.sh | 11 ++- dnsapi/dns_vultr.sh | 163 ++++++++++++++++++++++++++++++++++++++++ notify/pushover.sh | 63 ++++++++++++++++ 8 files changed, 443 insertions(+), 49 deletions(-) create mode 100755 dnsapi/dns_hexonet.sh create mode 100644 dnsapi/dns_vultr.sh create mode 100644 notify/pushover.sh diff --git a/acme.sh b/acme.sh index 67fcdcb5..891d2e1e 100755 --- a/acme.sh +++ b/acme.sh @@ -3035,11 +3035,13 @@ _clearupdns() { d=$(_getfield "$entry" 1) txtdomain=$(_getfield "$entry" 2) aliasDomain=$(_getfield "$entry" 3) + _currentRoot=$(_getfield "$entry" 4) txt=$(_getfield "$entry" 5) d_api=$(_getfield "$entry" 6) _debug "d" "$d" _debug "txtdomain" "$txtdomain" _debug "aliasDomain" "$aliasDomain" + _debug "_currentRoot" "$_currentRoot" _debug "txt" "$txt" _debug "d_api" "$d_api" if [ "$d_api" = "$txt" ]; then @@ -3621,7 +3623,7 @@ _ns_purge_cf() { _cf_d="$1" _cf_d_type="$2" _debug "Cloudflare purge $_cf_d_type record for domain $_cf_d" - _cf_purl="https://1.1.1.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" + _cf_purl="https://1.0.0.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" response="$(_post "" "$_cf_purl")" _debug2 response "$response" } @@ -6787,7 +6789,7 @@ _process() { _debug "Using server: $_server" fi fi - + _debug "Running cmd: ${_CMD}" case "${_CMD}" in install) install "$_nocron" "$_confighome" "$_noprofile" ;; uninstall) uninstall "$_nocron" ;; diff --git a/deploy/docker.sh b/deploy/docker.sh index 4e550991..05333b3f 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -126,6 +126,7 @@ docker_deploy() { fi if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then + _info "Reloading: $DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then return 1 fi @@ -223,7 +224,8 @@ _docker_cp() { _debug2 "_frompath" "$_frompath" _toname="$(basename "$_to")" _debug2 "_toname" "$_toname" - if ! tar --transform="s,$_frompath,$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then + _debug2 "_from" "$_from" + if ! tar --transform="s,$(printf "%s" "$_frompath" | tr '*' .),$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then _err "copy error" return 1 fi diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index cd93189f..62e40caf 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -5,6 +5,9 @@ # #CF_Email="xxxx@sss.com" +#CF_Token="xxxx" +#CF_Account_ID="xxxx" + CF_Api="https://api.cloudflare.com/client/v4" ######## Public functions ##################### @@ -14,25 +17,32 @@ dns_cf_add() { fulldomain=$1 txtvalue=$2 + CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" + CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then - CF_Key="" - CF_Email="" - _err "You didn't specify a Cloudflare api key and email yet." - _err "You can get yours from here https://dash.cloudflare.com/profile." - return 1 - fi - if ! _contains "$CF_Email" "@"; then - _err "It seems that the CF_Email=$CF_Email is not a valid email address." - _err "Please check and retry." - return 1 - fi + if [ "$CF_Token" ]; then + _saveaccountconf_mutable CF_Token "$CF_Token" + _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" + else + if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then + CF_Key="" + CF_Email="" + _err "You didn't specify a Cloudflare api key and email yet." + _err "You can get yours from here https://dash.cloudflare.com/profile." + return 1 + fi - #save the api key and email to the account conf file. - _saveaccountconf_mutable CF_Key "$CF_Key" - _saveaccountconf_mutable CF_Email "$CF_Email" + if ! _contains "$CF_Email" "@"; then + _err "It seems that the CF_Email=$CF_Email is not a valid email address." + _err "Please check and retry." + return 1 + fi + #save the api key and email to the account conf file. + _saveaccountconf_mutable CF_Key "$CF_Key" + _saveaccountconf_mutable CF_Email "$CF_Email" + fi _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -71,19 +81,6 @@ dns_cf_add() { fi _err "Add txt record error." return 1 - # else - # _info "Updating record" - # record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) - # _debug "record_id" "$record_id" - # - # _cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}" - # if [ "$?" = "0" ]; then - # _info "Updated, OK" - # return 0 - # fi - # _err "Update error" - # return 1 - # fi } @@ -92,15 +89,10 @@ dns_cf_rm() { fulldomain=$1 txtvalue=$2 + CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" + CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then - CF_Key="" - CF_Email="" - _err "You didn't specify a Cloudflare api key and email yet." - _err "You can get yours from here https://dash.cloudflare.com/profile." - return 1 - fi _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -157,8 +149,14 @@ _get_root() { return 1 fi - if ! _cf_rest GET "zones?name=$h"; then - return 1 + if [ "$CF_Account_ID" ]; then + if ! _cf_rest GET "zones?name=$h&account.id=$CF_Account_ID"; then + return 1 + fi + else + if ! _cf_rest GET "zones?name=$h"; then + return 1 + fi fi if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then @@ -182,12 +180,17 @@ _cf_rest() { data="$3" _debug "$ep" - email_trimmed=$(echo $CF_Email | tr -d '"') - key_trimmed=$(echo $CF_Key | tr -d '"') + email_trimmed=$(echo "$CF_Email" | tr -d '"') + key_trimmed=$(echo "$CF_Key" | tr -d '"') + token_trimmed=$(echo "$CF_Token" | tr -d '"') - export _H1="X-Auth-Email: $email_trimmed" - export _H2="X-Auth-Key: $key_trimmed" - export _H3="Content-Type: application/json" + export _H1="Content-Type: application/json" + if [ "$token_trimmed" ]; then + export _H2="Authorization: Bearer $token_trimmed" + else + export _H2="X-Auth-Email: $email_trimmed" + export _H3="X-Auth-Key: $key_trimmed" + fi if [ "$m" != "GET" ]; then _debug data "$data" diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh new file mode 100755 index 00000000..f1503118 --- /dev/null +++ b/dnsapi/dns_hexonet.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env sh + +# +# Hexonet_Login="username!roleId" +# +# Hexonet_Password="rolePassword" + +Hexonet_Api="https://coreapi.1api.net/api/call.cgi" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_hexonet_add() { + fulldomain=$1 + txtvalue=$2 + + Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}" + Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" + if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Login="" + Hexonet_Password="" + _err "You must export variables: Hexonet_Login and Hexonet_Password" + return 1 + fi + + if ! _contains "$Hexonet_Login" "!"; then + _err "It seems that the Hexonet_Login=$Hexonet_Login is not a restrivteed user." + _err "Please check and retry." + return 1 + fi + + #save the username and password to the account conf file. + _saveaccountconf_mutable Hexonet_Login "$Hexonet_Login" + _saveaccountconf_mutable Hexonet_Password "$Hexonet_Password" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT" + + if ! _contains "$response" "CODE=200"; then + _err "Error" + return 1 + fi + + _info "Adding record" + if _hexonet_rest "command=UpdateDNSZone&dnszone=${_domain}.&addrr0=${_sub_domain}%20IN%20TXT%20${txtvalue}"; then + if _contains "$response" "CODE=200"; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_hexonet_rm() { + fulldomain=$1 + txtvalue=$2 + + Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}" + Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" + if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Login="" + Hexonet_Password="" + _err "You must export variables: Hexonet_Login and Hexonet_Password" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT&RR=${txtvalue}" + + if ! _contains "$response" "CODE=200"; then + _err "Error" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "PROPERTY[TOTAL][0]=" | cut -d = -f 2) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + if ! _hexonet_rest "&command=UpdateDNSZone&dnszone=${_domain}.&delrr0='${_sub_domain}%20IN%20TXT%20\"${txtvalue}\""; then + _err "Delete record error." + return 1 + fi + _contains "$response" "CODE=200" + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}."; then + return 1 + fi + + if _contains "$response" "CODE=200"; 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 +} + +_hexonet_rest() { + query_params="$1" + _debug "$query_params" + + response="$(_get "${Hexonet_Api}?s_login=${Hexonet_Login}&s_pw=${Hexonet_Password}&${query_params}")" + + if [ "$?" != "0" ]; then + _err "error $query_params" + return 1 + fi + _debug2 response "$response" + return 0 +} diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 6553deb6..a82e12d7 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -164,7 +164,7 @@ _namecheap_set_publicip() { _debug sourceip "$NAMECHEAP_SOURCEIP" ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') - addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*') + addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https):\/\/.*') _debug2 ip "$ip" _debug2 addr "$addr" diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index dc1a4fda..ed6d0e08 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -59,9 +59,14 @@ dns_namesilo_rm() { if _namesilo_rest GET "dnsListRecords?version=1&type=xml&key=$Namesilo_Key&domain=$_domain"; then retcode=$(printf "%s\n" "$response" | _egrep_o "300") if [ "$retcode" ]; then - _record_id=$(printf "%s\n" "$response" | _egrep_o "([^<]*)TXT$fulldomain" | _egrep_o "([^<]*)" | sed -r "s/([^<]*)<\/record_id>/\1/" | tail -n 1) - _debug record_id "$_record_id" - _info "Successfully retrieved the record id for ACME challenge." + _record_id=$(echo "$response" | _egrep_o "([^<]*)TXT$fulldomain" | _egrep_o "([^<]*)" | sed -r "s/([^<]*)<\/record_id>/\1/" | tail -n 1) + _debug _record_id "$_record_id" + if [ "$_record_id" ]; then + _info "Successfully retrieved the record id for ACME challenge." + else + _info "Empty record id, it seems no such record." + return 0 + fi else _err "Unable to retrieve the record id." return 1 diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh new file mode 100644 index 00000000..f15e7c49 --- /dev/null +++ b/dnsapi/dns_vultr.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env sh + +# +#VULTR_API_KEY=000011112222333344445555666677778888 + +VULTR_Api="https://api.vultr.com/v1" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_vultr_add() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}" + if test -z "$VULTR_API_KEY"; then + VULTR_API_KEY='' + _err 'VULTR_API_KEY was not exported' + return 1 + fi + + _saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug 'Getting txt records' + _vultr_rest GET "dns/records?domain=$_domain" + + if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then + _err 'Error' + return 1 + fi + + if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + return 0 +} + +#fulldomain txtvalue +dns_vultr_rm() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}" + if test -z "$VULTR_API_KEY"; then + VULTR_API_KEY="" + _err 'VULTR_API_KEY was not exported' + return 1 + fi + + _saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug 'Getting txt records' + _vultr_rest GET "dns/records?domain=$_domain" + + if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then + _err 'Error' + return 1 + fi + + _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)" + _debug _record_id "$_record_id" + if [ "$_record_id" ]; then + _info "Successfully retrieved the record id for ACME challenge." + else + _info "Empty record id, it seems no such record." + return 0 + fi + + if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + 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=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + return 1 + fi + + if ! _vultr_rest GET "dns/list"; then + return 1 + fi + + if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then + if _contains "$response" "\"domain\":\"$_domain\""; then + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" + _domain=$_domain + return 0 + else + _err 'Invalid domain' + return 1 + fi + else + _err "$response" + return 1 + fi + i=$(_math "$i" + 1) + done + + return 1 +} + +_vultr_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"') + + export _H1="Api-Key: $api_key_trimmed" + export _H2='Content-Type: application/x-www-form-urlencoded' + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$VULTR_Api/$ep" "" "$m")" + else + response="$(_get "$VULTR_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "Error $ep" + return 1 + fi + + _debug2 response "$response" + return 0 +} diff --git a/notify/pushover.sh b/notify/pushover.sh new file mode 100644 index 00000000..a07cbd3d --- /dev/null +++ b/notify/pushover.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env sh + +#Support for pushover.net's api. Push notification platform for multiple platforms +#PUSHOVER_TOKEN="" Required, pushover application token +#PUSHOVER_USER="" Required, pushover userkey +#PUSHOVER_DEVICE="" Optional, Specific device or devices by hostnames, joining multiples with a comma (such as device=iphone,nexus5) +#PUSHOVER_PRIORITY="" Optional, Lowest Priority (-2), Low Priority (-1), Normal Priority (0), High Priority (1) + +PUSHOVER_URI="https://api.pushover.net/1/messages.json" + +pushover_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + PUSHOVER_TOKEN="${PUSHOVER_TOKEN:-$(_readaccountconf_mutable PUSHOVER_TOKEN)}" + if [ -z "$PUSHOVER_TOKEN" ]; then + PUSHOVER_TOKEN="" + _err "You didn't specify a PushOver application token yet." + return 1 + fi + _saveaccountconf_mutable PUSHOVER_TOKEN "$PUSHOVER_TOKEN" + + PUSHOVER_USER="${PUSHOVER_USER:-$(_readaccountconf_mutable PUSHOVER_USER)}" + if [ -z "$PUSHOVER_USER" ]; then + PUSHOVER_USER="" + _err "You didn't specify a PushOver UserKey yet." + return 1 + fi + _saveaccountconf_mutable PUSHOVER_USER "$PUSHOVER_USER" + + PUSHOVER_DEVICE="${PUSHOVER_DEVICE:-$(_readaccountconf_mutable PUSHOVER_DEVICE)}" + if [ "$PUSHOVER_DEVICE" ]; then + _saveaccountconf_mutable PUSHOVER_DEVICE "$PUSHOVER_DEVICE" + fi + + PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-$(_readaccountconf_mutable PUSHOVER_PRIORITY)}" + if [ "$PUSHOVER_PRIORITY" ]; then + _saveaccountconf_mutable PUSHOVER_PRIORITY "$PUSHOVER_PRIORITY" + fi + + PUSHOVER_SOUND="${PUSHOVER_SOUND:-$(_readaccountconf_mutable PUSHOVER_SOUND)}" + if [ "$PUSHOVER_SOUND" ]; then + _saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND" + fi + + export _H1="Content-Type: application/json" + _content="$(printf "*%s*\n" "$_content" | _json_encode)" + _subject="$(printf "*%s*\n" "$_subject" | _json_encode)" + _data="{\"token\": \"$PUSHOVER_TOKEN\",\"user\": \"$PUSHOVER_USER\",\"title\": \"$_subject\",\"message\": \"$_content\",\"sound\": \"$PUSHOVER_SOUND\", \"device\": \"$PUSHOVER_DEVICE\", \"priority\": \"$PUSHOVER_PRIORITY\"}" + + response="" #just make shellcheck happy + if _post "$_data" "$PUSHOVER_URI"; then + if _contains "$response" "{\"status\":1"; then + _info "PUSHOVER send success." + return 0 + fi + fi + _err "PUSHOVER send error." + _err "$response" + return 1 +} From b9b2cd278b098b7e43143e58809878f1e8fbcf2b Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 29 Jul 2019 21:12:19 +0800 Subject: [PATCH 0406/2234] fix https://github.com/Neilpang/acme.sh/pull/2275 --- acme.sh | 4 ++-- dnsapi/dns_dp.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 891d2e1e..66d9b7a8 100755 --- a/acme.sh +++ b/acme.sh @@ -3623,7 +3623,7 @@ _ns_purge_cf() { _cf_d="$1" _cf_d_type="$2" _debug "Cloudflare purge $_cf_d_type record for domain $_cf_d" - _cf_purl="https://1.0.0.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" + _cf_purl="https://cloudflare-dns.com/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" response="$(_post "" "$_cf_purl")" _debug2 response "$response" } @@ -3682,11 +3682,11 @@ _check_dns_entries() { fi _left=1 _info "Not valid yet, let's wait 10 seconds and check next one." - _sleep 10 __purge_txt "$txtdomain" if [ "$txtdomain" != "$aliasDomain" ]; then __purge_txt "$aliasDomain" fi + _sleep 10 done if [ "$_left" ]; then _info "Let's wait 10 seconds and check again". diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 6bbf149e..480c1f9a 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -63,7 +63,7 @@ dns_dp_rm() { return 0 fi - record_id=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2) + record_id=$(echo "$response" | tr "{" "\n" | grep -- "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2) _debug record_id "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id." From 75191e71870abdb35365d057ffd746e8cd8d5b4f Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 31 Jul 2019 23:22:07 +0800 Subject: [PATCH 0407/2234] fix https://github.com/Neilpang/acme.sh/issues/2417 --- acme.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 66d9b7a8..8bff2e84 100755 --- a/acme.sh +++ b/acme.sh @@ -5932,8 +5932,11 @@ _send_notify() { _send_err=0 for _n_hook in $(echo "$_nhooks" | tr ',' " "); do _n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")" - _info "Found $_n_hook_file" - + _info "Found $_n_hook_file for $_n_hook" + if [ -z "$_n_hook_file" ]; then + _err "Can not find the hook file for $_n_hook" + continue + fi if ! ( if ! . "$_n_hook_file"; then _err "Load file $_n_hook_file error. Please check your api file and try again." From d42cf6daebfd134dca7af41b47aac34866b6a771 Mon Sep 17 00:00:00 2001 From: James Qian Date: Mon, 5 Aug 2019 21:35:03 +0800 Subject: [PATCH 0408/2234] dnsapi: fix typo in dns_desec.sh (#2427) Signed-off-by: James Qian --- dnsapi/dns_desec.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index 6488b7fb..61d080bd 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -25,8 +25,8 @@ dns_desec_add() { if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then DEDYN_TOKEN="" DEDYN_NAME="" - _err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet." - _err "Please create you key and try again." + _err "You did not specify DEDYN_TOKEN and DEDYN_NAME yet." + _err "Please create your key and try again." _err "e.g." _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" _err "export DEDYN_NAME=foobar.dedyn.io" @@ -92,8 +92,8 @@ dns_desec_rm() { if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then DEDYN_TOKEN="" DEDYN_NAME="" - _err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet." - _err "Please create you key and try again." + _err "You did not specify DEDYN_TOKEN and DEDYN_NAME yet." + _err "Please create your key and try again." _err "e.g." _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" _err "export DEDYN_NAME=foobar.dedyn.io" From d74dfb1f5c333c911d150f7a7485ff99b8c984b4 Mon Sep 17 00:00:00 2001 From: lcdtyph Date: Mon, 5 Aug 2019 21:38:32 +0800 Subject: [PATCH 0409/2234] IFTTT Webhooks Notification (#2416) * IFTTT webhooks Notification * use sh instead of bash * don't save value that is not set --- notify/ifttt.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 notify/ifttt.sh diff --git a/notify/ifttt.sh b/notify/ifttt.sh new file mode 100644 index 00000000..8a14f5f5 --- /dev/null +++ b/notify/ifttt.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env sh + +#Support ifttt.com webhooks api + +#IFTTT_API_KEY="xxxx" +#IFTTT_EVENT_NAME="yyyy" + +#IFTTT_SUBJECT_KEY="value1|value2|value3" #optional, use "value1" as default +#IFTTT_CONTENT_KEY="value1|value2|value3" #optional, use "value2" as default + +_IFTTT_AVAIL_MSG_KEYS="value1,value2,value3" + +# subject content statusCode +ifttt_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + IFTTT_API_KEY="${IFTTT_API_KEY:-$(_readaccountconf_mutable IFTTT_API_KEY)}" + if [ -z "$IFTTT_API_KEY" ]; then + IFTTT_API_KEY="" + _err "You didn't specify a ifttt webhooks api key IFTTT_API_KEY yet." + _err "You can get yours from https://ifttt.com" + return 1 + fi + _saveaccountconf_mutable IFTTT_API_KEY "$IFTTT_API_KEY" + + IFTTT_EVENT_NAME="${IFTTT_EVENT_NAME:-$(_readaccountconf_mutable IFTTT_EVENT_NAME)}" + if [ -z "$IFTTT_EVENT_NAME" ]; then + IFTTT_EVENT_NAME="" + _err "You didn't specify a ifttt webhooks event name IFTTT_EVENT_NAME yet." + return 1 + fi + _saveaccountconf_mutable IFTTT_EVENT_NAME "$IFTTT_EVENT_NAME" + + IFTTT_SUBJECT_KEY="${IFTTT_SUBJECT_KEY:-$(_readaccountconf_mutable IFTTT_SUBJECT_KEY)}" + if [ -z "$IFTTT_SUBJECT_KEY" ]; then + IFTTT_SUBJECT_KEY="value1" + _info "The IFTTT_SUBJECT_KEY is not set, so use the default value1 as key." + elif ! _hasfield "$_IFTTT_AVAIL_MSG_KEYS" "$IFTTT_SUBJECT_KEY"; then + _err "The IFTTT_SUBJECT_KEY \"$IFTTT_SUBJECT_KEY\" is not available, should be one of $_IFTTT_AVAIL_MSG_KEYS" + IFTTT_SUBJECT_KEY="" + return 1 + else + _saveaccountconf_mutable IFTTT_SUBJECT_KEY "$IFTTT_SUBJECT_KEY" + fi + + IFTTT_CONTENT_KEY="${IFTTT_CONTENT_KEY:-$(_readaccountconf_mutable IFTTT_CONTENT_KEY)}" + if [ -z "$IFTTT_CONTENT_KEY" ]; then + IFTTT_CONTENT_KEY="value2" + _info "The IFTTT_CONTENT_KEY is not set, so use the default value2 as key." + elif ! _hasfield "$_IFTTT_AVAIL_MSG_KEYS" "$IFTTT_CONTENT_KEY"; then + _err "The IFTTT_CONTENT_KEY \"$IFTTT_CONTENT_KEY\" is not available, should be one of $_IFTTT_AVAIL_MSG_KEYS" + IFTTT_CONTENT_KEY="" + return 1 + else + _saveaccountconf_mutable IFTTT_CONTENT_KEY "$IFTTT_CONTENT_KEY" + fi + + if [ "$IFTTT_SUBJECT_KEY" = "$IFTTT_CONTENT_KEY" ]; then + IFTTT_SUBJECT_KEY="" + IFTTT_CONTENT_KEY="" + _err "The IFTTT_SUBJECT_KEY must not be same as IFTTT_CONTENT_KEY." + return 1 + fi + + IFTTT_API_URL="https://maker.ifttt.com/trigger/$IFTTT_EVENT_NAME/with/key/$IFTTT_API_KEY" + + _content=$(echo "$_content" | _json_encode) + _subject=$(echo "$_subject" | _json_encode) + _data="{\"$IFTTT_SUBJECT_KEY\": \"$_subject\", \"$IFTTT_CONTENT_KEY\": \"$_content\"}" + + response="" #just make shellcheck happy + if _post "$_data" "$IFTTT_API_URL" "" "POST" "application/json"; then + if _contains "$response" "Congratulations"; then + _info "IFTTT webhooks event fired success." + return 0 + fi + fi + _err "IFTTT webhooks event fired error." + _err "$response" + return 1 +} From 143eac092ce8b8fe7c068809449ce7a5b71f3ea2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 5 Aug 2019 22:03:56 +0800 Subject: [PATCH 0410/2234] fix notify message --- acme.sh | 5 +++-- notify/ifttt.sh | 12 ++++++------ notify/pushover.sh | 12 ++++++------ notify/sendgrid.sh | 12 ++++++------ 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/acme.sh b/acme.sh index 8bff2e84..8452d588 100755 --- a/acme.sh +++ b/acme.sh @@ -5932,7 +5932,8 @@ _send_notify() { _send_err=0 for _n_hook in $(echo "$_nhooks" | tr ',' " "); do _n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")" - _info "Found $_n_hook_file for $_n_hook" + _info "Sending via: $_n_hook" + _debug "Found $_n_hook_file for $_n_hook" if [ -z "$_n_hook_file" ]; then _err "Can not find the hook file for $_n_hook" continue @@ -5971,7 +5972,7 @@ _set_notify_hook() { _nhooks="$1" _test_subject="Hello, this is notification from $PROJECT_NAME" - _test_content="If you receive this email, your notification works." + _test_content="If you receive this message, your notification works." _send_notify "$_test_subject" "$_test_content" "$_nhooks" 0 diff --git a/notify/ifttt.sh b/notify/ifttt.sh index 8a14f5f5..7b829639 100644 --- a/notify/ifttt.sh +++ b/notify/ifttt.sh @@ -73,13 +73,13 @@ ifttt_send() { _subject=$(echo "$_subject" | _json_encode) _data="{\"$IFTTT_SUBJECT_KEY\": \"$_subject\", \"$IFTTT_CONTENT_KEY\": \"$_content\"}" - response="" #just make shellcheck happy - if _post "$_data" "$IFTTT_API_URL" "" "POST" "application/json"; then - if _contains "$response" "Congratulations"; then - _info "IFTTT webhooks event fired success." - return 0 - fi + response="$(_post "$_data" "$IFTTT_API_URL" "" "POST" "application/json")" + + if [ "$?" = "0" ] && _contains "$response" "Congratulations"; then + _info "IFTTT webhooks event fired success." + return 0 fi + _err "IFTTT webhooks event fired error." _err "$response" return 1 diff --git a/notify/pushover.sh b/notify/pushover.sh index a07cbd3d..0f99739a 100644 --- a/notify/pushover.sh +++ b/notify/pushover.sh @@ -50,13 +50,13 @@ pushover_send() { _subject="$(printf "*%s*\n" "$_subject" | _json_encode)" _data="{\"token\": \"$PUSHOVER_TOKEN\",\"user\": \"$PUSHOVER_USER\",\"title\": \"$_subject\",\"message\": \"$_content\",\"sound\": \"$PUSHOVER_SOUND\", \"device\": \"$PUSHOVER_DEVICE\", \"priority\": \"$PUSHOVER_PRIORITY\"}" - response="" #just make shellcheck happy - if _post "$_data" "$PUSHOVER_URI"; then - if _contains "$response" "{\"status\":1"; then - _info "PUSHOVER send success." - return 0 - fi + response="$(_post "$_data" "$PUSHOVER_URI")" + + if [ "$?" = "0" ] && _contains "$response" "{\"status\":1"; then + _info "PUSHOVER send success." + return 0 fi + _err "PUSHOVER send error." _err "$response" return 1 diff --git a/notify/sendgrid.sh b/notify/sendgrid.sh index 5c5bfdba..0d5ea3b3 100644 --- a/notify/sendgrid.sh +++ b/notify/sendgrid.sh @@ -42,13 +42,13 @@ sendgrid_send() { _content="$(echo "$_content" | _json_encode)" _data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}" - response="" #just make shellcheck happy - if _post "$_data" "https://api.sendgrid.com/v3/mail/send"; then - if [ -z "$response" ]; then - _info "sendgrid send sccess." - return 0 - fi + response="$(_post "$_data" "https://api.sendgrid.com/v3/mail/send")" + + if [ "$?" = "0" ] && [ -z "$response" ]; then + _info "sendgrid send sccess." + return 0 fi + _err "sendgrid send error." _err "$response" return 1 From 874bd093cb5076613f74aac84168952af0e27f9f Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Mon, 5 Aug 2019 22:35:40 +0800 Subject: [PATCH 0411/2234] fix https://github.com/Neilpang/acme.sh/issues/2409 (#2430) --- dnsapi/dns_he.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index df00c746..caa4d2c4 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -134,9 +134,9 @@ _find_zone() { _zone_ids=$(echo "$_matches" | _egrep_o "hosted_dns_zoneid=[0-9]*&" | cut -d = -f 2 | tr -d '&') _zone_names=$(echo "$_matches" | _egrep_o "name=.*onclick" | cut -d '"' -f 2) _debug2 "These are the zones on this HE account:" - _debug2 "$_zone_names" + _debug2 "_zone_names" "$_zone_names" _debug2 "And these are their respective IDs:" - _debug2 "$_zone_ids" + _debug2 "_zone_ids" "$_zone_ids" if [ -z "$_zone_names" ] || [ -z "$_zone_ids" ]; then _err "Can not get zone names." return 1 @@ -154,10 +154,14 @@ _find_zone() { _debug "Looking for zone \"${_attempted_zone}\"" - line_num="$(echo "$_zone_names" | grep -n "^$_attempted_zone" | cut -d : -f 1)" - + line_num="$(echo "$_zone_names" | grep -n "^$_attempted_zone\$" | _head_n 1 | cut -d : -f 1)" + _debug2 line_num "$line_num" if [ "$line_num" ]; then _zone_id=$(echo "$_zone_ids" | sed -n "${line_num}p") + if [ -z "$_zone_id" ]; then + _err "Can not find zone id." + return 1 + fi _debug "Found relevant zone \"$_attempted_zone\" with id \"$_zone_id\" - will be used for domain \"$_domain\"." return 0 fi From c7849a43e13fd98f2452613165561e547b2606df Mon Sep 17 00:00:00 2001 From: mleo2003 Date: Tue, 6 Aug 2019 06:41:12 -0700 Subject: [PATCH 0412/2234] Add variable exports for Successful Post Hook and Renew Hook calls (#2431) --- acme.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/acme.sh b/acme.sh index 8452d588..4742e611 100755 --- a/acme.sh +++ b/acme.sh @@ -3265,6 +3265,11 @@ _on_issue_success() { if [ "$_chk_post_hook" ]; then _info "Run post hook:'$_chk_post_hook'" if ! ( + export CERT_PATH + export CERT_KEY_PATH + export CA_CERT_PATH + export CERT_FULLCHAIN_PATH + export Le_Domain="$_main_domain" cd "$DOMAIN_PATH" && eval "$_chk_post_hook" ); then _err "Error when run post hook." @@ -3276,6 +3281,11 @@ _on_issue_success() { if [ "$IS_RENEW" ] && [ "$_chk_renew_hook" ]; then _info "Run renew hook:'$_chk_renew_hook'" if ! ( + export CERT_PATH + export CERT_KEY_PATH + export CA_CERT_PATH + export CERT_FULLCHAIN_PATH + export Le_Domain="$_main_domain" cd "$DOMAIN_PATH" && eval "$_chk_renew_hook" ); then _err "Error when run renew hook." From f82ff90f0670becb8b2c63e9eea591361a380ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B8=D0=BC=D1=83=D1=80=20=D0=AF=D1=85=D0=B8=D0=BD?= Date: Sun, 11 Aug 2019 06:41:57 +0300 Subject: [PATCH 0413/2234] fixed json parse regex for support api gcore_cdn (#2381) --- deploy/gcore_cdn.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index e0921bcb..bbda58ef 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -1,7 +1,6 @@ #!/usr/bin/env sh # Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). -# Uses command line curl for send requests and jq for parse responses. # Returns 0 when success. # # Written by temoffey @@ -117,7 +116,7 @@ gcore_cdn_deploy() { _debug _request "$_request" _response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") _debug _response "$_response" - _regex=".*\"sslData\":\([0-9]*\)}.*$" + _regex=".*\"sslData\":\([0-9]*\).*$" _debug _regex "$_regex" _sslDataNew=$(echo "$_response" | sed -n "s/$_regex/\1/p") _debug _sslDataNew "$_sslDataNew" From ee38cccad8f76b807206165324e7bf771aa981dc Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Sun, 11 Aug 2019 11:56:59 +0800 Subject: [PATCH 0414/2234] sync (#2436) * fix https://github.com/Neilpang/acme.sh/issues/2409 (#2430) * Add variable exports for Successful Post Hook and Renew Hook calls (#2431) * fixed json parse regex for support api gcore_cdn (#2381) --- acme.sh | 10 ++++++++++ deploy/gcore_cdn.sh | 3 +-- dnsapi/dns_he.sh | 12 ++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 8452d588..4742e611 100755 --- a/acme.sh +++ b/acme.sh @@ -3265,6 +3265,11 @@ _on_issue_success() { if [ "$_chk_post_hook" ]; then _info "Run post hook:'$_chk_post_hook'" if ! ( + export CERT_PATH + export CERT_KEY_PATH + export CA_CERT_PATH + export CERT_FULLCHAIN_PATH + export Le_Domain="$_main_domain" cd "$DOMAIN_PATH" && eval "$_chk_post_hook" ); then _err "Error when run post hook." @@ -3276,6 +3281,11 @@ _on_issue_success() { if [ "$IS_RENEW" ] && [ "$_chk_renew_hook" ]; then _info "Run renew hook:'$_chk_renew_hook'" if ! ( + export CERT_PATH + export CERT_KEY_PATH + export CA_CERT_PATH + export CERT_FULLCHAIN_PATH + export Le_Domain="$_main_domain" cd "$DOMAIN_PATH" && eval "$_chk_renew_hook" ); then _err "Error when run renew hook." diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index e0921bcb..bbda58ef 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -1,7 +1,6 @@ #!/usr/bin/env sh # Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). -# Uses command line curl for send requests and jq for parse responses. # Returns 0 when success. # # Written by temoffey @@ -117,7 +116,7 @@ gcore_cdn_deploy() { _debug _request "$_request" _response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") _debug _response "$_response" - _regex=".*\"sslData\":\([0-9]*\)}.*$" + _regex=".*\"sslData\":\([0-9]*\).*$" _debug _regex "$_regex" _sslDataNew=$(echo "$_response" | sed -n "s/$_regex/\1/p") _debug _sslDataNew "$_sslDataNew" diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index df00c746..caa4d2c4 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -134,9 +134,9 @@ _find_zone() { _zone_ids=$(echo "$_matches" | _egrep_o "hosted_dns_zoneid=[0-9]*&" | cut -d = -f 2 | tr -d '&') _zone_names=$(echo "$_matches" | _egrep_o "name=.*onclick" | cut -d '"' -f 2) _debug2 "These are the zones on this HE account:" - _debug2 "$_zone_names" + _debug2 "_zone_names" "$_zone_names" _debug2 "And these are their respective IDs:" - _debug2 "$_zone_ids" + _debug2 "_zone_ids" "$_zone_ids" if [ -z "$_zone_names" ] || [ -z "$_zone_ids" ]; then _err "Can not get zone names." return 1 @@ -154,10 +154,14 @@ _find_zone() { _debug "Looking for zone \"${_attempted_zone}\"" - line_num="$(echo "$_zone_names" | grep -n "^$_attempted_zone" | cut -d : -f 1)" - + line_num="$(echo "$_zone_names" | grep -n "^$_attempted_zone\$" | _head_n 1 | cut -d : -f 1)" + _debug2 line_num "$line_num" if [ "$line_num" ]; then _zone_id=$(echo "$_zone_ids" | sed -n "${line_num}p") + if [ -z "$_zone_id" ]; then + _err "Can not find zone id." + return 1 + fi _debug "Found relevant zone \"$_attempted_zone\" with id \"$_zone_id\" - will be used for domain \"$_domain\"." return 0 fi From 5bdfdfefbebd7ee4f95f7009947f56a25db07c4a Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 11 Aug 2019 14:07:36 +0800 Subject: [PATCH 0415/2234] start 2.8.3 Forbidden sudo --- acme.sh | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 4742e611..72bf0700 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.2 +VER=2.8.3 PROJECT_NAME="acme.sh" @@ -135,6 +135,8 @@ _DNS_MANUAL_WIKI="https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode" _NOTIFY_WIKI="https://github.com/Neilpang/acme.sh/wiki/notify" +_SUDO_WIKI="https://github.com/Neilpang/acme.sh/wiki/sudo" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -6233,6 +6235,23 @@ _processAccountConf() { } +_checkSudo() { + 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 + return 0 + fi + if [ "$SUDO_COMMAND" = "/bin/su" ]; then + #it's a normal user doing "sudo su" + #fine + return 0 + fi + #otherwise + return 1 + fi + return 0 +} + _process() { _CMD="" _domain="" @@ -6761,6 +6780,14 @@ _process() { done if [ "${_CMD}" != "install" ]; then + if [ "$__INTERACTIVE" ] && ! _checkSudo; then + if [ -z "$FORCE" ]; then + #Use "echo" here, instead of _info. it's too early + echo "It seems that you are using sudo, please read this link first:" + echo "$_SUDO_WIKI" + return 1 + fi + fi __initHome if [ "$_log" ]; then if [ -z "$_logfile" ]; then From a3361806ab49043fca46f81a0edc2357b7d3947c Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Sun, 11 Aug 2019 22:43:07 +0800 Subject: [PATCH 0416/2234] sync (#2437) * fix https://github.com/Neilpang/acme.sh/issues/2409 (#2430) * Add variable exports for Successful Post Hook and Renew Hook calls (#2431) * fixed json parse regex for support api gcore_cdn (#2381) * start 2.8.3 Forbidden sudo --- acme.sh | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 4742e611..72bf0700 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.2 +VER=2.8.3 PROJECT_NAME="acme.sh" @@ -135,6 +135,8 @@ _DNS_MANUAL_WIKI="https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode" _NOTIFY_WIKI="https://github.com/Neilpang/acme.sh/wiki/notify" +_SUDO_WIKI="https://github.com/Neilpang/acme.sh/wiki/sudo" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -6233,6 +6235,23 @@ _processAccountConf() { } +_checkSudo() { + 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 + return 0 + fi + if [ "$SUDO_COMMAND" = "/bin/su" ]; then + #it's a normal user doing "sudo su" + #fine + return 0 + fi + #otherwise + return 1 + fi + return 0 +} + _process() { _CMD="" _domain="" @@ -6761,6 +6780,14 @@ _process() { done if [ "${_CMD}" != "install" ]; then + if [ "$__INTERACTIVE" ] && ! _checkSudo; then + if [ -z "$FORCE" ]; then + #Use "echo" here, instead of _info. it's too early + echo "It seems that you are using sudo, please read this link first:" + echo "$_SUDO_WIKI" + return 1 + fi + fi __initHome if [ "$_log" ]; then if [ -z "$_logfile" ]; then From 9b173dcd7149dd9fa50d621bf21fe4a874616240 Mon Sep 17 00:00:00 2001 From: Sky Chen Date: Thu, 15 Aug 2019 14:23:12 +0800 Subject: [PATCH 0417/2234] fixed #2441: dns_namesilo.sh _get_root (#2442) fixed #2441: dns_namesilo.sh _get_root (#2442) --- dnsapi/dns_namesilo.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index ed6d0e08..0b87b7f7 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -110,7 +110,7 @@ _get_root() { return 1 fi - if _contains "$response" "$host"; then + if _contains "$response" "$host"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$host" return 0 From 0b2b8b960b07232edd92fed0124a35cbfd969a87 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Fri, 16 Aug 2019 22:56:22 -0400 Subject: [PATCH 0418/2234] Replace grep -o with sed --- dnsapi/dns_freedns.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 8a48cf77..ee013662 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -305,7 +305,7 @@ _freedns_domain_id() { domain_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ | grep "$search_domain\|$search_domain(.*)" \ - | grep -o "edit\.php?edit_domain_id=[0-9a-zA-Z]*" \ + | sed -n 's/.*\(edit\.php?edit_domain_id=[0-9a-zA-Z]*\).*/\1/p' \ | cut -d = -f 2)" # The above beauty extracts domain ID from the html page... # strip out all blank space and new lines. Then insert newlines @@ -352,7 +352,7 @@ _freedns_data_id() { data_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ | grep "$record_type" \ | grep "$search_domain" \ - | grep -o "edit\.php?data_id=[0-9a-zA-Z]*" \ + | sed -n 's/.*\(edit\.php?data_id=[0-9a-zA-Z]*\).*/\1/p' \ | cut -d = -f 2)" # The above beauty extracts data ID from the html page... # strip out all blank space and new lines. Then insert newlines From e0deca33d00f6e8dfd9473b1d2bbf83132fb2e72 Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Mon, 19 Aug 2019 14:27:23 +0200 Subject: [PATCH 0419/2234] Added Leaseweb API for dns-01 verification --- dnsapi/dns_leaseweb.sh | 130 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 dnsapi/dns_leaseweb.sh diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh new file mode 100644 index 00000000..3edf55f0 --- /dev/null +++ b/dnsapi/dns_leaseweb.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env sh + +#Author: Rolph Haspers +#Utilize leaseweb.com API to finish dns-01 verifications. +#Requires a Leaseweb API Key (export LSW_Key="Your Key") +######## Public functions ##################### + +LSW_API="https://api.leaseweb.com/hosting/v2/domains/" + +#Usage: dns_leaseweb_add _acme-challenge.www.domain.com +dns_leaseweb_add() { + fulldomain=$1 + txtvalue=$2 + + LSW_Key="${LSW_Key:-$(_readaccountconf_mutable LSW_Key)}" + if [ -z "$LSW_Key" ]; then + LSW_Key="" + _err "You don't specify Leaseweb api key yet." + _err "Please create your key and try again." + return 1 + fi + + #save the api key to the account conf file. + _saveaccountconf_mutable LSW_Key "$LSW_Key" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _root_domain "$_domain" + _debug _domain "$fulldomain" + + if _lsw_api "POST" "$_domain" "$fulldomain" "$txtvalue"; then + if [ "$_code" = "201" ]; then + _info "Added, OK" + return 0 + else + _err "Add txt record error, invalid code. Code: $_code" + return 1 + fi + fi + _err "Add txt record error." + + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_leaseweb_rm() { + fulldomain=$1 + txtvalue=$2 + + LSW_Key="${LSW_Key:-$(_readaccountconf_mutable LSW_Key)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _root_domain "$_domain" + _debug _domain "$fulldomain" + + if _lsw_api "DELETE" "$_domain" "$fulldomain" "$txtvalue"; then + if [ "$_code" = "204" ]; then + _info "Deleted, OK" + return 0 + else + _err "Delete txt record error." + return 1 + fi + fi + _err "Delete txt record error." + + return 1 +} + + +#################### Private functions below ################################## +# _acme-challenge.www.domain.com +# returns +# _domain=domain.com +_get_root() { + domain=$1 + i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)" + i=$(_math "$i" - 1) + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + if [ -z "$h" ]; then + return 1 + fi + _domain="$h" + return 0 + done + _debug "$domain not found" + return 1 +} + +_lsw_api() { + cmd=$1 + domain=$2 + fulldomain=$3 + txtvalue=$4 + + # Construct the HTTP Authorization header + export _H2="Content-Type: application/json" + export _H1="X-Lsw-Auth: ${LSW_Key}" + + if [ "$cmd" == "POST" ]; then + data="{\"name\": \"$fulldomain.\",\"type\": \"TXT\",\"content\": [\"$txtvalue\"],\"ttl\": 60}" + response="$(_post "$data" "$LSW_API/$domain/resourceRecordSets" "$data" "POST")" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + _debug "http response code $_code" + _debug response "$response" + return 0 + fi + + if [ "$cmd" == "DELETE" ]; then + response="$(_post "" "$LSW_API/$domain/resourceRecordSets/$fulldomain/TXT" "" "DELETE")" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + _debug "http response code $_code" + _debug response "$response" + return 0 + fi + + return 1 +} \ No newline at end of file From 54b38086e5abc37c48dcb55ffd2f3800098dd126 Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Mon, 19 Aug 2019 15:39:19 +0200 Subject: [PATCH 0420/2234] Fix style issues --- dnsapi/dns_leaseweb.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 3edf55f0..61609919 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -32,7 +32,7 @@ dns_leaseweb_add() { _debug _root_domain "$_domain" _debug _domain "$fulldomain" - if _lsw_api "POST" "$_domain" "$fulldomain" "$txtvalue"; then + if _lsw_api "POST" "$_domain" "$fulldomain" "$txtvalue"; then if [ "$_code" = "201" ]; then _info "Added, OK" return 0 @@ -63,7 +63,7 @@ dns_leaseweb_rm() { _debug _root_domain "$_domain" _debug _domain "$fulldomain" - if _lsw_api "DELETE" "$_domain" "$fulldomain" "$txtvalue"; then + if _lsw_api "DELETE" "$_domain" "$fulldomain" "$txtvalue"; then if [ "$_code" = "204" ]; then _info "Deleted, OK" return 0 @@ -109,16 +109,16 @@ _lsw_api() { export _H2="Content-Type: application/json" export _H1="X-Lsw-Auth: ${LSW_Key}" - if [ "$cmd" == "POST" ]; then + if [ "$cmd" = "POST" ]; then data="{\"name\": \"$fulldomain.\",\"type\": \"TXT\",\"content\": [\"$txtvalue\"],\"ttl\": 60}" - response="$(_post "$data" "$LSW_API/$domain/resourceRecordSets" "$data" "POST")" + response="$(_post "$data" "$LSW_API/$domain/resourceRecordSets" "$data" "POST")" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" - _debug "http response code $_code" - _debug response "$response" + _debug "http response code $_code" + _debug response "$response" return 0 fi - if [ "$cmd" == "DELETE" ]; then + if [ "$cmd" = "DELETE" ]; then response="$(_post "" "$LSW_API/$domain/resourceRecordSets/$fulldomain/TXT" "" "DELETE")" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _debug "http response code $_code" @@ -127,4 +127,4 @@ _lsw_api() { fi return 1 -} \ No newline at end of file +} From 400c31d03162a596fcbb22330e38df26b960eac0 Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Mon, 19 Aug 2019 16:01:51 +0200 Subject: [PATCH 0421/2234] Fixed another styling issue (trailing spaces) --- dnsapi/dns_leaseweb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 61609919..a792290b 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -111,7 +111,7 @@ _lsw_api() { if [ "$cmd" = "POST" ]; then data="{\"name\": \"$fulldomain.\",\"type\": \"TXT\",\"content\": [\"$txtvalue\"],\"ttl\": 60}" - response="$(_post "$data" "$LSW_API/$domain/resourceRecordSets" "$data" "POST")" + response="$(_post "$data" "$LSW_API/$domain/resourceRecordSets" "$data" "POST")" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _debug "http response code $_code" _debug response "$response" From 0ac37981cbd384ddfa7ccb890ccf4facb6c396ec Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Mon, 19 Aug 2019 16:04:16 +0200 Subject: [PATCH 0422/2234] Styling, newline removed --- dnsapi/dns_leaseweb.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index a792290b..17038f46 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -77,7 +77,6 @@ dns_leaseweb_rm() { return 1 } - #################### Private functions below ################################## # _acme-challenge.www.domain.com # returns From 4a81205e04f22f0de645d117e243794ba6ca403a Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Mon, 19 Aug 2019 16:22:48 +0200 Subject: [PATCH 0423/2234] Styling, trailing space --- dnsapi/dns_leaseweb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 17038f46..c9df4dc6 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -59,7 +59,7 @@ dns_leaseweb_rm() { _err "invalid domain" return 1 fi - + _debug _root_domain "$_domain" _debug _domain "$fulldomain" From f0d6d46766c8484e32010b2dc624130650900a3c Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Mon, 19 Aug 2019 17:27:19 +0200 Subject: [PATCH 0424/2234] Added link to API docs --- dnsapi/dns_leaseweb.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index c9df4dc6..976ad5ac 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -3,6 +3,7 @@ #Author: Rolph Haspers #Utilize leaseweb.com API to finish dns-01 verifications. #Requires a Leaseweb API Key (export LSW_Key="Your Key") +#See http://developer.leaseweb.com for more information. ######## Public functions ##################### LSW_API="https://api.leaseweb.com/hosting/v2/domains/" From 0ca46774ac207517724eb48338c04a4dbde0728a Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Mon, 2 Sep 2019 10:36:10 +0800 Subject: [PATCH 0425/2234] Create FUNDING.yml --- .github/FUNDING.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..24be2c47 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +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 +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 +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] From 1081d98bf9fac753a504a78af868eca444c73be1 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 5 Sep 2019 22:05:54 +0800 Subject: [PATCH 0426/2234] support to specify the nginx or site conf for nginx mode. https://github.com/Neilpang/acme.sh/issues/2469 --- acme.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/acme.sh b/acme.sh index 72bf0700..3ce377e8 100755 --- a/acme.sh +++ b/acme.sh @@ -2799,6 +2799,11 @@ _setNginx() { _debug NGINX_CONF "$NGINX_CONF" NGINX_CONF="$(echo "$NGINX_CONF" | cut -d = -f 2)" _debug NGINX_CONF "$NGINX_CONF" + if [ -z "$NGINX_CONF" ]; then + _err "Can not find nginx conf." + NGINX_CONF="" + return 1 + fi if [ ! -f "$NGINX_CONF" ]; then _err "'$NGINX_CONF' doesn't exist." NGINX_CONF="" @@ -6503,6 +6508,10 @@ _process() { ;; --nginx) wvalue="$NGINX" + if [ "$2" ] && ! _startswith "$2" "-"; then + wvalue="$NGINX$2" + shift + fi if [ -z "$_webroot" ]; then _webroot="$wvalue" else From 6b817d4563494e64d40d403c90746c869a3db73a Mon Sep 17 00:00:00 2001 From: Phil Porada Date: Thu, 5 Sep 2019 10:15:28 -0400 Subject: [PATCH 0427/2234] Set TXT record TTL to minimum possible value (#2465) --- dnsapi/dns_linode_v4.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index c9a83c77..ee7ee892 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -31,7 +31,8 @@ dns_linode_v4_add() { _payload="{ \"type\": \"TXT\", \"name\": \"$_sub_domain\", - \"target\": \"$txtvalue\" + \"target\": \"$txtvalue\", + \"ttl_sec\": 300 }" if _rest POST "/$_domain_id/records" "$_payload" && [ -n "$response" ]; then From 80d63dbb7cef07b14ec05d6d017689c19aec40a2 Mon Sep 17 00:00:00 2001 From: Kent Varmedal Date: Thu, 5 Sep 2019 16:26:28 +0200 Subject: [PATCH 0428/2234] Add support for Domeneshop DNS API (#2458) * Add support for Domeneshop DNS API * Fix double quotes after build fail * Fixing formating errors --- dnsapi/dns_domeneshop.sh | 155 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 dnsapi/dns_domeneshop.sh diff --git a/dnsapi/dns_domeneshop.sh b/dnsapi/dns_domeneshop.sh new file mode 100644 index 00000000..9a3791f4 --- /dev/null +++ b/dnsapi/dns_domeneshop.sh @@ -0,0 +1,155 @@ +#!/usr/bin/env sh + +DOMENESHOP_Api_Endpoint="https://api.domeneshop.no/v0" + +##################### Public functions ##################### + +# Usage: dns_domeneshop_add +# Example: dns_domeneshop_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_domeneshop_add() { + fulldomain=$1 + txtvalue=$2 + + # Get token and secret + DOMENESHOP_Token="${DOMENESHOP_Token:-$(_readaccountconf_mutable DOMENESHOP_Token)}" + DOMENESHOP_Secret="${DOMENESHOP_Secret:-$(_readaccountconf_mutable DOMENESHOP_Secret)}" + + if [ -z "$DOMENESHOP_Token" ] || [ -z "$DOMENESHOP_Secret" ]; then + DOMENESHOP_Token="" + DOMENESHOP_Secret="" + _err "You need to spesify a Domeneshop/Domainnameshop API Token and Secret." + return 1 + fi + + # Save the api token and secret. + _saveaccountconf_mutable DOMENESHOP_Token "$DOMENESHOP_Token" + _saveaccountconf_mutable DOMENESHOP_Secret "$DOMENESHOP_Secret" + + # Get the domain name id + if ! _get_domainid "$fulldomain"; then + _err "Did not find domainname" + return 1 + fi + + # Create record + _domeneshop_rest POST "domains/$_domainid/dns" "{\"type\":\"TXT\",\"host\":\"$_sub_domain\",\"data\":\"$txtvalue\",\"ttl\":120}" +} + +# Usage: dns_domeneshop_rm +# Example: dns_domeneshop_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_domeneshop_rm() { + fulldomain=$1 + txtvalue=$2 + + # Get token and secret + DOMENESHOP_Token="${DOMENESHOP_Token:-$(_readaccountconf_mutable DOMENESHOP_Token)}" + DOMENESHOP_Secret="${DOMENESHOP_Secret:-$(_readaccountconf_mutable DOMENESHOP_Secret)}" + + if [ -z "$DOMENESHOP_Token" ] || [ -z "$DOMENESHOP_Secret" ]; then + DOMENESHOP_Token="" + DOMENESHOP_Secret="" + _err "You need to spesify a Domeneshop/Domainnameshop API Token and Secret." + return 1 + fi + + # Get the domain name id + if ! _get_domainid "$fulldomain"; then + _err "Did not find domainname" + return 1 + fi + + # Find record + if ! _get_recordid "$_domainid" "$_sub_domain" "$txtvalue"; then + _err "Did not find dns record" + return 1 + fi + + # Remove record + _domeneshop_rest DELETE "domains/$_domainid/dns/$_recordid" +} + +##################### Private functions ##################### + +_get_domainid() { + domain=$1 + + # Get domains + _domeneshop_rest GET "domains" + + if ! _contains "$response" "\"id\":"; then + _err "failed to get domain names" + return 1 + fi + + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug "h" "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if _contains "$response" "\"$h\"" >/dev/null; then + # We have found the domain name. + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + _domainid=$(printf "%s" "$response" | _egrep_o "[^{]*\"domain\":\"$_domain\"[^}]*" | _egrep_o "\"id\":[0-9]+" | cut -d : -f 2) + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_get_recordid() { + domainid=$1 + subdomain=$2 + txtvalue=$3 + + # Get all dns records for the domainname + _domeneshop_rest GET "domains/$domainid/dns" + + if ! _contains "$response" "\"id\":"; then + _debug "No records in dns" + return 1 + fi + + if ! _contains "$response" "\"host\":\"$subdomain\""; then + _debug "Record does not exist" + return 1 + fi + + # Get the id of the record in question + _recordid=$(printf "%s" "$response" | _egrep_o "[^{]*\"host\":\"$subdomain\"[^}]*" | _egrep_o "[^{]*\"data\":\"$txtvalue\"[^}]*" | _egrep_o "\"id\":[0-9]+" | cut -d : -f 2) + if [ -z "$_recordid" ]; then + return 1 + fi + return 0 +} + +_domeneshop_rest() { + method=$1 + endpoint=$2 + data=$3 + + credentials=$(printf "%b" "$DOMENESHOP_Token:$DOMENESHOP_Secret" | _base64) + + export _H1="Authorization: Basic $credentials" + export _H2="Content-Type: application/json" + + if [ "$method" != "GET" ]; then + response="$(_post "$data" "$DOMENESHOP_Api_Endpoint/$endpoint" "" "$method")" + else + response="$(_get "$DOMENESHOP_Api_Endpoint/$endpoint")" + fi + + if [ "$?" != "0" ]; then + _err "error $endpoint" + return 1 + fi + + return 0 +} From b9994e52eb24e2389ca6e29fc79046d92e57e758 Mon Sep 17 00:00:00 2001 From: fgma <30936930+fgma@users.noreply.github.com> Date: Thu, 5 Sep 2019 16:28:47 +0200 Subject: [PATCH 0429/2234] Notify xmpp (#2407) * notify via xmpp (using sendxmpp) * fix formatting in notify/xmpp.sh * minor cleanup --- notify/xmpp.sh | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 notify/xmpp.sh diff --git a/notify/xmpp.sh b/notify/xmpp.sh new file mode 100644 index 00000000..580f471e --- /dev/null +++ b/notify/xmpp.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env sh + +#Support xmpp via sendxmpp + +#XMPP_BIN="/usr/bin/sendxmpp" +#XMPP_BIN_ARGS="-n -t --tls-ca-path=/etc/ssl/certs" +#XMPP_TO="zzzz@example.com" + +xmpp_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + XMPP_BIN="${XMPP_BIN:-$(_readaccountconf_mutable XMPP_BIN)}" + if [ -n "$XMPP_BIN" ] && ! _exists "$XMPP_BIN"; then + _err "It seems that the command $XMPP_BIN is not in path." + return 1 + fi + _XMPP_BIN=$(_xmpp_bin) + if [ -n "$XMPP_BIN" ]; then + _saveaccountconf_mutable XMPP_BIN "$XMPP_BIN" + else + _clearaccountconf "XMPP_BIN" + fi + + XMPP_BIN_ARGS="${XMPP_BIN_ARGS:-$(_readaccountconf_mutable XMPP_BIN_ARGS)}" + if [ -n "$XMPP_BIN_ARGS" ]; then + _saveaccountconf_mutable XMPP_BIN_ARGS "$XMPP_BIN_ARGS" + else + _clearaccountconf "XMPP_BIN_ARGS" + fi + + XMPP_TO="${XMPP_TO:-$(_readaccountconf_mutable XMPP_TO)}" + if [ -n "$XMPP_TO" ]; then + if ! _xmpp_valid "$XMPP_TO"; then + _err "It seems that the XMPP_TO=$XMPP_TO is not a valid xmpp address." + return 1 + fi + + _saveaccountconf_mutable XMPP_TO "$XMPP_TO" + fi + + result=$({ _xmpp_message | eval "$(_xmpp_cmnd)"; } 2>&1) + + # shellcheck disable=SC2181 + if [ $? -ne 0 ]; then + _debug "xmpp send error." + _err "$result" + return 1 + fi + + _debug "xmpp send success." + return 0 +} + +_xmpp_bin() { + if [ -n "$XMPP_BIN" ]; then + _XMPP_BIN="$XMPP_BIN" + elif _exists "sendxmpp"; then + _XMPP_BIN="sendxmpp" + else + _err "Please install sendxmpp first." + return 1 + fi + + echo "$_XMPP_BIN" +} + +_xmpp_cmnd() { + case $(basename "$_XMPP_BIN") in + sendxmpp) + echo "'$_XMPP_BIN' '$XMPP_TO' $XMPP_BIN_ARGS" + ;; + *) + _err "Command $XMPP_BIN is not supported, use sendxmpp." + return 1 + ;; + esac +} + +_xmpp_message() { + echo "$_subject" +} + +_xmpp_valid() { + _contains "$1" "@" +} From 4bf1f579f51d7343c1b643f7bb357ba9e48d0cd6 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Thu, 12 Sep 2019 16:28:57 +0200 Subject: [PATCH 0430/2234] Add OPNsense Bind API Support --- dnsapi/dns_opnsense.sh | 262 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100755 dnsapi/dns_opnsense.sh diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh new file mode 100755 index 00000000..aa123541 --- /dev/null +++ b/dnsapi/dns_opnsense.sh @@ -0,0 +1,262 @@ +#!/usr/bin/env sh + +#OPNsense Bind API +#https://docs.opnsense.org/development/api.html +# +#OPNs_Host="opnsense.example.com" +#OPNs_Port="443" +#OPNs_Key="qocfU9RSbt8vTIBcnW8bPqCrpfAHMDvj5OzadE7Str+rbjyCyk7u6yMrSCHtBXabgDDXx/dY0POUp7ZA" +#OPNs_Token="pZEQ+3ce8dDlfBBdg3N8EpqpF5I1MhFqdxX06le6Gl8YzyQvYCfCzNaFX9O9+IOSyAs7X71fwdRiZ+Lv" +#OPNs_Api_Insecure=1 # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) + +######## Public functions ##################### +#Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000" +#fulldomain +#txtvalue +dns_opnsense_add() { + fulldomain=$1 + txtvalue=$2 + + _opns_check_auth || return 1 + + if ! set_record "$fulldomain" "$txtvalue"; then + return 1 + fi + + return 0 +} + +#fulldomain +dns_opnsense_rm() { + fulldomain=$1 + txtvalue=$2 + + _opns_check_auth || return 1 + + if ! rm_record "$fulldomain" "$txtvalue"; then + return 1 + fi + + return 0 +} + +set_record() { + _info "Adding record" + fulldomain=$1 + new_challenge=$2 + + _debug "Detect root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain "$_domain" + _debug _host "$_host" + _debug _domainid "$_domainid" + _return_str="" + _record_string="" + _build_record_string "$_domainid" "$_host" "$new_challenge" + _uuid="" + if _existingchallenge "$_domain" "$_host" "$new_challenge"; then + # Update + if _opns_rest "POST" "/record/setRecord/${_uuid}" "$_record_string"; then + _return_str="$response" + else + return 1 + fi + + else + #create + if _opns_rest "POST" "/record/addRecord" "$_record_string"; then + _return_str="$response" + else + return 1 + fi + fi + + if echo "$_return_str" | _egrep_o "\"result\":\"saved\"" >/dev/null + then + _opns_rest "POST" "/service/reconfigure" "{}" + _debug "Record created" + else + _err "Error createing record $_record_string" + return 1 + fi + + return 0 +} + +rm_record() { + _info "Remove record" + fulldomain=$1 + new_challenge="$2" + + _debug "Detect root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _domain "$_domain" + _debug _host "$_host" + _debug _domainid "$_domainid" + _uuid="" + if _existingchallenge "$_domain" "$_host" "$new_challenge"; then + # Delete + if _opns_rest "POST" "/record/delRecord/${_uuid}" "\{\}"; then + if echo "$_return_str" | _egrep_o "result":"deleted" >/dev/null; then + _opns_rest "POST" "/service/reconfigure" "{}" + _debug "Record deleted" + else + _err "Error delteting record $fulldomain" + return 1 + fi + else + _err "Error delteting record $fulldomain" + return 1 + fi + else + _info "Record not found, nothing to remove" + fi + + return 0 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _domainid=domid + #_domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + if _opns_rest "GET" "/domain/get"; then + _domain_response="$response" + else + return 1 + fi + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + _debug h "$h" + id=$(echo $_domain_response| _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2 ) + + if [ -n "$id" ];then + _debug id "$id" + _host=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="${h}" + _domainid="${id}" + return 0 + fi + p=$i + i=$(_math $i + 1) + done + _debug "$domain not found" + + return 1 +} + +_opns_rest() { + method=$1 + ep=$2 + data=$3 + #Percent encode user and token + key=$(echo $OPNs_Key | tr -d "\n\r" | _url_encode ) + token=$(echo $OPNs_Token| tr -d "\n\r" | _url_encode ) + + opnsense_url="https://${key}:${token}@${OPNs_Host}:${OPNs_Port}/api/bind${ep}" + export _H1="Content-Type: application/json" + if [ ! "$method" = "GET" ]; then + _debug data "$data" + export _H1="Content-Type: application/json" + response="$(_post "$data" "$opnsense_url" "" "$method")" + else + export _H1="" + response="$(_get "$opnsense_url")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + + return 0 +} + +_build_record_string() { + _record_string="{\"record\":{\"enabled\":\"1\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"}}" +} + +_existingchallenge() { + if _opns_rest "GET" "/record/searchRecord"; then + _record_response="$response" + else + return 1 + fi + _uuid="" + _uuid=$( echo $_record_response| _egrep_o "\"uuid\":\"[^\"]*\",\"enabled\":\"[01]\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"" | cut -d ':' -f 2 | cut -d '"' -f 2 ) + + if [ -n "$_uuid" ];then + _debug uuid "$_uuid" + return 0 + fi + _debug "${2}.$1{1} record not found" + + return 1 +} + +_opns_check_auth() { + OPNs_Host="${OPNs_Host:-$(_readaccountconf_mutable OPNs_Host)}" + OPNs_Port="${OPNs_Port:-$(_readaccountconf_mutable OPNs_Port)}" + OPNs_Key="${OPNs_Key:-$(_readaccountconf_mutable OPNs_Key)}" + OPNs_Token="${OPNs_Token:-$(_readaccountconf_mutable OPNs_Token)}" + OPNs_Api_Insecure="${OPNs_Api_Insecure:-$(_readaccountconf_mutable OPNs_Api_Insecure)}" + + if [ -z "$OPNs_Host" ]; then + OPNs_Host="localhost" + _err "You don't specify OPNsense address." + fi + + if [ -z "$OPNs_Port" ]; then + OPNs_Port="443" + _err "You don't specify OPNsense Port." + fi + + if [ -z "$OPNs_Api_Insecure" ]; then + OPNs_Api_Insecure="0" + fi + + if [ -z "$OPNs_Key" ]; then + OPNs_Key="" + _err "You don't specify OPNsense api key id." + _err "Please set you OPNs_Key and try again." + return 1 + fi + + if [ -z "$OPNs_Token" ]; then + OPNs_Token="" + _err "You don't specify OPNsense token." + _err "Please create you OPNs_Token and try again." + return 1 + fi + + #save the api addr and key to the account conf file. + _saveaccountconf_mutable OPNs_Host "$OPNs_Host" + _saveaccountconf_mutable OPNs_Port "$OPNs_Port" + _saveaccountconf_mutable OPNs_Key "$OPNs_Key" + _saveaccountconf_mutable OPNs_Token "$OPNs_Token" + _saveaccountconf_mutable OPNs_Api_Insecure "$OPNs_Api_Insecure" + export HTTPS_INSECURE="${OPNs_Api_Insecure}" + + if ! _opns_rest "GET" "/general/get";then + _err "Can't Access OPNsense" + return 1 + fi + return 0 +} From dfb4883c936bed4377424aa3df3bb4a5a4576c2c Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Thu, 12 Sep 2019 17:17:32 +0200 Subject: [PATCH 0431/2234] Some fixes --- dnsapi/dns_opnsense.sh | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index aa123541..8b7942a7 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -7,7 +7,7 @@ #OPNs_Port="443" #OPNs_Key="qocfU9RSbt8vTIBcnW8bPqCrpfAHMDvj5OzadE7Str+rbjyCyk7u6yMrSCHtBXabgDDXx/dY0POUp7ZA" #OPNs_Token="pZEQ+3ce8dDlfBBdg3N8EpqpF5I1MhFqdxX06le6Gl8YzyQvYCfCzNaFX9O9+IOSyAs7X71fwdRiZ+Lv" -#OPNs_Api_Insecure=1 # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) +#OPNs_Api_Insecure=0 # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000" @@ -74,8 +74,7 @@ set_record() { fi fi - if echo "$_return_str" | _egrep_o "\"result\":\"saved\"" >/dev/null - then + if echo "$_return_str" | _egrep_o "\"result\":\"saved\"" >/dev/null; then _opns_rest "POST" "/service/reconfigure" "{}" _debug "Record created" else @@ -103,8 +102,8 @@ rm_record() { _uuid="" if _existingchallenge "$_domain" "$_host" "$new_challenge"; then # Delete - if _opns_rest "POST" "/record/delRecord/${_uuid}" "\{\}"; then - if echo "$_return_str" | _egrep_o "result":"deleted" >/dev/null; then + if _opns_rest "POST" "/record/delRecord/${_uuid}" "\{\}"; then + if echo "$_return_str" | _egrep_o "\"result\":\"deleted\"" >/dev/null; then _opns_rest "POST" "/service/reconfigure" "{}" _debug "Record deleted" else @@ -112,8 +111,8 @@ rm_record() { return 1 fi else - _err "Error delteting record $fulldomain" - return 1 + _err "Error delteting record $fulldomain" + return 1 fi else _info "Record not found, nothing to remove" @@ -126,7 +125,7 @@ rm_record() { #_acme-challenge.www.domain.com #returns # _domainid=domid - #_domain=domain.com +#_domain=domain.com _get_root() { domain=$1 i=2 @@ -144,9 +143,9 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo $_domain_response| _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2 ) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) - if [ -n "$id" ];then + if [ -n "$id" ]; then _debug id "$id" _host=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="${h}" @@ -166,8 +165,8 @@ _opns_rest() { ep=$2 data=$3 #Percent encode user and token - key=$(echo $OPNs_Key | tr -d "\n\r" | _url_encode ) - token=$(echo $OPNs_Token| tr -d "\n\r" | _url_encode ) + key=$(echo "$OPNs_Key" | tr -d "\n\r" | _url_encode) + token=$(echo "$OPNs_Token" | tr -d "\n\r" | _url_encode) opnsense_url="https://${key}:${token}@${OPNs_Host}:${OPNs_Port}/api/bind${ep}" export _H1="Content-Type: application/json" @@ -200,9 +199,9 @@ _existingchallenge() { return 1 fi _uuid="" - _uuid=$( echo $_record_response| _egrep_o "\"uuid\":\"[^\"]*\",\"enabled\":\"[01]\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"" | cut -d ':' -f 2 | cut -d '"' -f 2 ) + _uuid=$( echo "$_record_response" | _egrep_o "\"uuid\":\"[^\"]*\",\"enabled\":\"[01]\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"" | cut -d ':' -f 2 | cut -d '"' -f 2) - if [ -n "$_uuid" ];then + if [ -n "$_uuid" ]; then _debug uuid "$_uuid" return 0 fi @@ -254,7 +253,7 @@ _opns_check_auth() { _saveaccountconf_mutable OPNs_Api_Insecure "$OPNs_Api_Insecure" export HTTPS_INSECURE="${OPNs_Api_Insecure}" - if ! _opns_rest "GET" "/general/get";then + if ! _opns_rest "GET" "/general/get"; then _err "Can't Access OPNsense" return 1 fi From ec654d2355b47571f6d6fc1cbfcc3a8e808491c3 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Thu, 12 Sep 2019 17:24:00 +0200 Subject: [PATCH 0432/2234] More space removing --- dnsapi/dns_opnsense.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 8b7942a7..ac8be539 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -74,7 +74,7 @@ set_record() { fi fi - if echo "$_return_str" | _egrep_o "\"result\":\"saved\"" >/dev/null; then + if echo "$_return_str" | _egrep_o "\"result\":\"saved\"" >/dev/null; then _opns_rest "POST" "/service/reconfigure" "{}" _debug "Record created" else @@ -143,7 +143,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" @@ -199,7 +199,7 @@ _existingchallenge() { return 1 fi _uuid="" - _uuid=$( echo "$_record_response" | _egrep_o "\"uuid\":\"[^\"]*\",\"enabled\":\"[01]\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"" | cut -d ':' -f 2 | cut -d '"' -f 2) + _uuid=$( echo "$_record_response" | _egrep_o "\"uuid\":\"[^\"]*\",\"enabled\":\"[01]\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"" | cut -d ':' -f 2 | cut -d '"' -f 2) if [ -n "$_uuid" ]; then _debug uuid "$_uuid" From bfa6e52470de86363112c4e265721cd36ed2e400 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Thu, 12 Sep 2019 20:50:20 +0200 Subject: [PATCH 0433/2234] another whitespace --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index ac8be539..ff6f8a54 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -199,7 +199,7 @@ _existingchallenge() { return 1 fi _uuid="" - _uuid=$( echo "$_record_response" | _egrep_o "\"uuid\":\"[^\"]*\",\"enabled\":\"[01]\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"" | cut -d ':' -f 2 | cut -d '"' -f 2) + _uuid=$(echo "$_record_response" | _egrep_o "\"uuid\":\"[^\"]*\",\"enabled\":\"[01]\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"" | cut -d ':' -f 2 | cut -d '"' -f 2) if [ -n "$_uuid" ]; then _debug uuid "$_uuid" From 815a3be48b5d389eae234a5ffefb5eaa56492813 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 14 Sep 2019 11:21:55 +0800 Subject: [PATCH 0434/2234] fix https://github.com/Neilpang/acme.sh/issues/2478 support `sudo -i` and `sudo -s` --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 3ce377e8..980dc02f 100755 --- a/acme.sh +++ b/acme.sh @@ -6246,8 +6246,8 @@ _checkSudo() { #it's root using sudo, no matter it's using sudo or not, just fine return 0 fi - if [ "$SUDO_COMMAND" = "/bin/su" ]; then - #it's a normal user doing "sudo su" + if [ "$SUDO_COMMAND" = "/bin/su" ] || [ "$SUDO_COMMAND" = "/bin/bash" ]; then + #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s` #fine return 0 fi From 950d024a117665bcc31a2417360f7b941e16bad6 Mon Sep 17 00:00:00 2001 From: Boot Lee <82433808@qq.com> Date: Sat, 14 Sep 2019 23:06:25 +0800 Subject: [PATCH 0435/2234] fix grep error when txt value begin with - char (#2471) --- dnsapi/dns_ali.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 543a0a54..0c2365d7 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -185,7 +185,7 @@ _clean() { return 1 fi - record_id="$(echo "$response" | tr '{' "\n" | grep "$_sub_domain" | grep "$txtvalue" | tr "," "\n" | grep RecordId | cut -d '"' -f 4)" + record_id="$(echo "$response" | tr '{' "\n" | grep "$_sub_domain" | grep -- "$txtvalue" | tr "," "\n" | grep RecordId | cut -d '"' -f 4)" _debug2 record_id "$record_id" if [ -z "$record_id" ]; then From 5723fd112fb9238cd09b6cb2737f328d35746eb7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 24 Sep 2019 20:00:21 +0800 Subject: [PATCH 0436/2234] fix HEAD request against the new LE CDN. curl is fixed --- README.md | 2 +- acme.sh | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ab3412c1..6c6a7436 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh) -[![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. - Support ACME v1 and ACME v2 diff --git a/acme.sh b/acme.sh index 980dc02f..2cb577e1 100755 --- a/acme.sh +++ b/acme.sh @@ -1697,6 +1697,9 @@ _post() { if [ "$HTTPS_INSECURE" ]; then _CURL="$_CURL --insecure " fi + if [ "$httpmethod" = "HEAD" ]; then + _CURL="$_CURL -I " + fi _debug "_CURL" "$_CURL" if [ "$needbase64" ]; then if [ "$_postContentType" ]; then From 51b4a9e3509906b86aae4c25a350f8bcdf2d3f8c Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 24 Sep 2019 20:50:24 +0800 Subject: [PATCH 0437/2234] fix HEAD request against the new LE CDN. wget is fixed --- acme.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/acme.sh b/acme.sh index 2cb577e1..cfcd3575 100755 --- a/acme.sh +++ b/acme.sh @@ -1727,6 +1727,9 @@ _post() { if [ "$HTTPS_INSECURE" ]; then _WGET="$_WGET --no-check-certificate " fi + if [ "$httpmethod" = "HEAD" ]; then + _WGET="$_WGET --read-timeout=3.0 --tries=2 " + fi _debug "_WGET" "$_WGET" if [ "$needbase64" ]; then if [ "$httpmethod" = "POST" ]; then @@ -1749,6 +1752,12 @@ _post() { else response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" fi + elif [ "$httpmethod" = "HEAD" ]; then + if [ "$_postContentType" ]; then + response="$($_WGET --spider -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" + else + response="$($_WGET --spider -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" + fi else if [ "$_postContentType" ]; then response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")" From 1ba4ab2bd1d200962b7d611e3aeefcf2d32cc48b Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 24 Sep 2019 22:10:36 +0800 Subject: [PATCH 0438/2234] fix https://github.com/Neilpang/acme.sh/issues/2503 --- acme.sh | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index cfcd3575..39c07cbe 100755 --- a/acme.sh +++ b/acme.sh @@ -1702,16 +1702,32 @@ _post() { fi _debug "_CURL" "$_CURL" if [ "$needbase64" ]; then - if [ "$_postContentType" ]; then - response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" + if [ "$body" ]; then + if [ "$_postContentType" ]; then + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" + else + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" + fi else - response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" + if [ "$_postContentType" ]; then + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url" | _base64)" + else + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url" | _base64)" + fi fi else - if [ "$_postContentType" ]; then - response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" + if [ "$body" ]; then + if [ "$_postContentType" ]; then + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" + else + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" + fi else - response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" + if [ "$_postContentType" ]; then + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url")" + else + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url")" + fi fi fi _ret="$?" @@ -1890,7 +1906,7 @@ _send_signed_request() { if [ "$ACME_NEW_NONCE" ]; then _debug2 "Get nonce with HEAD. ACME_NEW_NONCE" "$ACME_NEW_NONCE" nonceurl="$ACME_NEW_NONCE" - if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then + if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type" >/dev/null; then _headers="$(cat "$HTTP_HEADER")" _debug2 _headers "$_headers" _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" From be0df07dfbe5e5fda893450305b9bd1cce3c7ff9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 28 Sep 2019 10:54:31 +0800 Subject: [PATCH 0439/2234] fix list() performance https://github.com/Neilpang/acme.sh/issues/2296 --- acme.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 39c07cbe..0ff24c98 100755 --- a/acme.sh +++ b/acme.sh @@ -4974,18 +4974,14 @@ list() { if [ "$_raw" ]; then printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}Created${_sep}Renew" for di in "${CERT_HOME}"/*.*/; do - if ! [ -d "$di" ]; then - _debug "Not directory, skip: $di" - continue - fi d=$(basename "$di") _debug d "$d" ( if _endswith "$d" "$ECC_SUFFIX"; then - _isEcc=$(echo "$d" | cut -d "$ECC_SEP" -f 2) + _isEcc="ecc" d=$(echo "$d" | cut -d "$ECC_SEP" -f 1) fi - _initpath "$d" "$_isEcc" + DOMAIN_CONF="$di/$d.conf" if [ -f "$DOMAIN_CONF" ]; then . "$DOMAIN_CONF" printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr" From 10eec7d48c11e91e988be335f5bd4989b628aadb Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 3 Oct 2019 20:37:46 +0800 Subject: [PATCH 0440/2234] support google dns --- acme.sh | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 0ff24c98..bded4ada 100755 --- a/acme.sh +++ b/acme.sh @@ -90,6 +90,9 @@ DEBUG_LEVEL_3=3 DEBUG_LEVEL_DEFAULT=$DEBUG_LEVEL_1 DEBUG_LEVEL_NONE=0 +DOH_CLOUDFLARE=1 +DOH_GOOGLE=2 + HIDDEN_VALUE="[hidden](please add '--output-insecure' to see this value)" SYSLOG_ERROR="user.error" @@ -3636,7 +3639,7 @@ __trigger_validation() { } #endpoint domain type -_ns_lookup() { +_ns_lookup_impl() { _ns_ep="$1" _ns_domain="$2" _ns_type="$3" @@ -3660,7 +3663,7 @@ _ns_lookup_cf() { _cf_ld="$1" _cf_ld_type="$2" _cf_ep="https://cloudflare-dns.com/dns-query" - _ns_lookup "$_cf_ep" "$_cf_ld" "$_cf_ld_type" + _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type" } #domain, type @@ -3673,6 +3676,44 @@ _ns_purge_cf() { _debug2 response "$response" } +#checks if cf server is available +_ns_is_available_cf() { + if _get "https://cloudflare-dns.com"; then + return 0 + else + return 1 + fi +} + +#domain, type +_ns_lookup_google() { + _cf_ld="$1" + _cf_ld_type="$2" + _cf_ep="https://dns.google/resolve" + _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type" +} + +#domain, type +_ns_lookup() { + if [ -z "$DOH_USE" ]; then + _debug "Detect dns server first." + if _ns_is_available_cf; then + _debug "Use cloudflare doh server" + export DOH_USE=$DOH_CLOUDFLARE + else + _debug "Use google doh server" + export DOH_USE=$DOH_GOOGLE + fi + fi + + if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then + _ns_lookup_cf "$@" + else + _ns_lookup_google "$@" + fi + +} + #txtdomain, alias, txt __check_txt() { _c_txtdomain="$1" @@ -3681,7 +3722,7 @@ __check_txt() { _debug "_c_txtdomain" "$_c_txtdomain" _debug "_c_aliasdomain" "$_c_aliasdomain" _debug "_c_txt" "$_c_txt" - _answers="$(_ns_lookup_cf "$_c_aliasdomain" TXT)" + _answers="$(_ns_lookup "$_c_aliasdomain" TXT)" _contains "$_answers" "$_c_txt" } @@ -3690,7 +3731,13 @@ __check_txt() { __purge_txt() { _p_txtdomain="$1" _debug _p_txtdomain "$_p_txtdomain" - _ns_purge_cf "$_p_txtdomain" "TXT" + if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then + _ns_purge_cf "$_p_txtdomain" "TXT" + else + _debug "no purge api for google dns api, just sleep 5 secs" + _sleep 5 + fi + } #wait and check each dns entries From b4a62bfa300b0d4c95a3f279b626227e50a8f0a5 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 3 Oct 2019 20:51:06 +0800 Subject: [PATCH 0441/2234] let's start 2.8.4 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index bded4ada..041b5b44 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.3 +VER=2.8.4 PROJECT_NAME="acme.sh" From 477a04760c8558d5385736a6537f3313f2f11b96 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Thu, 3 Oct 2019 21:00:30 +0800 Subject: [PATCH 0442/2234] support google public dns (#2522) * support google dns * let's start 2.8.4 --- acme.sh | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 0ff24c98..041b5b44 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.3 +VER=2.8.4 PROJECT_NAME="acme.sh" @@ -90,6 +90,9 @@ DEBUG_LEVEL_3=3 DEBUG_LEVEL_DEFAULT=$DEBUG_LEVEL_1 DEBUG_LEVEL_NONE=0 +DOH_CLOUDFLARE=1 +DOH_GOOGLE=2 + HIDDEN_VALUE="[hidden](please add '--output-insecure' to see this value)" SYSLOG_ERROR="user.error" @@ -3636,7 +3639,7 @@ __trigger_validation() { } #endpoint domain type -_ns_lookup() { +_ns_lookup_impl() { _ns_ep="$1" _ns_domain="$2" _ns_type="$3" @@ -3660,7 +3663,7 @@ _ns_lookup_cf() { _cf_ld="$1" _cf_ld_type="$2" _cf_ep="https://cloudflare-dns.com/dns-query" - _ns_lookup "$_cf_ep" "$_cf_ld" "$_cf_ld_type" + _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type" } #domain, type @@ -3673,6 +3676,44 @@ _ns_purge_cf() { _debug2 response "$response" } +#checks if cf server is available +_ns_is_available_cf() { + if _get "https://cloudflare-dns.com"; then + return 0 + else + return 1 + fi +} + +#domain, type +_ns_lookup_google() { + _cf_ld="$1" + _cf_ld_type="$2" + _cf_ep="https://dns.google/resolve" + _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type" +} + +#domain, type +_ns_lookup() { + if [ -z "$DOH_USE" ]; then + _debug "Detect dns server first." + if _ns_is_available_cf; then + _debug "Use cloudflare doh server" + export DOH_USE=$DOH_CLOUDFLARE + else + _debug "Use google doh server" + export DOH_USE=$DOH_GOOGLE + fi + fi + + if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then + _ns_lookup_cf "$@" + else + _ns_lookup_google "$@" + fi + +} + #txtdomain, alias, txt __check_txt() { _c_txtdomain="$1" @@ -3681,7 +3722,7 @@ __check_txt() { _debug "_c_txtdomain" "$_c_txtdomain" _debug "_c_aliasdomain" "$_c_aliasdomain" _debug "_c_txt" "$_c_txt" - _answers="$(_ns_lookup_cf "$_c_aliasdomain" TXT)" + _answers="$(_ns_lookup "$_c_aliasdomain" TXT)" _contains "$_answers" "$_c_txt" } @@ -3690,7 +3731,13 @@ __check_txt() { __purge_txt() { _p_txtdomain="$1" _debug _p_txtdomain "$_p_txtdomain" - _ns_purge_cf "$_p_txtdomain" "TXT" + if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then + _ns_purge_cf "$_p_txtdomain" "TXT" + else + _debug "no purge api for google dns api, just sleep 5 secs" + _sleep 5 + fi + } #wait and check each dns entries From 683592fa867ef034afea8036096f96f4f58ea00a Mon Sep 17 00:00:00 2001 From: jess Date: Thu, 3 Oct 2019 06:01:05 -0700 Subject: [PATCH 0443/2234] Added financial contributors to the README (#2513) --- README.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c6a7436..faaf9aa9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh) - [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. - Support ACME v1 and ACME v2 @@ -451,6 +451,36 @@ TODO: 2. ACME protocol: https://github.com/ietf-wg-acme/acme +## Contributors + +### Code Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. + + +### Financial Contributors + +Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/acmesh/contribute)] + +#### Individuals + + + +#### Organizations + +Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/acmesh/contribute)] + + + + + + + + + + + + # 19. License & Others License is GPLv3 From 8ef5daa8070d8c8e2d71b366f14d498c27a74261 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 3 Oct 2019 21:14:11 +0800 Subject: [PATCH 0444/2234] minor, update link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index faaf9aa9..d5012d68 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh) - [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. - Support ACME v1 and ACME v2 From 54143ae6d40ba8845de392ab8350c525f47a9417 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Thu, 3 Oct 2019 21:15:32 +0800 Subject: [PATCH 0445/2234] sync (#2523) sync --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index faaf9aa9..d5012d68 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh) - [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. - Support ACME v1 and ACME v2 From 72d800ed1098a77f565c14691f164be8ccab969b Mon Sep 17 00:00:00 2001 From: Michael Braunoeder Date: Sat, 5 Oct 2019 05:47:57 +0200 Subject: [PATCH 0446/2234] [DNSAPI] add dns_rcode0.sh - Support for https://my.rcodezero.at/api-doc (#2489) * first version dns_rcode0.sh * fixed URLs for ACME calls * fixed challenge remove * read & write Token/URL at rm too * make info messages debug * typos fixed * update rrset only if existing challenge is found * polish error messages and make "detect root zone" scaleable * fixed formating issues * code cleanup, remove some unneeded functions * removed empty lines * save rcode0 url only if not default --- dnsapi/dns_rcode0.sh | 224 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100755 dnsapi/dns_rcode0.sh diff --git a/dnsapi/dns_rcode0.sh b/dnsapi/dns_rcode0.sh new file mode 100755 index 00000000..9ed20e68 --- /dev/null +++ b/dnsapi/dns_rcode0.sh @@ -0,0 +1,224 @@ +#!/usr/bin/env sh + +#Rcode0 API Integration +#https://my.rcodezero.at/api-doc +# +# log into https://my.rcodezero.at/enableapi and get your ACME API Token (the ACME API token has limited +# access to the REST calls needed for acme.sh only) +# +#RCODE0_URL="https://my.rcodezero.at" +#RCODE0_API_TOKEN="0123456789ABCDEF" +#RCODE0_TTL=60 + +DEFAULT_RCODE0_URL="https://my.rcodezero.at" +DEFAULT_RCODE0_TTL=60 + +######## Public functions ##################### +#Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000" +#fulldomain +#txtvalue +dns_rcode0_add() { + fulldomain=$1 + txtvalue=$2 + + RCODE0_API_TOKEN="${RCODE0_API_TOKEN:-$(_readaccountconf_mutable RCODE0_API_TOKEN)}" + RCODE0_URL="${RCODE0_URL:-$(_readaccountconf_mutable RCODE0_URL)}" + RCODE0_TTL="${RCODE0_TTL:-$(_readaccountconf_mutable RCODE0_TTL)}" + + if [ -z "$RCODE0_URL" ]; then + RCODE0_URL="$DEFAULT_RCODE0_URL" + fi + + if [ -z "$RCODE0_API_TOKEN" ]; then + RCODE0_API_TOKEN="" + _err "Missing Rcode0 ACME API Token." + _err "Please login and create your token at httsp://my.rcodezero.at/enableapi and try again." + return 1 + fi + + if [ -z "$RCODE0_TTL" ]; then + RCODE0_TTL="$DEFAULT_RCODE0_TTL" + fi + + #save the token to the account conf file. + _saveaccountconf_mutable RCODE0_API_TOKEN "$RCODE0_API_TOKEN" + + if [ "$RCODE0_URL" != "$DEFAULT_RCODE0_URL" ]; then + _saveaccountconf_mutable RCODE0_URL "$RCODE0_URL" + fi + + if [ "$RCODE0_TTL" != "$DEFAULT_RCODE0_TTL" ]; then + _saveaccountconf_mutable RCODE0_TTL "$RCODE0_TTL" + fi + + _debug "Detect root zone" + if ! _get_root "$fulldomain"; then + _err "No 'MASTER' zone for $fulldomain found at RcodeZero Anycast." + return 1 + fi + _debug _domain "$_domain" + + _debug "Adding record" + + _record_string="" + _build_record_string "$txtvalue" + _list_existingchallenges + for oldchallenge in $_existing_challenges; do + _build_record_string "$oldchallenge" + done + + _debug "Challenges: $_existing_challenges" + + if [ -z "$_existing_challenges" ]; then + if ! _rcode0_rest "PATCH" "/api/v1/acme/zones/$_domain/rrsets" "[{\"changetype\": \"add\", \"name\": \"$fulldomain.\", \"type\": \"TXT\", \"ttl\": $RCODE0_TTL, \"records\": [$_record_string]}]"; then + _err "Add txt record error." + return 1 + fi + else + # try update in case a records exists (need for wildcard certs) + if ! _rcode0_rest "PATCH" "/api/v1/acme/zones/$_domain/rrsets" "[{\"changetype\": \"update\", \"name\": \"$fulldomain.\", \"type\": \"TXT\", \"ttl\": $RCODE0_TTL, \"records\": [$_record_string]}]"; then + _err "Set txt record error." + return 1 + fi + fi + + return 0 +} + +#fulldomain txtvalue +dns_rcode0_rm() { + fulldomain=$1 + txtvalue=$2 + + RCODE0_API_TOKEN="${RCODE0_API_TOKEN:-$(_readaccountconf_mutable RCODE0_API_TOKEN)}" + RCODE0_URL="${RCODE0_URL:-$(_readaccountconf_mutable RCODE0_URL)}" + RCODE0_TTL="${RCODE0_TTL:-$(_readaccountconf_mutable RCODE0_TTL)}" + + if [ -z "$RCODE0_URL" ]; then + RCODE0_URL="$DEFAULT_RCODE0_URL" + fi + + if [ -z "$RCODE0_API_TOKEN" ]; then + RCODE0_API_TOKEN="" + _err "Missing Rcode0 API Token." + _err "Please login and create your token at httsp://my.rcodezero.at/enableapi and try again." + return 1 + fi + + #save the api addr and key to the account conf file. + _saveaccountconf_mutable RCODE0_URL "$RCODE0_URL" + _saveaccountconf_mutable RCODE0_API_TOKEN "$RCODE0_API_TOKEN" + + if [ "$RCODE0_TTL" != "$DEFAULT_RCODE0_TTL" ]; then + _saveaccountconf_mutable RCODE0_TTL "$RCODE0_TTL" + fi + + if [ -z "$RCODE0_TTL" ]; then + RCODE0_TTL="$DEFAULT_RCODE0_TTL" + fi + + _debug "Detect root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug "Remove record" + + #Enumerate existing acme challenges + _list_existingchallenges + + if _contains "$_existing_challenges" "$txtvalue"; then + #Delete all challenges (PowerDNS API does not allow to delete content) + if ! _rcode0_rest "PATCH" "/api/v1/acme/zones/$_domain/rrsets" "[{\"changetype\": \"delete\", \"name\": \"$fulldomain.\", \"type\": \"TXT\"}]"; then + _err "Delete txt record error." + return 1 + fi + _record_string="" + #If the only existing challenge was the challenge to delete: nothing to do + if ! [ "$_existing_challenges" = "$txtvalue" ]; then + for oldchallenge in $_existing_challenges; do + #Build up the challenges to re-add, ommitting the one what should be deleted + if ! [ "$oldchallenge" = "$txtvalue" ]; then + _build_record_string "$oldchallenge" + fi + done + #Recreate the existing challenges + if ! _rcode0_rest "PATCH" "/api/v1/acme/zones/$_domain/rrsets" "[{\"changetype\": \"update\", \"name\": \"$fulldomain.\", \"type\": \"TXT\", \"ttl\": $RCODE0_TTL, \"records\": [$_record_string]}]"; then + _err "Set txt record error." + return 1 + fi + fi + else + _info "Record not found, nothing to remove" + fi + + return 0 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + + _debug "try to find: $h" + if _rcode0_rest "GET" "/api/v1/acme/zones/$h"; then + if [ "$response" = "[\"found\"]" ]; then + _domain="$h" + if [ -z "$h" ]; then + _domain="=2E" + fi + return 0 + elif [ "$response" = "[\"not a master domain\"]" ]; then + return 1 + fi + fi + + if [ -z "$h" ]; then + return 1 + fi + i=$(_math $i + 1) + done + _debug "no matching domain for $domain found" + + return 1 +} + +_rcode0_rest() { + method=$1 + ep=$2 + data=$3 + + export _H1="Authorization: Bearer $RCODE0_API_TOKEN" + + if [ ! "$method" = "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$RCODE0_URL$ep" "" "$method")" + else + response="$(_get "$RCODE0_URL$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + + return 0 +} + +_build_record_string() { + _record_string="${_record_string:+${_record_string}, }{\"content\": \"\\\"${1}\\\"\", \"disabled\": false}" +} + +_list_existingchallenges() { + _rcode0_rest "GET" "/api/v1/acme/zones/$_domain/rrsets" + _existing_challenges=$(echo "$response" | _normalizeJson | _egrep_o "\"name\":\"${fulldomain}[^]]*}" | _egrep_o 'content\":\"\\"[^\\]*' | sed -n 's/^content":"\\"//p') + _debug2 "$_existing_challenges" +} From 1e7534b9d7a4e629f46c6eb9995db20fcf962d80 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 5 Oct 2019 11:59:04 +0800 Subject: [PATCH 0447/2234] fix https://github.com/Neilpang/acme.sh/issues/2518#issuecomment-538474232 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 041b5b44..cac16d35 100755 --- a/acme.sh +++ b/acme.sh @@ -3678,7 +3678,7 @@ _ns_purge_cf() { #checks if cf server is available _ns_is_available_cf() { - if _get "https://cloudflare-dns.com"; then + if _get "https://cloudflare-dns.com" >/dev/null 2>&1; then return 0 else return 1 From ac9f6e3a4135dbc008c4e22af7f649d139690918 Mon Sep 17 00:00:00 2001 From: Peter Dave Hello Date: Sat, 5 Oct 2019 21:06:58 +0800 Subject: [PATCH 0448/2234] Remove trailing spaces in text files This issue in the shell scripts will also be detected in the stable version of shfmt(we are currently using an ancient pre-release of shfmt) --- .github/ISSUE_TEMPLATE.md | 2 +- .travis.yml | 4 ++-- acme.sh | 4 ++-- deploy/qiniu.sh | 2 +- deploy/routeros.sh | 2 +- deploy/vault_cli.sh | 4 ++-- dnsapi/dns_da.sh | 2 +- dnsapi/dns_doapi.sh | 6 +++--- dnsapi/dns_durabledns.sh | 10 +++++----- dnsapi/dns_euserv.sh | 2 +- dnsapi/dns_freedns.sh | 2 +- dnsapi/dns_me.sh | 2 +- dnsapi/dns_namecheap.sh | 6 +++--- dnsapi/dns_nsupdate.sh | 4 ++-- dnsapi/dns_rcode0.sh | 2 +- 15 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 189155e1..53112c6f 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,7 +5,7 @@ 如何调试 https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh If it is a bug report: -- make sure you are able to repro it on the latest released version. +- make sure you are able to repro it on the latest released version. You can install the latest version by: `acme.sh --upgrade` - Search the existing issues. diff --git a/.travis.yml b/.travis.yml index 04de1934..e77eb32c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,5 +34,5 @@ script: matrix: fast_finish: true - - + + diff --git a/acme.sh b/acme.sh index cac16d35..e060e334 100755 --- a/acme.sh +++ b/acme.sh @@ -178,7 +178,7 @@ _printargs() { printf -- "%s" "$1='$2'" fi printf "\n" - # return the saved exit status + # return the saved exit status return "$_exitstatus" } @@ -6215,7 +6215,7 @@ Parameters: --branch, -b Only valid for '--upgrade' command, specifies the branch name to upgrade to. --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. - 0: disabled, no notification will be sent. + 0: disabled, no notification will be sent. 1: send notifications only when there is an error. 2: send notifications when a cert is successfully renewed, or there is an error. 3: send notifications when a cert is skipped, renewed, or error. diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index e46e6fb3..13b09651 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Script to create certificate to qiniu.com +# Script to create certificate to qiniu.com # # This deployment required following variables # export QINIU_AK="QINIUACCESSKEY" diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 21c9196f..70fe70a3 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -85,7 +85,7 @@ routeros_deploy() { scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" _info "Trying to push cert '$_cfullchain' to router" scp "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" - DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=ftp,read,write,password,sensitive + DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=ftp,read,write,password,sensitive source=\"## generated by routeros deploy script in acme.sh \n/certificate remove [ find name=$_cdomain.cer_0 ] \n/certificate remove [ find name=$_cdomain.cer_1 ] diff --git a/deploy/vault_cli.sh b/deploy/vault_cli.sh index b93fdd51..5395d87e 100644 --- a/deploy/vault_cli.sh +++ b/deploy/vault_cli.sh @@ -2,10 +2,10 @@ # Here is a script to deploy cert to hashicorp vault # (https://www.vaultproject.io/) -# +# # it requires the vault binary to be available in PATH, and the following # environment variables: -# +# # VAULT_PREFIX - this contains the prefix path in vault # VAULT_ADDR - vault requires this to find your vault server # diff --git a/dnsapi/dns_da.sh b/dnsapi/dns_da.sh index 7755c7e1..4e9c4ef0 100755 --- a/dnsapi/dns_da.sh +++ b/dnsapi/dns_da.sh @@ -9,7 +9,7 @@ # # User must provide login data and URL to DirectAdmin incl. port. # You can create login key, by using the Login Keys function -# ( https://da.example.com:8443/CMD_LOGIN_KEYS ), which only has access to +# ( https://da.example.com:8443/CMD_LOGIN_KEYS ), which only has access to # - CMD_API_DNS_CONTROL # - CMD_API_SHOW_DOMAINS # diff --git a/dnsapi/dns_doapi.sh b/dnsapi/dns_doapi.sh index 135f0b03..a001d52c 100755 --- a/dnsapi/dns_doapi.sh +++ b/dnsapi/dns_doapi.sh @@ -1,11 +1,11 @@ #!/usr/bin/env sh # Official Let's Encrypt API for do.de / Domain-Offensive -# +# # This is different from the dns_do adapter, because dns_do is only usable for enterprise customers # This API is also available to private customers/individuals -# -# Provide the required LetsEncrypt token like this: +# +# Provide the required LetsEncrypt token like this: # DO_LETOKEN="FmD408PdqT1E269gUK57" DO_API="https://www.do.de/api/letsencrypt" diff --git a/dnsapi/dns_durabledns.sh b/dnsapi/dns_durabledns.sh index 9a05eb32..677ae24d 100644 --- a/dnsapi/dns_durabledns.sh +++ b/dnsapi/dns_durabledns.sh @@ -147,11 +147,11 @@ _dd_soap() { # build SOAP XML _xml=' - '"$body"' ' diff --git a/dnsapi/dns_euserv.sh b/dnsapi/dns_euserv.sh index 38101565..cfb4b814 100644 --- a/dnsapi/dns_euserv.sh +++ b/dnsapi/dns_euserv.sh @@ -127,7 +127,7 @@ dns_euserv_rm() { else # find XML block where txtvalue is in. The record_id is allways prior this line! _endLine=$(echo "$response" | grep -n '>dns_record_content<.*>'"$txtvalue"'<' | cut -d ':' -f 1) - # record_id is the last Tag with a number before the row _endLine, identified by + # record_id is the last Tag with a number before the row _endLine, identified by _record_id=$(echo "$response" | sed -n '1,'"$_endLine"'p' | grep '' | _tail_n 1 | sed 's/.*\([0-9]*\)<\/name>.*/\1/') _info "Deleting record" _euserv_delete_record "$_record_id" diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index e76e6495..29b18921 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -359,7 +359,7 @@ _freedns_data_id() { # before each table row # search for the record type withing each row (e.g. TXT) # search for the domain within each row (which is within a - # anchor. And finally extract the domain ID. + # anchor. And finally extract the domain ID. if [ -n "$data_id" ]; then printf "%s" "$data_id" return 0 diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 382eeedd..98a58411 100644 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -2,7 +2,7 @@ # bug reports to dev@1e.ca -# ME_Key=qmlkdjflmkqdjf +# ME_Key=qmlkdjflmkqdjf # ME_Secret=qmsdlkqmlksdvnnpae ME_Api=https://api.dnsmadeeasy.com/V2.0/dns/managed diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index a82e12d7..2e389265 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -3,10 +3,10 @@ # Namecheap API # https://www.namecheap.com/support/api/intro.aspx # -# Requires Namecheap API key set in -#NAMECHEAP_API_KEY, +# Requires Namecheap API key set in +#NAMECHEAP_API_KEY, #NAMECHEAP_USERNAME, -#NAMECHEAP_SOURCEIP +#NAMECHEAP_SOURCEIP # Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise. ######## Public functions ##################### diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index dfb3672a..cd4b7140 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -27,7 +27,7 @@ dns_nsupdate_add() { [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D" if [ -z "${NSUPDATE_ZONE}" ]; then nsupdate -k "${NSUPDATE_KEY}" $nsdebug < Date: Sat, 5 Oct 2019 21:13:23 +0800 Subject: [PATCH 0449/2234] Use shallow clone to speed up git clone on Travis CI Shallow clone is faster than a normal one, there is no need to clone the whole history of a repository when we only needs its latest or certain state of commit. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 04de1934..5f0ce0c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ script: - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" ; fi - cd .. - - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest + - git clone --depth 1 https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./rundocker.sh testplat ubuntu:latest ; fi - if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ACME_OPENSSL_BIN="$ACME_OPENSSL_BIN" ./letest.sh ; fi From bc396e7a90e05704eddf12d728809e72ce77d5dd Mon Sep 17 00:00:00 2001 From: Vadim Kalinnikov Date: Sun, 6 Oct 2019 14:38:26 +0300 Subject: [PATCH 0450/2234] Small fix in dns_vultr.sh --- dnsapi/dns_vultr.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh index f15e7c49..0dce2ca1 100644 --- a/dnsapi/dns_vultr.sh +++ b/dnsapi/dns_vultr.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/bin/bash # #VULTR_API_KEY=000011112222333344445555666677778888 @@ -106,9 +106,9 @@ _get_root() { domain=$1 i=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug h "$h" - if [ -z "$h" ]; then + _domain=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$_domain" + if [ -z "$_domain" ]; then return 1 fi @@ -119,11 +119,9 @@ _get_root() { if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then if _contains "$response" "\"domain\":\"$_domain\""; then _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" - _domain=$_domain return 0 else - _err 'Invalid domain' - return 1 + _debug "Go to next level of $_domain" fi else _err "$response" From e484f32b1abe2fea12a4b5fb9d13e7eb23996f9a Mon Sep 17 00:00:00 2001 From: Vadim Kalinnikov Date: Sun, 6 Oct 2019 14:40:57 +0300 Subject: [PATCH 0451/2234] - Return shell detect via env --- dnsapi/dns_vultr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh index 0dce2ca1..c7b52e84 100644 --- a/dnsapi/dns_vultr.sh +++ b/dnsapi/dns_vultr.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env sh # #VULTR_API_KEY=000011112222333344445555666677778888 From 65c950e1a41562b9eca0b23b04a260b18c3335d4 Mon Sep 17 00:00:00 2001 From: MooSE <32853697+moose-kazan@users.noreply.github.com> Date: Sun, 6 Oct 2019 15:02:48 +0300 Subject: [PATCH 0452/2234] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5012d68..faaf9aa9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh) - [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. - Support ACME v1 and ACME v2 From f500c7abcba29d19b2d49d8e3b25d9c6d5e2f726 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Tue, 8 Oct 2019 15:47:39 +0200 Subject: [PATCH 0453/2234] dnsapi/dns_miab.sh MIAB DNS-01 Validation Know I'm new to contorting to this project. I i've broke conventions please let me know what I've screwed up and I'll set it right as quickly as possible. Propose this as a new DNS-01 validation script to dynamically add challenge DNS records to MailinaBox (MIAB) DNS. MIAB uses a custom DNS API to manage external DNS records. The script was originally written by Darven Dissek and can be found in his repository: https://framagit.org/DarvenDissek/acme.sh-MIAB-DNS-API/). This has been forked and some slight cleanup applied and change shebang to UNIx shell. The forked repository can be found here: https://github.com/billgertz/MIAB_dns_api. Wrote to Darven but received no reply. Support for this script has been submitted to the OPNsense project via this pull request: https://github.com/opnsense/plugins/pull/1531 --- dnsapi/dns_miab.sh | 273 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 dnsapi/dns_miab.sh diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh new file mode 100644 index 00000000..b0a52d7e --- /dev/null +++ b/dnsapi/dns_miab.sh @@ -0,0 +1,273 @@ +#!/usr/bin/env sh + +#Name: dns_miab.sh +# +#Authors: +# Darven Dissek 2018 +# William Gertz 2019 +# +# Thanks to Neil Pang for the code reused from acme.sh from HTTP-01 validation +# used to communicate with the MailintheBox Custom DNS API +#Report Bugs here: +# https://github.com/billgertz/MIAB_dns_api (for dns_miab.sh) +# https://github.com/Neilpang/acme.sh (for acme.sh) +# +######## Public functions ##################### + +#Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_miab_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using miab" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + MIAB_Username="${MIAB_Username:-$(_readaccountconf_mutable MIAB_Username)}" + MIAB_Password="${MIAB_Password:-$(_readaccountconf_mutable MIAB_Password)}" + MIAB_Server="${MIAB_Server:-$(_readaccountconf_mutable MIAB_Server)}" + + #debug log the environmental variables + _debug MIAB_Username "$MIAB_Username" + _debug MIAB_Password "$MIAB_Password" + _debug MIAB_Server "$MIAB_Server" + + if [ -z "$MIAB_Username" ] || [ -z "$MIAB_Password" ] || [ -z "$MIAB_Server" ]; then + MIAB_Username="" + MIAB_Password="" + MIAB_Server="" + _err "You didn't specify MIAB_Username or MIAB_Password or MIAB_Server." + _err "Please try again." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable MIAB_Username "$MIAB_Username" + _saveaccountconf_mutable MIAB_Password "$MIAB_Password" + _saveaccountconf_mutable MIAB_Server "$MIAB_Server" + + baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt" + + #Add the challenge record + result="$(_miab_post "$txtvalue" "$baseurl" "" "POST" "" "$MIAB_Username" "$MIAB_Password")" + + _debug result "$result" + + #check if result was good + if _contains "$result" "updated DNS"; then + _info "Successfully created the txt record" + return 0 + else + _err "Error encountered during record addition" + _err "$result" + return 1 + fi + +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_miab_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using miab" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + MIAB_Username="${MIAB_Username:-$(_readaccountconf_mutable MIAB_Username)}" + MIAB_Password="${MIAB_Password:-$(_readaccountconf_mutable MIAB_Password)}" + MIAB_Server="${MIAB_Server:-$(_readaccountconf_mutable MIAB_Server)}" + + #debug log the environmental variables + _debug MIAB_Username "$MIAB_Username" + _debug MIAB_Password "$MIAB_Password" + _debug MIAB_Server "$MIAB_Server" + + if [ -z "$MIAB_Username" ] || [ -z "$MIAB_Password" ] || [ -z "$MIAB_Server" ]; then + MIAB_Username="" + MIAB_Password="" + MIAB_Server="" + _err "You didn't specify MIAB_Username or MIAB_Password or MIAB_Server." + _err "Please try again." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable MIAB_Username "$MIAB_Username" + _saveaccountconf_mutable MIAB_Password "$MIAB_Password" + _saveaccountconf_mutable MIAB_Server "$MIAB_Server" + + baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt" + + #Remove the challenge record + result="$(_miab_post "$txtvalue" "$baseurl" "" "DELETE" "" "$MIAB_Username" "$MIAB_Password")" + + _debug result $result + + #check if result was good + if _contains "$result" "updated DNS"; then + _info "Successfully created the txt record" + return 0 + else + _err "Error encountered during record addition" + _err "$result" + return 1 + fi +} + +#################### 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 + + 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" "\"name\":\"$h\"" >/dev/null; then + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") + + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + + return 1 + fi + + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} + +# post changes to MIAB dns (taken from acme.sh) +_miab_post() { + body="$1" + _post_url="$2" + needbase64="$3" + httpmethod="$4" + _postContentType="$5" + username="$6" + password="$7" + + if [ -z "$httpmethod" ]; then + httpmethod="POST" + fi + + _debug $httpmethod + _debug "_post_url" "$_post_url" + _debug2 "body" "$body" + _debug2 "_postContentType" "$_postContentType" + + _inithttp + + if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then + _CURL="$_ACME_CURL" + + if [ "$HTTPS_INSECURE" ]; then + _CURL="$_CURL --insecure " + fi + + _debug "_CURL" "$_CURL" + + if [ "$needbase64" ]; then + if [ "$_postContentType" ]; then + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" + else + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" + fi + else + if [ "$_postContentType" ]; then + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" + else + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" + fi + fi + + _ret="$?" + + if [ "$_ret" != "0" ]; then + _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" + if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then + _err "Here is the curl dump log:" + _err "$(cat "$_CURL_DUMP")" + fi + fi + + elif [ "$_ACME_WGET" ]; then + _WGET="$_ACME_WGET" + + if [ "$HTTPS_INSECURE" ]; then + _WGET="$_WGET --no-check-certificate " + fi + + _debug "_WGET" "$_WGET" + + if [ "$needbase64" ]; then + + if [ "$httpmethod" = "POST" ]; then + if [ "$_postContentType" ]; then + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" + else + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" + fi + else + if [ "$_postContentType" ]; then + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" + else + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" + fi + fi + + else + + if [ "$httpmethod" = "POST" ]; then + if [ "$_postContentType" ]; then + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" + else + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" + fi + else + if [ "$_postContentType" ]; then + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")" + else + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")" + fi + fi + + fi + + _ret="$?" + + if [ "$_ret" = "8" ]; then + _ret=0 + _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." + fi + + if [ "$_ret" != "0" ]; then + _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" + fi + + _sed_i "s/^ *//g" "$HTTP_HEADER" + + else + _ret="$?" + _err "Neither curl nor wget was found, cannot do $httpmethod." + fi + + _debug "_ret" "$_ret" + printf "%s" "$response" + return $_ret +} From 47c33d0344208d0bb47f173d64672e69fc18ac37 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Tue, 8 Oct 2019 16:29:23 +0200 Subject: [PATCH 0454/2234] Cleanup/ removed private function _get_root Function _get_root() copied from acme.sh and is not needed here. Other cleanup as recommended by acme.sh test bot. --- dnsapi/dns_miab.sh | 71 +++++++++++----------------------------------- 1 file changed, 17 insertions(+), 54 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index b0a52d7e..b68f6705 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -1,16 +1,16 @@ #!/usr/bin/env sh -#Name: dns_miab.sh +# Name: dns_miab.sh # -#Authors: -# Darven Dissek 2018 -# William Gertz 2019 +# Authors: +# Darven Dissek 2018 +# William Gertz 2019 # -# Thanks to Neil Pang for the code reused from acme.sh from HTTP-01 validation -# used to communicate with the MailintheBox Custom DNS API -#Report Bugs here: -# https://github.com/billgertz/MIAB_dns_api (for dns_miab.sh) -# https://github.com/Neilpang/acme.sh (for acme.sh) +# Thanks to Neil Pang for the code reused from acme.sh from HTTP-01 validation +# used to communicate with the MailintheBox Custom DNS API +# Report Bugs here: +# https://github.com/billgertz/MIAB_dns_api (for dns_miab.sh) +# https://github.com/Neilpang/acme.sh (for acme.sh) # ######## Public functions ##################### @@ -41,9 +41,9 @@ dns_miab_add() { fi #save the credentials to the account conf file. - _saveaccountconf_mutable MIAB_Username "$MIAB_Username" - _saveaccountconf_mutable MIAB_Password "$MIAB_Password" - _saveaccountconf_mutable MIAB_Server "$MIAB_Server" + _saveaccountconf_mutable MIAB_Username "$MIAB_Username" + _saveaccountconf_mutable MIAB_Password "$MIAB_Password" + _saveaccountconf_mutable MIAB_Server "$MIAB_Server" baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt" @@ -61,7 +61,6 @@ dns_miab_add() { _err "$result" return 1 fi - } #Usage: fulldomain txtvalue @@ -92,16 +91,16 @@ dns_miab_rm() { fi #save the credentials to the account conf file. - _saveaccountconf_mutable MIAB_Username "$MIAB_Username" - _saveaccountconf_mutable MIAB_Password "$MIAB_Password" - _saveaccountconf_mutable MIAB_Server "$MIAB_Server" + _saveaccountconf_mutable MIAB_Username "$MIAB_Username" + _saveaccountconf_mutable MIAB_Password "$MIAB_Password" + _saveaccountconf_mutable MIAB_Server "$MIAB_Server" baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt" #Remove the challenge record result="$(_miab_post "$txtvalue" "$baseurl" "" "DELETE" "" "$MIAB_Username" "$MIAB_Password")" - _debug result $result + _debug result "$result" #check if result was good if _contains "$result" "updated DNS"; then @@ -115,43 +114,7 @@ dns_miab_rm() { } #################### 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 - - 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" "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") - - if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _domain=$h - return 0 - fi - - return 1 - fi - - p=$i - i=$(_math "$i" + 1) - done - - return 1 -} - +# # post changes to MIAB dns (taken from acme.sh) _miab_post() { body="$1" From a4ec9f8b44a0ae2a22c4af44d423b58e73fa6fdf Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Tue, 8 Oct 2019 16:34:56 +0200 Subject: [PATCH 0455/2234] Fixed weird spacing on line 180 Um, fixed. --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index b68f6705..c91bf3c8 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -180,7 +180,7 @@ _miab_post() { if [ "$needbase64" ]; then - if [ "$httpmethod" = "POST" ]; then + if [ "$httpmethod" = "POST" ]; then if [ "$_postContentType" ]; then response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" else From 835f9aad91e9995e688b1be8e827f0a6443af746 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Tue, 8 Oct 2019 16:47:32 +0200 Subject: [PATCH 0456/2234] Um that's a wee bit of nit pick. 'Errant' space removed on blank line on line 147. --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index c91bf3c8..8786634d 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -144,7 +144,7 @@ _miab_post() { fi _debug "_CURL" "$_CURL" - + if [ "$needbase64" ]; then if [ "$_postContentType" ]; then response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" From c06ec7c6bae0cc40daede2121d006b764e73cb47 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Tue, 8 Oct 2019 18:15:16 +0200 Subject: [PATCH 0457/2234] Removed parameters and unused code for _miab_post Ok, should have noticed earlier that the calls to the private function _miab_post() never used the _needbase64_ or the __postContentType parameters. Parameters and code to handle them has been factored out. --- dnsapi/dns_miab.sh | 70 +++++++++------------------------------------- 1 file changed, 13 insertions(+), 57 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 8786634d..df2ca6e2 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -48,7 +48,7 @@ dns_miab_add() { baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt" #Add the challenge record - result="$(_miab_post "$txtvalue" "$baseurl" "" "POST" "" "$MIAB_Username" "$MIAB_Password")" + result="$(_miab_post "$txtvalue" "$baseurl" "POST" "$MIAB_Username" "$MIAB_Password")" _debug result "$result" @@ -91,14 +91,14 @@ dns_miab_rm() { fi #save the credentials to the account conf file. - _saveaccountconf_mutable MIAB_Username "$MIAB_Username" - _saveaccountconf_mutable MIAB_Password "$MIAB_Password" - _saveaccountconf_mutable MIAB_Server "$MIAB_Server" + _saveaccountconf_mutable MIAB_Username "$MIAB_Username" + _saveaccountconf_mutable MIAB_Password "$MIAB_Password" + _saveaccountconf_mutable MIAB_Server "$MIAB_Server" baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt" #Remove the challenge record - result="$(_miab_post "$txtvalue" "$baseurl" "" "DELETE" "" "$MIAB_Username" "$MIAB_Password")" + result="$(_miab_post "$txtvalue" "$baseurl" "DELETE" "$MIAB_Username" "$MIAB_Password")" _debug result "$result" @@ -119,11 +119,9 @@ dns_miab_rm() { _miab_post() { body="$1" _post_url="$2" - needbase64="$3" - httpmethod="$4" - _postContentType="$5" - username="$6" - password="$7" + httpmethod="$3" + username="$4" + password="$5" if [ -z "$httpmethod" ]; then httpmethod="POST" @@ -144,21 +142,7 @@ _miab_post() { fi _debug "_CURL" "$_CURL" - - if [ "$needbase64" ]; then - if [ "$_postContentType" ]; then - response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" - else - response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" - fi - else - if [ "$_postContentType" ]; then - response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" - else - response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" - fi - fi - + response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" _ret="$?" if [ "$_ret" != "0" ]; then @@ -178,40 +162,12 @@ _miab_post() { _debug "_WGET" "$_WGET" - if [ "$needbase64" ]; then - - if [ "$httpmethod" = "POST" ]; then - if [ "$_postContentType" ]; then - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" - else - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" - fi - else - if [ "$_postContentType" ]; then - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" - else - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)" - fi - fi - + if [ "$httpmethod" = "POST" ]; then + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" else - - if [ "$httpmethod" = "POST" ]; then - if [ "$_postContentType" ]; then - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" - else - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" - fi - else - if [ "$_postContentType" ]; then - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")" - else - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")" - fi - fi - + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")" fi - + _ret="$?" if [ "$_ret" = "8" ]; then From f323ced4ca0d46c4119a8c4ac3ce67125edce149 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Tue, 8 Oct 2019 18:24:14 +0200 Subject: [PATCH 0458/2234] Style issues and orphan _postContentType debug fix Fixed spacing and removed unneeded debug for _postContenetType --- dnsapi/dns_miab.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index df2ca6e2..e2f4d593 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -91,9 +91,9 @@ dns_miab_rm() { fi #save the credentials to the account conf file. - _saveaccountconf_mutable MIAB_Username "$MIAB_Username" - _saveaccountconf_mutable MIAB_Password "$MIAB_Password" - _saveaccountconf_mutable MIAB_Server "$MIAB_Server" + _saveaccountconf_mutable MIAB_Username "$MIAB_Username" + _saveaccountconf_mutable MIAB_Password "$MIAB_Password" + _saveaccountconf_mutable MIAB_Server "$MIAB_Server" baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt" @@ -130,8 +130,7 @@ _miab_post() { _debug $httpmethod _debug "_post_url" "$_post_url" _debug2 "body" "$body" - _debug2 "_postContentType" "$_postContentType" - + _inithttp if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then @@ -167,7 +166,7 @@ _miab_post() { else response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")" fi - + _ret="$?" if [ "$_ret" = "8" ]; then From f64b061a28bf06f7f1586048615cef090b9c09e9 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Tue, 8 Oct 2019 18:46:35 +0200 Subject: [PATCH 0459/2234] Style issue Spaces on blank line on line 133. --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index e2f4d593..d17a1f75 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -130,7 +130,7 @@ _miab_post() { _debug $httpmethod _debug "_post_url" "$_post_url" _debug2 "body" "$body" - + _inithttp if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then From ba7db3edda2c3d4e8265d2c5302b973d6541afd8 Mon Sep 17 00:00:00 2001 From: David Robles Date: Wed, 9 Oct 2019 08:08:05 -0700 Subject: [PATCH 0460/2234] Use more widely supported options for the "tr" command line utility by removing the use of the character class representation option. Fixes #2536 --- dnsapi/dns_freedns.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index e76e6495..bb80dc44 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -303,7 +303,7 @@ _freedns_domain_id() { return 1 fi - domain_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ + domain_id="$(echo "$htmlpage" | tr -d "\r\n" | sed 's//@/g' | tr '@' '\n' \ | grep "$search_domain\|$search_domain(.*)" \ | _egrep_o "edit\.php\?edit_domain_id=[0-9a-zA-Z]+" \ | cut -d = -f 2)" @@ -349,7 +349,7 @@ _freedns_data_id() { return 1 fi - data_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's//@/g' | tr '@' '\n' \ + data_id="$(echo "$htmlpage" | tr -d "\r\n" | sed 's//@/g' | tr '@' '\n' \ | grep "$record_type" \ | grep "$search_domain" \ | _egrep_o "edit\.php\?data_id=[0-9a-zA-Z]+" \ From 252a21e2ae715885e5c45044fe19538e6b009399 Mon Sep 17 00:00:00 2001 From: temoffey Date: Thu, 10 Oct 2019 00:36:34 +0300 Subject: [PATCH 0461/2234] fixed json parse regex for support api gcore_cdn --- deploy/gcore_cdn.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index bbda58ef..a2a35f7b 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -77,15 +77,15 @@ gcore_cdn_deploy() { _debug _regex "$_regex" _resource=$(echo "$_response" | sed 's/},{/},\n{/g' | _egrep_o "$_regex") _debug _resource "$_resource" - _regex=".*\"id\":\([0-9]*\),.*$" + _regex=".*\"id\":\([0-9]*\).*\"rules\".*$" _debug _regex "$_regex" _resourceId=$(echo "$_resource" | sed -n "s/$_regex/\1/p") _debug _resourceId "$_resourceId" - _regex=".*\"sslData\":\([0-9]*\)}.*$" + _regex=".*\"sslData\":\([0-9]*\).*$" _debug _regex "$_regex" _sslDataOld=$(echo "$_resource" | sed -n "s/$_regex/\1/p") _debug _sslDataOld "$_sslDataOld" - _regex=".*\"originGroup\":\([0-9]*\),.*$" + _regex=".*\"originGroup\":\([0-9]*\).*$" _debug _regex "$_regex" _originGroup=$(echo "$_resource" | sed -n "s/$_regex/\1/p") _debug _originGroup "$_originGroup" @@ -101,7 +101,7 @@ gcore_cdn_deploy() { _debug _request "$_request" _response=$(_post "$_request" "https://api.gcdn.co/sslData") _debug _response "$_response" - _regex=".*\"id\":\([0-9]*\),.*$" + _regex=".*\"id\":\([0-9]*\).*$" _debug _regex "$_regex" _sslDataAdd=$(echo "$_response" | sed -n "s/$_regex/\1/p") _debug _sslDataAdd "$_sslDataAdd" From aa6112482d90e17b19127b71d5f12d097e13c485 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Sun, 13 Oct 2019 19:56:04 +0200 Subject: [PATCH 0462/2234] Rewrite to conform to Dev guide Created _get_root() that tests the requested host is a subdomain to the domains hosted on MailinaBox (MIAB) DNS Server. Created common _miab_rest() used with dns_miab_add(), dns_miab_rm() and _get_root(). Also created barbaric _is_json() to test the response given by the MIAB Custom DNS API at least looks like a JSON file. We should add a hint to use _normalizeJson with JSON responses so _startswith, _endswith won't perplexingly fail. --- dnsapi/dns_miab.sh | 273 ++++++++++++++++++++++++--------------------- 1 file changed, 147 insertions(+), 126 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index d17a1f75..313e4eb8 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -6,186 +6,207 @@ # Darven Dissek 2018 # William Gertz 2019 # -# Thanks to Neil Pang for the code reused from acme.sh from HTTP-01 validation -# used to communicate with the MailintheBox Custom DNS API +# Thanks to Neil Pang and other developers here for code reused from acme.sh from DNS-01 +# used to communicate with the MailinaBox Custom DNS API # Report Bugs here: # https://github.com/billgertz/MIAB_dns_api (for dns_miab.sh) # https://github.com/Neilpang/acme.sh (for acme.sh) # ######## Public functions ##################### -#Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_miab_add() { fulldomain=$1 txtvalue=$2 - _info "Using miab" + _info "Using miab challange add" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" - MIAB_Username="${MIAB_Username:-$(_readaccountconf_mutable MIAB_Username)}" - MIAB_Password="${MIAB_Password:-$(_readaccountconf_mutable MIAB_Password)}" - MIAB_Server="${MIAB_Server:-$(_readaccountconf_mutable MIAB_Server)}" - - #debug log the environmental variables - _debug MIAB_Username "$MIAB_Username" - _debug MIAB_Password "$MIAB_Password" - _debug MIAB_Server "$MIAB_Server" - - if [ -z "$MIAB_Username" ] || [ -z "$MIAB_Password" ] || [ -z "$MIAB_Server" ]; then - MIAB_Username="" - MIAB_Password="" - MIAB_Server="" - _err "You didn't specify MIAB_Username or MIAB_Password or MIAB_Server." - _err "Please try again." + #retrieve MIAB environemt vars + if ! _retrieve_miab_env; then + return 1 + fi + + #check domain and seperate into doamin and host + if ! _get_root "$fulldomain"; then + _err "Cannot find any part of ${fulldomain} is hosted on ${MIAB_Server}" return 1 fi - #save the credentials to the account conf file. - _saveaccountconf_mutable MIAB_Username "$MIAB_Username" - _saveaccountconf_mutable MIAB_Password "$MIAB_Password" - _saveaccountconf_mutable MIAB_Server "$MIAB_Server" + _debug2 _sub_domain "$_sub_domain" + _debug2 _domain "$_domain" - baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt" - - #Add the challenge record - result="$(_miab_post "$txtvalue" "$baseurl" "POST" "$MIAB_Username" "$MIAB_Password")" - - _debug result "$result" + #add the challenge record + _api_path="custom/${fulldomain}/txt" + _miab_rest "$txtvalue" "$_api_path" "POST" #check if result was good - if _contains "$result" "updated DNS"; then + if _contains "$response" "updated DNS"; then _info "Successfully created the txt record" return 0 else - _err "Error encountered during record addition" - _err "$result" + _err "Error encountered during record add" + _err "$response" return 1 fi } -#Usage: fulldomain txtvalue -#Remove the txt record after validation. +#Usage: dns_miab_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_miab_rm() { fulldomain=$1 txtvalue=$2 - _info "Using miab" + + _info "Using miab challage delete" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" - MIAB_Username="${MIAB_Username:-$(_readaccountconf_mutable MIAB_Username)}" - MIAB_Password="${MIAB_Password:-$(_readaccountconf_mutable MIAB_Password)}" - MIAB_Server="${MIAB_Server:-$(_readaccountconf_mutable MIAB_Server)}" + #retrieve MIAB environemt vars + if ! _retrieve_miab_env; then + return 1 + fi - #debug log the environmental variables - _debug MIAB_Username "$MIAB_Username" - _debug MIAB_Password "$MIAB_Password" - _debug MIAB_Server "$MIAB_Server" - - if [ -z "$MIAB_Username" ] || [ -z "$MIAB_Password" ] || [ -z "$MIAB_Server" ]; then - MIAB_Username="" - MIAB_Password="" - MIAB_Server="" - _err "You didn't specify MIAB_Username or MIAB_Password or MIAB_Server." - _err "Please try again." + #check domain and seperate into doamin and host + if ! _get_root "$fulldomain"; then + _err "Cannot find any part of ${fulldomain} is hosted on ${MIAB_Server}" return 1 fi - #save the credentials to the account conf file. - _saveaccountconf_mutable MIAB_Username "$MIAB_Username" - _saveaccountconf_mutable MIAB_Password "$MIAB_Password" - _saveaccountconf_mutable MIAB_Server "$MIAB_Server" - - baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt" + _debug2 _sub_domain "$_sub_domain" + _debug2 _domain "$_domain" #Remove the challenge record - result="$(_miab_post "$txtvalue" "$baseurl" "DELETE" "$MIAB_Username" "$MIAB_Password")" - - _debug result "$result" + _api_path="custom/${fulldomain}/txt" + _miab_rest "$txtvalue" "$_api_path" "DELETE" #check if result was good - if _contains "$result" "updated DNS"; then - _info "Successfully created the txt record" + if _contains "$response" "updated DNS"; then + _info "Successfully removed the txt record" return 0 else - _err "Error encountered during record addition" - _err "$result" + _err "Error encountered during record remove" + _err "$response" return 1 fi } #################### Private functions below ################################## # -# post changes to MIAB dns (taken from acme.sh) -_miab_post() { - body="$1" - _post_url="$2" - httpmethod="$3" - username="$4" - password="$5" +#Usage: _get_root _acme-challenge.www.domain.com +#Returns: +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + _passed_domain=$1 + _debug _passed_domain "$_passed_domain" + _i=2 + _p=1 - if [ -z "$httpmethod" ]; then - httpmethod="POST" + #get the zones hosed on MIAB server, must be a json stream + _miab_rest "" "zones" "GET" + + _info "_startswith test:$(_startswith "test" "t")" + _info "_endstest test:$(_endswith "test" "t")" + + if ! _is_json "$response"; then + _err "ERROR fetching domain list" + _err "$response" + return 1 fi - _debug $httpmethod - _debug "_post_url" "$_post_url" - _debug2 "body" "$body" + #cycle through the passed domain seperating out a test domain discarding + # the subdomain by marching thorugh the dots + while true; do + _test_domain=$(printf "%s" "$_passed_domain" | cut -d . -f ${_i}-100) + _debug _test_domain "$_test_domain" - _inithttp - - if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then - _CURL="$_ACME_CURL" - - if [ "$HTTPS_INSECURE" ]; then - _CURL="$_CURL --insecure " + if [ -z "$_test_domain" ]; then + return 1 fi - _debug "_CURL" "$_CURL" - response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" - _ret="$?" - - if [ "$_ret" != "0" ]; then - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" - if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then - _err "Here is the curl dump log:" - _err "$(cat "$_CURL_DUMP")" - fi + #report found if the test domain is in the json response and + # report the subdomain + if _contains "$response" "\"$_test_domain\""; then + _sub_domain=$(printf "%s" "$_passed_domain" | cut -d . -f 1-${_p}) + _domain=${_test_domain} + return 0 fi - elif [ "$_ACME_WGET" ]; then - _WGET="$_ACME_WGET" + #cycle to the next dot in the passed domain + _p=${_i} + _i=$(_math "$_i" + 1) + done - if [ "$HTTPS_INSECURE" ]; then - _WGET="$_WGET --no-check-certificate " - fi - - _debug "_WGET" "$_WGET" - - if [ "$httpmethod" = "POST" ]; then - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")" - else - response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")" - fi - - _ret="$?" - - if [ "$_ret" = "8" ]; then - _ret=0 - _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." - fi - - if [ "$_ret" != "0" ]; then - _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" - fi - - _sed_i "s/^ *//g" "$HTTP_HEADER" - - else - _ret="$?" - _err "Neither curl nor wget was found, cannot do $httpmethod." - fi - - _debug "_ret" "$_ret" - printf "%s" "$response" - return $_ret + return 1 +} + +#Usage: _retrieve_miab_env +#Returns (from store or environment variables): +# MIAB_Username +# MIAB_Password +# MIAB_Server +#retrieve MIAB environment variables, report errors and quit if problems +_retrieve_miab_env() { + MIAB_Username="${MIAB_Username:-$(_readaccountconf_mutable MIAB_Username)}" + MIAB_Password="${MIAB_Password:-$(_readaccountconf_mutable MIAB_Password)}" + MIAB_Server="${MIAB_Server:-$(_readaccountconf_mutable MIAB_Server)}" + + #debug log the environmental variables + _debug MIAB_Username "$MIAB_Username" + _debug MIAB_Password "$MIAB_Password" + _debug MIAB_Server "$MIAB_Server" + + #check if MIAB environemt vars set and quit if not + if [ -z "$MIAB_Username" ] || [ -z "$MIAB_Password" ] || [ -z "$MIAB_Server" ]; then + _err "You didn't specify one or more of MIAB_Username, MIAB_Password or MIAB_Server." + _err "Please check these environment variables and try again." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable MIAB_Username "$MIAB_Username" + _saveaccountconf_mutable MIAB_Password "$MIAB_Password" + _saveaccountconf_mutable MIAB_Server "$MIAB_Server" +} + +#Useage: _miab_rest "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" "custom/_acme-challenge.www.domain.com/txt "POST" +#Returns: "updated DNS: domain.com" +#rest interface MIAB dns +_miab_rest() { + _data="$1" + _api_path="$2" + _httpmethod="$3" + + #encode username and password for url + _username="$(printf "%s" "$MIAB_Username" | _url_encode)" + _password="$(printf "%s" "$MIAB_Password" | _url_encode)" + _url="https://${_username}:${_password}@${MIAB_Server}/admin/dns/${_api_path}" + + _debug2 _data "$_data" + _debug _api_path "$_api_path" + _debug2 _url "$_url" + _debug _httpmethod "$_httpmethod" + + if [ "$_httpmethod" = "GET" ]; then + response="$(_get "$_url")" + else + response="$(_post "$_data" "$_url" "" "$_httpmethod")" + fi + + _retcode="$?" + + if [ "$_retcode" != "0" ]; then + _err "MAAB REST authentication failed on $_httpmethod" + return 1 + fi + + _debug response "$response" + return 0 +} + +#Usage: _is_json "\[\n "mydomain.com"\n]" +#Reurns "\[\n "mydomain.com"\n]" +#returns the string if it begins and ends with square braces +_is_json() { + _str="$(echo "$1" | _normalizeJson)" + echo "$_str" | grep '^\[.*\]$' >/dev/null 2>&1 } From 7ec52145e807fc15dfb6c1e501183f14b58f3d80 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Sun, 13 Oct 2019 20:02:03 +0200 Subject: [PATCH 0463/2234] Space style changes. Local copy of shellcheck somehow missed these, odd. --- dnsapi/dns_miab.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 313e4eb8..7630a744 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -23,10 +23,10 @@ dns_miab_add() { _debug txtvalue "$txtvalue" #retrieve MIAB environemt vars - if ! _retrieve_miab_env; then - return 1 - fi - + if ! _retrieve_miab_env; then + return 1 + fi + #check domain and seperate into doamin and host if ! _get_root "$fulldomain"; then _err "Cannot find any part of ${fulldomain} is hosted on ${MIAB_Server}" @@ -61,9 +61,9 @@ dns_miab_rm() { _debug txtvalue "$txtvalue" #retrieve MIAB environemt vars - if ! _retrieve_miab_env; then - return 1 - fi + if ! _retrieve_miab_env; then + return 1 + fi #check domain and seperate into doamin and host if ! _get_root "$fulldomain"; then @@ -76,7 +76,7 @@ dns_miab_rm() { #Remove the challenge record _api_path="custom/${fulldomain}/txt" - _miab_rest "$txtvalue" "$_api_path" "DELETE" + _miab_rest "$txtvalue" "$_api_path" "DELETE" #check if result was good if _contains "$response" "updated DNS"; then From 9af85f5a7eedb7d3fd36a01834492e50e8c65138 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Mon, 14 Oct 2019 00:01:25 +0200 Subject: [PATCH 0464/2234] Updated to use _H1 Authorization: Basic Updated to use suggested export _H1 env var to supply Authorization Basic credentials. This undocumented support for Basic Authorization, ContentType, etc. needs to be documented in DNSAPI Dev Guide. Removed two stray debugging lines. --- dnsapi/dns_miab.sh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 7630a744..25a8ffc7 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -26,7 +26,7 @@ dns_miab_add() { if ! _retrieve_miab_env; then return 1 fi - + #check domain and seperate into doamin and host if ! _get_root "$fulldomain"; then _err "Cannot find any part of ${fulldomain} is hosted on ${MIAB_Server}" @@ -104,9 +104,6 @@ _get_root() { #get the zones hosed on MIAB server, must be a json stream _miab_rest "" "zones" "GET" - _info "_startswith test:$(_startswith "test" "t")" - _info "_endstest test:$(_endswith "test" "t")" - if ! _is_json "$response"; then _err "ERROR fetching domain list" _err "$response" @@ -176,14 +173,15 @@ _miab_rest() { _api_path="$2" _httpmethod="$3" - #encode username and password for url - _username="$(printf "%s" "$MIAB_Username" | _url_encode)" - _password="$(printf "%s" "$MIAB_Password" | _url_encode)" - _url="https://${_username}:${_password}@${MIAB_Server}/admin/dns/${_api_path}" + #encode username and password for basic authentication + _credentials="$(printf "%s" "$MIAB_Username:$MIAB_Password" | _base64)" + export _H1="Authorization: Basic $_credentials" + _url="https://${MIAB_Server}/admin/dns/${_api_path}" _debug2 _data "$_data" _debug _api_path "$_api_path" _debug2 _url "$_url" + _debug2 _credentails "$_credentials" _debug _httpmethod "$_httpmethod" if [ "$_httpmethod" = "GET" ]; then @@ -195,7 +193,7 @@ _miab_rest() { _retcode="$?" if [ "$_retcode" != "0" ]; then - _err "MAAB REST authentication failed on $_httpmethod" + _err "MIAB REST authentication failed on $_httpmethod" return 1 fi From 933d49b0b09cc886402c59e08de1651e8121d822 Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Mon, 14 Oct 2019 00:06:08 +0200 Subject: [PATCH 0465/2234] Style space change Extra space on empty line 27. --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 25a8ffc7..23ff6cee 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -26,7 +26,7 @@ dns_miab_add() { if ! _retrieve_miab_env; then return 1 fi - + #check domain and seperate into doamin and host if ! _get_root "$fulldomain"; then _err "Cannot find any part of ${fulldomain} is hosted on ${MIAB_Server}" From dc5c220e8fc0d605a9c4434b421b9d33960b149c Mon Sep 17 00:00:00 2001 From: rserpent <53250916+rserpent@users.noreply.github.com> Date: Wed, 16 Oct 2019 15:12:21 +0500 Subject: [PATCH 0466/2234] dns_nic init --- dnsapi/dns_nic.sh | 185 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 dnsapi/dns_nic.sh diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh new file mode 100644 index 00000000..277cc2d8 --- /dev/null +++ b/dnsapi/dns_nic.sh @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +#NIC_Token="sdfsdfsdfljlbjkljlkjsdfoiwjedfglgkdlfgkfgldfkg" +# +#NIC_Username="000000/NIC-D" + +#NIC_Password="xxxxxxx" + +NIC_Api="https://api.nic.ru" + +dns_nic_add() { + fulldomain="${1}" + txtvalue="${2}" + + NIC_Token="${NIC_Token:-$(_readaccountconf_mutable NIC_Token)}" + NIC_Username="${NIC_Username:-$(_readaccountconf_mutable NIC_Username)}" + NIC_Password="${NIC_Password:-$(_readaccountconf_mutable NIC_Password)}" + if [ -z "$NIC_Token" ] || [ -z "$NIC_Username" ] || [ -z "$NIC_Password" ]; then + NIC_Token="" + NIC_Username="" + NIC_Password="" + _err "You must export variables: NIC_Token, NIC_Username and NIC_Password" + return 1 + fi + + _saveaccountconf_mutable NIC_Customer "$NIC_Token" + _saveaccountconf_mutable NIC_Username "$NIC_Username" + _saveaccountconf_mutable NIC_Password "$NIC_Password" + + if ! _nic_get_authtoken "$NIC_Username" "$NIC_Password" "$NIC_Token"; then + _err "get NIC auth token failed" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug _service "$_service" + + _info "Adding record" + if ! _nic_rest PUT "services/$_service/zones/$_domain/records" "$_sub_domainTXT$txtvalue"; then + _err "Add TXT record error" + return 1 + fi + + if ! _nic_rest POST "services/$_service/zones/$_domain/commit" ""; then + return 1 + fi + _info "Added, OK" +} + +dns_nic_rm() { + fulldomain="${1}" + txtvalue="${2}" + + NIC_Token="${NIC_Token:-$(_readaccountconf_mutable NIC_Token)}" + NIC_Username="${NIC_Username:-$(_readaccountconf_mutable NIC_Username)}" + NIC_Password="${NIC_Password:-$(_readaccountconf_mutable NIC_Password)}" + if [ -z "$NIC_Token" ] || [ -z "$NIC_Username" ] || [ -z "$NIC_Password" ]; then + NIC_Token="" + NIC_Username="" + NIC_Password="" + _err "You must export variables: NIC_Token, NIC_Username and NIC_Password" + return 1 + fi + + if ! _nic_get_authtoken "$NIC_Username" "$NIC_Password" "$NIC_Token"; then + _err "get NIC auth token failed" + return 1 + fi + + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug _service "$_service" + + if ! _nic_rest GET "services/$_service/zones/$_domain/records"; then + _err "Get records error" + return 1 + fi + + _domain_id=$(printf "%s" "$response" | grep "$_sub_domain" | grep "$txtvalue" | sed -r "s/.*"; then + error=$(printf "%s" "$response" | grep "error code" | sed -r "s/.*(.*)<\/error>/\1/g") + _err "Error: $error" + return 1 + fi + + if ! _contains "$response" "success"; then + return 1 + fi + _debug2 response "$response" + return 0 +} From e00f0b4cf1df691c4baf0293d49d380bf98b5e94 Mon Sep 17 00:00:00 2001 From: rserpent <53250916+rserpent@users.noreply.github.com> Date: Wed, 16 Oct 2019 15:31:50 +0500 Subject: [PATCH 0467/2234] Update dns_nic.sh --- dnsapi/dns_nic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 277cc2d8..b92d2ac9 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -113,7 +113,7 @@ _nic_get_authtoken() { export _H1="Authorization: Basic $token" export _H2="Content-Type: application/x-www-form-urlencoded" - res="$(_post "grant_type=password&username=$username&password=$password&scope=%28GET%7CPUT%7CPOST%7CDELETE%29%3A%2Fdns-master%2F.%2B" "$NIC_Api/oauth/token" "" "POST")" + res=$(_post "grant_type=password&username=$username&password=$password&scope=%28GET%7CPUT%7CPOST%7CDELETE%29%3A%2Fdns-master%2F.%2B" "$NIC_Api/oauth/token" "" "POST") if _contains "$res" "access_token"; then _auth_token=$(printf "%s" "$res" | cut -d , -f2 | tr -d "\"" | sed "s/access_token://") _info "Token received" From ffa5472b31b69cedae6e29bc10edf689176d54a0 Mon Sep 17 00:00:00 2001 From: rserpent <53250916+rserpent@users.noreply.github.com> Date: Wed, 16 Oct 2019 16:25:38 +0500 Subject: [PATCH 0468/2234] fix whitespaces --- dnsapi/dns_nic.sh | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index b92d2ac9..493b05bc 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -79,7 +79,7 @@ dns_nic_rm() { _err "Invalid domain" return 1 fi - + _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" _debug _service "$_service" @@ -129,28 +129,28 @@ _get_root() { p=1 if ! _nic_rest GET "zones"; then - return 1 + return 1 fi _all_domains=$(printf "%s" "$response" | grep "idn-name" | sed -r "s/.*idn-name=\"(.*)\" name=.*/\1/g") _debug2 _all_domains "$_all_domains" while true; do - h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) - _debug h "$h" + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + _debug h "$h" - if [ -z "$h" ]; then - return 1 - fi + if [ -z "$h" ]; then + return 1 + fi - if _contains "$_all_domains" "^$h$"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _domain=$h - _service=$(printf "%s" "$response" | grep "$_domain" | sed -r "s/.*service=\"(.*)\".*$/\1/") - return 0 - fi - p="$i" - i=$(_math "$i" + 1) + if _contains "$_all_domains" "^$h$"; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + _service=$(printf "%s" "$response" | grep "$_domain" | sed -r "s/.*service=\"(.*)\".*$/\1/") + return 0 + fi + p="$i" + i=$(_math "$i" + 1) done return 1 } @@ -165,20 +165,20 @@ _nic_rest() { export _H2="Authorization: Bearer $_auth_token" if [ "$m" != "GET" ]; then - _debug data "$data" - response=$(_post "$data" "$NIC_Api/dns-master/$ep" "" "$m") + _debug data "$data" + response=$(_post "$data" "$NIC_Api/dns-master/$ep" "" "$m") else - response=$(_get "$NIC_Api/dns-master/$ep") + response=$(_get "$NIC_Api/dns-master/$ep") fi if _contains "$response" ""; then - error=$(printf "%s" "$response" | grep "error code" | sed -r "s/.*(.*)<\/error>/\1/g") - _err "Error: $error" - return 1 + error=$(printf "%s" "$response" | grep "error code" | sed -r "s/.*(.*)<\/error>/\1/g") + _err "Error: $error" + return 1 fi if ! _contains "$response" "success"; then - return 1 + return 1 fi _debug2 response "$response" return 0 From 573c8f3b13e002cc948adfee840005cc18982098 Mon Sep 17 00:00:00 2001 From: David Robles Date: Wed, 23 Oct 2019 07:20:01 -0700 Subject: [PATCH 0469/2234] Use more widely supported options for the "tr" command line utility by removing the use of the character class representation option. [:space:] => "\t\r\n\v\f" --- dnsapi/dns_freedns.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 81b1de5b..6fac0c21 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -303,7 +303,7 @@ _freedns_domain_id() { return 1 fi - domain_id="$(echo "$htmlpage" | tr -d "\r\n" | sed 's//@/g' | tr '@' '\n' \ + domain_id="$(echo "$htmlpage" | tr -d "\t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ | grep "$search_domain\|$search_domain(.*)" \ | sed -n 's/.*\(edit\.php?edit_domain_id=[0-9a-zA-Z]*\).*/\1/p' \ | cut -d = -f 2)" @@ -349,7 +349,7 @@ _freedns_data_id() { return 1 fi - data_id="$(echo "$htmlpage" | tr -d "\r\n" | sed 's//@/g' | tr '@' '\n' \ + data_id="$(echo "$htmlpage" | tr -d "\t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ | grep "$record_type" \ | grep "$search_domain" \ | sed -n 's/.*\(edit\.php?data_id=[0-9a-zA-Z]*\).*/\1/p' \ From 18ad01533b3b5d0cf51f9e72464940e7a080d880 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Oct 2019 09:19:18 +0800 Subject: [PATCH 0470/2234] add space. fix https://github.com/Neilpang/acme.sh/pull/2553 --- dnsapi/dns_freedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 6fac0c21..32d240fc 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -303,7 +303,7 @@ _freedns_domain_id() { return 1 fi - domain_id="$(echo "$htmlpage" | tr -d "\t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ + domain_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ | grep "$search_domain\|$search_domain(.*)" \ | sed -n 's/.*\(edit\.php?edit_domain_id=[0-9a-zA-Z]*\).*/\1/p' \ | cut -d = -f 2)" From c0449a3ed22e102cd68f959460619dd9ceff18cc Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Fri, 25 Oct 2019 08:04:20 +0200 Subject: [PATCH 0471/2234] Only save Attributes if it is set --- dnsapi/dns_opnsense.sh | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index ff6f8a54..ea9677b7 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -220,22 +220,32 @@ _opns_check_auth() { if [ -z "$OPNs_Host" ]; then OPNs_Host="localhost" _err "You don't specify OPNsense address." + return 1 + else + _saveaccountconf_mutable OPNs_Host "$OPNs_Host" fi if [ -z "$OPNs_Port" ]; then OPNs_Port="443" - _err "You don't specify OPNsense Port." + else + _saveaccountconf_mutable OPNs_Port "$OPNs_Port" fi if [ -z "$OPNs_Api_Insecure" ]; then OPNs_Api_Insecure="0" + else + #save the api addr and key to the account conf file. + _saveaccountconf_mutable OPNs_Api_Insecure "$OPNs_Api_Insecure" fi + export HTTPS_INSECURE="${OPNs_Api_Insecure}" if [ -z "$OPNs_Key" ]; then OPNs_Key="" _err "You don't specify OPNsense api key id." _err "Please set you OPNs_Key and try again." return 1 + else + _saveaccountconf_mutable OPNs_Key "$OPNs_Key" fi if [ -z "$OPNs_Token" ]; then @@ -243,15 +253,10 @@ _opns_check_auth() { _err "You don't specify OPNsense token." _err "Please create you OPNs_Token and try again." return 1 + else + _saveaccountconf_mutable OPNs_Token "$OPNs_Token" fi - #save the api addr and key to the account conf file. - _saveaccountconf_mutable OPNs_Host "$OPNs_Host" - _saveaccountconf_mutable OPNs_Port "$OPNs_Port" - _saveaccountconf_mutable OPNs_Key "$OPNs_Key" - _saveaccountconf_mutable OPNs_Token "$OPNs_Token" - _saveaccountconf_mutable OPNs_Api_Insecure "$OPNs_Api_Insecure" - export HTTPS_INSECURE="${OPNs_Api_Insecure}" if ! _opns_rest "GET" "/general/get"; then _err "Can't Access OPNsense" From 430956d3043d0a958fa696fe51a1d88f5c77d48d Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Fri, 25 Oct 2019 08:13:35 +0200 Subject: [PATCH 0472/2234] Fix whitespaces --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index ea9677b7..abd85abb 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -234,7 +234,7 @@ _opns_check_auth() { if [ -z "$OPNs_Api_Insecure" ]; then OPNs_Api_Insecure="0" else - #save the api addr and key to the account conf file. + #save the api addr and key to the account conf file. _saveaccountconf_mutable OPNs_Api_Insecure "$OPNs_Api_Insecure" fi export HTTPS_INSECURE="${OPNs_Api_Insecure}" From b85c1a88614b531698133565643e618482904f06 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Fri, 25 Oct 2019 08:22:15 +0200 Subject: [PATCH 0473/2234] Fix additional line --- dnsapi/dns_opnsense.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index abd85abb..0f7cdea6 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -257,7 +257,6 @@ _opns_check_auth() { _saveaccountconf_mutable OPNs_Token "$OPNs_Token" fi - if ! _opns_rest "GET" "/general/get"; then _err "Can't Access OPNsense" return 1 From 1d1f61613c539eaa0eddf8b10e8a1dea47824b8a Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Fri, 25 Oct 2019 09:25:29 +0200 Subject: [PATCH 0474/2234] Check for root domain via API --- dnsapi/dns_leaseweb.sh | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 976ad5ac..6a75ef33 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -88,14 +88,24 @@ _get_root() { i=$(_math "$i" - 1) while true; do - h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + h=$(printf "%s" "$domain" | cut -d . -f $i-100) if [ -z "$h" ]; then - return 1 + return 1 #not valid domain + fi + + #Check API if domain exists + if _lsw_api "GET" "$h"; then + if [ "$_code" = "200"]; then + _domain="$h" + return 0 + fi + fi + i=$(_math "$i" - 1) + if (( $i < 1)); then + return 1 #not found fi - _domain="$h" - return 0 done - _debug "$domain not found" + return 1 } @@ -109,6 +119,14 @@ _lsw_api() { export _H2="Content-Type: application/json" export _H1="X-Lsw-Auth: ${LSW_Key}" + if [ "$cmd" = "GET" ]; then + response="$(_get "$LSW_API/$domain")" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + _debug "http response code $_code" + _debug response "$response" + return 0 + fi + if [ "$cmd" = "POST" ]; then data="{\"name\": \"$fulldomain.\",\"type\": \"TXT\",\"content\": [\"$txtvalue\"],\"ttl\": 60}" response="$(_post "$data" "$LSW_API/$domain/resourceRecordSets" "$data" "POST")" From e10f447b5b6b56c8742136f1c288dce32c392f41 Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Fri, 25 Oct 2019 11:42:15 +0200 Subject: [PATCH 0475/2234] Fixed some bugs, tested and working --- dnsapi/dns_leaseweb.sh | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 6a75ef33..cb49ce7b 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -83,19 +83,20 @@ dns_leaseweb_rm() { # returns # _domain=domain.com _get_root() { - domain=$1 - i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)" + rdomain=$1 + i="$(echo "$rdomain" | tr '.' ' ' | wc -w)" i=$(_math "$i" - 1) while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$rdomain" | cut -d . -f $i-100) + _debug h "$h" if [ -z "$h" ]; then return 1 #not valid domain fi #Check API if domain exists if _lsw_api "GET" "$h"; then - if [ "$_code" = "200"]; then + if [ "$_code" = "200" ]; then _domain="$h" return 0 fi @@ -111,16 +112,16 @@ _get_root() { _lsw_api() { cmd=$1 - domain=$2 - fulldomain=$3 - txtvalue=$4 + data=$2 + fd=$3 + tvalue=$4 # Construct the HTTP Authorization header export _H2="Content-Type: application/json" export _H1="X-Lsw-Auth: ${LSW_Key}" if [ "$cmd" = "GET" ]; then - response="$(_get "$LSW_API/$domain")" + response="$(_get "$LSW_API/$d")" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _debug "http response code $_code" _debug response "$response" @@ -128,8 +129,8 @@ _lsw_api() { fi if [ "$cmd" = "POST" ]; then - data="{\"name\": \"$fulldomain.\",\"type\": \"TXT\",\"content\": [\"$txtvalue\"],\"ttl\": 60}" - response="$(_post "$data" "$LSW_API/$domain/resourceRecordSets" "$data" "POST")" + data="{\"name\": \"$fd.\",\"type\": \"TXT\",\"content\": [\"$tvalue\"],\"ttl\": 60}" + response="$(_post "$data" "$LSW_API/$d/resourceRecordSets" "$data" "POST")" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _debug "http response code $_code" _debug response "$response" @@ -137,7 +138,7 @@ _lsw_api() { fi if [ "$cmd" = "DELETE" ]; then - response="$(_post "" "$LSW_API/$domain/resourceRecordSets/$fulldomain/TXT" "" "DELETE")" + response="$(_post "" "$LSW_API/$d/resourceRecordSets/$fd/TXT" "" "DELETE")" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _debug "http response code $_code" _debug response "$response" From 14f6f9ec94a5d0e68f495fe485610db82b6eefc0 Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Fri, 25 Oct 2019 11:56:27 +0200 Subject: [PATCH 0476/2234] Fixed wrong assignement of var --- dnsapi/dns_leaseweb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index cb49ce7b..31446bec 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -112,7 +112,7 @@ _get_root() { _lsw_api() { cmd=$1 - data=$2 + d=$2 fd=$3 tvalue=$4 From 6d62ae226a82c8c42129a1bae560495790e092d4 Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Fri, 25 Oct 2019 12:14:53 +0200 Subject: [PATCH 0477/2234] Small fix --- dnsapi/dns_leaseweb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 31446bec..72f53b23 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -102,8 +102,8 @@ _get_root() { fi fi i=$(_math "$i" - 1) - if (( $i < 1)); then - return 1 #not found + if (( i < 2 )); then + return 1 #not found, no need to check _acme-challenge.sub.domain in leaseweb api. fi done From 58642286c95fa42d3e78754a9f0253fa70f529bb Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Fri, 25 Oct 2019 13:22:19 +0200 Subject: [PATCH 0478/2234] Fix for SC2039/SC2086 --- dnsapi/dns_leaseweb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 72f53b23..0fd8dcc0 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -88,7 +88,7 @@ _get_root() { i=$(_math "$i" - 1) while true; do - h=$(printf "%s" "$rdomain" | cut -d . -f $i-100) + h=$(printf "%s" "$rdomain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then return 1 #not valid domain @@ -102,7 +102,7 @@ _get_root() { fi fi i=$(_math "$i" - 1) - if (( i < 2 )); then + if $(( i < 2 )); then return 1 #not found, no need to check _acme-challenge.sub.domain in leaseweb api. fi done From e48daffad99af7cd09b0c5860b439de2895541ca Mon Sep 17 00:00:00 2001 From: Rolph Haspers Date: Fri, 25 Oct 2019 13:46:10 +0200 Subject: [PATCH 0479/2234] Fixed error --- dnsapi/dns_leaseweb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 0fd8dcc0..a1d9e749 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -102,7 +102,7 @@ _get_root() { fi fi i=$(_math "$i" - 1) - if $(( i < 2 )); then + if [ "$i" -lt 2 ]; then return 1 #not found, no need to check _acme-challenge.sub.domain in leaseweb api. fi done From d04c6dd3ac03ff6031cbb0d8a2d86645fe9adb20 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Oct 2019 22:31:36 +0800 Subject: [PATCH 0480/2234] fix https://github.com/Neilpang/acme.sh/issues/2557 and https://github.com/Neilpang/acme.sh/issues/2544 --- acme.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index e060e334..37ce15aa 100755 --- a/acme.sh +++ b/acme.sh @@ -4047,7 +4047,18 @@ $_authorizations_map" fi if [ "$ACME_VERSION" = "2" ]; then - response="$(echo "$_authorizations_map" | grep "^$(_idn "$d")," | sed "s/$d,//")" + _idn_d="$(_idn "$d")" + _candindates="$(echo "$_authorizations_map" | grep "^$_idn_d,")" + _debug2 _candindates "$_candindates" + if [ "$(echo "$_candindates" | wc -l)" -gt 1 ]; then + for _can in $_candindates; do + if _startswith "$(echo "$_can" | tr '.' '|')" "$(echo "$_idn_d" | tr '.' '|'),"; then + _candindates="$_can" + break + fi + done + fi + response="$(echo "$_candindates" | sed "s/$_idn_d,//")" _debug2 "response" "$response" if [ -z "$response" ]; then _err "get to authz error." From 2a2877231268cce11ccc624c007ecf3fc2c8dea6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Oct 2019 22:34:33 +0800 Subject: [PATCH 0481/2234] fix https://github.com/Neilpang/acme.sh/pull/2553#issuecomment-546173277 --- dnsapi/dns_freedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 32d240fc..6a0b58ac 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -349,7 +349,7 @@ _freedns_data_id() { return 1 fi - data_id="$(echo "$htmlpage" | tr -d "\t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ + data_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ | grep "$record_type" \ | grep "$search_domain" \ | sed -n 's/.*\(edit\.php?data_id=[0-9a-zA-Z]*\).*/\1/p' \ From df3575217acc5c50d45145672a3008cdb5895cdc Mon Sep 17 00:00:00 2001 From: scottkof Date: Fri, 25 Oct 2019 12:05:15 -0700 Subject: [PATCH 0482/2234] Avoid API throttling errors in AWS DNS plugin --- dnsapi/dns_aws.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 246f4774..54b1bb3a 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -6,6 +6,8 @@ #AWS_SECRET_ACCESS_KEY="xxxxxxx" #This is the Amazon Route53 api wrapper for acme.sh +#All `sleep` commands are included to avoid Route53 throttling, see +#https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests AWS_HOST="route53.amazonaws.com" AWS_URL="https://$AWS_HOST" @@ -43,6 +45,7 @@ dns_aws_add() { _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" + sleep 1 return 1 fi _debug _domain_id "$_domain_id" @@ -51,6 +54,7 @@ dns_aws_add() { _info "Getting existing records for $fulldomain" if ! aws_rest GET "2013-04-01$_domain_id/rrset" "name=$fulldomain&type=TXT"; then + sleep 1 return 1 fi @@ -63,6 +67,7 @@ dns_aws_add() { if [ "$_resource_record" ] && _contains "$response" "$txtvalue"; then _info "The TXT record already exists. Skipping." + sleep 1 return 0 fi @@ -72,9 +77,10 @@ dns_aws_add() { if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then _info "TXT record updated successfully." + sleep 1 return 0 fi - + sleep 1 return 1 } @@ -93,6 +99,7 @@ dns_aws_rm() { _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" + sleep 1 return 1 fi _debug _domain_id "$_domain_id" @@ -101,6 +108,7 @@ dns_aws_rm() { _info "Getting existing records for $fulldomain" if ! aws_rest GET "2013-04-01$_domain_id/rrset" "name=$fulldomain&type=TXT"; then + sleep 1 return 1 fi @@ -109,6 +117,7 @@ dns_aws_rm() { _debug "_resource_record" "$_resource_record" else _debug "no records exist, skip" + sleep 1 return 0 fi @@ -116,9 +125,10 @@ dns_aws_rm() { if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then _info "TXT record deleted successfully." + sleep 1 return 0 fi - + sleep 1 return 1 } From bba5376a3693dc19186edd6ffc42277d45dfa2fb Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Tue, 15 Oct 2019 14:37:38 -0700 Subject: [PATCH 0483/2234] Improve debug capabilities when using bash When calling the _debug3() function will print the filename, function name, and line number when running under bash --- acme.sh | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 041b5b44..46df2ed5 100755 --- a/acme.sh +++ b/acme.sh @@ -265,6 +265,37 @@ _usage() { printf "\n" >&2 } +__debug_bash_helper() { + # At this point only do for --debug 3 + if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -lt "$DEBUG_LEVEL_3" ]; then + echo "" + return + fi + # Return extra debug info when running with bash, otherwise return empty + # string. + if [ -z "${BASH_VERSION}" ]; then + echo "" + return + fi + # We are a bash shell at this point, return the filename, function name, and + # line number as a string + _dbh_saveIFS=$IFS + IFS=" " + # Must use eval or syntax error happens under dash + # Use 'caller 1' as we want one level up the stack as we should be called + # by one of the _debug* functions + eval "_dbh_called=($(caller 1))" + IFS=$_dbh_saveIFS + _dbh_file=${_dbh_called[2]} + if [ -n "${_script_home}" ]; then + # Trim off the _script_home directory name + _dbh_file=${_dbh_file#$_script_home/} + fi + _dbh_function=${_dbh_called[1]} + _dbh_lineno=${_dbh_called[0]} + printf "%-40s " "$_dbh_file:${_dbh_function}:${_dbh_lineno}" +} + _debug() { if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_1" ]; then _log "$@" @@ -273,7 +304,8 @@ _debug() { _syslog "$SYSLOG_DEBUG" "$@" fi if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_1" ]; then - _printargs "$@" >&2 + _bash_debug=$(__debug_bash_helper) + _printargs "${_bash_debug}$@" >&2 fi } @@ -306,7 +338,8 @@ _debug2() { _syslog "$SYSLOG_DEBUG" "$@" fi if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then - _printargs "$@" >&2 + _bash_debug=$(__debug_bash_helper) + _printargs "${_bash_debug}$@" >&2 fi } @@ -338,7 +371,8 @@ _debug3() { _syslog "$SYSLOG_DEBUG" "$@" fi if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_3" ]; then - _printargs "$@" >&2 + _bash_debug=$(__debug_bash_helper) + _printargs "${_bash_debug}$@" >&2 fi } From ed9e196bf68d9eb4494fbd33826eaa2e2a9366bf Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 00:58:33 +0100 Subject: [PATCH 0484/2234] Update list of DNS providers for Plesk XML API --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c8bebc6f..32d30147 100644 --- a/README.md +++ b/README.md @@ -321,6 +321,7 @@ You don't have to do anything manually! 1. acme-dns (https://github.com/joohoi/acme-dns) 1. TELE3 (https://www.tele3.cz) 1. EUSERV.EU (https://www.euserv.eu) +1. Plesk XML API (https://www.plesk.com) And: From 1339b9422d0a7ad0f8c57b549ddb50eff7c18d05 Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 01:04:08 +0100 Subject: [PATCH 0485/2234] Update for dns pleskxml --- dnsapi/README.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 1f394f92..568baba9 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -897,6 +897,26 @@ acme.sh --issue --dns dns_euserv -d example.com -d *.example.com --insecure The `EUSERV_Username` and `EUSERV_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. Please report any issues to https://github.com/initit/acme.sh or to + +## 47. Use Plesk XML API to automatically issue cert + +The plesk plugin uses an XML API to add and remove dns records. +The Plesk API URI (URL), and the user name and password for logging in, must be configured. + +``` +export pleskxml_uri="https://YOUR_PLESK_URI_HERE:8443/enterprise/control/agent.php" + (or probably something similar) +export pleskxml_user="plesk username" +export pleskxml_pass="plesk password" +``` + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_pleskxml -d example.com -d www.example.com +``` + +The `pleskxml_user`, `pleskxml_pass` and `pleskxml_uri` will be saved in `~/.acme.sh/account.conf` and are reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. @@ -917,4 +937,4 @@ See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide # Use lexicon DNS API -https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api \ No newline at end of file +https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api From 274393ac64fbccf994fd240498cb863348388da3 Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 01:09:50 +0100 Subject: [PATCH 0486/2234] Create DNS 01 module for Plesk XML API --- dnsapi/dns_pleskxml | 402 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 dnsapi/dns_pleskxml diff --git a/dnsapi/dns_pleskxml b/dnsapi/dns_pleskxml new file mode 100644 index 00000000..a8a74721 --- /dev/null +++ b/dnsapi/dns_pleskxml @@ -0,0 +1,402 @@ +#!/usr/bin/env sh + +## Name: dns_pleskxml.sh +## Created by Stilez. +## Also uses some code from PR#1832 by @romanlum (https://github.com/Neilpang/acme.sh/pull/1832/files) + +## This DNS01 method uses the Plesk XML API described at: +## https://docs.plesk.com/en-US/12.5/api-rpc/about-xml-api.28709 +## and more specifically: https://docs.plesk.com/en-US/12.5/api-rpc/reference.28784 + +## Note: a DNS ID with host = empty string is OK for this API, see +## https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-dns/managing-dns-records/adding-dns-record.34798 +## For example, to add a TXT record to DNS alias domain "acme-alias.com" would be a valid Plesk action. +## So this API module can handle such a request, if needed. + +## The plesk plugin uses the xml api to add and remvoe the dns records. Therefore the url, username +## and password have to be configured by the user before this module is called. +## +## ``` +## export pleskxml_uri="https://YOUR_PLESK_URI_HERE:8443/enterprise/control/agent.php" +## (or probably something similar) +## export pleskxml_user="plesk username" +## export pleskxml_pass="plesk password" +## ``` + +## Ok, let's issue a cert now: +## ``` +## acme.sh --issue --dns dns_pleskxml -d example.com -d www.example.com +## ``` +## +## The `pleskxml_uri`, `pleskxml_user` and `pleskxml_pass` will be saved in `~/.acme.sh/account.conf` and reused when needed. + + +#################### INTERNAL VARIABLES + NEWLINE ################################## + +pleskxml_init_checks_done=0 + +# Variable containing bare newline - not a style issue +# shellcheck disable=SC1004 +NEWLINE='\ +' + + +#################### API Templates ################################## + +pleskxml_tplt_get_domains="" + # Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh + # Also used to test credentials and URI. + # No args. +pleskxml_tplt_get_dns_records="%s" + # Get all DNS records for a Plesk domain ID. + # ARG = Plesk domain id to query +pleskxml_tplt_add_txt_record="%sTXT%s%s" + # Add a TXT record to a domain. + # ARGS = (1) Plesk internal domain ID, (2) "hostname" for the new record, eg '_acme_challenge', (3) TXT record value +pleskxml_tplt_rmv_dns_record="%s" + # Add a TXT record to a domain. + # ARG = the Plesk internal ID for the dns record to be deleted + + +#################### Public functions ################################## + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_pleskxml_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Entering dns_pleskxml_add() to add TXT record '$2' to domain '$1'..." + + # Get credentials if not already checked, and confirm we can log in to Plesk XML API + if ! _credential_check; then + return 1 + fi + + # Get root and subdomain details, and Plesk domain ID + if ! _pleskxml_get_root_domain "$fulldomain"; then + return 1 + fi + + _debug 'Credentials OK, and domain identified. Calling Plesk XML API to add TXT record' + + + # printf using template in a variable - not a style issue + # shellcheck disable=SC2059 + request="$( printf "$pleskxml_tplt_add_txt_record" "$root_domain_id" "$sub_domain_name" "$txtvalue" )" + if ! _call_api "$request"; then + return 1 + fi + + # OK, we should have added a TXT record. Let's check and return success if so. + # All that should be left in the result, is one section, containing okNEW_DNS_RECORD_ID + + results="$( _api_response_split "$pleskxml_prettyprint_result" 'result' '' )" + + if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then + # Error - doesn't contain expected string. Something's wrong. + _err 'Error when calling Plesk XML API.' + _err 'The result did not contain the expected XXXXX section, or contained other values as well.' + _err 'This is unexpected: something has gone wrong.' + _err 'The full response was:\n' "$pleskxml_prettyprint_result" + return 1 + fi + + recid="$( _value "$results" | grep -E '[0-9]+' | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/' )" + + _info "Success. TXT record appears to be correctly added (Plesk record ID=$recid). Exiting dns_pleskxml_add()." + + return 0 +} + +#Usage: rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_pleskxml_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Entering dns_pleskxml_rm() to remove TXT record '$2' from domain '$1'..." + + # Get credentials if not already checked, and confirm we can log in to Plesk XML API + if ! _credential_check; then + return 1 + fi + + # Get root and subdomain details, and Plesk domain ID + if ! _pleskxml_get_root_domain "$fulldomain"; then + return 1 + fi + + _debug 'Credentials OK, and domain identified. Calling Plesk XML API to get list of TXT records and their IDs' + + # printf using template in a variable - not a style issue + # shellcheck disable=SC2059 + request="$( printf "$pleskxml_tplt_get_dns_records" "$root_domain_id" )" + if ! _call_api "$request"; then + return 1 + fi + + # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) + reclist="$( _api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | \ + grep "${root_domain_id}" | \ + grep -E '[0-9]+' | \ + grep 'TXT' \ + )" + + if [ -z "$reclist" ]; then + _err "No TXT records found for root domain ${root_domain_name} (Plesk domain ID ${root_domain_id}). Exiting." + return 1 + fi + + _debug "Got list of DNS TXT records for root domain '$root_domain_name'"':\n'"$reclist" + + recid="$( _value "$reclist" | \ + grep "$1." | \ + grep "$txtvalue" | \ + sed -E 's/(^.*|<\/id>.*$)//g' \ + )" + + _debug "List of DNS TXT records for host:"'\n'"$( _value "$reclist" | grep "$1." )" + + + if ! _value "$recid" | grep -Eq '^[0-9]+$'; then + _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" + _err "Cannot delete TXT record. Exiting." + return 1 + fi + + _debug "Found Plesk record ID for target text string '${txtvalue}': ID=${recid}" + _debug 'Calling Plesk XML API to remove TXT record' + + # printf using template in a variable - not a style issue + # shellcheck disable=SC2059 + request="$( printf "$pleskxml_tplt_rmv_dns_record" "$recid" )" + if ! _call_api "$request"; then + return 1 + fi + + # OK, we should have removed a TXT record. Let's check and return success if so. + # All that should be left in the result, is one section, containing okPLESK_DELETED_DNS_RECORD_ID + + results="$( _api_response_split "$pleskxml_prettyprint_result" 'result' '' )" + + if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then + # Error - doesn't contain expected string. Something's wrong. + _err 'Error when calling Plesk XML API.' + _err 'The result did not contain the expected XXXXX section, or contained other values as well.' + _err 'This is unexpected: something has gone wrong.' + _err 'The full response was:\n' "$pleskxml_prettyprint_result" + return 1 + fi + + _info "Success. TXT record appears to be correctly removed. Exiting dns_pleskxml_rm()." + return 0 +} + + + +#################### Private functions below ################################## + +# Outputs value of a variable +_value() { + printf '%s' "$1" +} + + +# Outputs value of a variable (FQDN) and cuts it at 2 delimiters +# $1, $2 = where to cut +# $3 = FQDN +_valuecut() { + printf '%s' "$3" | cut -d . -f "${1}-${2}" +} + + +# Cleans up an API response, splits it "per item" and greps for a string to validate useful lines +# $1 - result string from API +# $2 - tag to resplit on (usually "result" or "domain") +# $3 - regex to recognise useful return lines +_api_response_split() { + printf '%s' "$1" | \ + sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' | \ + tr -d '\n\r' | \ + sed -E "s/<\/?$2>/${NEWLINE}/g" | \ + grep -E "$3" +} + + +# Calls Plesk XML API, and checks results for obvious issues +_call_api() { + request="$1" + errtext='' + + _debug 'Entered _call_api(). Calling Plesk XML API with request:\n' "'${request}'" + + export _H1="HTTP_AUTH_LOGIN: $pleskxml_user" + export _H2="HTTP_AUTH_PASSWD: $pleskxml_pass" + export _H3="content-Type: text/xml" + export _H4="HTTP_PRETTY_PRINT: true" + pleskxml_prettyprint_result="$(_post "${request}" "$pleskxml_uri" "" "POST")" + pleskxml_retcode="$?" + _debug "acme _post() returned retcode=$pleskxml_retcode. Literal response:" '\n' "'${pleskxml_prettyprint_result}'" + + # Error handling + + # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. + # Also detect if there simply aren't any status lines (null result?) and report that, as well. + + statuslines="$( echo "$pleskxml_prettyprint_result" | grep -E '^[[:space:]]*[^<]*[[:space:]]*$' )" + + if _value "$statuslines" | grep -qv 'ok'; then + + # We have some status lines that aren't "ok". Get the details + errtext="$( \ + _value "$pleskxml_prettyprint_result" | \ + grep -iE "(||)" | \ + sed -E 's/(^[[:space:]]+|<\/[a-z]+$)//g' | \ + sed -E 's/^<([a-z]+)>/\1: /' \ + )" + + elif ! _value "$statuslines" | grep -q 'ok'; then + + # We have no status lines at all. Results are empty + errtext='The Plesk XML API unexpectedly returned an empty set of results for this call.' + + fi + + if [ "$pleskxml_retcode" -ne 0 ] || [ "$errtext" != "" ]; then + _err "The Plesk XML API call failed." + _err "The return code for the POST request was $pleskxml_retcode (0=success)." + if [ "$errtext" != "" ]; then + _err 'Status and error messages received from the Plesk server:\n' "$errtext" + else + _err "No additional error messages were received back from the Plesk server" + fi + return 1 + fi + + _debug "Leaving _call_api(). Successful call." + + return 0 +} + + +_credential_check() { + # Startup checks (credentials, URI) + + _debug "Checking Plesk XML API login credentials and URI..." + + if [ "$pleskxml_init_checks_done" -eq 1 ]; then + _debug "Initial checks already done, no need to repeat. Skipped." + return 0 + fi + + + pleskxml_user="${pleskxml_user:-$(_readaccountconf_mutable pleskxml_user)}" + pleskxml_pass="${pleskxml_pass:-$(_readaccountconf_mutable pleskxml_pass)}" + pleskxml_uri="${pleskxml_uri:-$(_readaccountconf_mutable pleskxml_uri)}" + + _debug "Credentials - User: '${pleskxml_user}' Passwd: ****** URI: '${pleskxml_uri}'" + + if [ -z "$pleskxml_user" ] || [ -z "$pleskxml_pass" ] || [ -z "$pleskxml_uri" ]; then + pleskxml_user="" + pleskxml_pass="" + pleskxml_uri="" + _err "You didn't specify one or more of the Plesk XML API username, password, or URI." + _err "Please create these and try again." + _err "Instructions are in the module source code." + return 1 + fi + + # Test the API is usable, by trying to read the list of managed domains... + _call_api "$pleskxml_tplt_get_domains" + if [ "$pleskxml_retcode" -ne 0 ]; then + _err '\nFailed to access Plesk XML API.' + _err "Please check your login credentials and Plesk URI, and that the URI is reachable, and try again." + return 1 + fi + + _saveaccountconf_mutable pleskxml_uri "$pleskxml_uri" + _saveaccountconf_mutable pleskxml_user "$pleskxml_user" + _saveaccountconf_mutable pleskxml_pass "$pleskxml_pass" + + _debug "Test login to Plesk XML API successful. Login credentials and URI successfully saved to the acme.sh configuration file for future use." + + pleskxml_init_checks_done=1 + + return 0 +} + + +# For a FQDN, identify the root domain managed by Plesk, its domain ID in Plesk, and the host if any. +_pleskxml_get_root_domain() { + _debug "Identifying DNS root domain for '$1' that is managed by the Plesk account." + + # test if the domain is valid for splitting. + + if _value "$root_domain_name" | grep -qvE '^[^.]+\.[^.]+\.[^.]'; then + ### COMMENTED OUT ALSO FOR SAME REASON + ### _err "Invalid domain. The ACME domain must contain at least three parts (aa.bb.tld) to identify a host, domain, and tld for the TXT record." + _err "Invalid domain. The ACME domain must contain at least two parts (aa.bb) to identify a domain and tld for the TXT record." + return 1 + fi + + _debug "Querying Plesk server for list of managed domains..." + + _call_api "$pleskxml_tplt_get_domains" + if [ "$pleskxml_retcode" -ne 0 ]; then + return 1 + fi + + # Generate a hacked list of domains known to this Plesk account. + # We convert tags to so it'll flag on a hit with either or fields, + # for non-Western character sets. + # Output will be one line per known domain, containing 1 or 2 tages and an tag + # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. + output="$( _api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed -E 's/<(\/?)ascii-name>/<\1name>/g' | grep '' | grep '' )" + + _debug 'Domains managed by Plesk server are (ignore the hacked output):\n' "$output" + + # loop and test if domain, or any parent domain, is managed by Plesk + # Loop until we don't have any '.' in the sring we're testing as a root domain + + root_domain_name="$1" + doneloop=0 + + while _contains "$root_domain_name" '\.'; do + + _debug "Checking if '$root_domain_name' is managed by the Plesk server..." + + root_domain_id="$( _value "$output" | grep "$root_domain_name" | _head_n 1 | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/' )" + + if [ -n "$root_domain_id" ]; then + # Found a match + # Note that a result with host = empty string is OK for this API, see + # https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-dns/managing-dns-records/adding-dns-record.34798 + # See notes at top of this file + sub_domain_name="$( _value "$1" | sed -E "s/\.?${root_domain_name}"'$//' )" + _info "Matched host '$1' to: DOMAIN '${root_domain_name}' (Plesk ID '${root_domain_id}'), HOST '${sub_domain_name}'. Returning." + return 0 + fi + + # No match, try next parent up (if any)... + + if _contains "$root_domain_name" '\.[^.]+\.'; then + _debug "No match, trying next parent up..." + else + _debug "No match,and next parent would be a TLD..." + fi + root_domain_name="$( _valuecut 2 1000 "$root_domain_name" )" + doneloop=1 + + done + + # if we get here, we failed to find a root domain match in the list of domains managed by Plesk. + # if we never ran the loop a first time, $1 wasn't at least a 2 level domain (domain.tld) and wasn't valid anyway + + if [ -z $doneloop ]; then + _err "'$1' isn't a valid domain for ACME DNS. Exiting." + else + _err "Cannot find '$1' or any parent domain of it, in Plesk." + _err "Are you sure that this domain is managed by this Plesk server?" + fi + + return 1 +} From a00300f88a7e9d85883616e55819f51052e64b7e Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 01:23:14 +0100 Subject: [PATCH 0487/2234] revert changes to this file --- README.md | 646 ++++++++++++++++-------------------------------------- 1 file changed, 189 insertions(+), 457 deletions(-) diff --git a/README.md b/README.md index 32d30147..613fff7f 100644 --- a/README.md +++ b/README.md @@ -1,503 +1,235 @@ + +Skip to content +Pull requests +Issues +Marketplace +Explore +@stilez +Learn Git and GitHub without any code! + +Using the Hello World guide, you’ll start a branch, write comments, and open a pull request. + +395 +14.7k + + 1.9k + +Neilpang/acme.sh +Code +Issues 415 +Pull requests 110 +Actions +Projects 0 +Wiki +Security +Insights +You’re editing a file in a project you don’t have write access to. Submitting a change to this file will write it to a new branch in your fork stilez/acme.sh, so you can send a pull request. +acme.sh/ + +1 + # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh) -[![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +2 + +​ + +3 + + [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +4 + - An ACME protocol client written purely in Shell (Unix shell) language. + +5 + - Full ACME protocol implementation. + +6 + - Support ACME v1 and ACME v2 + +7 + - Support ACME v2 wildcard certs + +8 + - Simple, powerful and very easy to use. You only need 3 minutes to learn it. + +9 + - Bash, dash and sh compatible. + +10 + - Simplest shell script for Let's Encrypt free certificate client. + +11 + - Purely written in Shell with no dependencies on python or the official Let's Encrypt client. + +12 + - Just one script to issue, renew and install your certificates automatically. + +13 + - DOES NOT require `root/sudoer` access. + +14 + - Docker friendly + +15 + - IPv6 support +16 + +- Cron job notifications for renewal or error etc. + +17 + +​ + +18 + It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt. +19 + +​ + +20 + Wiki: https://github.com/Neilpang/acme.sh/wiki +21 + +​ + +22 + For Docker Fans: [acme.sh :two_hearts: Docker ](https://github.com/Neilpang/acme.sh/wiki/Run-acme.sh-in-docker) +23 + +​ + +24 + Twitter: [@neilpangxa](https://twitter.com/neilpangxa) +25 + +​ + +26 + +​ + +27 # [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E) +28 + +​ + +29 + # Who: + +30 + - [FreeBSD.org](https://blog.crashed.org/letsencrypt-in-freebsd-org/) + +31 + - [ruby-china.org](https://ruby-china.org/topics/31983) + +32 + - [Proxmox](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x_and_newer)) + +33 + - [pfsense](https://github.com/pfsense/FreeBSD-ports/pull/89) + +34 + - [webfaction](https://community.webfaction.com/questions/19988/using-letsencrypt) + +35 + - [Loadbalancer.org](https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty) + +36 + - [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709) + +37 + - [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html) + +38 + - [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297) -- [archlinux](https://aur.archlinux.org/packages/acme.sh-git/) + +39 + +- [archlinux](https://www.archlinux.org/packages/community/any/acme.sh) + +40 + - [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient) + +41 + - [CentOS Web Panel](http://centos-webpanel.com/) + +42 + - [lnmp.org](https://lnmp.org/) + +43 + - [more...](https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials) +44 + +​ + +45 + # Tested OS +46 + +​ + +47 + | NO | Status| Platform| -|----|-------|---------| -|1|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu -|2|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/debian-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Debian -|3|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/centos-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|CentOS -|4|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/windows-cygwin.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) -|5|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/freebsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|FreeBSD -|6|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/pfsense.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|pfsense -|7|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/opensuse-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|openSUSE -|8|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/alpine-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Alpine Linux (with curl) -|9|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/base-archlinux.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Archlinux -|10|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/fedora-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|fedora -|11|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/kalilinux-kali-linux-docker.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Kali Linux -|12|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/oraclelinux-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Oracle Linux -|13|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/proxmox.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh -|14|-----| Cloud Linux https://github.com/Neilpang/le/issues/111 -|15|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/openbsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|OpenBSD -|16|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia -|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT) -|18|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris -|19|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux -|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX -For all build statuses, check our [weekly build project](https://github.com/Neilpang/acmetest): +@stilez +Propose file change +Commit summary +Optional extended description + + © 2019 GitHub, Inc. + Terms + Privacy + Security + Status + Help + + Contact GitHub + Pricing + API + Training + Blog + About -https://github.com/Neilpang/acmetest - - -# Supported modes - -- Webroot mode -- Standalone mode -- Apache mode -- Nginx mode -- DNS mode -- [DNS alias mode](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode) -- [Stateless mode](https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode) - - -# 1. How to install - -### 1. Install online - -Check this project: https://github.com/Neilpang/get.acme.sh - -```bash -curl https://get.acme.sh | sh -``` - -Or: - -```bash -wget -O - https://get.acme.sh | sh -``` - - -### 2. Or, Install from git - -Clone this project and launch installation: - -```bash -git clone https://github.com/Neilpang/acme.sh.git -cd ./acme.sh -./acme.sh --install -``` - -You `don't have to be root` then, although `it is recommended`. - -Advanced Installation: https://github.com/Neilpang/acme.sh/wiki/How-to-install - -The installer will perform 3 actions: - -1. Create and copy `acme.sh` to your home dir (`$HOME`): `~/.acme.sh/`. -All certs will be placed in this folder too. -2. Create alias for: `acme.sh=~/.acme.sh/acme.sh`. -3. Create daily cron job to check and renew the certs if needed. - -Cron entry example: - -```bash -0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null -``` - -After the installation, you must close the current terminal and reopen it to make the alias take effect. - -Ok, you are ready to issue certs now. - -Show help message: - -```sh -root@v1:~# acme.sh -h -``` - -# 2. Just issue a cert - -**Example 1:** Single domain. - -```bash -acme.sh --issue -d example.com -w /home/wwwroot/example.com -``` - -or: - -```bash -acme.sh --issue -d example.com -w /home/username/public_html -``` - -or: - -```bash -acme.sh --issue -d example.com -w /var/www/html -``` - -**Example 2:** Multiple domains in the same cert. - -```bash -acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com -``` - -The parameter `/home/wwwroot/example.com` or `/home/username/public_html` or `/var/www/html` is the web root folder where you host your website files. You **MUST** have `write access` to this folder. - -Second argument **"example.com"** is the main domain you want to issue the cert for. -You must have at least one domain there. - -You must point and bind all the domains to the same webroot dir: `/home/wwwroot/example.com`. - -The certs will be placed in `~/.acme.sh/example.com/` - -The certs will be renewed automatically every **60** days. - -More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert - - -# 3. Install the cert to Apache/Nginx etc. - -After the cert is generated, you probably want to install/copy the cert to your Apache/Nginx or other servers. -You **MUST** use this command to copy the certs to the target files, **DO NOT** use the certs files in **~/.acme.sh/** folder, they are for internal use only, the folder structure may change in the future. - -**Apache** example: -```bash -acme.sh --install-cert -d example.com \ ---cert-file /path/to/certfile/in/apache/cert.pem \ ---key-file /path/to/keyfile/in/apache/key.pem \ ---fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \ ---reloadcmd "service apache2 force-reload" -``` - -**Nginx** example: -```bash -acme.sh --install-cert -d example.com \ ---key-file /path/to/keyfile/in/nginx/key.pem \ ---fullchain-file /path/to/fullchain/nginx/cert.pem \ ---reloadcmd "service nginx force-reload" -``` - -Only the domain is required, all the other parameters are optional. - -The ownership and permission info of existing files are preserved. You can pre-create the files to define the ownership and permission. - -Install/copy the cert/key to the production Apache or Nginx path. - -The cert will be renewed every **60** days by default (which is configurable). Once the cert is renewed, the Apache/Nginx service will be reloaded automatically by the command: `service apache2 force-reload` or `service nginx force-reload`. - - -**Please take care: The reloadcmd is very important. The cert can be automatically renewed, but, without a correct 'reloadcmd' the cert may not be flushed to your server(like nginx or apache), then your website will not be able to show renewed cert in 60 days.** - -# 4. Use Standalone server to issue cert - -**(requires you to be root/sudoer or have permission to listen on port 80 (TCP))** - -Port `80` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again. - -```bash -acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com -``` - -More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert - - -# 5. Use Apache mode - -**(requires you to be root/sudoer, since it is required to interact with Apache server)** - -If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`. - -Particularly, if you are running an Apache server, you can use Apache mode instead. This mode doesn't write any files to your web root folder. - -Just set string "apache" as the second argument and it will force use of apache plugin automatically. - -```sh -acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com -``` - -**This apache mode is only to issue the cert, it will not change your apache config files. -You will need to configure your website config files to use the cert by yourself. -We don't want to mess your apache server, don't worry.** - -More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert - -# 6. Use Nginx mode - -**(requires you to be root/sudoer, since it is required to interact with Nginx server)** - -If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`. - -Particularly, if you are running an nginx server, you can use nginx mode instead. This mode doesn't write any files to your web root folder. - -Just set string "nginx" as the second argument. - -It will configure nginx server automatically to verify the domain and then restore the nginx config to the original version. - -So, the config is not changed. - -```sh -acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com -``` - -**This nginx mode is only to issue the cert, it will not change your nginx config files. -You will need to configure your website config files to use the cert by yourself. -We don't want to mess your nginx server, don't worry.** - -More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert - -# 7. Automatic DNS API integration - -If your DNS provider supports API access, we can use that API to automatically issue the certs. - -You don't have to do anything manually! - -### Currently acme.sh supports: - -1. CloudFlare.com API -1. DNSPod.cn API -1. CloudXNS.com API -1. GoDaddy.com API -1. PowerDNS.com API -1. OVH, kimsufi, soyoustart and runabove API -1. nsupdate API -1. LuaDNS.com API -1. DNSMadeEasy.com API -1. AWS Route 53 -1. aliyun.com(阿里云) API -1. ISPConfig 3.1 API -1. Alwaysdata.com API -1. Linode.com API -1. FreeDNS (https://freedns.afraid.org/) -1. cyon.ch -1. Domain-Offensive/Resellerinterface/Domainrobot API -1. Gandi LiveDNS API -1. Knot DNS API -1. DigitalOcean API (native) -1. ClouDNS.net API -1. Infoblox NIOS API (https://www.infoblox.com/) -1. VSCALE (https://vscale.io/) -1. Dynu API (https://www.dynu.com) -1. DNSimple API -1. NS1.com API -1. DuckDNS.org API -1. Name.com API -1. Dyn Managed DNS API -1. Yandex PDD API (https://pdd.yandex.ru) -1. Hurricane Electric DNS service (https://dns.he.net) -1. UnoEuro API (https://www.unoeuro.com/) -1. INWX (https://www.inwx.de/) -1. Servercow (https://servercow.de) -1. Namesilo (https://www.namesilo.com) -1. InternetX autoDNS API (https://internetx.com) -1. Azure DNS -1. selectel.com(selectel.ru) DNS API -1. zonomi.com DNS API -1. DreamHost.com API -1. DirectAdmin API -1. KingHost (https://www.kinghost.com.br/) -1. Zilore (https://zilore.com) -1. Loopia.se API -1. acme-dns (https://github.com/joohoi/acme-dns) -1. TELE3 (https://www.tele3.cz) -1. EUSERV.EU (https://www.euserv.eu) -1. Plesk XML API (https://www.plesk.com) - -And: - -**lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api - (DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.)** - - -**More APIs coming soon...** - -If your DNS provider is not on the supported list above, you can write your own DNS API script easily. If you do, please consider submitting a [Pull Request](https://github.com/Neilpang/acme.sh/pulls) and contribute it to the project. - -For more details: [How to use DNS API](dnsapi) - -# 8. Use DNS manual mode: - -See: https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode first. - -If your dns provider doesn't support any api access, you can add the txt record by your hand. - -```bash -acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com -``` - -You should get an output like below: - -```sh -Add the following txt record: -Domain:_acme-challenge.example.com -Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c - -Add the following txt record: -Domain:_acme-challenge.www.example.com -Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - -Please add those txt records to the domains. Waiting for the dns to take effect. -``` - -Then just rerun with `renew` argument: - -```bash -acme.sh --renew -d example.com -``` - -Ok, it's done. - -**Take care, this is dns manual mode, it can not be renewed automatically. you will have to add a new txt record to your domain by your hand when you renew your cert.** - -**Please use dns api mode instead.** - -# 9. Issue ECC certificates - -`Let's Encrypt` can now issue **ECDSA** certificates. - -And we support them too! - -Just set the `keylength` parameter with a prefix `ec-`. - -For example: - -### Single domain ECC certificate - -```bash -acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256 -``` - -### SAN multi domain ECC certificate - -```bash -acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256 -``` - -Please look at the `keylength` parameter above. - -Valid values are: - -1. **ec-256 (prime256v1, "ECDSA P-256")** -2. **ec-384 (secp384r1, "ECDSA P-384")** -3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)** - - - -# 10. Issue Wildcard certificates - -It's simple, just give a wildcard domain as the `-d` parameter. - -```sh -acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf -``` - - - -# 11. How to renew the certs - -No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days. - -However, you can also force to renew a cert: - -```sh -acme.sh --renew -d example.com --force -``` - -or, for ECC cert: - -```sh -acme.sh --renew -d example.com --force --ecc -``` - - -# 12. How to stop cert renewal - -To stop renewal of a cert, you can execute the following to remove the cert from the renewal list: - -```sh -acme.sh --remove -d example.com [--ecc] -``` - -The cert/key file is not removed from the disk. - -You can remove the respective directory (e.g. `~/.acme.sh/example.com`) by yourself. - - -# 13. How to upgrade `acme.sh` - -acme.sh is in constant development, so it's strongly recommended to use the latest code. - -You can update acme.sh to the latest code: - -```sh -acme.sh --upgrade -``` - -You can also enable auto upgrade: - -```sh -acme.sh --upgrade --auto-upgrade -``` - -Then **acme.sh** will be kept up to date automatically. - -Disable auto upgrade: - -```sh -acme.sh --upgrade --auto-upgrade 0 -``` - - -# 14. Issue a cert from an existing CSR - -https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR - - -# 15. Under the Hood - -Speak ACME language using shell, directly to "Let's Encrypt". - -TODO: - - -# 16. Acknowledgments - -1. Acme-tiny: https://github.com/diafygi/acme-tiny -2. ACME protocol: https://github.com/ietf-wg-acme/acme - - -# 17. License & Others - -License is GPLv3 - -Please Star and Fork me. - -[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome. - - -# 18. Donate -Your donation makes **acme.sh** better: - -1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/) - -[Donate List](https://github.com/Neilpang/acme.sh/wiki/Donate-list) From 4c9d99040c822b35eefbcee46b88bdb766af32a5 Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 01:31:17 +0100 Subject: [PATCH 0488/2234] Fix (revert) edited .md file --- README.md | 609 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 461 insertions(+), 148 deletions(-) diff --git a/README.md b/README.md index 6c692885..d5012d68 100644 --- a/README.md +++ b/README.md @@ -1,185 +1,498 @@ - -Skip to content -Pull requests -Issues -Marketplace -Explore -@stilez -Learn Git and GitHub without any code! - -Using the Hello World guide, you’ll start a branch, write comments, and open a pull request. - -395 -14.7k - - 1.9k - -Neilpang/acme.sh -Code -Issues 415 -Pull requests 110 -Actions -Projects 0 -Wiki -Security -Insights -You’re editing a file in a project you don’t have write access to. Submitting a change to this file will write it to a new branch in your fork stilez/acme.sh, so you can send a pull request. -acme.sh/ - -1 - - -2 - - -3 +# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh) [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -4 - - An ACME protocol client written purely in Shell (Unix shell) language. - -5 - - Full ACME protocol implementation. - -6 - - -7 - - -8 - +- Support ACME v1 and ACME v2 +- Support ACME v2 wildcard certs - Simple, powerful and very easy to use. You only need 3 minutes to learn it. - +- Bash, dash and sh compatible. +- Simplest shell script for Let's Encrypt free certificate client. +- Purely written in Shell with no dependencies on python or the official Let's Encrypt client. +- Just one script to issue, renew and install your certificates automatically. - DOES NOT require `root/sudoer` access. - -14 - - Docker friendly - -15 - - IPv6 support - -16 - - Cron job notifications for renewal or error etc. -17 - -​ - -18 - It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt. -19 - - -20 - Wiki: https://github.com/Neilpang/acme.sh/wiki -21 - -​ - -22 - For Docker Fans: [acme.sh :two_hearts: Docker ](https://github.com/Neilpang/acme.sh/wiki/Run-acme.sh-in-docker) -23 - -​ - -24 - Twitter: [@neilpangxa](https://twitter.com/neilpangxa) -25 - -​ - -26 - - -27 # [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E) -28 - -​ - - # Who: - -30 - - [FreeBSD.org](https://blog.crashed.org/letsencrypt-in-freebsd-org/) - -31 - - [ruby-china.org](https://ruby-china.org/topics/31983) - -32 - - -33 - +- [Proxmox](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x_and_newer)) - [pfsense](https://github.com/pfsense/FreeBSD-ports/pull/89) - -34 - - [webfaction](https://community.webfaction.com/questions/19988/using-letsencrypt) - -35 - - -36 - +- [Loadbalancer.org](https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty) - [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709) - -37 - - [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html) - -38 - - [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297) - -39 - - [archlinux](https://www.archlinux.org/packages/community/any/acme.sh) - -40 - - -41 - +- [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient) - [CentOS Web Panel](http://centos-webpanel.com/) - - - [lnmp.org](https://lnmp.org/) - -43 - - [more...](https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials) - -​ - -45 - - -46 - -​ - -47 +# Tested OS | NO | Status| Platform| +|----|-------|---------| +|1|[![](https://neilpang.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu +|2|[![](https://neilpang.github.io/acmetest/status/debian-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Debian +|3|[![](https://neilpang.github.io/acmetest/status/centos-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|CentOS +|4|[![](https://neilpang.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) +|5|[![](https://neilpang.github.io/acmetest/status/freebsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|FreeBSD +|6|[![](https://neilpang.github.io/acmetest/status/pfsense.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|pfsense +|7|[![](https://neilpang.github.io/acmetest/status/opensuse-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|openSUSE +|8|[![](https://neilpang.github.io/acmetest/status/alpine-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Alpine Linux (with curl) +|9|[![](https://neilpang.github.io/acmetest/status/base-archlinux.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Archlinux +|10|[![](https://neilpang.github.io/acmetest/status/fedora-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|fedora +|11|[![](https://neilpang.github.io/acmetest/status/kalilinux-kali-linux-docker.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Kali Linux +|12|[![](https://neilpang.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Oracle Linux +|13|[![](https://neilpang.github.io/acmetest/status/proxmox.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh +|14|-----| Cloud Linux https://github.com/Neilpang/le/issues/111 +|15|[![](https://neilpang.github.io/acmetest/status/openbsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|OpenBSD +|16|[![](https://neilpang.github.io/acmetest/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia +|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT) +|18|[![](https://neilpang.github.io/acmetest/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris +|19|[![](https://neilpang.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux +|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX +For all build statuses, check our [weekly build project](https://github.com/Neilpang/acmetest): + +https://github.com/Neilpang/acmetest + +# Supported CA + +- Letsencrypt.org CA(default) +- [BuyPass.com CA](https://github.com/Neilpang/acme.sh/wiki/BuyPass.com-CA) +- [Pebble strict Mode](https://github.com/letsencrypt/pebble) + +# Supported modes + +- Webroot mode +- Standalone mode +- Standalone tls-alpn mode +- Apache mode +- Nginx mode +- DNS mode +- [DNS alias mode](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode) +- [Stateless mode](https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode) + + +# 1. How to install + +### 1. Install online + +Check this project: https://github.com/Neilpang/get.acme.sh + +```bash +curl https://get.acme.sh | sh +``` + +Or: + +```bash +wget -O - https://get.acme.sh | sh +``` + + +### 2. Or, Install from git + +Clone this project and launch installation: + +```bash +git clone https://github.com/Neilpang/acme.sh.git +cd ./acme.sh +./acme.sh --install +``` + +You `don't have to be root` then, although `it is recommended`. + +Advanced Installation: https://github.com/Neilpang/acme.sh/wiki/How-to-install + +The installer will perform 3 actions: + +1. Create and copy `acme.sh` to your home dir (`$HOME`): `~/.acme.sh/`. +All certs will be placed in this folder too. +2. Create alias for: `acme.sh=~/.acme.sh/acme.sh`. +3. Create daily cron job to check and renew the certs if needed. + +Cron entry example: + +```bash +0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null +``` + +After the installation, you must close the current terminal and reopen it to make the alias take effect. + +Ok, you are ready to issue certs now. + +Show help message: + +```sh +root@v1:~# acme.sh -h +``` + +# 2. Just issue a cert + +**Example 1:** Single domain. + +```bash +acme.sh --issue -d example.com -w /home/wwwroot/example.com +``` + +or: + +```bash +acme.sh --issue -d example.com -w /home/username/public_html +``` + +or: + +```bash +acme.sh --issue -d example.com -w /var/www/html +``` + +**Example 2:** Multiple domains in the same cert. + +```bash +acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com +``` + +The parameter `/home/wwwroot/example.com` or `/home/username/public_html` or `/var/www/html` is the web root folder where you host your website files. You **MUST** have `write access` to this folder. + +Second argument **"example.com"** is the main domain you want to issue the cert for. +You must have at least one domain there. + +You must point and bind all the domains to the same webroot dir: `/home/wwwroot/example.com`. + +The certs will be placed in `~/.acme.sh/example.com/` + +The certs will be renewed automatically every **60** days. + +More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert + + +# 3. Install the cert to Apache/Nginx etc. + +After the cert is generated, you probably want to install/copy the cert to your Apache/Nginx or other servers. +You **MUST** use this command to copy the certs to the target files, **DO NOT** use the certs files in **~/.acme.sh/** folder, they are for internal use only, the folder structure may change in the future. + +**Apache** example: +```bash +acme.sh --install-cert -d example.com \ +--cert-file /path/to/certfile/in/apache/cert.pem \ +--key-file /path/to/keyfile/in/apache/key.pem \ +--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \ +--reloadcmd "service apache2 force-reload" +``` + +**Nginx** example: +```bash +acme.sh --install-cert -d example.com \ +--key-file /path/to/keyfile/in/nginx/key.pem \ +--fullchain-file /path/to/fullchain/nginx/cert.pem \ +--reloadcmd "service nginx force-reload" +``` + +Only the domain is required, all the other parameters are optional. + +The ownership and permission info of existing files are preserved. You can pre-create the files to define the ownership and permission. + +Install/copy the cert/key to the production Apache or Nginx path. + +The cert will be renewed every **60** days by default (which is configurable). Once the cert is renewed, the Apache/Nginx service will be reloaded automatically by the command: `service apache2 force-reload` or `service nginx force-reload`. + + +**Please take care: The reloadcmd is very important. The cert can be automatically renewed, but, without a correct 'reloadcmd' the cert may not be flushed to your server(like nginx or apache), then your website will not be able to show renewed cert in 60 days.** + +# 4. Use Standalone server to issue cert + +**(requires you to be root/sudoer or have permission to listen on port 80 (TCP))** + +Port `80` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again. + +```bash +acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com +``` + +More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert + +# 5. Use Standalone ssl server to issue cert + +**(requires you to be root/sudoer or have permission to listen on port 443 (TCP))** + +Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again. + +```bash +acme.sh --issue --alpn -d example.com -d www.example.com -d cp.example.com +``` + +More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert + + +# 6. Use Apache mode + +**(requires you to be root/sudoer, since it is required to interact with Apache server)** + +If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`. + +Particularly, if you are running an Apache server, you can use Apache mode instead. This mode doesn't write any files to your web root folder. + +Just set string "apache" as the second argument and it will force use of apache plugin automatically. + +```sh +acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com +``` + +**This apache mode is only to issue the cert, it will not change your apache config files. +You will need to configure your website config files to use the cert by yourself. +We don't want to mess your apache server, don't worry.** + +More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert + +# 7. Use Nginx mode + +**(requires you to be root/sudoer, since it is required to interact with Nginx server)** + +If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`. + +Particularly, if you are running an nginx server, you can use nginx mode instead. This mode doesn't write any files to your web root folder. + +Just set string "nginx" as the second argument. + +It will configure nginx server automatically to verify the domain and then restore the nginx config to the original version. + +So, the config is not changed. + +```sh +acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com +``` + +**This nginx mode is only to issue the cert, it will not change your nginx config files. +You will need to configure your website config files to use the cert by yourself. +We don't want to mess your nginx server, don't worry.** + +More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert + +# 8. Automatic DNS API integration + +If your DNS provider supports API access, we can use that API to automatically issue the certs. + +You don't have to do anything manually! + +### Currently acme.sh supports most of the dns providers: + +https://github.com/Neilpang/acme.sh/wiki/dnsapi + +# 9. Use DNS manual mode: + +See: https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode first. + +If your dns provider doesn't support any api access, you can add the txt record by your hand. + +```bash +acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com +``` + +You should get an output like below: + +```sh +Add the following txt record: +Domain:_acme-challenge.example.com +Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c + +Add the following txt record: +Domain:_acme-challenge.www.example.com +Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +Please add those txt records to the domains. Waiting for the dns to take effect. +``` + +Then just rerun with `renew` argument: + +```bash +acme.sh --renew -d example.com +``` + +Ok, it's done. + +**Take care, this is dns manual mode, it can not be renewed automatically. you will have to add a new txt record to your domain by your hand when you renew your cert.** + +**Please use dns api mode instead.** + +# 10. Issue ECC certificates + +`Let's Encrypt` can now issue **ECDSA** certificates. + +And we support them too! + +Just set the `keylength` parameter with a prefix `ec-`. + +For example: + +### Single domain ECC certificate + +```bash +acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256 +``` + +### SAN multi domain ECC certificate + +```bash +acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256 +``` + +Please look at the `keylength` parameter above. + +Valid values are: + +1. **ec-256 (prime256v1, "ECDSA P-256")** +2. **ec-384 (secp384r1, "ECDSA P-384")** +3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)** + + + +# 11. Issue Wildcard certificates + +It's simple, just give a wildcard domain as the `-d` parameter. + +```sh +acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf +``` + + + +# 12. How to renew the certs + +No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days. + +However, you can also force to renew a cert: + +```sh +acme.sh --renew -d example.com --force +``` + +or, for ECC cert: + +```sh +acme.sh --renew -d example.com --force --ecc +``` + + +# 13. How to stop cert renewal + +To stop renewal of a cert, you can execute the following to remove the cert from the renewal list: + +```sh +acme.sh --remove -d example.com [--ecc] +``` + +The cert/key file is not removed from the disk. + +You can remove the respective directory (e.g. `~/.acme.sh/example.com`) by yourself. + + +# 14. How to upgrade `acme.sh` + +acme.sh is in constant development, so it's strongly recommended to use the latest code. + +You can update acme.sh to the latest code: + +```sh +acme.sh --upgrade +``` + +You can also enable auto upgrade: + +```sh +acme.sh --upgrade --auto-upgrade +``` + +Then **acme.sh** will be kept up to date automatically. + +Disable auto upgrade: + +```sh +acme.sh --upgrade --auto-upgrade 0 +``` + + +# 15. Issue a cert from an existing CSR + +https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR + + +# 16. Send notifications in cronjob + +https://github.com/Neilpang/acme.sh/wiki/notify + + +# 17. Under the Hood + +Speak ACME language using shell, directly to "Let's Encrypt". + +TODO: + + +# 18. Acknowledgments + +1. Acme-tiny: https://github.com/diafygi/acme-tiny +2. ACME protocol: https://github.com/ietf-wg-acme/acme + + +## Contributors + +### Code Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. + + +### Financial Contributors + +Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/acmesh/contribute)] + +#### Individuals + + + +#### Organizations + +Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/acmesh/contribute)] + + + + + + + + + + + + +# 19. License & Others + +License is GPLv3 + +Please Star and Fork me. + +[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome. + + +# 20. Donate +Your donation makes **acme.sh** better: + +1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/) + +[Donate List](https://github.com/Neilpang/acme.sh/wiki/Donate-list) From a6614abd24600618a23ee390470eea7af912b9f4 Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 01:00:59 +0000 Subject: [PATCH 0489/2234] Formatting fixes for Travis --- dnsapi/dns_pleskxml | 102 +++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 49 deletions(-) diff --git a/dnsapi/dns_pleskxml b/dnsapi/dns_pleskxml index a8a74721..bed1b26f 100644 --- a/dnsapi/dns_pleskxml +++ b/dnsapi/dns_pleskxml @@ -44,18 +44,21 @@ NEWLINE='\ #################### API Templates ################################## pleskxml_tplt_get_domains="" - # Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh - # Also used to test credentials and URI. - # No args. +# Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh +# Also used to test credentials and URI. +# No args. + pleskxml_tplt_get_dns_records="%s" - # Get all DNS records for a Plesk domain ID. - # ARG = Plesk domain id to query +# Get all DNS records for a Plesk domain ID. +# ARG = Plesk domain id to query + pleskxml_tplt_add_txt_record="%sTXT%s%s" - # Add a TXT record to a domain. - # ARGS = (1) Plesk internal domain ID, (2) "hostname" for the new record, eg '_acme_challenge', (3) TXT record value +# Add a TXT record to a domain. +# ARGS = (1) Plesk internal domain ID, (2) "hostname" for the new record, eg '_acme_challenge', (3) TXT record value + pleskxml_tplt_rmv_dns_record="%s" - # Add a TXT record to a domain. - # ARG = the Plesk internal ID for the dns record to be deleted +# Add a TXT record to a domain. +# ARG = the Plesk internal ID for the dns record to be deleted #################### Public functions ################################## @@ -82,7 +85,7 @@ dns_pleskxml_add() { # printf using template in a variable - not a style issue # shellcheck disable=SC2059 - request="$( printf "$pleskxml_tplt_add_txt_record" "$root_domain_id" "$sub_domain_name" "$txtvalue" )" + request="$(printf "$pleskxml_tplt_add_txt_record" "$root_domain_id" "$sub_domain_name" "$txtvalue")" if ! _call_api "$request"; then return 1 fi @@ -90,7 +93,7 @@ dns_pleskxml_add() { # OK, we should have added a TXT record. Let's check and return success if so. # All that should be left in the result, is one section, containing okNEW_DNS_RECORD_ID - results="$( _api_response_split "$pleskxml_prettyprint_result" 'result' '' )" + results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then # Error - doesn't contain expected string. Something's wrong. @@ -101,7 +104,7 @@ dns_pleskxml_add() { return 1 fi - recid="$( _value "$results" | grep -E '[0-9]+' | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/' )" + recid="$(_value "$results" | grep -E '[0-9]+' | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" _info "Success. TXT record appears to be correctly added (Plesk record ID=$recid). Exiting dns_pleskxml_add()." @@ -129,16 +132,16 @@ dns_pleskxml_rm() { # printf using template in a variable - not a style issue # shellcheck disable=SC2059 - request="$( printf "$pleskxml_tplt_get_dns_records" "$root_domain_id" )" + request="$(printf "$pleskxml_tplt_get_dns_records" "$root_domain_id")" if ! _call_api "$request"; then return 1 fi # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) - reclist="$( _api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | \ - grep "${root_domain_id}" | \ - grep -E '[0-9]+' | \ - grep 'TXT' \ + reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ + | grep "${root_domain_id}" \ + | grep -E '[0-9]+' \ + | grep 'TXT' \ )" if [ -z "$reclist" ]; then @@ -148,14 +151,13 @@ dns_pleskxml_rm() { _debug "Got list of DNS TXT records for root domain '$root_domain_name'"':\n'"$reclist" - recid="$( _value "$reclist" | \ - grep "$1." | \ - grep "$txtvalue" | \ - sed -E 's/(^.*|<\/id>.*$)//g' \ - )" - - _debug "List of DNS TXT records for host:"'\n'"$( _value "$reclist" | grep "$1." )" + recid="$(_value "$reclist" \ + | grep "$1." \ + | grep "$txtvalue" \ + | sed -E 's/(^.*|<\/id>.*$)//g' \ + )" + _debug "List of DNS TXT records for host:"'\n'"$(_value "$reclist" | grep "$1.")" if ! _value "$recid" | grep -Eq '^[0-9]+$'; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" @@ -168,7 +170,7 @@ dns_pleskxml_rm() { # printf using template in a variable - not a style issue # shellcheck disable=SC2059 - request="$( printf "$pleskxml_tplt_rmv_dns_record" "$recid" )" + request="$(printf "$pleskxml_tplt_rmv_dns_record" "$recid")" if ! _call_api "$request"; then return 1 fi @@ -176,7 +178,7 @@ dns_pleskxml_rm() { # OK, we should have removed a TXT record. Let's check and return success if so. # All that should be left in the result, is one section, containing okPLESK_DELETED_DNS_RECORD_ID - results="$( _api_response_split "$pleskxml_prettyprint_result" 'result' '' )" + results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then # Error - doesn't contain expected string. Something's wrong. @@ -214,11 +216,11 @@ _valuecut() { # $2 - tag to resplit on (usually "result" or "domain") # $3 - regex to recognise useful return lines _api_response_split() { - printf '%s' "$1" | \ - sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' | \ - tr -d '\n\r' | \ - sed -E "s/<\/?$2>/${NEWLINE}/g" | \ - grep -E "$3" + printf '%s' "$1" \ + | sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' \ + | tr -d '\n\r' \ + | sed -E "s/<\/?$2>/${NEWLINE}/g" \ + | grep -E "$3" } @@ -242,17 +244,16 @@ _call_api() { # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. - statuslines="$( echo "$pleskxml_prettyprint_result" | grep -E '^[[:space:]]*[^<]*[[:space:]]*$' )" + statuslines="$(echo "$pleskxml_prettyprint_result" | grep -E '^[[:space:]]*[^<]*[[:space:]]*$')" if _value "$statuslines" | grep -qv 'ok'; then # We have some status lines that aren't "ok". Get the details - errtext="$( \ - _value "$pleskxml_prettyprint_result" | \ - grep -iE "(||)" | \ - sed -E 's/(^[[:space:]]+|<\/[a-z]+$)//g' | \ - sed -E 's/^<([a-z]+)>/\1: /' \ - )" + errtext="$( _value "$pleskxml_prettyprint_result" \ + | grep -iE "(||)" \ + | sed -E 's/(^[[:space:]]+|<\/[a-z]+$)//g' \ + | sed -E 's/^<([a-z]+)>/\1: /' \ + )" elif ! _value "$statuslines" | grep -q 'ok'; then @@ -326,14 +327,17 @@ _credential_check() { # For a FQDN, identify the root domain managed by Plesk, its domain ID in Plesk, and the host if any. + +# IMPORTANT NOTE: a result with host = empty string is OK for this API, see +# https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-dns/managing-dns-records/adding-dns-record.34798 +# See notes at top of this file + _pleskxml_get_root_domain() { _debug "Identifying DNS root domain for '$1' that is managed by the Plesk account." # test if the domain is valid for splitting. - if _value "$root_domain_name" | grep -qvE '^[^.]+\.[^.]+\.[^.]'; then - ### COMMENTED OUT ALSO FOR SAME REASON - ### _err "Invalid domain. The ACME domain must contain at least three parts (aa.bb.tld) to identify a host, domain, and tld for the TXT record." + if _value "$root_domain_name" | grep -qvE '^[^.]+\.[^.]+\.[^.]'; then _err "Invalid domain. The ACME domain must contain at least two parts (aa.bb) to identify a domain and tld for the TXT record." return 1 fi @@ -350,7 +354,8 @@ _pleskxml_get_root_domain() { # for non-Western character sets. # Output will be one line per known domain, containing 1 or 2 tages and an tag # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. - output="$( _api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed -E 's/<(\/?)ascii-name>/<\1name>/g' | grep '' | grep '' )" + + output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed -E 's/<(\/?)ascii-name>/<\1name>/g' | grep '' | grep '')" _debug 'Domains managed by Plesk server are (ignore the hacked output):\n' "$output" @@ -364,14 +369,13 @@ _pleskxml_get_root_domain() { _debug "Checking if '$root_domain_name' is managed by the Plesk server..." - root_domain_id="$( _value "$output" | grep "$root_domain_name" | _head_n 1 | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/' )" + root_domain_id="$(_value "$output" | grep "$root_domain_name" | _head_n 1 | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" if [ -n "$root_domain_id" ]; then # Found a match - # Note that a result with host = empty string is OK for this API, see - # https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-dns/managing-dns-records/adding-dns-record.34798 - # See notes at top of this file - sub_domain_name="$( _value "$1" | sed -E "s/\.?${root_domain_name}"'$//' )" + # SEE IMPORTANT NOTE ABOVE - THIS FUNCTION CAN RETURN HOST='', AND THAT'S OK FOR PLESK XML API WHICH ALLOWS IT. + # SO WE HANDLE IT AND DON'T PREVENT IT + sub_domain_name="$(_value "$1" | sed -E "s/\.?${root_domain_name}"'$//')" _info "Matched host '$1' to: DOMAIN '${root_domain_name}' (Plesk ID '${root_domain_id}'), HOST '${sub_domain_name}'. Returning." return 0 fi @@ -379,11 +383,11 @@ _pleskxml_get_root_domain() { # No match, try next parent up (if any)... if _contains "$root_domain_name" '\.[^.]+\.'; then - _debug "No match, trying next parent up..." + _debug "No match, trying next parent up..." else _debug "No match,and next parent would be a TLD..." fi - root_domain_name="$( _valuecut 2 1000 "$root_domain_name" )" + root_domain_name="$(_valuecut 2 1000 "$root_domain_name")" doneloop=1 done From 9299a83b175c77feec281a8f8754283e8c6333a0 Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 01:10:03 +0000 Subject: [PATCH 0490/2234] Travis fixes --- dnsapi/dns_pleskxml | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/dnsapi/dns_pleskxml b/dnsapi/dns_pleskxml index bed1b26f..794127c7 100644 --- a/dnsapi/dns_pleskxml +++ b/dnsapi/dns_pleskxml @@ -30,8 +30,7 @@ ## ## The `pleskxml_uri`, `pleskxml_user` and `pleskxml_pass` will be saved in `~/.acme.sh/account.conf` and reused when needed. - -#################### INTERNAL VARIABLES + NEWLINE ################################## +#################### INTERNAL VARIABLES + NEWLINE + API TEMPLATES ################################## pleskxml_init_checks_done=0 @@ -40,9 +39,6 @@ pleskxml_init_checks_done=0 NEWLINE='\ ' - -#################### API Templates ################################## - pleskxml_tplt_get_domains="" # Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh # Also used to test credentials and URI. @@ -60,7 +56,6 @@ pleskxml_tplt_rmv_dns_record="%s # Add a TXT record to a domain. # ARG = the Plesk internal ID for the dns record to be deleted - #################### Public functions ################################## #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -141,7 +136,7 @@ dns_pleskxml_rm() { reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ | grep "${root_domain_id}" \ | grep -E '[0-9]+' \ - | grep 'TXT' \ + | grep 'TXT' )" if [ -z "$reclist" ]; then @@ -154,8 +149,8 @@ dns_pleskxml_rm() { recid="$(_value "$reclist" \ | grep "$1." \ | grep "$txtvalue" \ - | sed -E 's/(^.*|<\/id>.*$)//g' \ - )" + | sed -E 's/(^.*|<\/id>.*$)//g' + )" _debug "List of DNS TXT records for host:"'\n'"$(_value "$reclist" | grep "$1.")" @@ -193,8 +188,6 @@ dns_pleskxml_rm() { return 0 } - - #################### Private functions below ################################## # Outputs value of a variable @@ -202,7 +195,6 @@ _value() { printf '%s' "$1" } - # Outputs value of a variable (FQDN) and cuts it at 2 delimiters # $1, $2 = where to cut # $3 = FQDN @@ -210,20 +202,18 @@ _valuecut() { printf '%s' "$3" | cut -d . -f "${1}-${2}" } - # Cleans up an API response, splits it "per item" and greps for a string to validate useful lines # $1 - result string from API # $2 - tag to resplit on (usually "result" or "domain") # $3 - regex to recognise useful return lines _api_response_split() { printf '%s' "$1" \ - | sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' \ - | tr -d '\n\r' \ - | sed -E "s/<\/?$2>/${NEWLINE}/g" \ - | grep -E "$3" + | sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' \ + | tr -d '\n\r' \ + | sed -E "s/<\/?$2>/${NEWLINE}/g" \ + | grep -E "$3" } - # Calls Plesk XML API, and checks results for obvious issues _call_api() { request="$1" @@ -249,11 +239,11 @@ _call_api() { if _value "$statuslines" | grep -qv 'ok'; then # We have some status lines that aren't "ok". Get the details - errtext="$( _value "$pleskxml_prettyprint_result" \ + errtext="$(_value "$pleskxml_prettyprint_result" \ | grep -iE "(||)" \ | sed -E 's/(^[[:space:]]+|<\/[a-z]+$)//g' \ - | sed -E 's/^<([a-z]+)>/\1: /' \ - )" + | sed -E 's/^<([a-z]+)>/\1: /' + )" elif ! _value "$statuslines" | grep -q 'ok'; then @@ -278,10 +268,8 @@ _call_api() { return 0 } - +# Startup checks (credentials, URI) _credential_check() { - # Startup checks (credentials, URI) - _debug "Checking Plesk XML API login credentials and URI..." if [ "$pleskxml_init_checks_done" -eq 1 ]; then @@ -289,7 +277,6 @@ _credential_check() { return 0 fi - pleskxml_user="${pleskxml_user:-$(_readaccountconf_mutable pleskxml_user)}" pleskxml_pass="${pleskxml_pass:-$(_readaccountconf_mutable pleskxml_pass)}" pleskxml_uri="${pleskxml_uri:-$(_readaccountconf_mutable pleskxml_uri)}" @@ -325,7 +312,6 @@ _credential_check() { return 0 } - # For a FQDN, identify the root domain managed by Plesk, its domain ID in Plesk, and the host if any. # IMPORTANT NOTE: a result with host = empty string is OK for this API, see @@ -369,7 +355,7 @@ _pleskxml_get_root_domain() { _debug "Checking if '$root_domain_name' is managed by the Plesk server..." - root_domain_id="$(_value "$output" | grep "$root_domain_name" | _head_n 1 | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" + root_domain_id="$(_value "$output" | grep "$root_domain_name" | _head_n 1 | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" if [ -n "$root_domain_id" ]; then # Found a match From 6df31eb7f58f32428de4a57971b882421d19b3f5 Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 01:13:15 +0000 Subject: [PATCH 0491/2234] travis --- dnsapi/dns_pleskxml | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_pleskxml b/dnsapi/dns_pleskxml index 794127c7..83017c3b 100644 --- a/dnsapi/dns_pleskxml +++ b/dnsapi/dns_pleskxml @@ -77,7 +77,6 @@ dns_pleskxml_add() { _debug 'Credentials OK, and domain identified. Calling Plesk XML API to add TXT record' - # printf using template in a variable - not a style issue # shellcheck disable=SC2059 request="$(printf "$pleskxml_tplt_add_txt_record" "$root_domain_id" "$sub_domain_name" "$txtvalue")" From 1253357a39206dd43047bdbbbd341ffef1d735ab Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 01:48:02 +0000 Subject: [PATCH 0492/2234] edits to comments --- dnsapi/dns_pleskxml | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/dnsapi/dns_pleskxml b/dnsapi/dns_pleskxml index 83017c3b..e2ec5717 100644 --- a/dnsapi/dns_pleskxml +++ b/dnsapi/dns_pleskxml @@ -1,6 +1,6 @@ #!/usr/bin/env sh -## Name: dns_pleskxml.sh +## Name: dns_pleskxml ## Created by Stilez. ## Also uses some code from PR#1832 by @romanlum (https://github.com/Neilpang/acme.sh/pull/1832/files) @@ -13,14 +13,16 @@ ## For example, to add a TXT record to DNS alias domain "acme-alias.com" would be a valid Plesk action. ## So this API module can handle such a request, if needed. +## For ACME v2 purposes, new TXT records are appended when added, and removing one TXT record will not affect any other TXT records. + ## The plesk plugin uses the xml api to add and remvoe the dns records. Therefore the url, username ## and password have to be configured by the user before this module is called. ## ## ``` -## export pleskxml_uri="https://YOUR_PLESK_URI_HERE:8443/enterprise/control/agent.php" +## export pleskxml_uri="https://address-of-my-plesk-server.net:8443/enterprise/control/agent.php" ## (or probably something similar) -## export pleskxml_user="plesk username" -## export pleskxml_pass="plesk password" +## export pleskxml_user="my plesk username" +## export pleskxml_pass="my plesk password" ## ``` ## Ok, let's issue a cert now: @@ -42,19 +44,19 @@ NEWLINE='\ pleskxml_tplt_get_domains="" # Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh # Also used to test credentials and URI. -# No args. +# No params. pleskxml_tplt_get_dns_records="%s" # Get all DNS records for a Plesk domain ID. -# ARG = Plesk domain id to query +# PARAM = Plesk domain id to query pleskxml_tplt_add_txt_record="%sTXT%s%s" # Add a TXT record to a domain. -# ARGS = (1) Plesk internal domain ID, (2) "hostname" for the new record, eg '_acme_challenge', (3) TXT record value +# PARAMS = (1) Plesk internal domain ID, (2) "hostname" for the new record, eg '_acme_challenge', (3) TXT record value pleskxml_tplt_rmv_dns_record="%s" -# Add a TXT record to a domain. -# ARG = the Plesk internal ID for the dns record to be deleted +# Delete a specific TXT record from a domain. +# PARAM = the Plesk internal ID for the DNS record to be deleted #################### Public functions ################################## @@ -63,7 +65,7 @@ dns_pleskxml_add() { fulldomain=$1 txtvalue=$2 - _info "Entering dns_pleskxml_add() to add TXT record '$2' to domain '$1'..." + _info "Entering dns_pleskxml_add() to add TXT record '$txtvalue' to domain '$fulldomain'..." # Get credentials if not already checked, and confirm we can log in to Plesk XML API if ! _credential_check; then @@ -110,7 +112,7 @@ dns_pleskxml_rm() { fulldomain=$1 txtvalue=$2 - _info "Entering dns_pleskxml_rm() to remove TXT record '$2' from domain '$1'..." + _info "Entering dns_pleskxml_rm() to remove TXT record '$txtvalue' from domain '$fulldomain'..." # Get credentials if not already checked, and confirm we can log in to Plesk XML API if ! _credential_check; then @@ -189,19 +191,19 @@ dns_pleskxml_rm() { #################### Private functions below ################################## -# Outputs value of a variable +# Outputs value of a variable without additional newlines etc _value() { printf '%s' "$1" } -# Outputs value of a variable (FQDN) and cuts it at 2 delimiters +# Outputs value of a variable (FQDN) and cuts it at 2 specified '.' delimiters, returning the text in between # $1, $2 = where to cut # $3 = FQDN _valuecut() { printf '%s' "$3" | cut -d . -f "${1}-${2}" } -# Cleans up an API response, splits it "per item" and greps for a string to validate useful lines +# Cleans up an API response, splits it "one line per item in the response" and greps for a string that in the context, identifies "useful" lines # $1 - result string from API # $2 - tag to resplit on (usually "result" or "domain") # $3 - regex to recognise useful return lines @@ -228,8 +230,6 @@ _call_api() { pleskxml_retcode="$?" _debug "acme _post() returned retcode=$pleskxml_retcode. Literal response:" '\n' "'${pleskxml_prettyprint_result}'" - # Error handling - # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. @@ -320,7 +320,7 @@ _credential_check() { _pleskxml_get_root_domain() { _debug "Identifying DNS root domain for '$1' that is managed by the Plesk account." - # test if the domain is valid for splitting. + # test if the domain as provided is valid for splitting. if _value "$root_domain_name" | grep -qvE '^[^.]+\.[^.]+\.[^.]'; then _err "Invalid domain. The ACME domain must contain at least two parts (aa.bb) to identify a domain and tld for the TXT record." @@ -334,10 +334,10 @@ _pleskxml_get_root_domain() { return 1 fi - # Generate a hacked list of domains known to this Plesk account. + # Generate a crude list of domains known to this Plesk account. # We convert tags to so it'll flag on a hit with either or fields, # for non-Western character sets. - # Output will be one line per known domain, containing 1 or 2 tages and an tag + # Output will be one line per known domain, containing 2 tages and a single tag # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed -E 's/<(\/?)ascii-name>/<\1name>/g' | grep '' | grep '')" @@ -345,7 +345,7 @@ _pleskxml_get_root_domain() { _debug 'Domains managed by Plesk server are (ignore the hacked output):\n' "$output" # loop and test if domain, or any parent domain, is managed by Plesk - # Loop until we don't have any '.' in the sring we're testing as a root domain + # Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain root_domain_name="$1" doneloop=0 @@ -378,7 +378,7 @@ _pleskxml_get_root_domain() { done # if we get here, we failed to find a root domain match in the list of domains managed by Plesk. - # if we never ran the loop a first time, $1 wasn't at least a 2 level domain (domain.tld) and wasn't valid anyway + # if we never ran the loop even once, $1 wasn't a 2nd level (or deeper) domain (e.g. domain.tld) and wasn't valid anyway if [ -z $doneloop ]; then _err "'$1' isn't a valid domain for ACME DNS. Exiting." From 671edc33e173b0318972d7eb4fd50d03fbde85cd Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 27 Oct 2019 11:43:40 +0800 Subject: [PATCH 0493/2234] fix background color --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 37ce15aa..07dc63d2 100755 --- a/acme.sh +++ b/acme.sh @@ -153,7 +153,7 @@ fi __green() { if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then - printf '\033[1;31;32m%b\033[0m' "$1" + printf '\33[1;32m%b\33[0m' "$1" return fi printf -- "%b" "$1" @@ -161,7 +161,7 @@ __green() { __red() { if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then - printf '\033[1;31;40m%b\033[0m' "$1" + printf '\33[1;31m%b\33[0m' "$1" return fi printf -- "%b" "$1" From 9eb5f65b8f272b71fdf2d69a33492e67b5b76836 Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 07:38:22 +0000 Subject: [PATCH 0494/2234] edit comments --- dnsapi/dns_pleskxml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml b/dnsapi/dns_pleskxml index e2ec5717..d613f8e1 100644 --- a/dnsapi/dns_pleskxml +++ b/dnsapi/dns_pleskxml @@ -60,7 +60,7 @@ pleskxml_tplt_rmv_dns_record="%s #################### Public functions ################################## -#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Usage: dns_pleskxml_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_pleskxml_add() { fulldomain=$1 txtvalue=$2 @@ -107,7 +107,7 @@ dns_pleskxml_add() { return 0 } -#Usage: rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Usage: dns_pleskxml_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_pleskxml_rm() { fulldomain=$1 txtvalue=$2 From 582c77805c837962129ea5372a664658739a13e1 Mon Sep 17 00:00:00 2001 From: peterkelm Date: Sun, 27 Oct 2019 13:13:22 +0100 Subject: [PATCH 0495/2234] variomedia dns api initial commit for the variomedia dns api implementation --- dnsapi/dns_variomedia.sh | 166 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 dnsapi/dns_variomedia.sh diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh new file mode 100644 index 00000000..56f1bf96 --- /dev/null +++ b/dnsapi/dns_variomedia.sh @@ -0,0 +1,166 @@ +#!/usr/bin/env sh + +# +#VARIOMEDIA_API_TOKEN=000011112222333344445555666677778888 + +VARIOMEDIA_API="https://api.variomedia.de" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_variomedia_add() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + VARIOMEDIA_API_TOKEN="${VARIOMEDIA_API_TOKEN:-$(_readaccountconf_mutable VARIOMEDIA_API_TOKEN)}" + if test -z "$VARIOMEDIA_API_TOKEN"; then + VARIOMEDIA_API_TOKEN="" + _err 'VARIOMEDIA_API_TOKEN was not exported' + return 1 + fi + + _saveaccountconf_mutable VARIOMEDIA_API_TOKEN "$VARIOMEDIA_API_TOKEN" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + +# _debug 'Getting txt records' +# _variomedia_rest GET "/dns-records?filter[domain]=$_domain" + +# if printf "%s\n" "$response" | grep "\"record_type\": \"A\", \"fqdn\": \"$fulldomain\"" >/dev/null; then +# _err 'Error' +# return 1 +# fi + + if ! _variomedia_rest POST "dns-records" "{\"data\": {\"type\": \"dns-record\", \"attributes\": {\"record_type\": \"TXT\", \"name\": \"$_sub_domain\", \"domain\": \"$_domain\", \"data\": \"$txtvalue\", \"ttl\":300}}}"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + return 0 +} + +#fulldomain txtvalue +dns_variomedia_rm() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + VARIOMEDIA_API_TOKEN="${VARIOMEDIA_API_TOKEN:-$(_readaccountconf_mutable VARIOMEDIA_API_TOKEN)}" + if test -z "$VARIOMEDIA_API_TOKEN"; then + VARIOMEDIA_API_TOKEN="" + _err 'VARIOMEDIA_API_TOKEN was not exported' + return 1 + fi + + _saveaccountconf_mutable VARIOMEDIA_API_TOKEN "$VARIOMEDIA_API_TOKEN" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug 'Getting txt records' + + if ! _variomedia_rest GET "dns-records?filter[domain]=$_domain"; then + _err 'Error' + return 1 + fi + + _record_id="$(echo $response | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep $_sub_domain | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')" + _debug _record_id "$_record_id" + if [ "$_record_id" ]; then + _info "Successfully retrieved the record id for ACME challenge." + else + _info "Empty record id, it seems no such record." + return 0 + fi + + if ! _variomedia_rest DELETE "/dns-records/$_record_id"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + return 0 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + fulldomain=$1 + i=1 + while true; do + h=$(printf "%s" "$fulldomain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + return 1 + fi + + if ! _variomedia_rest GET "domains/$h"; then + return 1 + fi + + if _startswith "$response" "\{\"data\":"; then + if _contains "$response" "\"id\": \"$h\""; then + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$h\$//")" + _domain=$h + return 0 +# else +# _err 'Invalid domain' +# return 1 + fi +# else +# _err "$response" +# return 1 + fi + i=$(_math "$i" + 1) + done + + _debug "root domain not found" + + return 1 +} + +_variomedia_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + +# api_key_trimmed=$(echo $VARIOMEDIA_API_TOKEN | tr -d '"') + +# export _H1="Api-Key: $api_key_trimmed" + + export _H1="Authorization: token $VARIOMEDIA_API_TOKEN" + export _H2="Content-Type: application/vnd.api+json" + export _H3="Accept: application/vnd.variomedia.v1+json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$VARIOMEDIA_API/$ep" "" "$m")" + else + response="$(_get "$VARIOMEDIA_API/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "Error $ep" + return 1 + fi + + _debug2 response "$response" + return 0 +} From 1271f97b669ee66727293beea3f2a39da2899e04 Mon Sep 17 00:00:00 2001 From: peterkelm Date: Sun, 27 Oct 2019 16:52:51 +0100 Subject: [PATCH 0496/2234] fixed dns_variomedia_rm for wildcard certs fixed dns_variomedia_rm to respect the txtvalue supplied as function parameter --- dnsapi/dns_variomedia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index 56f1bf96..2e822a0d 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -77,7 +77,7 @@ dns_variomedia_rm() { return 1 fi - _record_id="$(echo $response | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep $_sub_domain | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')" + _record_id="$(echo $response | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep $_sub_domain | grep $txtvalue | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')" _debug _record_id "$_record_id" if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." From c1b089d1c3adb314daf29a084c3bf13042e72c7f Mon Sep 17 00:00:00 2001 From: peterkelm Date: Sun, 27 Oct 2019 16:58:36 +0100 Subject: [PATCH 0497/2234] unused code removed --- dnsapi/dns_variomedia.sh | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index 2e822a0d..8588d7c8 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -30,14 +30,6 @@ dns_variomedia_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" -# _debug 'Getting txt records' -# _variomedia_rest GET "/dns-records?filter[domain]=$_domain" - -# if printf "%s\n" "$response" | grep "\"record_type\": \"A\", \"fqdn\": \"$fulldomain\"" >/dev/null; then -# _err 'Error' -# return 1 -# fi - if ! _variomedia_rest POST "dns-records" "{\"data\": {\"type\": \"dns-record\", \"attributes\": {\"record_type\": \"TXT\", \"name\": \"$_sub_domain\", \"domain\": \"$_domain\", \"data\": \"$txtvalue\", \"ttl\":300}}}"; then _err "$response" return 1 @@ -119,13 +111,7 @@ _get_root() { _sub_domain="$(echo "$fulldomain" | sed "s/\\.$h\$//")" _domain=$h return 0 -# else -# _err 'Invalid domain' -# return 1 fi -# else -# _err "$response" -# return 1 fi i=$(_math "$i" + 1) done @@ -141,10 +127,6 @@ _variomedia_rest() { data="$3" _debug "$ep" -# api_key_trimmed=$(echo $VARIOMEDIA_API_TOKEN | tr -d '"') - -# export _H1="Api-Key: $api_key_trimmed" - export _H1="Authorization: token $VARIOMEDIA_API_TOKEN" export _H2="Content-Type: application/vnd.api+json" export _H3="Accept: application/vnd.variomedia.v1+json" From bc291141b13a802ac0190ba06946ef2fa9add768 Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 16:58:22 +0000 Subject: [PATCH 0498/2234] fix filename --- dnsapi/dns_pleskxml.sh | 391 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 391 insertions(+) create mode 100644 dnsapi/dns_pleskxml.sh diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh new file mode 100644 index 00000000..25d1e6dc --- /dev/null +++ b/dnsapi/dns_pleskxml.sh @@ -0,0 +1,391 @@ +#!/usr/bin/env sh + +## Name: dns_pleskxml.sh +## Created by Stilez. +## Also uses some code from PR#1832 by @romanlum (https://github.com/Neilpang/acme.sh/pull/1832/files) + +## This DNS01 method uses the Plesk XML API described at: +## https://docs.plesk.com/en-US/12.5/api-rpc/about-xml-api.28709 +## and more specifically: https://docs.plesk.com/en-US/12.5/api-rpc/reference.28784 + +## Note: a DNS ID with host = empty string is OK for this API, see +## https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-dns/managing-dns-records/adding-dns-record.34798 +## For example, to add a TXT record to DNS alias domain "acme-alias.com" would be a valid Plesk action. +## So this API module can handle such a request, if needed. + +## For ACME v2 purposes, new TXT records are appended when added, and removing one TXT record will not affect any other TXT records. + +## The plesk plugin uses the xml api to add and remvoe the dns records. Therefore the url, username +## and password have to be configured by the user before this module is called. +## +## ``` +## export pleskxml_uri="https://address-of-my-plesk-server.net:8443/enterprise/control/agent.php" +## (or probably something similar) +## export pleskxml_user="my plesk username" +## export pleskxml_pass="my plesk password" +## ``` + +## Ok, let's issue a cert now: +## ``` +## acme.sh --issue --dns dns_pleskxml -d example.com -d www.example.com +## ``` +## +## The `pleskxml_uri`, `pleskxml_user` and `pleskxml_pass` will be saved in `~/.acme.sh/account.conf` and reused when needed. + +#################### INTERNAL VARIABLES + NEWLINE + API TEMPLATES ################################## + +pleskxml_init_checks_done=0 + +# Variable containing bare newline - not a style issue +# shellcheck disable=SC1004 +NEWLINE='\ +' + +pleskxml_tplt_get_domains="" +# Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh +# Also used to test credentials and URI. +# No params. + +pleskxml_tplt_get_dns_records="%s" +# Get all DNS records for a Plesk domain ID. +# PARAM = Plesk domain id to query + +pleskxml_tplt_add_txt_record="%sTXT%s%s" +# Add a TXT record to a domain. +# PARAMS = (1) Plesk internal domain ID, (2) "hostname" for the new record, eg '_acme_challenge', (3) TXT record value + +pleskxml_tplt_rmv_dns_record="%s" +# Delete a specific TXT record from a domain. +# PARAM = the Plesk internal ID for the DNS record to be deleted + +#################### Public functions ################################## + +#Usage: dns_pleskxml_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_pleskxml_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Entering dns_pleskxml_add() to add TXT record '$txtvalue' to domain '$fulldomain'..." + + # Get credentials if not already checked, and confirm we can log in to Plesk XML API + if ! _credential_check; then + return 1 + fi + + # Get root and subdomain details, and Plesk domain ID + if ! _pleskxml_get_root_domain "$fulldomain"; then + return 1 + fi + + _debug 'Credentials OK, and domain identified. Calling Plesk XML API to add TXT record' + + # printf using template in a variable - not a style issue + # shellcheck disable=SC2059 + request="$(printf "$pleskxml_tplt_add_txt_record" "$root_domain_id" "$sub_domain_name" "$txtvalue")" + if ! _call_api "$request"; then + return 1 + fi + + # OK, we should have added a TXT record. Let's check and return success if so. + # All that should be left in the result, is one section, containing okNEW_DNS_RECORD_ID + + results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" + + if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then + # Error - doesn't contain expected string. Something's wrong. + _err 'Error when calling Plesk XML API.' + _err 'The result did not contain the expected XXXXX section, or contained other values as well.' + _err 'This is unexpected: something has gone wrong.' + _err 'The full response was:\n' "$pleskxml_prettyprint_result" + return 1 + fi + + recid="$(_value "$results" | grep -E '[0-9]+' | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" + + _info "Success. TXT record appears to be correctly added (Plesk record ID=$recid). Exiting dns_pleskxml_add()." + + return 0 +} + +#Usage: dns_pleskxml_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_pleskxml_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Entering dns_pleskxml_rm() to remove TXT record '$txtvalue' from domain '$fulldomain'..." + + # Get credentials if not already checked, and confirm we can log in to Plesk XML API + if ! _credential_check; then + return 1 + fi + + # Get root and subdomain details, and Plesk domain ID + if ! _pleskxml_get_root_domain "$fulldomain"; then + return 1 + fi + + _debug 'Credentials OK, and domain identified. Calling Plesk XML API to get list of TXT records and their IDs' + + # printf using template in a variable - not a style issue + # shellcheck disable=SC2059 + request="$(printf "$pleskxml_tplt_get_dns_records" "$root_domain_id")" + if ! _call_api "$request"; then + return 1 + fi + + # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) + reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ + | grep "${root_domain_id}" \ + | grep -E '[0-9]+' \ + | grep 'TXT' + )" + + if [ -z "$reclist" ]; then + _err "No TXT records found for root domain ${root_domain_name} (Plesk domain ID ${root_domain_id}). Exiting." + return 1 + fi + + _debug "Got list of DNS TXT records for root domain '$root_domain_name'"':\n'"$reclist" + + recid="$(_value "$reclist" \ + | grep "$1." \ + | grep "$txtvalue" \ + | sed -E 's/(^.*|<\/id>.*$)//g' + )" + + _debug "List of DNS TXT records for host:"'\n'"$(_value "$reclist" | grep "$1.")" + + if ! _value "$recid" | grep -Eq '^[0-9]+$'; then + _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" + _err "Cannot delete TXT record. Exiting." + return 1 + fi + + _debug "Found Plesk record ID for target text string '${txtvalue}': ID=${recid}" + _debug 'Calling Plesk XML API to remove TXT record' + + # printf using template in a variable - not a style issue + # shellcheck disable=SC2059 + request="$(printf "$pleskxml_tplt_rmv_dns_record" "$recid")" + if ! _call_api "$request"; then + return 1 + fi + + # OK, we should have removed a TXT record. Let's check and return success if so. + # All that should be left in the result, is one section, containing okPLESK_DELETED_DNS_RECORD_ID + + results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" + + if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then + # Error - doesn't contain expected string. Something's wrong. + _err 'Error when calling Plesk XML API.' + _err 'The result did not contain the expected XXXXX section, or contained other values as well.' + _err 'This is unexpected: something has gone wrong.' + _err 'The full response was:\n' "$pleskxml_prettyprint_result" + return 1 + fi + + _info "Success. TXT record appears to be correctly removed. Exiting dns_pleskxml_rm()." + return 0 +} + +#################### Private functions below ################################## + +# Outputs value of a variable without additional newlines etc +_value() { + printf '%s' "$1" +} + +# Outputs value of a variable (FQDN) and cuts it at 2 specified '.' delimiters, returning the text in between +# $1, $2 = where to cut +# $3 = FQDN +_valuecut() { + printf '%s' "$3" | cut -d . -f "${1}-${2}" +} + +# Cleans up an API response, splits it "one line per item in the response" and greps for a string that in the context, identifies "useful" lines +# $1 - result string from API +# $2 - tag to resplit on (usually "result" or "domain") +# $3 - regex to recognise useful return lines +_api_response_split() { + printf '%s' "$1" \ + | sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' \ + | tr -d '\n\r' \ + | sed -E "s/<\/?$2>/${NEWLINE}/g" \ + | grep -E "$3" +} + +# Calls Plesk XML API, and checks results for obvious issues +_call_api() { + request="$1" + errtext='' + + _debug 'Entered _call_api(). Calling Plesk XML API with request:\n' "'${request}'" + + export _H1="HTTP_AUTH_LOGIN: $pleskxml_user" + export _H2="HTTP_AUTH_PASSWD: $pleskxml_pass" + export _H3="content-Type: text/xml" + export _H4="HTTP_PRETTY_PRINT: true" + pleskxml_prettyprint_result="$(_post "${request}" "$pleskxml_uri" "" "POST")" + pleskxml_retcode="$?" + _debug "acme _post() returned retcode=$pleskxml_retcode. Literal response:" '\n' "'${pleskxml_prettyprint_result}'" + + # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. + # Also detect if there simply aren't any status lines (null result?) and report that, as well. + + statuslines="$(echo "$pleskxml_prettyprint_result" | grep -E '^[[:space:]]*[^<]*[[:space:]]*$')" + + if _value "$statuslines" | grep -qv 'ok'; then + + # We have some status lines that aren't "ok". Get the details + errtext="$(_value "$pleskxml_prettyprint_result" \ + | grep -iE "(||)" \ + | sed -E 's/(^[[:space:]]+|<\/[a-z]+$)//g' \ + | sed -E 's/^<([a-z]+)>/\1: /' + )" + + elif ! _value "$statuslines" | grep -q 'ok'; then + + # We have no status lines at all. Results are empty + errtext='The Plesk XML API unexpectedly returned an empty set of results for this call.' + + fi + + if [ "$pleskxml_retcode" -ne 0 ] || [ "$errtext" != "" ]; then + _err "The Plesk XML API call failed." + _err "The return code for the POST request was $pleskxml_retcode (0=success)." + if [ "$errtext" != "" ]; then + _err 'Status and error messages received from the Plesk server:\n' "$errtext" + else + _err "No additional error messages were received back from the Plesk server" + fi + return 1 + fi + + _debug "Leaving _call_api(). Successful call." + + return 0 +} + +# Startup checks (credentials, URI) +_credential_check() { + _debug "Checking Plesk XML API login credentials and URI..." + + if [ "$pleskxml_init_checks_done" -eq 1 ]; then + _debug "Initial checks already done, no need to repeat. Skipped." + return 0 + fi + + pleskxml_user="${pleskxml_user:-$(_readaccountconf_mutable pleskxml_user)}" + pleskxml_pass="${pleskxml_pass:-$(_readaccountconf_mutable pleskxml_pass)}" + pleskxml_uri="${pleskxml_uri:-$(_readaccountconf_mutable pleskxml_uri)}" + + _debug "Credentials - User: '${pleskxml_user}' Passwd: ****** URI: '${pleskxml_uri}'" + + if [ -z "$pleskxml_user" ] || [ -z "$pleskxml_pass" ] || [ -z "$pleskxml_uri" ]; then + pleskxml_user="" + pleskxml_pass="" + pleskxml_uri="" + _err "You didn't specify one or more of the Plesk XML API username, password, or URI." + _err "Please create these and try again." + _err "Instructions are in the module source code." + return 1 + fi + + # Test the API is usable, by trying to read the list of managed domains... + _call_api "$pleskxml_tplt_get_domains" + if [ "$pleskxml_retcode" -ne 0 ]; then + _err '\nFailed to access Plesk XML API.' + _err "Please check your login credentials and Plesk URI, and that the URI is reachable, and try again." + return 1 + fi + + _saveaccountconf_mutable pleskxml_uri "$pleskxml_uri" + _saveaccountconf_mutable pleskxml_user "$pleskxml_user" + _saveaccountconf_mutable pleskxml_pass "$pleskxml_pass" + + _debug "Test login to Plesk XML API successful. Login credentials and URI successfully saved to the acme.sh configuration file for future use." + + pleskxml_init_checks_done=1 + + return 0 +} + +# For a FQDN, identify the root domain managed by Plesk, its domain ID in Plesk, and the host if any. + +# IMPORTANT NOTE: a result with host = empty string is OK for this API, see +# https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-dns/managing-dns-records/adding-dns-record.34798 +# See notes at top of this file + +_pleskxml_get_root_domain() { + _debug "Identifying DNS root domain for '$1' that is managed by the Plesk account." + + # test if the domain as provided is valid for splitting. + + if _value "$root_domain_name" | grep -qvE '^[^.]+\.[^.]+\.[^.]'; then + _err "Invalid domain. The ACME domain must contain at least two parts (aa.bb) to identify a domain and tld for the TXT record." + return 1 + fi + + _debug "Querying Plesk server for list of managed domains..." + + _call_api "$pleskxml_tplt_get_domains" + if [ "$pleskxml_retcode" -ne 0 ]; then + return 1 + fi + + # Generate a crude list of domains known to this Plesk account. + # We convert tags to so it'll flag on a hit with either or fields, + # for non-Western character sets. + # Output will be one line per known domain, containing 2 tages and a single tag + # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. + + output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed -E 's/<(\/?)ascii-name>/<\1name>/g' | grep '' | grep '')" + + _debug 'Domains managed by Plesk server are (ignore the hacked output):\n' "$output" + + # loop and test if domain, or any parent domain, is managed by Plesk + # Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain + + root_domain_name="$1" + doneloop=0 + + while _contains "$root_domain_name" '\.'; do + + _debug "Checking if '$root_domain_name' is managed by the Plesk server..." + + root_domain_id="$(_value "$output" | grep "$root_domain_name" | _head_n 1 | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" + + if [ -n "$root_domain_id" ]; then + # Found a match + # SEE IMPORTANT NOTE ABOVE - THIS FUNCTION CAN RETURN HOST='', AND THAT'S OK FOR PLESK XML API WHICH ALLOWS IT. + # SO WE HANDLE IT AND DON'T PREVENT IT + sub_domain_name="$(_value "$1" | sed -E "s/\.?${root_domain_name}"'$//')" + _info "Matched host '$1' to: DOMAIN '${root_domain_name}' (Plesk ID '${root_domain_id}'), HOST '${sub_domain_name}'. Returning." + return 0 + fi + + # No match, try next parent up (if any)... + + if _contains "$root_domain_name" '\.[^.]+\.'; then + _debug "No match, trying next parent up..." + else + _debug "No match,and next parent would be a TLD..." + fi + root_domain_name="$(_valuecut 2 1000 "$root_domain_name")" + doneloop=1 + + done + + # if we get here, we failed to find a root domain match in the list of domains managed by Plesk. + # if we never ran the loop even once, $1 wasn't a 2nd level (or deeper) domain (e.g. domain.tld) and wasn't valid anyway + + if [ -z $doneloop ]; then + _err "'$1' isn't a valid domain for ACME DNS. Exiting." + else + _err "Cannot find '$1' or any parent domain of it, in Plesk." + _err "Are you sure that this domain is managed by this Plesk server?" + fi + + return 1 +} From 7c09bdc6e0dde113a241d1526ede4b9a01a7f864 Mon Sep 17 00:00:00 2001 From: stilez Date: Sun, 27 Oct 2019 16:58:58 +0000 Subject: [PATCH 0499/2234] renamed --- dnsapi/dns_pleskxml | 391 -------------------------------------------- 1 file changed, 391 deletions(-) delete mode 100644 dnsapi/dns_pleskxml diff --git a/dnsapi/dns_pleskxml b/dnsapi/dns_pleskxml deleted file mode 100644 index d613f8e1..00000000 --- a/dnsapi/dns_pleskxml +++ /dev/null @@ -1,391 +0,0 @@ -#!/usr/bin/env sh - -## Name: dns_pleskxml -## Created by Stilez. -## Also uses some code from PR#1832 by @romanlum (https://github.com/Neilpang/acme.sh/pull/1832/files) - -## This DNS01 method uses the Plesk XML API described at: -## https://docs.plesk.com/en-US/12.5/api-rpc/about-xml-api.28709 -## and more specifically: https://docs.plesk.com/en-US/12.5/api-rpc/reference.28784 - -## Note: a DNS ID with host = empty string is OK for this API, see -## https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-dns/managing-dns-records/adding-dns-record.34798 -## For example, to add a TXT record to DNS alias domain "acme-alias.com" would be a valid Plesk action. -## So this API module can handle such a request, if needed. - -## For ACME v2 purposes, new TXT records are appended when added, and removing one TXT record will not affect any other TXT records. - -## The plesk plugin uses the xml api to add and remvoe the dns records. Therefore the url, username -## and password have to be configured by the user before this module is called. -## -## ``` -## export pleskxml_uri="https://address-of-my-plesk-server.net:8443/enterprise/control/agent.php" -## (or probably something similar) -## export pleskxml_user="my plesk username" -## export pleskxml_pass="my plesk password" -## ``` - -## Ok, let's issue a cert now: -## ``` -## acme.sh --issue --dns dns_pleskxml -d example.com -d www.example.com -## ``` -## -## The `pleskxml_uri`, `pleskxml_user` and `pleskxml_pass` will be saved in `~/.acme.sh/account.conf` and reused when needed. - -#################### INTERNAL VARIABLES + NEWLINE + API TEMPLATES ################################## - -pleskxml_init_checks_done=0 - -# Variable containing bare newline - not a style issue -# shellcheck disable=SC1004 -NEWLINE='\ -' - -pleskxml_tplt_get_domains="" -# Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh -# Also used to test credentials and URI. -# No params. - -pleskxml_tplt_get_dns_records="%s" -# Get all DNS records for a Plesk domain ID. -# PARAM = Plesk domain id to query - -pleskxml_tplt_add_txt_record="%sTXT%s%s" -# Add a TXT record to a domain. -# PARAMS = (1) Plesk internal domain ID, (2) "hostname" for the new record, eg '_acme_challenge', (3) TXT record value - -pleskxml_tplt_rmv_dns_record="%s" -# Delete a specific TXT record from a domain. -# PARAM = the Plesk internal ID for the DNS record to be deleted - -#################### Public functions ################################## - -#Usage: dns_pleskxml_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_pleskxml_add() { - fulldomain=$1 - txtvalue=$2 - - _info "Entering dns_pleskxml_add() to add TXT record '$txtvalue' to domain '$fulldomain'..." - - # Get credentials if not already checked, and confirm we can log in to Plesk XML API - if ! _credential_check; then - return 1 - fi - - # Get root and subdomain details, and Plesk domain ID - if ! _pleskxml_get_root_domain "$fulldomain"; then - return 1 - fi - - _debug 'Credentials OK, and domain identified. Calling Plesk XML API to add TXT record' - - # printf using template in a variable - not a style issue - # shellcheck disable=SC2059 - request="$(printf "$pleskxml_tplt_add_txt_record" "$root_domain_id" "$sub_domain_name" "$txtvalue")" - if ! _call_api "$request"; then - return 1 - fi - - # OK, we should have added a TXT record. Let's check and return success if so. - # All that should be left in the result, is one section, containing okNEW_DNS_RECORD_ID - - results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - - if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then - # Error - doesn't contain expected string. Something's wrong. - _err 'Error when calling Plesk XML API.' - _err 'The result did not contain the expected XXXXX section, or contained other values as well.' - _err 'This is unexpected: something has gone wrong.' - _err 'The full response was:\n' "$pleskxml_prettyprint_result" - return 1 - fi - - recid="$(_value "$results" | grep -E '[0-9]+' | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" - - _info "Success. TXT record appears to be correctly added (Plesk record ID=$recid). Exiting dns_pleskxml_add()." - - return 0 -} - -#Usage: dns_pleskxml_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_pleskxml_rm() { - fulldomain=$1 - txtvalue=$2 - - _info "Entering dns_pleskxml_rm() to remove TXT record '$txtvalue' from domain '$fulldomain'..." - - # Get credentials if not already checked, and confirm we can log in to Plesk XML API - if ! _credential_check; then - return 1 - fi - - # Get root and subdomain details, and Plesk domain ID - if ! _pleskxml_get_root_domain "$fulldomain"; then - return 1 - fi - - _debug 'Credentials OK, and domain identified. Calling Plesk XML API to get list of TXT records and their IDs' - - # printf using template in a variable - not a style issue - # shellcheck disable=SC2059 - request="$(printf "$pleskxml_tplt_get_dns_records" "$root_domain_id")" - if ! _call_api "$request"; then - return 1 - fi - - # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) - reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ - | grep "${root_domain_id}" \ - | grep -E '[0-9]+' \ - | grep 'TXT' - )" - - if [ -z "$reclist" ]; then - _err "No TXT records found for root domain ${root_domain_name} (Plesk domain ID ${root_domain_id}). Exiting." - return 1 - fi - - _debug "Got list of DNS TXT records for root domain '$root_domain_name'"':\n'"$reclist" - - recid="$(_value "$reclist" \ - | grep "$1." \ - | grep "$txtvalue" \ - | sed -E 's/(^.*|<\/id>.*$)//g' - )" - - _debug "List of DNS TXT records for host:"'\n'"$(_value "$reclist" | grep "$1.")" - - if ! _value "$recid" | grep -Eq '^[0-9]+$'; then - _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" - _err "Cannot delete TXT record. Exiting." - return 1 - fi - - _debug "Found Plesk record ID for target text string '${txtvalue}': ID=${recid}" - _debug 'Calling Plesk XML API to remove TXT record' - - # printf using template in a variable - not a style issue - # shellcheck disable=SC2059 - request="$(printf "$pleskxml_tplt_rmv_dns_record" "$recid")" - if ! _call_api "$request"; then - return 1 - fi - - # OK, we should have removed a TXT record. Let's check and return success if so. - # All that should be left in the result, is one section, containing okPLESK_DELETED_DNS_RECORD_ID - - results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - - if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then - # Error - doesn't contain expected string. Something's wrong. - _err 'Error when calling Plesk XML API.' - _err 'The result did not contain the expected XXXXX section, or contained other values as well.' - _err 'This is unexpected: something has gone wrong.' - _err 'The full response was:\n' "$pleskxml_prettyprint_result" - return 1 - fi - - _info "Success. TXT record appears to be correctly removed. Exiting dns_pleskxml_rm()." - return 0 -} - -#################### Private functions below ################################## - -# Outputs value of a variable without additional newlines etc -_value() { - printf '%s' "$1" -} - -# Outputs value of a variable (FQDN) and cuts it at 2 specified '.' delimiters, returning the text in between -# $1, $2 = where to cut -# $3 = FQDN -_valuecut() { - printf '%s' "$3" | cut -d . -f "${1}-${2}" -} - -# Cleans up an API response, splits it "one line per item in the response" and greps for a string that in the context, identifies "useful" lines -# $1 - result string from API -# $2 - tag to resplit on (usually "result" or "domain") -# $3 - regex to recognise useful return lines -_api_response_split() { - printf '%s' "$1" \ - | sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' \ - | tr -d '\n\r' \ - | sed -E "s/<\/?$2>/${NEWLINE}/g" \ - | grep -E "$3" -} - -# Calls Plesk XML API, and checks results for obvious issues -_call_api() { - request="$1" - errtext='' - - _debug 'Entered _call_api(). Calling Plesk XML API with request:\n' "'${request}'" - - export _H1="HTTP_AUTH_LOGIN: $pleskxml_user" - export _H2="HTTP_AUTH_PASSWD: $pleskxml_pass" - export _H3="content-Type: text/xml" - export _H4="HTTP_PRETTY_PRINT: true" - pleskxml_prettyprint_result="$(_post "${request}" "$pleskxml_uri" "" "POST")" - pleskxml_retcode="$?" - _debug "acme _post() returned retcode=$pleskxml_retcode. Literal response:" '\n' "'${pleskxml_prettyprint_result}'" - - # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. - # Also detect if there simply aren't any status lines (null result?) and report that, as well. - - statuslines="$(echo "$pleskxml_prettyprint_result" | grep -E '^[[:space:]]*[^<]*[[:space:]]*$')" - - if _value "$statuslines" | grep -qv 'ok'; then - - # We have some status lines that aren't "ok". Get the details - errtext="$(_value "$pleskxml_prettyprint_result" \ - | grep -iE "(||)" \ - | sed -E 's/(^[[:space:]]+|<\/[a-z]+$)//g' \ - | sed -E 's/^<([a-z]+)>/\1: /' - )" - - elif ! _value "$statuslines" | grep -q 'ok'; then - - # We have no status lines at all. Results are empty - errtext='The Plesk XML API unexpectedly returned an empty set of results for this call.' - - fi - - if [ "$pleskxml_retcode" -ne 0 ] || [ "$errtext" != "" ]; then - _err "The Plesk XML API call failed." - _err "The return code for the POST request was $pleskxml_retcode (0=success)." - if [ "$errtext" != "" ]; then - _err 'Status and error messages received from the Plesk server:\n' "$errtext" - else - _err "No additional error messages were received back from the Plesk server" - fi - return 1 - fi - - _debug "Leaving _call_api(). Successful call." - - return 0 -} - -# Startup checks (credentials, URI) -_credential_check() { - _debug "Checking Plesk XML API login credentials and URI..." - - if [ "$pleskxml_init_checks_done" -eq 1 ]; then - _debug "Initial checks already done, no need to repeat. Skipped." - return 0 - fi - - pleskxml_user="${pleskxml_user:-$(_readaccountconf_mutable pleskxml_user)}" - pleskxml_pass="${pleskxml_pass:-$(_readaccountconf_mutable pleskxml_pass)}" - pleskxml_uri="${pleskxml_uri:-$(_readaccountconf_mutable pleskxml_uri)}" - - _debug "Credentials - User: '${pleskxml_user}' Passwd: ****** URI: '${pleskxml_uri}'" - - if [ -z "$pleskxml_user" ] || [ -z "$pleskxml_pass" ] || [ -z "$pleskxml_uri" ]; then - pleskxml_user="" - pleskxml_pass="" - pleskxml_uri="" - _err "You didn't specify one or more of the Plesk XML API username, password, or URI." - _err "Please create these and try again." - _err "Instructions are in the module source code." - return 1 - fi - - # Test the API is usable, by trying to read the list of managed domains... - _call_api "$pleskxml_tplt_get_domains" - if [ "$pleskxml_retcode" -ne 0 ]; then - _err '\nFailed to access Plesk XML API.' - _err "Please check your login credentials and Plesk URI, and that the URI is reachable, and try again." - return 1 - fi - - _saveaccountconf_mutable pleskxml_uri "$pleskxml_uri" - _saveaccountconf_mutable pleskxml_user "$pleskxml_user" - _saveaccountconf_mutable pleskxml_pass "$pleskxml_pass" - - _debug "Test login to Plesk XML API successful. Login credentials and URI successfully saved to the acme.sh configuration file for future use." - - pleskxml_init_checks_done=1 - - return 0 -} - -# For a FQDN, identify the root domain managed by Plesk, its domain ID in Plesk, and the host if any. - -# IMPORTANT NOTE: a result with host = empty string is OK for this API, see -# https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-dns/managing-dns-records/adding-dns-record.34798 -# See notes at top of this file - -_pleskxml_get_root_domain() { - _debug "Identifying DNS root domain for '$1' that is managed by the Plesk account." - - # test if the domain as provided is valid for splitting. - - if _value "$root_domain_name" | grep -qvE '^[^.]+\.[^.]+\.[^.]'; then - _err "Invalid domain. The ACME domain must contain at least two parts (aa.bb) to identify a domain and tld for the TXT record." - return 1 - fi - - _debug "Querying Plesk server for list of managed domains..." - - _call_api "$pleskxml_tplt_get_domains" - if [ "$pleskxml_retcode" -ne 0 ]; then - return 1 - fi - - # Generate a crude list of domains known to this Plesk account. - # We convert tags to so it'll flag on a hit with either or fields, - # for non-Western character sets. - # Output will be one line per known domain, containing 2 tages and a single tag - # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. - - output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed -E 's/<(\/?)ascii-name>/<\1name>/g' | grep '' | grep '')" - - _debug 'Domains managed by Plesk server are (ignore the hacked output):\n' "$output" - - # loop and test if domain, or any parent domain, is managed by Plesk - # Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain - - root_domain_name="$1" - doneloop=0 - - while _contains "$root_domain_name" '\.'; do - - _debug "Checking if '$root_domain_name' is managed by the Plesk server..." - - root_domain_id="$(_value "$output" | grep "$root_domain_name" | _head_n 1 | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" - - if [ -n "$root_domain_id" ]; then - # Found a match - # SEE IMPORTANT NOTE ABOVE - THIS FUNCTION CAN RETURN HOST='', AND THAT'S OK FOR PLESK XML API WHICH ALLOWS IT. - # SO WE HANDLE IT AND DON'T PREVENT IT - sub_domain_name="$(_value "$1" | sed -E "s/\.?${root_domain_name}"'$//')" - _info "Matched host '$1' to: DOMAIN '${root_domain_name}' (Plesk ID '${root_domain_id}'), HOST '${sub_domain_name}'. Returning." - return 0 - fi - - # No match, try next parent up (if any)... - - if _contains "$root_domain_name" '\.[^.]+\.'; then - _debug "No match, trying next parent up..." - else - _debug "No match,and next parent would be a TLD..." - fi - root_domain_name="$(_valuecut 2 1000 "$root_domain_name")" - doneloop=1 - - done - - # if we get here, we failed to find a root domain match in the list of domains managed by Plesk. - # if we never ran the loop even once, $1 wasn't a 2nd level (or deeper) domain (e.g. domain.tld) and wasn't valid anyway - - if [ -z $doneloop ]; then - _err "'$1' isn't a valid domain for ACME DNS. Exiting." - else - _err "Cannot find '$1' or any parent domain of it, in Plesk." - _err "Are you sure that this domain is managed by this Plesk server?" - fi - - return 1 -} From a22d3b239070ddc573a283bf2a709e68a12d2085 Mon Sep 17 00:00:00 2001 From: scottkof Date: Mon, 28 Oct 2019 06:32:08 -0700 Subject: [PATCH 0500/2234] Switch from `sleep` to `_sleep` --- dnsapi/dns_aws.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 54b1bb3a..6db87666 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -6,7 +6,7 @@ #AWS_SECRET_ACCESS_KEY="xxxxxxx" #This is the Amazon Route53 api wrapper for acme.sh -#All `sleep` commands are included to avoid Route53 throttling, see +#All `_sleep` commands are included to avoid Route53 throttling, see #https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests AWS_HOST="route53.amazonaws.com" @@ -45,7 +45,7 @@ dns_aws_add() { _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" - sleep 1 + _sleep 1 return 1 fi _debug _domain_id "$_domain_id" @@ -54,7 +54,7 @@ dns_aws_add() { _info "Getting existing records for $fulldomain" if ! aws_rest GET "2013-04-01$_domain_id/rrset" "name=$fulldomain&type=TXT"; then - sleep 1 + _sleep 1 return 1 fi @@ -67,7 +67,7 @@ dns_aws_add() { if [ "$_resource_record" ] && _contains "$response" "$txtvalue"; then _info "The TXT record already exists. Skipping." - sleep 1 + _sleep 1 return 0 fi @@ -77,10 +77,10 @@ dns_aws_add() { if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then _info "TXT record updated successfully." - sleep 1 + _sleep 1 return 0 fi - sleep 1 + _sleep 1 return 1 } @@ -99,7 +99,7 @@ dns_aws_rm() { _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" - sleep 1 + _sleep 1 return 1 fi _debug _domain_id "$_domain_id" @@ -108,7 +108,7 @@ dns_aws_rm() { _info "Getting existing records for $fulldomain" if ! aws_rest GET "2013-04-01$_domain_id/rrset" "name=$fulldomain&type=TXT"; then - sleep 1 + _sleep 1 return 1 fi @@ -117,7 +117,7 @@ dns_aws_rm() { _debug "_resource_record" "$_resource_record" else _debug "no records exist, skip" - sleep 1 + _sleep 1 return 0 fi @@ -125,10 +125,10 @@ dns_aws_rm() { if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then _info "TXT record deleted successfully." - sleep 1 + _sleep 1 return 0 fi - sleep 1 + _sleep 1 return 1 } From d7affad05981f3fdc59ecf1f30e4455f06cc9f5a Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 29 Oct 2019 10:30:00 +0000 Subject: [PATCH 0501/2234] various small improves --- dnsapi/dns_pleskxml.sh | 73 +++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 25d1e6dc..bd6eaa87 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -189,7 +189,7 @@ dns_pleskxml_rm() { return 0 } -#################### Private functions below ################################## +#################### Private functions below (utility functions) ################################## # Outputs value of a variable without additional newlines etc _value() { @@ -203,6 +203,12 @@ _valuecut() { printf '%s' "$3" | cut -d . -f "${1}-${2}" } +# Counts '.' present in a domain name +# $1 = domain name +_countdots() { + _value "$1" | tr -dc '.' | wc -c +} + # Cleans up an API response, splits it "one line per item in the response" and greps for a string that in the context, identifies "useful" lines # $1 - result string from API # $2 - tag to resplit on (usually "result" or "domain") @@ -215,6 +221,8 @@ _api_response_split() { | grep -E "$3" } +#################### Private functions below (DNS functions) ################################## + # Calls Plesk XML API, and checks results for obvious issues _call_api() { request="$1" @@ -228,7 +236,7 @@ _call_api() { export _H4="HTTP_PRETTY_PRINT: true" pleskxml_prettyprint_result="$(_post "${request}" "$pleskxml_uri" "" "POST")" pleskxml_retcode="$?" - _debug "acme _post() returned retcode=$pleskxml_retcode. Literal response:" '\n' "'${pleskxml_prettyprint_result}'" + _debug 'The responses from the Plesk XML server were:\n' "retcode=$pleskxml_retcode. Literal response:"'\n' "'$pleskxml_prettyprint_result'" # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. @@ -239,9 +247,9 @@ _call_api() { # We have some status lines that aren't "ok". Get the details errtext="$(_value "$pleskxml_prettyprint_result" \ - | grep -iE "(||)" \ - | sed -E 's/(^[[:space:]]+|<\/[a-z]+$)//g' \ - | sed -E 's/^<([a-z]+)>/\1: /' + | grep -E "(||)" \ + | sed -E 's/^<(status|errcode|errtext)>/\1: /' \ + | sed -E 's/(^[[:space:]]+|<\/(status|errcode|errtext)>$)//g' \ )" elif ! _value "$statuslines" | grep -q 'ok'; then @@ -252,14 +260,23 @@ _call_api() { fi if [ "$pleskxml_retcode" -ne 0 ] || [ "$errtext" != "" ]; then - _err "The Plesk XML API call failed." - _err "The return code for the POST request was $pleskxml_retcode (0=success)." + # Call failed, for reasons either in the retcode or the response text... + + if [ "$pleskxml_retcode" -eq 0 ]; then + _err "The POST request was successfully sent to the Plesk server." + else + _err "The return code for the POST request was $pleskxml_retcode (non-zero = could not submit request to server)." + fi + if [ "$errtext" != "" ]; then - _err 'Status and error messages received from the Plesk server:\n' "$errtext" + _err 'The error responses received from the Plesk server were:\n' "$errtext" else _err "No additional error messages were received back from the Plesk server" fi + + _err "The Plesk XML API call failed." return 1 + fi _debug "Leaving _call_api(). Successful call." @@ -319,10 +336,12 @@ _credential_check() { _pleskxml_get_root_domain() { _debug "Identifying DNS root domain for '$1' that is managed by the Plesk account." + original_full_domain_name="$1" + root_domain_name="$1" # test if the domain as provided is valid for splitting. - if _value "$root_domain_name" | grep -qvE '^[^.]+\.[^.]+\.[^.]'; then + if ! _countdots "$root_domain_name"; then _err "Invalid domain. The ACME domain must contain at least two parts (aa.bb) to identify a domain and tld for the TXT record." return 1 fi @@ -347,10 +366,7 @@ _pleskxml_get_root_domain() { # loop and test if domain, or any parent domain, is managed by Plesk # Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain - root_domain_name="$1" - doneloop=0 - - while _contains "$root_domain_name" '\.'; do + while true; do _debug "Checking if '$root_domain_name' is managed by the Plesk server..." @@ -360,32 +376,23 @@ _pleskxml_get_root_domain() { # Found a match # SEE IMPORTANT NOTE ABOVE - THIS FUNCTION CAN RETURN HOST='', AND THAT'S OK FOR PLESK XML API WHICH ALLOWS IT. # SO WE HANDLE IT AND DON'T PREVENT IT - sub_domain_name="$(_value "$1" | sed -E "s/\.?${root_domain_name}"'$//')" - _info "Matched host '$1' to: DOMAIN '${root_domain_name}' (Plesk ID '${root_domain_id}'), HOST '${sub_domain_name}'. Returning." + sub_domain_name="$(_value "$original_full_domain_name" | sed -E "s/\.?${root_domain_name}"'$//')" + _info "Success. Matched host '$original_full_domain_name' to: DOMAIN '${root_domain_name}' (Plesk ID '${root_domain_id}'), HOST '${sub_domain_name}'. Returning." return 0 fi # No match, try next parent up (if any)... - if _contains "$root_domain_name" '\.[^.]+\.'; then - _debug "No match, trying next parent up..." - else - _debug "No match,and next parent would be a TLD..." - fi root_domain_name="$(_valuecut 2 1000 "$root_domain_name")" - doneloop=1 + + if ! _countdots "$root_domain_name"; then + _debug "No match, and next parent would be a TLD..." + _err "Cannot find '$original_full_domain_name' or any parent domain of it, in Plesk." + _err "Are you sure that this domain is managed by this Plesk server?" + return 1 + fi + + _debug "No match, trying next parent up..." done - - # if we get here, we failed to find a root domain match in the list of domains managed by Plesk. - # if we never ran the loop even once, $1 wasn't a 2nd level (or deeper) domain (e.g. domain.tld) and wasn't valid anyway - - if [ -z $doneloop ]; then - _err "'$1' isn't a valid domain for ACME DNS. Exiting." - else - _err "Cannot find '$1' or any parent domain of it, in Plesk." - _err "Are you sure that this domain is managed by this Plesk server?" - fi - - return 1 } From b7c3df455e275a6fa0556d178c48f944666410bf Mon Sep 17 00:00:00 2001 From: stilez Date: Wed, 30 Oct 2019 09:38:03 +0000 Subject: [PATCH 0502/2234] travis fix --- dnsapi/dns_pleskxml.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index bd6eaa87..aa1da6f4 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -249,7 +249,7 @@ _call_api() { errtext="$(_value "$pleskxml_prettyprint_result" \ | grep -E "(||)" \ | sed -E 's/^<(status|errcode|errtext)>/\1: /' \ - | sed -E 's/(^[[:space:]]+|<\/(status|errcode|errtext)>$)//g' \ + | sed -E 's/(^[[:space:]]+|<\/(status|errcode|errtext)>$)//g' )" elif ! _value "$statuslines" | grep -q 'ok'; then From 05ced9fbc4edf0c2d3bbe9913209e6c750702cad Mon Sep 17 00:00:00 2001 From: stilez Date: Wed, 30 Oct 2019 09:53:40 +0000 Subject: [PATCH 0503/2234] edit a comment --- dnsapi/dns_pleskxml.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index aa1da6f4..24650d10 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -4,7 +4,7 @@ ## Created by Stilez. ## Also uses some code from PR#1832 by @romanlum (https://github.com/Neilpang/acme.sh/pull/1832/files) -## This DNS01 method uses the Plesk XML API described at: +## This DNS-01 method uses the Plesk XML API described at: ## https://docs.plesk.com/en-US/12.5/api-rpc/about-xml-api.28709 ## and more specifically: https://docs.plesk.com/en-US/12.5/api-rpc/reference.28784 @@ -15,8 +15,8 @@ ## For ACME v2 purposes, new TXT records are appended when added, and removing one TXT record will not affect any other TXT records. -## The plesk plugin uses the xml api to add and remvoe the dns records. Therefore the url, username -## and password have to be configured by the user before this module is called. +## The user credentials (username+password) and URL/URI for the Plesk XML API must be set by the user +## before this module is called (case sensitive): ## ## ``` ## export pleskxml_uri="https://address-of-my-plesk-server.net:8443/enterprise/control/agent.php" From 3441bd0e7c476a5add8dbfec730b5fa25b7a9f7e Mon Sep 17 00:00:00 2001 From: stilez Date: Wed, 30 Oct 2019 10:22:04 +0000 Subject: [PATCH 0504/2234] improve _err message and remove a dubious _debug message. --- dnsapi/dns_pleskxml.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 24650d10..8a957e40 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -297,15 +297,13 @@ _credential_check() { pleskxml_pass="${pleskxml_pass:-$(_readaccountconf_mutable pleskxml_pass)}" pleskxml_uri="${pleskxml_uri:-$(_readaccountconf_mutable pleskxml_uri)}" - _debug "Credentials - User: '${pleskxml_user}' Passwd: ****** URI: '${pleskxml_uri}'" - if [ -z "$pleskxml_user" ] || [ -z "$pleskxml_pass" ] || [ -z "$pleskxml_uri" ]; then pleskxml_user="" pleskxml_pass="" pleskxml_uri="" _err "You didn't specify one or more of the Plesk XML API username, password, or URI." _err "Please create these and try again." - _err "Instructions are in the module source code." + _err "Instructions are in the 'dns_pleskxml' plugin source code or in the acme.sh documentation." return 1 fi From 2422e0b481b74e008fc995afd4e1994d6f0817e4 Mon Sep 17 00:00:00 2001 From: stilez Date: Wed, 30 Oct 2019 17:01:06 +0000 Subject: [PATCH 0505/2234] grep -E and sed -E --- dnsapi/dns_pleskxml.sh | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 8a957e40..03c58534 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -91,7 +91,7 @@ dns_pleskxml_add() { results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then + if ! _value "$results" | grep 'ok' | egrep -q '[0-9]+'; then # Error - doesn't contain expected string. Something's wrong. _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' @@ -100,7 +100,7 @@ dns_pleskxml_add() { return 1 fi - recid="$(_value "$results" | grep -E '[0-9]+' | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" + recid="$(_value "$results" | egrep '[0-9]+' | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" _info "Success. TXT record appears to be correctly added (Plesk record ID=$recid). Exiting dns_pleskxml_add()." @@ -136,7 +136,7 @@ dns_pleskxml_rm() { # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ | grep "${root_domain_id}" \ - | grep -E '[0-9]+' \ + | egrep '[0-9]+' \ | grep 'TXT' )" @@ -150,12 +150,12 @@ dns_pleskxml_rm() { recid="$(_value "$reclist" \ | grep "$1." \ | grep "$txtvalue" \ - | sed -E 's/(^.*|<\/id>.*$)//g' + | sed -r 's/(^.*|<\/id>.*$)//g' )" _debug "List of DNS TXT records for host:"'\n'"$(_value "$reclist" | grep "$1.")" - if ! _value "$recid" | grep -Eq '^[0-9]+$'; then + if ! _value "$recid" | egrep -q '^[0-9]+$'; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" _err "Cannot delete TXT record. Exiting." return 1 @@ -176,7 +176,7 @@ dns_pleskxml_rm() { results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - if ! _value "$results" | grep 'ok' | grep -qE '[0-9]+'; then + if ! _value "$results" | grep 'ok' | egrep -q '[0-9]+'; then # Error - doesn't contain expected string. Something's wrong. _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' @@ -215,10 +215,10 @@ _countdots() { # $3 - regex to recognise useful return lines _api_response_split() { printf '%s' "$1" \ - | sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' \ + | sed -r 's/(^[[:space:]]+|[[:space:]]+$)//g' \ | tr -d '\n\r' \ - | sed -E "s/<\/?$2>/${NEWLINE}/g" \ - | grep -E "$3" + | sed -r "s/<\/?$2>/${NEWLINE}/g" \ + | egrep "$3" } #################### Private functions below (DNS functions) ################################## @@ -241,15 +241,15 @@ _call_api() { # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. - statuslines="$(echo "$pleskxml_prettyprint_result" | grep -E '^[[:space:]]*[^<]*[[:space:]]*$')" + statuslines="$(echo "$pleskxml_prettyprint_result" | egrep '^[[:space:]]*[^<]*[[:space:]]*$')" if _value "$statuslines" | grep -qv 'ok'; then # We have some status lines that aren't "ok". Get the details errtext="$(_value "$pleskxml_prettyprint_result" \ - | grep -E "(||)" \ - | sed -E 's/^<(status|errcode|errtext)>/\1: /' \ - | sed -E 's/(^[[:space:]]+|<\/(status|errcode|errtext)>$)//g' + | egrep "(||)" \ + | sed -r 's/^<(status|errcode|errtext)>/\1: /' \ + | sed -r 's/(^[[:space:]]+|<\/(status|errcode|errtext)>$)//g' )" elif ! _value "$statuslines" | grep -q 'ok'; then @@ -357,7 +357,7 @@ _pleskxml_get_root_domain() { # Output will be one line per known domain, containing 2 tages and a single tag # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. - output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed -E 's/<(\/?)ascii-name>/<\1name>/g' | grep '' | grep '')" + output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed -r 's/<(\/?)ascii-name>/<\1name>/g' | grep '' | grep '')" _debug 'Domains managed by Plesk server are (ignore the hacked output):\n' "$output" @@ -368,13 +368,13 @@ _pleskxml_get_root_domain() { _debug "Checking if '$root_domain_name' is managed by the Plesk server..." - root_domain_id="$(_value "$output" | grep "$root_domain_name" | _head_n 1 | sed -E 's/^.*([0-9]+)<\/id>.*$/\1/')" + root_domain_id="$(_value "$output" | grep "$root_domain_name" | _head_n 1 | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" if [ -n "$root_domain_id" ]; then # Found a match # SEE IMPORTANT NOTE ABOVE - THIS FUNCTION CAN RETURN HOST='', AND THAT'S OK FOR PLESK XML API WHICH ALLOWS IT. # SO WE HANDLE IT AND DON'T PREVENT IT - sub_domain_name="$(_value "$original_full_domain_name" | sed -E "s/\.?${root_domain_name}"'$//')" + sub_domain_name="$(_value "$original_full_domain_name" | sed -r "s/\.?${root_domain_name}"'$//')" _info "Success. Matched host '$original_full_domain_name' to: DOMAIN '${root_domain_name}' (Plesk ID '${root_domain_id}'), HOST '${sub_domain_name}'. Returning." return 0 fi From a32b95544ba8aa385251f757940c93f3fef266c0 Mon Sep 17 00:00:00 2001 From: stilez Date: Wed, 30 Oct 2019 17:06:03 +0000 Subject: [PATCH 0506/2234] [[:space:]] -> " " --- dnsapi/dns_pleskxml.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 03c58534..12f56316 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -215,7 +215,7 @@ _countdots() { # $3 - regex to recognise useful return lines _api_response_split() { printf '%s' "$1" \ - | sed -r 's/(^[[:space:]]+|[[:space:]]+$)//g' \ + | sed -r 's/(^ +| +$)//g' \ | tr -d '\n\r' \ | sed -r "s/<\/?$2>/${NEWLINE}/g" \ | egrep "$3" @@ -241,15 +241,15 @@ _call_api() { # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. - statuslines="$(echo "$pleskxml_prettyprint_result" | egrep '^[[:space:]]*[^<]*[[:space:]]*$')" + statuslines="$(echo "$pleskxml_prettyprint_result" | egrep '^ *[^<]* *$')" if _value "$statuslines" | grep -qv 'ok'; then # We have some status lines that aren't "ok". Get the details errtext="$(_value "$pleskxml_prettyprint_result" \ | egrep "(||)" \ - | sed -r 's/^<(status|errcode|errtext)>/\1: /' \ - | sed -r 's/(^[[:space:]]+|<\/(status|errcode|errtext)>$)//g' + | sed -r 's/^ *<(status|errcode|errtext)>/\1: /' \ + | sed -r 's/<\/(status|errcode|errtext)>$//g' )" elif ! _value "$statuslines" | grep -q 'ok'; then From dca6a4bbd57eed4b87f24cb7f1644fb5a51c2327 Mon Sep 17 00:00:00 2001 From: peterkelm Date: Wed, 30 Oct 2019 20:51:16 +0100 Subject: [PATCH 0507/2234] minor formatting changes --- dnsapi/dns_variomedia.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index 8588d7c8..ecc9ea4c 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -5,9 +5,9 @@ VARIOMEDIA_API="https://api.variomedia.de" -######## Public functions ##################### +######## Public functions ##################### -#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_variomedia_add() { fulldomain=$1 txtvalue=$2 @@ -69,7 +69,7 @@ dns_variomedia_rm() { return 1 fi - _record_id="$(echo $response | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep $_sub_domain | grep $txtvalue | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')" + _record_id="$(echo $response | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep "$_sub_domain" | grep "$txtvalue" | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')" _debug _record_id "$_record_id" if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." @@ -87,7 +87,7 @@ dns_variomedia_rm() { return 0 } -#################### Private functions below ################################## +#################### Private functions below ################################## #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www @@ -117,7 +117,6 @@ _get_root() { done _debug "root domain not found" - return 1 } From 343d7df57c366fe594edf8f4a523611a18cb0ac2 Mon Sep 17 00:00:00 2001 From: stilez Date: Wed, 30 Oct 2019 22:11:16 +0000 Subject: [PATCH 0508/2234] shellcheck directive --- dnsapi/dns_pleskxml.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 12f56316..c12b2eeb 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -1,5 +1,9 @@ #!/usr/bin/env sh +# Globally disable this shellcheck error. +# Shellcheck errors on egrep ("deprecated"), but acme.sh uses egrep for compatibility. +# shellcheck disable=SC2196 + ## Name: dns_pleskxml.sh ## Created by Stilez. ## Also uses some code from PR#1832 by @romanlum (https://github.com/Neilpang/acme.sh/pull/1832/files) From bec26ce754fb575a6969c917cd8fd5fa212a800e Mon Sep 17 00:00:00 2001 From: peterkelm Date: Thu, 31 Oct 2019 09:03:35 +0100 Subject: [PATCH 0509/2234] Shellcheck'd --- dnsapi/dns_variomedia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index ecc9ea4c..729cda5e 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -69,7 +69,7 @@ dns_variomedia_rm() { return 1 fi - _record_id="$(echo $response | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep "$_sub_domain" | grep "$txtvalue" | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')" + _record_id="$(echo "$response" | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep "$_sub_domain" | grep "$txtvalue" | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')" _debug _record_id "$_record_id" if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." From fee9baca895cecf5cb7a6d94791b655f09c73684 Mon Sep 17 00:00:00 2001 From: Johann Richard <189003+johannrichard@users.noreply.github.com> Date: Fri, 1 Nov 2019 17:59:40 +0100 Subject: [PATCH 0510/2234] Add openssh package * `acme.sh`'s `ssh.sh` is probably one of the hooks that's most versatile * By default, it's not installed on `alpine` docker images and therefore is lacking in the `acme.sh` docker image * This change adds the `openssh` package and therefore the `ssh` and associated commands --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index a6e37999..02dd5030 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,7 @@ FROM alpine:3.10 RUN apk update -f \ && apk --no-cache add -f \ openssl \ + openssh \ coreutils \ bind-tools \ curl \ From 5698bec6213d8c1ffa8c3c30b1587c8f982638c8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 2 Nov 2019 09:48:41 +0800 Subject: [PATCH 0511/2234] fix https://github.com/Neilpang/acme.sh/issues/2566 --- acme.sh | 2 +- notify/dingtalk.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 notify/dingtalk.sh diff --git a/acme.sh b/acme.sh index 07dc63d2..78604337 100755 --- a/acme.sh +++ b/acme.sh @@ -6070,7 +6070,7 @@ _send_notify() { _set_notify_hook() { _nhooks="$1" - _test_subject="Hello, this is notification from $PROJECT_NAME" + _test_subject="Hello, this is a notification from $PROJECT_NAME" _test_content="If you receive this message, your notification works." _send_notify "$_test_subject" "$_test_content" "$_nhooks" 0 diff --git a/notify/dingtalk.sh b/notify/dingtalk.sh new file mode 100644 index 00000000..7d354da2 --- /dev/null +++ b/notify/dingtalk.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env sh + +#Support dingtalk webhooks api + +#DINGTALK_WEBHOOK="xxxx" + +#optional +#DINGTALK_KEYWORD="yyyy" + +#DINGTALK_SIGNING_KEY="SEC08ffdbd403cbc3fc8a65xxxxxxxxxxxxxxxxxxxx" + +# subject content statusCode +dingtalk_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + DINGTALK_WEBHOOK="${DINGTALK_WEBHOOK:-$(_readaccountconf_mutable DINGTALK_WEBHOOK)}" + if [ -z "$DINGTALK_WEBHOOK" ]; then + DINGTALK_WEBHOOK="" + _err "You didn't specify a dingtalk webhooks DINGTALK_WEBHOOK yet." + _err "You can get yours from https://dingtalk.com" + return 1 + fi + _saveaccountconf_mutable DINGTALK_WEBHOOK "$DINGTALK_WEBHOOK" + + DINGTALK_KEYWORD="${DINGTALK_KEYWORD:-$(_readaccountconf_mutable DINGTALK_KEYWORD)}" + if [ "$DINGTALK_KEYWORD" ]; then + _saveaccountconf_mutable DINGTALK_KEYWORD "$DINGTALK_KEYWORD" + fi + +# DINGTALK_SIGNING_KEY="${DINGTALK_SIGNING_KEY:-$(_readaccountconf_mutable DINGTALK_SIGNING_KEY)}" +# if [ -z "$DINGTALK_SIGNING_KEY" ]; then +# DINGTALK_SIGNING_KEY="value1" +# _info "The DINGTALK_SIGNING_KEY is not set, so use the default value1 as key." +# elif ! _hasfield "$_IFTTT_AVAIL_MSG_KEYS" "$DINGTALK_SIGNING_KEY"; then +# _err "The DINGTALK_SIGNING_KEY \"$DINGTALK_SIGNING_KEY\" is not available, should be one of $_IFTTT_AVAIL_MSG_KEYS" +# DINGTALK_SIGNING_KEY="" +# return 1 +# else +# _saveaccountconf_mutable DINGTALK_SIGNING_KEY "$DINGTALK_SIGNING_KEY" +# fi + +# if [ "$DINGTALK_SIGNING_KEY" = "$IFTTT_CONTENT_KEY" ]; then +# DINGTALK_SIGNING_KEY="" +# IFTTT_CONTENT_KEY="" +# _err "The DINGTALK_SIGNING_KEY must not be same as IFTTT_CONTENT_KEY." +# return 1 +# fi + + _content=$(echo "$_content" | _json_encode) + _subject=$(echo "$_subject" | _json_encode) + _data="{\"msgtype\": \"text\", \"text\": {\"content\": \"[$DINGTALK_KEYWORD]\n$_subject\n$_content\"}}" + + response="$(_post "$_data" "$DINGTALK_WEBHOOK" "" "POST" "application/json")" + + if [ "$?" = "0" ] && _contains "$response" "errmsg\":\"ok"; then + _info "dingtalk webhooks event fired success." + return 0 + fi + + _err "dingtalk webhooks event fired error." + _err "$response" + return 1 +} + From 05acf28e0ddb47b5eab3a3c32ed69f7813237736 Mon Sep 17 00:00:00 2001 From: Johann Richard <189003+johannrichard@users.noreply.github.com> Date: Sat, 2 Nov 2019 07:10:50 +0100 Subject: [PATCH 0512/2234] Update Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 02dd5030..5112bf07 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM alpine:3.10 RUN apk update -f \ && apk --no-cache add -f \ openssl \ - openssh \ + openssh-client \ coreutils \ bind-tools \ curl \ From 35b34c43ed26ec2ad08ff004823f5b408e6a3401 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 2 Nov 2019 19:44:43 +0800 Subject: [PATCH 0513/2234] fix format --- notify/dingtalk.sh | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/notify/dingtalk.sh b/notify/dingtalk.sh index 7d354da2..c547da6e 100644 --- a/notify/dingtalk.sh +++ b/notify/dingtalk.sh @@ -32,24 +32,24 @@ dingtalk_send() { _saveaccountconf_mutable DINGTALK_KEYWORD "$DINGTALK_KEYWORD" fi -# DINGTALK_SIGNING_KEY="${DINGTALK_SIGNING_KEY:-$(_readaccountconf_mutable DINGTALK_SIGNING_KEY)}" -# if [ -z "$DINGTALK_SIGNING_KEY" ]; then -# DINGTALK_SIGNING_KEY="value1" -# _info "The DINGTALK_SIGNING_KEY is not set, so use the default value1 as key." -# elif ! _hasfield "$_IFTTT_AVAIL_MSG_KEYS" "$DINGTALK_SIGNING_KEY"; then -# _err "The DINGTALK_SIGNING_KEY \"$DINGTALK_SIGNING_KEY\" is not available, should be one of $_IFTTT_AVAIL_MSG_KEYS" -# DINGTALK_SIGNING_KEY="" -# return 1 -# else -# _saveaccountconf_mutable DINGTALK_SIGNING_KEY "$DINGTALK_SIGNING_KEY" -# fi + # DINGTALK_SIGNING_KEY="${DINGTALK_SIGNING_KEY:-$(_readaccountconf_mutable DINGTALK_SIGNING_KEY)}" + # if [ -z "$DINGTALK_SIGNING_KEY" ]; then + # DINGTALK_SIGNING_KEY="value1" + # _info "The DINGTALK_SIGNING_KEY is not set, so use the default value1 as key." + # elif ! _hasfield "$_IFTTT_AVAIL_MSG_KEYS" "$DINGTALK_SIGNING_KEY"; then + # _err "The DINGTALK_SIGNING_KEY \"$DINGTALK_SIGNING_KEY\" is not available, should be one of $_IFTTT_AVAIL_MSG_KEYS" + # DINGTALK_SIGNING_KEY="" + # return 1 + # else + # _saveaccountconf_mutable DINGTALK_SIGNING_KEY "$DINGTALK_SIGNING_KEY" + # fi -# if [ "$DINGTALK_SIGNING_KEY" = "$IFTTT_CONTENT_KEY" ]; then -# DINGTALK_SIGNING_KEY="" -# IFTTT_CONTENT_KEY="" -# _err "The DINGTALK_SIGNING_KEY must not be same as IFTTT_CONTENT_KEY." -# return 1 -# fi + # if [ "$DINGTALK_SIGNING_KEY" = "$IFTTT_CONTENT_KEY" ]; then + # DINGTALK_SIGNING_KEY="" + # IFTTT_CONTENT_KEY="" + # _err "The DINGTALK_SIGNING_KEY must not be same as IFTTT_CONTENT_KEY." + # return 1 + # fi _content=$(echo "$_content" | _json_encode) _subject=$(echo "$_subject" | _json_encode) @@ -66,4 +66,3 @@ dingtalk_send() { _err "$response" return 1 } - From 6eaf2d67b7588f23f1870c8813d3d6d391820b89 Mon Sep 17 00:00:00 2001 From: Kukushkin Alexander Date: Fri, 16 Nov 2018 08:30:44 +0300 Subject: [PATCH 0514/2234] Fix Vscale --- dnsapi/dns_vscale.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_vscale.sh b/dnsapi/dns_vscale.sh index e50b7d8b..d717d6e2 100755 --- a/dnsapi/dns_vscale.sh +++ b/dnsapi/dns_vscale.sh @@ -102,7 +102,7 @@ _get_root() { return 1 fi - hostedzone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")" + hostedzone="$(echo "$response" | tr "{" "\n" | _egrep_o "\"name\":\s*\"$h\".*}")" if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then From 2d1a776db792e475dfdedc3a3bfde7b649d8fa7e Mon Sep 17 00:00:00 2001 From: stilez Date: Mon, 4 Nov 2019 18:40:12 +0000 Subject: [PATCH 0515/2234] Replace egrep -> basic regex grep (( ... isn't it annoying that basic regex has * but not + ..... )) --- dnsapi/dns_pleskxml.sh | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index c12b2eeb..f3d6a1de 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -1,9 +1,5 @@ #!/usr/bin/env sh -# Globally disable this shellcheck error. -# Shellcheck errors on egrep ("deprecated"), but acme.sh uses egrep for compatibility. -# shellcheck disable=SC2196 - ## Name: dns_pleskxml.sh ## Created by Stilez. ## Also uses some code from PR#1832 by @romanlum (https://github.com/Neilpang/acme.sh/pull/1832/files) @@ -95,7 +91,7 @@ dns_pleskxml_add() { results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - if ! _value "$results" | grep 'ok' | egrep -q '[0-9]+'; then + if ! _value "$results" | grep 'ok' | grep -q '[0-9][0-9]*'; then # Error - doesn't contain expected string. Something's wrong. _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' @@ -104,7 +100,7 @@ dns_pleskxml_add() { return 1 fi - recid="$(_value "$results" | egrep '[0-9]+' | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" + recid="$(_value "$results" | grep '[0-9][0-9]*' | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" _info "Success. TXT record appears to be correctly added (Plesk record ID=$recid). Exiting dns_pleskxml_add()." @@ -140,7 +136,7 @@ dns_pleskxml_rm() { # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ | grep "${root_domain_id}" \ - | egrep '[0-9]+' \ + | grep '[0-9][0-9]*' \ | grep 'TXT' )" @@ -159,7 +155,7 @@ dns_pleskxml_rm() { _debug "List of DNS TXT records for host:"'\n'"$(_value "$reclist" | grep "$1.")" - if ! _value "$recid" | egrep -q '^[0-9]+$'; then + if ! _value "$recid" | grep -q '^[0-9][0-9]*$'; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" _err "Cannot delete TXT record. Exiting." return 1 @@ -180,7 +176,7 @@ dns_pleskxml_rm() { results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - if ! _value "$results" | grep 'ok' | egrep -q '[0-9]+'; then + if ! _value "$results" | grep 'ok' | grep -q '[0-9][0-9]*'; then # Error - doesn't contain expected string. Something's wrong. _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' @@ -216,13 +212,16 @@ _countdots() { # Cleans up an API response, splits it "one line per item in the response" and greps for a string that in the context, identifies "useful" lines # $1 - result string from API # $2 - tag to resplit on (usually "result" or "domain") -# $3 - regex to recognise useful return lines +# $3 - basic regex to recognise useful return lines +# note: $3 matches via basic NOT extended regex (BRE), as extended regex capabilities not needed at the moment. +# Last line could change to instead, with suitablew ewscaping of ['"/$], +# if future Plesk XML API changes ever require extended regex _api_response_split() { printf '%s' "$1" \ | sed -r 's/(^ +| +$)//g' \ | tr -d '\n\r' \ | sed -r "s/<\/?$2>/${NEWLINE}/g" \ - | egrep "$3" + | grep "$3" } #################### Private functions below (DNS functions) ################################## @@ -245,15 +244,13 @@ _call_api() { # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. - statuslines="$(echo "$pleskxml_prettyprint_result" | egrep '^ *[^<]* *$')" + statuslines="$(echo "$pleskxml_prettyprint_result" | grep '^ *[^<]* *$')" if _value "$statuslines" | grep -qv 'ok'; then # We have some status lines that aren't "ok". Get the details errtext="$(_value "$pleskxml_prettyprint_result" \ - | egrep "(||)" \ - | sed -r 's/^ *<(status|errcode|errtext)>/\1: /' \ - | sed -r 's/<\/(status|errcode|errtext)>$//g' + | sed -rn 's/^ *<(status|errcode|errtext)>([^<]+)<\/(status|errcode|errtext)> *$/\1: \2/p' \ )" elif ! _value "$statuslines" | grep -q 'ok'; then From 63a779baa86ed8609c7030fa8aa37deb11341752 Mon Sep 17 00:00:00 2001 From: stilez Date: Mon, 4 Nov 2019 18:44:14 +0000 Subject: [PATCH 0516/2234] remove unnecessary \ --- dnsapi/dns_pleskxml.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index f3d6a1de..c673744f 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -250,7 +250,7 @@ _call_api() { # We have some status lines that aren't "ok". Get the details errtext="$(_value "$pleskxml_prettyprint_result" \ - | sed -rn 's/^ *<(status|errcode|errtext)>([^<]+)<\/(status|errcode|errtext)> *$/\1: \2/p' \ + | sed -rn 's/^ *<(status|errcode|errtext)>([^<]+)<\/(status|errcode|errtext)> *$/\1: \2/p' )" elif ! _value "$statuslines" | grep -q 'ok'; then From 04b0c62bf959c800c36f9b19da599741caacd1c8 Mon Sep 17 00:00:00 2001 From: stilez Date: Mon, 4 Nov 2019 19:05:44 +0000 Subject: [PATCH 0517/2234] basic regex's to use \+ Maybe BRE aren't as basic as they sound. But I'm sure `man grep` didn't list the extra syntax of "preceded by backslash" :) So let's use it --- dnsapi/dns_pleskxml.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index c673744f..dca0d246 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -91,7 +91,7 @@ dns_pleskxml_add() { results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - if ! _value "$results" | grep 'ok' | grep -q '[0-9][0-9]*'; then + if ! _value "$results" | grep 'ok' | grep -q '[0-9]\+'; then # Error - doesn't contain expected string. Something's wrong. _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' @@ -100,7 +100,7 @@ dns_pleskxml_add() { return 1 fi - recid="$(_value "$results" | grep '[0-9][0-9]*' | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" + recid="$(_value "$results" | grep '[0-9]\+' | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" _info "Success. TXT record appears to be correctly added (Plesk record ID=$recid). Exiting dns_pleskxml_add()." @@ -136,7 +136,7 @@ dns_pleskxml_rm() { # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ | grep "${root_domain_id}" \ - | grep '[0-9][0-9]*' \ + | grep '[0-9]\+' \ | grep 'TXT' )" @@ -155,7 +155,7 @@ dns_pleskxml_rm() { _debug "List of DNS TXT records for host:"'\n'"$(_value "$reclist" | grep "$1.")" - if ! _value "$recid" | grep -q '^[0-9][0-9]*$'; then + if ! _value "$recid" | grep -q '^[0-9]\+$'; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" _err "Cannot delete TXT record. Exiting." return 1 @@ -176,7 +176,7 @@ dns_pleskxml_rm() { results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - if ! _value "$results" | grep 'ok' | grep -q '[0-9][0-9]*'; then + if ! _value "$results" | grep 'ok' | grep -q '[0-9]\+'; then # Error - doesn't contain expected string. Something's wrong. _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' From 896778cead810f88ffd8e5efa61d97cbd78dfe6d Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 17:56:20 +0000 Subject: [PATCH 0518/2234] Grep fixes and minor improvements --- dnsapi/dns_pleskxml.sh | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index dca0d246..551e42fe 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -91,7 +91,7 @@ dns_pleskxml_add() { results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - if ! _value "$results" | grep 'ok' | grep -q '[0-9]\+'; then + if ! _value "$results" | grep 'ok' | grep '[0-9]\{1,\}' >/dev/null; then # Error - doesn't contain expected string. Something's wrong. _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' @@ -100,7 +100,7 @@ dns_pleskxml_add() { return 1 fi - recid="$(_value "$results" | grep '[0-9]\+' | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" + recid="$(_value "$results" | grep '[0-9]\{1,\}' | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" _info "Success. TXT record appears to be correctly added (Plesk record ID=$recid). Exiting dns_pleskxml_add()." @@ -136,7 +136,7 @@ dns_pleskxml_rm() { # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ | grep "${root_domain_id}" \ - | grep '[0-9]\+' \ + | grep '[0-9]\{1,\}' \ | grep 'TXT' )" @@ -155,7 +155,7 @@ dns_pleskxml_rm() { _debug "List of DNS TXT records for host:"'\n'"$(_value "$reclist" | grep "$1.")" - if ! _value "$recid" | grep -q '^[0-9]\+$'; then + if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" _err "Cannot delete TXT record. Exiting." return 1 @@ -176,7 +176,7 @@ dns_pleskxml_rm() { results="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '')" - if ! _value "$results" | grep 'ok' | grep -q '[0-9]\+'; then + if ! _value "$results" | grep 'ok' | grep '[0-9]\{1,\}' >/dev/null; then # Error - doesn't contain expected string. Something's wrong. _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' @@ -244,20 +244,27 @@ _call_api() { # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. - statuslines="$(echo "$pleskxml_prettyprint_result" | grep '^ *[^<]* *$')" + statuslines_count_total="$(echo "$pleskxml_prettyprint_result" | grep -c '^ *[^<]* *$')" + statuslines_count_okay="$(echo "$pleskxml_prettyprint_result" | grep -c '^ *ok *$')" - if _value "$statuslines" | grep -qv 'ok'; then - - # We have some status lines that aren't "ok". Get the details - errtext="$(_value "$pleskxml_prettyprint_result" \ - | sed -rn 's/^ *<(status|errcode|errtext)>([^<]+)<\/(status|errcode|errtext)> *$/\1: \2/p' - )" - - elif ! _value "$statuslines" | grep -q 'ok'; then + if [ -z "$statuslines_count_total" ]; then # We have no status lines at all. Results are empty errtext='The Plesk XML API unexpectedly returned an empty set of results for this call.' + elif [ "$statuslines_count_okay" -ne "$statuslines_count_total" ]; then + + # We have some status lines that aren't "ok". Any available details are in API response fields "status" "errcode" and "errtext" + # Workaround for basic regex: + # - filter output to keep only lines like this: "SPACEStextSPACES" (shouldn't be necessary with prettyprint but guarantees subsequent code is ok) + # - then edit the 3 "useful" error tokens individually and remove closing tags on all lines + # - then filter again to remove all lines not edited (which will be the lines not starting A-Z) + errtext="$(_value "$pleskxml_prettyprint_result" \ + | grep '^ *<[a-z]\{1,\}>[^<]*<\/[a-z]\{1,\}> *$' \ + | sed 's/^ */Status: /;s/^ */Error code: /;s/^ */Error text: /;s/<\/.*$//' \ + | grep '^[A-Z]' + )" + fi if [ "$pleskxml_retcode" -ne 0 ] || [ "$errtext" != "" ]; then @@ -266,7 +273,7 @@ _call_api() { if [ "$pleskxml_retcode" -eq 0 ]; then _err "The POST request was successfully sent to the Plesk server." else - _err "The return code for the POST request was $pleskxml_retcode (non-zero = could not submit request to server)." + _err "The return code for the POST request was $pleskxml_retcode (non-zero = failure in submitting request to server)." fi if [ "$errtext" != "" ]; then From cbacc779fcc3dc9bf3b5924d5691c12f9d74ebe3 Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 18:50:39 +0000 Subject: [PATCH 0519/2234] Fix some sed -r, and clean up some variable references ("$1" -> "$varname") --- dnsapi/dns_pleskxml.sh | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 551e42fe..2c9a4d56 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -100,7 +100,7 @@ dns_pleskxml_add() { return 1 fi - recid="$(_value "$results" | grep '[0-9]\{1,\}' | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" + recid="$(_value "$results" | grep '[0-9]\{1,\}' | sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/')" _info "Success. TXT record appears to be correctly added (Plesk record ID=$recid). Exiting dns_pleskxml_add()." @@ -145,16 +145,16 @@ dns_pleskxml_rm() { return 1 fi - _debug "Got list of DNS TXT records for root domain '$root_domain_name'"':\n'"$reclist" + _debug "Got list of DNS TXT records for root domain '$root_domain_name'. Full list is:"'\n'"$reclist" + + _debug "DNS TXT records for host '$fulldomain':"'\n'"$(_value "$reclist" | grep "${fulldomain}.")" recid="$(_value "$reclist" \ - | grep "$1." \ - | grep "$txtvalue" \ - | sed -r 's/(^.*|<\/id>.*$)//g' + | grep "${fulldomain}." \ + | grep "${txtvalue}" \ + | sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' )" - _debug "List of DNS TXT records for host:"'\n'"$(_value "$reclist" | grep "$1.")" - if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" _err "Cannot delete TXT record. Exiting." @@ -341,13 +341,13 @@ _credential_check() { # See notes at top of this file _pleskxml_get_root_domain() { - _debug "Identifying DNS root domain for '$1' that is managed by the Plesk account." original_full_domain_name="$1" - root_domain_name="$1" + + _debug "Identifying DNS root domain for '$original_full_domain_name' that is managed by the Plesk account." # test if the domain as provided is valid for splitting. - if ! _countdots "$root_domain_name"; then + if ! _countdots "$original_full_domain_name"; then _err "Invalid domain. The ACME domain must contain at least two parts (aa.bb) to identify a domain and tld for the TXT record." return 1 fi @@ -372,6 +372,8 @@ _pleskxml_get_root_domain() { # loop and test if domain, or any parent domain, is managed by Plesk # Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain + root_domain_name="$original_full_domain_name" + while true; do _debug "Checking if '$root_domain_name' is managed by the Plesk server..." From a8d670fc0d7abb2efa3cbcc411c79f37ad8c737d Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 19:01:32 +0000 Subject: [PATCH 0520/2234] Rest of sed -r --- dnsapi/dns_pleskxml.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 2c9a4d56..c2de2184 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -211,16 +211,16 @@ _countdots() { # Cleans up an API response, splits it "one line per item in the response" and greps for a string that in the context, identifies "useful" lines # $1 - result string from API -# $2 - tag to resplit on (usually "result" or "domain") +# $2 - plain text tag to resplit on (usually "result" or "domain"). NOT REGEX # $3 - basic regex to recognise useful return lines # note: $3 matches via basic NOT extended regex (BRE), as extended regex capabilities not needed at the moment. -# Last line could change to instead, with suitablew ewscaping of ['"/$], +# Last line could change to instead, with suitable escaping of ['"/$], # if future Plesk XML API changes ever require extended regex _api_response_split() { printf '%s' "$1" \ - | sed -r 's/(^ +| +$)//g' \ + | sed 's/^ +//;s/ +$//' \ | tr -d '\n\r' \ - | sed -r "s/<\/?$2>/${NEWLINE}/g" \ + | sed "s/<\/\{0,1\}$2>/${NEWLINE}/g" \ | grep "$3" } @@ -365,7 +365,7 @@ _pleskxml_get_root_domain() { # Output will be one line per known domain, containing 2 tages and a single tag # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. - output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed -r 's/<(\/?)ascii-name>/<\1name>/g' | grep '' | grep '')" + output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" _debug 'Domains managed by Plesk server are (ignore the hacked output):\n' "$output" @@ -378,13 +378,13 @@ _pleskxml_get_root_domain() { _debug "Checking if '$root_domain_name' is managed by the Plesk server..." - root_domain_id="$(_value "$output" | grep "$root_domain_name" | _head_n 1 | sed -r 's/^.*([0-9]+)<\/id>.*$/\1/')" + root_domain_id="$(_value "$output" | grep "$root_domain_name" | _head_n 1 | sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/')" if [ -n "$root_domain_id" ]; then # Found a match # SEE IMPORTANT NOTE ABOVE - THIS FUNCTION CAN RETURN HOST='', AND THAT'S OK FOR PLESK XML API WHICH ALLOWS IT. # SO WE HANDLE IT AND DON'T PREVENT IT - sub_domain_name="$(_value "$original_full_domain_name" | sed -r "s/\.?${root_domain_name}"'$//')" + sub_domain_name="$(_value "$original_full_domain_name" | sed "s/\.\{0,1\}${root_domain_name}"'$//')" _info "Success. Matched host '$original_full_domain_name' to: DOMAIN '${root_domain_name}' (Plesk ID '${root_domain_id}'), HOST '${sub_domain_name}'. Returning." return 0 fi From 4216c9e8f745d76588c8dc8592ade0e020f82d62 Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 19:19:08 +0000 Subject: [PATCH 0521/2234] rmv spaces --- dnsapi/dns_pleskxml.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index c2de2184..d2a2684a 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -146,7 +146,7 @@ dns_pleskxml_rm() { fi _debug "Got list of DNS TXT records for root domain '$root_domain_name'. Full list is:"'\n'"$reclist" - + _debug "DNS TXT records for host '$fulldomain':"'\n'"$(_value "$reclist" | grep "${fulldomain}.")" recid="$(_value "$reclist" \ From a9726bd52f764f519332783f8002ef8e2c742b5b Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 20:58:51 +0000 Subject: [PATCH 0522/2234] bugfix --- dnsapi/dns_pleskxml.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index d2a2684a..ad8d5cfd 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -393,7 +393,7 @@ _pleskxml_get_root_domain() { root_domain_name="$(_valuecut 2 1000 "$root_domain_name")" - if ! _countdots "$root_domain_name"; then + if [ _countdots "$root_domain_name" -eq 0 ]; then _debug "No match, and next parent would be a TLD..." _err "Cannot find '$original_full_domain_name' or any parent domain of it, in Plesk." _err "Are you sure that this domain is managed by this Plesk server?" From 38854bd876d11c4bf0f696e23c694a61d2b640ec Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 21:00:34 +0000 Subject: [PATCH 0523/2234] bugfix --- dnsapi/dns_pleskxml.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index ad8d5cfd..ca64325b 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -393,7 +393,7 @@ _pleskxml_get_root_domain() { root_domain_name="$(_valuecut 2 1000 "$root_domain_name")" - if [ _countdots "$root_domain_name" -eq 0 ]; then + if [ "$(_countdots "$root_domain_name")" -eq 0 ]; then _debug "No match, and next parent would be a TLD..." _err "Cannot find '$original_full_domain_name' or any parent domain of it, in Plesk." _err "Are you sure that this domain is managed by this Plesk server?" From 43011f3bfa2e08807b3e7450d123aabcbd6905a8 Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 21:04:10 +0000 Subject: [PATCH 0524/2234] enhance --- dnsapi/dns_pleskxml.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index ca64325b..5abe9dd1 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -203,10 +203,10 @@ _valuecut() { printf '%s' "$3" | cut -d . -f "${1}-${2}" } -# Counts '.' present in a domain name +# Counts '.' present in a domain name or other string # $1 = domain name _countdots() { - _value "$1" | tr -dc '.' | wc -c + _value "$1" | tr -dc '.' | wc -c | sed 's/ //g' } # Cleans up an API response, splits it "one line per item in the response" and greps for a string that in the context, identifies "useful" lines From 05247dc4a4dca564a8d38e223da89556e2e68493 Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 21:09:14 +0000 Subject: [PATCH 0525/2234] fix --- dnsapi/dns_pleskxml.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 5abe9dd1..b6781c2e 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -347,7 +347,7 @@ _pleskxml_get_root_domain() { # test if the domain as provided is valid for splitting. - if ! _countdots "$original_full_domain_name"; then + if [ "$(_countdots "$original_full_domain_name")" -eq 0 ]; then _err "Invalid domain. The ACME domain must contain at least two parts (aa.bb) to identify a domain and tld for the TXT record." return 1 fi From 6d0e4bed4b9d9bcb31e445ecadc7c4f741abc6fc Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 23:26:05 +0000 Subject: [PATCH 0526/2234] remove \n in output messages --- dnsapi/dns_pleskxml.sh | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index b6781c2e..ca07bc4e 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -96,7 +96,8 @@ dns_pleskxml_add() { _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' _err 'This is unexpected: something has gone wrong.' - _err 'The full response was:\n' "$pleskxml_prettyprint_result" + _err 'The full response was:' + _err "$pleskxml_prettyprint_result" return 1 fi @@ -134,7 +135,9 @@ dns_pleskxml_rm() { fi # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) + # Also strip out spaces between tags, redundant and group tags and any tags reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ + | sed 's# \{1,\}<\([a-zA-Z]\)#<\1#g;s###g;s#<[a-z][^/<>]*/>##g' \ | grep "${root_domain_id}" \ | grep '[0-9]\{1,\}' \ | grep 'TXT' @@ -145,9 +148,8 @@ dns_pleskxml_rm() { return 1 fi - _debug "Got list of DNS TXT records for root domain '$root_domain_name'. Full list is:"'\n'"$reclist" - - _debug "DNS TXT records for host '$fulldomain':"'\n'"$(_value "$reclist" | grep "${fulldomain}.")" + _debug "Got list of DNS TXT records for root domain '$root_domain_name':" + _debug "$reclist" recid="$(_value "$reclist" \ | grep "${fulldomain}." \ @@ -181,7 +183,8 @@ dns_pleskxml_rm() { _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' _err 'This is unexpected: something has gone wrong.' - _err 'The full response was:\n' "$pleskxml_prettyprint_result" + _err 'The full response was:' + _err "$pleskxml_prettyprint_result" return 1 fi @@ -231,7 +234,8 @@ _call_api() { request="$1" errtext='' - _debug 'Entered _call_api(). Calling Plesk XML API with request:\n' "'${request}'" + _debug 'Entered _call_api(). Calling Plesk XML API with request:' + _debug "'$request'" export _H1="HTTP_AUTH_LOGIN: $pleskxml_user" export _H2="HTTP_AUTH_PASSWD: $pleskxml_pass" @@ -239,7 +243,9 @@ _call_api() { export _H4="HTTP_PRETTY_PRINT: true" pleskxml_prettyprint_result="$(_post "${request}" "$pleskxml_uri" "" "POST")" pleskxml_retcode="$?" - _debug 'The responses from the Plesk XML server were:\n' "retcode=$pleskxml_retcode. Literal response:"'\n' "'$pleskxml_prettyprint_result'" + _debug 'The responses from the Plesk XML server were:' + _debug "retcode=$pleskxml_retcode. Literal response:" + _debug "'$pleskxml_prettyprint_result'" # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. @@ -277,7 +283,8 @@ _call_api() { fi if [ "$errtext" != "" ]; then - _err 'The error responses received from the Plesk server were:\n' "$errtext" + _err 'The error responses received from the Plesk server were:' + _err "$errtext" else _err "No additional error messages were received back from the Plesk server" fi @@ -318,7 +325,7 @@ _credential_check() { # Test the API is usable, by trying to read the list of managed domains... _call_api "$pleskxml_tplt_get_domains" if [ "$pleskxml_retcode" -ne 0 ]; then - _err '\nFailed to access Plesk XML API.' + _err 'Failed to access Plesk XML API.' _err "Please check your login credentials and Plesk URI, and that the URI is reachable, and try again." return 1 fi @@ -367,7 +374,8 @@ _pleskxml_get_root_domain() { output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" - _debug 'Domains managed by Plesk server are (ignore the hacked output):\n' "$output" + _debug 'Domains managed by Plesk server are (ignore the hacked output):' + _debug "$output" # loop and test if domain, or any parent domain, is managed by Plesk # Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain From 51cfd996eb8aaa142c9cbe61270bf1c5751f7d1e Mon Sep 17 00:00:00 2001 From: stilez Date: Tue, 5 Nov 2019 23:29:51 +0000 Subject: [PATCH 0527/2234] rmv space --- dnsapi/dns_pleskxml.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index ca07bc4e..c5d9e544 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -96,7 +96,7 @@ dns_pleskxml_add() { _err 'Error when calling Plesk XML API.' _err 'The result did not contain the expected XXXXX section, or contained other values as well.' _err 'This is unexpected: something has gone wrong.' - _err 'The full response was:' + _err 'The full response was:' _err "$pleskxml_prettyprint_result" return 1 fi From c6ec8bc0d9f1db2fb0f90c20a5cfbc0ae552e2f9 Mon Sep 17 00:00:00 2001 From: rewqazxv <41326691+rewqazxv@users.noreply.github.com> Date: Wed, 6 Nov 2019 18:57:05 +0800 Subject: [PATCH 0528/2234] fix sudo issue --- acme.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 81a20b0b..4a1ce9b7 100755 --- a/acme.sh +++ b/acme.sh @@ -6362,11 +6362,17 @@ _checkSudo() { #it's root using sudo, no matter it's using sudo or not, just fine return 0 fi - if [ "$SUDO_COMMAND" = "/bin/su" ] || [ "$SUDO_COMMAND" = "/bin/bash" ]; then - #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s` - #fine - return 0 - fi + case "$SUDO_COMMAND" in + */su ) + #it's a normal user doing `sudo su`, no problem + return 0 ;; + esac + for i in `cat /etc/shells`; do + if [ "$SUDO_COMMAND" = "$i" ]; then + #it's a normal user running `sudo -i` or `sudo -s`, fine + return 0 + fi + done #otherwise return 1 fi From 6a5ee72722550c76cb925916cfde2f103bda8b40 Mon Sep 17 00:00:00 2001 From: rewqazxv <41326691+rewqazxv@users.noreply.github.com> Date: Wed, 6 Nov 2019 20:27:12 +0800 Subject: [PATCH 0529/2234] format code style --- acme.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 4a1ce9b7..d3c0fc7a 100755 --- a/acme.sh +++ b/acme.sh @@ -6363,11 +6363,12 @@ _checkSudo() { return 0 fi case "$SUDO_COMMAND" in - */su ) + */su) #it's a normal user doing `sudo su`, no problem - return 0 ;; + return 0 + ;; esac - for i in `cat /etc/shells`; do + for i in $(cat /etc/shells); do if [ "$SUDO_COMMAND" = "$i" ]; then #it's a normal user running `sudo -i` or `sudo -s`, fine return 0 From 0b3ae1f9727787f46eec66ce796e030a5474a845 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Thu, 7 Nov 2019 14:10:30 +0100 Subject: [PATCH 0530/2234] Add suggestions --- dnsapi/dns_opnsense.sh | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 0f7cdea6..97f18d1a 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -4,15 +4,19 @@ #https://docs.opnsense.org/development/api.html # #OPNs_Host="opnsense.example.com" -#OPNs_Port="443" +#OPNs_Port="443" (optional, defaults to 443 if unset) #OPNs_Key="qocfU9RSbt8vTIBcnW8bPqCrpfAHMDvj5OzadE7Str+rbjyCyk7u6yMrSCHtBXabgDDXx/dY0POUp7ZA" #OPNs_Token="pZEQ+3ce8dDlfBBdg3N8EpqpF5I1MhFqdxX06le6Gl8YzyQvYCfCzNaFX9O9+IOSyAs7X71fwdRiZ+Lv" -#OPNs_Api_Insecure=0 # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) +#OPNs_Api_Insecure=0 (optional, defaults to 0 if unset) # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000" #fulldomain #txtvalue +OPNs_DefaultPort=443 +OPNs_DefaultApi_Insecure=0 + + dns_opnsense_add() { fulldomain=$1 txtvalue=$2 @@ -168,7 +172,7 @@ _opns_rest() { key=$(echo "$OPNs_Key" | tr -d "\n\r" | _url_encode) token=$(echo "$OPNs_Token" | tr -d "\n\r" | _url_encode) - opnsense_url="https://${key}:${token}@${OPNs_Host}:${OPNs_Port}/api/bind${ep}" + opnsense_url="https://${key}:${token}@${OPNs_Host}:${OPNs_Port:-$OPNs_DefaultPort}/api/bind${ep}" export _H1="Content-Type: application/json" if [ ! "$method" = "GET" ]; then _debug data "$data" @@ -218,29 +222,30 @@ _opns_check_auth() { OPNs_Api_Insecure="${OPNs_Api_Insecure:-$(_readaccountconf_mutable OPNs_Api_Insecure)}" if [ -z "$OPNs_Host" ]; then - OPNs_Host="localhost" _err "You don't specify OPNsense address." return 1 else _saveaccountconf_mutable OPNs_Host "$OPNs_Host" fi - if [ -z "$OPNs_Port" ]; then - OPNs_Port="443" + if ! printf '%s' "$OPNs_Port" | grep -q '^[0-9]*$'; then + _err 'OPNs_Port specified but not numeric value' + return 1 + elif [ -z "$OPNs_Port" ]; then + _info "OPNSense port not specified. Defaulting to using port $OPNs_DefaultPort" else _saveaccountconf_mutable OPNs_Port "$OPNs_Port" fi - - if [ -z "$OPNs_Api_Insecure" ]; then - OPNs_Api_Insecure="0" - else - #save the api addr and key to the account conf file. + + if ! printf '%s' "$OPNs_Api_Insecure" | grep -q '^[01]$'; then + _err 'OPNs_Api_Insecure specified but not 0/1 value' + return 1 + elif [ -n "$OPNs_Api_Insecure" ]; then _saveaccountconf_mutable OPNs_Api_Insecure "$OPNs_Api_Insecure" fi - export HTTPS_INSECURE="${OPNs_Api_Insecure}" + export HTTPS_INSECURE="${OPNs_Api_Insecure:-$OPNs_DefaultApi_Insecure}" if [ -z "$OPNs_Key" ]; then - OPNs_Key="" _err "You don't specify OPNsense api key id." _err "Please set you OPNs_Key and try again." return 1 @@ -249,7 +254,6 @@ _opns_check_auth() { fi if [ -z "$OPNs_Token" ]; then - OPNs_Token="" _err "You don't specify OPNsense token." _err "Please create you OPNs_Token and try again." return 1 From afdf8a78c0a42e22265309c522ee3cda4993e227 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Thu, 7 Nov 2019 14:18:09 +0100 Subject: [PATCH 0531/2234] fix space --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 97f18d1a..afd96c3e 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -236,7 +236,7 @@ _opns_check_auth() { else _saveaccountconf_mutable OPNs_Port "$OPNs_Port" fi - + if ! printf '%s' "$OPNs_Api_Insecure" | grep -q '^[01]$'; then _err 'OPNs_Api_Insecure specified but not 0/1 value' return 1 From fc8d9df5162bdec5e401edc4e8d6faba80e92d89 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Thu, 7 Nov 2019 14:33:38 +0100 Subject: [PATCH 0532/2234] fix newline --- dnsapi/dns_opnsense.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index afd96c3e..6dde12a5 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -16,7 +16,6 @@ OPNs_DefaultPort=443 OPNs_DefaultApi_Insecure=0 - dns_opnsense_add() { fulldomain=$1 txtvalue=$2 From 18fc42e63b5f4491502b8a2203036c93b1c4eaba Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Thu, 7 Nov 2019 22:06:32 +0100 Subject: [PATCH 0533/2234] typos and integrate suggestions from stilez --- dnsapi/dns_opnsense.sh | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 6dde12a5..4fbe9447 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -4,10 +4,13 @@ #https://docs.opnsense.org/development/api.html # #OPNs_Host="opnsense.example.com" -#OPNs_Port="443" (optional, defaults to 443 if unset) +#OPNs_Port="443" +# optional, defaults to 443 if unset #OPNs_Key="qocfU9RSbt8vTIBcnW8bPqCrpfAHMDvj5OzadE7Str+rbjyCyk7u6yMrSCHtBXabgDDXx/dY0POUp7ZA" #OPNs_Token="pZEQ+3ce8dDlfBBdg3N8EpqpF5I1MhFqdxX06le6Gl8YzyQvYCfCzNaFX9O9+IOSyAs7X71fwdRiZ+Lv" -#OPNs_Api_Insecure=0 (optional, defaults to 0 if unset) # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) +#OPNs_Api_Insecure=0 +# optional, defaults to 0 if unset +# Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000" @@ -44,15 +47,16 @@ dns_opnsense_rm() { } set_record() { - _info "Adding record" fulldomain=$1 new_challenge=$2 + _info "Adding record $fulldomain with challenge: $new_challenge" _debug "Detect root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 fi + _debug _domain "$_domain" _debug _host "$_host" _debug _domainid "$_domainid" @@ -81,7 +85,7 @@ set_record() { _opns_rest "POST" "/service/reconfigure" "{}" _debug "Record created" else - _err "Error createing record $_record_string" + _err "Error creating record $_record_string" return 1 fi @@ -89,9 +93,9 @@ set_record() { } rm_record() { - _info "Remove record" fulldomain=$1 new_challenge="$2" + _info "Remove record $fulldomain with challenge: $new_challenge" _debug "Detect root zone" if ! _get_root "$fulldomain"; then @@ -110,18 +114,18 @@ rm_record() { _opns_rest "POST" "/service/reconfigure" "{}" _debug "Record deleted" else - _err "Error delteting record $fulldomain" + _err "Error deleting record $host from domain $fulldomain" return 1 fi else - _err "Error delteting record $fulldomain" + _err "Error deleting record $host from domain $fulldomain" return 1 fi else _info "Record not found, nothing to remove" fi - return 0 + return 0 } #################### Private functions below ################################## @@ -173,6 +177,7 @@ _opns_rest() { opnsense_url="https://${key}:${token}@${OPNs_Host}:${OPNs_Port:-$OPNs_DefaultPort}/api/bind${ep}" export _H1="Content-Type: application/json" + _debug2 "Try to call api: https://${OPNs_Host}:${OPNs_Port:-$OPNs_DefaultPort}/api/bind${ep}" if [ ! "$method" = "GET" ]; then _debug data "$data" export _H1="Content-Type: application/json" @@ -227,7 +232,7 @@ _opns_check_auth() { _saveaccountconf_mutable OPNs_Host "$OPNs_Host" fi - if ! printf '%s' "$OPNs_Port" | grep -q '^[0-9]*$'; then + if ! printf '%s' "$OPNs_Port" | grep '^[0-9]*$' >/dev/null ; then _err 'OPNs_Port specified but not numeric value' return 1 elif [ -z "$OPNs_Port" ]; then @@ -236,7 +241,7 @@ _opns_check_auth() { _saveaccountconf_mutable OPNs_Port "$OPNs_Port" fi - if ! printf '%s' "$OPNs_Api_Insecure" | grep -q '^[01]$'; then + if ! printf '%s' "$OPNs_Api_Insecure" | grep '^[01]$' >/dev/null ; then _err 'OPNs_Api_Insecure specified but not 0/1 value' return 1 elif [ -n "$OPNs_Api_Insecure" ]; then @@ -245,23 +250,23 @@ _opns_check_auth() { export HTTPS_INSECURE="${OPNs_Api_Insecure:-$OPNs_DefaultApi_Insecure}" if [ -z "$OPNs_Key" ]; then - _err "You don't specify OPNsense api key id." - _err "Please set you OPNs_Key and try again." + _err "you have not specified your OPNsense api key id." + _err "Please set OPNs_Key and try again." return 1 else _saveaccountconf_mutable OPNs_Key "$OPNs_Key" fi if [ -z "$OPNs_Token" ]; then - _err "You don't specify OPNsense token." - _err "Please create you OPNs_Token and try again." + _err "you have not specified your OPNsense token." + _err "Please create OPNs_Token and try again." return 1 else _saveaccountconf_mutable OPNs_Token "$OPNs_Token" fi if ! _opns_rest "GET" "/general/get"; then - _err "Can't Access OPNsense" + _err "Call to OPNsense API interface failed. Unable to access OPNsense API." return 1 fi return 0 From 0c76890572932edc06bf3fb39c9e329b2ceec326 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Fri, 8 Nov 2019 08:52:10 +0100 Subject: [PATCH 0534/2234] whitespace fix --- dnsapi/dns_opnsense.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 4fbe9447..9e4af15f 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -125,7 +125,7 @@ rm_record() { _info "Record not found, nothing to remove" fi - return 0 + return 0 } #################### Private functions below ################################## @@ -232,7 +232,7 @@ _opns_check_auth() { _saveaccountconf_mutable OPNs_Host "$OPNs_Host" fi - if ! printf '%s' "$OPNs_Port" | grep '^[0-9]*$' >/dev/null ; then + if ! printf '%s' "$OPNs_Port" | grep '^[0-9]*$' >/dev/null; then _err 'OPNs_Port specified but not numeric value' return 1 elif [ -z "$OPNs_Port" ]; then @@ -241,7 +241,7 @@ _opns_check_auth() { _saveaccountconf_mutable OPNs_Port "$OPNs_Port" fi - if ! printf '%s' "$OPNs_Api_Insecure" | grep '^[01]$' >/dev/null ; then + if ! printf '%s' "$OPNs_Api_Insecure" | grep '^[01]$' >/dev/null; then _err 'OPNs_Api_Insecure specified but not 0/1 value' return 1 elif [ -n "$OPNs_Api_Insecure" ]; then From 9cb328966c63d86565276e3ccc7d7e53d5101514 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Fri, 8 Nov 2019 08:58:51 +0100 Subject: [PATCH 0535/2234] typo --- dnsapi/dns_opnsense.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 9e4af15f..b2a3746f 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -114,11 +114,11 @@ rm_record() { _opns_rest "POST" "/service/reconfigure" "{}" _debug "Record deleted" else - _err "Error deleting record $host from domain $fulldomain" + _err "Error deleting record $_host from domain $fulldomain" return 1 fi else - _err "Error deleting record $host from domain $fulldomain" + _err "Error deleting record $_host from domain $fulldomain" return 1 fi else From f1f14040b85cb05330552d644c94890f6b82f2c3 Mon Sep 17 00:00:00 2001 From: Vitalii Tverdokhlib Date: Sat, 9 Nov 2019 12:12:30 +0200 Subject: [PATCH 0536/2234] DOCS: typo --- notify/mailgun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/mailgun.sh b/notify/mailgun.sh index 4b6ee3ba..93cdf793 100644 --- a/notify/mailgun.sh +++ b/notify/mailgun.sh @@ -7,7 +7,7 @@ #MAILGUN_REGION="us|eu" #optional, use "us" as default #MAILGUN_API_DOMAIN="xxxxxx.com" #optional, use the default sandbox domain -#MAILGUN_FROM="xxx@xxxxx.com" #optional, use the default sendbox account +#MAILGUN_FROM="xxx@xxxxx.com" #optional, use the default sandbox account _MAILGUN_BASE_US="https://api.mailgun.net/v3" _MAILGUN_BASE_EU="https://api.eu.mailgun.net/v3" From 867ec010abe4aa4af349895a1d1ac93c3d0fba66 Mon Sep 17 00:00:00 2001 From: arlecchino Date: Tue, 12 Nov 2019 19:58:36 +0100 Subject: [PATCH 0537/2234] Fix callhook error in manual mode Fixes #1586 Check force manual switch before causing error about it. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 81a20b0b..0164d54e 100755 --- a/acme.sh +++ b/acme.sh @@ -3365,7 +3365,7 @@ _on_issue_success() { fi fi - if _hasfield "$Le_Webroot" "$W_DNS"; then + if _hasfield "$Le_Webroot" "$W_DNS" && [ -z "$FORCE_DNS_MANUAL" ]; then _err "$_DNS_MANUAL_WARN" fi From adce8f52e8b71da504541bec2a10a607b9b3fac4 Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Tue, 12 Nov 2019 08:48:41 -0800 Subject: [PATCH 0538/2234] debug_bash_helper: Use eval as busybox systems have problems In _debug_bash_helper use eval as we are seeing issues with busybox systems having issues with array access. Even though they aren't actually running the code they appear to be parsing it and failing. Also older versions of busybox have a bug with eval and double quotes, so make sure to use single quotes when using eval. Resolves: #2579 --- acme.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index 81a20b0b..0c8ab903 100755 --- a/acme.sh +++ b/acme.sh @@ -268,31 +268,31 @@ _usage() { __debug_bash_helper() { # At this point only do for --debug 3 if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -lt "$DEBUG_LEVEL_3" ]; then - echo "" return fi # Return extra debug info when running with bash, otherwise return empty # string. if [ -z "${BASH_VERSION}" ]; then - echo "" return fi # We are a bash shell at this point, return the filename, function name, and # line number as a string _dbh_saveIFS=$IFS IFS=" " - # Must use eval or syntax error happens under dash + # Must use eval or syntax error happens under dash. The eval should use + # single quotes as older versions of busybox had a bug with double quotes and + # eval. # Use 'caller 1' as we want one level up the stack as we should be called # by one of the _debug* functions - eval "_dbh_called=($(caller 1))" + eval '_dbh_called=($(caller 1))' IFS=$_dbh_saveIFS - _dbh_file=${_dbh_called[2]} + eval '_dbh_file=${_dbh_called[2]}' if [ -n "${_script_home}" ]; then # Trim off the _script_home directory name - _dbh_file=${_dbh_file#$_script_home/} + eval '_dbh_file=${_dbh_file#$_script_home/}' fi - _dbh_function=${_dbh_called[1]} - _dbh_lineno=${_dbh_called[0]} + eval '_dbh_function=${_dbh_called[1]}' + eval '_dbh_lineno=${_dbh_called[0]}' printf "%-40s " "$_dbh_file:${_dbh_function}:${_dbh_lineno}" } From c282dd086fe0fc2152f7d47fb4ee1885f26aec09 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Nov 2019 08:06:21 +0800 Subject: [PATCH 0539/2234] minor --- dnsapi/dns_nic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 493b05bc..e3b39b0c 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -89,7 +89,7 @@ dns_nic_rm() { return 1 fi - _domain_id=$(printf "%s" "$response" | grep "$_sub_domain" | grep "$txtvalue" | sed -r "s/.* Date: Tue, 26 Nov 2019 20:39:08 +1100 Subject: [PATCH 0540/2234] Added trailing slash to end of each line of DEPLOY_SCRIPT_CMD --- deploy/routeros.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 21c9196f..2f349999 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -85,19 +85,19 @@ routeros_deploy() { scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" _info "Trying to push cert '$_cfullchain' to router" scp "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" - DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=ftp,read,write,password,sensitive -source=\"## generated by routeros deploy script in acme.sh -\n/certificate remove [ find name=$_cdomain.cer_0 ] -\n/certificate remove [ find name=$_cdomain.cer_1 ] -\ndelay 1 -\n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\" -\n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\" -\ndelay 1 -\n/file remove $_cdomain.cer -\n/file remove $_cdomain.key -\ndelay 2 -\n/ip service set www-ssl certificate=$_cdomain.cer_0 -\n$ROUTER_OS_ADDITIONAL_SERVICES + DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=ftp,read,write,password,sensitive \ +source=\"## generated by routeros deploy script in acme.sh;\ +\n/certificate remove [ find name=$_cdomain.cer_0 ];\ +\n/certificate remove [ find name=$_cdomain.cer_1 ];\ +\ndelay 1;\ +\n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\";\ +\n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\";\ +\ndelay 1;\ +\n/file remove $_cdomain.cer;\ +\n/file remove $_cdomain.key;\ +\ndelay 2;\ +\n/ip service set www-ssl certificate=$_cdomain.cer_0;\ +\n$ROUTER_OS_ADDITIONAL_SERVICES;\ \n\" " # shellcheck disable=SC2029 From ec1f9841b21cd9aa7ca96aac4589472f3624f4eb Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 29 Nov 2019 22:22:26 +0100 Subject: [PATCH 0541/2234] Replace grep -A. --- dnsapi/dns_kas.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 14c0b378..bf01fef3 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -69,13 +69,13 @@ dns_kas_rm() { _get_record_name "$_fulldomain" _get_record_id - # If there is a record_id, delete the entry + # If there is a record_id, delete the entry if [ -n "$_record_id" ]; then params="?kas_login=$KAS_Login" params="$params&kas_auth_type=$KAS_Authtype" params="$params&kas_auth_data=$KAS_Authdata" params="$params&kas_action=delete_dns_settings" - + # split it into a seperated list, if there where multiples entries made records=($_record_id) for i in "${records[@]}" @@ -150,7 +150,7 @@ _get_record_id() { response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" - _record_id="$(echo "$response" | grep -A 4 "$_record_name" | grep "record_id" | cut -f2 -d">" | xargs)" + _record_id="$(echo "$response" | tr -d "\n\r" | sed "s/=> Array/\n=> Array/g" | tr -d " " | tr '[]' '<>' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | cut -d '>' -f 3)" _debug2 _record_id "$_record_id" return 0 -} \ No newline at end of file +} From c641b61b26f20771b044bf838ce5943fc163d8f7 Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 29 Nov 2019 22:46:44 +0100 Subject: [PATCH 0542/2234] Fix a few snytax issues --- dnsapi/dns_kas.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index bf01fef3..759b3aaa 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -78,8 +78,7 @@ dns_kas_rm() { # split it into a seperated list, if there where multiples entries made records=($_record_id) - for i in "${records[@]}" - do + for i in "${records[@]}"; do params2="$params&var1=record_id" params2="$params2&wert1=$i" _debug2 "Wait for 10 seconds by default before calling KAS API." @@ -95,7 +94,7 @@ dns_kas_rm() { _err "No record_id found that can be deleted. Please check manually." return 1 fi -return 0 + return 0 } ########################## PRIVATE FUNCTIONS ########################### From 953a9b17681a456ed4538f82e071eca3f713199d Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 29 Nov 2019 22:51:23 +0100 Subject: [PATCH 0543/2234] Remove obsolete blank. --- dnsapi/dns_kas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 759b3aaa..4f2b1d5a 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -149,7 +149,7 @@ _get_record_id() { response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" - _record_id="$(echo "$response" | tr -d "\n\r" | sed "s/=> Array/\n=> Array/g" | tr -d " " | tr '[]' '<>' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | cut -d '>' -f 3)" + _record_id="$(echo "$response" | tr -d "\n\r" | sed "s/=> Array/\n=> Array/g" | tr -d " " | tr '[]' '<>' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | cut -d '>' -f 3)" _debug2 _record_id "$_record_id" return 0 } From 5014f83b86cf456869063043a526476dd9937d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbyszek=20=C5=BB=C3=B3=C5=82kiewski?= Date: Fri, 6 Dec 2019 09:59:35 +0100 Subject: [PATCH 0544/2234] Fix case sensitive detection of domain in the response request --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 4d4957f5..07838b29 100755 --- a/acme.sh +++ b/acme.sh @@ -4082,7 +4082,7 @@ $_authorizations_map" if [ "$ACME_VERSION" = "2" ]; then _idn_d="$(_idn "$d")" - _candindates="$(echo "$_authorizations_map" | grep "^$_idn_d,")" + _candindates="$(echo "$_authorizations_map" | grep -i "^$_idn_d,")" _debug2 _candindates "$_candindates" if [ "$(echo "$_candindates" | wc -l)" -gt 1 ]; then for _can in $_candindates; do From 0ffd5de6fc4a414f207f532e0501929b009935ee Mon Sep 17 00:00:00 2001 From: Gustav Genberg Date: Sun, 8 Dec 2019 00:13:30 +0100 Subject: [PATCH 0545/2234] Fix add record error --- dnsapi/dns_unoeuro.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_unoeuro.sh b/dnsapi/dns_unoeuro.sh index 9132f136..c4593a63 100644 --- a/dnsapi/dns_unoeuro.sh +++ b/dnsapi/dns_unoeuro.sh @@ -52,7 +52,7 @@ dns_unoeuro_add() { fi _info "Adding record" - if _uno_rest POST "my/products/$h/dns/records" "{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":120}"; then + if _uno_rest POST "my/products/$h/dns/records" "{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":120,\"priority\":0}"; then if _contains "$response" "\"status\": 200" >/dev/null; then _info "Added, OK" return 0 From c22705a59392f11007bdd18b086520399794b6e6 Mon Sep 17 00:00:00 2001 From: Wout Date: Wed, 11 Dec 2019 17:13:11 +0100 Subject: [PATCH 0546/2234] Add DNS API support for Constellix. --- dnsapi/dns_constellix.sh | 137 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 dnsapi/dns_constellix.sh diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh new file mode 100644 index 00000000..bc552316 --- /dev/null +++ b/dnsapi/dns_constellix.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env sh + +# Author: Wout Decre + +CONSTELLIX_API="https://api.dns.constellix.com/v1" +#CONSTELLIX_KEY="XXX" +#CONSTELLIX_SECRET="XXX" + +######## Public functions ##################### + +dns_constellix_add() { + fulldomain=$1 + txtvalue=$2 + + CONSTELLIX_KEY="${CONSTELLIX_KEY:-$(_readaccountconf_mutable CONSTELLIX_KEY)}" + CONSTELLIX_SECRET="${CONSTELLIX_SECRET:-$(_readaccountconf_mutable CONSTELLIX_SECRET)}" + + if [ -z "$CONSTELLIX_KEY" ] || [ -z "$CONSTELLIX_SECRET" ]; then + _err "You did not specify the Contellix API key and secret yet." + return 1 + fi + + _saveaccountconf_mutable CONSTELLIX_KEY "$CONSTELLIX_KEY" + _saveaccountconf_mutable CONSTELLIX_SECRET "$CONSTELLIX_SECRET" + + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + + _info "Adding TXT record" + if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"add\":true,\"set\":{\"name\":\"${_sub_domain}\",\"ttl\":120,\"roundRobin\":[{\"value\":\"${txtvalue}\"}]}}]"; then + if printf -- "%s" "$response" | grep "{\"success\":\"1 record(s) added, 0 record(s) updated, 0 record(s) deleted\"}" >/dev/null; then + _info "Added" + return 0 + else + _err "Error adding TXT record" + return 1 + fi + fi +} + +dns_constellix_rm() { + fulldomain=$1 + txtvalue=$2 + + CONSTELLIX_KEY="${CONSTELLIX_KEY:-$(_readaccountconf_mutable CONSTELLIX_KEY)}" + CONSTELLIX_SECRET="${CONSTELLIX_SECRET:-$(_readaccountconf_mutable CONSTELLIX_SECRET)}" + + if [ -z "$CONSTELLIX_KEY" ] || [ -z "$CONSTELLIX_SECRET" ]; then + _err "You did not specify the Contellix API key and secret yet." + return 1 + fi + + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + + _info "Removing TXT record" + if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"delete\":true,\"filter\":{\"field\":\"name\",\"op\":\"eq\",\"value\":\"${_sub_domain}\"}}]"; then + if printf -- "%s" "$response" | grep "{\"success\":\"0 record(s) added, 0 record(s) updated, 1 record(s) deleted\"}" >/dev/null; then + _info "Removed" + return 0 + else + _err "Error removing TXT record" + return 1 + fi + fi +} + +#################### Private functions below ################################## + +_get_root() { + domain=$1 + i=2 + p=1 + _debug "Detecting root zone" + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + return 1 + fi + + if ! _constellix_rest GET "domains"; then + return 1 + fi + + if _contains "$response" "\"name\":\"$h\""; then + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | head -n 1 | cut -d ':' -f 2 | tr -d '}') + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p) + _domain="$h" + + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_constellix_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + rdate=$(date +"%s")"000" + hmac=$(printf "%s" "$rdate" | _hmac sha1 "$(printf "%s" "$CONSTELLIX_SECRET" | _hex_dump | tr -d ' ')" | _base64) + + export _H1="x-cnsdns-apiKey: $CONSTELLIX_KEY" + export _H2="x-cnsdns-requestDate: $rdate" + export _H3="x-cnsdns-hmac: $hmac" + export _H4="Accept: application/json" + export _H5="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$CONSTELLIX_API/$ep" "" "$m")" + else + response="$(_get "$CONSTELLIX_API/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "Error $ep" + return 1 + fi + + _debug response "$response" + return 0 +} From e8e6feeb0ffd273c20328bfa11a36f3f916c997a Mon Sep 17 00:00:00 2001 From: Wout Date: Wed, 11 Dec 2019 17:15:35 +0100 Subject: [PATCH 0547/2234] Use different e-mail. --- dnsapi/dns_constellix.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index bc552316..55f4a71b 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Author: Wout Decre +# Author: Wout Decre CONSTELLIX_API="https://api.dns.constellix.com/v1" #CONSTELLIX_KEY="XXX" From 3ccac629bcbb9f94602a7338891ec56ad9a1501d Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Thu, 12 Dec 2019 16:23:42 +0100 Subject: [PATCH 0548/2234] Change the loop for sh. --- dnsapi/dns_kas.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 4f2b1d5a..a2dc0d5f 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -76,9 +76,7 @@ dns_kas_rm() { params="$params&kas_auth_data=$KAS_Authdata" params="$params&kas_action=delete_dns_settings" - # split it into a seperated list, if there where multiples entries made - records=($_record_id) - for i in "${records[@]}"; do + for i in $_record_id; do params2="$params&var1=record_id" params2="$params2&wert1=$i" _debug2 "Wait for 10 seconds by default before calling KAS API." From f37546e173e41827a7aab169de32124d4fdfd5e9 Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Fri, 13 Dec 2019 18:46:09 +0800 Subject: [PATCH 0549/2234] add acme.sh support for misaka.io dns service --- dnsapi/dns_misaka.sh | 160 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100755 dnsapi/dns_misaka.sh diff --git a/dnsapi/dns_misaka.sh b/dnsapi/dns_misaka.sh new file mode 100755 index 00000000..7d83bf51 --- /dev/null +++ b/dnsapi/dns_misaka.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env sh + +# bug reports to support+acmesh@misaka.io +# based on dns_nsone.sh by dev@1e.ca + +# +#Misaka_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" +# + +Misaka_Api="https://dnsapi.misaka.io/dns" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_misaka_add() { + fulldomain=$1 + txtvalue=$2 + + if [ -z "$Misaka_Key" ]; then + Misaka_Key="" + _err "You didn't specify misaka.io dns api key yet." + _err "Please create you key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf Misaka_Key "$Misaka_Key" + + _debug "checking root zone [$fulldomain]" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _misaka_rest GET "zones/${_domain}/recordsets?search=${_sub_domain}" + + if ! _contains "$response" "\"results\":"; then + _err "Error" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\"" | wc -l | tr -d " ") + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Adding record" + + if _misaka_rest PUT "zones/${_domain}/recordsets/${_sub_domain}/TXT" "{\"records\":[{\"value\":\"\\\"$txtvalue\\\"\"}],\"filters\":[],\"ttl\":1}"; then + _debug response "$response" + if _contains "$response" "$_sub_domain"; then + _info "Added" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + else + _info "Updating record" + + # todo: add existing challenges + _misaka_rest POST "zones/${_domain}/recordsets/${_sub_domain}/TXT" "{\"records\": [{\"value\": \"\\\"$txtvalue\\\"\"}],\"ttl\":1}" + if [ "$?" = "0" ] && _contains "$response" "$_sub_domain"; then + _info "Updated!" + #todo: check if the record takes effect + return 0 + fi + _err "Update error" + return 1 + fi + +} + +#fulldomain +dns_misaka_rm() { + fulldomain=$1 + txtvalue=$2 + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _misaka_rest GET "zones/${_domain}/recordsets?search=${_sub_domain}" + + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\"" | wc -l | tr -d " ") + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + if ! _misaka_rest DELETE "zones/${_domain}/recordsets/${_sub_domain}/TXT"; then + _err "Delete record error." + return 1 + fi + _contains "$response" "" + fi +} + +#################### 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 ! _misaka_rest GET "zones?limit=1000"; 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" "\"name\":\"$h\""; 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 +} + +_misaka_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + export _H1="Content-Type: application/json" + export _H2="User-Agent: acme.sh/$VER misaka-dns-acmesh/20191213" + export _H3="Authorization: Token $Misaka_Key" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$Misaka_Api/$ep" "" "$m")" + else + response="$(_get "$Misaka_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 375b8dceb70ab9fc32e4da4aa62fcb2cb3654284 Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Sat, 14 Dec 2019 10:44:57 +0800 Subject: [PATCH 0550/2234] use append mode to update recordsets --- dnsapi/dns_misaka.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_misaka.sh b/dnsapi/dns_misaka.sh index 7d83bf51..eed4170e 100755 --- a/dnsapi/dns_misaka.sh +++ b/dnsapi/dns_misaka.sh @@ -61,8 +61,7 @@ dns_misaka_add() { else _info "Updating record" - # todo: add existing challenges - _misaka_rest POST "zones/${_domain}/recordsets/${_sub_domain}/TXT" "{\"records\": [{\"value\": \"\\\"$txtvalue\\\"\"}],\"ttl\":1}" + _misaka_rest POST "zones/${_domain}/recordsets/${_sub_domain}/TXT?append=true" "{\"records\": [{\"value\": \"\\\"$txtvalue\\\"\"}],\"ttl\":1}" if [ "$?" = "0" ] && _contains "$response" "$_sub_domain"; then _info "Updated!" #todo: check if the record takes effect From 549ebbb462caa0ad49f9936f28c51dd8191f1fd4 Mon Sep 17 00:00:00 2001 From: wurzelpanzer <32928046+wurzelpanzer@users.noreply.github.com> Date: Sat, 21 Dec 2019 20:19:02 +0100 Subject: [PATCH 0551/2234] Add easyDNS support --- dnsapi/dns_easydns.sh | 172 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 dnsapi/dns_easydns.sh diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh new file mode 100644 index 00000000..1d905841 --- /dev/null +++ b/dnsapi/dns_easydns.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +####################################################### +# +# easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh +# +# Please note: # API is currently beta and subject to constant change +# http://sandbox.rest.easydns.net:3000/ +# +# Author: wurzelpanzer [wurzelpanzer@maximolider.net] +# Report Bugs here: https://github.com/Neilpang/acme.sh/issues/2647 +# +#################### Public functions ################# + +#EASYDNS_Key="xxxxxxxxxxxxxxxxxxxxxxxx" +#EASYDNS_Token="xxxxxxxxxxxxxxxxxxxxxxxx" +EASYDNS_Api="https://rest.easydns.net" + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_easydns_add() { + fulldomain=$1 + txtvalue=$2 + + EASYDNS_Token="${EASYDNS_Token:-$(_readaccountconf_mutable EASYDNS_Token)}" + EASYDNS_Key="${EASYDNS_Key:-$(_readaccountconf_mutable EASYDNS_Key)}" + + if [ -z "$EASYDNS_Token" ] || [ -z "$EASYDNS_Key" ]; then + _err "You didn't specify an easydns.net token or api key. Please sign up at http://docs.sandbox.rest.easydns.net/beta_signup.php" + return 1 + else + _saveaccountconf_mutable EASYDNS_Token "$EASYDNS_Token" + _saveaccountconf_mutable EASYDNS_Key "$EASYDNS_Key" + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _EASYDNS_rest GET "zones/records/all/${_domain}/search/${_sub_domain}" + + if ! printf "%s" "$response" | grep \"status\":200 >/dev/null; then + _err "Error" + return 1 + fi + + _info "Adding record" + if _EASYDNS_rest PUT "zones/records/add/$_domain/TXT" "{\"host\":\"$_sub_domain\",\"rdata\":\"$txtvalue\"}"; then + if _contains "$response" "\"status\":201"; then + _info "Added, OK" + return 0 + elif _contains "$response" "Record already exists"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +dns_easydns_rm() { + fulldomain=$1 + txtvalue=$2 + + EASYDNS_Token="${EASYDNS_Token:-$(_readaccountconf_mutable EASYDNS_Token)}" + EASYDNS_Key="${EASYDNS_Key:-$(_readaccountconf_mutable EASYDNS_Key)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _EASYDNS_rest GET "zones/records/all/${_domain}/search/${_sub_domain}" + + if ! printf "%s" "$response" | grep \"status\":200 >/dev/null; then + _err "Error" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _EASYDNS_rest DELETE "zones/records/$_domain/$record_id"; then + _err "Delete record error." + return 1 + fi + _contains "$response" "\"status\":200" + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _EASYDNS_rest GET "zones/records/all/$h"; then + return 1 + fi + + if _contains "$response" "\"status\":200"; 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 +} + +_EASYDNS_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + basicauth=$(printf "%s" "$EASYDNS_Token":"$EASYDNS_Key" | _base64) + + export _H1="accept: application/json" + if [ "$basicauth" ]; then + export _H2="Authorization: Basic $basicauth" + fi + + if [ "$m" != "GET" ]; then + export _H3="Content-Type: application/json" + _debug data "$data" + response="$(_post "$data" "$EASYDNS_Api/$ep" "" "$m")" + else + response="$(_get "$EASYDNS_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 594b83e7a646e6d5a8176e50712c688da31a8d6a Mon Sep 17 00:00:00 2001 From: Marco4223 Date: Sat, 28 Dec 2019 11:58:21 +0100 Subject: [PATCH 0552/2234] Update dns_kas.sh remove "rev" command fix "Error removing txt for domain:_acme-challenge.foo" --- dnsapi/dns_kas.sh | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index a2dc0d5f..19bfd6bb 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -12,8 +12,7 @@ # Credits: Inspired by dns_he.sh. Thanks a lot man! # Git repo: https://github.com/phlegx/acme.sh # TODO: Better Error handling -# TODO: Does not work with Domains that have double endings like i.e. 'co.uk' -# => Get all root zones and compare once the provider offers that. +######################################################################## KAS_Api="https://kasapi.kasserver.com/dokumentation/formular.php" @@ -26,8 +25,7 @@ dns_kas_add() { _info "Adding or Updating $_fulldomain DNS TXT entry on All-inkl/Kasserver" _check_and_save - _get_zone "$_fulldomain" - _get_record_name "$_fulldomain" + _get_zone_and_record_name "$_fulldomain" _get_record_id _info "Creating TXT DNS record" @@ -65,8 +63,7 @@ dns_kas_rm() { _info "Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver" _check_and_save - _get_zone "$_fulldomain" - _get_record_name "$_fulldomain" + _get_zone_and_record_name "$_fulldomain" _get_record_id # If there is a record_id, delete the entry @@ -116,20 +113,28 @@ _check_and_save() { return 0 } -# Gets back the base domain/zone. -# TODO Get a list of all possible root zones and compare (Currently not possible via provider) +# Gets back the base domain/zone and record name. # See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide -_get_zone() { - _zone=$(echo "$1" | rev | cut -d . -f1-2 | rev). - return 0 -} +_get_zone_and_record_name()() { + _zonen="$( cat testfile.txt | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | cut -d '>' -f 3)" + _domain="$1" + if _endswith "$_domain" "."; then + _domain="$(echo "$_domain" | sed 's/.$//')" + fi + _rootzone="$_domain" + for i in $_zonen; do + l1=${#_rootzone} + l2=${#i} + if _endswith "$_domain" "$i" && [ "$l1" -ge "$l2" ]; then + _rootzone="$i" + fi + done + _zone="$_rootzone" + _debug2 "zone:" "$_zone" -# Removes the domain/subdomain from the entry since kasserver -# cannot handle _fulldomain -# TODO Get a list of all possible root zones and compare (Currently not possible via provider) -# See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide -_get_record_name() { - _record_name=$(echo "$1" | rev | cut -d"." -f3- | rev) + l3=$((${#_domain}-l1-1)) + _record_name="$(echo "$_domain" | cut -c -"$l3")" + _debug2 "record_name:" "$_record_name" return 0 } @@ -146,8 +151,7 @@ _get_record_id() { sleep 10 response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" - - _record_id="$(echo "$response" | tr -d "\n\r" | sed "s/=> Array/\n=> Array/g" | tr -d " " | tr '[]' '<>' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | cut -d '>' -f 3)" + _record_id="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | cut -d '>' -f 3)" _debug2 _record_id "$_record_id" return 0 } From 99c47dd50a7a41fa8ef519c23ee5fc94644135bf Mon Sep 17 00:00:00 2001 From: Marco4223 Date: Sat, 28 Dec 2019 22:42:51 +0100 Subject: [PATCH 0553/2234] Update dns_kas.sh only bash needed --- dnsapi/dns_kas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 19bfd6bb..a39f8c9e 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/bin/bash ######################################################################## # All-inkl Kasserver hook script for acme.sh # From a138425417fe76deb6eade981a6e4c240f9afc41 Mon Sep 17 00:00:00 2001 From: Marco4223 Date: Sat, 28 Dec 2019 23:42:46 +0100 Subject: [PATCH 0554/2234] Update dns_kas.sh sorry for this commit. ;) Fix NewBeMistakes --- dnsapi/dns_kas.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index a39f8c9e..437422bd 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -115,8 +115,8 @@ _check_and_save() { # Gets back the base domain/zone and record name. # See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide -_get_zone_and_record_name()() { - _zonen="$( cat testfile.txt | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | cut -d '>' -f 3)" +_get_zone_and_record_name() { + _zonen="$( echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | cut -d '>' -f 3)" _domain="$1" if _endswith "$_domain" "."; then _domain="$(echo "$_domain" | sed 's/.$//')" From 2214507db01f547520fbed05afb3ecc1035c6fd3 Mon Sep 17 00:00:00 2001 From: Marco4223 Date: Sun, 29 Dec 2019 10:59:28 +0100 Subject: [PATCH 0555/2234] Revert "Update dns_kas.sh" This reverts commit 99c47dd50a7a41fa8ef519c23ee5fc94644135bf. --- dnsapi/dns_kas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 437422bd..5c7cd9ef 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env sh ######################################################################## # All-inkl Kasserver hook script for acme.sh # From a44ea0ddf0ea5ee46e2cf8a6dc54d79e0584639e Mon Sep 17 00:00:00 2001 From: gildea Date: Tue, 31 Dec 2019 20:22:08 -0800 Subject: [PATCH 0556/2234] Return failure when falling through limiting loop In _send_signed_request and _check_dns_entries, return 1 when the timeout (or number of retries) has been exhausted. This allows the calling function to correctly handle the error. --- acme.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 4d4957f5..902b39d4 100755 --- a/acme.sh +++ b/acme.sh @@ -2040,8 +2040,10 @@ _send_signed_request() { continue fi fi - break + return 0 done + _info "Giving up sending to CA server after $MAX_REQUEST_RETRY_TIMES retries." + return 1 } @@ -3819,9 +3821,11 @@ _check_dns_entries() { _sleep 10 else _info "All success, let's return" - break + return 0 fi done + _info "Timed out waiting for DNS." + return 1 } From b59b0f0386fd1b0a35dd68dce0d5d18054973e34 Mon Sep 17 00:00:00 2001 From: Tambet Liiv Date: Thu, 2 Jan 2020 14:55:36 +0200 Subject: [PATCH 0557/2234] use different method to get root --- dnsapi/dns_zone.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_zone.sh b/dnsapi/dns_zone.sh index 847e32cd..176fc494 100755 --- a/dnsapi/dns_zone.sh +++ b/dnsapi/dns_zone.sh @@ -136,10 +136,10 @@ _get_root() { if [ -z "$h" ]; then return 1 fi - if ! _zone_rest GET "dns/$h/a"; then + if ! _zone_rest GET "dns/$h"; then return 1 fi - if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + if _contains "$response" "\"identificator\":\"$h\"" >/dev/null; then _domain=$h return 0 fi From 8dd1df71cc6cf59eaedbe9b2fd0a40279cb98f60 Mon Sep 17 00:00:00 2001 From: Marco4223 Date: Thu, 2 Jan 2020 17:10:36 +0100 Subject: [PATCH 0558/2234] Update dns_kas.sh tested and works now --- dnsapi/dns_kas.sh | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 5c7cd9ef..b17eeee4 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -13,19 +13,18 @@ # Git repo: https://github.com/phlegx/acme.sh # TODO: Better Error handling ######################################################################## - KAS_Api="https://kasapi.kasserver.com/dokumentation/formular.php" - ######## Public functions ##################### - -dns_kas_add() { +dns_kas_add(){ _fulldomain=$1 _txtvalue=$2 _info "Using DNS-01 All-inkl/Kasserver hook" _info "Adding or Updating $_fulldomain DNS TXT entry on All-inkl/Kasserver" - + _info "Check and Save Props" _check_and_save + _info "Checking Zone and Record_Name" _get_zone_and_record_name "$_fulldomain" + _info "Getting Record ID" _get_record_id _info "Creating TXT DNS record" @@ -61,11 +60,14 @@ dns_kas_rm() { _info "Using DNS-01 All-inkl/Kasserver hook" _info "Cleaning up after All-inkl/Kasserver hook" _info "Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver" - + + _info "Check and Save Props" _check_and_save + _info "Checking Zone and Record_Name" _get_zone_and_record_name "$_fulldomain" + _info "Getting Record ID" _get_record_id - + # If there is a record_id, delete the entry if [ -n "$_record_id" ]; then params="?kas_login=$KAS_Login" @@ -116,11 +118,19 @@ _check_and_save() { # Gets back the base domain/zone and record name. # See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide _get_zone_and_record_name() { - _zonen="$( echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | cut -d '>' -f 3)" + + params="?kas_login=$KAS_Login" + params="$params&kas_auth_type=$KAS_Authtype" + params="$params&kas_auth_data=$KAS_Authdata" + params="$params&kas_action=get_domains" + + _debug2 "Wait for 10 seconds by default before calling KAS API." + sleep 10 + response="$(_get "$KAS_Api$params")" + _debug2 "response" "$response" + _zonen="$( echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | sed "s/domain_name>=>//g")" _domain="$1" - if _endswith "$_domain" "."; then - _domain="$(echo "$_domain" | sed 's/.$//')" - fi + _temp_domain="$(echo "$1" | sed 's/\.$//')" _rootzone="$_domain" for i in $_zonen; do l1=${#_rootzone} @@ -129,12 +139,12 @@ _get_zone_and_record_name() { _rootzone="$i" fi done - _zone="$_rootzone" - _debug2 "zone:" "$_zone" - - l3=$((${#_domain}-l1-1)) - _record_name="$(echo "$_domain" | cut -c -"$l3")" - _debug2 "record_name:" "$_record_name" + _zone="${_rootzone}." + _temp_record_name="$(echo "$_temp_domain" | sed "s/"$_rootzone"//g")" + _record_name="$(echo "$_temp_record_name" | sed 's/\.$//')" + _debug2 "Zone:" "$_zone" + _debug2 "Domain:" "$_domain" + _debug2 "Record_Name:" "$_record_name" return 0 } @@ -151,7 +161,7 @@ _get_record_id() { sleep 10 response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" - _record_id="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | cut -d '>' -f 3)" + _record_id="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | sed "s/record_id>=>//g")" _debug2 _record_id "$_record_id" return 0 } From 7a3c61b7449dfe57e079eb124fbe2e934139e132 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 3 Jan 2020 21:38:47 +0800 Subject: [PATCH 0559/2234] check upgrade hash https://github.com/Neilpang/acme.sh/issues/2667 --- acme.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/acme.sh b/acme.sh index fcebab7f..570e2836 100755 --- a/acme.sh +++ b/acme.sh @@ -6303,6 +6303,7 @@ _installOnline() { chmod +x $PROJECT_ENTRY if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then _info "Install success!" + _saveaccountconf "UPGRADE_HASH" "$(_getMasterHash)" fi cd .. @@ -6312,9 +6313,15 @@ _installOnline() { ) } +_getMasterHash() { + _hash_url="https://api.github.com/repos/Neilpang/acme.sh/git/refs/heads/master" + _get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4 +} + upgrade() { if ( _initpath + [ -z "$FORCE" ] && [ "$(_getMasterHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0 export LE_WORKING_DIR cd "$LE_WORKING_DIR" _installOnline "nocron" "noprofile" From 8aedf26a87fff9aadf33df74fafa4615ea1106ef Mon Sep 17 00:00:00 2001 From: Ryan Meyers Date: Sat, 4 Jan 2020 10:51:32 -0600 Subject: [PATCH 0560/2234] Replace \s with hard space --- dnsapi/dns_linode_v4.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index ee7ee892..fc49bb6f 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -36,7 +36,7 @@ dns_linode_v4_add() { }" if _rest POST "/$_domain_id/records" "$_payload" && [ -n "$response" ]; then - _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"id\": *[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) _debug _resource_id "$_resource_id" if [ -z "$_resource_id" ]; then @@ -74,9 +74,9 @@ dns_linode_v4_rm() { if _rest GET "/$_domain_id/records" && [ -n "$response" ]; then response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" - resource="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$_sub_domain\".*}")" + resource="$(echo "$response" | _egrep_o "{.*\"name\": *\"$_sub_domain\".*}")" if [ "$resource" ]; then - _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_resource_id" ]; then _debug _resource_id "$_resource_id" @@ -139,9 +139,9 @@ _get_root() { return 1 fi - hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\":\s*\"$h\".*}")" + hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\": *\"$h\".*}")" if [ "$hostedzone" ]; then - _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 38a8721a91be420a5ce83b6b18558c79ee0eb48a Mon Sep 17 00:00:00 2001 From: Ryan Meyers Date: Sat, 4 Jan 2020 10:52:52 -0600 Subject: [PATCH 0561/2234] Escape opening brackets --- dnsapi/dns_linode_v4.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index fc49bb6f..c2bebc57 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -74,7 +74,7 @@ dns_linode_v4_rm() { if _rest GET "/$_domain_id/records" && [ -n "$response" ]; then response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" - resource="$(echo "$response" | _egrep_o "{.*\"name\": *\"$_sub_domain\".*}")" + resource="$(echo "$response" | _egrep_o "\{.*\"name\": *\"$_sub_domain\".*}")" if [ "$resource" ]; then _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_resource_id" ]; then @@ -139,7 +139,7 @@ _get_root() { return 1 fi - hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\": *\"$h\".*}")" + hostedzone="$(echo "$response" | _egrep_o "\{.*\"domain\": *\"$h\".*}")" if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then From f174d7dd39ac0bc39f12e537e7c987afcaf950aa Mon Sep 17 00:00:00 2001 From: Silvan Raijer Date: Sun, 5 Jan 2020 15:27:04 +0100 Subject: [PATCH 0562/2234] dns_lexicon.sh: Add extra variable _API_KEY --- dnsapi/dns_lexicon.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index f6f54464..bb9f7efc 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -63,6 +63,16 @@ _lexicon_init() { _saveaccountconf_mutable "$Lx_domaintoken" "$Lx_domaintoken_v" eval export "$Lx_domaintoken" fi + + # shellcheck disable=SC2018,SC2019 + Lx_api_key=$(echo LEXICON_"${PROVIDER}"_API_KEY | tr 'a-z' 'A-Z') + eval "$Lx_api_key=\${$Lx_api_key:-$(_readaccountconf_mutable "$Lx_api_key")}" + Lx_api_key_v=$(eval echo \$"$Lx_api_key") + _secure_debug "$Lx_api_key" "$Lx_api_key_v" + if [ "$Lx_api_key_v" ]; then + _saveaccountconf_mutable "$Lx_api_key" "$Lx_api_key_v" + eval export "$Lx_api_key" + fi } ######## Public functions ##################### From c3fbc36ce7142e7013aa4bad3e2d2d4e8596bbca Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 6 Jan 2020 20:57:12 +0800 Subject: [PATCH 0563/2234] fix https://github.com/Neilpang/acme.sh/issues/2547#issuecomment-570963981 --- dnsapi/dns_nic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index e3b39b0c..76e30a87 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -24,7 +24,7 @@ dns_nic_add() { return 1 fi - _saveaccountconf_mutable NIC_Customer "$NIC_Token" + _saveaccountconf_mutable NIC_Token "$NIC_Token" _saveaccountconf_mutable NIC_Username "$NIC_Username" _saveaccountconf_mutable NIC_Password "$NIC_Password" From a88622c1be477dead8175334c08aa450b8e75b1c Mon Sep 17 00:00:00 2001 From: Sergey Zorin Date: Mon, 6 Jan 2020 23:39:15 +0300 Subject: [PATCH 0564/2234] #2547 replace NIC_Token to NIC_ClientID&NIC_ClientSecret with backward compatibility --- dnsapi/dns_nic.sh | 86 +++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 76e30a87..4c3b280f 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -13,22 +13,8 @@ dns_nic_add() { fulldomain="${1}" txtvalue="${2}" - NIC_Token="${NIC_Token:-$(_readaccountconf_mutable NIC_Token)}" - NIC_Username="${NIC_Username:-$(_readaccountconf_mutable NIC_Username)}" - NIC_Password="${NIC_Password:-$(_readaccountconf_mutable NIC_Password)}" - if [ -z "$NIC_Token" ] || [ -z "$NIC_Username" ] || [ -z "$NIC_Password" ]; then - NIC_Token="" - NIC_Username="" - NIC_Password="" - _err "You must export variables: NIC_Token, NIC_Username and NIC_Password" - return 1 - fi - _saveaccountconf_mutable NIC_Token "$NIC_Token" - _saveaccountconf_mutable NIC_Username "$NIC_Username" - _saveaccountconf_mutable NIC_Password "$NIC_Password" - - if ! _nic_get_authtoken "$NIC_Username" "$NIC_Password" "$NIC_Token"; then + if ! _nic_get_authtoken save; then _err "get NIC auth token failed" return 1 fi @@ -59,18 +45,7 @@ dns_nic_rm() { fulldomain="${1}" txtvalue="${2}" - NIC_Token="${NIC_Token:-$(_readaccountconf_mutable NIC_Token)}" - NIC_Username="${NIC_Username:-$(_readaccountconf_mutable NIC_Username)}" - NIC_Password="${NIC_Password:-$(_readaccountconf_mutable NIC_Password)}" - if [ -z "$NIC_Token" ] || [ -z "$NIC_Username" ] || [ -z "$NIC_Password" ]; then - NIC_Token="" - NIC_Username="" - NIC_Password="" - _err "You must export variables: NIC_Token, NIC_Username and NIC_Password" - return 1 - fi - - if ! _nic_get_authtoken "$NIC_Username" "$NIC_Password" "$NIC_Token"; then + if ! _nic_get_authtoken; then _err "get NIC auth token failed" return 1 fi @@ -103,17 +78,64 @@ dns_nic_rm() { #################### Private functions below ################################## +#_nic_get_auth_elements [need2save] +_nic_get_auth_elements() { + _need2save=$1 + + NIC_ClientID="${NIC_ClientID:-$(_readaccountconf_mutable NIC_ClientID)}" + NIC_ClientSecret="${NIC_ClientSecret:-$(_readaccountconf_mutable NIC_ClientSecret)}" + NIC_Username="${NIC_Username:-$(_readaccountconf_mutable NIC_Username)}" + NIC_Password="${NIC_Password:-$(_readaccountconf_mutable NIC_Password)}" + + ## for backward compatibility + if [ -z "$NIC_ClientID" ] || [ -z "$NIC_ClientSecret" ]; then + NIC_Token="${NIC_Token:-$(_readaccountconf_mutable NIC_Token)}" + _debug NIC_Token "$NIC_Token" + if [ -n "$NIC_Token" ]; then + _two_values="$(echo "${NIC_Token}" | _dbase64)" + _debug _two_values "$_two_values" + IFS=":" read -r NIC_ClientID NIC_ClientSecret <<< $_two_values + _debug restored_NIC_ClientID "$NIC_ClientID" + _debug restored_NIC_ClientSecret "$NIC_ClientSecret" + fi + fi + + + if [ -z "$NIC_ClientID" ] || [ -z "$NIC_ClientSecret" ] || [ -z "$NIC_Username" ] || [ -z "$NIC_Password" ]; then + NIC_ClientID="" + NIC_ClientSecret="" + NIC_Username="" + NIC_Password="" + _err "You must export variables: NIC_ClientID, NIC_ClientSecret, NIC_Username and NIC_Password" + return 1 + fi + + if [ "$_need2save" ]; then + _saveaccountconf_mutable NIC_ClientID "$NIC_ClientID" + _saveaccountconf_mutable NIC_ClientSecret "$NIC_ClientSecret" + _saveaccountconf_mutable NIC_Username "$NIC_Username" + _saveaccountconf_mutable NIC_Password "$NIC_Password" + fi + + NIC_BasicAuth=$(printf "%s:%s" "${NIC_ClientID}" "${NIC_ClientSecret}" | _base64) + _debug NIC_BasicAuth "$NIC_BasicAuth" + +} + +#_nic_get_authtoken [need2save] _nic_get_authtoken() { - username="$1" - password="$2" - token="$3" + _need2save=$1 + + if ! _nic_get_auth_elements $_need2save; then + return 1 + fi _info "Getting NIC auth token" - export _H1="Authorization: Basic $token" + export _H1="Authorization: Basic ${NIC_BasicAuth}" export _H2="Content-Type: application/x-www-form-urlencoded" - res=$(_post "grant_type=password&username=$username&password=$password&scope=%28GET%7CPUT%7CPOST%7CDELETE%29%3A%2Fdns-master%2F.%2B" "$NIC_Api/oauth/token" "" "POST") + res=$(_post "grant_type=password&username=${NIC_Username}&password=${NIC_Password}&scope=%28GET%7CPUT%7CPOST%7CDELETE%29%3A%2Fdns-master%2F.%2B" "$NIC_Api/oauth/token" "" "POST") if _contains "$res" "access_token"; then _auth_token=$(printf "%s" "$res" | cut -d , -f2 | tr -d "\"" | sed "s/access_token://") _info "Token received" From 9666cf680e87df90238480ca960d2a7ff83692b3 Mon Sep 17 00:00:00 2001 From: Sergey Zorin Date: Mon, 6 Jan 2020 23:42:08 +0300 Subject: [PATCH 0565/2234] #2547 fix multiply _service selection --- dnsapi/dns_nic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 4c3b280f..9dba92c2 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -168,7 +168,7 @@ _get_root() { if _contains "$_all_domains" "^$h$"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h - _service=$(printf "%s" "$response" | grep "$_domain" | sed -r "s/.*service=\"(.*)\".*$/\1/") + _service=$(printf "%s" "$response" | grep -F "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/") return 0 fi p="$i" From c822870cf850936db13d2fb5a30be230c75209d5 Mon Sep 17 00:00:00 2001 From: Sergey Zorin Date: Mon, 6 Jan 2020 23:52:11 +0300 Subject: [PATCH 0566/2234] comment cleaning --- dnsapi/dns_nic.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 9dba92c2..5629b3be 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -1,10 +1,9 @@ #!/usr/bin/env sh # -#NIC_Token="sdfsdfsdfljlbjkljlkjsdfoiwjedfglgkdlfgkfgldfkg" -# +#NIC_ClientID='0dc0xxxxxxxxxxxxxxxxxxxxxxxxce88' +#NIC_ClientSecret='3LTtxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxnuW8' #NIC_Username="000000/NIC-D" - #NIC_Password="xxxxxxx" NIC_Api="https://api.nic.ru" From 346454c21bdee14074001f6e2aa6e1b7686a0d5d Mon Sep 17 00:00:00 2001 From: Sergey Zorin Date: Tue, 7 Jan 2020 00:26:44 +0300 Subject: [PATCH 0567/2234] fix CI warnings --- dnsapi/dns_nic.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 5629b3be..d0d6e546 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -12,7 +12,6 @@ dns_nic_add() { fulldomain="${1}" txtvalue="${2}" - if ! _nic_get_authtoken save; then _err "get NIC auth token failed" return 1 @@ -93,7 +92,7 @@ _nic_get_auth_elements() { if [ -n "$NIC_Token" ]; then _two_values="$(echo "${NIC_Token}" | _dbase64)" _debug _two_values "$_two_values" - IFS=":" read -r NIC_ClientID NIC_ClientSecret <<< $_two_values + IFS=":" read -r NIC_ClientID NIC_ClientSecret <<<"$_two_values" _debug restored_NIC_ClientID "$NIC_ClientID" _debug restored_NIC_ClientSecret "$NIC_ClientSecret" fi @@ -117,7 +116,7 @@ _nic_get_auth_elements() { fi NIC_BasicAuth=$(printf "%s:%s" "${NIC_ClientID}" "${NIC_ClientSecret}" | _base64) - _debug NIC_BasicAuth "$NIC_BasicAuth" + _debug NIC_BasicAuth "$NIC_BasicAuth" } @@ -125,7 +124,7 @@ _nic_get_auth_elements() { _nic_get_authtoken() { _need2save=$1 - if ! _nic_get_auth_elements $_need2save; then + if ! _nic_get_auth_elements "$_need2save"; then return 1 fi From 8e2f11389d7b17c90a04ef97b2bd1ddb28176960 Mon Sep 17 00:00:00 2001 From: Sergey Zorin Date: Tue, 7 Jan 2020 00:49:13 +0300 Subject: [PATCH 0568/2234] fix CI warnings SC2039 --- dnsapi/dns_nic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index d0d6e546..34429fe4 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -92,7 +92,7 @@ _nic_get_auth_elements() { if [ -n "$NIC_Token" ]; then _two_values="$(echo "${NIC_Token}" | _dbase64)" _debug _two_values "$_two_values" - IFS=":" read -r NIC_ClientID NIC_ClientSecret <<<"$_two_values" + IFS=":" read -r NIC_ClientID NIC_ClientSecret < <(echo "$_two_values") _debug restored_NIC_ClientID "$NIC_ClientID" _debug restored_NIC_ClientSecret "$NIC_ClientSecret" fi From be7688a4dfae5dac8d95707e985aefbfbccfd50d Mon Sep 17 00:00:00 2001 From: Sergey Zorin Date: Tue, 7 Jan 2020 01:05:50 +0300 Subject: [PATCH 0569/2234] fix CI warnings SC2039 v2 --- dnsapi/dns_nic.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 34429fe4..190d4d1f 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -92,7 +92,8 @@ _nic_get_auth_elements() { if [ -n "$NIC_Token" ]; then _two_values="$(echo "${NIC_Token}" | _dbase64)" _debug _two_values "$_two_values" - IFS=":" read -r NIC_ClientID NIC_ClientSecret < <(echo "$_two_values") + NIC_ClientID=$(echo "$_two_values" | cut -d':' -f1) + NIC_ClientSecret=$(echo "$_two_values" | cut -d':' -f2-) _debug restored_NIC_ClientID "$NIC_ClientID" _debug restored_NIC_ClientSecret "$NIC_ClientSecret" fi From f3dd1603db9f998f2496e2baee89bac0b9ac7615 Mon Sep 17 00:00:00 2001 From: Sergey Zorin Date: Tue, 7 Jan 2020 01:11:43 +0300 Subject: [PATCH 0570/2234] fix CI warnings v3 --- dnsapi/dns_nic.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 190d4d1f..1ad18d5b 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -99,7 +99,6 @@ _nic_get_auth_elements() { fi fi - if [ -z "$NIC_ClientID" ] || [ -z "$NIC_ClientSecret" ] || [ -z "$NIC_Username" ] || [ -z "$NIC_Password" ]; then NIC_ClientID="" NIC_ClientSecret="" From efd3e8067b28c269517ec89e08d77284a8907931 Mon Sep 17 00:00:00 2001 From: Sergey Zorin Date: Thu, 9 Jan 2020 17:05:18 +0300 Subject: [PATCH 0571/2234] remove -F option --- dnsapi/dns_nic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 1ad18d5b..5052ee10 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -166,7 +166,7 @@ _get_root() { if _contains "$_all_domains" "^$h$"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h - _service=$(printf "%s" "$response" | grep -F "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/") + _service=$(printf "%s" "$response" | grep "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/") return 0 fi p="$i" From 0712e98904448fd16fc5aeaece54685d099f730d Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 12 Jan 2020 13:36:24 +0800 Subject: [PATCH 0572/2234] fix https://github.com/Neilpang/acme.sh/pull/2559 --- acme.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 570e2836..539e843d 100755 --- a/acme.sh +++ b/acme.sh @@ -2019,7 +2019,7 @@ _send_signed_request() { _debug code "$code" _debug2 original "$response" - if echo "$responseHeaders" | grep -i "Content-Type: application/json" >/dev/null 2>&1; then + if echo "$responseHeaders" | grep -i "Content-Type: *application/json" >/dev/null 2>&1; then response="$(echo "$response" | _normalizeJson)" fi _debug2 response "$response" @@ -3447,7 +3447,7 @@ _regAccount() { fi _debug2 responseHeaders "$responseHeaders" - _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")" + _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" _debug "_accUri" "$_accUri" if [ -z "$_accUri" ]; then _err "Can not find account id url." @@ -4006,7 +4006,7 @@ issue() { _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)" + 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)" _debug Le_OrderFinalize "$Le_OrderFinalize" @@ -4521,7 +4521,7 @@ $_authorizations_map" return 1 fi if [ -z "$Le_LinkOrder" ]; then - Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)" + Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d ":" -f 2-)" fi _savedomainconf "Le_LinkOrder" "$Le_LinkOrder" @@ -5572,7 +5572,7 @@ _deactivate() { return 1 fi - authzUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")" + authzUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n")" _debug "authzUri" "$authzUri" if [ "$code" ] && [ ! "$code" = '201' ]; then _err "new-authz error: $response" From 8494ac8f3dbe88123db60ab4441f27574d13f46e Mon Sep 17 00:00:00 2001 From: Nick Stepa Date: Sun, 12 Jan 2020 13:29:09 +0100 Subject: [PATCH 0573/2234] Fix dns records removing after usage. --- dnsapi/dns_yandex.sh | 128 ++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 57 deletions(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index a4f39784..90bbf74e 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -6,83 +6,91 @@ # Values to export: # export PDD_Token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +# Sometimes cloudflare / google doesn't pick new dns recods fast enough. +# You can add --dnssleep XX to params as workaround. + ######## Public functions ##################### #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_yandex_add() { - fulldomain="${1}" - txtvalue="${2}" - _debug "Calling: dns_yandex_add() '${fulldomain}' '${txtvalue}'" + local fulldomain="${1}" + local txtvalue="${2}" + _debug "Calling: dns_yandex_add() '${fulldomain}' '$txtvalue'" + _PDD_credentials || return 1 - export _H1="PddToken: $PDD_Token" _PDD_get_domain "$fulldomain" || return 1 - _debug "Found suitable domain in pdd: $curDomain" - curData="domain=${curDomain}&type=TXT&subdomain=${curSubdomain}&ttl=360&content=${txtvalue}" - curUri="https://pddimp.yandex.ru/api2/admin/dns/add" - curResult="$(_post "${curData}" "${curUri}")" - _debug "Result: $curResult" + _debug "Found suitable domain: $domain" + + _PDD_get_record_ids "${domain}" "${subdomain}" || return 1 + _debug "Record_ids: $record_ids" + + if [ ! -z "$record_ids" ]; then + _err "Remove all existing $subdomain records from $domain" + return 1 + fi + + local data="domain=${domain}&type=TXT&subdomain=${subdomain}&ttl=300&content=${txtvalue}" + local uri="https://pddimp.yandex.ru/api2/admin/dns/add" + local result="$(_post "${data}" "${uri}" | _normalizeJson)" + _debug "Result: $result" + + if ! _contains "$result" '"success":"ok"'; then + _err "Can't add $subdomain to $domain" + return 1 + fi } #Usage: dns_myapi_rm _acme-challenge.www.domain.com dns_yandex_rm() { - fulldomain="${1}" + local fulldomain="${1}" _debug "Calling: dns_yandex_rm() '${fulldomain}'" + _PDD_credentials || return 1 - export _H1="PddToken: $PDD_Token" _PDD_get_domain "$fulldomain" || return 1 - _debug "Found suitable domain in pdd: $curDomain" + _debug "Found suitable domain: $domain" - record_id=$(pdd_get_record_id "${fulldomain}") - _debug "Result: $record_id" + _PDD_get_record_ids "${domain}" "${subdomain}" || return 1 + _debug "Record_ids: $record_ids" - for rec_i in $record_id; do - curUri="https://pddimp.yandex.ru/api2/admin/dns/del" - curData="domain=${curDomain}&record_id=${rec_i}" - curResult="$(_post "${curData}" "${curUri}")" - _debug "Result: $curResult" + for record_id in $record_ids; do + local data="domain=${domain}&record_id=${record_id}" + local uri="https://pddimp.yandex.ru/api2/admin/dns/del" + local result="$(_post "${data}" "${uri}" | _normalizeJson)" + _debug "Result: $result" + + if ! _contains "$result" '"success":"ok"'; then + _info "Can't remove $subdomain from $domain" + fi done } #################### Private functions below ################################## _PDD_get_domain() { - fulldomain="${1}" - __page=1 - __last=0 - while [ $__last -eq 0 ]; do - uri1="https://pddimp.yandex.ru/api2/admin/domain/domains?page=${__page}&on_page=20" - res1="$(_get "$uri1" | _normalizeJson)" - _debug2 "res1" "$res1" - __found="$(echo "$res1" | sed -n -e 's#.* "found": \([^,]*\),.*#\1#p')" - _debug "found: $__found results on page" - if [ "0$__found" -lt 20 ]; then - _debug "last page: $__page" - __last=1 + local fulldomain=${1} + + local subdomain_start=1 + while true; do + local domain_start=$(_math $subdomain_start + 1) + domain=$(echo "$fulldomain" | cut -d . -f $domain_start-) + subdomain=$(echo "$fulldomain" | cut -d . -f -$subdomain_start) + + _debug "Checking domain $domain" + if [ -z "$domain" ]; then + return 1 fi - __all_domains="$__all_domains $(echo "$res1" | tr "," "\n" | grep '"name"' | cut -d: -f2 | sed -e 's@"@@g')" + local uri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=$domain" + local result="$(_get "${uri}" | _normalizeJson)" + _debug "Result: $result" - __page=$(_math $__page + 1) - done - - k=2 - while [ $k -lt 10 ]; do - __t=$(echo "$fulldomain" | cut -d . -f $k-100) - _debug "finding zone for domain $__t" - for d in $__all_domains; do - if [ "$d" = "$__t" ]; then - p=$(_math $k - 1) - curSubdomain="$(echo "$fulldomain" | cut -d . -f "1-$p")" - curDomain="$__t" + if _contains "$result" '"success":"ok"'; then return 0 - fi - done - k=$(_math $k + 1) + fi + subdomain_start=$(_math $subdomain_start + 1) done - _err "No suitable domain found in your account" - return 1 } _PDD_credentials() { @@ -94,16 +102,22 @@ _PDD_credentials() { else _saveaccountconf PDD_Token "${PDD_Token}" fi + export _H1="PddToken: $PDD_Token" } -pdd_get_record_id() { - fulldomain="${1}" +_PDD_get_record_ids() { + local domain="${1}" + local subdomain="${2}" - _PDD_get_domain "$fulldomain" - _debug "Found suitable domain in pdd: $curDomain" + _debug "Check existing records for $subdomain" - curUri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=${curDomain}" - curResult="$(_get "${curUri}" | _normalizeJson)" - _debug "Result: $curResult" - echo "$curResult" | _egrep_o "{[^{]*\"content\":[^{]*\"subdomain\":\"${curSubdomain}\"" | sed -n -e 's#.* "record_id": \(.*\),[^,]*#\1#p' + local uri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=${domain}" + local result="$(_get "${uri}" | _normalizeJson)" + _debug "Result: $result" + + if ! _contains "$result" '"success":"ok"'; then + return 1 + fi + + record_ids=$(echo "$result" | _egrep_o "{[^{]*\"subdomain\":\"${subdomain}\"[^}]*}" | sed -n -e 's#.*"record_id": \([0-9]*\).*#\1#p') } From ef7b51beb7d7c0e6607efca377e1089531aeb435 Mon Sep 17 00:00:00 2001 From: Nick Stepa Date: Sun, 12 Jan 2020 13:54:18 +0100 Subject: [PATCH 0574/2234] Remove local keyword. --- dnsapi/dns_yandex.sh | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index 90bbf74e..fc693d6e 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -6,15 +6,15 @@ # Values to export: # export PDD_Token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -# Sometimes cloudflare / google doesn't pick new dns recods fast enough. +# Sometimes cloudflare / google doesn't pick new dns records fast enough. # You can add --dnssleep XX to params as workaround. ######## Public functions ##################### #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_yandex_add() { - local fulldomain="${1}" - local txtvalue="${2}" + fulldomain="${1}" + txtvalue="${2}" _debug "Calling: dns_yandex_add() '${fulldomain}' '$txtvalue'" _PDD_credentials || return 1 @@ -30,9 +30,9 @@ dns_yandex_add() { return 1 fi - local data="domain=${domain}&type=TXT&subdomain=${subdomain}&ttl=300&content=${txtvalue}" - local uri="https://pddimp.yandex.ru/api2/admin/dns/add" - local result="$(_post "${data}" "${uri}" | _normalizeJson)" + data="domain=${domain}&type=TXT&subdomain=${subdomain}&ttl=300&content=${txtvalue}" + uri="https://pddimp.yandex.ru/api2/admin/dns/add" + result="$(_post "${data}" "${uri}" | _normalizeJson)" _debug "Result: $result" if ! _contains "$result" '"success":"ok"'; then @@ -43,7 +43,7 @@ dns_yandex_add() { #Usage: dns_myapi_rm _acme-challenge.www.domain.com dns_yandex_rm() { - local fulldomain="${1}" + fulldomain="${1}" _debug "Calling: dns_yandex_rm() '${fulldomain}'" _PDD_credentials || return 1 @@ -55,9 +55,9 @@ dns_yandex_rm() { _debug "Record_ids: $record_ids" for record_id in $record_ids; do - local data="domain=${domain}&record_id=${record_id}" - local uri="https://pddimp.yandex.ru/api2/admin/dns/del" - local result="$(_post "${data}" "${uri}" | _normalizeJson)" + data="domain=${domain}&record_id=${record_id}" + uri="https://pddimp.yandex.ru/api2/admin/dns/del" + result="$(_post "${data}" "${uri}" | _normalizeJson)" _debug "Result: $result" if ! _contains "$result" '"success":"ok"'; then @@ -69,21 +69,21 @@ dns_yandex_rm() { #################### Private functions below ################################## _PDD_get_domain() { - local fulldomain=${1} + fulldomain=${1} - local subdomain_start=1 + subdomain_start=1 while true; do - local domain_start=$(_math $subdomain_start + 1) - domain=$(echo "$fulldomain" | cut -d . -f $domain_start-) - subdomain=$(echo "$fulldomain" | cut -d . -f -$subdomain_start) + domain_start=$(_math $subdomain_start + 1) + domain=$(echo "$fulldomain" | cut -d . -f "$domain_start"-) + subdomain=$(echo "$fulldomain" | cut -d . -f -"$subdomain_start") _debug "Checking domain $domain" if [ -z "$domain" ]; then return 1 fi - local uri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=$domain" - local result="$(_get "${uri}" | _normalizeJson)" + uri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=$domain" + result="$(_get "${uri}" | _normalizeJson)" _debug "Result: $result" if _contains "$result" '"success":"ok"'; then @@ -106,13 +106,13 @@ _PDD_credentials() { } _PDD_get_record_ids() { - local domain="${1}" - local subdomain="${2}" + domain="${1}" + subdomain="${2}" _debug "Check existing records for $subdomain" - local uri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=${domain}" - local result="$(_get "${uri}" | _normalizeJson)" + uri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=${domain}" + result="$(_get "${uri}" | _normalizeJson)" _debug "Result: $result" if ! _contains "$result" '"success":"ok"'; then From e5f69f0815b39d37e49188e659f3b0b6f4d9b58f Mon Sep 17 00:00:00 2001 From: Nick Stepa Date: Sun, 12 Jan 2020 14:07:49 +0100 Subject: [PATCH 0575/2234] Fix indentation. --- dnsapi/dns_yandex.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index fc693d6e..cf702ba8 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -26,8 +26,8 @@ dns_yandex_add() { _debug "Record_ids: $record_ids" if [ ! -z "$record_ids" ]; then - _err "Remove all existing $subdomain records from $domain" - return 1 + _err "Remove all existing $subdomain records from $domain" + return 1 fi data="domain=${domain}&type=TXT&subdomain=${subdomain}&ttl=300&content=${txtvalue}" @@ -36,8 +36,8 @@ dns_yandex_add() { _debug "Result: $result" if ! _contains "$result" '"success":"ok"'; then - _err "Can't add $subdomain to $domain" - return 1 + _err "Can't add $subdomain to $domain" + return 1 fi } @@ -87,7 +87,7 @@ _PDD_get_domain() { _debug "Result: $result" if _contains "$result" '"success":"ok"'; then - return 0 + return 0 fi subdomain_start=$(_math $subdomain_start + 1) done @@ -116,7 +116,7 @@ _PDD_get_record_ids() { _debug "Result: $result" if ! _contains "$result" '"success":"ok"'; then - return 1 + return 1 fi record_ids=$(echo "$result" | _egrep_o "{[^{]*\"subdomain\":\"${subdomain}\"[^}]*}" | sed -n -e 's#.*"record_id": \([0-9]*\).*#\1#p') From 4eff3b6a24efd9cae60183cbbde4b89eef8f391c Mon Sep 17 00:00:00 2001 From: Nick Stepa Date: Sun, 12 Jan 2020 15:16:48 +0100 Subject: [PATCH 0576/2234] Change error to info in case record already exists. --- dnsapi/dns_yandex.sh | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index cf702ba8..5721f994 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -15,19 +15,18 @@ dns_yandex_add() { fulldomain="${1}" txtvalue="${2}" - _debug "Calling: dns_yandex_add() '${fulldomain}' '$txtvalue'" + _debug "Calling: dns_yandex_add() '${fulldomain}' '${txtvalue}'" _PDD_credentials || return 1 - _PDD_get_domain "$fulldomain" || return 1 + _PDD_get_domain || return 1 _debug "Found suitable domain: $domain" - _PDD_get_record_ids "${domain}" "${subdomain}" || return 1 + _PDD_get_record_ids || return 1 _debug "Record_ids: $record_ids" if [ ! -z "$record_ids" ]; then - _err "Remove all existing $subdomain records from $domain" - return 1 + _info "All existing $subdomain records from $domain will be removed at the very end." fi data="domain=${domain}&type=TXT&subdomain=${subdomain}&ttl=300&content=${txtvalue}" @@ -36,8 +35,12 @@ dns_yandex_add() { _debug "Result: $result" if ! _contains "$result" '"success":"ok"'; then - _err "Can't add $subdomain to $domain" - return 1 + if _contains "$result" '"success":"error"' && _contains "$result" '"error":"record_exists"'; then + _info "Record already exists." + else + _err "Can't add $subdomain to $domain." + return 1 + fi fi } @@ -61,7 +64,7 @@ dns_yandex_rm() { _debug "Result: $result" if ! _contains "$result" '"success":"ok"'; then - _info "Can't remove $subdomain from $domain" + _info "Can't remove $subdomain from $domain." fi done } @@ -69,8 +72,6 @@ dns_yandex_rm() { #################### Private functions below ################################## _PDD_get_domain() { - fulldomain=${1} - subdomain_start=1 while true; do domain_start=$(_math $subdomain_start + 1) @@ -96,8 +97,8 @@ _PDD_get_domain() { _PDD_credentials() { if [ -z "${PDD_Token}" ]; then PDD_Token="" - _err "You need to export PDD_Token=xxxxxxxxxxxxxxxxx" - _err "You can get it at https://pddimp.yandex.ru/api2/admin/get_token" + _err "You need to export PDD_Token=xxxxxxxxxxxxxxxxx." + _err "You can get it at https://pddimp.yandex.ru/api2/admin/get_token." return 1 else _saveaccountconf PDD_Token "${PDD_Token}" @@ -106,9 +107,6 @@ _PDD_credentials() { } _PDD_get_record_ids() { - domain="${1}" - subdomain="${2}" - _debug "Check existing records for $subdomain" uri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=${domain}" From 70fdb1042fd194e6e107e57d5ce1a670f3df0070 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Tue, 14 Jan 2020 15:55:44 +0300 Subject: [PATCH 0577/2234] fix: added public dns zones filter --- dnsapi/dns_gcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index ebbeecf2..6365b338 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -131,7 +131,7 @@ _dns_gcloud_find_zone() { filter="$filter$part. " part="$(echo "$part" | sed 's/[^.]*\.*//')" done - filter="$filter)" + filter="$filter) AND visibility=public" _debug filter "$filter" # List domains and find the zone with the deepest sub-domain (in case of some levels of delegation) From f01936ca4fac5499d90787098c2eec3a6359ab56 Mon Sep 17 00:00:00 2001 From: helbgd Date: Tue, 14 Jan 2020 15:19:37 +0100 Subject: [PATCH 0578/2234] Server Name not correct the servername of the server that has the upd.php file was not correct --- dnsapi/dns_ddnss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index 903b9619..1bf258f5 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -12,7 +12,7 @@ # -- # -DDNSS_DNS_API="https://ddnss.de/upd.php" +DDNSS_DNS_API="https://www.ddnss.de/upd.php" ######## Public functions ##################### From b1ce6ffcc79da2d0b458a4195c10d1fd45a59182 Mon Sep 17 00:00:00 2001 From: helbgd Date: Tue, 14 Jan 2020 15:27:35 +0100 Subject: [PATCH 0579/2234] www is incorrect as well use ip4 and not www, if you use www it deletes the ip4 address of the host and updates only the ip6 address --- dnsapi/dns_ddnss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index 1bf258f5..53781d0d 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -12,7 +12,7 @@ # -- # -DDNSS_DNS_API="https://www.ddnss.de/upd.php" +DDNSS_DNS_API="https://ip4.ddnss.de/upd.php" ######## Public functions ##################### From 024619676b73e2cf20527471c6209c924d63c0e4 Mon Sep 17 00:00:00 2001 From: Marco4223 Date: Wed, 15 Jan 2020 13:56:01 +0100 Subject: [PATCH 0580/2234] Update dns_kas.sh fixing 4 Travis style --- dnsapi/dns_kas.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index b17eeee4..31d68e62 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -9,17 +9,18 @@ # - $KAS_Authdata (Kasserver API auth data.) # # Author: Martin Kammerlander, Phlegx Systems OG +# Updated by: Marc-Oliver Lange # Credits: Inspired by dns_he.sh. Thanks a lot man! # Git repo: https://github.com/phlegx/acme.sh # TODO: Better Error handling ######################################################################## KAS_Api="https://kasapi.kasserver.com/dokumentation/formular.php" -######## Public functions ##################### -dns_kas_add(){ +######## Public functions ##################### +dns_kas_add() { _fulldomain=$1 _txtvalue=$2 _info "Using DNS-01 All-inkl/Kasserver hook" - _info "Adding or Updating $_fulldomain DNS TXT entry on All-inkl/Kasserver" + _info "Adding $_fulldomain DNS TXT entry on All-inkl/Kasserver" _info "Check and Save Props" _check_and_save _info "Checking Zone and Record_Name" @@ -128,9 +129,9 @@ _get_zone_and_record_name() { sleep 10 response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" - _zonen="$( echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | sed "s/domain_name>=>//g")" + _zonen="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | sed "s/domain_name>=>//g")" _domain="$1" - _temp_domain="$(echo "$1" | sed 's/\.$//')" + _temp_domain="$(echo "$1" | sed 's/\.$//')" _rootzone="$_domain" for i in $_zonen; do l1=${#_rootzone} @@ -140,8 +141,8 @@ _get_zone_and_record_name() { fi done _zone="${_rootzone}." - _temp_record_name="$(echo "$_temp_domain" | sed "s/"$_rootzone"//g")" - _record_name="$(echo "$_temp_record_name" | sed 's/\.$//')" + _temp_record_name="$(echo "$_temp_domain" | sed "s/$_rootzone//g")" + _record_name="$(echo "$_temp_record_name" | sed 's/\.$//')" _debug2 "Zone:" "$_zone" _debug2 "Domain:" "$_domain" _debug2 "Record_Name:" "$_record_name" From ac3667c7652a6338aba1528de4a4dd7b0d77e8cd Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 15 Jan 2020 21:43:49 +0800 Subject: [PATCH 0581/2234] fix https://github.com/Neilpang/acme.sh/issues/2693 --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index 539e843d..f461c575 100755 --- a/acme.sh +++ b/acme.sh @@ -6303,6 +6303,7 @@ _installOnline() { chmod +x $PROJECT_ENTRY if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then _info "Install success!" + _initpath _saveaccountconf "UPGRADE_HASH" "$(_getMasterHash)" fi From f8f53a6bd99d50293bc775fb74fcee9bde8a1280 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 15 Jan 2020 22:01:34 +0800 Subject: [PATCH 0582/2234] debug --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index f461c575..cae7c30e 100755 --- a/acme.sh +++ b/acme.sh @@ -2415,7 +2415,7 @@ __initHome() { if [ -z "$ACCOUNT_CONF_PATH" ]; then ACCOUNT_CONF_PATH="$_DEFAULT_ACCOUNT_CONF_PATH" fi - + _debug3 ACCOUNT_CONF_PATH "$ACCOUNT_CONF_PATH" DEFAULT_LOG_FILE="$LE_CONFIG_HOME/$PROJECT_NAME.log" DEFAULT_CA_HOME="$LE_CONFIG_HOME/ca" From 26309f51e380c0c60798a62ba1842b1263cc6fcf Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 15 Jan 2020 22:04:49 +0800 Subject: [PATCH 0583/2234] start 2.8.5 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 539e843d..547d4a1d 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.4 +VER=2.8.5 PROJECT_NAME="acme.sh" From 79ad0ff56baac1a338d4155e40f77bc8eeae8109 Mon Sep 17 00:00:00 2001 From: rewqazxv <41326691+rewqazxv@users.noreply.github.com> Date: Wed, 15 Jan 2020 22:11:34 +0800 Subject: [PATCH 0584/2234] Simplify code --- acme.sh | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index d3c0fc7a..00d10fcc 100755 --- a/acme.sh +++ b/acme.sh @@ -6362,18 +6362,11 @@ _checkSudo() { #it's root using sudo, no matter it's using sudo or not, just fine return 0 fi - case "$SUDO_COMMAND" in - */su) - #it's a normal user doing `sudo su`, no problem - return 0 - ;; - esac - for i in $(cat /etc/shells); do - if [ "$SUDO_COMMAND" = "$i" ]; then - #it's a normal user running `sudo -i` or `sudo -s`, fine - return 0 - fi - done + if [ -n "$SUDO_COMMAND" ]; then + #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s` + _endswith "$SUDO_COMMAND" /bin/su || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1 + return $? + fi #otherwise return 1 fi From 431c53efcf6f8ee4ae011b572729b624c9c86ace Mon Sep 17 00:00:00 2001 From: Marco4223 Date: Wed, 15 Jan 2020 17:48:30 +0100 Subject: [PATCH 0585/2234] Update dns_kas.sh Removing spaces in empty lines --- dnsapi/dns_kas.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 31d68e62..95401684 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -61,14 +61,14 @@ dns_kas_rm() { _info "Using DNS-01 All-inkl/Kasserver hook" _info "Cleaning up after All-inkl/Kasserver hook" _info "Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver" - + _info "Check and Save Props" _check_and_save _info "Checking Zone and Record_Name" _get_zone_and_record_name "$_fulldomain" _info "Getting Record ID" _get_record_id - + # If there is a record_id, delete the entry if [ -n "$_record_id" ]; then params="?kas_login=$KAS_Login" @@ -119,7 +119,7 @@ _check_and_save() { # Gets back the base domain/zone and record name. # See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide _get_zone_and_record_name() { - + params="?kas_login=$KAS_Login" params="?kas_login=$KAS_Login" params="$params&kas_auth_type=$KAS_Authtype" params="$params&kas_auth_data=$KAS_Authdata" From 0f54cf83f4f24f037e1adf52be37c9e809df4825 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sat, 18 Jan 2020 13:48:29 +0100 Subject: [PATCH 0586/2234] fixed dynv6 dns validation --- dnsapi/dns_dynv6.sh | 125 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 dnsapi/dns_dynv6.sh diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh new file mode 100644 index 00000000..b1fa7650 --- /dev/null +++ b/dnsapi/dns_dynv6.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env sh +#Author StefanAbl +#Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"' +#if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub +######## Public functions ##################### +# Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_dynv6_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using dynv6 api" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + _get_keyfile + + _info "using keyfile $dynv6_keyfile" + _get_domain "$fulldomain" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _contains "$_your_hosts" "$_host"; then + _debug "The host is $_host and the record $_record" + _debug "Dynv6 returned $_your_hosts" + _err "The host $_host does not exists on your dynv6 account" + return 1 + fi + _debug "found host on your account" + returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" + _debug "Dynv6 returend this after record was added: $returnval" + if _contains "$returnval" "created"; then + return 0 + elif _contains "$returnval" "updated"; then + return 0 + else + _err "Something went wrong! it does not seem like the record was added succesfully" + return 1 + fi + return 1 +} +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_dynv6_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using dynv6 api" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + _get_keyfile + _info "using keyfile $dynv6_keyfile" + _get_domain "$fulldomain" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _contains "$_your_hosts" "$_host"; then + _debug "The host is $_host and the record $_record" + _debug "Dynv6 returned $_your_hosts" + _err "The host $_host does not exists on your dynv6 account" + return 1 + fi + _debug "found host on your account" + _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" + return 0 + +} +#################### Private functions below ################################## +#Usage: No Input required +#returns +#dynv6_keyfile the path to the new keyfile that has been generated +_generate_new_key() { + dynv6_keyfile="$(eval echo ~"$USER")/.ssh/dynv6" + _info "Path to key file used: $dynv6_keyfile" + if [ ! -f "$dynv6_keyfile" ] && [ ! -f "$dynv6_keyfile.pub" ]; then + _debug "generating key in $dynv6_keyfile and $dynv6_keyfile.pub" + ssh-keygen -f "$dynv6_keyfile" -t ssh-ed25519 -N '' + else + _err "There is already a file in $dynv6_keyfile or $dynv6_keyfile.pub" + return 1 + fi + +} +#Usage: _acme-challenge.www.example.dynv6.net +#returns +#_host= example.dynv6.net +#_record=_acme-challenge.www +#aborts if not a valid domain +_get_domain() { + _full_domain="$1" + _debug "getting domain for $_full_domain" + if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy'; then + _err "The hosts does not seem to be a dynv6 host" + return 1 + fi + _record="${_full_domain%.*}" + _record="${_record%.*}" + _record="${_record%.*}" + _debug "The record we are ging to use is $_record" + _host="$_full_domain" + while [ "$(echo "$_host" | grep -o '\.' | wc -l)" != "2" ]; do + _host="${_host#*.}" + done + _debug "And the host is $_host" + return 0 + +} + +# Usage: No input required +#returns +#dynv6_keyfile path to the key that will be used +_get_keyfile() { + _debug "get keyfile method called" + dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" + _debug Your key is "$dynv6_keyfile" + if [ -z "$dynv6_keyfile" ]; then + if [ -z "$KEY" ]; then + _err "You did not specify a key to use with dynv6" + _info "Creating new dynv6 api key to add to dynv6.com" + _generate_new_key + _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" + _info "Hit Enter to contiue" + read _ + #save the credentials to the account conf file. + else + dynv6_keyfile="$KEY" + fi + _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" + fi + + +} From 6e3ba3ca45daaa47f2afe901647585bb6d5c2010 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sat, 18 Jan 2020 13:53:26 +0100 Subject: [PATCH 0587/2234] travis --- dnsapi/dns_dynv6.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index b1fa7650..cf39282b 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -12,7 +12,6 @@ dns_dynv6_add() { _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" _get_keyfile - _info "using keyfile $dynv6_keyfile" _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" @@ -72,7 +71,6 @@ _generate_new_key() { _err "There is already a file in $dynv6_keyfile or $dynv6_keyfile.pub" return 1 fi - } #Usage: _acme-challenge.www.example.dynv6.net #returns @@ -103,7 +101,7 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_keyfile() { - _debug "get keyfile method called" + _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" _debug Your key is "$dynv6_keyfile" if [ -z "$dynv6_keyfile" ]; then @@ -113,13 +111,11 @@ _get_keyfile() { _generate_new_key _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" _info "Hit Enter to contiue" - read _ + read -r _ #save the credentials to the account conf file. else dynv6_keyfile="$KEY" fi _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" fi - - } From e7d130cc11e4a52695e84fd1ea86d7c27a090b18 Mon Sep 17 00:00:00 2001 From: Radek SPRTA Date: Tue, 21 Jan 2020 06:36:31 +0100 Subject: [PATCH 0588/2234] Add support for CloudDNS API --- dnsapi/dns_clouddns.sh | 186 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100755 dnsapi/dns_clouddns.sh diff --git a/dnsapi/dns_clouddns.sh b/dnsapi/dns_clouddns.sh new file mode 100755 index 00000000..2678c66b --- /dev/null +++ b/dnsapi/dns_clouddns.sh @@ -0,0 +1,186 @@ +#!/usr/bin/env sh + +# Author: Radek Sprta + +#CLOUDDNS_EMAIL=XXXXX +#CLOUDDNS_PASSWORD="YYYYYYYYY" +#CLOUDDNS_CLIENT_ID=XXXXX + +CLOUDDNS_API='https://admin.vshosting.cloud/clouddns' +CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login' + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_clouddns_add() { + fulldomain=$1 + txtvalue=$2 + + CLOUDDNS_CLIENT_ID="${CLOUDDNS_CLIENT_ID:-$(_readaccountconf_mutable CLOUDDNS_CLIENT_ID)}" + CLOUDDNS_EMAIL="${CLOUDDNS_EMAIL:-$(_readaccountconf_mutable CLOUDDNS_EMAIL)}" + CLOUDDNS_PASSWORD="${CLOUDDNS_PASSWORD:-$(_readaccountconf_mutable CLOUDDNS_PASSWORD)}" + + if [ -z "$CLOUDDNS_PASSWORD" ] || [ -z "$CLOUDDNS_EMAIL" ] || [ -z "$CLOUDDNS_CLIENT_ID" ]; then + CLOUDDNS_CLIENT_ID="" + CLOUDDNS_EMAIL="" + CLOUDDNS_PASSWORD="" + _err "You didn't specify a CloudDNS password, email and client id yet." + return 1 + fi + if ! _contains "$CLOUDDNS_EMAIL" "@"; then + _err "It seems that the CLOUDDNS_EMAIL=$CLOUDDNS_EMAIL is not a valid email address." + _err "Please check and retry." + return 1 + fi + # Save CloudDNS client id, email and password to config file + _saveaccountconf_mutable CLOUDDNS_CLIENT_ID "$CLOUDDNS_CLIENT_ID" + _saveaccountconf_mutable CLOUDDNS_EMAIL "$CLOUDDNS_EMAIL" + _saveaccountconf_mutable CLOUDDNS_PASSWORD "$CLOUDDNS_PASSWORD" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so + # we can not use updating anymore. + _info "Adding record" + if _clouddns_api POST "record-txt" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"domainId\":\"$_domain_id\"}"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + elif _contains "$response" '"code":4136'; then + _info "Already exists, OK" + else + _err "Add txt record error." + return 1 + fi + fi + + # Publish challenge record + _debug "Publishing record changes" + _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}" +} + +#fulldomain txtvalue +dns_clouddns_rm() { + fulldomain=$1 + txtvalue=$2 + + CLOUDDNS_CLIENT_ID="${CLOUDDNS_CLIENT_ID:-$(_readaccountconf_mutable CLOUDDNS_CLIENT_ID)}" + CLOUDDNS_EMAIL="${CLOUDDNS_EMAIL:-$(_readaccountconf_mutable CLOUDDNS_EMAIL)}" + CLOUDDNS_PASSWORD="${CLOUDDNS_PASSWORD:-$(_readaccountconf_mutable CLOUDDNS_PASSWORD)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # Get record Id + response="$(_clouddns_api GET "domain/$_domain_id" | tr -d '\t\r\n ')" + _debug response "$response" + if _contains "$response" "lastDomainRecordList"; then + re="\"lastDomainRecordList\".*\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\"," + _last_domains=$(echo "$response" | _egrep_o "$re") + re2="\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\"," + _record_id=$(echo "$_last_domains" | _egrep_o "$re2" | _head_n 1 | cut -d : -f 2 | cut -d , -f 1 | tr -d "\"") + _debug _record_id "$_record_id" + else + _err "Could not retrieve record id" + return 1 + fi + + _info "Removing record" + if _clouddns_api DELETE "record/$_record_id"; then + if _contains "$response" "\"error\":"; then + _err "Could not remove record" + return 1 + fi + fi + + # Publish challenge record + _debug "Publishing record changes" + _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}" +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=sdjkglgdfewsdfg +_get_root() { + domain=$1 + domain_root=$(echo "$fulldomain" | _egrep_o '\.([^\.]*\.[^\.]*)$' | cut -c 2-) + _debug domain_root "$domain_root" + + # Get domain id + data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}, \ + {\"name\": \"domainName\", \"operator\": \"eq\", \"value\": \"$domain_root.\"}]}" + response="$(_clouddns_api "POST" "domain/search" "$data" | tr -d '\t\r\n ')" + _debug "Domain id $response" + + if _contains "$response" "\"id\":\""; then + re='domainType\":\"[^\"]*\",\"id\":\"([^\"]*)\",' # Match domain id + _domain_id=$(echo "$response" | _egrep_o "$re" | _head_n 1 | cut -d : -f 3 | tr -d "\",") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | sed "s/.$domain_root//") + _domain="$domain_root" + return 0 + fi + _err 'Domain name not found on your CloudDNS account' + return 1 + fi + return 1 +} + +_clouddns_api() { + method=$1 + endpoint="$2" + data="$3" + _debug endpoint "$endpoint" + + if [ -z "$CLOUDDNS_TOKEN" ]; then + _clouddns_login + fi + _debug CLOUDDNS_TOKEN "$CLOUDDNS_TOKEN" + + export _H1="Content-Type: application/json" + export _H2="Authorization: Bearer $CLOUDDNS_TOKEN" + + if [ "$method" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$CLOUDDNS_API/$endpoint" "" "$method")" + else + response="$(_get "$CLOUDDNS_API/$endpoint")" + fi + + if [ "$?" != "0" ]; then + _err "error $endpoint" + return 1 + fi + printf "%s" "$response" + return 0 +} + +_clouddns_login() { + login_data="{\"email\": \"$CLOUDDNS_EMAIL\", \"password\": \"$CLOUDDNS_PASSWORD\"}" + response="$(_post "$login_data" "$CLOUDDNS_LOGIN_API" "" "POST" "Content-Type: application/json")" + _debug2 response "$response" + + if _contains "$response" "\"accessToken\":\""; then + CLOUDDNS_TOKEN=$(echo "$response" | _egrep_o "\"accessToken\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") + export CLOUDDNS_TOKEN + else + echo 'Could not get CloudDNS access token; check your credentials' + return 1 + fi + return 0 +} From 69392f67e8c49bfaaa447bd7f1dd14a428cf357c Mon Sep 17 00:00:00 2001 From: Radek SPRTA Date: Wed, 22 Jan 2020 01:33:15 +0100 Subject: [PATCH 0589/2234] Correctly handle .co.uk type domains --- dnsapi/dns_clouddns.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_clouddns.sh b/dnsapi/dns_clouddns.sh index 2678c66b..174d740f 100755 --- a/dnsapi/dns_clouddns.sh +++ b/dnsapi/dns_clouddns.sh @@ -118,15 +118,24 @@ dns_clouddns_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 - domain_root=$(echo "$fulldomain" | _egrep_o '\.([^\.]*\.[^\.]*)$' | cut -c 2-) - _debug domain_root "$domain_root" + + # Get domain root + data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}]}" + response="$(_clouddns_api "POST" "domain/search" "$data" | tr -d '\t\r\n ')" + _debug2 "response" "$response" + domain_slice="$domain" + while [ -z "$domain_root" ]; do + if _contains "$response" "\"domainName\":\"$domain_slice\.\""; then + domain_root="$domain_slice" + _debug domain_root "$domain_root" + fi + domain_slice="$(echo "$domain_slice" | cut -d . -f 2-)" + done # Get domain id data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}, \ - {\"name\": \"domainName\", \"operator\": \"eq\", \"value\": \"$domain_root.\"}]}" + {\"name\": \"domainName\", \"operator\": \"eq\", \"value\": \"$domain_root.\"}]}" response="$(_clouddns_api "POST" "domain/search" "$data" | tr -d '\t\r\n ')" - _debug "Domain id $response" - if _contains "$response" "\"id\":\""; then re='domainType\":\"[^\"]*\",\"id\":\"([^\"]*)\",' # Match domain id _domain_id=$(echo "$response" | _egrep_o "$re" | _head_n 1 | cut -d : -f 3 | tr -d "\",") From 36e0feea430a008d63b818a4dc3cc8b46ddf459f Mon Sep 17 00:00:00 2001 From: Radek SPRTA Date: Wed, 22 Jan 2020 01:59:40 +0100 Subject: [PATCH 0590/2234] Clean up comments --- dnsapi/dns_clouddns.sh | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/dnsapi/dns_clouddns.sh b/dnsapi/dns_clouddns.sh index 174d740f..75d9ca6c 100755 --- a/dnsapi/dns_clouddns.sh +++ b/dnsapi/dns_clouddns.sh @@ -11,10 +11,11 @@ CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login' ######## Public functions ##################### -#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_clouddns_add() { fulldomain=$1 txtvalue=$2 + _debug "fulldomain" "$fulldomain" CLOUDDNS_CLIENT_ID="${CLOUDDNS_CLIENT_ID:-$(_readaccountconf_mutable CLOUDDNS_CLIENT_ID)}" CLOUDDNS_EMAIL="${CLOUDDNS_EMAIL:-$(_readaccountconf_mutable CLOUDDNS_EMAIL)}" @@ -24,7 +25,7 @@ dns_clouddns_add() { CLOUDDNS_CLIENT_ID="" CLOUDDNS_EMAIL="" CLOUDDNS_PASSWORD="" - _err "You didn't specify a CloudDNS password, email and client id yet." + _err "You didn't specify a CloudDNS password, email and client ID yet." return 1 fi if ! _contains "$CLOUDDNS_EMAIL" "@"; then @@ -46,8 +47,6 @@ dns_clouddns_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so - # we can not use updating anymore. _info "Adding record" if _clouddns_api POST "record-txt" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"domainId\":\"$_domain_id\"}"; then if _contains "$response" "$txtvalue"; then @@ -55,20 +54,19 @@ dns_clouddns_add() { elif _contains "$response" '"code":4136'; then _info "Already exists, OK" else - _err "Add txt record error." + _err "Add TXT record error." return 1 fi fi - # Publish challenge record _debug "Publishing record changes" _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}" } -#fulldomain txtvalue +# Usage: rm _acme-challenge.www.domain.com dns_clouddns_rm() { fulldomain=$1 - txtvalue=$2 + _debug "fulldomain" "$fulldomain" CLOUDDNS_CLIENT_ID="${CLOUDDNS_CLIENT_ID:-$(_readaccountconf_mutable CLOUDDNS_CLIENT_ID)}" CLOUDDNS_EMAIL="${CLOUDDNS_EMAIL:-$(_readaccountconf_mutable CLOUDDNS_EMAIL)}" @@ -76,16 +74,16 @@ dns_clouddns_rm() { _debug "First detect the root zone" if ! _get_root "$fulldomain"; then - _err "invalid domain" + _err "Invalid domain" return 1 fi _debug _domain_id "$_domain_id" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - # Get record Id + # Get record ID response="$(_clouddns_api GET "domain/$_domain_id" | tr -d '\t\r\n ')" - _debug response "$response" + _debug2 response "$response" if _contains "$response" "lastDomainRecordList"; then re="\"lastDomainRecordList\".*\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\"," _last_domains=$(echo "$response" | _egrep_o "$re") @@ -93,7 +91,7 @@ dns_clouddns_rm() { _record_id=$(echo "$_last_domains" | _egrep_o "$re2" | _head_n 1 | cut -d : -f 2 | cut -d , -f 1 | tr -d "\"") _debug _record_id "$_record_id" else - _err "Could not retrieve record id" + _err "Could not retrieve record ID" return 1 fi @@ -105,14 +103,14 @@ dns_clouddns_rm() { fi fi - # Publish challenge record _debug "Publishing record changes" _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}" } #################### Private functions below ################################## -#_acme-challenge.www.domain.com -#returns + +# Usage: _get_root _acme-challenge.www.domain.com +# Returns: # _sub_domain=_acme-challenge.www # _domain=domain.com # _domain_id=sdjkglgdfewsdfg @@ -122,7 +120,7 @@ _get_root() { # Get domain root data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}]}" response="$(_clouddns_api "POST" "domain/search" "$data" | tr -d '\t\r\n ')" - _debug2 "response" "$response" + _debug2 response "$response" domain_slice="$domain" while [ -z "$domain_root" ]; do if _contains "$response" "\"domainName\":\"$domain_slice\.\""; then @@ -134,7 +132,7 @@ _get_root() { # Get domain id data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}, \ - {\"name\": \"domainName\", \"operator\": \"eq\", \"value\": \"$domain_root.\"}]}" + {\"name\": \"domainName\", \"operator\": \"eq\", \"value\": \"$domain_root.\"}]}" response="$(_clouddns_api "POST" "domain/search" "$data" | tr -d '\t\r\n ')" if _contains "$response" "\"id\":\""; then re='domainType\":\"[^\"]*\",\"id\":\"([^\"]*)\",' # Match domain id @@ -150,6 +148,9 @@ _get_root() { return 1 } +# Usage: _clouddns_api GET domain/search '{"data": "value"}' +# Returns: +# response='{"message": "api response"}' _clouddns_api() { method=$1 endpoint="$2" @@ -172,13 +173,15 @@ _clouddns_api() { fi if [ "$?" != "0" ]; then - _err "error $endpoint" + _err "Error $endpoint" return 1 fi printf "%s" "$response" return 0 } +# Returns: +# CLOUDDNS_TOKEN=dslfje2rj23l _clouddns_login() { login_data="{\"email\": \"$CLOUDDNS_EMAIL\", \"password\": \"$CLOUDDNS_PASSWORD\"}" response="$(_post "$login_data" "$CLOUDDNS_LOGIN_API" "" "POST" "Content-Type: application/json")" From 6b675117481153bd8067737969f089bd24ada53e Mon Sep 17 00:00:00 2001 From: Radek SPRTA Date: Wed, 22 Jan 2020 02:03:11 +0100 Subject: [PATCH 0591/2234] Disable check --- dnsapi/dns_clouddns.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_clouddns.sh b/dnsapi/dns_clouddns.sh index 75d9ca6c..1e9987db 100755 --- a/dnsapi/dns_clouddns.sh +++ b/dnsapi/dns_clouddns.sh @@ -172,6 +172,7 @@ _clouddns_api() { response="$(_get "$CLOUDDNS_API/$endpoint")" fi + # shellcheck disable=SC2181 if [ "$?" != "0" ]; then _err "Error $endpoint" return 1 From 23f26770523807630df8d87cd38016a8359c57a9 Mon Sep 17 00:00:00 2001 From: Radek SPRTA Date: Wed, 22 Jan 2020 02:53:50 +0100 Subject: [PATCH 0592/2234] Do not print HTTP responses to stdout --- dnsapi/dns_clouddns.sh | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_clouddns.sh b/dnsapi/dns_clouddns.sh index 1e9987db..cfbb1cbb 100755 --- a/dnsapi/dns_clouddns.sh +++ b/dnsapi/dns_clouddns.sh @@ -47,8 +47,9 @@ dns_clouddns_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _info "Adding record" - if _clouddns_api POST "record-txt" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"domainId\":\"$_domain_id\"}"; then + # Add TXT record + data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"domainId\":\"$_domain_id\"}" + if _clouddns_api POST "record-txt" "$data"; then if _contains "$response" "$txtvalue"; then _info "Added, OK" elif _contains "$response" '"code":4136'; then @@ -82,8 +83,7 @@ dns_clouddns_rm() { _debug _domain "$_domain" # Get record ID - response="$(_clouddns_api GET "domain/$_domain_id" | tr -d '\t\r\n ')" - _debug2 response "$response" + _clouddns_api GET "domain/$_domain_id" if _contains "$response" "lastDomainRecordList"; then re="\"lastDomainRecordList\".*\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\"," _last_domains=$(echo "$response" | _egrep_o "$re") @@ -119,8 +119,7 @@ _get_root() { # Get domain root data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}]}" - response="$(_clouddns_api "POST" "domain/search" "$data" | tr -d '\t\r\n ')" - _debug2 response "$response" + _clouddns_api "POST" "domain/search" "$data" domain_slice="$domain" while [ -z "$domain_root" ]; do if _contains "$response" "\"domainName\":\"$domain_slice\.\""; then @@ -133,7 +132,7 @@ _get_root() { # Get domain id data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}, \ {\"name\": \"domainName\", \"operator\": \"eq\", \"value\": \"$domain_root.\"}]}" - response="$(_clouddns_api "POST" "domain/search" "$data" | tr -d '\t\r\n ')" + _clouddns_api "POST" "domain/search" "$data" if _contains "$response" "\"id\":\""; then re='domainType\":\"[^\"]*\",\"id\":\"([^\"]*)\",' # Match domain id _domain_id=$(echo "$response" | _egrep_o "$re" | _head_n 1 | cut -d : -f 3 | tr -d "\",") @@ -167,9 +166,9 @@ _clouddns_api() { if [ "$method" != "GET" ]; then _debug data "$data" - response="$(_post "$data" "$CLOUDDNS_API/$endpoint" "" "$method")" + response="$(_post "$data" "$CLOUDDNS_API/$endpoint" "" "$method" | tr -d '\t\r\n ')" else - response="$(_get "$CLOUDDNS_API/$endpoint")" + response="$(_get "$CLOUDDNS_API/$endpoint" | tr -d '\t\r\n ')" fi # shellcheck disable=SC2181 @@ -177,7 +176,7 @@ _clouddns_api() { _err "Error $endpoint" return 1 fi - printf "%s" "$response" + _debug2 response "$response" return 0 } @@ -186,7 +185,6 @@ _clouddns_api() { _clouddns_login() { login_data="{\"email\": \"$CLOUDDNS_EMAIL\", \"password\": \"$CLOUDDNS_PASSWORD\"}" response="$(_post "$login_data" "$CLOUDDNS_LOGIN_API" "" "POST" "Content-Type: application/json")" - _debug2 response "$response" if _contains "$response" "\"accessToken\":\""; then CLOUDDNS_TOKEN=$(echo "$response" | _egrep_o "\"accessToken\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") From 5c7feba77bd4a0b6f8ba1edaca2c1118a26cfa17 Mon Sep 17 00:00:00 2001 From: Radek SPRTA Date: Wed, 22 Jan 2020 05:33:46 +0100 Subject: [PATCH 0593/2234] Format with shfmt --- dnsapi/dns_clouddns.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_clouddns.sh b/dnsapi/dns_clouddns.sh index cfbb1cbb..31ae4ee9 100755 --- a/dnsapi/dns_clouddns.sh +++ b/dnsapi/dns_clouddns.sh @@ -85,7 +85,7 @@ dns_clouddns_rm() { # Get record ID _clouddns_api GET "domain/$_domain_id" if _contains "$response" "lastDomainRecordList"; then - re="\"lastDomainRecordList\".*\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\"," + re="\"lastDomainRecordList\".*\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\"," _last_domains=$(echo "$response" | _egrep_o "$re") re2="\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\"," _record_id=$(echo "$_last_domains" | _egrep_o "$re2" | _head_n 1 | cut -d : -f 2 | cut -d , -f 1 | tr -d "\"") @@ -94,7 +94,7 @@ dns_clouddns_rm() { _err "Could not retrieve record ID" return 1 fi - + _info "Removing record" if _clouddns_api DELETE "record/$_record_id"; then if _contains "$response" "\"error\":"; then @@ -119,7 +119,7 @@ _get_root() { # Get domain root data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}]}" - _clouddns_api "POST" "domain/search" "$data" + _clouddns_api "POST" "domain/search" "$data" domain_slice="$domain" while [ -z "$domain_root" ]; do if _contains "$response" "\"domainName\":\"$domain_slice\.\""; then From 3c98fae4f286f0ed1f68ae86ec8781b471be23d6 Mon Sep 17 00:00:00 2001 From: xpac1985 Date: Wed, 22 Jan 2020 20:00:04 +0100 Subject: [PATCH 0594/2234] Updated/fixed some entries in --help output --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index b5f80b35..9b33fc74 100755 --- a/acme.sh +++ b/acme.sh @@ -6202,7 +6202,7 @@ Parameters: --force, -f Used to force to install or force to renew a cert immediately. --staging, --test Use staging server, just for test. --debug Output debug info. - --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for secure. + --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for security. --webroot, -w /path/to/webroot Specifies the web root folder for web root mode. --standalone Use standalone mode. --alpn Use standalone alpn mode. @@ -6211,7 +6211,7 @@ Parameters: --dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api. --dnssleep [$DEFAULT_DNS_SLEEP] The time in seconds to wait for all the txt records to take effect in dns api mode. Default $DEFAULT_DNS_SLEEP seconds. - --keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384. + --keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. --accountkeylength, -ak [2048] Specifies the account key length. --log [/path/to/logfile] Specifies the log file. The default is: \"$DEFAULT_LOG_FILE\" if you don't give a file path here. --log-level 1|2 Specifies the log level, default is 1. @@ -6226,7 +6226,7 @@ Parameters: --reloadcmd \"service nginx reload\" After issue/renew, it's used to reload the server. - --server SERVER ACME Directory Resource URI. (default: https://acme-v01.api.letsencrypt.org/directory) + --server SERVER ACME Directory Resource URI. (default: $DEFAULT_CA) --accountconf Specifies a customized account config file. --home Specifies the home dir for $PROJECT_NAME. --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. From b6552aff7502c5ef183fdee8a91cd7cb143eea2e Mon Sep 17 00:00:00 2001 From: xpac1985 Date: Wed, 22 Jan 2020 21:21:38 +0100 Subject: [PATCH 0595/2234] Added maximum account key length to --help output --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 9b33fc74..dae42714 100755 --- a/acme.sh +++ b/acme.sh @@ -6212,7 +6212,7 @@ Parameters: --dnssleep [$DEFAULT_DNS_SLEEP] The time in seconds to wait for all the txt records to take effect in dns api mode. Default $DEFAULT_DNS_SLEEP seconds. --keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. - --accountkeylength, -ak [2048] Specifies the account key length. + --accountkeylength, -ak [2048] Specifies the account key length: 2048, 3072, 4096 --log [/path/to/logfile] Specifies the log file. The default is: \"$DEFAULT_LOG_FILE\" if you don't give a file path here. --log-level 1|2 Specifies the log level, default is 1. --syslog [0|3|6|7] Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. From 6613ae57b0a08dbae9e1f089d948c832a6b00074 Mon Sep 17 00:00:00 2001 From: Marco4223 Date: Thu, 23 Jan 2020 19:20:44 +0100 Subject: [PATCH 0596/2234] Update dns_kas.sh sleep 10 to _sleep 10 --- dnsapi/dns_kas.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 95401684..2cb0b439 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -44,7 +44,7 @@ dns_kas_add() { params="$params&var5=zone_host" params="$params&wert5=$_zone" _debug2 "Wait for 10 seconds by default before calling KAS API." - sleep 10 + _sleep 10 response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" @@ -80,7 +80,7 @@ dns_kas_rm() { params2="$params&var1=record_id" params2="$params2&wert1=$i" _debug2 "Wait for 10 seconds by default before calling KAS API." - sleep 10 + _sleep 10 response="$(_get "$KAS_Api$params2")" _debug2 "response" "$response" if ! _contains "$response" "TRUE"; then @@ -126,7 +126,7 @@ _get_zone_and_record_name() { params="$params&kas_action=get_domains" _debug2 "Wait for 10 seconds by default before calling KAS API." - sleep 10 + _sleep 10 response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" _zonen="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | sed "s/domain_name>=>//g")" @@ -159,7 +159,7 @@ _get_record_id() { params="$params&wert1=$_zone" _debug2 "Wait for 10 seconds by default before calling KAS API." - sleep 10 + _sleep 10 response="$(_get "$KAS_Api$params")" _debug2 "response" "$response" _record_id="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | sed "s/record_id>=>//g")" From 05aa26e6197241231bf968d23c03e1af4d6ad3b4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 27 Jan 2020 21:22:42 +0800 Subject: [PATCH 0597/2234] minor, remove space key --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index b5f80b35..786d929a 100755 --- a/acme.sh +++ b/acme.sh @@ -4006,7 +4006,7 @@ issue() { _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-)" + 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)" _debug Le_OrderFinalize "$Le_OrderFinalize" From 4f303de00c8d640351db5fb065bf0861786fab18 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 27 Jan 2020 22:12:21 +0800 Subject: [PATCH 0598/2234] fix bug https://github.com/Neilpang/acme.sh/issues/2695 If a domain was already verified by http-01 method, when we try to issue a cert for them same domain with dns-01 method, we just get only one challenge object of type http-01 with "valid" status, from the authz-v3 url. So, we report error that we are not able the validate the domain, because of that we don't find dns-01 challenge. This behavior is not the same as before. I believe it was changed by the letsencrypt CA. --- acme.sh | 80 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/acme.sh b/acme.sh index 786d929a..0de32794 100755 --- a/acme.sh +++ b/acme.sh @@ -4119,45 +4119,59 @@ $_authorizations_map" entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" + keyauthorization="" if [ -z "$entry" ]; then - _err "Error, can not get domain token entry $d" - _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" - if [ "$_supported_vtypes" ]; then - _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" + _err "Error, can not get domain token entry $d for $vtype" + if ! _startswith "$d" '*.'; then + _debug "Not a wildcard domain, lets check whether the validation is already valid." + if echo "$response" | grep '"status":"valid"' >/dev/null 2>&1; then + _debug "$d is already valid." + keyauthorization="$STATE_VERIFIED" + _debug keyauthorization "$keyauthorization" + fi + fi + if [ -z "$keyauthorization" ]; then + _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" + if [ "$_supported_vtypes" ]; then + _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" + fi + _clearup + _on_issue_err "$_post_hook" + return 1 fi - _clearup - _on_issue_err "$_post_hook" - return 1 fi - token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" - _debug token "$token" + + if [ -z "$keyauthorization" ]; then + token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" + _debug token "$token" - if [ -z "$token" ]; then - _err "Error, can not get domain token $entry" - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - if [ "$ACME_VERSION" = "2" ]; then - uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" - else - uri="$(echo "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)" - fi - _debug uri "$uri" + if [ -z "$token" ]; then + _err "Error, can not get domain token $entry" + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + if [ "$ACME_VERSION" = "2" ]; then + uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" + else + uri="$(echo "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)" + fi + _debug uri "$uri" - if [ -z "$uri" ]; then - _err "Error, can not get domain uri. $entry" - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - keyauthorization="$token.$thumbprint" - _debug keyauthorization "$keyauthorization" - - if printf "%s" "$response" | grep '"status":"valid"' >/dev/null 2>&1; then - _debug "$d is already verified." - keyauthorization="$STATE_VERIFIED" + if [ -z "$uri" ]; then + _err "Error, can not get domain uri. $entry" + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + keyauthorization="$token.$thumbprint" _debug keyauthorization "$keyauthorization" + + if printf "%s" "$response" | grep '"status":"valid"' >/dev/null 2>&1; then + _debug "$d is already verified." + keyauthorization="$STATE_VERIFIED" + _debug keyauthorization "$keyauthorization" + fi fi dvlist="$d$sep$keyauthorization$sep$uri$sep$vtype$sep$_currentRoot" From dc0cca8c8371e0040fea4db3c0f19bd2740776b7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 27 Jan 2020 22:22:25 +0800 Subject: [PATCH 0599/2234] move the error message --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 0de32794..c8b5bf95 100755 --- a/acme.sh +++ b/acme.sh @@ -4121,7 +4121,6 @@ $_authorizations_map" _debug entry "$entry" keyauthorization="" if [ -z "$entry" ]; then - _err "Error, can not get domain token entry $d for $vtype" if ! _startswith "$d" '*.'; then _debug "Not a wildcard domain, lets check whether the validation is already valid." if echo "$response" | grep '"status":"valid"' >/dev/null 2>&1; then @@ -4131,6 +4130,7 @@ $_authorizations_map" fi fi if [ -z "$keyauthorization" ]; then + _err "Error, can not get domain token entry $d for $vtype" _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" if [ "$_supported_vtypes" ]; then _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" From f716f6060e7ee99704055dc57f603da3668e7da6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 27 Jan 2020 23:02:09 +0800 Subject: [PATCH 0600/2234] minor check update hash for branch name --- acme.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 786d929a..b4974fe3 100755 --- a/acme.sh +++ b/acme.sh @@ -6315,7 +6315,11 @@ _installOnline() { } _getMasterHash() { - _hash_url="https://api.github.com/repos/Neilpang/acme.sh/git/refs/heads/master" + _b="$BRANCH" + if [ -z "$_b" ]; then + _b="master" + fi + _hash_url="https://api.github.com/repos/Neilpang/acme.sh/git/refs/heads/$_b" _get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4 } From 9541ea6a9fee42567a194fbec82b6c80bd2a04bb Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 27 Jan 2020 22:12:21 +0800 Subject: [PATCH 0601/2234] fix bug https://github.com/Neilpang/acme.sh/issues/2695 If a domain was already verified by http-01 method, when we try to issue a cert for them same domain with dns-01 method, we just get only one challenge object of type http-01 with "valid" status, from the authz-v3 url. So, we report error that we are not able the validate the domain, because of that we don't find dns-01 challenge. This behavior is not the same as before. I believe it was changed by the letsencrypt CA. --- acme.sh | 80 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/acme.sh b/acme.sh index b4974fe3..3c21c75b 100755 --- a/acme.sh +++ b/acme.sh @@ -4119,45 +4119,59 @@ $_authorizations_map" entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" + keyauthorization="" if [ -z "$entry" ]; then - _err "Error, can not get domain token entry $d" - _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" - if [ "$_supported_vtypes" ]; then - _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" + _err "Error, can not get domain token entry $d for $vtype" + if ! _startswith "$d" '*.'; then + _debug "Not a wildcard domain, lets check whether the validation is already valid." + if echo "$response" | grep '"status":"valid"' >/dev/null 2>&1; then + _debug "$d is already valid." + keyauthorization="$STATE_VERIFIED" + _debug keyauthorization "$keyauthorization" + fi + fi + if [ -z "$keyauthorization" ]; then + _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" + if [ "$_supported_vtypes" ]; then + _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" + fi + _clearup + _on_issue_err "$_post_hook" + return 1 fi - _clearup - _on_issue_err "$_post_hook" - return 1 fi - token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" - _debug token "$token" + + if [ -z "$keyauthorization" ]; then + token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" + _debug token "$token" - if [ -z "$token" ]; then - _err "Error, can not get domain token $entry" - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - if [ "$ACME_VERSION" = "2" ]; then - uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" - else - uri="$(echo "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)" - fi - _debug uri "$uri" + if [ -z "$token" ]; then + _err "Error, can not get domain token $entry" + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + if [ "$ACME_VERSION" = "2" ]; then + uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" + else + uri="$(echo "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)" + fi + _debug uri "$uri" - if [ -z "$uri" ]; then - _err "Error, can not get domain uri. $entry" - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - keyauthorization="$token.$thumbprint" - _debug keyauthorization "$keyauthorization" - - if printf "%s" "$response" | grep '"status":"valid"' >/dev/null 2>&1; then - _debug "$d is already verified." - keyauthorization="$STATE_VERIFIED" + if [ -z "$uri" ]; then + _err "Error, can not get domain uri. $entry" + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + keyauthorization="$token.$thumbprint" _debug keyauthorization "$keyauthorization" + + if printf "%s" "$response" | grep '"status":"valid"' >/dev/null 2>&1; then + _debug "$d is already verified." + keyauthorization="$STATE_VERIFIED" + _debug keyauthorization "$keyauthorization" + fi fi dvlist="$d$sep$keyauthorization$sep$uri$sep$vtype$sep$_currentRoot" From fc3a181779e8c4dbc3dd65a727df656619a100df Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 27 Jan 2020 22:22:25 +0800 Subject: [PATCH 0602/2234] move the error message --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3c21c75b..5ae2e312 100755 --- a/acme.sh +++ b/acme.sh @@ -4121,7 +4121,6 @@ $_authorizations_map" _debug entry "$entry" keyauthorization="" if [ -z "$entry" ]; then - _err "Error, can not get domain token entry $d for $vtype" if ! _startswith "$d" '*.'; then _debug "Not a wildcard domain, lets check whether the validation is already valid." if echo "$response" | grep '"status":"valid"' >/dev/null 2>&1; then @@ -4131,6 +4130,7 @@ $_authorizations_map" fi fi if [ -z "$keyauthorization" ]; then + _err "Error, can not get domain token entry $d for $vtype" _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" if [ "$_supported_vtypes" ]; then _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" From f8b225e70e2286622e01134d4e5ba5e69d1ab00e Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 27 Jan 2020 23:30:36 +0800 Subject: [PATCH 0603/2234] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 5ae2e312..200c95c0 100755 --- a/acme.sh +++ b/acme.sh @@ -4140,7 +4140,7 @@ $_authorizations_map" return 1 fi fi - + if [ -z "$keyauthorization" ]; then token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" _debug token "$token" From 09f74a9af8f1de082f605e1f4338fb5ca7cb148e Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 30 Jan 2020 10:50:39 +0800 Subject: [PATCH 0604/2234] start v2.8.6, change the repo name --- acme.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/acme.sh b/acme.sh index 200c95c0..b05c341b 100755 --- a/acme.sh +++ b/acme.sh @@ -1,12 +1,12 @@ #!/usr/bin/env sh -VER=2.8.5 +VER=2.8.6 PROJECT_NAME="acme.sh" PROJECT_ENTRY="acme.sh" -PROJECT="https://github.com/Neilpang/$PROJECT_NAME" +PROJECT="https://github.com/acmesh-official/$PROJECT_NAME" DEFAULT_INSTALL_HOME="$HOME/.$PROJECT_NAME" @@ -126,19 +126,19 @@ NOTIFY_MODE_CERT=1 NOTIFY_MODE_DEFAULT=$NOTIFY_MODE_BULK -_DEBUG_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh" +_DEBUG_WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh" -_PREPARE_LINK="https://github.com/Neilpang/acme.sh/wiki/Install-preparations" +_PREPARE_LINK="https://github.com/acmesh-official/acme.sh/wiki/Install-preparations" -_STATELESS_WIKI="https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode" +_STATELESS_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Stateless-Mode" -_DNS_ALIAS_WIKI="https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode" +_DNS_ALIAS_WIKI="https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode" -_DNS_MANUAL_WIKI="https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode" +_DNS_MANUAL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode" -_NOTIFY_WIKI="https://github.com/Neilpang/acme.sh/wiki/notify" +_NOTIFY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/notify" -_SUDO_WIKI="https://github.com/Neilpang/acme.sh/wiki/sudo" +_SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo" _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." @@ -6333,7 +6333,7 @@ _getMasterHash() { if [ -z "$_b" ]; then _b="master" fi - _hash_url="https://api.github.com/repos/Neilpang/acme.sh/git/refs/heads/$_b" + _hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/heads/$_b" _get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4 } From d795fac37a3ea23b3e3fa1babf685f1e2c079ad3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 30 Jan 2020 12:06:39 +0800 Subject: [PATCH 0605/2234] update repo name --- .github/ISSUE_TEMPLATE.md | 4 +- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .travis.yml | 2 +- README.md | 86 ++++++++++++++++---------------- deploy/README.md | 2 +- deploy/docker.sh | 2 +- dnsapi/README.md | 2 +- dnsapi/dns_aws.sh | 2 +- dnsapi/dns_azure.sh | 2 +- dnsapi/dns_cyon.sh | 2 +- dnsapi/dns_easydns.sh | 2 +- dnsapi/dns_freedns.sh | 2 +- dnsapi/dns_lexicon.sh | 2 +- dnsapi/dns_miab.sh | 2 +- dnsapi/dns_myapi.sh | 4 +- dnsapi/dns_openprovider.sh | 2 +- dnsapi/dns_ovh.sh | 4 +- dnsapi/dns_pleskxml.sh | 2 +- dnsapi/dns_rackspace.sh | 2 +- dnsapi/dns_servercow.sh | 2 +- 20 files changed, 65 insertions(+), 65 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 53112c6f..c9c1b555 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -2,7 +2,7 @@ 我很忙, 每天可能只有 几秒钟 时间看你的 issue, 如果不按照我的要求写 issue, 你可能不会得到任何回复, 石沉大海. 请确保已经更新到最新的代码, 然后贴上来 `--debug 2` 的调试输出. 没有调试信息. 我做不了什么. -如何调试 https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh +如何调试 https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh If it is a bug report: - make sure you are able to repro it on the latest released version. @@ -10,7 +10,7 @@ You can install the latest version by: `acme.sh --upgrade` - Search the existing issues. - Refer to the [WIKI](https://wiki.acme.sh). -- Debug info [Debug](https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh). +- Debug info [Debug](https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh). --> diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3bd170b7..4f7ceb47 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,7 +3,7 @@ Please send to `dev` branch instead. Any PR to `master` branch will NOT be merged. -2. For dns api support, read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide +2. For dns api support, read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide You will NOT get any review without passing this guide. You also need to fix the CI errors. --> \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 1264803e..155ec64b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ script: - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" ; fi - cd .. - - git clone --depth 1 https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest + - git clone --depth 1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./rundocker.sh testplat ubuntu:latest ; fi - if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ACME_OPENSSL_BIN="$ACME_OPENSSL_BIN" ./letest.sh ; fi diff --git a/README.md b/README.md index d5012d68..d71c3c57 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,14 @@ It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt. -Wiki: https://github.com/Neilpang/acme.sh/wiki +Wiki: https://github.com/acmesh-official/acme.sh/wiki -For Docker Fans: [acme.sh :two_hearts: Docker ](https://github.com/Neilpang/acme.sh/wiki/Run-acme.sh-in-docker) +For Docker Fans: [acme.sh :two_hearts: Docker ](https://github.com/acmesh-official/acme.sh/wiki/Run-acme.sh-in-docker) Twitter: [@neilpangxa](https://twitter.com/neilpangxa) -# [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E) +# [中文说明](https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E) # Who: - [FreeBSD.org](https://blog.crashed.org/letsencrypt-in-freebsd-org/) @@ -40,41 +40,41 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) - [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient) - [CentOS Web Panel](http://centos-webpanel.com/) - [lnmp.org](https://lnmp.org/) -- [more...](https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials) +- [more...](https://github.com/acmesh-official/acme.sh/wiki/Blogs-and-tutorials) # Tested OS | NO | Status| Platform| |----|-------|---------| -|1|[![](https://neilpang.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu -|2|[![](https://neilpang.github.io/acmetest/status/debian-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Debian -|3|[![](https://neilpang.github.io/acmetest/status/centos-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|CentOS -|4|[![](https://neilpang.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) -|5|[![](https://neilpang.github.io/acmetest/status/freebsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|FreeBSD -|6|[![](https://neilpang.github.io/acmetest/status/pfsense.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|pfsense -|7|[![](https://neilpang.github.io/acmetest/status/opensuse-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|openSUSE -|8|[![](https://neilpang.github.io/acmetest/status/alpine-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Alpine Linux (with curl) -|9|[![](https://neilpang.github.io/acmetest/status/base-archlinux.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Archlinux -|10|[![](https://neilpang.github.io/acmetest/status/fedora-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|fedora -|11|[![](https://neilpang.github.io/acmetest/status/kalilinux-kali-linux-docker.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Kali Linux -|12|[![](https://neilpang.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Oracle Linux -|13|[![](https://neilpang.github.io/acmetest/status/proxmox.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh -|14|-----| Cloud Linux https://github.com/Neilpang/le/issues/111 -|15|[![](https://neilpang.github.io/acmetest/status/openbsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|OpenBSD -|16|[![](https://neilpang.github.io/acmetest/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia -|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT) -|18|[![](https://neilpang.github.io/acmetest/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris -|19|[![](https://neilpang.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux +|1|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Ubuntu +|2|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Debian +|3|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|CentOS +|4|[![](https://acmesh-official.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) +|5|[![](https://acmesh-official.github.io/acmetest/status/freebsd.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|FreeBSD +|6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|pfsense +|7|[![](https://acmesh-official.github.io/acmetest/status/opensuse-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|openSUSE +|8|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Alpine Linux (with curl) +|9|[![](https://acmesh-official.github.io/acmetest/status/base-archlinux.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Archlinux +|10|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|fedora +|11|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali-linux-docker.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Kali Linux +|12|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Oracle Linux +|13|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh +|14|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 +|15|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|OpenBSD +|16|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Mageia +|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) +|18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|SunOS/Solaris +|19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Gentoo Linux |20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX -For all build statuses, check our [weekly build project](https://github.com/Neilpang/acmetest): +For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): -https://github.com/Neilpang/acmetest +https://github.com/acmesh-official/acmetest # Supported CA - Letsencrypt.org CA(default) -- [BuyPass.com CA](https://github.com/Neilpang/acme.sh/wiki/BuyPass.com-CA) +- [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) # Supported modes @@ -85,15 +85,15 @@ https://github.com/Neilpang/acmetest - Apache mode - Nginx mode - DNS mode -- [DNS alias mode](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode) -- [Stateless mode](https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode) +- [DNS alias mode](https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode) +- [Stateless mode](https://github.com/acmesh-official/acme.sh/wiki/Stateless-Mode) # 1. How to install ### 1. Install online -Check this project: https://github.com/Neilpang/get.acme.sh +Check this project: https://github.com/acmesh-official/get.acme.sh ```bash curl https://get.acme.sh | sh @@ -111,14 +111,14 @@ wget -O - https://get.acme.sh | sh Clone this project and launch installation: ```bash -git clone https://github.com/Neilpang/acme.sh.git +git clone https://github.com/acmesh-official/acme.sh.git cd ./acme.sh ./acme.sh --install ``` You `don't have to be root` then, although `it is recommended`. -Advanced Installation: https://github.com/Neilpang/acme.sh/wiki/How-to-install +Advanced Installation: https://github.com/acmesh-official/acme.sh/wiki/How-to-install The installer will perform 3 actions: @@ -180,7 +180,7 @@ The certs will be placed in `~/.acme.sh/example.com/` The certs will be renewed automatically every **60** days. -More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert +More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert # 3. Install the cert to Apache/Nginx etc. @@ -226,7 +226,7 @@ Port `80` (TCP) **MUST** be free to listen on, otherwise you will be prompted to acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com ``` -More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert +More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert # 5. Use Standalone ssl server to issue cert @@ -238,7 +238,7 @@ Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted t acme.sh --issue --alpn -d example.com -d www.example.com -d cp.example.com ``` -More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert +More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert # 6. Use Apache mode @@ -259,7 +259,7 @@ acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com You will need to configure your website config files to use the cert by yourself. We don't want to mess your apache server, don't worry.** -More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert +More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert # 7. Use Nginx mode @@ -283,7 +283,7 @@ acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com You will need to configure your website config files to use the cert by yourself. We don't want to mess your nginx server, don't worry.** -More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert +More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert # 8. Automatic DNS API integration @@ -293,11 +293,11 @@ You don't have to do anything manually! ### Currently acme.sh supports most of the dns providers: -https://github.com/Neilpang/acme.sh/wiki/dnsapi +https://github.com/acmesh-official/acme.sh/wiki/dnsapi # 9. Use DNS manual mode: -See: https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode first. +See: https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode first. If your dns provider doesn't support any api access, you can add the txt record by your hand. @@ -430,12 +430,12 @@ acme.sh --upgrade --auto-upgrade 0 # 15. Issue a cert from an existing CSR -https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR +https://github.com/acmesh-official/acme.sh/wiki/Issue-a-cert-from-existing-CSR # 16. Send notifications in cronjob -https://github.com/Neilpang/acme.sh/wiki/notify +https://github.com/acmesh-official/acme.sh/wiki/notify # 17. Under the Hood @@ -456,7 +456,7 @@ TODO: ### Code Contributors This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. - + ### Financial Contributors @@ -487,7 +487,7 @@ License is GPLv3 Please Star and Fork me. -[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome. +[Issues](https://github.com/acmesh-official/acme.sh/issues) and [pull requests](https://github.com/acmesh-official/acme.sh/pulls) are welcome. # 20. Donate @@ -495,4 +495,4 @@ Your donation makes **acme.sh** better: 1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/) -[Donate List](https://github.com/Neilpang/acme.sh/wiki/Donate-list) +[Donate List](https://github.com/acmesh-official/acme.sh/wiki/Donate-list) diff --git a/deploy/README.md b/deploy/README.md index fc633ad7..e3f239fa 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -2,5 +2,5 @@ deploy hook usage: -https://github.com/Neilpang/acme.sh/wiki/deployhooks +https://github.com/acmesh-official/acme.sh/wiki/deployhooks diff --git a/deploy/docker.sh b/deploy/docker.sh index 05333b3f..06d79855 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -8,7 +8,7 @@ #DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/path/to/fullchain.pem" #DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload" -_DEPLOY_DOCKER_WIKI="https://github.com/Neilpang/acme.sh/wiki/deploy-to-docker-containers" +_DEPLOY_DOCKER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/deploy-to-docker-containers" _DOCKER_HOST_DEFAULT="/var/run/docker.sock" diff --git a/dnsapi/README.md b/dnsapi/README.md index 4fa59cf2..e81f7916 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -2,5 +2,5 @@ DNS api usage: -https://github.com/Neilpang/acme.sh/wiki/dnsapi +https://github.com/acmesh-official/acme.sh/wiki/dnsapi diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 6db87666..0503d0f2 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -12,7 +12,7 @@ AWS_HOST="route53.amazonaws.com" AWS_URL="https://$AWS_HOST" -AWS_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API" +AWS_WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Amazon-Route53-API" ######## Public functions ##################### diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 8b52dee7..bf7cf2bf 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-use-Azure-DNS" +WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Azure-DNS" ######## Public functions ##################### diff --git a/dnsapi/dns_cyon.sh b/dnsapi/dns_cyon.sh index d7ad712c..8db3011d 100644 --- a/dnsapi/dns_cyon.sh +++ b/dnsapi/dns_cyon.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh ######## -# Custom cyon.ch DNS API for use with [acme.sh](https://github.com/Neilpang/acme.sh) +# Custom cyon.ch DNS API for use with [acme.sh](https://github.com/acmesh-official/acme.sh) # # Usage: acme.sh --issue --dns dns_cyon -d www.domain.com # diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh index 1d905841..ca8faab2 100644 --- a/dnsapi/dns_easydns.sh +++ b/dnsapi/dns_easydns.sh @@ -8,7 +8,7 @@ # http://sandbox.rest.easydns.net:3000/ # # Author: wurzelpanzer [wurzelpanzer@maximolider.net] -# Report Bugs here: https://github.com/Neilpang/acme.sh/issues/2647 +# Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2647 # #################### Public functions ################# diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 6a0b58ac..4a58931f 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -7,7 +7,7 @@ # #Author: David Kerr #Report Bugs here: https://github.com/dkerr64/acme.sh -#or here... https://github.com/Neilpang/acme.sh/issues/2305 +#or here... https://github.com/acmesh-official/acme.sh/issues/2305 # ######## Public functions ##################### diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index bb9f7efc..516b6eff 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -5,7 +5,7 @@ # https://github.com/AnalogJ/lexicon lexicon_cmd="lexicon" -wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api" +wiki="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-lexicon-dns-api" _lexicon_init() { if ! _exists "$lexicon_cmd"; then diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 23ff6cee..7e697704 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -10,7 +10,7 @@ # used to communicate with the MailinaBox Custom DNS API # Report Bugs here: # https://github.com/billgertz/MIAB_dns_api (for dns_miab.sh) -# https://github.com/Neilpang/acme.sh (for acme.sh) +# https://github.com/acmesh-official/acme.sh (for acme.sh) # ######## Public functions ##################### diff --git a/dnsapi/dns_myapi.sh b/dnsapi/dns_myapi.sh index 2451d193..7f3c5a86 100755 --- a/dnsapi/dns_myapi.sh +++ b/dnsapi/dns_myapi.sh @@ -7,11 +7,11 @@ #returns 0 means success, otherwise error. # #Author: Neilpang -#Report Bugs here: https://github.com/Neilpang/acme.sh +#Report Bugs here: https://github.com/acmesh-official/acme.sh # ######## Public functions ##################### -# Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide +# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_myapi_add() { diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh index 1b1b760e..ad1e5838 100755 --- a/dnsapi/dns_openprovider.sh +++ b/dnsapi/dns_openprovider.sh @@ -3,7 +3,7 @@ # This is the OpenProvider API wrapper for acme.sh # # Author: Sylvia van Os -# Report Bugs here: https://github.com/Neilpang/acme.sh/issues/2104 +# Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2104 # # export OPENPROVIDER_USER="username" # export OPENPROVIDER_PASSWORDHASH="hashed_password" diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 65567efd..7c18d009 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -32,9 +32,9 @@ SYS_CA='https://ca.api.soyoustart.com/1.0' #'runabove-ca' RAV_CA='https://api.runabove.com/1.0' -wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api" +wiki="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-OVH-domain-api" -ovh_success="https://github.com/Neilpang/acme.sh/wiki/OVH-Success" +ovh_success="https://github.com/acmesh-official/acme.sh/wiki/OVH-Success" _ovh_get_api() { _ogaep="$1" diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index c5d9e544..fe18bef4 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -2,7 +2,7 @@ ## Name: dns_pleskxml.sh ## Created by Stilez. -## Also uses some code from PR#1832 by @romanlum (https://github.com/Neilpang/acme.sh/pull/1832/files) +## Also uses some code from PR#1832 by @romanlum (https://github.com/acmesh-official/acme.sh/pull/1832/files) ## This DNS-01 method uses the Plesk XML API described at: ## https://docs.plesk.com/en-US/12.5/api-rpc/about-xml-api.28709 diff --git a/dnsapi/dns_rackspace.sh b/dnsapi/dns_rackspace.sh index 3939fd81..159671f9 100644 --- a/dnsapi/dns_rackspace.sh +++ b/dnsapi/dns_rackspace.sh @@ -9,7 +9,7 @@ RACKSPACE_Endpoint="https://dns.api.rackspacecloud.com/v1.0" # 20190213 - The name & id fields swapped in the API response; fix sed # 20190101 - Duplicating file for new pull request to dev branch -# Original - tcocca:rackspace_dnsapi https://github.com/Neilpang/acme.sh/pull/1297 +# Original - tcocca:rackspace_dnsapi https://github.com/acmesh-official/acme.sh/pull/1297 ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index be4e59da..e73d85b0 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh ########## -# Custom servercow.de DNS API v1 for use with [acme.sh](https://github.com/Neilpang/acme.sh) +# Custom servercow.de DNS API v1 for use with [acme.sh](https://github.com/acmesh-official/acme.sh) # # Usage: # export SERVERCOW_API_Username=username From d610eb15d8b8f7ea4f9a407ee230d4822e510b65 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 30 Jan 2020 12:44:02 +0800 Subject: [PATCH 0606/2234] update repo name --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d71c3c57..d1c793d4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh) +# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - An ACME protocol client written purely in Shell (Unix shell) language. @@ -65,7 +65,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) |18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|SunOS/Solaris |19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Gentoo Linux -|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX +|20|[![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh)|Mac OSX For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): From d9a9695fe089f07e81199fcfb9ebb75fe6def7be Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Wed, 5 Feb 2020 14:29:01 -0800 Subject: [PATCH 0607/2234] Deploy certificates to Palo Alto Network Firewalls --- deploy/panos.sh | 144 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 deploy/panos.sh diff --git a/deploy/panos.sh b/deploy/panos.sh new file mode 100644 index 00000000..8a288e7b --- /dev/null +++ b/deploy/panos.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env sh + +# Script to deploy certificates to Palo Alto Networks PANOS via API +# Note PANOS API KEY and IP address needs to be set prior to running. +# The following variables exported from environment will be used. +# If not set then values previously saved in domain.conf file are used. +# +# Firewall admin with superuser and IP address is required. +# +# export PANOS_USER="" # required +# export PANOS_PASS="" # required +# export PANOS_HOST="" # required + +# This function is to parse the XML +parse_response() { + status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g') + message=$(echo "$1" | sed 's/^.*\(.*\)<\/result.*/\1/g') + return 0 +} + +deployer() { + type=$1 # Types are cert, key, commit + _debug "**** Deploying $type *****" + + #Generate DEIM + delim="-----MultipartDelimiter$(date "+%s%N")" + nl="\015\012" + #Set Header + _H1="Content-Type: multipart/form-data; boundary=$delim" + if [ $type = 'cert' ]; then + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" + fi + if [ $type = 'key' ]; then + #Add key + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" + fi + #Close multipart + content="$content${nl}--$delim--${nl}" + #Convert CRLF + content=$(printf %b "$content") + + if [ $type = 'cert' ]; then + panos_url="https://$_panos_host/api/?type=import&category=certificate&certificate-name=$_cdomain&format=pem&key=$_panos_key" + fi + + if [ $type = 'key' ]; then + panos_url="https://$_panos_host/api/?type=import&category=private-key&certificate-name=$_cdomain&format=pem&passphrase=none&key=$_panos_key" + fi + if [ $type = 'commit' ]; then + cmd=$(_url_encode "<$_panos_user>") + panos_url="https://$_panos_host/api/?type=commit&cmd=$cmd&key=$_panos_key" + fi + + if [ $type = 'key' ] || [ $type = 'cert' ]; then + response=$(_post "$content" "$panos_url" "" "POST") + else + response=$(_get $panos_url) + fi + _debug panos_url $panos_url + _debug "RESPONSE $response" + parse_response "$response" + _debug "STATUS IS $status" + _debug "MESSAGE IS $message" + # Saving response to variables + response_status=$status + # Check for cert upload error and handle gracefully. + + #DEBUG + _debug header "$_H1" + # _debug content "$content" + _debug response_status "$response_status" + if [ "$response_status" = "success" ]; then + _debug "Successfully deployed $type" + return 0 + else + _err "Deploy of type $type failed. Try deploying with --debug to troubleshoot." + _debug "$message" + return 1 + fi +} + +# This is the main function that will call the other functions to deploy everything. +panos_deploy() { + _cdomain="$1" + _ckey="$2" + _cfullchain="$5" + # PANOS HOST is required to make API calls to the PANOS/Panorama + if [ -z "$PANOS_HOST" ]; then + if [ -z "$_panos_host" ]; then + _err "PANOS_HOST not defined." + return 1 + fi + else + _debug "PANOS HOST is set. Save to domain conf." + _panos_host="$PANOS_HOST" + _savedomainconf _panos_host "$_panos_host" + fi + # Retrieve stored variables + _panos_user="$(_readaccountconf_mutable PANOS_USER)" + _panos_pass="$(_readaccountconf_mutable PANOS_PASS)" + # PANOS Credentials check + if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ]; then + _debug "PANOS_USER, PANOS_PASS is not defined" + if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ]; then + _err "No user and pass found in storage. If this is the first time deploying please set PANOS_USER and PANOS_PASS in environment variables." + return 1 + else + _debug "ok" + fi + else + _debug "Saving environment variables" + # Encrypt and save user + _saveaccountconf_mutable PANOS_USER "$PANOS_USER" + _saveaccountconf_mutable PANOS_PASS "$PANOS_PASS" + _panos_user="$PANOS_USER" + _panos_pass="$PANOS_PASS" + fi + _debug "Let's use username and pass to generate token." + if [ -z "$_panos_user" ] || [ -z "$_panos_pass" ] || [ -z "$_panos_host" ]; then + _err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST" + return 1 + else + _debug "Getting PANOS KEY" + panos_key_response=$(_get "https://$_panos_host/api/?type=keygen&user=$_panos_user&password=$_panos_pass") + _debug "PANOS KEY FULL RESPONSE $panos_key_response" + status=$(echo "$panos_key_response" | sed 's/^.*\(['\'']\)\([a-z]*\)'\''.*/\2/g') + _debug "STATUS IS $status" + if [ "$status" = "success" ]; then + panos_key=$(echo "$panos_key_response" | sed 's/^.*\(\)\(.*\)<\/key>.*/\2/g') + _panos_key=$panos_key + else + _err "PANOS Key could not be set. Deploy with --debug to troubleshoot" + return 1 + fi + if [ -z "$_panos_host" ] && [ -z "$_panos_key" ] && [ -z "$_panos_user" ]; then + _err "Missing host, apikey, user." + return 1 + else + deployer cert + deployer key + deployer commit + fi + fi +} \ No newline at end of file From 64f8a222cb1ef1a036957ba613afe30d2a2dd770 Mon Sep 17 00:00:00 2001 From: Victor Huang Date: Thu, 6 Feb 2020 11:12:14 +0800 Subject: [PATCH 0608/2234] Add support for CQHTTP QQ bot API --- notify/cqhttp.sh | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 notify/cqhttp.sh diff --git a/notify/cqhttp.sh b/notify/cqhttp.sh new file mode 100644 index 00000000..a47f4c92 --- /dev/null +++ b/notify/cqhttp.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +#Support for CQHTTP api. Push notification on CoolQ +#CQHTTP_TOKEN="" Required, QQ application token +#CQHTTP_USER="" Required, QQ reciever ID +#CQHTTP_APIROOT="" Required, CQHTTP Server URL (without slash suffix) +#CQHTTP_CUSTOM_MSGHEAD="" Optional, custom message header + +CQHTTP_APIPATH="/send_private_msg" + +cqhttp_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + CQHTTP_TOKEN="${CQHTTP_TOKEN:-$(_readaccountconf_mutable CQHTTP_TOKEN)}" + if [ -z "$CQHTTP_TOKEN" ]; then + CQHTTP_TOKEN="" + _err "You didn't specify a CQHTTP application token yet. If it's empty please pass \"__ACME_SH_TOKEN_EMPTY__\" (without quote)." + return 1 + fi + _saveaccountconf_mutable CQHTTP_TOKEN "$CQHTTP_TOKEN" + if [ "$CQHTTP_TOKEN" = "__ACME_SH_TOKEN_EMPTY__" ]; then + CQHTTP_TOKEN="" + fi + + CQHTTP_USER="${CQHTTP_USER:-$(_readaccountconf_mutable CQHTTP_USER)}" + if [ -z "$CQHTTP_USER" ]; then + CQHTTP_USER="" + _err "You didn't specify a QQ user yet." + return 1 + fi + _saveaccountconf_mutable CQHTTP_USER "$CQHTTP_USER" + + CQHTTP_APIROOT="${CQHTTP_APIROOT:-$(_readaccountconf_mutable CQHTTP_APIROOT)}" + if [ -z "$CQHTTP_APIROOT" ]; then + CQHTTP_APIROOT="" + _err "You didn't specify a QQ user yet." + return 1 + fi + _saveaccountconf_mutable CQHTTP_APIROOT "$CQHTTP_APIROOT" + + CQHTTP_APIROOT="${CQHTTP_APIROOT:-$(_readaccountconf_mutable CQHTTP_APIROOT)}" + if [ -z "$CQHTTP_APIROOT" ]; then + CQHTTP_APIROOT="" + _err "You didn't specify a QQ user yet." + return 1 + fi + _saveaccountconf_mutable CQHTTP_APIROOT "$CQHTTP_APIROOT" + + CQHTTP_CUSTOM_MSGHEAD="${CQHTTP_CUSTOM_MSGHEAD:-$(_readaccountconf_mutable CQHTTP_CUSTOM_MSGHEAD)}" + if [ -z "$CQHTTP_CUSTOM_MSGHEAD" ]; then + CQHTTP_CUSTOM_MSGHEAD="A message from acme.sh:" + else + _saveaccountconf_mutable CQHTTP_CUSTOM_MSGHEAD "$CQHTTP_CUSTOM_MSGHEAD" + fi + + _access_token="$(printf "%s" "$CQHTTP_TOKEN" | _url_encode)" + _user_id="$(printf "%s" "$CQHTTP_USER" | _url_encode)" + _message="$(printf "$CQHTTP_CUSTOM_MSGHEAD %s\\n%s" "$_subject" "$_content" | _url_encode)" + + _finalUrl="$CQHTTP_APIROOT$CQHTTP_APIPATH?access_token=$_access_token&user_id=$_user_id&message=$_message" + response="$(_get "$_finalUrl")" + + if [ "$?" = "0" ] && _contains "$response" "\"retcode\":0,\"status\":\"ok\""; then + _info "QQ send success." + return 0 + fi + + _err "QQ send error." + _err "URL: $_finalUrl" + _err "Response: $response" + return 1 +} From 33670a5bd0788ffc403f6e6b32feef179382413a Mon Sep 17 00:00:00 2001 From: Victor Huang Date: Thu, 6 Feb 2020 11:26:56 +0800 Subject: [PATCH 0609/2234] CQHTTP: Change shebang to "/usr/bin/env sh" --- notify/cqhttp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/cqhttp.sh b/notify/cqhttp.sh index a47f4c92..fe78a0fd 100644 --- a/notify/cqhttp.sh +++ b/notify/cqhttp.sh @@ -1,8 +1,8 @@ -#!/bin/bash +#!/usr/bin/env sh #Support for CQHTTP api. Push notification on CoolQ #CQHTTP_TOKEN="" Required, QQ application token -#CQHTTP_USER="" Required, QQ reciever ID +#CQHTTP_USER="" Required, QQ receiver ID #CQHTTP_APIROOT="" Required, CQHTTP Server URL (without slash suffix) #CQHTTP_CUSTOM_MSGHEAD="" Optional, custom message header From 2cc50a2b65d4e443d7469675c5639999a27f8f19 Mon Sep 17 00:00:00 2001 From: Wout Date: Sat, 8 Feb 2020 12:27:19 +0100 Subject: [PATCH 0610/2234] Cosmetic fixes. --- dnsapi/dns_constellix.sh | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 55f4a71b..c47ede44 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -2,26 +2,28 @@ # Author: Wout Decre -CONSTELLIX_API="https://api.dns.constellix.com/v1" -#CONSTELLIX_KEY="XXX" -#CONSTELLIX_SECRET="XXX" +CONSTELLIX_Api="https://api.dns.constellix.com/v1" +#CONSTELLIX_Key="XXX" +#CONSTELLIX_Secret="XXX" ######## Public functions ##################### +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record dns_constellix_add() { fulldomain=$1 txtvalue=$2 - CONSTELLIX_KEY="${CONSTELLIX_KEY:-$(_readaccountconf_mutable CONSTELLIX_KEY)}" - CONSTELLIX_SECRET="${CONSTELLIX_SECRET:-$(_readaccountconf_mutable CONSTELLIX_SECRET)}" + CONSTELLIX_Key="${CONSTELLIX_Key:-$(_readaccountconf_mutable CONSTELLIX_Key)}" + CONSTELLIX_Secret="${CONSTELLIX_Secret:-$(_readaccountconf_mutable CONSTELLIX_Secret)}" - if [ -z "$CONSTELLIX_KEY" ] || [ -z "$CONSTELLIX_SECRET" ]; then + if [ -z "$CONSTELLIX_Key" ] || [ -z "$CONSTELLIX_Secret" ]; then _err "You did not specify the Contellix API key and secret yet." return 1 fi - _saveaccountconf_mutable CONSTELLIX_KEY "$CONSTELLIX_KEY" - _saveaccountconf_mutable CONSTELLIX_SECRET "$CONSTELLIX_SECRET" + _saveaccountconf_mutable CONSTELLIX_Key "$CONSTELLIX_Key" + _saveaccountconf_mutable CONSTELLIX_Secret "$CONSTELLIX_Secret" if ! _get_root "$fulldomain"; then _err "Invalid domain" @@ -40,14 +42,16 @@ dns_constellix_add() { fi } +# Usage: fulldomain txtvalue +# Used to remove the txt record after validation dns_constellix_rm() { fulldomain=$1 txtvalue=$2 - CONSTELLIX_KEY="${CONSTELLIX_KEY:-$(_readaccountconf_mutable CONSTELLIX_KEY)}" - CONSTELLIX_SECRET="${CONSTELLIX_SECRET:-$(_readaccountconf_mutable CONSTELLIX_SECRET)}" + CONSTELLIX_Key="${CONSTELLIX_Key:-$(_readaccountconf_mutable CONSTELLIX_Key)}" + CONSTELLIX_Secret="${CONSTELLIX_Secret:-$(_readaccountconf_mutable CONSTELLIX_Secret)}" - if [ -z "$CONSTELLIX_KEY" ] || [ -z "$CONSTELLIX_SECRET" ]; then + if [ -z "$CONSTELLIX_Key" ] || [ -z "$CONSTELLIX_Secret" ]; then _err "You did not specify the Contellix API key and secret yet." return 1 fi @@ -112,9 +116,9 @@ _constellix_rest() { _debug "$ep" rdate=$(date +"%s")"000" - hmac=$(printf "%s" "$rdate" | _hmac sha1 "$(printf "%s" "$CONSTELLIX_SECRET" | _hex_dump | tr -d ' ')" | _base64) + hmac=$(printf "%s" "$rdate" | _hmac sha1 "$(printf "%s" "$CONSTELLIX_Secret" | _hex_dump | tr -d ' ')" | _base64) - export _H1="x-cnsdns-apiKey: $CONSTELLIX_KEY" + export _H1="x-cnsdns-apiKey: $CONSTELLIX_Key" export _H2="x-cnsdns-requestDate: $rdate" export _H3="x-cnsdns-hmac: $hmac" export _H4="Accept: application/json" @@ -122,9 +126,9 @@ _constellix_rest() { if [ "$m" != "GET" ]; then _debug data "$data" - response="$(_post "$data" "$CONSTELLIX_API/$ep" "" "$m")" + response="$(_post "$data" "$CONSTELLIX_Api/$ep" "" "$m")" else - response="$(_get "$CONSTELLIX_API/$ep")" + response="$(_get "$CONSTELLIX_Api/$ep")" fi if [ "$?" != "0" ]; then From 5d88ad554feb1f7b676ecb75c89e2f1543261fbf Mon Sep 17 00:00:00 2001 From: Victor Huang Date: Sat, 8 Feb 2020 23:24:45 +0800 Subject: [PATCH 0611/2234] Improved token processing method and misc bugfixes Replace '_err' to '_debug' in the final error report. Removed redundancy code. --- notify/cqhttp.sh | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/notify/cqhttp.sh b/notify/cqhttp.sh index fe78a0fd..ac76f5b8 100644 --- a/notify/cqhttp.sh +++ b/notify/cqhttp.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh #Support for CQHTTP api. Push notification on CoolQ -#CQHTTP_TOKEN="" Required, QQ application token +#CQHTTP_TOKEN="" Recommended to be not empty, QQ application token #CQHTTP_USER="" Required, QQ receiver ID #CQHTTP_APIROOT="" Required, CQHTTP Server URL (without slash suffix) #CQHTTP_CUSTOM_MSGHEAD="" Optional, custom message header @@ -17,12 +17,9 @@ cqhttp_send() { CQHTTP_TOKEN="${CQHTTP_TOKEN:-$(_readaccountconf_mutable CQHTTP_TOKEN)}" if [ -z "$CQHTTP_TOKEN" ]; then CQHTTP_TOKEN="" - _err "You didn't specify a CQHTTP application token yet. If it's empty please pass \"__ACME_SH_TOKEN_EMPTY__\" (without quote)." - return 1 - fi - _saveaccountconf_mutable CQHTTP_TOKEN "$CQHTTP_TOKEN" - if [ "$CQHTTP_TOKEN" = "__ACME_SH_TOKEN_EMPTY__" ]; then - CQHTTP_TOKEN="" + _info "You didn't specify a CQHTTP application token yet, which is unsafe. Assuming it to be empty." + else + _saveaccountconf_mutable CQHTTP_TOKEN "$CQHTTP_TOKEN" fi CQHTTP_USER="${CQHTTP_USER:-$(_readaccountconf_mutable CQHTTP_USER)}" @@ -36,15 +33,7 @@ cqhttp_send() { CQHTTP_APIROOT="${CQHTTP_APIROOT:-$(_readaccountconf_mutable CQHTTP_APIROOT)}" if [ -z "$CQHTTP_APIROOT" ]; then CQHTTP_APIROOT="" - _err "You didn't specify a QQ user yet." - return 1 - fi - _saveaccountconf_mutable CQHTTP_APIROOT "$CQHTTP_APIROOT" - - CQHTTP_APIROOT="${CQHTTP_APIROOT:-$(_readaccountconf_mutable CQHTTP_APIROOT)}" - if [ -z "$CQHTTP_APIROOT" ]; then - CQHTTP_APIROOT="" - _err "You didn't specify a QQ user yet." + _err "You didn't specify the API root yet." return 1 fi _saveaccountconf_mutable CQHTTP_APIROOT "$CQHTTP_APIROOT" @@ -69,7 +58,7 @@ cqhttp_send() { fi _err "QQ send error." - _err "URL: $_finalUrl" - _err "Response: $response" + _debug "URL" "$_finalUrl" + _debug "Response" "$response" return 1 } From 8189a34d145050a3ffb5598d330e6bcdd4cadf02 Mon Sep 17 00:00:00 2001 From: Blfrg Date: Sat, 8 Feb 2020 16:43:23 -0600 Subject: [PATCH 0612/2234] fix dns_me id parse The API seems to have changed and the ID is no longer in the same location. --- dnsapi/dns_me.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 98a58411..302603ea 100644 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -114,7 +114,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\""; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | head -n 1 | cut -d : -f 2 | tr -d '}') + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+}$" | head -n 1 | cut -d : -f 2 | tr -d '}') if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" From 555e0de9e45f36ddd2507975a0368eaab9141074 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 29 Jun 2019 21:47:24 -0600 Subject: [PATCH 0613/2234] Initial support for Synology DSM This allows you to update a key on a Synology DSM using the existing API. Handles restarting the necessary services the certificate is attached to and all other internal stuff (copying the certificate around, etc.) This is way less error prone than most articles I've found on how to update a Synology DSM certificate. --- deploy/synology_dsm.sh | 145 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 deploy/synology_dsm.sh diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh new file mode 100644 index 00000000..45eab335 --- /dev/null +++ b/deploy/synology_dsm.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env sh + +# Here is a script to deploy cert to Synology DSM vault +# (https://www.vaultproject.io/) +# +# it requires the jq and curl are in the $PATH and the following +# environment variables must be set: +# +# SYNO_Username - Synology Username to login (must be an administrator) +# SYNO_Password - Synology Password to login +# SYNO_Certificate - Certificate description to target for replacement +# +# The following environmental variables may be set if you don't like their +# default values: +# +# SYNO_Scheme - defaults to http +# SYNO_Hostname - defaults to localhost +# SYNO_Port - defaults to 5000 +# +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +synology_dsm_deploy() { + + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + + _debug _cdomain "$_cdomain" + + # Get Username and Password, but don't save until we successfully authenticate + SYNO_Username="${SYNO_Username:-$(_readaccountconf_mutable SYNO_Username)}" + SYNO_Password="${SYNO_Password:-$(_readaccountconf_mutable SYNO_Password)}" + if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then + SYNO_Username="" + SYNO_Password="" + _err "SYNO_Username & SYNO_Password must be set" + return 1 + fi + _debug2 SYNO_Username "$SYNO_Username" + _secure_debug2 SYNO_Password "$SYNO_Password" + + # Optional scheme, hostname, and port for Synology DSM + SYNO_Scheme="${SYNO_Scheme:-$(_readaccountconf_mutable SYNO_Scheme)}" + SYNO_Hostname="${SYNO_Hostname:-$(_readaccountconf_mutable SYNO_Hostname)}" + SYNO_Port="${SYNO_Port:-$(_readaccountconf_mutable SYNO_Port)}" + _saveaccountconf_mutable SYNO_Scheme "$SYNO_Scheme" + _saveaccountconf_mutable SYNO_Hostname "$SYNO_Hostname" + _saveaccountconf_mutable SYNO_Port "$SYNO_Port" + + # default vaules for scheme, hostname, and port + # defaulting to localhost and http because it's localhost... + [ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http" + [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost" + [ -n "${SYNO_Port}" ] || SYNO_Port="5000" + + _debug2 SYNO_Scheme "$SYNO_Scheme" + _debug2 SYNO_Hostname "$SYNO_Hostname" + _debug2 SYNO_Port "$SYNO_Port" + + # Get the certificate description, but don't save it until we verfiy it's real + _getdeployconf SYNO_Certificate + if [ -z "${SYNO_Certificate}" ]; then + _err "SYNO_Certificate needs to be defined (with the Certificate description name)" + return 1 + fi + _debug SYNO_Certificate "$SYNO_Certificate" + + # We can't use _get or _post because they lack support for cookies + # use jq because I'm too lazy to figure out what is required to parse json + # by hand. Also it seems to be in place for Synology DSM (6.2.1 at least) + for x in curl jq; do + if ! _exists "$x"; then + _err "Please install $x first." + _err "We need $x to work." + return 1 + fi + done + + _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" + _debug _base_url "$_base_url" + + _cookie_jar="$(_mktemp)" + _debug _cookie_jar "$_cookie_jar" + + # Login, get the token from JSON and session id from cookie + _debug "Logging into $SYNO_Hostname:$SYNO_Port" + token=$(curl -sk -c $_cookie_jar "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken) + if [ $token = "null" ]; then + _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." + _err "Check your username and password." + rm "$_cookie_jar" + return 1 + fi + + # Now that we know the username and password are good, save them + _saveaccountconf_mutable SYNO_Username "$SYNO_Username" + _saveaccountconf_mutable SYNO_Password "$SYNO_Password" + _secure_debug2 token "$token" + + # Use token and session id to get the list of certificates + response=$(curl -sk -b $_cookie_jar $_base_url/webapi/entry.cgi -H "X-SYNO-TOKEN: $token" -d api=SYNO.Core.Certificate.CRT -d method=list -d version=1) + _debug3 response "$response" + # select the first certificate matching our description + cert=$(echo "$response" | jq -r ".data.certificates | map(select(.desc == \"$SYNO_Certificate\"))[0]") + _debug3 cert "$cert" + + if [ "$cert" = "null" ]; then + _err "Unable to find certificate: $SYNO_Certificate" + rm "$_cookie_jar" + return 1 + fi + + # we've verified this certificate description is a thing, so save it + _savedeployconf SYNO_Certificate "$SYNO_Certificate" + + id=$(echo $cert | jq -r ".id") + default=$(echo "$cert" | jq -r ".is_default") + _debug2 id "$id" + _debug2 default "$default" + + # This is the heavy lifting, make the API call to update a certificate in place + response=$(curl -sk -b $_cookie_jar "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" -F key=@$_ckey -F cert=@$_ccert -F inter_cert=@$_cca -F id=$id -F desc=$SYNO_Certificate -F as_default=$default) + _debug3 response "$response" + success=$(echo "$response" | jq -r ".success") + _debug2 success "$success" + rm "$_cookie_jar" + + if [ "$success" = "true" ]; then + restarted=$(echo "$response" | jq -r ".data.restart_httpd") + if [ "$restarted" = "true" ]; then + _info "http services were restarted" + else + _info "http services were NOT restarted" + fi + return 0; + else + code=$(echo "$response" | jq -r ".error.code") + _err "Unable to update certificate, error code $code" + return 1 + fi +} From 548f83c3adf4533140980774892cc484937960ac Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 30 Jun 2019 00:13:07 -0600 Subject: [PATCH 0614/2234] Cleanup shellcheck errors --- deploy/synology_dsm.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 45eab335..d131e9cd 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -63,6 +63,7 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verfiy it's real _getdeployconf SYNO_Certificate + # shellcheck disable=SC2154 if [ -z "${SYNO_Certificate}" ]; then _err "SYNO_Certificate needs to be defined (with the Certificate description name)" return 1 @@ -88,8 +89,8 @@ synology_dsm_deploy() { # Login, get the token from JSON and session id from cookie _debug "Logging into $SYNO_Hostname:$SYNO_Port" - token=$(curl -sk -c $_cookie_jar "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken) - if [ $token = "null" ]; then + token=$(curl -sk -c "$_cookie_jar" "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken) + if [ "$token" = "null" ]; then _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." _err "Check your username and password." rm "$_cookie_jar" @@ -102,7 +103,7 @@ synology_dsm_deploy() { _secure_debug2 token "$token" # Use token and session id to get the list of certificates - response=$(curl -sk -b $_cookie_jar $_base_url/webapi/entry.cgi -H "X-SYNO-TOKEN: $token" -d api=SYNO.Core.Certificate.CRT -d method=list -d version=1) + response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi" -H "X-SYNO-TOKEN: $token" -d api=SYNO.Core.Certificate.CRT -d method=list -d version=1) _debug3 response "$response" # select the first certificate matching our description cert=$(echo "$response" | jq -r ".data.certificates | map(select(.desc == \"$SYNO_Certificate\"))[0]") @@ -117,13 +118,13 @@ synology_dsm_deploy() { # we've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate" - id=$(echo $cert | jq -r ".id") + id=$(echo "$cert" | jq -r ".id") default=$(echo "$cert" | jq -r ".is_default") _debug2 id "$id" _debug2 default "$default" # This is the heavy lifting, make the API call to update a certificate in place - response=$(curl -sk -b $_cookie_jar "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" -F key=@$_ckey -F cert=@$_ccert -F inter_cert=@$_cca -F id=$id -F desc=$SYNO_Certificate -F as_default=$default) + response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" -F "key=@$_ckey" -F "cert=@$_ccert" -F "inter_cert=@$_cca" -F "id=$id" -F "desc=$SYNO_Certificate" -F "as_default=$default") _debug3 response "$response" success=$(echo "$response" | jq -r ".success") _debug2 success "$success" From 6459ccb18517c3f9f6c87410df8d76a0082020e3 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 30 Jun 2019 00:13:45 -0600 Subject: [PATCH 0615/2234] Cleanup shfmt warnings --- deploy/synology_dsm.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index d131e9cd..7fab47d8 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -74,11 +74,11 @@ synology_dsm_deploy() { # use jq because I'm too lazy to figure out what is required to parse json # by hand. Also it seems to be in place for Synology DSM (6.2.1 at least) for x in curl jq; do - if ! _exists "$x"; then - _err "Please install $x first." - _err "We need $x to work." - return 1 - fi + if ! _exists "$x"; then + _err "Please install $x first." + _err "We need $x to work." + return 1 + fi done _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" @@ -133,11 +133,11 @@ synology_dsm_deploy() { if [ "$success" = "true" ]; then restarted=$(echo "$response" | jq -r ".data.restart_httpd") if [ "$restarted" = "true" ]; then - _info "http services were restarted" + _info "http services were restarted" else - _info "http services were NOT restarted" + _info "http services were NOT restarted" fi - return 0; + return 0 else code=$(echo "$response" | jq -r ".error.code") _err "Unable to update certificate, error code $code" From 8e8cda132c0ab64548122478ab59f6eea7262dba Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 30 Jun 2019 00:30:35 -0600 Subject: [PATCH 0616/2234] Remove boilerplate from what I used for template --- deploy/synology_dsm.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 7fab47d8..e37d7d44 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -1,7 +1,6 @@ #!/usr/bin/env sh -# Here is a script to deploy cert to Synology DSM vault -# (https://www.vaultproject.io/) +# Here is a script to deploy cert to Synology DSM # # it requires the jq and curl are in the $PATH and the following # environment variables must be set: From b3b00b6700e7bc960d96ddd0f2abf1315cab0e03 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Mon, 30 Sep 2019 14:06:04 -0600 Subject: [PATCH 0617/2234] Using domainconf instead of account --- deploy/synology_dsm.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index e37d7d44..25b63767 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -31,8 +31,8 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" # Get Username and Password, but don't save until we successfully authenticate - SYNO_Username="${SYNO_Username:-$(_readaccountconf_mutable SYNO_Username)}" - SYNO_Password="${SYNO_Password:-$(_readaccountconf_mutable SYNO_Password)}" + SYNO_Username="${SYNO_Username:-$(_readdomainconf SYNO_Username)}" + SYNO_Password="${SYNO_Password:-$(_readdomainconf SYNO_Password)}" if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" @@ -43,12 +43,12 @@ synology_dsm_deploy() { _secure_debug2 SYNO_Password "$SYNO_Password" # Optional scheme, hostname, and port for Synology DSM - SYNO_Scheme="${SYNO_Scheme:-$(_readaccountconf_mutable SYNO_Scheme)}" - SYNO_Hostname="${SYNO_Hostname:-$(_readaccountconf_mutable SYNO_Hostname)}" - SYNO_Port="${SYNO_Port:-$(_readaccountconf_mutable SYNO_Port)}" - _saveaccountconf_mutable SYNO_Scheme "$SYNO_Scheme" - _saveaccountconf_mutable SYNO_Hostname "$SYNO_Hostname" - _saveaccountconf_mutable SYNO_Port "$SYNO_Port" + SYNO_Scheme="${SYNO_Scheme:-$(_readdomainconf SYNO_Scheme)}" + SYNO_Hostname="${SYNO_Hostname:-$(_readdomainconf SYNO_Hostname)}" + SYNO_Port="${SYNO_Port:-$(_readdomainconf SYNO_Port)}" + _savedomainconf SYNO_Scheme "$SYNO_Scheme" + _savedomainconf SYNO_Hostname "$SYNO_Hostname" + _savedomainconf SYNO_Port "$SYNO_Port" # default vaules for scheme, hostname, and port # defaulting to localhost and http because it's localhost... @@ -97,8 +97,8 @@ synology_dsm_deploy() { fi # Now that we know the username and password are good, save them - _saveaccountconf_mutable SYNO_Username "$SYNO_Username" - _saveaccountconf_mutable SYNO_Password "$SYNO_Password" + _savedomainconf SYNO_Username "$SYNO_Username" + _savedomainconf SYNO_Password "$SYNO_Password" _secure_debug2 token "$token" # Use token and session id to get the list of certificates From 52a168b96160d5c407e54067181bedebe2c9aad9 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 8 Feb 2020 16:27:18 -0800 Subject: [PATCH 0618/2234] Stop using jq/curl directly This is a lot more fragile then the previous code due to treating JSON as just a string --- deploy/synology_dsm.sh | 105 ++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 25b63767..82645829 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -20,6 +20,12 @@ ######## Public functions ##################### +_syno_get_cookie_data() { + _debug2 Cookie "$1" + _debug3 grep "$(grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' )" + grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' +} + #domain keyfile certfile cafile fullchain synology_dsm_deploy() { @@ -31,8 +37,8 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" # Get Username and Password, but don't save until we successfully authenticate - SYNO_Username="${SYNO_Username:-$(_readdomainconf SYNO_Username)}" - SYNO_Password="${SYNO_Password:-$(_readdomainconf SYNO_Password)}" + SYNO_Username="${SYNO_Username:-$(_getdeployconf SYNO_Username)}" + SYNO_Password="${SYNO_Password:-$(_getdeployconf SYNO_Password)}" if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" @@ -43,12 +49,12 @@ synology_dsm_deploy() { _secure_debug2 SYNO_Password "$SYNO_Password" # Optional scheme, hostname, and port for Synology DSM - SYNO_Scheme="${SYNO_Scheme:-$(_readdomainconf SYNO_Scheme)}" - SYNO_Hostname="${SYNO_Hostname:-$(_readdomainconf SYNO_Hostname)}" - SYNO_Port="${SYNO_Port:-$(_readdomainconf SYNO_Port)}" - _savedomainconf SYNO_Scheme "$SYNO_Scheme" - _savedomainconf SYNO_Hostname "$SYNO_Hostname" - _savedomainconf SYNO_Port "$SYNO_Port" + SYNO_Scheme="${SYNO_Scheme:-$(_getdeployconf SYNO_Scheme)}" + SYNO_Hostname="${SYNO_Hostname:-$(_getdeployconf SYNO_Hostname)}" + SYNO_Port="${SYNO_Port:-$(_getdeployconf SYNO_Port)}" + _savedeployconf SYNO_Scheme "$SYNO_Scheme" + _savedeployconf SYNO_Hostname "$SYNO_Hostname" + _savedeployconf SYNO_Port "$SYNO_Port" # default vaules for scheme, hostname, and port # defaulting to localhost and http because it's localhost... @@ -69,77 +75,78 @@ synology_dsm_deploy() { fi _debug SYNO_Certificate "$SYNO_Certificate" - # We can't use _get or _post because they lack support for cookies - # use jq because I'm too lazy to figure out what is required to parse json - # by hand. Also it seems to be in place for Synology DSM (6.2.1 at least) - for x in curl jq; do - if ! _exists "$x"; then - _err "Please install $x first." - _err "We need $x to work." - return 1 - fi - done - _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" - _cookie_jar="$(_mktemp)" - _debug _cookie_jar "$_cookie_jar" - # Login, get the token from JSON and session id from cookie - _debug "Logging into $SYNO_Hostname:$SYNO_Port" - token=$(curl -sk -c "$_cookie_jar" "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken) - if [ "$token" = "null" ]; then + _info "Logging into $SYNO_Hostname:$SYNO_Port" + response=$(_get "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes") + token=$(echo "$response" | grep "SynoToken" | sed -n 's/.*"SynoToken" *: *"\([^"]*\).*/\1/p') + _debug3 response "$response" + + if [ -z "$token" ]; then _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." _err "Check your username and password." - rm "$_cookie_jar" return 1 fi + _H1="Cookie: $(_syno_get_cookie_data "id"); $(_syno_get_cookie_data "smid")" + _H2="X-SYNO-TOKEN: $token" + export _H1 + export _H2 + _debug3 H1 "${_H1}" + _debug3 H2 "${_H2}" + # Now that we know the username and password are good, save them - _savedomainconf SYNO_Username "$SYNO_Username" - _savedomainconf SYNO_Password "$SYNO_Password" + _savedeployconf SYNO_Username "$SYNO_Username" + _savedeployconf SYNO_Password "$SYNO_Password" _secure_debug2 token "$token" - # Use token and session id to get the list of certificates - response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi" -H "X-SYNO-TOKEN: $token" -d api=SYNO.Core.Certificate.CRT -d method=list -d version=1) + _info "Getting certificates in Synology DSM" + response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1" "$_base_url/webapi/entry.cgi") _debug3 response "$response" - # select the first certificate matching our description - cert=$(echo "$response" | jq -r ".data.certificates | map(select(.desc == \"$SYNO_Certificate\"))[0]") - _debug3 cert "$cert" + id=$(printf "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") + _debug2 id "$id" - if [ "$cert" = "null" ]; then + if [ -z "$id" ]; then _err "Unable to find certificate: $SYNO_Certificate" - rm "$_cookie_jar" return 1 fi # we've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate" - id=$(echo "$cert" | jq -r ".id") - default=$(echo "$cert" | jq -r ".is_default") - _debug2 id "$id" + default=false + if printf "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -q -- 'is_default":true'; then + default=true + fi _debug2 default "$default" - # This is the heavy lifting, make the API call to update a certificate in place - response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" -F "key=@$_ckey" -F "cert=@$_ccert" -F "inter_cert=@$_cca" -F "id=$id" -F "desc=$SYNO_Certificate" -F "as_default=$default") - _debug3 response "$response" - success=$(echo "$response" | jq -r ".success") - _debug2 success "$success" - rm "$_cookie_jar" + _info "Generate form POST request" + nl="\015\012" + delim="--------------------------$(date +%Y%m%d%H%M%S)" + content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\012" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\012" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\012" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}${default}" + content="$content${nl}--$delim--${nl}" + content="$(printf "%b_" "$content")";content="${content%_}" # protect trailing \n - if [ "$success" = "true" ]; then - restarted=$(echo "$response" | jq -r ".data.restart_httpd") - if [ "$restarted" = "true" ]; then + _info "Upload certificate to the Synology DSM" + response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" "" "POST" "multipart/form-data; boundary=${delim}") + _debug3 response "$response" + + if ! printf "$response" | grep -q '"error":'; then + if printf "$response" | grep -q '"restart_httpd":true'; then _info "http services were restarted" else _info "http services were NOT restarted" fi return 0 else - code=$(echo "$response" | jq -r ".error.code") - _err "Unable to update certificate, error code $code" + _err "Unable to update certificate, error code $response" return 1 fi } From 95769de464b6e21a3b31c644febd262738d0f63c Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 02:01:26 -0800 Subject: [PATCH 0619/2234] Fix shfmt/shellcheck issues --- deploy/synology_dsm.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 82645829..7d713930 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -22,7 +22,7 @@ _syno_get_cookie_data() { _debug2 Cookie "$1" - _debug3 grep "$(grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' )" + _debug3 grep "$(grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';')" grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' } @@ -105,7 +105,7 @@ synology_dsm_deploy() { _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1" "$_base_url/webapi/entry.cgi") _debug3 response "$response" - id=$(printf "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") + id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" if [ -z "$id" ]; then @@ -117,8 +117,8 @@ synology_dsm_deploy() { _savedeployconf SYNO_Certificate "$SYNO_Certificate" default=false - if printf "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -q -- 'is_default":true'; then - default=true + if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -q -- 'is_default":true'; then + default=true fi _debug2 default "$default" @@ -132,14 +132,15 @@ synology_dsm_deploy() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}${default}" content="$content${nl}--$delim--${nl}" - content="$(printf "%b_" "$content")";content="${content%_}" # protect trailing \n + content="$(printf "%b_" "$content")" + content="${content%_}" # protect trailing \n _info "Upload certificate to the Synology DSM" response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" "" "POST" "multipart/form-data; boundary=${delim}") _debug3 response "$response" - if ! printf "$response" | grep -q '"error":'; then - if printf "$response" | grep -q '"restart_httpd":true'; then + if ! echo "$response" | grep -q '"error":'; then + if echo "$response" | grep -q '"restart_httpd":true'; then _info "http services were restarted" else _info "http services were NOT restarted" From de25232a7345d8dfe221d1d1a131419182989ca6 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 02:26:55 -0800 Subject: [PATCH 0620/2234] Allow creating new certificates when certificate is not found --- deploy/synology_dsm.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 7d713930..71d9e7dc 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -39,6 +39,7 @@ synology_dsm_deploy() { # Get Username and Password, but don't save until we successfully authenticate SYNO_Username="${SYNO_Username:-$(_getdeployconf SYNO_Username)}" SYNO_Password="${SYNO_Password:-$(_getdeployconf SYNO_Password)}" + SYNO_Create="${SYNO_Create:-$(_getdeployconf SYNO_Create)}" if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" @@ -108,8 +109,8 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - if [ -z "$id" ]; then - _err "Unable to find certificate: $SYNO_Certificate" + if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then + _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set" return 1 fi From 5d3bc95ac529550077505189b4e2cc07ca4b5155 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 02:50:29 -0800 Subject: [PATCH 0621/2234] Fix some debug output --- deploy/synology_dsm.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 71d9e7dc..bb49f279 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -21,8 +21,6 @@ ######## Public functions ##################### _syno_get_cookie_data() { - _debug2 Cookie "$1" - _debug3 grep "$(grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';')" grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' } @@ -95,13 +93,13 @@ synology_dsm_deploy() { _H2="X-SYNO-TOKEN: $token" export _H1 export _H2 - _debug3 H1 "${_H1}" - _debug3 H2 "${_H2}" + _debug2 H1 "${_H1}" + _debug2 H2 "${_H2}" # Now that we know the username and password are good, save them _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" - _secure_debug2 token "$token" + _debug token "$token" _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1" "$_base_url/webapi/entry.cgi") From 1259341095f2b15946f0db39ce53f821b194c00f Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 03:10:11 -0800 Subject: [PATCH 0622/2234] Use deployconf properly --- deploy/synology_dsm.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index bb49f279..13728d66 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -35,9 +35,9 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" # Get Username and Password, but don't save until we successfully authenticate - SYNO_Username="${SYNO_Username:-$(_getdeployconf SYNO_Username)}" - SYNO_Password="${SYNO_Password:-$(_getdeployconf SYNO_Password)}" - SYNO_Create="${SYNO_Create:-$(_getdeployconf SYNO_Create)}" + _getdeployconf SYNO_Username + _getdeployconf SYNO_Password + _getdeployconf SYNO_Create if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" @@ -48,12 +48,9 @@ synology_dsm_deploy() { _secure_debug2 SYNO_Password "$SYNO_Password" # Optional scheme, hostname, and port for Synology DSM - SYNO_Scheme="${SYNO_Scheme:-$(_getdeployconf SYNO_Scheme)}" - SYNO_Hostname="${SYNO_Hostname:-$(_getdeployconf SYNO_Hostname)}" - SYNO_Port="${SYNO_Port:-$(_getdeployconf SYNO_Port)}" - _savedeployconf SYNO_Scheme "$SYNO_Scheme" - _savedeployconf SYNO_Hostname "$SYNO_Hostname" - _savedeployconf SYNO_Port "$SYNO_Port" + _getdeployconf SYNO_Scheme + _getdeployconf SYNO_Hostname + _getdeployconf SYNO_Port # default vaules for scheme, hostname, and port # defaulting to localhost and http because it's localhost... @@ -61,6 +58,10 @@ synology_dsm_deploy() { [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost" [ -n "${SYNO_Port}" ] || SYNO_Port="5000" + _savedeployconf SYNO_Scheme "$SYNO_Scheme" + _savedeployconf SYNO_Hostname "$SYNO_Hostname" + _savedeployconf SYNO_Port "$SYNO_Port" + _debug2 SYNO_Scheme "$SYNO_Scheme" _debug2 SYNO_Hostname "$SYNO_Hostname" _debug2 SYNO_Port "$SYNO_Port" @@ -107,6 +108,7 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" + # shellcheck disable=SC2154 if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set" return 1 From 79637097bada83f251c68159df4baa657f16d7ad Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 11:50:50 -0800 Subject: [PATCH 0623/2234] Use _utc_date --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 13728d66..dd26e3d8 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -125,7 +125,7 @@ synology_dsm_deploy() { _info "Generate form POST request" nl="\015\012" - delim="--------------------------$(date +%Y%m%d%H%M%S)" + delim="--------------------------$(_utc_date | tr -d -- '-: ')" content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\012" From d07172a52843b8eeb412e85f2cdfc9a527c646c6 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 12:06:13 -0800 Subject: [PATCH 0624/2234] Replace disabled linter with variable substituion --- deploy/synology_dsm.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index dd26e3d8..f1c08c36 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -68,8 +68,7 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verfiy it's real _getdeployconf SYNO_Certificate - # shellcheck disable=SC2154 - if [ -z "${SYNO_Certificate}" ]; then + if [ -z "${SYNO_Certificate:?}" ]; then _err "SYNO_Certificate needs to be defined (with the Certificate description name)" return 1 fi @@ -108,8 +107,7 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - # shellcheck disable=SC2154 - if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then + if [ -z "$id" ] && [ -z "${SYNO_Create:?}" ]; then _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set" return 1 fi From eb49127b9ec75472c663eaaebb6370ab95a3f357 Mon Sep 17 00:00:00 2001 From: Blfrg Date: Sun, 9 Feb 2020 14:50:29 -0600 Subject: [PATCH 0625/2234] improve id parse Locate only the outer most "id" property --- dnsapi/dns_me.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 302603ea..db51cc7c 100644 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -114,7 +114,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\""; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+}$" | head -n 1 | cut -d : -f 2 | tr -d '}') + _domain_id=$(printf "%s\n" "$response" | cut -c 2- | head -c -2 | sed 's/{.*}//' | sed -r 's/^.*"id":([0-9]+).*$/\1/') if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" From 719b690451c9ec28f42bb7889fb1658f9efc0591 Mon Sep 17 00:00:00 2001 From: Arthur Wiebe Date: Mon, 10 Feb 2020 10:22:55 -0500 Subject: [PATCH 0626/2234] add support for using a Zone ID --- dnsapi/dns_cf.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 62e40caf..f29f0f51 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -7,6 +7,7 @@ #CF_Token="xxxx" #CF_Account_ID="xxxx" +#CF_Zone_ID="xxxx" CF_Api="https://api.cloudflare.com/client/v4" @@ -19,12 +20,14 @@ dns_cf_add() { CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" + CF_Zone_ID="${CF_Zone_ID:-$(_readaccountconf_mutable CF_Zone_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" if [ "$CF_Token" ]; then _saveaccountconf_mutable CF_Token "$CF_Token" _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" + _saveaccountconf_mutable CF_Zone_ID "$CF_Zone_ID" else if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then CF_Key="" @@ -141,6 +144,28 @@ _get_root() { domain=$1 i=1 p=1 + + # Use Zone ID directly if provided + if [ "$CF_Zone_ID" ]; then + if ! _cf_rest GET "zones/$CF_Zone_ID"; then + return 1 + else + if _contains "$response" '"success":true'; then + _domain=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + if [ "$_domain" ]; then + _cutlength=$(expr ${#domain} - ${#_domain} - 1) + _sub_domain=$(printf "%s" "$domain" | cut -c 1-$_cutlength) + _domain_id=$CF_Zone_ID + return 0 + else + return 1 + fi + else + return 1 + fi + fi + fi + while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug h "$h" From 1b475cf9f3997c27aae49ab578dd7070d9169b3d Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Mon, 10 Feb 2020 21:02:27 -0700 Subject: [PATCH 0627/2234] Remove -q from greps --- deploy/synology_dsm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index f1c08c36..0c2b1185 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -116,7 +116,7 @@ synology_dsm_deploy() { _savedeployconf SYNO_Certificate "$SYNO_Certificate" default=false - if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -q -- 'is_default":true'; then + if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then default=true fi _debug2 default "$default" @@ -138,8 +138,8 @@ synology_dsm_deploy() { response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" "" "POST" "multipart/form-data; boundary=${delim}") _debug3 response "$response" - if ! echo "$response" | grep -q '"error":'; then - if echo "$response" | grep -q '"restart_httpd":true'; then + if ! echo "$response" | grep '"error":' >/dev/null; then + if echo "$response" | grep '"restart_httpd":true' >/dev/null; then _info "http services were restarted" else _info "http services were NOT restarted" From d43227ede4fdc47f22abe971e647b3686678b607 Mon Sep 17 00:00:00 2001 From: Arthur Wiebe Date: Tue, 11 Feb 2020 13:07:10 -0500 Subject: [PATCH 0628/2234] fix shellcheck issues --- dnsapi/dns_cf.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index f29f0f51..2927ab4b 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -153,8 +153,8 @@ _get_root() { if _contains "$response" '"success":true'; then _domain=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) if [ "$_domain" ]; then - _cutlength=$(expr ${#domain} - ${#_domain} - 1) - _sub_domain=$(printf "%s" "$domain" | cut -c 1-$_cutlength) + _cutlength=$((${#domain} - ${#_domain} - 1)) + _sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cutlength") _domain_id=$CF_Zone_ID return 0 else From c2812896f8947c29117fe3a8b0832965aabdabeb Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Tue, 11 Feb 2020 18:15:10 -0800 Subject: [PATCH 0629/2234] Update deployer --- deploy/panos.sh | 114 +++++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 55 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 8a288e7b..ca03706f 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -13,61 +13,75 @@ # This function is to parse the XML parse_response() { - status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g') - message=$(echo "$1" | sed 's/^.*\(.*\)<\/result.*/\1/g') + type=$2 + if [ $type = 'keygen' ]; then + status=$(echo "$1" | sed 's/^.*\(['\'']\)\([a-z]*\)'\''.*/\2/g') + if [ "$status" = "success" ]; then + panos_key=$(echo "$1" | sed 's/^.*\(\)\(.*\)<\/key>.*/\2/g') + _panos_key=$panos_key + message='PAN-OS key is set.' + else + message="PAN-OS Key could not be set." + fi + else + status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g') + message=$(echo "$1" | sed 's/^.*\(.*\)<\/result.*/\1/g') + fi return 0 } deployer() { - type=$1 # Types are cert, key, commit + type=$1 # Types are keygen, cert, key, commit _debug "**** Deploying $type *****" - - #Generate DEIM - delim="-----MultipartDelimiter$(date "+%s%N")" - nl="\015\012" - #Set Header - _H1="Content-Type: multipart/form-data; boundary=$delim" - if [ $type = 'cert' ]; then - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" + panos_url="https://$_panos_host/api/" + + if [ $type = 'keygen' ]; then + _H1="Content-Type: application/x-www-form-urlencoded" + content="type=keygen&user=$_panos_user&password=$_panos_pass" + # content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}" fi - if [ $type = 'key' ]; then - #Add key - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" - fi - #Close multipart - content="$content${nl}--$delim--${nl}" - #Convert CRLF - content=$(printf %b "$content") - if [ $type = 'cert' ]; then - panos_url="https://$_panos_host/api/?type=import&category=certificate&certificate-name=$_cdomain&format=pem&key=$_panos_key" + if [ $type = 'cert' ] || [ $type = 'key' ]; then + #Generate DEIM + delim="-----MultipartDelimiter$(date "+%s%N")" + nl="\015\012" + #Set Header + _H1="Content-Type: multipart/form-data; boundary=$delim" + + if [ $type = 'cert' ]; then + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\ncertificate" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n\r\n$_panos_key" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\n\r\npem" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" + fi + if [ $type = 'key' ]; then + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\nprivate-key" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n\r\n$_panos_key" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\n\r\npem" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n\r\nnone" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" + fi + #Close multipart + content="$content${nl}--$delim--${nl}" + #Convert CRLF + content=$(printf %b "$content") + fi + + if [ $type = 'commit' ]; then + _H1="Content-Type: application/x-www-form-urlencoded" + cmd=$(printf "%s" "<$_panos_user>" | _url_encode) + content="type=commit&key=$_panos_key&cmd=$cmd" fi - if [ $type = 'key' ]; then - panos_url="https://$_panos_host/api/?type=import&category=private-key&certificate-name=$_cdomain&format=pem&passphrase=none&key=$_panos_key" - fi - if [ $type = 'commit' ]; then - cmd=$(_url_encode "<$_panos_user>") - panos_url="https://$_panos_host/api/?type=commit&cmd=$cmd&key=$_panos_key" - fi - - if [ $type = 'key' ] || [ $type = 'cert' ]; then - response=$(_post "$content" "$panos_url" "" "POST") - else - response=$(_get $panos_url) - fi - _debug panos_url $panos_url - _debug "RESPONSE $response" - parse_response "$response" - _debug "STATUS IS $status" - _debug "MESSAGE IS $message" + response=$(_post "$content" "$panos_url" "" "POST") + parse_response "$response" $type # Saving response to variables response_status=$status - # Check for cert upload error and handle gracefully. - #DEBUG - _debug header "$_H1" - # _debug content "$content" _debug response_status "$response_status" if [ "$response_status" = "success" ]; then _debug "Successfully deployed $type" @@ -121,18 +135,8 @@ panos_deploy() { return 1 else _debug "Getting PANOS KEY" - panos_key_response=$(_get "https://$_panos_host/api/?type=keygen&user=$_panos_user&password=$_panos_pass") - _debug "PANOS KEY FULL RESPONSE $panos_key_response" - status=$(echo "$panos_key_response" | sed 's/^.*\(['\'']\)\([a-z]*\)'\''.*/\2/g') - _debug "STATUS IS $status" - if [ "$status" = "success" ]; then - panos_key=$(echo "$panos_key_response" | sed 's/^.*\(\)\(.*\)<\/key>.*/\2/g') - _panos_key=$panos_key - else - _err "PANOS Key could not be set. Deploy with --debug to troubleshoot" - return 1 - fi - if [ -z "$_panos_host" ] && [ -z "$_panos_key" ] && [ -z "$_panos_user" ]; then + deployer keygen + if [ -z "$_panos_key" ]; then _err "Missing host, apikey, user." return 1 else From 71bc993e3ddf72d497b16a2a9ee598bcc0f92847 Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Tue, 11 Feb 2020 22:23:10 -0800 Subject: [PATCH 0630/2234] Fixed Shellchecks --- deploy/panos.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index ca03706f..b2c3b1d9 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -14,7 +14,7 @@ # This function is to parse the XML parse_response() { type=$2 - if [ $type = 'keygen' ]; then + if [ $type = "keygen" ]; then status=$(echo "$1" | sed 's/^.*\(['\'']\)\([a-z]*\)'\''.*/\2/g') if [ "$status" = "success" ]; then panos_key=$(echo "$1" | sed 's/^.*\(\)\(.*\)<\/key>.*/\2/g') @@ -35,20 +35,20 @@ deployer() { _debug "**** Deploying $type *****" panos_url="https://$_panos_host/api/" - if [ $type = 'keygen' ]; then + if [ $type = "keygen" ]; then _H1="Content-Type: application/x-www-form-urlencoded" content="type=keygen&user=$_panos_user&password=$_panos_pass" # content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}" fi - if [ $type = 'cert' ] || [ $type = 'key' ]; then + if [ $type = "cert" ] || [ $type = "key" ]; then #Generate DEIM delim="-----MultipartDelimiter$(date "+%s%N")" nl="\015\012" #Set Header - _H1="Content-Type: multipart/form-data; boundary=$delim" + export _H1="Content-Type: multipart/form-data; boundary=$delim" - if [ $type = 'cert' ]; then + if [ $type = "cert" ]; then content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\ncertificate" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain" @@ -56,7 +56,7 @@ deployer() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\n\r\npem" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" fi - if [ $type = 'key' ]; then + if [ $type = "key" ]; then content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\nprivate-key" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain" @@ -71,14 +71,14 @@ deployer() { content=$(printf %b "$content") fi - if [ $type = 'commit' ]; then - _H1="Content-Type: application/x-www-form-urlencoded" + if [ $type = "commit" ]; then + export _H1="Content-Type: application/x-www-form-urlencoded" cmd=$(printf "%s" "<$_panos_user>" | _url_encode) content="type=commit&key=$_panos_key&cmd=$cmd" fi response=$(_post "$content" "$panos_url" "" "POST") - parse_response "$response" $type + parse_response "$response" "$type" # Saving response to variables response_status=$status #DEBUG From 5dcb4176769321555f953f44a046258dc1096294 Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Tue, 11 Feb 2020 22:26:48 -0800 Subject: [PATCH 0631/2234] ShellCheck fixes --- deploy/panos.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index b2c3b1d9..8e00fd6c 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -14,7 +14,7 @@ # This function is to parse the XML parse_response() { type=$2 - if [ $type = "keygen" ]; then + if [ "$type" = 'keygen' ]; then status=$(echo "$1" | sed 's/^.*\(['\'']\)\([a-z]*\)'\''.*/\2/g') if [ "$status" = "success" ]; then panos_key=$(echo "$1" | sed 's/^.*\(\)\(.*\)<\/key>.*/\2/g') @@ -35,20 +35,20 @@ deployer() { _debug "**** Deploying $type *****" panos_url="https://$_panos_host/api/" - if [ $type = "keygen" ]; then + if [ "$type" = 'keygen' ]; then _H1="Content-Type: application/x-www-form-urlencoded" content="type=keygen&user=$_panos_user&password=$_panos_pass" # content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}" fi - if [ $type = "cert" ] || [ $type = "key" ]; then + if [ "$type" = 'cert' ] || [ "$type" = 'key' ]; then #Generate DEIM delim="-----MultipartDelimiter$(date "+%s%N")" nl="\015\012" #Set Header export _H1="Content-Type: multipart/form-data; boundary=$delim" - if [ $type = "cert" ]; then + if [ "$type" = 'cert' ]; then content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\ncertificate" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain" @@ -56,7 +56,7 @@ deployer() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\n\r\npem" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" fi - if [ $type = "key" ]; then + if [ "$type" = 'key' ]; then content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\nprivate-key" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain" @@ -71,7 +71,7 @@ deployer() { content=$(printf %b "$content") fi - if [ $type = "commit" ]; then + if [ "$type" = 'commit' ]; then export _H1="Content-Type: application/x-www-form-urlencoded" cmd=$(printf "%s" "<$_panos_user>" | _url_encode) content="type=commit&key=$_panos_key&cmd=$cmd" From cbdb8bd9b96a8370051f952806fa24dc13d80f9b Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Tue, 11 Feb 2020 22:34:55 -0800 Subject: [PATCH 0632/2234] Fixing gitdiff --- deploy/panos.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 8e00fd6c..c199caf4 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -42,11 +42,11 @@ deployer() { fi if [ "$type" = 'cert' ] || [ "$type" = 'key' ]; then - #Generate DEIM - delim="-----MultipartDelimiter$(date "+%s%N")" - nl="\015\012" - #Set Header - export _H1="Content-Type: multipart/form-data; boundary=$delim" + #Generate DEIM + delim="-----MultipartDelimiter$(date "+%s%N")" + nl="\015\012" + #Set Header + export _H1="Content-Type: multipart/form-data; boundary=$delim" if [ "$type" = 'cert' ]; then content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" @@ -76,7 +76,6 @@ deployer() { cmd=$(printf "%s" "<$_panos_user>" | _url_encode) content="type=commit&key=$_panos_key&cmd=$cmd" fi - response=$(_post "$content" "$panos_url" "" "POST") parse_response "$response" "$type" # Saving response to variables @@ -145,4 +144,4 @@ panos_deploy() { deployer commit fi fi -} \ No newline at end of file +} From 2077a70d03a548dfbb5501a5b4388948b93db9f7 Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Tue, 11 Feb 2020 22:44:51 -0800 Subject: [PATCH 0633/2234] Fixing gitdiff --- deploy/panos.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index c199caf4..3806f14f 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -34,7 +34,6 @@ deployer() { type=$1 # Types are keygen, cert, key, commit _debug "**** Deploying $type *****" panos_url="https://$_panos_host/api/" - if [ "$type" = 'keygen' ]; then _H1="Content-Type: application/x-www-form-urlencoded" content="type=keygen&user=$_panos_user&password=$_panos_pass" @@ -47,7 +46,6 @@ deployer() { nl="\015\012" #Set Header export _H1="Content-Type: multipart/form-data; boundary=$delim" - if [ "$type" = 'cert' ]; then content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\ncertificate" From 930e16b64a25e60fbb6998d3f27749a257111939 Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Tue, 11 Feb 2020 22:50:05 -0800 Subject: [PATCH 0634/2234] fix gitdiff --- deploy/panos.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 3806f14f..eaa19c89 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -19,7 +19,6 @@ parse_response() { if [ "$status" = "success" ]; then panos_key=$(echo "$1" | sed 's/^.*\(\)\(.*\)<\/key>.*/\2/g') _panos_key=$panos_key - message='PAN-OS key is set.' else message="PAN-OS Key could not be set." fi From 1fe3d80838d2aab564ad15aca7c2342b29e04f97 Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Wed, 12 Feb 2020 14:57:31 -0800 Subject: [PATCH 0635/2234] Updated to use saveconf function and base64encode. --- deploy/panos.sh | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index eaa19c89..627a59de 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -94,36 +94,31 @@ panos_deploy() { _cdomain="$1" _ckey="$2" _cfullchain="$5" - # PANOS HOST is required to make API calls to the PANOS/Panorama - if [ -z "$PANOS_HOST" ]; then - if [ -z "$_panos_host" ]; then - _err "PANOS_HOST not defined." - return 1 - fi - else - _debug "PANOS HOST is set. Save to domain conf." - _panos_host="$PANOS_HOST" - _savedomainconf _panos_host "$_panos_host" - fi - # Retrieve stored variables - _panos_user="$(_readaccountconf_mutable PANOS_USER)" - _panos_pass="$(_readaccountconf_mutable PANOS_PASS)" - # PANOS Credentials check - if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ]; then - _debug "PANOS_USER, PANOS_PASS is not defined" - if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ]; then - _err "No user and pass found in storage. If this is the first time deploying please set PANOS_USER and PANOS_PASS in environment variables." + + # PANOS ENV VAR check + if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ] || [ -z "$PANOS_HOST" ]; then + _debug "No ENV variables found lets check for saved variables" + _getdeployconf PANOS_USER + _getdeployconf PANOS_PASS + _getdeployconf PANOS_HOST + _panos_user=$PANOS_USER + _panos_pass=$PANOS_PASS + _panos_host=$PANOS_HOST + if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ] && [ -z "$_panos_host" ]; then + _err "No host, user and pass found.. If this is the first time deploying please set PANOS_HOST, PANOS_USER and PANOS_PASS in environment variables. Delete them after you have succesfully deployed certs." return 1 else - _debug "ok" + _debug "Using saved env variables." fi else - _debug "Saving environment variables" + _debug "Detected ENV variables to be saved to the deploy conf." # Encrypt and save user - _saveaccountconf_mutable PANOS_USER "$PANOS_USER" - _saveaccountconf_mutable PANOS_PASS "$PANOS_PASS" + _savedeployconf PANOS_USER "$PANOS_USER" 1 + _savedeployconf PANOS_PASS "$PANOS_PASS" 1 + _savedeployconf PANOS_HOST "$PANOS_HOST" 1 _panos_user="$PANOS_USER" _panos_pass="$PANOS_PASS" + _panos_host="$PANOS_HOST" fi _debug "Let's use username and pass to generate token." if [ -z "$_panos_user" ] || [ -z "$_panos_pass" ] || [ -z "$_panos_host" ]; then @@ -133,7 +128,7 @@ panos_deploy() { _debug "Getting PANOS KEY" deployer keygen if [ -z "$_panos_key" ]; then - _err "Missing host, apikey, user." + _err "Missing apikey." return 1 else deployer cert From c355b25bb1eea5fbf1b5d08185bc52032b60cabd Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Wed, 12 Feb 2020 15:00:23 -0800 Subject: [PATCH 0636/2234] Fixed line formatting --- deploy/panos.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 627a59de..a550d877 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -94,7 +94,6 @@ panos_deploy() { _cdomain="$1" _ckey="$2" _cfullchain="$5" - # PANOS ENV VAR check if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ] || [ -z "$PANOS_HOST" ]; then _debug "No ENV variables found lets check for saved variables" From 21450a08c27af39e3788526464c249a41c3db61f Mon Sep 17 00:00:00 2001 From: Paul Nguyen Date: Thu, 13 Feb 2020 18:01:27 -0800 Subject: [PATCH 0637/2234] Fixed 6 character requirement. --- deploy/panos.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index a550d877..6316784a 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -30,6 +30,7 @@ parse_response() { } deployer() { + content="" type=$1 # Types are keygen, cert, key, commit _debug "**** Deploying $type *****" panos_url="https://$_panos_host/api/" @@ -59,7 +60,7 @@ deployer() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n\r\n$_panos_key" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\n\r\npem" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n\r\nnone" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n\r\n123456" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" fi #Close multipart From 463df9e4ba25273cc9a9fe82d12c47ad412518af Mon Sep 17 00:00:00 2001 From: xpac1985 Date: Tue, 18 Feb 2020 16:26:15 +0100 Subject: [PATCH 0638/2234] Make socat debug output show version + features instead of help text --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index c9cd0d1c..3a01c13d 100755 --- a/acme.sh +++ b/acme.sh @@ -207,7 +207,7 @@ _dlg_versions() { echo "socat:" if _exists "socat"; then - socat -h 2>&1 + socat -V 2>&1 else _debug "socat doesn't exists." fi From f8662c9bc21329fc4f0481e50a27df81cb57c249 Mon Sep 17 00:00:00 2001 From: adrian5 Date: Thu, 20 Feb 2020 18:43:08 +0100 Subject: [PATCH 0639/2234] Fix phrasing in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d1c793d4..de674cbf 100644 --- a/README.md +++ b/README.md @@ -257,7 +257,7 @@ acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com **This apache mode is only to issue the cert, it will not change your apache config files. You will need to configure your website config files to use the cert by yourself. -We don't want to mess your apache server, don't worry.** +We don't want to mess with your apache server, don't worry.** More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert @@ -281,7 +281,7 @@ acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com **This nginx mode is only to issue the cert, it will not change your nginx config files. You will need to configure your website config files to use the cert by yourself. -We don't want to mess your nginx server, don't worry.** +We don't want to mess with your nginx server, don't worry.** More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert From e184a1b9e64f9985387cc402449f459a2b1e6649 Mon Sep 17 00:00:00 2001 From: xpac1985 Date: Thu, 20 Feb 2020 23:28:55 +0100 Subject: [PATCH 0640/2234] haproxy deploy script now compatible with OpenSSL v1.1+ haproxy deploy script now compatible with OpenSSL v1.1+ The OpenSSL OCSP request for haproxy deployment breaks from OpenSSL v1.1.0 on. The format of the `-header` option has been changed and does now contain a `=` instead of a whitespace. Other projects have hit the same issue: https://github.com/nghttp2/nghttp2/issues/742 This commit determines the OpenSSL/LibreSSL version and then adjusts the request accordingly. Also removed the duplicate command line and added some more debug output. --- deploy/haproxy.sh | 52 +++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 836c5182..3cd2a80a 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -208,33 +208,37 @@ haproxy_deploy() { _issuerdn=$(openssl x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) _debug _issuerdn "${_issuerdn}" _info "Requesting OCSP response" - # Request the OCSP response from the issuer and store it + # If the issuer is a CA cert then our command line has "-CAfile" added if [ "${_subjectdn}" = "${_issuerdn}" ]; then - # If the issuer is a CA cert then our command line has "-CAfile" added - openssl ocsp \ - -issuer "${_issuer}" \ - -cert "${_pem}" \ - -url "${_ocsp_url}" \ - -header Host "${_ocsp_host}" \ - -respout "${_ocsp}" \ - -verify_other "${_issuer}" \ - -no_nonce \ - -CAfile "${_issuer}" \ - | grep -q "${_pem}: good" - _ret=$? + _cafile_argument="-CAfile \"${_issuer}\"" else - # Issuer is not a root CA so no "-CAfile" option - openssl ocsp \ - -issuer "${_issuer}" \ - -cert "${_pem}" \ - -url "${_ocsp_url}" \ - -header Host "${_ocsp_host}" \ - -respout "${_ocsp}" \ - -verify_other "${_issuer}" \ - -no_nonce \ - | grep -q "${_pem}: good" - _ret=$? + _cafile_argument="" fi + _debug _cafile_argument "${_cafile_argument}" + # if OpenSSL/LibreSSL is v1.1 or above, the format for the -header option has changed + _openssl_version=$(openssl version | cut -d' ' -f2) + _debug _openssl_version "${_openssl_version}" + _openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1) + _openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2) + if [ "${_openssl_major}" -eq "1" ] && [ "${_openssl_minor}" -ge "1" ] || [ "${_openssl_major}" -ge "2" ]; then + _header_sep="=" + else + _header_sep=" " + fi + # Request the OCSP response from the issuer and store it + _openssl_ocsp_cmd="openssl ocsp \ + -issuer \"${_issuer}\" \ + -cert \"${_pem}\" \ + -url \"${_ocsp_url}\" \ + -header Host${_header_sep}\"${_ocsp_host}\" \ + -respout \"${_ocsp}\" \ + -verify_other \"${_issuer}\" \ + -no_nonce \ + ${_cafile_argument} \ + | grep -q \"${_pem}: good\"" + _debug _openssl_ocsp_cmd "${_openssl_ocsp_cmd}" + eval "${_openssl_ocsp_cmd}" + _ret=$? else # Non fatal: No issuer file was present so no OCSP stapling file created _err "OCSP stapling in use but no .issuer file was present" From 3d9608faa086890321ba8d9d630c5b659f89ed46 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 20:09:24 -0500 Subject: [PATCH 0641/2234] Move -T parameter into default ssh command variable --- deploy/ssh.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 9cb0af9e..783e6f7b 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -12,7 +12,7 @@ # Only a username is required. All others are optional. # # The following examples are for QNAP NAS running QTS 4.2 -# export DEPLOY_SSH_CMD="" # defaults to ssh +# export DEPLOY_SSH_CMD="" # defaults to "ssh -T" # export DEPLOY_SSH_USER="admin" # required # export DEPLOY_SSH_SERVER="qnap" # defaults to domain name # export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem" @@ -71,7 +71,7 @@ ssh_deploy() { Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD" _savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd" elif [ -z "$Le_Deploy_ssh_cmd" ]; then - Le_Deploy_ssh_cmd="ssh" + Le_Deploy_ssh_cmd="ssh -T" fi # BACKUP is optional. If not provided then default to yes @@ -194,7 +194,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _info "Submitting sequence of commands to remote server by ssh" # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 - $Le_Deploy_ssh_cmd -T "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'" + $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'" _ret="$?" if [ "$_ret" != "0" ]; then From 04771e5a4ae243cdc757b7d3159cef92fce40605 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 20:16:36 -0500 Subject: [PATCH 0642/2234] Move call to remote system into separate function --- deploy/ssh.sh | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 783e6f7b..8c83f0b3 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -31,6 +31,7 @@ ssh_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" + _err_code=0 _cmdstr="" _homedir='~' _backupprefix="$_homedir/.acme_ssh_deploy/$_cdomain-backup" @@ -190,16 +191,25 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _info "Backup directories erased after 180 days." fi - _secure_debug "Remote commands to execute: " "$_cmdstr" - _info "Submitting sequence of commands to remote server by ssh" - # quotations in bash cmd below intended. Squash travis spellcheck error - # shellcheck disable=SC2029 - $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'" - _ret="$?" - - if [ "$_ret" != "0" ]; then - _err "Error code $_ret returned from $Le_Deploy_ssh_cmd" + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code fi - return $_ret + return 0 +} + +#cmd +_ssh_remote_cmd() { + _secure_debug "Remote commands to execute: $_cmd" + _info "Submitting sequence of commands to remote server by $Le_Deploy_ssh_cmd" + # quotations in bash cmd below intended. Squash travis spellcheck error + # shellcheck disable=SC2029 + $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'" + _err_code="$?" + + if [ "$_err_code" != "0" ]; then + _err "Error code $_err_code returned from $Le_Deploy_ssh_cmd" + fi + + return $_err_code } From 6420d1239fda00fb5d40299bfbf1b22c4af4762f Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 20:31:52 -0500 Subject: [PATCH 0643/2234] Move call to remote system into separate function --- deploy/ssh.sh | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 783e6f7b..00d9d21d 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -31,6 +31,7 @@ ssh_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" + _err_code=0 _cmdstr="" _homedir='~' _backupprefix="$_homedir/.acme_ssh_deploy/$_cdomain-backup" @@ -190,16 +191,26 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _info "Backup directories erased after 180 days." fi - _secure_debug "Remote commands to execute: " "$_cmdstr" - _info "Submitting sequence of commands to remote server by ssh" - # quotations in bash cmd below intended. Squash travis spellcheck error - # shellcheck disable=SC2029 - $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'" - _ret="$?" - - if [ "$_ret" != "0" ]; then - _err "Error code $_ret returned from $Le_Deploy_ssh_cmd" + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code fi - return $_ret + return 0 +} + +#cmd +_ssh_remote_cmd() { + _cmd="$1" + _secure_debug "Remote commands to execute: $_cmd" + _info "Submitting sequence of commands to remote server by $Le_Deploy_ssh_cmd" + # quotations in bash cmd below intended. Squash travis spellcheck error + # shellcheck disable=SC2029 + $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'" + _err_code="$?" + + if [ "$_err_code" != "0" ]; then + _err "Error code $_err_code returned from $Le_Deploy_ssh_cmd" + fi + + return $_err_code } From 283b04df739dff70ed22ee20ffac6a1c576db842 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 20:43:28 -0500 Subject: [PATCH 0644/2234] Move cleanup of backup directory to first step in the function. --- deploy/ssh.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 00d9d21d..39a0a218 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -85,6 +85,19 @@ ssh_deploy() { _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" + if [ "$Le_Deploy_ssh_backup" = "yes" ]; then + # run cleanup on the backup directory, erase all older + # than 180 days (15552000 seconds). + _cmdstr="{ now=\"\$(date -u +%s)\"; for fn in $_backupprefix*; \ +do if [ -d \"\$fn\" ] && [ \"\$(expr \$now - \$(date -ur \$fn +%s) )\" -ge \"15552000\" ]; \ +then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; done; }; $_cmdstr" + # Alternate version of above... _cmdstr="find $_backupprefix* -type d -mtime +180 2>/dev/null | xargs rm -rf; $_cmdstr" + # Create our backup directory for overwritten cert files. + _cmdstr="mkdir -p $_backupdir; $_cmdstr" + _info "Backup of old certificate files will be placed in remote directory $_backupdir" + _info "Backup directories erased after 180 days." + fi + # KEYFILE is optional. # If provided then private key will be copied to provided filename. if [ -n "$DEPLOY_SSH_KEYFILE" ]; then @@ -178,17 +191,6 @@ ssh_deploy() { if [ -z "$_cmdstr" ]; then _err "No remote commands to excute. Failed to deploy certificates to remote server" return 1 - elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then - # run cleanup on the backup directory, erase all older - # than 180 days (15552000 seconds). - _cmdstr="{ now=\"\$(date -u +%s)\"; for fn in $_backupprefix*; \ -do if [ -d \"\$fn\" ] && [ \"\$(expr \$now - \$(date -ur \$fn +%s) )\" -ge \"15552000\" ]; \ -then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; done; }; $_cmdstr" - # Alternate version of above... _cmdstr="find $_backupprefix* -type d -mtime +180 2>/dev/null | xargs rm -rf; $_cmdstr" - # Create our backup directory for overwritten cert files. - _cmdstr="mkdir -p $_backupdir; $_cmdstr" - _info "Backup of old certificate files will be placed in remote directory $_backupdir" - _info "Backup directories erased after 180 days." fi if ! _ssh_remote_cmd "$_cmdstr"; then From cc820e97c6e7cea1d5de0165bd5b7b5d84249843 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 21:10:42 -0500 Subject: [PATCH 0645/2234] Add support for DEPLOY_SSH_BATCH_MODE with default of yes. Before this update all remote commands were bunched together and sent to the remote host in a single SSH command. This could result in a very long sequence of commands that might be rejected by a remote host (example is VMware ESXi that uses busybox sh). With this update you can set DEPLOY_SSH_BATCH_MODE="no" and each remote command is sent as a separate SSH call so now we do not have big long sequence of commands. Defaults to same behaviour as before this update. --- deploy/ssh.sh | 63 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 39a0a218..92aa43d9 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -21,6 +21,7 @@ # export DEPLOY_SSH_FULLCHAIN="" # export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes +# export DEPLOY_SSH_BATCH_MODE="yes" # yes or no, default to yes # ######## Public functions ##################### @@ -83,7 +84,20 @@ ssh_deploy() { fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" + # BATCH_MODE is optional. If not provided then default to yes + if [ "$DEPLOY_SSH_BATCH_MODE" = "no" ]; then + Le_Deploy_ssh_batch_mode="no" + elif [ -z "$Le_Deploy_ssh_batch_mode" ]; then + Le_Deploy_ssh_batch_mode="yes" + fi + _savedomainconf Le_Deploy_ssh_batch_mode "$Le_Deploy_ssh_batch_mode" + _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" + if [ "$Le_Deploy_ssh_batch_mode" = "yes" ]; then + _info "Using BATCH MODE... Multiple commands sent in single call to remote host" + else + _info "Commands sent individually in multiple calls to remote host" + fi if [ "$Le_Deploy_ssh_backup" = "yes" ]; then # run cleanup on the backup directory, erase all older @@ -96,6 +110,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _cmdstr="mkdir -p $_backupdir; $_cmdstr" _info "Backup of old certificate files will be placed in remote directory $_backupdir" _info "Backup directories erased after 180 days." + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # KEYFILE is optional. @@ -112,6 +132,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # CERTFILE is optional. @@ -132,6 +158,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # CAFILE is optional. @@ -153,6 +185,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # FULLCHAIN is optional. @@ -175,6 +213,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # REMOTE_CMD is optional. @@ -186,17 +230,20 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then _cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;" _info "Will execute remote command $Le_Deploy_ssh_remote_cmd" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi - if [ -z "$_cmdstr" ]; then - _err "No remote commands to excute. Failed to deploy certificates to remote server" - return 1 + # if running as batch mode then all commands sent in a single SSH call now... + if [ -n "$_cmdstr" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi fi - - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code - fi - return 0 } From 806b746fc0522bed79a1b51f3c0137a0fa721dc5 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 21:23:59 -0500 Subject: [PATCH 0646/2234] Fix bug where backup and batch_mode yes/no values could not be changed. Once set to "no" then they could never be set back to "yes" --- deploy/ssh.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 92aa43d9..113ae23e 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -79,7 +79,7 @@ ssh_deploy() { # BACKUP is optional. If not provided then default to yes if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then Le_Deploy_ssh_backup="no" - elif [ -z "$Le_Deploy_ssh_backup" ]; then + elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then Le_Deploy_ssh_backup="yes" fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" @@ -87,7 +87,7 @@ ssh_deploy() { # BATCH_MODE is optional. If not provided then default to yes if [ "$DEPLOY_SSH_BATCH_MODE" = "no" ]; then Le_Deploy_ssh_batch_mode="no" - elif [ -z "$Le_Deploy_ssh_batch_mode" ]; then + elif [ -z "$Le_Deploy_ssh_batch_mode" ] || [ "$DEPLOY_SSH_BATCH_MODE" = "yes" ]; then Le_Deploy_ssh_batch_mode="yes" fi _savedomainconf Le_Deploy_ssh_batch_mode "$Le_Deploy_ssh_batch_mode" From 46ee74ed1687bcc5dbb7732bf7483e6c793ec253 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 22:05:06 -0500 Subject: [PATCH 0647/2234] Remove variable from info/error printout that could potentially expose login credentials. --- deploy/ssh.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 113ae23e..b68dad7e 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -251,14 +251,14 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _ssh_remote_cmd() { _cmd="$1" _secure_debug "Remote commands to execute: $_cmd" - _info "Submitting sequence of commands to remote server by $Le_Deploy_ssh_cmd" + _info "Submitting sequence of commands to remote server by ssh" # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'" _err_code="$?" if [ "$_err_code" != "0" ]; then - _err "Error code $_err_code returned from $Le_Deploy_ssh_cmd" + _err "Error code $_err_code returned from ssh" fi return $_err_code From f73a49440790018aacff9e1d540c937f481cfc20 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 22:09:28 -0500 Subject: [PATCH 0648/2234] Remove spaces on blank line to fix travis error --- deploy/ssh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index b68dad7e..b3e040b3 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -91,7 +91,7 @@ ssh_deploy() { Le_Deploy_ssh_batch_mode="yes" fi _savedomainconf Le_Deploy_ssh_batch_mode "$Le_Deploy_ssh_batch_mode" - + _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" if [ "$Le_Deploy_ssh_batch_mode" = "yes" ]; then _info "Using BATCH MODE... Multiple commands sent in single call to remote host" From b64f0ba83f2a55c2a619f838d3f35ec512901fc8 Mon Sep 17 00:00:00 2001 From: Stephane Moser Date: Mon, 24 Feb 2020 23:14:40 +0000 Subject: [PATCH 0649/2234] Update usage of AWS_DNS_SLOWRATE --- dnsapi/dns_aws.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 4fab09e2..a3d0082e 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -20,10 +20,10 @@ AWS_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API dns_aws_add() { fulldomain=$1 txtvalue=$2 - slowrateslepp=$AWS_DNS_SLOWRATE AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}" AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}" + AWS_DNS_SLOWRATE="${AWS_DNS_SLOWRATE:-$(_readaccountconf_mutable AWS_DNS_SLOWRATE)}" if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then _use_container_role || _use_instance_role @@ -41,6 +41,7 @@ dns_aws_add() { if [ -z "$_using_role" ]; then _saveaccountconf_mutable AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID" _saveaccountconf_mutable AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY" + _saveaccountconf_mutable AWS_DNS_SLOWRATE "$AWS_DNS_SLOWRATE" fi _debug "First detect the root zone" @@ -78,9 +79,9 @@ dns_aws_add() { if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then _info "TXT record updated successfully." - if [ -n "$slowrateslepp" ]; then - _info "Slow rate activated: sleeping for $slowrateslepp seconds" - _sleep "$slowrateslepp" + if [ -n "$AWS_DNS_SLOWRATE" ]; then + _info "Slow rate activated: sleeping for $AWS_DNS_SLOWRATE seconds" + _sleep "$AWS_DNS_SLOWRATE" else _sleep 1 fi @@ -95,10 +96,10 @@ dns_aws_add() { dns_aws_rm() { fulldomain=$1 txtvalue=$2 - slowrateslepp=$AWS_DNS_SLOWRATE AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}" AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}" + AWS_DNS_SLOWRATE="${AWS_DNS_SLOWRATE:-$(_readaccountconf_mutable AWS_DNS_SLOWRATE)}" if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then _use_container_role || _use_instance_role @@ -133,9 +134,9 @@ dns_aws_rm() { if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then _info "TXT record deleted successfully." - if [ -n "$slowrateslepp" ]; then - _info "Slow rate activated: sleeping for $slowrateslepp seconds" - _sleep "$slowrateslepp" + if [ -n "$AWS_DNS_SLOWRATE" ]; then + _info "Slow rate activated: sleeping for $AWS_DNS_SLOWRATE seconds" + _sleep "$AWS_DNS_SLOWRATE" else _sleep 1 fi From 22f9a3b467095635b4ab755f6229888ff563f92b Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 25 Feb 2020 12:33:50 +0100 Subject: [PATCH 0650/2234] Fix error on docker deploy command with spaces. This adds quotes to the last eval in _getdeployconf which is reponsible for loading and exporting saved environment variables back into the acme.sh process. This caused some errors if used with the docker deploy-hook and the example nginx "service nginx force-reload" command as it contains spaces. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3a01c13d..283b0a39 100755 --- a/acme.sh +++ b/acme.sh @@ -2166,7 +2166,7 @@ _getdeployconf() { return 0 # do nothing fi _saved=$(_readdomainconf "SAVED_$_rac_key") - eval "export $_rac_key=$_saved" + eval "export $_rac_key=\"$_saved\"" } #_saveaccountconf key value base64encode From 8ba573d1967e13dcdc03631308f5dbdd3acf565c Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Tue, 3 Mar 2020 13:40:33 -0500 Subject: [PATCH 0651/2234] Change variable name to MULTI_CALL so default can be "no" --- deploy/ssh.sh | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index b3e040b3..7eed8a34 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -21,7 +21,7 @@ # export DEPLOY_SSH_FULLCHAIN="" # export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes -# export DEPLOY_SSH_BATCH_MODE="yes" # yes or no, default to yes +# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no # ######## Public functions ##################### @@ -84,19 +84,19 @@ ssh_deploy() { fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" - # BATCH_MODE is optional. If not provided then default to yes - if [ "$DEPLOY_SSH_BATCH_MODE" = "no" ]; then - Le_Deploy_ssh_batch_mode="no" - elif [ -z "$Le_Deploy_ssh_batch_mode" ] || [ "$DEPLOY_SSH_BATCH_MODE" = "yes" ]; then - Le_Deploy_ssh_batch_mode="yes" + # MULTI_CALL is optional. If not provided then default to no + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then + Le_Deploy_ssh_multi_call="yes" + elif [ -z "$Le_Deploy_ssh_multi_call" ] || [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then + Le_Deploy_ssh_multi_call="no" fi - _savedomainconf Le_Deploy_ssh_batch_mode "$Le_Deploy_ssh_batch_mode" + _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" - if [ "$Le_Deploy_ssh_batch_mode" = "yes" ]; then - _info "Using BATCH MODE... Multiple commands sent in single call to remote host" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" else - _info "Commands sent individually in multiple calls to remote host" + _info "Required commands batched and sent in single call to remote host" fi if [ "$Le_Deploy_ssh_backup" = "yes" ]; then @@ -110,7 +110,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _cmdstr="mkdir -p $_backupdir; $_cmdstr" _info "Backup of old certificate files will be placed in remote directory $_backupdir" _info "Backup directories erased after 180 days." - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -132,7 +132,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -158,7 +158,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -185,7 +185,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -213,7 +213,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -230,7 +230,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then _cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;" _info "Will execute remote command $Le_Deploy_ssh_remote_cmd" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -238,7 +238,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # if running as batch mode then all commands sent in a single SSH call now... + # if commands not all sent in multiple calls then all commands sent in a single SSH call now... if [ -n "$_cmdstr" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code From 72e1a1b2e9973dc65dd74514e75f30687248d781 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Wed, 4 Mar 2020 09:12:28 +1100 Subject: [PATCH 0652/2234] Update account.json on account update When running --updateaccount, the ca//account.json file isn't updated with the new response showing the updated account details. This can be a bit confusing if you add an email to the account but then you're not sure if it actually applied looking at this file. Write out the new response on successful account updates. --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index 283b0a39..1f4d3687 100755 --- a/acme.sh +++ b/acme.sh @@ -3518,6 +3518,7 @@ updateaccount() { _send_signed_request "$_accUri" "$updjson" if [ "$code" = '200' ]; then + echo "$response" >"$ACCOUNT_JSON_PATH" _info "account update success for $_accUri." else _info "Error. The account was not updated." From 69b11575e38cbafb84686831f81e151affabca5b Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 4 Mar 2020 09:51:16 +0800 Subject: [PATCH 0653/2234] add clearlinux fix https://github.com/acmesh-official/acme.sh/issues/2768 --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index de674cbf..249dc85f 100644 --- a/README.md +++ b/README.md @@ -52,11 +52,11 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |4|[![](https://acmesh-official.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) |5|[![](https://acmesh-official.github.io/acmetest/status/freebsd.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|FreeBSD |6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|pfsense -|7|[![](https://acmesh-official.github.io/acmetest/status/opensuse-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|openSUSE +|7|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|openSUSE |8|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Alpine Linux (with curl) -|9|[![](https://acmesh-official.github.io/acmetest/status/base-archlinux.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Archlinux +|9|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Archlinux |10|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|fedora -|11|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali-linux-docker.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Kali Linux +|11|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Kali Linux |12|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Oracle Linux |13|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh |14|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 @@ -66,6 +66,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|SunOS/Solaris |19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Gentoo Linux |20|[![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh)|Mac OSX +|21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|ClearLinux For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): From f84a87f2a2d3697280b22e49b55f470af368d04f Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 7 Mar 2020 18:26:22 +0800 Subject: [PATCH 0654/2234] remove DEFAULT_DNS_SLEEP. fix https://github.com/acmesh-official/acme.sh/issues/2773 --- acme.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 283b0a39..eb5c78b2 100755 --- a/acme.sh +++ b/acme.sh @@ -48,7 +48,6 @@ LOCAL_ANY_ADDRESS="0.0.0.0" DEFAULT_RENEW=60 -DEFAULT_DNS_SLEEP=120 NO_VALUE="no" @@ -6223,7 +6222,7 @@ Parameters: --stateless Use stateless mode, see: $_STATELESS_WIKI --apache Use apache mode. --dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api. - --dnssleep [$DEFAULT_DNS_SLEEP] The time in seconds to wait for all the txt records to take effect in dns api mode. Default $DEFAULT_DNS_SLEEP seconds. + --dnssleep 300 The time in seconds to wait for all the txt records to take effect in dns api mode. It's not necessary to use this by default, $PROJECT_NAME polls dns status automatically. --keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. --accountkeylength, -ak [2048] Specifies the account key length: 2048, 3072, 4096 From f21ef0d2e9ee0a6cbb020dc1cf3edbe0f615c1c6 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 14:55:09 +0100 Subject: [PATCH 0655/2234] add support for namemaster.de --- dnsapi/dns_nm.sh | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 dnsapi/dns_nm.sh diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh new file mode 100644 index 00000000..53c0c768 --- /dev/null +++ b/dnsapi/dns_nm.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env sh + +######################################################################## +# https://namemaster.de hook script for acme.sh +# +# Environment variables: +# +# - $NM_user (your namemaster.de API username) +# - $NM_md5 (your namemaster.de API password_as_md5hash) +# +# Author: Thilo Gass +# Git repo: https://github.com/ThiloGa/acme.sh + +#-- dns_nm_add() - Add TXT record -------------------------------------- +# Usage: dns_nm_add _acme-challenge.subdomain.domain.com "XyZ123..." + +dns_nm_add() { + fulldomain=$1 + txt_value=$2 + _info "Using DNS-01 namemaster hook" + + NM_user="${NM_user:-$(_readaccountconf_mutable NM_user)}" + NM_md5="${NM_md5:-$(_readaccountconf_mutable NM_md5)}" + if [ -z "$NM_user" ] || [ -z "$NM_md5" ]; then + NM_user="" + NM_md5="" + _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables." + return 1 + fi + #save the api user and md5 password to the account conf file. + _debug "Save user and hash" + _saveaccountconf_mutable NM_user "$NM_user" + _saveaccountconf_mutable NM_md5 "$NM_md5" + + + zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" + get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=ACME&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" + erg="$(_get "$get")" + + if [ "$?" != "0" ]; then + _err "error $action $zone TXT: $txt" + _err "Error $?" + return 1 + fi + + if _contains "$erg" "Success"; then + _info "Success, TXT Added, OK" + else + _err "error Auto $zone TXT: $txt erg: $erg" + return 1 + fi + + _debug "ok Auto $zone TXT: $txt erg: $erg" + return 0 +} + +dns_nm_rm() { + +fulldomain=$1 +txt_value=$2 + + NM_user="${NM_user:-$(_readaccountconf_mutable NM_user)}" + NM_md5="${NM_md5:-$(_readaccountconf_mutable NM_md5)}" + if [ -z "$NM_user" ] || [ -z "$NM_md5" ]; then + NM_user="" + NM_md5="" + _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables." + return 1 + fi + + zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" + get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN&TTL=0" + erg="$(_get "$get")" + if [ "$?" != "0" ]; then + _err "error $action $zone TXT: $txt" + _err "Error $?" + return 1 + fi + +if _contains "$erg" "Success"; then + _info "Success, TXT removed, OK" + +else + _err "error Auto $zone TXT: $txt erg: $erg" + return 1 +fi + +_debug "ok Auto $zone TXT: $txt erg: $erg" +return 0 + + +} From 30416f54d169fbf391df1dffbea939003f69acd0 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 15:18:25 +0100 Subject: [PATCH 0656/2234] Fixes for Travis CI -removing some blanks etc. --- dnsapi/dns_nm.sh | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 53c0c768..b7e2d498 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -18,29 +18,28 @@ dns_nm_add() { fulldomain=$1 txt_value=$2 _info "Using DNS-01 namemaster hook" - + NM_user="${NM_user:-$(_readaccountconf_mutable NM_user)}" NM_md5="${NM_md5:-$(_readaccountconf_mutable NM_md5)}" if [ -z "$NM_user" ] || [ -z "$NM_md5" ]; then NM_user="" NM_md5="" - _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables." + _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables." return 1 fi #save the api user and md5 password to the account conf file. _debug "Save user and hash" _saveaccountconf_mutable NM_user "$NM_user" _saveaccountconf_mutable NM_md5 "$NM_md5" - - + zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=ACME&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" erg="$(_get "$get")" if [ "$?" != "0" ]; then - _err "error $action $zone TXT: $txt" + _err "error Auto $zone TXT: $txt" _err "Error $?" - return 1 + return 1 fi if _contains "$erg" "Success"; then @@ -56,15 +55,15 @@ dns_nm_add() { dns_nm_rm() { -fulldomain=$1 -txt_value=$2 + fulldomain=$1 + txt_value=$2 NM_user="${NM_user:-$(_readaccountconf_mutable NM_user)}" NM_md5="${NM_md5:-$(_readaccountconf_mutable NM_md5)}" if [ -z "$NM_user" ] || [ -z "$NM_md5" ]; then NM_user="" NM_md5="" - _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables." + _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables." return 1 fi @@ -73,20 +72,19 @@ txt_value=$2 erg="$(_get "$get")" if [ "$?" != "0" ]; then _err "error $action $zone TXT: $txt" - _err "Error $?" + _err "Error $?" return 1 fi -if _contains "$erg" "Success"; then - _info "Success, TXT removed, OK" + if _contains "$erg" "Success"; then + _info "Success, TXT removed, OK" + else + _err "error Auto $zone TXT: $txt erg: $erg" + return 1 + fi -else - _err "error Auto $zone TXT: $txt erg: $erg" - return 1 -fi - -_debug "ok Auto $zone TXT: $txt erg: $erg" -return 0 + _debug "ok Auto $zone TXT: $txt erg: $erg" + return 0 } From 3b01bf7bda9e2d05db2bc7e1f2a25d9233c0d021 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 15:33:21 +0100 Subject: [PATCH 0657/2234] removed the probably last blank line --- dnsapi/dns_nm.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index b7e2d498..9928270b 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -37,7 +37,7 @@ dns_nm_add() { erg="$(_get "$get")" if [ "$?" != "0" ]; then - _err "error Auto $zone TXT: $txt" + _err "error Auto $zone TXT: $txt_value" _err "Error $?" return 1 fi @@ -45,11 +45,11 @@ dns_nm_add() { if _contains "$erg" "Success"; then _info "Success, TXT Added, OK" else - _err "error Auto $zone TXT: $txt erg: $erg" + _err "error Auto $zone TXT: $txt_value erg: $erg" return 1 fi - _debug "ok Auto $zone TXT: $txt erg: $erg" + _debug "ok Auto $zone TXT: $txt_value erg: $erg" return 0 } @@ -71,7 +71,7 @@ dns_nm_rm() { get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN&TTL=0" erg="$(_get "$get")" if [ "$?" != "0" ]; then - _err "error $action $zone TXT: $txt" + _err "error $action $zone TXT: $txt_value" _err "Error $?" return 1 fi @@ -79,12 +79,11 @@ dns_nm_rm() { if _contains "$erg" "Success"; then _info "Success, TXT removed, OK" else - _err "error Auto $zone TXT: $txt erg: $erg" + _err "error Auto $zone TXT: $txt_value erg: $erg" return 1 fi - _debug "ok Auto $zone TXT: $txt erg: $erg" + _debug "ok Auto $zone TXT: $txt_value erg: $erg" return 0 - } From 142ca58d387c248ca34fec45efcc08bc981e62df Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 15:45:41 +0100 Subject: [PATCH 0658/2234] removed some unused Vars --- acme.sh | 1 - dnsapi/dns_nm.sh | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 12f2cbed..4d9a7c25 100755 --- a/acme.sh +++ b/acme.sh @@ -48,7 +48,6 @@ LOCAL_ANY_ADDRESS="0.0.0.0" DEFAULT_RENEW=60 - NO_VALUE="no" W_DNS="dns" diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 9928270b..4c3f6c44 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -37,7 +37,7 @@ dns_nm_add() { erg="$(_get "$get")" if [ "$?" != "0" ]; then - _err "error Auto $zone TXT: $txt_value" + _err "error Ading $zone TXT: $txt_value" _err "Error $?" return 1 fi @@ -45,7 +45,7 @@ dns_nm_add() { if _contains "$erg" "Success"; then _info "Success, TXT Added, OK" else - _err "error Auto $zone TXT: $txt_value erg: $erg" + _err "error Adding $zone TXT: $txt_value erg: $erg" return 1 fi @@ -71,7 +71,7 @@ dns_nm_rm() { get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN&TTL=0" erg="$(_get "$get")" if [ "$?" != "0" ]; then - _err "error $action $zone TXT: $txt_value" + _err "error Deleting $zone TXT: $txt_value" _err "Error $?" return 1 fi From e1e1ee31f07d28d460be4677f3ef75221fe3aa38 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 16:00:52 +0100 Subject: [PATCH 0659/2234] Dont use $? directly anymore --- dnsapi/dns_nm.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 4c3f6c44..7ba5ce3c 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -36,9 +36,10 @@ dns_nm_add() { get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=ACME&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" erg="$(_get "$get")" - if [ "$?" != "0" ]; then + exit_code="$?" + if [ "$exit_code" != 0 ]; then _err "error Ading $zone TXT: $txt_value" - _err "Error $?" + _err "Error $exit_code" return 1 fi @@ -70,9 +71,11 @@ dns_nm_rm() { zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN&TTL=0" erg="$(_get "$get")" - if [ "$?" != "0" ]; then + + exit_code="$?" + if [ "$exit_code" != "0" ]; then _err "error Deleting $zone TXT: $txt_value" - _err "Error $?" + _err "Error $exit_code?" return 1 fi From efef76d9cf2edd8711bd15d795942647a780e889 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 19:34:57 +0100 Subject: [PATCH 0660/2234] fixed typo --- dnsapi/dns_nm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 7ba5ce3c..ec0e2d88 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -75,7 +75,7 @@ dns_nm_rm() { exit_code="$?" if [ "$exit_code" != "0" ]; then _err "error Deleting $zone TXT: $txt_value" - _err "Error $exit_code?" + _err "Error $exit_code" return 1 fi From 7d7e9501facc62f89618c2ad12963a57de253e82 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 20:37:29 +0100 Subject: [PATCH 0661/2234] fixing https://github.com/koalaman/shellcheck/wiki/SC2181 problems --- dnsapi/dns_nm.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index ec0e2d88..af98bbe3 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -34,11 +34,10 @@ dns_nm_add() { zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=ACME&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" - erg="$(_get "$get")" - exit_code="$?" - if [ "$exit_code" != 0 ]; then - _err "error Ading $zone TXT: $txt_value" + if ! erg="$(_get "$get")" + then + _err "error Deleting $zone TXT: $txt_value" _err "Error $exit_code" return 1 fi @@ -70,10 +69,9 @@ dns_nm_rm() { zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN&TTL=0" - erg="$(_get "$get")" - exit_code="$?" - if [ "$exit_code" != "0" ]; then + if ! erg="$(_get "$get")" + then _err "error Deleting $zone TXT: $txt_value" _err "Error $exit_code" return 1 From 20702d26ec1dc48aa228052d4703d4569e0c2dcc Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 21:05:42 +0100 Subject: [PATCH 0662/2234] fixing https://github.com/koalaman/shellcheck/wiki/SC2181 problems --- dnsapi/dns_nm.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index af98bbe3..090101e3 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -35,8 +35,7 @@ dns_nm_add() { zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=ACME&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" - if ! erg="$(_get "$get")" - then + if ! erg="$(_get "$get")"; then _err "error Deleting $zone TXT: $txt_value" _err "Error $exit_code" return 1 @@ -70,8 +69,7 @@ dns_nm_rm() { zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN&TTL=0" - if ! erg="$(_get "$get")" - then + if ! erg="$(_get "$get")"; then _err "error Deleting $zone TXT: $txt_value" _err "Error $exit_code" return 1 From d8dbb85946527ee377eaae82dc9876fd88c7adc9 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 21:11:08 +0100 Subject: [PATCH 0663/2234] small fixes --- dnsapi/dns_nm.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 090101e3..74ffd6f2 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -37,7 +37,6 @@ dns_nm_add() { if ! erg="$(_get "$get")"; then _err "error Deleting $zone TXT: $txt_value" - _err "Error $exit_code" return 1 fi @@ -50,6 +49,7 @@ dns_nm_add() { _debug "ok Auto $zone TXT: $txt_value erg: $erg" return 0 + } dns_nm_rm() { @@ -71,7 +71,6 @@ dns_nm_rm() { if ! erg="$(_get "$get")"; then _err "error Deleting $zone TXT: $txt_value" - _err "Error $exit_code" return 1 fi From 3c79bb77db87fd3e94b0b8431cf65d8469b4dd90 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 7 Mar 2020 21:21:39 +0100 Subject: [PATCH 0664/2234] fixing travis-ci warnings SC2086: Double quote to prevent globbing and word splitting. --- dnsapi/dns_nm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 74ffd6f2..f5b0bd0e 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -32,7 +32,7 @@ dns_nm_add() { _saveaccountconf_mutable NM_user "$NM_user" _saveaccountconf_mutable NM_md5 "$NM_md5" - zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" + zone="$(echo "$fulldomain" | _egrep_o "[^.]+.[^.]+$")" get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=ACME&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" if ! erg="$(_get "$get")"; then @@ -66,7 +66,7 @@ dns_nm_rm() { return 1 fi - zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")" + zone="$(echo "$fulldomain" | _egrep_o "[^.]+.[^.]+$")" get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN&TTL=0" if ! erg="$(_get "$get")"; then From ea652c023e75344e408f698b4a8687bf46fc3658 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 8 Mar 2020 10:17:21 +0800 Subject: [PATCH 0665/2234] fix https://github.com/acmesh-official/acme.sh/issues/2778 --- dnsapi/dns_inwx.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index f4590cf8..7c08d72e 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -55,6 +55,7 @@ dns_inwx_rm() { INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}" INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}" + INWX_Shared_Secret="${INWX_Shared_Secret:-$(_readaccountconf_mutable INWX_Shared_Secret)}" if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then INWX_User="" INWX_Password="" @@ -63,10 +64,6 @@ dns_inwx_rm() { return 1 fi - #save the api key and email to the account conf file. - _saveaccountconf_mutable INWX_User "$INWX_User" - _saveaccountconf_mutable INWX_Password "$INWX_Password" - _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" From 15b841da06e0f2babf639103e7d0d5615a8d9f7b Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 8 Mar 2020 04:47:55 +0100 Subject: [PATCH 0666/2234] Feat: simplify conditions for bin and command --- notify/mail.sh | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index ec9aa0de..f992cd4b 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -76,17 +76,16 @@ mail_send() { } _mail_bin() { - if [ -n "$MAIL_BIN" ]; then - _MAIL_BIN="$MAIL_BIN" - elif _exists "sendmail"; then - _MAIL_BIN="sendmail" - elif _exists "ssmtp"; then - _MAIL_BIN="ssmtp" - elif _exists "mutt"; then - _MAIL_BIN="mutt" - elif _exists "mail"; then - _MAIL_BIN="mail" - else + _MAIL_BIN="" + + for b in "$MAIL_BIN" sendmail ssmtp mutt mail; do + if _exists "$b"; then + _MAIL_BIN="$b" + break + fi + done + + if [ -z "$_MAIL_BIN" ]; then _err "Please install sendmail, ssmtp, mutt or mail first." return 1 fi @@ -95,25 +94,22 @@ _mail_bin() { } _mail_cmnd() { + _MAIL_ARGS="" + case $(basename "$_MAIL_BIN") in sendmail) if [ -n "$MAIL_FROM" ]; then - echo "'$_MAIL_BIN' -f '$MAIL_FROM' '$MAIL_TO'" - else - echo "'$_MAIL_BIN' '$MAIL_TO'" + _MAIL_ARGS="-f '$MAIL_FROM'" fi ;; - ssmtp) - echo "'$_MAIL_BIN' '$MAIL_TO'" - ;; mutt | mail) - echo "'$_MAIL_BIN' -s '$_subject' '$MAIL_TO'" + _MAIL_ARGS="-s '$_subject'" ;; *) - _err "Command $MAIL_BIN is not supported, use sendmail, ssmtp, mutt or mail." - return 1 ;; esac + + echo "'$_MAIL_BIN' $_MAIL_ARGS '$MAIL_TO'" } _mail_body() { From 80f1034dd6d9c0635ce8820453130654be3798de Mon Sep 17 00:00:00 2001 From: Markus Lippert Date: Sun, 8 Mar 2020 19:49:46 +0100 Subject: [PATCH 0667/2234] add OTP support --- deploy/synology_dsm.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 0c2b1185..23e97f24 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -15,6 +15,7 @@ # SYNO_Scheme - defaults to http # SYNO_Hostname - defaults to localhost # SYNO_Port - defaults to 5000 +# SYNO_DID - device ID to skip OTP - defaults to empty # #returns 0 means success, otherwise error. @@ -79,7 +80,7 @@ synology_dsm_deploy() { # Login, get the token from JSON and session id from cookie _info "Logging into $SYNO_Hostname:$SYNO_Port" - response=$(_get "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes") + response=$(_get "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes&device_id=$SYNO_DID") token=$(echo "$response" | grep "SynoToken" | sed -n 's/.*"SynoToken" *: *"\([^"]*\).*/\1/p') _debug3 response "$response" From fd64c20807978d576cd3fcfb484f930e9ca406d7 Mon Sep 17 00:00:00 2001 From: Markus Lippert Date: Sun, 8 Mar 2020 20:22:31 +0100 Subject: [PATCH 0668/2234] store device ID --- deploy/synology_dsm.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 23e97f24..5aef3b93 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -39,6 +39,7 @@ synology_dsm_deploy() { _getdeployconf SYNO_Username _getdeployconf SYNO_Password _getdeployconf SYNO_Create + _getdeployconf SYNO_DID if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" @@ -100,6 +101,7 @@ synology_dsm_deploy() { # Now that we know the username and password are good, save them _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" + _savedeployconf SYNO_DID "$SYNO_DID" _debug token "$token" _info "Getting certificates in Synology DSM" From c25b4ba0991f083634063a076b51f7d71f004b97 Mon Sep 17 00:00:00 2001 From: Jeremiah Date: Sun, 8 Mar 2020 15:39:18 -0600 Subject: [PATCH 0669/2234] dns_me id parse using only sed --- dnsapi/dns_me.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index db51cc7c..3a01f803 100644 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -114,7 +114,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\""; then - _domain_id=$(printf "%s\n" "$response" | cut -c 2- | head -c -2 | sed 's/{.*}//' | sed -r 's/^.*"id":([0-9]+).*$/\1/') + _domain_id=$(printf "%s\n" "$response" | sed 's/^{//; s/}$//; s/{.*}//' | sed -E 's/^.*"id":([0-9]+).*$/\1/') if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" From 3d8164113916a54db1f266ca34f13eb60d5a0ceb Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 9 Mar 2020 19:04:32 +0800 Subject: [PATCH 0670/2234] fix format --- acme.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/acme.sh b/acme.sh index 12f2cbed..4d9a7c25 100755 --- a/acme.sh +++ b/acme.sh @@ -48,7 +48,6 @@ LOCAL_ANY_ADDRESS="0.0.0.0" DEFAULT_RENEW=60 - NO_VALUE="no" W_DNS="dns" From 5d881a8b0ff8dc5db10a4da1379113e7163ea155 Mon Sep 17 00:00:00 2001 From: Jeremiah Date: Mon, 9 Mar 2020 11:34:50 -0600 Subject: [PATCH 0671/2234] use more compatible regex flag --- dnsapi/dns_me.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 3a01f803..49007402 100644 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -114,7 +114,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\""; then - _domain_id=$(printf "%s\n" "$response" | sed 's/^{//; s/}$//; s/{.*}//' | sed -E 's/^.*"id":([0-9]+).*$/\1/') + _domain_id=$(printf "%s\n" "$response" | sed 's/^{//; s/}$//; s/{.*}//' | sed -r 's/^.*"id":([0-9]+).*$/\1/') if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" From 554e083f3d387baacbc151b98463efc697091706 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Wed, 11 Mar 2020 10:58:36 -0400 Subject: [PATCH 0672/2234] For MULTI_CALL default to undefined, deleting entry in config file if set to "no" --- deploy/ssh.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 7eed8a34..5d1ee805 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -20,8 +20,8 @@ # export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem" # export DEPLOY_SSH_FULLCHAIN="" # export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" -# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes -# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no +# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value +# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value # ######## Public functions ##################### @@ -76,7 +76,7 @@ ssh_deploy() { Le_Deploy_ssh_cmd="ssh -T" fi - # BACKUP is optional. If not provided then default to yes + # BACKUP is optional. If not provided then default to previously saved value or yes. if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then Le_Deploy_ssh_backup="no" elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then @@ -84,13 +84,15 @@ ssh_deploy() { fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" - # MULTI_CALL is optional. If not provided then default to no + # MULTI_CALL is optional. If not provided then default to previously saved + # value (which may be undefined... equivalent to "no"). if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then Le_Deploy_ssh_multi_call="yes" - elif [ -z "$Le_Deploy_ssh_multi_call" ] || [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then - Le_Deploy_ssh_multi_call="no" + _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then + Le_Deploy_ssh_multi_call="" + _cleardomainconf Le_Deploy_ssh_multi_call fi - _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then From 2a8746f6b0702238b28a69a79e8fe4d05ffcaddc Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 8 Mar 2020 04:51:39 +0100 Subject: [PATCH 0673/2234] Feat: add msmtp command --- notify/mail.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index f992cd4b..54b2a6d4 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -6,6 +6,7 @@ #MAIL_FROM="yyyy@gmail.com" #MAIL_TO="yyyy@gmail.com" #MAIL_NOVALIDATE="" +#MAIL_MSMTP_ACCOUNT="" mail_send() { _subject="$1" @@ -78,7 +79,7 @@ mail_send() { _mail_bin() { _MAIL_BIN="" - for b in "$MAIL_BIN" sendmail ssmtp mutt mail; do + for b in "$MAIL_BIN" sendmail ssmtp mutt mail msmtp; do if _exists "$b"; then _MAIL_BIN="$b" break @@ -86,7 +87,7 @@ _mail_bin() { done if [ -z "$_MAIL_BIN" ]; then - _err "Please install sendmail, ssmtp, mutt or mail first." + _err "Please install sendmail, ssmtp, mutt, mail or msmtp first." return 1 fi @@ -105,8 +106,16 @@ _mail_cmnd() { mutt | mail) _MAIL_ARGS="-s '$_subject'" ;; - *) + msmtp) + if [ -n "$MAIL_FROM" ]; then + _MAIL_ARGS="-f '$MAIL_FROM'" + fi + + if [ -n "$MAIL_MSMTP_ACCOUNT" ]; then + _MAIL_ARGS="$_MAIL_ARGS -a '$MAIL_MSMTP_ACCOUNT'" + fi ;; + *) ;; esac echo "'$_MAIL_BIN' $_MAIL_ARGS '$MAIL_TO'" @@ -114,7 +123,7 @@ _mail_cmnd() { _mail_body() { case $(basename "$_MAIL_BIN") in - sendmail | ssmtp) + sendmail | ssmtp | msmtp) if [ -n "$MAIL_FROM" ]; then echo "From: $MAIL_FROM" fi From f38df4df1151822d50628be22f27ab3eb20429f4 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 14 Mar 2020 21:51:21 -0400 Subject: [PATCH 0674/2234] Make remote backup directory path user configurable. --- deploy/ssh.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 5d1ee805..d71637a1 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -21,6 +21,7 @@ # export DEPLOY_SSH_FULLCHAIN="" # export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value +# export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy # export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value # ######## Public functions ##################### @@ -34,9 +35,8 @@ ssh_deploy() { _cfullchain="$5" _err_code=0 _cmdstr="" - _homedir='~' - _backupprefix="$_homedir/.acme_ssh_deploy/$_cdomain-backup" - _backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')" + _backupprefix="" + _backupdir="" if [ -f "$DOMAIN_CONF" ]; then # shellcheck disable=SC1090 @@ -84,6 +84,14 @@ ssh_deploy() { fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" + # BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy + if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then + Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH" + elif [ -z "$Le_Deploy_ssh_backup_path" ]; then + Le_Deploy_ssh_backup_path=".acme_ssh_deploy" + fi + _savedomainconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path" + # MULTI_CALL is optional. If not provided then default to previously saved # value (which may be undefined... equivalent to "no"). if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then @@ -102,6 +110,8 @@ ssh_deploy() { fi if [ "$Le_Deploy_ssh_backup" = "yes" ]; then + _backupprefix="$Le_Deploy_ssh_backup_path/$_cdomain-backup" + _backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')" # run cleanup on the backup directory, erase all older # than 180 days (15552000 seconds). _cmdstr="{ now=\"\$(date -u +%s)\"; for fn in $_backupprefix*; \ From f61f2d6e5e024e7e08687beaacf8a9807c3a6bee Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 21 Mar 2020 19:28:16 +0100 Subject: [PATCH 0675/2234] adaptations to the new api functions _get_root fully functional due to the extended api --- dnsapi/dns_nm.sh | 81 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index f5b0bd0e..f9e98b2a 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -6,7 +6,7 @@ # Environment variables: # # - $NM_user (your namemaster.de API username) -# - $NM_md5 (your namemaster.de API password_as_md5hash) +# - $NM_sha256 (your namemaster.de API password_as_sha256hash) # # Author: Thilo Gass # Git repo: https://github.com/ThiloGa/acme.sh @@ -14,42 +14,53 @@ #-- dns_nm_add() - Add TXT record -------------------------------------- # Usage: dns_nm_add _acme-challenge.subdomain.domain.com "XyZ123..." +namemaster_api="https://namemaster.de/api/api.php" + + dns_nm_add() { fulldomain=$1 txt_value=$2 _info "Using DNS-01 namemaster hook" NM_user="${NM_user:-$(_readaccountconf_mutable NM_user)}" - NM_md5="${NM_md5:-$(_readaccountconf_mutable NM_md5)}" - if [ -z "$NM_user" ] || [ -z "$NM_md5" ]; then + NM_sha256="${NM_sha256:-$(_readaccountconf_mutable NM_sha256)}" + if [ -z "$NM_user" ] || [ -z "$NM_sha256" ]; then NM_user="" - NM_md5="" - _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables." + NM_sha256="" + _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_sha256 environment variables." return 1 fi - #save the api user and md5 password to the account conf file. + #save the api user and sha256 password to the account conf file. _debug "Save user and hash" _saveaccountconf_mutable NM_user "$NM_user" - _saveaccountconf_mutable NM_md5 "$NM_md5" + _saveaccountconf_mutable NM_sha256 "$NM_sha256" - zone="$(echo "$fulldomain" | _egrep_o "[^.]+.[^.]+$")" - get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=ACME&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" - if ! erg="$(_get "$get")"; then - _err "error Deleting $zone TXT: $txt_value" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" "$fulldomain" + return 1 + fi + + _info "die Zone lautet:" "$zone" + + get="$namemaster_api?User=$NM_user&Password=$NM_sha256&Antwort=csv&Typ=ACME&zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" + + if ! erg="$(_get "$get")" + then + _err "error Adding $fulldomain TXT: $txt_value" return 1 fi if _contains "$erg" "Success"; then _info "Success, TXT Added, OK" else - _err "error Adding $zone TXT: $txt_value erg: $erg" + _err "error Adding $fulldomain TXT: $txt_value erg: $erg" return 1 fi - _debug "ok Auto $zone TXT: $txt_value erg: $erg" + _debug "ok Auto $fulldomain TXT: $txt_value erg: $erg" return 0 - } dns_nm_rm() { @@ -58,30 +69,52 @@ dns_nm_rm() { txt_value=$2 NM_user="${NM_user:-$(_readaccountconf_mutable NM_user)}" - NM_md5="${NM_md5:-$(_readaccountconf_mutable NM_md5)}" - if [ -z "$NM_user" ] || [ -z "$NM_md5" ]; then + NM_sha256="${NM_sha256:-$(_readaccountconf_mutable NM_sha256)}" + if [ -z "$NM_user" ] || [ -z "$NM_sha256" ]; then NM_user="" - NM_md5="" - _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables." + NM_sha256="" + _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_sha256 environment variables." return 1 fi - zone="$(echo "$fulldomain" | _egrep_o "[^.]+.[^.]+$")" - get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN&TTL=0" - if ! erg="$(_get "$get")"; then - _err "error Deleting $zone TXT: $txt_value" + zone="$(echo "$fulldomain" | _egrep_o "[^.]+.[^.]+$")" + get="$namemaster_api?User=$NM_user&Password=$NM_sha256&Antwort=csv&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN" + + if ! erg="$(_get "$get")" + then + _err "error Deleting $fulldomain TXT: $txt_value" return 1 fi if _contains "$erg" "Success"; then _info "Success, TXT removed, OK" else - _err "error Auto $zone TXT: $txt_value erg: $erg" + _err "error Auto $fulldomain TXT: $txt_value erg: $erg" return 1 fi - _debug "ok Auto $zone TXT: $txt_value erg: $erg" + _debug "ok Auto $fulldomain TXT: $txt_value erg: $erg" return 0 } + + +_get_root() { + + domain=$1 + + get="$namemaster_api?User=$NM_user&Password=$NM_sha256&Typ=acme&hostname=$domain&Action=getzone&antwort=csv" + + if ! zone="$(_get "$get")" + then + _err "error getting Zone" + return 1 + else + if _contains "$zone" "hostname not found" + then + return 1 + fi + fi + +} \ No newline at end of file From 598f29b78e107baad00e8a07365c322d41c5b2c9 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 21 Mar 2020 19:41:46 +0100 Subject: [PATCH 0676/2234] doing shellcheck staff --- dnsapi/dns_nm.sh | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index f9e98b2a..24ff5409 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -16,7 +16,6 @@ namemaster_api="https://namemaster.de/api/api.php" - dns_nm_add() { fulldomain=$1 txt_value=$2 @@ -35,7 +34,6 @@ dns_nm_add() { _saveaccountconf_mutable NM_user "$NM_user" _saveaccountconf_mutable NM_sha256 "$NM_sha256" - _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" "$fulldomain" @@ -46,8 +44,8 @@ dns_nm_add() { get="$namemaster_api?User=$NM_user&Password=$NM_sha256&Antwort=csv&Typ=ACME&zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" - if ! erg="$(_get "$get")" - then + + if ! erg="$(_get "$get")"; then _err "error Adding $fulldomain TXT: $txt_value" return 1 fi @@ -77,12 +75,10 @@ dns_nm_rm() { return 1 fi - zone="$(echo "$fulldomain" | _egrep_o "[^.]+.[^.]+$")" get="$namemaster_api?User=$NM_user&Password=$NM_sha256&Antwort=csv&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN" - if ! erg="$(_get "$get")" - then + if ! erg="$(_get "$get")"; then _err "error Deleting $fulldomain TXT: $txt_value" return 1 fi @@ -99,15 +95,13 @@ dns_nm_rm() { } - _get_root() { domain=$1 get="$namemaster_api?User=$NM_user&Password=$NM_sha256&Typ=acme&hostname=$domain&Action=getzone&antwort=csv" - if ! zone="$(_get "$get")" - then + if ! zone="$(_get "$get")"; then _err "error getting Zone" return 1 else @@ -117,4 +111,4 @@ _get_root() { fi fi -} \ No newline at end of file +} From a1c4d159dd1710cd451f3d0bcac15b6b9121f58f Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 21 Mar 2020 19:48:17 +0100 Subject: [PATCH 0677/2234] further shellcheck fixes --- dnsapi/dns_nm.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 24ff5409..18369ebd 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -44,7 +44,6 @@ dns_nm_add() { get="$namemaster_api?User=$NM_user&Password=$NM_sha256&Antwort=csv&Typ=ACME&zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600" - if ! erg="$(_get "$get")"; then _err "error Adding $fulldomain TXT: $txt_value" return 1 @@ -105,8 +104,7 @@ _get_root() { _err "error getting Zone" return 1 else - if _contains "$zone" "hostname not found" - then + if _contains "$zone" "hostname not found"; then return 1 fi fi From bc2ed602e7d4596a1f1a0d009b8ed152a8987862 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Sat, 21 Mar 2020 21:18:25 +0100 Subject: [PATCH 0678/2234] deleted txt entry routine by request of namemaster.de, entry is deleted automatically --- dnsapi/dns_nm.sh | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 18369ebd..4dfcc777 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -63,34 +63,10 @@ dns_nm_add() { dns_nm_rm() { fulldomain=$1 - txt_value=$2 - - NM_user="${NM_user:-$(_readaccountconf_mutable NM_user)}" - NM_sha256="${NM_sha256:-$(_readaccountconf_mutable NM_sha256)}" - if [ -z "$NM_user" ] || [ -z "$NM_sha256" ]; then - NM_user="" - NM_sha256="" - _err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_sha256 environment variables." - return 1 - fi - - zone="$(echo "$fulldomain" | _egrep_o "[^.]+.[^.]+$")" - get="$namemaster_api?User=$NM_user&Password=$NM_sha256&Antwort=csv&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN" - - if ! erg="$(_get "$get")"; then - _err "error Deleting $fulldomain TXT: $txt_value" - return 1 - fi - - if _contains "$erg" "Success"; then - _info "Success, TXT removed, OK" - else - _err "error Auto $fulldomain TXT: $txt_value erg: $erg" - return 1 - fi - - _debug "ok Auto $fulldomain TXT: $txt_value erg: $erg" - return 0 + txtvalue=$2 + _info "TXT enrty in $fulldomain is deleted automatically" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" } From 4fa59ea04ec8e31777ce4fcd7c4456094518dee4 Mon Sep 17 00:00:00 2001 From: Ehsan Aliakbar Date: Tue, 24 Mar 2020 17:56:50 +0430 Subject: [PATCH 0679/2234] Adding Arvan Dns Api --- dnsapi/dns_arvan.sh | 163 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 dnsapi/dns_arvan.sh diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh new file mode 100644 index 00000000..af9de462 --- /dev/null +++ b/dnsapi/dns_arvan.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env sh + +#Arvan_Token="xxxx" + +ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" + +#Author: Ehsan Aliakbar +#Report Bugs here: https://github.com/Neilpang/acme.sh +# +######## Public functions ##################### + +#Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_arvan_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using Arvan" + + Arvan_Token="${Arvan_Token:-$(_readaccountconf_mutable Arvan_Token)}" + + if [ -z "$Arvan_Token" ]; then + _err "You didn't specify \"Arvan_Token\" token yet." + _err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys" + return 1 + fi + #save the api token to the account conf file. + _saveaccountconf_mutable Arvan_Token "$Arvan_Token" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + if _arvan_rest POST "$_domain/dns-records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":{\"text\":\"$txtvalue\"},\"ttl\":120}"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + return 0 + elif _contains "$response" "Record Data is Duplicated"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_arvan_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using Arvan" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + Arvan_Token="${Arvan_Token:-$(_readaccountconf_mutable Arvan_Token)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + shorted_txtvalue=$(printf "%s" "$txtvalue" | cut -d "-" -d "_" -f1) + _arvan_rest GET "${_domain}/dns-records?search=$shorted_txtvalue" + + if ! printf "%s" "$response" | grep \"current_page\":1 >/dev/null; then + _err "Error on Arvan Api" + -err "Please create a github issue with debbug log" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "\"total\":[^,]*" | cut -d : -f 2) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _arvan_rest "DELETE" "${_domain}/dns-records/$record_id"; then + _err "Delete record error." + return 1 + fi + _debug "$response" + _contains "$response" 'dns record deleted' + fi +} + +#################### 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=1 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _arvan_rest GET "?search=$h"; then + return 1 + fi + + if _contains "$response" "\"domain\":\"$h\"" || _contains "$response" '"total":1'; then + _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_arvan_rest() { + mtd="$1" + ep="$2" + data="$3" + + token_trimmed=$(echo "$Arvan_Token" | tr -d '"') + + export _H1="Authorization: $token_trimmed" + + if [ "$mtd" == "DELETE" ]; then + # DELETE Request shouldn't have Content-Type + _debug data "$data" + response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" + elif [ "$mtd" == "POST" ]; then + export _H2="Content-Type: application/json" + _debug data "$data" + response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" + else + response="$(_get "$ARVAN_API_URL/$ep$data")" + fi +} \ No newline at end of file From cb7e38577df79f6c19047e9dfa2cd60438c08bd3 Mon Sep 17 00:00:00 2001 From: Oliver Blaha Date: Tue, 24 Mar 2020 14:44:35 +0100 Subject: [PATCH 0680/2234] add support for upgrade from tag --- acme.sh | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 4d9a7c25..f5e79ee8 100755 --- a/acme.sh +++ b/acme.sh @@ -6317,7 +6317,7 @@ _installOnline() { if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then _info "Install success!" _initpath - _saveaccountconf "UPGRADE_HASH" "$(_getMasterHash)" + _saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)" fi cd .. @@ -6327,19 +6327,27 @@ _installOnline() { ) } -_getMasterHash() { +_getRepoHash() { + _hash_path=$1 + shift + _hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/$_hash_path" + _get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4 +} + +_getUpgradeHash() { _b="$BRANCH" if [ -z "$_b" ]; then _b="master" fi - _hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/heads/$_b" - _get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4 + _hash=$(_getRepoHash "heads/$_b") + if [ -z "$_hash" ]; then _hash=$(_getRepoHash "tags/$_b"); fi + echo $_hash } upgrade() { if ( _initpath - [ -z "$FORCE" ] && [ "$(_getMasterHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0 + [ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0 export LE_WORKING_DIR cd "$LE_WORKING_DIR" _installOnline "nocron" "noprofile" From 0453d656d629705059800a7d91cd3ea152649747 Mon Sep 17 00:00:00 2001 From: Brian Torres-Gil Date: Tue, 24 Mar 2020 20:01:51 -0700 Subject: [PATCH 0681/2234] fix(deploy/panos): data format improvements It was discovered in testing that PAN-OS < 9.0 has slightly different requirements for the multipart/form-data format and requires the `type` parameter to be passed in the URL. These corrections should work for all PAN-OS versions. --- deploy/panos.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 6316784a..ef622ded 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -47,24 +47,24 @@ deployer() { #Set Header export _H1="Content-Type: multipart/form-data; boundary=$delim" if [ "$type" = 'cert' ]; then - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\ncertificate" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n\r\n$_panos_key" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\n\r\npem" + panos_url="${panos_url}?type=import" + content="--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\ncertificate" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_cdomain" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" fi if [ "$type" = 'key' ]; then - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\nprivate-key" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n\r\n$_panos_key" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\n\r\npem" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n\r\n123456" + panos_url="${panos_url}?type=import" + content="--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\nprivate-key" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_cdomain" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" fi #Close multipart - content="$content${nl}--$delim--${nl}" + content="$content${nl}--$delim--${nl}${nl}" #Convert CRLF content=$(printf %b "$content") fi From 20ba82025316e033d7cf9cc9db0f1abaaedf1b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E8=AF=9A?= Date: Wed, 25 Mar 2020 14:39:52 +0800 Subject: [PATCH 0682/2234] Update dns_dp.sh https://dnsapi.cn has change the default language to cn other then en. So the api call need to add `lang=en` to url params for getting the english messages. And, They also change the susccess message from "Action completed successful" to "Operation successful". Simply use "successful" as keyword will be fine. --- dnsapi/dns_dp.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 480c1f9a..033fa5aa 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -53,7 +53,7 @@ dns_dp_rm() { return 1 fi - if ! _rest POST "Record.List" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain"; then + if ! _rest POST "Record.List" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain"; then _err "Record.Lis error." return 1 fi @@ -70,12 +70,12 @@ dns_dp_rm() { return 1 fi - if ! _rest POST "Record.Remove" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then + if ! _rest POST "Record.Remove" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&record_id=$record_id"; then _err "Record.Remove error." return 1 fi - _contains "$response" "Action completed successful" + _contains "$response" "successful" } @@ -89,11 +89,11 @@ add_record() { _info "Adding record" - if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then + if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then return 1 fi - _contains "$response" "Action completed successful" || _contains "$response" "Domain record already exists" + _contains "$response" "successful" || _contains "$response" "Domain record already exists" } #################### Private functions below ################################## @@ -113,11 +113,11 @@ _get_root() { return 1 fi - if ! _rest POST "Domain.Info" "login_token=$DP_Id,$DP_Key&format=json&domain=$h"; then + if ! _rest POST "Domain.Info" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain=$h"; then return 1 fi - if _contains "$response" "Action completed successful"; then + if _contains "$response" "successful"; then _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then From 6132af8ecb1e978f1e9d01f2670af22b7d179d8a Mon Sep 17 00:00:00 2001 From: ucando Date: Thu, 26 Mar 2020 14:59:23 +0800 Subject: [PATCH 0683/2234] enable qiniu to deploy more than one domain --- deploy/qiniu.sh | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/deploy/qiniu.sh b/deploy/qiniu.sh index 13b09651..70669917 100644 --- a/deploy/qiniu.sh +++ b/deploy/qiniu.sh @@ -6,6 +6,8 @@ # export QINIU_AK="QINIUACCESSKEY" # export QINIU_SK="QINIUSECRETKEY" # export QINIU_CDN_DOMAIN="cdn.example.com" +# If you have more than one domain, just +# export QINIU_CDN_DOMAIN="cdn1.example.com cdn2.example.com" QINIU_API_BASE="https://api.qiniu.com" @@ -67,21 +69,23 @@ qiniu_deploy() { _debug certId "$_certId" ## update domain ssl config - update_path="/domain/$QINIU_CDN_DOMAIN/httpsconf" update_body="{\"certid\":$_certId,\"forceHttps\":false}" - 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") + for domain in $QINIU_CDN_DOMAIN; do + update_path="/domain/$domain/httpsconf" + 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") - if _contains "$update_response" "error"; then - _err "Error in updating domain httpsconf:" - _err "$update_response" - return 1 - fi + if _contains "$update_response" "error"; then + _err "Error in updating domain $domain httpsconf:" + _err "$update_response" + return 1 + fi - _debug update_response "$update_response" - _info "Certificate successfully deployed" + _debug update_response "$update_response" + _info "Domain $domain certificate has been deployed successfully" + done return 0 } From 200cd5972aac175a11536218cb2b21c0026a6172 Mon Sep 17 00:00:00 2001 From: Ehsan Aliakbar Date: Sat, 28 Mar 2020 21:50:58 +0430 Subject: [PATCH 0684/2234] fix shellcheck errors in Arvan Dns Api --- dnsapi/dns_arvan.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index af9de462..341c8c17 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -78,7 +78,7 @@ dns_arvan_rm() { if ! printf "%s" "$response" | grep \"current_page\":1 >/dev/null; then _err "Error on Arvan Api" - -err "Please create a github issue with debbug log" + _err "Please create a github issue with debbug log" return 1 fi @@ -149,11 +149,11 @@ _arvan_rest() { export _H1="Authorization: $token_trimmed" - if [ "$mtd" == "DELETE" ]; then + if [ "$mtd" = "DELETE" ]; then # DELETE Request shouldn't have Content-Type _debug data "$data" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" - elif [ "$mtd" == "POST" ]; then + elif [ "$mtd" = "POST" ]; then export _H2="Content-Type: application/json" _debug data "$data" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" From 34cebe8c0c1e08b25684e5b94535013087875519 Mon Sep 17 00:00:00 2001 From: netpok Date: Sun, 29 Mar 2020 23:45:52 +0200 Subject: [PATCH 0685/2234] Fix invalid domain error on dns_cf update When dns_cf used with Zone ID it fails on removal of the entry. This pull request adds the missing CF_Zone_ID loading. --- dnsapi/dns_cf.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 2927ab4b..040934e2 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -94,6 +94,7 @@ dns_cf_rm() { CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" + CF_Zone_ID="${CF_Zone_ID:-$(_readaccountconf_mutable CF_Zone_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" From ff9be30f869147428fb70fc08262a53ce8cac7f0 Mon Sep 17 00:00:00 2001 From: Xiaohui Lam Date: Tue, 31 Mar 2020 03:10:12 +0800 Subject: [PATCH 0686/2234] resolved #2818 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index f5e79ee8..aaab2104 100755 --- a/acme.sh +++ b/acme.sh @@ -4540,7 +4540,7 @@ $_authorizations_map" _savedomainconf "Le_LinkOrder" "$Le_LinkOrder" _link_cert_retry=0 - _MAX_CERT_RETRY=5 + _MAX_CERT_RETRY=30 while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do if _contains "$response" "\"status\":\"valid\""; then _debug "Order status is valid." From dc697a686279caf6a534dca51d5c9f4ec23e8f3c Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Wed, 1 Apr 2020 20:24:40 +0200 Subject: [PATCH 0687/2234] fix #2830 Autorization segment typo fixed This fixes the parsing of the authorization segment in the response of an order. Without this fix the start of the array is not found correctly and therefore the finalize URL is part of the authorization segment. Changing the regex to *\[[^\[]*\] fix this. Seems to be a typo which has not been recognized so far. This can be only recognized if the response is in a single line. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index aaab2104..937e435c 100755 --- a/acme.sh +++ b/acme.sh @@ -4019,7 +4019,7 @@ issue() { #for dns manual mode _savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize" - _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" + _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\[]]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" _debug2 _authorizations_seg "$_authorizations_seg" if [ -z "$_authorizations_seg" ]; then _err "_authorizations_seg not found." From 37d22a144a0f4e6e08941672b3137a2045cf1d17 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Wed, 1 Apr 2020 20:31:06 +0200 Subject: [PATCH 0688/2234] fix #2830 Autorization segment typo fixed This fixes the parsing of the authorization segment in the response of an order. Without this fix the start of the array is not found correctly and therefore the finalize URL is part of the authorization segment. Changing the regex to *\[[^\[]*\] fix this. Seems to be a typo which has not been recognized so far. This can be only recognized if the response is in a single line. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 937e435c..adf03427 100755 --- a/acme.sh +++ b/acme.sh @@ -4019,7 +4019,7 @@ issue() { #for dns manual mode _savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize" - _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\[]]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" + _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\[]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" _debug2 _authorizations_seg "$_authorizations_seg" if [ -z "$_authorizations_seg" ]; then _err "_authorizations_seg not found." From 7595808d260410177d92cd41df1c1b9c97c2ff00 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Wed, 1 Apr 2020 20:35:07 +0200 Subject: [PATCH 0689/2234] fix #2828 mailto compliant to RFC6068 This fix removes the space between "mailto:" and the email address to make the contact attribute compliant to RFC6068. --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index adf03427..512d57e8 100755 --- a/acme.sh +++ b/acme.sh @@ -3417,13 +3417,13 @@ _regAccount() { if [ "$ACME_VERSION" = "2" ]; then regjson='{"termsOfServiceAgreed": true}' if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"contact": ["mailto: '$ACCOUNT_EMAIL'"], "termsOfServiceAgreed": true}' + regjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"], "termsOfServiceAgreed": true}' fi else _reg_res="$ACME_NEW_ACCOUNT_RES" regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"resource": "'$_reg_res'", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' + regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$ACCOUNT_EMAIL'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' fi fi @@ -3503,7 +3503,7 @@ updateaccount() { if [ "$ACME_VERSION" = "2" ]; then if [ "$ACCOUNT_EMAIL" ]; then - updjson='{"contact": ["mailto: '$ACCOUNT_EMAIL'"]}' + updjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"]}' fi else # ACMEv1: Updates happen the same way a registration is done. From 47883a94a6af56c39af62e9a8c297b089154e741 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 5 Apr 2020 13:46:02 +0800 Subject: [PATCH 0690/2234] support auto-comment --- .github/auto-comment.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/auto-comment.yml diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml new file mode 100644 index 00000000..75e6ac5d --- /dev/null +++ b/.github/auto-comment.yml @@ -0,0 +1,18 @@ +# Comment to a new issue. +issuesOpened: > + If this is a bug report, please upgrade to the latest code and try again: + 请先更新到最新版再试: + ```sh + acme.sh --upgrade + ``` + + +pullRequestOpened: > + If this is a PR to support new DNS API or new notification API, please read this guide first: + https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide + + Please check the guide items one by one. + + Then add your usage here: + https://github.com/acmesh-official/acme.sh/wiki/dnsapi + From 5530e743827a043f467fc647247c7908432b924f Mon Sep 17 00:00:00 2001 From: aattww <52109748+aattww@users.noreply.github.com> Date: Sun, 5 Apr 2020 21:57:37 +0300 Subject: [PATCH 0691/2234] Initial release --- dnsapi/dns_joker.sh | 129 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 dnsapi/dns_joker.sh diff --git a/dnsapi/dns_joker.sh b/dnsapi/dns_joker.sh new file mode 100644 index 00000000..14a0e3cf --- /dev/null +++ b/dnsapi/dns_joker.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env sh + +# Joker.com API for acme.sh +# +# This script adds the necessary TXT record to a domain in Joker.com. +# +# You must activate Dynamic DNS in Joker.com DNS configuration first. +# Username and password below refer to Dynamic DNS authentication, +# not your Joker.com login credentials. +# See: https://joker.com/faq/content/11/427/en/what-is-dynamic-dns-dyndns.html +# +# NOTE: This script does not support wildcard certificates, because +# Joker.com API does not support adding two TXT records with the same +# subdomain. Adding the second record will overwrite the first one. +# See: https://joker.com/faq/content/6/496/en/let_s-encrypt-support.html +# "... this request will replace all TXT records for the specified +# label by the provided content" +# +# Author: aattww (https://github.com/aattww/) +# +# JOKER_USERNAME="xxxx" +# JOKER_PASSWORD="xxxx" + +JOKER_API="https://svc.joker.com/nic/replace" + +######## Public functions ##################### + +#Usage: dns_joker_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_joker_add() { + fulldomain=$1 + txtvalue=$2 + + JOKER_USERNAME="${JOKER_USERNAME:-$(_readaccountconf_mutable JOKER_USERNAME)}" + JOKER_PASSWORD="${JOKER_PASSWORD:-$(_readaccountconf_mutable JOKER_PASSWORD)}" + + if [ -z "$JOKER_USERNAME" ] || [ -z "$JOKER_PASSWORD" ]; then + _err "No Joker.com username and password specified." + return 1 + fi + + _saveaccountconf_mutable JOKER_USERNAME "$JOKER_USERNAME" + _saveaccountconf_mutable JOKER_PASSWORD "$JOKER_PASSWORD" + + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + + _info "Adding TXT record" + if _joker_rest "username=$JOKER_USERNAME&password=$JOKER_PASSWORD&zone=$_domain&label=$_sub_domain&type=TXT&value=$txtvalue"; then + if _startswith "$response" "OK"; then + _info "Added, OK" + return 0 + fi + fi + _err "Error adding TXT record." + return 1 +} + +#fulldomain txtvalue +dns_joker_rm() { + fulldomain=$1 + txtvalue=$2 + + JOKER_USERNAME="${JOKER_USERNAME:-$(_readaccountconf_mutable JOKER_USERNAME)}" + JOKER_PASSWORD="${JOKER_PASSWORD:-$(_readaccountconf_mutable JOKER_PASSWORD)}" + + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + + _info "Removing TXT record" + # TXT record is removed by setting its value to empty. + if _joker_rest "username=$JOKER_USERNAME&password=$JOKER_PASSWORD&zone=$_domain&label=$_sub_domain&type=TXT&value="; then + if _startswith "$response" "OK"; then + _info "Removed, OK" + return 0 + fi + fi + _err "Error removing TXT record." + return 1 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + fulldomain=$1 + i=1 + while true; do + h=$(printf "%s" "$fulldomain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + return 1 + fi + + # Try to remove a test record. With correct root domain, username and password this will return "OK: ..." regardless + # of record in question existing or not. + if _joker_rest "username=$JOKER_USERNAME&password=$JOKER_PASSWORD&zone=$h&label=jokerTXTUpdateTest&type=TXT&value="; then + if _startswith "$response" "OK"; then + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$h\$//")" + _domain=$h + return 0 + fi + fi + + i=$(_math "$i" + 1) + done + + _debug "Root domain not found" + return 1 +} + +_joker_rest() { + data="$1" + _debug data "$data" + + response="$(_post "$data" "$JOKER_API" "" "POST")" + + if [ "$?" != "0" ]; then + _err "Error POSTing" + return 1 + fi + _debug response "$response" + return 0 +} From 8400d1e60ea75bc0ced48ba43ad649135be31121 Mon Sep 17 00:00:00 2001 From: aattww <52109748+aattww@users.noreply.github.com> Date: Sun, 5 Apr 2020 22:07:20 +0300 Subject: [PATCH 0692/2234] Add bugs report link --- dnsapi/dns_joker.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_joker.sh b/dnsapi/dns_joker.sh index 14a0e3cf..e25530c1 100644 --- a/dnsapi/dns_joker.sh +++ b/dnsapi/dns_joker.sh @@ -18,6 +18,8 @@ # # Author: aattww (https://github.com/aattww/) # +# Report bugs to https://github.com/acmesh-official/acme.sh/issues/2840 +# # JOKER_USERNAME="xxxx" # JOKER_PASSWORD="xxxx" From c064b3896a6ab6a24a8d2ff6a9364c42d453850d Mon Sep 17 00:00:00 2001 From: aattww <52109748+aattww@users.noreply.github.com> Date: Mon, 6 Apr 2020 01:13:59 +0300 Subject: [PATCH 0693/2234] Change command check to fully pass shellcheck --- dnsapi/dns_joker.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dnsapi/dns_joker.sh b/dnsapi/dns_joker.sh index e25530c1..5d50953e 100644 --- a/dnsapi/dns_joker.sh +++ b/dnsapi/dns_joker.sh @@ -120,9 +120,7 @@ _joker_rest() { data="$1" _debug data "$data" - response="$(_post "$data" "$JOKER_API" "" "POST")" - - if [ "$?" != "0" ]; then + if ! response="$(_post "$data" "$JOKER_API" "" "POST")"; then _err "Error POSTing" return 1 fi From 5fac282ee098394ee3cd6eff1975e699bc5ce9b2 Mon Sep 17 00:00:00 2001 From: der-berni Date: Tue, 7 Apr 2020 19:25:39 +0200 Subject: [PATCH 0694/2234] Update to work with new one.com procedure Since some Months, its no longer possible to add TXT Records with the Name "_acme-challenge" to the base domain. To override the fallback value, you must use a CNAME and proxy it. For example. CNAME _acme-challenge.yourdomain.com => proxy_acme-challenge.yourdomain.com The TXT Records have to be created on proxy_acme-challenge.yourdomain.com Since the default CNAME TTL is 3600 seconds, it is recommended to leave the CNAME record. But if you would like to use the build-in SSL (for your web-site etc.) from one.com, you have to delete the record. A new variable "ONECOM_KeepCnameProxy" you can set in the account.conf is used to keep the CNAME record. By default the CNAME record will be removed. For ex.: SAVED_ONECOM_KeepCnameProxy='1' to keep the CNAME Record and speedup the process. --- dnsapi/dns_one.sh | 195 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 146 insertions(+), 49 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 0fdc3d5e..4cc159da 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -5,7 +5,7 @@ # Author: github: @diseq # Created: 2019-02-17 # Fixed by: @der-berni -# Modified: 2019-05-31 +# Modified: 2020-04-07 # # export ONECOM_User="username" # export ONECOM_Password="password" @@ -29,33 +29,46 @@ dns_one_add() { _err "root domain not found" return 1 fi - - mysubdomain=$_sub_domain - mydomain=$_domain - _debug mysubdomain "$mysubdomain" - _debug mydomain "$mydomain" - - # get entries - response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" - _debug response "$response" - - # Update the IP address for domain entry - postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}" - _debug postdata "$postdata" - response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records" "" "POST" "application/json")" - response="$(echo "$response" | _normalizeJson)" - _debug response "$response" - - id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") - - if [ -z "$id" ]; then - _err "Add txt record error." - return 1 - else - _info "Added, OK ($id)" + + subdomain="${_sub_domain}" + maindomain=${_domain} + + useProxy=0 + if [ "${_sub_domain}" = "_acme-challenge" ]; then + subdomain="proxy${_sub_domain}" + useProxy=1 + fi + + _debug subdomain "$subdomain" + _debug maindomain "$maindomain" + + if [ $useProxy -eq 1 ]; then + #Check if the CNAME exists + _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" + if [ -z "$id" ]; then + _info "$(__red "Add CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + _dns_one_addrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" + + _info "Not valid yet, let's wait 1 hour to take effect." + _sleep 3600 + fi + fi + + #Check if the TXT exists + _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" + if [ ! -z "$id" ]; then + _info "$(__green "Txt record with the same value found. Skip adding.")" + return 0 + fi + + _dns_one_addrecord "TXT" "$subdomain" "$txtvalue" + if [ -z "$id" ]; then + _err "Add CNAME record error." + return 1 + else + _info "$(__green "Added, OK ($id)")" return 0 fi - } dns_one_rm() { @@ -73,36 +86,46 @@ dns_one_rm() { return 1 fi - mysubdomain=$_sub_domain - mydomain=$_domain - _debug mysubdomain "$mysubdomain" - _debug mydomain "$mydomain" - - # get entries - response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" - response="$(echo "$response" | _normalizeJson)" - _debug response "$response" - - id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}.*/\1/p") - + subdomain="${_sub_domain}" + maindomain=${_domain} + + useProxy=0 + if [ "${_sub_domain}" = "_acme-challenge" ]; then + subdomain="proxy${_sub_domain}" + useProxy=1 + fi + + _debug subdomain "$subdomain" + _debug maindomain "$maindomain" + if [ $useProxy -eq 1 ]; then + if [ "$ONECOM_KeepCnameProxy" = "1" ]; then + _info "$(__red "Keeping CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + else + #Check if the CNAME exists + _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" + if [ ! -z "$id" ]; then + _info "$(__red "Removing CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + _dns_one_delrecord "$id" + fi + fi + fi + + #Check if the TXT exists + _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" if [ -z "$id" ]; then _err "Txt record not found." return 1 fi - + # delete entry - response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records/$id" "" "DELETE" "application/json")" - response="$(echo "$response" | _normalizeJson)" - _debug response "$response" - - if [ "$response" = '{"result":null,"metadata":null}' ]; then - _info "Removed, OK" - return 0 + + if _dns_one_delrecord "$id"; then + _info "$(__green Removed, OK)" + return 0 else - _err "Removing txt record error." - return 1 + _err "Removing txt record error." + return 1 fi - } #_acme-challenge.www.domain.com @@ -138,6 +161,7 @@ _get_root() { _dns_one_login() { # get credentials + ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-$(_readaccountconf_mutable ONECOM_KeepCnameProxy)}" ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then @@ -177,3 +201,76 @@ _dns_one_login() { return 0 } + +_dns_one_getrecord() { + type="$1" + name="$2" + value="$3" + if [ -z "$type" ]; then + type="TXT" + fi + if [ -z "$name" ]; then + _err "Record name is empty." + return 1 + fi + + response="$(_get "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records")" + response="$(echo "$response" | _normalizeJson)" + _debug response "$response" + + if [ -z "${value}" ]; then + id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"[^\"]*\",\"priority\":0,\"ttl\":600}.*/\1/p") + response=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"[^\"]*\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"\([^\"]*\)\",\"priority\":0,\"ttl\":600}.*/\1/p") + else + id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"${value}\",\"priority\":0,\"ttl\":600}.*/\1/p") + fi + if [ -z "$id" ]; then + _err "Record not found." + return 1 + fi + return 0 +} + +_dns_one_addrecord() { + type="$1" + name="$2" + value="$3" + if [ -z "$type" ]; then + type="TXT" + fi + if [ -z "$name" ]; then + _err "Record name is empty." + return 1 + fi + + postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"${type}\",\"prefix\":\"${name}\",\"content\":\"${value}\"}}" + _debug postdata "$postdata" + response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records" "" "POST" "application/json")" + response="$(echo "$response" | _normalizeJson)" + _debug response "$response" + + id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$subdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") + + if [ -z "$id" ]; then + return 1 + else + return 0 + fi +} + +_dns_one_delrecord() { + id="$1" + if [ -z "$id" ]; then + return 1 + fi + + response="$(_post "" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records/$id" "" "DELETE" "application/json")" + response="$(echo "$response" | _normalizeJson)" + _debug response "$response" + + if [ "$response" = '{"result":null,"metadata":null}' ]; then + return 0 + else + return 1 + fi +} From 62378d063e9592837f33a9bf50fdab334569d63a Mon Sep 17 00:00:00 2001 From: Wout Date: Tue, 7 Apr 2020 22:34:05 +0200 Subject: [PATCH 0695/2234] Fixes getting the correct domain id using Contellix API. --- dnsapi/dns_constellix.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index c47ede44..2eb266b7 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -86,12 +86,12 @@ _get_root() { return 1 fi - if ! _constellix_rest GET "domains"; then + if ! _constellix_rest GET "domains/search?name=$h"; then return 1 fi if _contains "$response" "\"name\":\"$h\""; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | head -n 1 | cut -d ':' -f 2 | tr -d '}') + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+" | cut -d ':' -f 2) if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p) _domain="$h" From da7b1fb014ceb1791bff30f65967c3aa1af491e4 Mon Sep 17 00:00:00 2001 From: der-berni Date: Thu, 9 Apr 2020 12:17:08 +0200 Subject: [PATCH 0696/2234] cleanup according to styleguide / ShellCheck --- dnsapi/dns_one.sh | 87 ++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 4cc159da..96ef5969 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -6,7 +6,10 @@ # Created: 2019-02-17 # Fixed by: @der-berni # Modified: 2020-04-07 -# +# +# Use ONECOM_KeepCnameProxy to keep the CNAME DNS record +# export ONECOM_KeepCnameProxy="1" +# # export ONECOM_User="username" # export ONECOM_Password="password" # @@ -29,41 +32,41 @@ dns_one_add() { _err "root domain not found" return 1 fi - + subdomain="${_sub_domain}" maindomain=${_domain} - + useProxy=0 if [ "${_sub_domain}" = "_acme-challenge" ]; then subdomain="proxy${_sub_domain}" useProxy=1 fi - + _debug subdomain "$subdomain" _debug maindomain "$maindomain" - + if [ $useProxy -eq 1 ]; then #Check if the CNAME exists _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" if [ -z "$id" ]; then _info "$(__red "Add CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" _dns_one_addrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" - + _info "Not valid yet, let's wait 1 hour to take effect." _sleep 3600 fi fi - + #Check if the TXT exists _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" - if [ ! -z "$id" ]; then + if [ -n "$id" ]; then _info "$(__green "Txt record with the same value found. Skip adding.")" return 0 fi - + _dns_one_addrecord "TXT" "$subdomain" "$txtvalue" if [ -z "$id" ]; then - _err "Add CNAME record error." + _err "Add TXT record error." return 1 else _info "$(__green "Added, OK ($id)")" @@ -88,43 +91,42 @@ dns_one_rm() { subdomain="${_sub_domain}" maindomain=${_domain} - + useProxy=0 if [ "${_sub_domain}" = "_acme-challenge" ]; then subdomain="proxy${_sub_domain}" useProxy=1 fi - + _debug subdomain "$subdomain" _debug maindomain "$maindomain" if [ $useProxy -eq 1 ]; then - if [ "$ONECOM_KeepCnameProxy" = "1" ]; then - _info "$(__red "Keeping CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" - else - #Check if the CNAME exists - _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" - if [ ! -z "$id" ]; then - _info "$(__red "Removing CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" - _dns_one_delrecord "$id" - fi + if [ "$ONECOM_KeepCnameProxy" = "1" ]; then + _info "$(__red "Keeping CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + else + #Check if the CNAME exists + _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" + if [ -n "$id" ]; then + _info "$(__red "Removing CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + _dns_one_delrecord "$id" fi + fi fi - + #Check if the TXT exists _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" if [ -z "$id" ]; then _err "Txt record not found." return 1 fi - + # delete entry - if _dns_one_delrecord "$id"; then - _info "$(__green Removed, OK)" - return 0 + _info "$(__green Removed, OK)" + return 0 else - _err "Removing txt record error." - return 1 + _err "Removing txt record error." + return 1 fi } @@ -162,6 +164,7 @@ _dns_one_login() { # get credentials ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-$(_readaccountconf_mutable ONECOM_KeepCnameProxy)}" + ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-0}" ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then @@ -173,6 +176,7 @@ _dns_one_login() { fi #save the api key and email to the account conf file. + _saveaccountconf_mutable ONECOM_KeepCnameProxy "$ONECOM_KeepCnameProxy" _saveaccountconf_mutable ONECOM_User "$ONECOM_User" _saveaccountconf_mutable ONECOM_Password "$ONECOM_Password" @@ -207,17 +211,17 @@ _dns_one_getrecord() { name="$2" value="$3" if [ -z "$type" ]; then - type="TXT" + type="TXT" fi if [ -z "$name" ]; then - _err "Record name is empty." - return 1 + _err "Record name is empty." + return 1 fi - + response="$(_get "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records")" response="$(echo "$response" | _normalizeJson)" _debug response "$response" - + if [ -z "${value}" ]; then id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"[^\"]*\",\"priority\":0,\"ttl\":600}.*/\1/p") response=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"[^\"]*\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"\([^\"]*\)\",\"priority\":0,\"ttl\":600}.*/\1/p") @@ -225,7 +229,6 @@ _dns_one_getrecord() { id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"${value}\",\"priority\":0,\"ttl\":600}.*/\1/p") fi if [ -z "$id" ]; then - _err "Record not found." return 1 fi return 0 @@ -236,13 +239,13 @@ _dns_one_addrecord() { name="$2" value="$3" if [ -z "$type" ]; then - type="TXT" + type="TXT" fi if [ -z "$name" ]; then - _err "Record name is empty." - return 1 + _err "Record name is empty." + return 1 fi - + postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"${type}\",\"prefix\":\"${name}\",\"content\":\"${value}\"}}" _debug postdata "$postdata" response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records" "" "POST" "application/json")" @@ -261,16 +264,16 @@ _dns_one_addrecord() { _dns_one_delrecord() { id="$1" if [ -z "$id" ]; then - return 1 + return 1 fi - + response="$(_post "" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records/$id" "" "DELETE" "application/json")" response="$(echo "$response" | _normalizeJson)" _debug response "$response" if [ "$response" = '{"result":null,"metadata":null}' ]; then - return 0 + return 0 else - return 1 + return 1 fi } From e158b5ccf65848233dd00c7fbafcf41f87a68a18 Mon Sep 17 00:00:00 2001 From: Wout Date: Thu, 9 Apr 2020 19:15:32 +0200 Subject: [PATCH 0697/2234] Constellix made changes to their API. They added more search capabilities, but the changes are not backwards compatible. We need to use the `exact` parameter instead of `name` now. --- dnsapi/dns_constellix.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 2eb266b7..42df710d 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -86,7 +86,7 @@ _get_root() { return 1 fi - if ! _constellix_rest GET "domains/search?name=$h"; then + if ! _constellix_rest GET "domains/search?exact=$h"; then return 1 fi From eef9a60037cc9771a43074f1f6bf855c5850113d Mon Sep 17 00:00:00 2001 From: Adrian Fedoreanu Date: Fri, 10 Apr 2020 23:25:28 +0200 Subject: [PATCH 0698/2234] add dns_1984hosting dns api --- dnsapi/dns_1984hosting.sh | 254 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100755 dnsapi/dns_1984hosting.sh diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh new file mode 100755 index 00000000..b7cb36d7 --- /dev/null +++ b/dnsapi/dns_1984hosting.sh @@ -0,0 +1,254 @@ +#!/usr/bin/env sh +#This file name is "dns_1984hosting.sh" +#So, here must be a method dns_1984hosting_add() +#Which will be called by acme.sh to add the txt record to your api system. +#returns 0 means success, otherwise error. +# +#Author: Adrian Fedoreanu +#Report Bugs here: https://github.com/acmesh-official/acme.sh +# or here... https://github.com/acmesh-official/acme.sh/issues/2851 +# +######## Public functions ##################### + +# Export 1984HOSTING username and password in following variables +# +# One984HOSTING_Username=username +# One984HOSTING_Password=password +# +# sessionid cookie is saved in ~/.acme.sh/account.conf +# username/password need to be set only when changed. + +#Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_1984hosting_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Add TXT record using 1984Hosting" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + if ! _1984hosting_login; then + _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" "$fulldomain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _1984hosting_add_txt_record "$_domain" "$_sub_domain" "$txtvalue" + return $? +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_1984hosting_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Delete TXT record using 1984Hosting" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + if ! _1984hosting_login; then + _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" "$fulldomain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _1984hosting_delete_txt_record "$_domain" "$_sub_domain" + return $? +} + +#################### Private functions below ################################## + +# usage _1984hosting_add_txt_record domain subdomain value +# returns 0 success +_1984hosting_add_txt_record() { + _debug "Add TXT record $1 with value '$3'" + domain="$1" + subdomain="$2" + value="$(printf '%s' "$3" | _url_encode)" + url="https://management.1984hosting.com/domains/entry/" + + postdata="entry=new" + postdata="$postdata&type=TXT" + postdata="$postdata&ttl=3600" + postdata="$postdata&zone=$domain" + postdata="$postdata&host=$subdomain" + postdata="$postdata&rdata=%22$value%22" + _debug2 postdata "$postdata" + + _authpost "$postdata" "$url" + response="$(echo "$_response" | _normalizeJson)" + _debug2 response "$response" + + if _contains "$response" '"haserrors": true'; then + _err "1984Hosting failed to add TXT record for $subdomain bad RC from _post" + return 1 + elif _contains "$response" ""; then + _err "1984Hosting failed to add TXT record for $subdomain. Check $HTTP_HEADER file" + return 1 + elif [ "$response" = '{"auth": false, "ok": false}' ]; then + _err "1984Hosting failed to add TXT record for $subdomain. Invalid or expired cookie" + return 1 + fi + + _info "Added acme challenge TXT record for $fulldomain at 1984Hosting" + return 0 +} + +# usage _1984hosting_delete_txt_record entry_id +# returns 0 success +_1984hosting_delete_txt_record() { + _debug "Delete $fulldomain TXT record" + domain="$1" + subdomain="$2" + url="https://management.1984hosting.com/domains" + + _htmlget "$url" "$domain" + _debug2 _response "$_response" + zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" + _debug2 zone_id "$zone_id" + if [ -z "$zone_id" ]; then + _err "Error getting zone_id for $1" + return 1 + fi + + _htmlget "$url/$zone_id" "$subdomain" + _debug2 _response "$_response" + entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" + _debug2 entry_id "$entry_id" + if [ -z "$entry_id" ]; then + _err "Error getting TXT entry_id for $1" + return 1 + fi + + _authpost "entry=$entry_id" "$url/delentry/" + response="$(echo "$_response" | _normalizeJson)" + _debug2 response "$response" + + if ! _contains "$response" '"ok": true'; then + _err "1984Hosting failed to delete TXT record for $entry_id bad RC from _post" + return 1 + fi + + _info "Deleted acme challenge TXT record for $fulldomain at 1984Hosting" + return 0 +} + +# usage: _1984hosting_login username password +# returns 0 success +_1984hosting_login() { + if ! _check_credentials; then return 1; fi + + if _check_cookie; then + _debug "Already logged in" + return 0 + fi + + _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/" + + response="$(_post "username=$username&password=$password&otpkey=" "$url")" + response="$(echo "$response" | _normalizeJson)" + _debug2 response "$response" + + if [ "$response" = '{"loggedin": true, "ok": true}' ]; then + One984HOSTING_COOKIE="$(grep '^Set-Cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" + export One984HOSTING_COOKIE + _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" + return 0 + fi + return 1 +} + +_check_credentials() { + if [ -z "$One984HOSTING_Username" ] || [ -z "$One984HOSTING_Password" ]; then + One984HOSTING_Username="" + One984HOSTING_Password="" + _err "You haven't specified 1984Hosting username or password yet." + _err "Please export as One984HOSTING_Username / One984HOSTING_Password and try again." + return 1 + fi + return 0 +} + +_check_cookie() { + One984HOSTING_COOKIE="${One984HOSTING_COOKIE:-$(_readaccountconf_mutable One984HOSTING_COOKIE)}" + if [ -z "$One984HOSTING_COOKIE" ]; then + _debug "No cached cookie found" + return 1 + fi + + _authget "https://management.1984hosting.com/accounts/loginstatus/" + response="$(echo "$_response" | _normalizeJson)" + if [ "$_response" = '{"ok": true}' ]; then + _debug "Cached cookie still valid" + return 0 + fi + _debug "Cached cookie no longer valid" + One984HOSTING_COOKIE="" + _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" + return 1 +} + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain="$1" + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + + if [ -z "$h" ]; then + #not valid + return 1 + fi + + _authget "https://management.1984hosting.com/domains/soacheck/?zone=$h&nameserver=ns0.1984.is." + if _contains "$_response" "serial"; 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 +} + +# add extra headers to request +_authget() { + export _H1="Cookie: $One984HOSTING_COOKIE" + _response=$(_get "$1") +} + +# truncate huge HTML response +# echo: Argument list too long +_htmlget() { + export _H1="Cookie: $One984HOSTING_COOKIE" + _response=$(_get "$1" | grep "$2" | _head_n 1) +} + +# add extra headers to request +_authpost() { + export _H1="Cookie: $One984HOSTING_COOKIE" + _response=$(_post "$1" "$2") +} From 52a16c917f3f28d7a83e0ac368c62b28aa99174c Mon Sep 17 00:00:00 2001 From: Scott Wiersdorf Date: Sat, 11 Apr 2020 11:24:30 -0600 Subject: [PATCH 0699/2234] show response when unable to retrieve DNS records for a zone --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 040934e2..43bc1428 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -111,7 +111,7 @@ dns_cf_rm() { _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain&content=$txtvalue" if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then - _err "Error" + _err "Error: $response" return 1 fi From a57ba3d81ca3986fd405a38b22c9d7ec23f10dcd Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 12 Apr 2020 10:38:31 +0800 Subject: [PATCH 0700/2234] update comments --- .github/auto-comment.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml index 75e6ac5d..3ef3d9e4 100644 --- a/.github/auto-comment.yml +++ b/.github/auto-comment.yml @@ -1,13 +1,17 @@ # Comment to a new issue. issuesOpened: > If this is a bug report, please upgrade to the latest code and try again: - 请先更新到最新版再试: + + 如果有 bug, 请先更新到最新版试试: + ```sh acme.sh --upgrade ``` pullRequestOpened: > + First, never send a PR to `master` branch, it will never be accepted. Please send to the `dev` branch instead. + If this is a PR to support new DNS API or new notification API, please read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide @@ -16,3 +20,5 @@ pullRequestOpened: > Then add your usage here: https://github.com/acmesh-official/acme.sh/wiki/dnsapi + + From 5ace44493a8f6691c39f2143f8fbc2227cff9618 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 12 Apr 2020 10:47:41 +0800 Subject: [PATCH 0701/2234] fix comments --- .github/auto-comment.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml index 3ef3d9e4..1e7b389e 100644 --- a/.github/auto-comment.yml +++ b/.github/auto-comment.yml @@ -7,6 +7,10 @@ issuesOpened: > ```sh acme.sh --upgrade ``` + + please also provide the log with `--debug 2`. + + see: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh pullRequestOpened: > From 93de1e4903a975efa45da8fecbc819559e89ded7 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 12 Apr 2020 11:48:24 +0800 Subject: [PATCH 0702/2234] un-escape json chars fix https://github.com/acmesh-official/acme.sh/issues/2833 --- acme.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 512d57e8..f672710d 100755 --- a/acme.sh +++ b/acme.sh @@ -846,6 +846,14 @@ _json_encode() { echo "$_j_str" | _hex_dump | _lower_case | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n" } +#from: http:\/\/ to http:// +_json_decode() { + _j_str="$(sed 's#\\/#/#g')" + _debug3 "_json_decode" + _debug3 "_j_str" "$_j_str" + echo "$_j_str" +} + #options file _sed_i() { options="$1" @@ -4019,7 +4027,7 @@ issue() { #for dns manual mode _savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize" - _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\[]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" + _authorizations_seg="$(echo "$response" | _json_decode | _egrep_o '"authorizations" *: *\[[^\[]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" _debug2 _authorizations_seg "$_authorizations_seg" if [ -z "$_authorizations_seg" ]; then _err "_authorizations_seg not found." From 4dfdfa0b7db773cc46d12c1ff107ee50fef2fb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=96=B5=E5=96=B5=E5=9B=9B?= Date: Sun, 12 Apr 2020 12:28:07 +0800 Subject: [PATCH 0703/2234] Fix typo on line 27 --- dnsapi/dns_he.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index caa4d2c4..5829e00e 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -24,7 +24,7 @@ dns_he_add() { if [ -z "$HE_Username" ] || [ -z "$HE_Password" ]; then HE_Username= HE_Password= - _err "No auth details provided. Please set user credentials using the \$HE_Username and \$HE_Password envoronment variables." + _err "No auth details provided. Please set user credentials using the \$HE_Username and \$HE_Password environment variables." return 1 fi _saveaccountconf_mutable HE_Username "$HE_Username" From 2c971a25985049c928597da57e636b5487d19abf Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Thu, 16 Apr 2020 20:03:34 +0200 Subject: [PATCH 0704/2234] Filter out blank lines Response from the provider has changed so that there are blank lines at the end, which leads to the result can not be parsed correctly --- dnsapi/dns_ddnss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index 53781d0d..ecc4f174 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -119,7 +119,7 @@ _ddnss_rest() { # DDNSS uses GET to update domain info if [ "$method" = "GET" ]; then - response="$(_get "$url" | sed 's/<[a-zA-Z\/][^>]*>//g' | _tail_n 1)" + response="$(_get "$url" | sed 's/<[a-zA-Z\/][^>]*>//g' | tr -s "\n" | _tail_n 1)" else _err "Unsupported method" return 1 From 2febdfc3636614a226e00fe27a419baa8ffe9d6c Mon Sep 17 00:00:00 2001 From: Simon Wydooghe Date: Fri, 17 Apr 2020 15:53:15 +0200 Subject: [PATCH 0705/2234] Fix: allow removal of email address as contact It seems the current code doesn't allow for removing the email address from the contact field. This fixes that. This only removes the email address if an explicit empty email address is specified on the command line or in the account.conf file. If it is left unspecified on the command line it still just uses whatever was configured in the account.conf. --- acme.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acme.sh b/acme.sh index f672710d..763d8a1c 100755 --- a/acme.sh +++ b/acme.sh @@ -3512,6 +3512,8 @@ updateaccount() { if [ "$ACME_VERSION" = "2" ]; then if [ "$ACCOUNT_EMAIL" ]; then updjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"]}' + else + updjson='{"contact": []}' fi else # ACMEv1: Updates happen the same way a registration is done. From d842ccb287588de346c40bcc26c531e0b183e4bb Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 18:51:08 +0800 Subject: [PATCH 0706/2234] fix format error --- dnsapi/dns_arvan.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 341c8c17..edeb56ca 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -8,7 +8,7 @@ ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" #Report Bugs here: https://github.com/Neilpang/acme.sh # ######## Public functions ##################### - + #Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_arvan_add() { fulldomain=$1 @@ -22,7 +22,7 @@ dns_arvan_add() { _err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys" return 1 fi - #save the api token to the account conf file. + #save the api token to the account conf file. _saveaccountconf_mutable Arvan_Token "$Arvan_Token" _debug "First detect the root zone" @@ -150,7 +150,7 @@ _arvan_rest() { export _H1="Authorization: $token_trimmed" if [ "$mtd" = "DELETE" ]; then - # DELETE Request shouldn't have Content-Type + #DELETE Request shouldn't have Content-Type _debug data "$data" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" elif [ "$mtd" = "POST" ]; then @@ -160,4 +160,4 @@ _arvan_rest() { else response="$(_get "$ARVAN_API_URL/$ep$data")" fi -} \ No newline at end of file +} From ed7a945261c96d8b721a53c10fd9eaf00ce54182 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 18:59:33 +0800 Subject: [PATCH 0707/2234] add comment message. --- .github/auto-comment.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml index 1e7b389e..1c3b746e 100644 --- a/.github/auto-comment.yml +++ b/.github/auto-comment.yml @@ -10,8 +10,14 @@ issuesOpened: > please also provide the log with `--debug 2`. + 同时请提供调试输出 `--debug 2` + see: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh - + + Without `--debug 2` log, your issue will NEVER get replied. + + 没有调试输出, 你的 issue 不会得到任何解答. + pullRequestOpened: > First, never send a PR to `master` branch, it will never be accepted. Please send to the `dev` branch instead. From 1564742b76d2e3d20d7c55411d008aaa4cbef402 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 19:38:38 +0800 Subject: [PATCH 0708/2234] add comments --- .github/auto-comment.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml index 1c3b746e..520b3ce3 100644 --- a/.github/auto-comment.yml +++ b/.github/auto-comment.yml @@ -4,7 +4,7 @@ issuesOpened: > 如果有 bug, 请先更新到最新版试试: - ```sh + ``` acme.sh --upgrade ``` @@ -17,10 +17,10 @@ issuesOpened: > Without `--debug 2` log, your issue will NEVER get replied. 没有调试输出, 你的 issue 不会得到任何解答. - + pullRequestOpened: > - First, never send a PR to `master` branch, it will never be accepted. Please send to the `dev` branch instead. + First, NEVER send a PR to `master` branch, it will NEVER be accepted. Please send to the `dev` branch instead. If this is a PR to support new DNS API or new notification API, please read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide @@ -29,6 +29,12 @@ pullRequestOpened: > Then add your usage here: https://github.com/acmesh-official/acme.sh/wiki/dnsapi - + + Or some other wiki pages: + + https://github.com/acmesh-official/acme.sh/wiki/deployhooks + + https://github.com/acmesh-official/acme.sh/wiki/notify + From 1041c9f9fc50eb6aa29de5b882dc7244e9f4024d Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 20:03:48 +0800 Subject: [PATCH 0709/2234] support revoke reason. https://github.com/acmesh-official/acme.sh/issues/2856 --- acme.sh | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 763d8a1c..18c8e007 100755 --- a/acme.sh +++ b/acme.sh @@ -138,6 +138,8 @@ _NOTIFY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/notify" _SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo" +_REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -5456,6 +5458,7 @@ uninstallcronjob() { } +#domain isECC revokeReason revoke() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then @@ -5464,7 +5467,10 @@ revoke() { fi _isEcc="$2" - + _reason="$3" + if [ -z "$_reason" ]; then + _reason="0" + fi _initpath "$Le_Domain" "$_isEcc" if [ ! -f "$DOMAIN_CONF" ]; then _err "$Le_Domain is not a issued domain, skip." @@ -5486,7 +5492,7 @@ revoke() { _initAPI if [ "$ACME_VERSION" = "2" ]; then - data="{\"certificate\": \"$cert\"}" + data="{\"certificate\": \"$cert\",\"reason\":$_reason}" else data="{\"resource\": \"revoke-cert\", \"certificate\": \"$cert\"}" fi @@ -6295,6 +6301,7 @@ Parameters: 0: Bulk mode. Send all the domain's notifications in one message(mail). 1: Cert mode. Send a message for every single cert. --notify-hook [hookname] Set the notify hook + --revoke-reason [0-10] The reason for '--revoke' command. See: $_REVOKE_WIKI " } @@ -6470,6 +6477,7 @@ _process() { _notify_hook="" _notify_level="" _notify_mode="" + _revoke_reason="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -6941,6 +6949,14 @@ _process() { fi _notify_mode="$_nmode" shift + ;; + --revoke-reason) + _revoke_reason="$2" + if _startswith "$_revoke_reason" "-"; then + _err "'$_revoke_reason' is not a integer for '$1'" + return 1 + fi + shift ;; *) _err "Unknown parameter : $1" @@ -7029,7 +7045,7 @@ _process() { renewAll "$_stopRenewOnError" ;; revoke) - revoke "$_domain" "$_ecc" + revoke "$_domain" "$_ecc" "$_revoke_reason" ;; remove) remove "$_domain" "$_ecc" From a995333081876b7f9a06e2c824ed1127d784ebaf Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 22:34:32 +0800 Subject: [PATCH 0710/2234] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 18c8e007..57f45905 100755 --- a/acme.sh +++ b/acme.sh @@ -6950,7 +6950,7 @@ _process() { _notify_mode="$_nmode" shift ;; - --revoke-reason) + --revoke-reason) _revoke_reason="$2" if _startswith "$_revoke_reason" "-"; then _err "'$_revoke_reason' is not a integer for '$1'" From 08cc7587ab8042caf4ddab9e4d6910a62797c2ea Mon Sep 17 00:00:00 2001 From: Wolfram Webers Date: Sat, 18 Apr 2020 18:11:24 +0200 Subject: [PATCH 0711/2234] - Adding fix for latest "os-bind" plugin --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index b2a3746f..ec7d2277 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"allownotifyslave\":{\"\":{[^}]*}},\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" From 3bad815982841302a9d55d073fff9d69937cf1ab Mon Sep 17 00:00:00 2001 From: Nils Sandmann Date: Sat, 18 Apr 2020 18:52:08 +0200 Subject: [PATCH 0712/2234] Better error handling on login, return correct return code --- dnsapi/dns_inwx.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index 7c08d72e..4995ca1d 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -148,17 +148,21 @@ _inwx_login() { - ' $INWX_User $INWX_Password) + ' "$INWX_User" "$INWX_Password") response="$(_post "$xml_content" "$INWX_Api" "" "POST")" _H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") export _H1 + if ! _contains "$response" "code1000"; then + _err "INWX API: Authentication error (username/password correct?)" + return 1 + fi + #https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71 - if _contains "$response" "code1000" \ - && _contains "$response" "tfaGOOGLE-AUTH"; then + if _contains "$response" "tfaGOOGLE-AUTH"; then if [ -z "$INWX_Shared_Secret" ]; then - _err "Mobile TAN detected." + _err "INWX API: Mobile TAN detected." _err "Please define a shared secret." return 1 fi @@ -191,6 +195,11 @@ _inwx_login() { ' "$tan") response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + if ! _contains "$response" "code1000"; then + _err "INWX API: Mobile TAN not correct." + return 1 + fi fi } From 5d00edc896dfbd09d961ea6f76843cf7c18b6083 Mon Sep 17 00:00:00 2001 From: Nils Sandmann Date: Sat, 18 Apr 2020 18:54:43 +0200 Subject: [PATCH 0713/2234] Fix multiple domains with 2FA, reuse session cookie --- dnsapi/dns_inwx.sh | 50 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index 4995ca1d..50b4b10c 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -34,6 +34,10 @@ dns_inwx_add() { _saveaccountconf_mutable INWX_Password "$INWX_Password" _saveaccountconf_mutable INWX_Shared_Secret "$INWX_Shared_Secret" + if ! _inwx_login; then + return 1 + fi + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -64,6 +68,10 @@ dns_inwx_rm() { return 1 fi + if ! _inwx_login; then + return 1 + fi + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -123,8 +131,42 @@ dns_inwx_rm() { #################### Private functions below ################################## +_inwx_check_cookie() { + INWX_Cookie="${INWX_Cookie:-$(_readaccountconf_mutable INWX_Cookie)}" + if [ -z "$INWX_Cookie" ]; then + _debug "No cached cookie found" + return 1 + fi + _H1="$INWX_Cookie" + export _H1 + + xml_content=$(printf ' + + account.info + ') + + response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + if _contains "$response" "code1000"; then + _debug "Cached cookie still valid" + return 0 + fi + + _debug "Cached cookie no longer valid" + _H1="" + export _H1 + INWX_Cookie="" + _saveaccountconf_mutable INWX_Cookie "$INWX_Cookie" + return 1 +} + _inwx_login() { + if _inwx_check_cookie; then + _debug "Already logged in" + return 0 + fi + xml_content=$(printf ' account.login @@ -151,8 +193,12 @@ _inwx_login() { ' "$INWX_User" "$INWX_Password") response="$(_post "$xml_content" "$INWX_Api" "" "POST")" - _H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") + + INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") + _H1=$INWX_Cookie export _H1 + export INWX_Cookie + _saveaccountconf_mutable INWX_Cookie "$INWX_Cookie" if ! _contains "$response" "code1000"; then _err "INWX API: Authentication error (username/password correct?)" @@ -212,8 +258,6 @@ _get_root() { i=2 p=1 - _inwx_login - xml_content=' nameserver.list From a9c4b8dd1a294cfd385a8cc5dd3ea47b3e98156b Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 19 Apr 2020 00:44:48 +0200 Subject: [PATCH 0714/2234] feat: Microsoft Teams notify --- notify/teams.sh | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 notify/teams.sh diff --git a/notify/teams.sh b/notify/teams.sh new file mode 100644 index 00000000..752c24c6 --- /dev/null +++ b/notify/teams.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env sh + +#Support Microsoft Teams webhooks + +#TEAMS_WEBHOOK_URL="" +#TEAMS_THEME_COLOR="" +#TEAMS_SUCCESS_COLOR="" +#TEAMS_ERROR_COLOR="" +#TEAMS_SKIP_COLOR="" + +teams_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + TEAMS_WEBHOOK_URL="${TEAMS_WEBHOOK_URL:-$(_readaccountconf_mutable TEAMS_WEBHOOK_URL)}" + if [ -z "$TEAMS_WEBHOOK_URL" ]; then + TEAMS_WEBHOOK_URL="" + _err "You didn't specify a Microsoft Teams webhook url TEAMS_WEBHOOK_URL yet." + return 1 + fi + _saveaccountconf_mutable TEAMS_WEBHOOK_URL "$TEAMS_WEBHOOK_URL" + + TEAMS_THEME_COLOR="${TEAMS_THEME_COLOR:-$(_readaccountconf_mutable TEAMS_THEME_COLOR)}" + if [ -n "$TEAMS_THEME_COLOR" ]; then + _saveaccountconf_mutable TEAMS_THEME_COLOR "$TEAMS_THEME_COLOR" + fi + + TEAMS_SUCCESS_COLOR="${TEAMS_SUCCESS_COLOR:-$(_readaccountconf_mutable TEAMS_SUCCESS_COLOR)}" + if [ -n "$TEAMS_SUCCESS_COLOR" ]; then + _saveaccountconf_mutable TEAMS_SUCCESS_COLOR "$TEAMS_SUCCESS_COLOR" + fi + + TEAMS_ERROR_COLOR="${TEAMS_ERROR_COLOR:-$(_readaccountconf_mutable TEAMS_ERROR_COLOR)}" + if [ -n "$TEAMS_ERROR_COLOR" ]; then + _saveaccountconf_mutable TEAMS_ERROR_COLOR "$TEAMS_ERROR_COLOR" + fi + + TEAMS_SKIP_COLOR="${TEAMS_SKIP_COLOR:-$(_readaccountconf_mutable TEAMS_SKIP_COLOR)}" + if [ -n "$TEAMS_SKIP_COLOR" ]; then + _saveaccountconf_mutable TEAMS_SKIP_COLOR "$TEAMS_SKIP_COLOR" + fi + + export _H1="Content-Type: application/json" + + _subject=$(echo "$_subject" | _json_encode) + _content=$(echo "$_content" | _json_encode) + + case "$_statusCode" in + 0) + _color="$TEAMS_SUCCESS_COLOR" + ;; + 1) + _color="$TEAMS_ERROR_COLOR" + ;; + 2) + _color="$TEAMS_SKIP_COLOR" + ;; + esac + _color="$(echo "${_color:-$TEAMS_THEME_COLOR}" | tr -cd '[:xdigit:]')" + + _data="{\"title\": \"$_subject\"," + if [ -n "$_color" ]; then + _data="$_data\"themeColor\": \"$_color\", " + fi + _data="$_data\"text\": \"$_content\"}" + + if _post "$_data" "$TEAMS_WEBHOOK_URL"; then + # shellcheck disable=SC2154 + if ! _contains "$response" error; then + _info "teams send success." + return 0 + fi + fi + _err "teams send error." + _err "$response" + return 1 +} From 74cdcde4496b17c6cc0a55d98592ce954b875b54 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 19 Apr 2020 23:59:35 +0200 Subject: [PATCH 0715/2234] fix: remove :xdigit: --- notify/teams.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/teams.sh b/notify/teams.sh index 752c24c6..d1de1c57 100644 --- a/notify/teams.sh +++ b/notify/teams.sh @@ -58,7 +58,7 @@ teams_send() { _color="$TEAMS_SKIP_COLOR" ;; esac - _color="$(echo "${_color:-$TEAMS_THEME_COLOR}" | tr -cd '[:xdigit:]')" + _color="$(echo "${_color:-$TEAMS_THEME_COLOR}" | tr -cd 'a-fA-F0-9')" _data="{\"title\": \"$_subject\"," if [ -n "$_color" ]; then From 9bad11ec79e23cf617b9b07c91537a3f7962c4d4 Mon Sep 17 00:00:00 2001 From: wurzelpanzer <32928046+wurzelpanzer@users.noreply.github.com> Date: Mon, 20 Apr 2020 08:49:08 +0200 Subject: [PATCH 0716/2234] easyDNS API out of beta Added new links to API docs and API access signup --- dnsapi/dns_easydns.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh index ca8faab2..f466f1e2 100644 --- a/dnsapi/dns_easydns.sh +++ b/dnsapi/dns_easydns.sh @@ -4,8 +4,7 @@ # # easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh # -# Please note: # API is currently beta and subject to constant change -# http://sandbox.rest.easydns.net:3000/ +# API Documentation: https://sandbox.rest.easydns.net:3001/ # # Author: wurzelpanzer [wurzelpanzer@maximolider.net] # Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2647 @@ -25,7 +24,7 @@ dns_easydns_add() { EASYDNS_Key="${EASYDNS_Key:-$(_readaccountconf_mutable EASYDNS_Key)}" if [ -z "$EASYDNS_Token" ] || [ -z "$EASYDNS_Key" ]; then - _err "You didn't specify an easydns.net token or api key. Please sign up at http://docs.sandbox.rest.easydns.net/beta_signup.php" + _err "You didn't specify an easydns.net token or api key. Signup at https://cp.easydns.com/manage/security/api/signup.php" return 1 else _saveaccountconf_mutable EASYDNS_Token "$EASYDNS_Token" From c06db30a65d970f914a06020d872573d656cd11a Mon Sep 17 00:00:00 2001 From: Viktor G Date: Mon, 20 Apr 2020 21:05:40 +0300 Subject: [PATCH 0717/2234] DNS Loopia min 300 TTL --- dnsapi/dns_loopia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 1316a274..7760b53e 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -217,7 +217,7 @@ _loopia_add_record() { ttl - 60 + 300 rdata From c49b40ee95e28a8bac57e71001f7d65715e98063 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Tue, 21 Apr 2020 11:43:08 +0200 Subject: [PATCH 0718/2234] Allow old and new API response CLOSES #2480 --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index ec7d2277..069f6c32 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"allownotifyslave\":{\"\":{[^}]*}},\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\"(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" From 24925a17392147c857d20a6b0272ea7da0bf1843 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Wed, 22 Apr 2020 21:13:52 +0200 Subject: [PATCH 0719/2234] feat: add default colors --- notify/teams.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/notify/teams.sh b/notify/teams.sh index d1de1c57..6b360ae5 100644 --- a/notify/teams.sh +++ b/notify/teams.sh @@ -14,6 +14,10 @@ teams_send() { _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped _debug "_statusCode" "$_statusCode" + _color_success="2cbe4e" # green + _color_danger="cb2431" # red + _color_muted="586069" # gray + TEAMS_WEBHOOK_URL="${TEAMS_WEBHOOK_URL:-$(_readaccountconf_mutable TEAMS_WEBHOOK_URL)}" if [ -z "$TEAMS_WEBHOOK_URL" ]; then TEAMS_WEBHOOK_URL="" @@ -49,16 +53,20 @@ teams_send() { case "$_statusCode" in 0) - _color="$TEAMS_SUCCESS_COLOR" + _color="${TEAMS_SUCCESS_COLOR:-$_color_success}" ;; 1) - _color="$TEAMS_ERROR_COLOR" + _color="${TEAMS_ERROR_COLOR:-$_color_danger}" ;; 2) - _color="$TEAMS_SKIP_COLOR" + _color="${TEAMS_SKIP_COLOR:-$_color_muted}" ;; esac - _color="$(echo "${_color:-$TEAMS_THEME_COLOR}" | tr -cd 'a-fA-F0-9')" + + _color=$(echo "$_color" | tr -cd 'a-fA-F0-9') + if [ -z "$_color" ]; then + _color=$(echo "${TEAMS_THEME_COLOR:-$_color_muted}" | tr -cd 'a-fA-F0-9') + fi _data="{\"title\": \"$_subject\"," if [ -n "$_color" ]; then From 6ba1eda96fb9afb7382794468ee47e3baf61806e Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 25 Apr 2020 22:44:00 +0800 Subject: [PATCH 0720/2234] fix https://github.com/acmesh-official/acme.sh/issues/2883#issuecomment-619215961 --- acme.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 57f45905..97d71a22 100755 --- a/acme.sh +++ b/acme.sh @@ -1174,9 +1174,8 @@ _createcsr() { _info "Multi domain" "$alt" printf -- "\nsubjectAltName=$alt" >>"$csrconf" fi - if [ "$Le_OCSP_Staple" ] || [ "$Le_OCSP_Stable" ]; then + if [ "$Le_OCSP_Staple" = "1" ]; then _savedomainconf Le_OCSP_Staple "$Le_OCSP_Staple" - _cleardomainconf Le_OCSP_Stable printf -- "\nbasicConstraints = CA:FALSE\n1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05" >>"$csrconf" fi From 3ff48b8559678b0e02e25871eae29694f77d26ce Mon Sep 17 00:00:00 2001 From: Bas van Ritbergen Date: Mon, 27 Apr 2020 15:34:20 +0200 Subject: [PATCH 0721/2234] Update dns_openprovider.sh #2104 Fix wildcard handling & custom NS config for OpenProvider DNS --- dnsapi/dns_openprovider.sh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh index ad1e5838..84058f60 100755 --- a/dnsapi/dns_openprovider.sh +++ b/dnsapi/dns_openprovider.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/bin/bash # This is the OpenProvider API wrapper for acme.sh # @@ -59,16 +59,17 @@ dns_openprovider_add() { break fi - items="$(echo "$items" | sed "s|${item}||")" + tmpitem="$(echo "$item" | sed 's/\*/\\*/g')" + items="$(echo "$items" | sed "s|${tmpitem}||")" results_retrieved="$(_math "$results_retrieved" + 1)" new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)\.'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" if [ -z "$new_item" ]; then - # Base record + # Domain apex new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" fi - if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then + if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA|NS)<\/type>.*")" ]; then _debug "not an allowed record type, skipping" "$new_item" continue fi @@ -86,7 +87,7 @@ dns_openprovider_add() { _debug "Creating acme record" acme_record="$(echo "$fulldomain" | sed -e "s/.$_domain_name.$_domain_extension$//")" - _openprovider_request "$(printf '%s%smaster%s%sTXT%s86400' "$_domain_name" "$_domain_extension" "$existing_items" "$acme_record" "$txtvalue")" + _openprovider_request "$(printf '%s%smaster%s%sTXT%s600' "$_domain_name" "$_domain_extension" "$existing_items" "$acme_record" "$txtvalue")" return 0 } @@ -136,7 +137,8 @@ dns_openprovider_rm() { break fi - items="$(echo "$items" | sed "s|${item}||")" + tmpitem="$(echo "$item" | sed 's/\*/\\*/g')" + items="$(echo "$items" | sed "s|${tmpitem}||")" results_retrieved="$(_math "$results_retrieved" + 1)" if ! echo "$item" | grep -v "$fulldomain"; then @@ -147,11 +149,11 @@ dns_openprovider_rm() { new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)\.'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" if [ -z "$new_item" ]; then - # Base record + # domain apex new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" fi - if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then + if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA|NS)<\/type>.*")" ]; then _debug "not an allowed record type, skipping" "$new_item" continue fi @@ -205,7 +207,8 @@ _get_root() { break fi - items="$(echo "$items" | sed "s|${item}||")" + tmpitem="$(echo "$item" | sed 's/\*/\\*/g')" + items="$(echo "$items" | sed "s|${tmpitem}||")" results_retrieved="$(_math "$results_retrieved" + 1)" From 1bfd0f014984c47b9b97da8709628a030a580fd9 Mon Sep 17 00:00:00 2001 From: Bas van Ritbergen Date: Mon, 27 Apr 2020 15:41:50 +0200 Subject: [PATCH 0722/2234] Update dns_openprovider.sh fixed shebang shell to be as suggested --- dnsapi/dns_openprovider.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh index 84058f60..0a9e5ade 100755 --- a/dnsapi/dns_openprovider.sh +++ b/dnsapi/dns_openprovider.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env sh # This is the OpenProvider API wrapper for acme.sh # From da957a3caf587ad82fd0d11b8c5078d9b31f291b Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 29 Apr 2020 10:12:29 +0800 Subject: [PATCH 0723/2234] fix https://github.com/acmesh-official/acme.sh/issues/2888 --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 43bc1428..3e66a585 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -59,7 +59,7 @@ dns_cf_add() { _debug "Getting txt records" _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain" - if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then + if ! echo "$response" | tr -d " " | grep \"success\":true >/dev/null; then _err "Error" return 1 fi From 1209b9b86eb994f76582aada3083a43806170a8b Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 29 Apr 2020 10:15:13 +0800 Subject: [PATCH 0724/2234] fix https://github.com/acmesh-official/acme.sh/issues/2888 --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 3e66a585..8d2e23ba 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -110,7 +110,7 @@ dns_cf_rm() { _debug "Getting txt records" _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain&content=$txtvalue" - if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then + if ! echo "$response" | tr -d " " | grep \"success\":true >/dev/null; then _err "Error: $response" return 1 fi From b19799bc72599716f2a9067ecef10f42d0d6372c Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 29 Apr 2020 10:19:35 +0800 Subject: [PATCH 0725/2234] fix https://github.com/acmesh-official/acme.sh/issues/2888 --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 8d2e23ba..652c3769 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -120,7 +120,7 @@ dns_cf_rm() { if [ "$count" = "0" ]; then _info "Don't need to remove." else - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + record_id=$(echo "$response" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1) _debug "record_id" "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id to remove." From ad9f488df60fa5ceb8f4a269f3119f378395ec46 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 29 Apr 2020 10:38:21 +0800 Subject: [PATCH 0726/2234] fix https://github.com/acmesh-official/acme.sh/issues/2888 --- dnsapi/dns_cf.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 652c3769..b4e9f632 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -115,12 +115,12 @@ dns_cf_rm() { return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + count=$(echo "$response" | _egrep_o "\"count\": *[^,]*" | cut -d : -f 2 | tr -d " ") _debug count "$count" if [ "$count" = "0" ]; then _info "Don't need to remove." else - record_id=$(echo "$response" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1) + record_id=$(echo "$response" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") _debug "record_id" "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id to remove." @@ -152,7 +152,7 @@ _get_root() { return 1 else if _contains "$response" '"success":true'; then - _domain=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + _domain=$(echo "$response" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") if [ "$_domain" ]; then _cutlength=$((${#domain} - ${#_domain} - 1)) _sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cutlength") @@ -186,7 +186,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then - _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + _domain_id=$(echo "$response" | _egrep_o "\[.\"id\": *\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 58c2c701468b70df258c210ad7daff4a442d57af Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 29 Apr 2020 10:42:17 +0800 Subject: [PATCH 0727/2234] fix https://github.com/acmesh-official/acme.sh/issues/2888 --- dnsapi/dns_cf.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index b4e9f632..36799dcd 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -130,7 +130,7 @@ dns_cf_rm() { _err "Delete record error." return 1 fi - _contains "$response" '"success":true' + echo "$response" | tr -d " " | grep \"success\":true >/dev/null fi } @@ -151,7 +151,7 @@ _get_root() { if ! _cf_rest GET "zones/$CF_Zone_ID"; then return 1 else - if _contains "$response" '"success":true'; then + if echo "$response" | tr -d " " | grep \"success\":true >/dev/null; then _domain=$(echo "$response" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") if [ "$_domain" ]; then _cutlength=$((${#domain} - ${#_domain} - 1)) From 45e6000619d65f15caefa6ac738789ae68a16274 Mon Sep 17 00:00:00 2001 From: ThiloGa Date: Fri, 1 May 2020 06:25:19 +0200 Subject: [PATCH 0728/2234] adding support for dyndnsfree.de --- dnsapi/dns_df.sh | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 dnsapi/dns_df.sh diff --git a/dnsapi/dns_df.sh b/dnsapi/dns_df.sh new file mode 100644 index 00000000..c71f0b44 --- /dev/null +++ b/dnsapi/dns_df.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env sh + +######################################################################## +# https://dyndnsfree.de hook script for acme.sh +# +# Environment variables: +# +# - $DF_user (your dyndnsfree.de API username) +# - $DF_password (your dyndnsfree.de API password) +# +# Author: Thilo Gass +# Git repo: https://github.com/ThiloGa/acme.sh + +#-- dns_df_add() - Add TXT record -------------------------------------- +# Usage: dns_df_add _acme-challenge.subdomain.domain.com "XyZ123..." + +dyndnsfree_api="https://dynup.de/acme.php" + +dns_df_add() { + fulldomain=$1 + txt_value=$2 + _info "Using DNS-01 dyndnsfree.de hook" + + DF_user="${DF_user:-$(_readaccountconf_mutable DF_user)}" + DF_password="${DF_password:-$(_readaccountconf_mutable DF_password)}" + if [ -z "$DF_user" ] || [ -z "$DF_password" ]; then + DF_user="" + DF_password="" + _err "No auth details provided. Please set user credentials using the \$DF_user and \$DF_password environment variables." + return 1 + fi + #save the api user and sha256 password to the account conf file. + _debug "Save user and hash" + _saveaccountconf_mutable DF_user "$DF_user" + _saveaccountconf_mutable DF_password "$DF_password" + + domain="$(printf "%s" "$fulldomain" | cut -d"." -f2-)" + + get="$dyndnsfree_api?username=$DF_user&password=$DF_password&hostname=$domain&add_hostname=$fulldomain&txt=$txt_value" + + if ! erg="$(_get "$get")"; then + _err "error Adding $fulldomain TXT: $txt_value" + return 1 + fi + + if _contains "$erg" "success"; then + _info "Success, TXT Added, OK" + else + _err "error Adding $fulldomain TXT: $txt_value erg: $erg" + return 1 + fi + + _debug "ok Auto $fulldomain TXT: $txt_value erg: $erg" + return 0 +} + +dns_df_rm() { + + fulldomain=$1 + txtvalue=$2 + _info "TXT enrty in $fulldomain is deleted automatically" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + +} From c3d7f5b28b1dd5298dc398e012f2c5cc75b5af3f Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 1 May 2020 23:44:56 +0800 Subject: [PATCH 0729/2234] build on docker hub --- .github/workflows/dockerhub.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/dockerhub.yml diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml new file mode 100644 index 00000000..f1c0025d --- /dev/null +++ b/.github/workflows/dockerhub.yml @@ -0,0 +1,16 @@ + +name: Build DockerHub +on: + push: + branches: [ master, dev ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: trigger + run: curl -X POST https://hub.docker.com/api/build/v1/source/1813a660-2ee5-4583-a238-dd54e9a6ebac/trigger/c8cd9f1f-f269-45bc-9750-a08327257f62/call/ + + + + From 22f8ab110e84d9d6dfbf6223afe4fecddbd4d8b9 Mon Sep 17 00:00:00 2001 From: ThiloGa <61890902+ThiloGa@users.noreply.github.com> Date: Sat, 2 May 2020 08:26:26 +0200 Subject: [PATCH 0730/2234] typo fixing --- dnsapi/dns_df.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_df.sh b/dnsapi/dns_df.sh index c71f0b44..d5410d95 100644 --- a/dnsapi/dns_df.sh +++ b/dnsapi/dns_df.sh @@ -5,8 +5,8 @@ # # Environment variables: # -# - $DF_user (your dyndnsfree.de API username) -# - $DF_password (your dyndnsfree.de API password) +# - $DF_user (your dyndnsfree.de username) +# - $DF_password (your dyndnsfree.de password) # # Author: Thilo Gass # Git repo: https://github.com/ThiloGa/acme.sh @@ -30,7 +30,7 @@ dns_df_add() { return 1 fi #save the api user and sha256 password to the account conf file. - _debug "Save user and hash" + _debug "Save user and password" _saveaccountconf_mutable DF_user "$DF_user" _saveaccountconf_mutable DF_password "$DF_password" From 3b0d7bc4adaf41e04e5ef78f6c69bd66864055ca Mon Sep 17 00:00:00 2001 From: ThiloGa <61890902+ThiloGa@users.noreply.github.com> Date: Sat, 2 May 2020 08:29:44 +0200 Subject: [PATCH 0731/2234] typo fixing --- dnsapi/dns_df.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_df.sh b/dnsapi/dns_df.sh index d5410d95..c0499ddf 100644 --- a/dnsapi/dns_df.sh +++ b/dnsapi/dns_df.sh @@ -29,7 +29,7 @@ dns_df_add() { _err "No auth details provided. Please set user credentials using the \$DF_user and \$DF_password environment variables." return 1 fi - #save the api user and sha256 password to the account conf file. + #save the api user and password to the account conf file. _debug "Save user and password" _saveaccountconf_mutable DF_user "$DF_user" _saveaccountconf_mutable DF_password "$DF_password" From cf5952f5081b8f4a1ac7e5e6f6ae993667ae369c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20B=C3=BCnemann?= Date: Sat, 2 May 2020 22:14:21 +0200 Subject: [PATCH 0732/2234] fix haproxy deploy hook ocsp update fixes ocsp reponse update failing with `Responder Error: unauthorized (6)` by removing `-no_nonce` switch from `openssl oscp` command . --- deploy/haproxy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 3cd2a80a..0a45ee07 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -233,7 +233,6 @@ haproxy_deploy() { -header Host${_header_sep}\"${_ocsp_host}\" \ -respout \"${_ocsp}\" \ -verify_other \"${_issuer}\" \ - -no_nonce \ ${_cafile_argument} \ | grep -q \"${_pem}: good\"" _debug _openssl_ocsp_cmd "${_openssl_ocsp_cmd}" From eab35605e47331d378292b0e6e32db466954b18e Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 3 May 2020 11:01:02 +0800 Subject: [PATCH 0733/2234] remove sudo --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 155ec64b..91da2731 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: shell -sudo: required dist: trusty os: From 9044adecb58e5d7b91056688ce1ca60543d7c3d3 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 4 May 2020 08:43:47 +0800 Subject: [PATCH 0734/2234] start 2.8.7 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 97d71a22..dd47481d 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.6 +VER=2.8.7 PROJECT_NAME="acme.sh" From 81036894c01d8a3793215f65dfd1f1d03c7d94d5 Mon Sep 17 00:00:00 2001 From: Philipp Bandow <43735306+philband@users.noreply.github.com> Date: Thu, 7 May 2020 15:28:00 +0200 Subject: [PATCH 0735/2234] Add new DNS Provider: Njalla --- dnsapi/dns_njalla.sh | 169 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 dnsapi/dns_njalla.sh diff --git a/dnsapi/dns_njalla.sh b/dnsapi/dns_njalla.sh new file mode 100644 index 00000000..3b8b9ac7 --- /dev/null +++ b/dnsapi/dns_njalla.sh @@ -0,0 +1,169 @@ +#!/usr/bin/env sh + +# +#NJALLA_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" + +NJALLA_Api="https://njal.la/api/1/" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_njalla_add() { + fulldomain=$1 + txtvalue=$2 + + NJALLA_Token="${NJALLA_Token:-$(_readaccountconf_mutable NJALLA_Token)}" + + if [ "$NJALLA_Token" ]; then + _saveaccountconf_mutable NJALLA_Token "$NJALLA_Token" + else + NJALLA_Token="" + _err "You didn't specify a Njalla api token yet." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so + # we can not use updating anymore. + # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + # _debug count "$count" + # if [ "$count" = "0" ]; then + _info "Adding record" + if _njalla_rest "{\"method\":\"add-record\",\"params\":{\"domain\":\"$_domain\",\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}}"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_njalla_rm() { + fulldomain=$1 + txtvalue=$2 + + NJALLA_Token="${NJALLA_Token:-$(_readaccountconf_mutable NJALLA_Token)}" + + if [ "$NJALLA_Token" ]; then + _saveaccountconf_mutable NJALLA_Token "$NJALLA_Token" + else + NJALLA_Token="" + _err "You didn't specify a Njalla api token yet." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting records for domain" + if ! _njalla_rest "{\"method\":\"list-records\",\"params\":{\"domain\":\"${_domain}\"}}"; then + return 1 + fi + + if ! echo "$response" | tr -d " " | grep "\"id\":" >/dev/null; then + _err "Error: $response" + return 1 + fi + + records=$(echo "$response" | _egrep_o "\"records\":\s?\[(.*)\]\}" | _egrep_o "\[.*\]" | _egrep_o "\{[^\{\}]*\"id\":[^\{\}]*\}") + count=$(echo "$records" | wc -l) + _debug count "$count" + + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + echo "$records" | while read -r record ; do + record_name=$(echo "$record" | _egrep_o "\"name\":\s?\"[^\"]*\"" | cut -d : -f 2 | tr -d " " | tr -d \") + record_content=$(echo "$record" | _egrep_o "\"content\":\s?\"[^\"]*\"" | cut -d : -f 2 | tr -d " " | tr -d \") + record_id=$(echo "$record" | _egrep_o "\"id\":\s?[0-9]+" | cut -d : -f 2 | tr -d " " | tr -d \") + if [ "$_sub_domain" = "$record_name" ]; then + if [ "$txtvalue" = "$record_content" ]; then + _debug "record_id" "$record_id" + if ! _njalla_rest "{\"method\":\"remove-record\",\"params\":{\"domain\":\"${_domain}\",\"id\":${record_id}}}"; then + _err "Delete record error." + return 1 + fi + echo "$response" | tr -d " " | grep "\"result\"" >/dev/null + fi + fi + done + fi + +} + +#################### 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=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + + if ! _njalla_rest "{\"method\":\"get-domain\",\"params\":{\"domain\":\"${h}\"}}"; then + return 1 + fi + + if _contains "$response" "\"$h\""; then + _domain_returned=$(echo "$response" | _egrep_o "\{\"name\": *\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ") + if [ "$_domain_returned" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_njalla_rest() { + data="$1" + + token_trimmed=$(echo "$NJALLA_Token" | tr -d '"') + + export _H1="Content-Type: application/json" + export _H2="Accept: application/json" + export _H3="Authorization: Njalla $token_trimmed" + + _debug data "$data" + response="$(_post "$data" "$NJALLA_Api" "" "POST")" + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 9bbcfead67638bcd602c50a8051e042bfa02360b Mon Sep 17 00:00:00 2001 From: Philipp Bandow <43735306+philband@users.noreply.github.com> Date: Thu, 7 May 2020 15:37:59 +0200 Subject: [PATCH 0736/2234] Bugfix shell format error --- dnsapi/dns_njalla.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_njalla.sh b/dnsapi/dns_njalla.sh index 3b8b9ac7..f91a1ed5 100644 --- a/dnsapi/dns_njalla.sh +++ b/dnsapi/dns_njalla.sh @@ -90,7 +90,7 @@ dns_njalla_rm() { if [ "$count" = "0" ]; then _info "Don't need to remove." else - echo "$records" | while read -r record ; do + echo "$records" | while read -r record; do record_name=$(echo "$record" | _egrep_o "\"name\":\s?\"[^\"]*\"" | cut -d : -f 2 | tr -d " " | tr -d \") record_content=$(echo "$record" | _egrep_o "\"content\":\s?\"[^\"]*\"" | cut -d : -f 2 | tr -d " " | tr -d \") record_id=$(echo "$record" | _egrep_o "\"id\":\s?[0-9]+" | cut -d : -f 2 | tr -d " " | tr -d \") From d507979ec1b6ad67b82ac36cb23ed52384fae9a3 Mon Sep 17 00:00:00 2001 From: Philipp Bandow <43735306+philband@users.noreply.github.com> Date: Thu, 7 May 2020 15:41:09 +0200 Subject: [PATCH 0737/2234] Make CI happy: Remove extraneous new line --- dnsapi/dns_njalla.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_njalla.sh b/dnsapi/dns_njalla.sh index f91a1ed5..804b0772 100644 --- a/dnsapi/dns_njalla.sh +++ b/dnsapi/dns_njalla.sh @@ -128,7 +128,6 @@ _get_root() { return 1 fi - if ! _njalla_rest "{\"method\":\"get-domain\",\"params\":{\"domain\":\"${h}\"}}"; then return 1 fi From d904df57ca48cb01e71b0a6c86d7cb3027b8fb3d Mon Sep 17 00:00:00 2001 From: Philipp Bandow <43735306+philband@users.noreply.github.com> Date: Thu, 7 May 2020 15:45:47 +0200 Subject: [PATCH 0738/2234] Bugfix error message in rest function --- dnsapi/dns_njalla.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_njalla.sh b/dnsapi/dns_njalla.sh index 804b0772..e9243288 100644 --- a/dnsapi/dns_njalla.sh +++ b/dnsapi/dns_njalla.sh @@ -160,7 +160,7 @@ _njalla_rest() { response="$(_post "$data" "$NJALLA_Api" "" "POST")" if [ "$?" != "0" ]; then - _err "error $ep" + _err "error $data" return 1 fi _debug2 response "$response" From 036a37e3511f09c8fd33a18fe4fa3c589134423e Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Thu, 7 May 2020 23:19:02 +0200 Subject: [PATCH 0739/2234] Nullify output from lexicon_cmd to prevent getting wrong return codes --- dnsapi/dns_lexicon.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index 516b6eff..34a95599 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -92,7 +92,7 @@ dns_lexicon_add() { _savedomainconf LEXICON_OPTS "$LEXICON_OPTS" # shellcheck disable=SC2086 - $lexicon_cmd "$PROVIDER" $LEXICON_OPTS create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" + $lexicon_cmd "$PROVIDER" $LEXICON_OPTS create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" >/dev/null } @@ -108,6 +108,6 @@ dns_lexicon_rm() { domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999) # shellcheck disable=SC2086 - $lexicon_cmd "$PROVIDER" $LEXICON_OPTS delete "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" + $lexicon_cmd "$PROVIDER" $LEXICON_OPTS delete "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" >/dev/null } From 99793bb2c492a8fe45a6ae8789b304d06be308e0 Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sat, 9 May 2020 12:26:16 +0200 Subject: [PATCH 0740/2234] chore: remove shellcheck disable --- notify/teams.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/notify/teams.sh b/notify/teams.sh index 6b360ae5..e50ea703 100644 --- a/notify/teams.sh +++ b/notify/teams.sh @@ -74,8 +74,7 @@ teams_send() { fi _data="$_data\"text\": \"$_content\"}" - if _post "$_data" "$TEAMS_WEBHOOK_URL"; then - # shellcheck disable=SC2154 + if response=$(_post "$_data" "$TEAMS_WEBHOOK_URL"); then if ! _contains "$response" error; then _info "teams send success." return 0 From 94bf54e7e0f18cbf2e00fd44348c101bd18cfbda Mon Sep 17 00:00:00 2001 From: QDaniel Date: Wed, 13 May 2020 12:14:27 +0200 Subject: [PATCH 0741/2234] INWX fix Domain Limit #1491 --- dnsapi/dns_inwx.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index 50b4b10c..ba789da9 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -261,6 +261,20 @@ _get_root() { xml_content=' nameserver.list + + + + + + pagelimit + + 9999 + + + + + + ' response="$(_post "$xml_content" "$INWX_Api" "" "POST")" From a4c57ee363f253fc9104a449fac957d3ca6cc532 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Wed, 13 May 2020 15:35:51 +0200 Subject: [PATCH 0742/2234] Add TransIP provider --- acme.sh | 2 +- dnsapi/dns_transip.sh | 163 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 dnsapi/dns_transip.sh diff --git a/acme.sh b/acme.sh index 97d71a22..df16c1e7 100755 --- a/acme.sh +++ b/acme.sh @@ -1003,7 +1003,7 @@ _sign() { _sign_openssl="${ACME_OPENSSL_BIN:-openssl} dgst -sign $keyfile " - if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then + if egrep -o "BEGIN( RSA)? PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then $_sign_openssl -$alg | _base64 elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then if ! _signedECText="$($_sign_openssl -sha$__ECC_KEY_LEN | ${ACME_OPENSSL_BIN:-openssl} asn1parse -inform DER)"; then diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh new file mode 100644 index 00000000..c828fa66 --- /dev/null +++ b/dnsapi/dns_transip.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env sh +TRANSIP_Api_Url="https://api.transip.nl/v6" +TRANSIP_Key_File="transip2.key" +TRANSIP_Token_Read_Only="false" +TRANSIP_Token_Global_Key="false" +TRANSIP_Token_Expiration="30 minutes" +# You can't reuse a label token, so we leave this empty normally +TRANSIP_Token_Label="" + +######## Public functions ##################### +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_transip_add() { + fulldomain="$1" + _debug fulldomain="$fulldomain" + txtvalue="$2" + _debug txtvalue="$txtvalue" + _transip_setup $fulldomain || return 1 + _info "Creating TXT record." + if ! _transip_rest POST "domains/$_domain/dns" "{\"dnsEntry\":{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"expire\":300}}"; then + _err "Could not add TXT record." + return 1 + fi + return 0 +} + +dns_transip_rm() { + fulldomain=$1 + _debug fulldomain="$fulldomain" + txtvalue=$2 + _debug txtvalue="$txtvalue" + _transip_setup $fulldomain || return 1 + _info "Removing TXT record." + if ! _transip_rest DELETE "domains/$_domain/dns" "{\"dnsEntry\":{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"expire\":300}}"; then + _err "Could not remove TXT record $_sub_domain for $domain" + 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 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + + if [ -z "$h" ]; then + #not valid + return 1 + fi + + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + + if _transip_rest GET "domains/$h/dns" && _contains $response "dnsEntries"; then + return 0 + fi + + p=$i + i=$(_math "$i" + 1) + done + _err "Unable to parse this domain" + return 1 +} + +_transip_rest() { + m="$1" + ep="$2" + data="$3" + _debug ep "$ep" + export _H1="Accept: application/json" + export _H2="Authorization: Bearer $_token" + export _H4="Content-Type: application/json" + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$TRANSIP_Api_Url/$ep" "" "$m")" + retcode=$? + else + response="$(_get "$TRANSIP_Api_Url/$ep")" + retcode=$? + fi + + if [ "$retcode" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} + +_transip_get_token() { + nonce=$(openssl rand -hex 12) + + data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key}\"}" + _debug data "$data" + + #_signature=$(printf "%s" "$data" | openssl dgst -sha512 -sign "$TRANSIP_Key_File" | _base64) + _signature=$(printf "%s" "$data" | _sign "$TRANSIP_Key_File" "sha512") + _debug2 _signature "$_signature" + + export _H1="Signature: $_signature" + export _H2="Content-Type: application/json" + + response="$(_post "$data" "$TRANSIP_Api_Url/auth" "" "POST")" + retcode=$? + _debug2 response "$response" + if [ "$retcode" != "0" ]; then + _err "Authentication failed." + return 1 + fi + if _contains "$response" "token"; then + _token="$(echo "$response" | _normalizeJson | sed -n 's/^{"token":"\(.*\)"}/\1/p')" + _debug _token "$_token" + return 0 + fi + return 1 +} + +_transip_setup() { + fulldomain=$1 + + # retrieve the transip creds + TRANSIP_Username="${TRANSIP_Username:-$(_readaccountconf_mutable TRANSIP_Username)}" + TRANSIP_Key_File="${TRANSIP_Key_File:-$(_readaccountconf_mutable TRANSIP_Key_File)}" + # check their vals for null + if [ -z "$TRANSIP_Username" ] || [ -z "$TRANSIP_Key_File" ]; then + TRANSIP_Username="" + TRANSIP_Key_File="" + _err "You didn't specify a TransIP username and api key file location" + _err "Please set those values and try again." + return 1 + fi + # save the username and api key to the account conf file. + _saveaccountconf_mutable TRANSIP_Username "$TRANSIP_Username" + _saveaccountconf_mutable TRANSIP_Key_File "$TRANSIP_Key_File" + + if [ -f "$TRANSIP_Key_File"]; then + if ! grep "BEGIN PRIVATE KEY" "$TRANSIP_Key_File" >/dev/null 2>&1; then + _err "Key file doesn't seem to be a valid key: ${TRANSIP_Key_File}" + return 1 + fi + else + _err "Can't read private key file: ${TRANSIP_Key_File}" + return 1 + fi + + + if [ -z "$_token" ]; then + if ! _transip_get_token; then + _err "Can not get token." + return 1 + fi + fi + + _get_root $fulldomain || return 1 + + return 0 +} From 80a636bd14f9b01aca0fb4da6867ef163932e36f Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Wed, 13 May 2020 16:08:34 +0200 Subject: [PATCH 0743/2234] Fix extra space --- dnsapi/dns_transip.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index c828fa66..180b278e 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -139,7 +139,7 @@ _transip_setup() { _saveaccountconf_mutable TRANSIP_Username "$TRANSIP_Username" _saveaccountconf_mutable TRANSIP_Key_File "$TRANSIP_Key_File" - if [ -f "$TRANSIP_Key_File"]; then + if [ -f "$TRANSIP_Key_File" ]; then if ! grep "BEGIN PRIVATE KEY" "$TRANSIP_Key_File" >/dev/null 2>&1; then _err "Key file doesn't seem to be a valid key: ${TRANSIP_Key_File}" return 1 From 65e82b03ade1566d74058f5bcb4bcd4526668548 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Wed, 13 May 2020 16:11:53 +0200 Subject: [PATCH 0744/2234] Fix CI errors --- dnsapi/dns_transip.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 180b278e..5403cc10 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -14,7 +14,7 @@ dns_transip_add() { _debug fulldomain="$fulldomain" txtvalue="$2" _debug txtvalue="$txtvalue" - _transip_setup $fulldomain || return 1 + _transip_setup "$fulldomain" || return 1 _info "Creating TXT record." if ! _transip_rest POST "domains/$_domain/dns" "{\"dnsEntry\":{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"expire\":300}}"; then _err "Could not add TXT record." @@ -28,7 +28,7 @@ dns_transip_rm() { _debug fulldomain="$fulldomain" txtvalue=$2 _debug txtvalue="$txtvalue" - _transip_setup $fulldomain || return 1 + _transip_setup "$fulldomain" || return 1 _info "Removing TXT record." if ! _transip_rest DELETE "domains/$_domain/dns" "{\"dnsEntry\":{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"expire\":300}}"; then _err "Could not remove TXT record $_sub_domain for $domain" @@ -57,7 +57,7 @@ _get_root() { _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" - if _transip_rest GET "domains/$h/dns" && _contains $response "dnsEntries"; then + if _transip_rest GET "domains/$h/dns" && _contains "$response" "dnsEntries"; then return 0 fi @@ -157,7 +157,7 @@ _transip_setup() { fi fi - _get_root $fulldomain || return 1 + _get_root "$fulldomain" || return 1 return 0 } From a102d775b25ca00b210ab25a246653be65f6ee3b Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Wed, 13 May 2020 16:49:07 +0200 Subject: [PATCH 0745/2234] Formatting issues --- dnsapi/dns_transip.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 5403cc10..1fd8e4c9 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -58,7 +58,7 @@ _get_root() { _domain="$h" if _transip_rest GET "domains/$h/dns" && _contains "$response" "dnsEntries"; then - return 0 + return 0 fi p=$i @@ -140,10 +140,10 @@ _transip_setup() { _saveaccountconf_mutable TRANSIP_Key_File "$TRANSIP_Key_File" if [ -f "$TRANSIP_Key_File" ]; then - if ! grep "BEGIN PRIVATE KEY" "$TRANSIP_Key_File" >/dev/null 2>&1; then - _err "Key file doesn't seem to be a valid key: ${TRANSIP_Key_File}" - return 1 - fi + if ! grep "BEGIN PRIVATE KEY" "$TRANSIP_Key_File" >/dev/null 2>&1; then + _err "Key file doesn't seem to be a valid key: ${TRANSIP_Key_File}" + return 1 + fi else _err "Can't read private key file: ${TRANSIP_Key_File}" return 1 From e768e285ce96ba10a9791485afd5a6a5886d3d4a Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Wed, 13 May 2020 16:49:42 +0200 Subject: [PATCH 0746/2234] Remove extra newline --- dnsapi/dns_transip.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 1fd8e4c9..34fbafa6 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -149,7 +149,6 @@ _transip_setup() { return 1 fi - if [ -z "$_token" ]; then if ! _transip_get_token; then _err "Can not get token." From d5ef3a3f8ca423688062b7177f8320f8719a828e Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Wed, 13 May 2020 17:07:19 +0200 Subject: [PATCH 0747/2234] Formatting issues --- dnsapi/dns_transip.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 34fbafa6..23a7f493 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -145,8 +145,8 @@ _transip_setup() { return 1 fi else - _err "Can't read private key file: ${TRANSIP_Key_File}" - return 1 + _err "Can't read private key file: ${TRANSIP_Key_File}" + return 1 fi if [ -z "$_token" ]; then From 748cb28017398ca125f507342a2c8cf5d7480a85 Mon Sep 17 00:00:00 2001 From: Ian Epperson Date: Wed, 13 May 2020 10:39:11 -0700 Subject: [PATCH 0748/2234] 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 048f754d837a85ee6e7698219f6848702c254890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Vestergaard=20V=C3=A6rum?= Date: Thu, 14 May 2020 22:49:04 +0200 Subject: [PATCH 0749/2234] Bug fix: DNS TXT entries will now be removed for dns_gdnsdk.sh --- dnsapi/dns_gdnsdk.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_gdnsdk.sh b/dnsapi/dns_gdnsdk.sh index 8c4962c0..90842b25 100755 --- a/dnsapi/dns_gdnsdk.sh +++ b/dnsapi/dns_gdnsdk.sh @@ -157,9 +157,18 @@ _successful_update() { } _findentry() { + #args $1: fulldomain, $2: txtvalue #returns id of dns entry, if it exists _myget "action=dns_primary_changeDNSsetup&user_domain=$_domain" - _id=$(echo "$_result" | _egrep_o "$1\s*$2[^?]*[^&]*&id=[^&]*" | sed 's/^.*=//') + _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 From 52b81608a1cbb51409d25e9c97d7a5087f7982c7 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Fri, 15 May 2020 23:48:50 -0600 Subject: [PATCH 0750/2234] need to _url_encode anything sent in GET requests Fixes issue raised by @tatablack --- deploy/synology_dsm.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 5aef3b93..279b3c4f 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -83,6 +83,9 @@ synology_dsm_deploy() { _info "Logging into $SYNO_Hostname:$SYNO_Port" response=$(_get "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes&device_id=$SYNO_DID") token=$(echo "$response" | grep "SynoToken" | sed -n 's/.*"SynoToken" *: *"\([^"]*\).*/\1/p') + encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" + encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" + encoded_did="$(printf "%s" "$SYNO_DID" | _url_encode)" _debug3 response "$response" if [ -z "$token" ]; then From d15c14ab939682e0327202a78ef2470df7472181 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Fri, 15 May 2020 23:53:00 -0600 Subject: [PATCH 0751/2234] Fix support for wget I'm actually not entirely sure why/how this worked with curl but not wget, but it did. The short answer is that using a GET does not result in the HTTP_HEADER file being written, instead you must pass in the http_headers param ($2) which will return the HTTP headers as a string. Luckily, the Token is in both the body and the header. We need it and the id (and smid if 2fa) cookie to proceed. So now we parrse the response for that instead of the HTTP_HEADER file. Interesting side note: wget is fine if the URL contains a \r or \n, but curl will barf on it. So we need to make sure those are stripped from the token as it will be passed in the URL later. --- deploy/synology_dsm.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 279b3c4f..7e77344f 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -22,7 +22,7 @@ ######## Public functions ##################### _syno_get_cookie_data() { - grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' + grep "\W$1=" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' } #domain keyfile certfile cafile fullchain @@ -81,12 +81,13 @@ synology_dsm_deploy() { # Login, get the token from JSON and session id from cookie _info "Logging into $SYNO_Hostname:$SYNO_Port" - response=$(_get "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes&device_id=$SYNO_DID") - token=$(echo "$response" | grep "SynoToken" | sed -n 's/.*"SynoToken" *: *"\([^"]*\).*/\1/p') encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" encoded_did="$(printf "%s" "$SYNO_DID" | _url_encode)" + response=$(_get "$_base_url/webman/login.cgi?username=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_id=$encoded_did" 1) + token=$(echo "$response" | grep "X-SYNO-TOKEN:" | sed -n 's/^X-SYNO-TOKEN: \(.*\)$/\1/p' | tr -d "\r\n") _debug3 response "$response" + _debug token "$token" if [ -z "$token" ]; then _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." @@ -94,7 +95,7 @@ synology_dsm_deploy() { return 1 fi - _H1="Cookie: $(_syno_get_cookie_data "id"); $(_syno_get_cookie_data "smid")" + _H1="Cookie: $(echo "$response" | _syno_get_cookie_data "id"); $(echo "$response" | _syno_get_cookie_data "smid")" _H2="X-SYNO-TOKEN: $token" export _H1 export _H2 @@ -105,7 +106,6 @@ synology_dsm_deploy() { _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" _savedeployconf SYNO_DID "$SYNO_DID" - _debug token "$token" _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1" "$_base_url/webapi/entry.cgi") From 668967a7198c583143d5c63b5aed805fd779ac8e Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 16 May 2020 00:05:35 -0600 Subject: [PATCH 0752/2234] If SYNO_Create is not set here, print the nice message --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 7e77344f..b55d1286 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -113,7 +113,7 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - if [ -z "$id" ] && [ -z "${SYNO_Create:?}" ]; then + if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set" return 1 fi From 3a7c7fe4e8fc663a4ec913aee1997736918493f5 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 16 May 2020 00:19:18 -0600 Subject: [PATCH 0753/2234] Fix shellcheck issues --- deploy/synology_dsm.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index b55d1286..06ee2f1e 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -40,9 +40,7 @@ synology_dsm_deploy() { _getdeployconf SYNO_Password _getdeployconf SYNO_Create _getdeployconf SYNO_DID - if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then - SYNO_Username="" - SYNO_Password="" + if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then _err "SYNO_Username & SYNO_Password must be set" return 1 fi @@ -70,7 +68,7 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verfiy it's real _getdeployconf SYNO_Certificate - if [ -z "${SYNO_Certificate:?}" ]; then + if [ -z "${SYNO_Certificate:-}" ]; then _err "SYNO_Certificate needs to be defined (with the Certificate description name)" return 1 fi @@ -113,7 +111,7 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then + if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set" return 1 fi From c7f61f8b804793aebcc131354b5d0978a2b397ce Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 16 May 2020 01:38:44 -0600 Subject: [PATCH 0754/2234] Allow rotating the default certificate which has no description This means, by default, we will rotate the default certificate that comes with the DSM --- deploy/synology_dsm.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 06ee2f1e..7ca4375e 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -68,10 +68,6 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verfiy it's real _getdeployconf SYNO_Certificate - if [ -z "${SYNO_Certificate:-}" ]; then - _err "SYNO_Certificate needs to be defined (with the Certificate description name)" - return 1 - fi _debug SYNO_Certificate "$SYNO_Certificate" _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" From 694194be2f1d1e98385f884b0fb0f11ace3b4a77 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 16 May 2020 02:25:53 -0600 Subject: [PATCH 0755/2234] Shellcheck fix SYNO_Certificate gets set by _getdeployconf, so this may be an empty string but that's fine --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 7ca4375e..b93d0187 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -68,7 +68,7 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verfiy it's real _getdeployconf SYNO_Certificate - _debug SYNO_Certificate "$SYNO_Certificate" + _debug SYNO_Certificate "${SYNO_Certificate:-}" _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" From 4954b44d8e818ac7b78943d5446d9a7b0aae5410 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Sat, 16 May 2020 16:18:05 +0200 Subject: [PATCH 0756/2234] Remove default key file (leave it to the user to explicitly specify) --- dnsapi/dns_transip.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 23a7f493..b5cea51b 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -1,6 +1,5 @@ #!/usr/bin/env sh TRANSIP_Api_Url="https://api.transip.nl/v6" -TRANSIP_Key_File="transip2.key" TRANSIP_Token_Read_Only="false" TRANSIP_Token_Global_Key="false" TRANSIP_Token_Expiration="30 minutes" From fa91516dcec14813ad27fc158ebf3c85645d1142 Mon Sep 17 00:00:00 2001 From: Gassan Gousseinov Date: Sun, 17 May 2020 18:54:06 +0200 Subject: [PATCH 0757/2234] added dnsapi/dns_hetzner.sh --- dnsapi/dns_hetzner.sh | 252 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 dnsapi/dns_hetzner.sh diff --git a/dnsapi/dns_hetzner.sh b/dnsapi/dns_hetzner.sh new file mode 100644 index 00000000..9499501f --- /dev/null +++ b/dnsapi/dns_hetzner.sh @@ -0,0 +1,252 @@ +#!/usr/bin/env sh + +# +#HETZNER_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" +# + +HETZNER_Api="https://dns.hetzner.com/api/v1" + +######## Public functions ##################### + +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record +# Ref: https://dns.hetzner.com/api-docs/ +dns_hetzner_add() { + full_domain=$1 + txt_value=$2 + + HETZNER_Token="${HETZNER_Token:-$(_readaccountconf_mutable HETZNER_Token)}" + + if [ -z "$HETZNER_Token" ]; then + HETZNER_Token="" + _err "You didn't specify a Hetzner api token." + _err "You can get yours from here https://dns.hetzner.com/settings/api-token." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable HETZNER_Token "$HETZNER_Token" + + _debug "First detect the root zone" + + if ! _get_root "$full_domain"; then + _err "Invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting TXT records" + if ! _find_record "$_sub_domain" "$txt_value"; then + return 1 + fi + + if [ -z "$_record_id" ]; then + _info "Adding record" + if _hetzner_rest POST "records" "{\"zone_id\":\"${HETZNER_Zone_ID}\",\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txt_value\",\"ttl\":120}"; then + if _contains "$response" "$txt_value"; then + _info "Record added, OK" + _sleep 2 + return 0 + fi + fi + _err "Add txt record error${_response_error}" + return 1 + else + _info "Found record id: $_record_id." + _info "Record found, do nothing." + return 0; +# # we could modify a record, if the names for txt records for *.example.com and example.com would be not the same +# if _hetzner_rest PUT "records/${_record_id}" "{\"zone_id\":\"${HETZNER_Zone_ID}\",\"type\":\"TXT\",\"name\":\"$full_domain\",\"value\":\"$txt_value\",\"ttl\":120}"; then +# if _contains "$response" "$txt_value"; then +# _info "Modified, OK" +# return 0 +# fi +# fi +# _err "Add txt record error (modify)." +# return 1 + fi +} + +# Usage: full_domain txt_value +# Used to remove the txt record after validation +dns_hetzner_rm() { + full_domain=$1 + txt_value=$2 + + HETZNER_Token="${HETZNER_Token:-$(_readaccountconf_mutable HETZNER_Token)}" + + _debug "First detect the root zone" + if ! _get_root "$full_domain"; then + _err "Invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting TXT records" + if ! _find_record "$_sub_domain" "$txt_value"; then + return 1 + fi + + if [ -z "$_record_id" ]; then + _info "Remove not needed. Record not found." + else + if ! _hetzner_rest DELETE "records/$_record_id"; then + _err "Delete record error${_response_error}" + return 1 + fi + _sleep 2 + _info "Record deleted" + fi +} + +#################### Private functions below ################################## +#returns +# _record_id=a8d58f22d6931bf830eaa0ec6464bf81 if found; or 1 if error +_find_record() { + unset _record_id; + _record_name=$1 + _record_value=$2 + + if [ -z "$_record_value" ]; then + _record_value="[^\"]*" + fi + + _debug "Getting all records" + _hetzner_rest GET "records?zone_id=${_domain_id}" + + if _response_has_error; then + _err "Error${_response_error}" + return 1 + else + _record_id=$( + echo "$response" \ + | grep -o "{[^\{\}]*\"name\":\"$_record_name\"[^\}]*}" \ + | grep "\"value\":\"$_record_value\"" \ + | while read -r record; do + # test for type and + if [ -n "$(echo "$record" | _egrep_o '"type":"TXT"')" ]; then + echo "$record" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" + break + fi + done + ) + fi +} + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=sdjkglgdfewsdfg +_get_root() { + domain=$1 + i=1 + p=1 + + domain_without_acme=$(echo "$domain" | cut -d . -f 2-) + domain_param_name=$(echo "HETZNER_Zone_ID_for_${domain_without_acme}" | sed 's/[\.\-]/_/g') + + _debug "Reading zone_id for '$domain_without_acme' from config..." + HETZNER_Zone_ID=$(_readdomainconf "$domain_param_name") + if [ "$HETZNER_Zone_ID" ]; then + _debug "Found, using: $HETZNER_Zone_ID" + if ! _hetzner_rest GET "zones/${HETZNER_Zone_ID}"; then + _debug "Zone with id '$HETZNER_Zone_ID' not exists." + _cleardomainconf "$domain_param_name" + unset HETZNER_Zone_ID + else + if _contains "$response" "\"id\":\"$HETZNER_Zone_ID\""; then + _domain=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + if [ "$_domain" ]; then + _cut_length=$((${#domain} - ${#_domain} - 1)) + _sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cut_length") + _domain_id="$HETZNER_Zone_ID" + return 0 + else + return 1 + fi + else + return 1 + fi + fi + fi + + _debug "Trying to get zone id by domain name for '$domain_without_acme'." + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + _debug h "$h" + + _hetzner_rest GET "zones?name=$h" + + if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_entries":1'; then + _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + HETZNER_Zone_ID=$_domain_id + _savedomainconf "$domain_param_name" "$HETZNER_Zone_ID" + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +#returns +# _response_error +_response_has_error() { + unset _response_error + + err_part="$(echo "$response" | _egrep_o '"error":{[^}]*}')" + + if [ -n "$err_part" ]; then + err_code=$(echo "$err_part" | _egrep_o '"code":[0-9]+' | cut -d : -f 2) + err_message=$(echo "$err_part" | _egrep_o '"message":"[^"]+"' | cut -d : -f 2 | tr -d \") + + if [ -n "$err_code" ] && [ -n "$err_message" ]; then + _response_error=" - message: ${err_message}, code: ${err_code}" + return 0 + fi + fi + + return 1 +} + +#returns +# response +_hetzner_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + key_trimmed=$(echo "$HETZNER_Token" | tr -d \") + + export _H1="Content-TType: application/json" + export _H2="Auth-API-Token: $key_trimmed" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$HETZNER_Api/$ep" "" "$m")" + else + response="$(_get "$HETZNER_Api/$ep")" + fi + + if [ "$?" != "0" ] || _response_has_error; then + _debug "Error$_response_error" + return 1 + fi + _debug2 response "$response" + return 0 +} From b82c48b66f1c75befb372316bc2cd882d9d9d3a0 Mon Sep 17 00:00:00 2001 From: Gassan Gousseinov Date: Sun, 17 May 2020 22:51:04 +0200 Subject: [PATCH 0758/2234] shfmt --- dnsapi/dns_hetzner.sh | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/dnsapi/dns_hetzner.sh b/dnsapi/dns_hetzner.sh index 9499501f..d994d665 100644 --- a/dnsapi/dns_hetzner.sh +++ b/dnsapi/dns_hetzner.sh @@ -56,16 +56,16 @@ dns_hetzner_add() { else _info "Found record id: $_record_id." _info "Record found, do nothing." - return 0; -# # we could modify a record, if the names for txt records for *.example.com and example.com would be not the same -# if _hetzner_rest PUT "records/${_record_id}" "{\"zone_id\":\"${HETZNER_Zone_ID}\",\"type\":\"TXT\",\"name\":\"$full_domain\",\"value\":\"$txt_value\",\"ttl\":120}"; then -# if _contains "$response" "$txt_value"; then -# _info "Modified, OK" -# return 0 -# fi -# fi -# _err "Add txt record error (modify)." -# return 1 + return 0 + # we could modify a record, if the names for txt records for *.example.com and example.com would be not the same + #if _hetzner_rest PUT "records/${_record_id}" "{\"zone_id\":\"${HETZNER_Zone_ID}\",\"type\":\"TXT\",\"name\":\"$full_domain\",\"value\":\"$txt_value\",\"ttl\":120}"; then + # if _contains "$response" "$txt_value"; then + # _info "Modified, OK" + # return 0 + # fi + #fi + #_err "Add txt record error (modify)." + #return 1 fi } @@ -107,12 +107,12 @@ dns_hetzner_rm() { #returns # _record_id=a8d58f22d6931bf830eaa0ec6464bf81 if found; or 1 if error _find_record() { - unset _record_id; + unset _record_id _record_name=$1 _record_value=$2 if [ -z "$_record_value" ]; then - _record_value="[^\"]*" + _record_value='[^"]*' fi _debug "Getting all records" @@ -129,11 +129,11 @@ _find_record() { | while read -r record; do # test for type and if [ -n "$(echo "$record" | _egrep_o '"type":"TXT"')" ]; then - echo "$record" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" + echo "$record" | _egrep_o '"id":"[^"]*"' | cut -d : -f 2 | tr -d \" break fi done - ) + ) fi } @@ -160,7 +160,7 @@ _get_root() { unset HETZNER_Zone_ID else if _contains "$response" "\"id\":\"$HETZNER_Zone_ID\""; then - _domain=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + _domain=$(printf "%s\n" "$response" | _egrep_o '"name":"[^"]*"' | cut -d : -f 2 | tr -d \" | head -n 1) if [ "$_domain" ]; then _cut_length=$((${#domain} - ${#_domain} - 1)) _sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cut_length") @@ -206,21 +206,21 @@ _get_root() { #returns # _response_error _response_has_error() { - unset _response_error + unset _response_error - err_part="$(echo "$response" | _egrep_o '"error":{[^}]*}')" + err_part="$(echo "$response" | _egrep_o '"error":{[^}]*}')" - if [ -n "$err_part" ]; then - err_code=$(echo "$err_part" | _egrep_o '"code":[0-9]+' | cut -d : -f 2) - err_message=$(echo "$err_part" | _egrep_o '"message":"[^"]+"' | cut -d : -f 2 | tr -d \") + if [ -n "$err_part" ]; then + err_code=$(echo "$err_part" | _egrep_o '"code":[0-9]+' | cut -d : -f 2) + err_message=$(echo "$err_part" | _egrep_o '"message":"[^"]+"' | cut -d : -f 2 | tr -d \") - if [ -n "$err_code" ] && [ -n "$err_message" ]; then - _response_error=" - message: ${err_message}, code: ${err_code}" - return 0 - fi - fi + if [ -n "$err_code" ] && [ -n "$err_message" ]; then + _response_error=" - message: ${err_message}, code: ${err_code}" + return 0 + fi + fi - return 1 + return 1 } #returns From 8b3d792bec2061fb6ad18ee5eb2f22b58b92cd54 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Mon, 18 May 2020 15:24:54 +1000 Subject: [PATCH 0759/2234] dns_rackspace: search for domain The current call uses the /domains end-point which lists all domains. This only returns 100 domains at a time, so for long domain lists you may not match and find the required ID. Switch to using the search interface that only returns values matching the requested domain. This will avoid missing results. Reported by @jjamfd. Closes: #2944 --- dnsapi/dns_rackspace.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_rackspace.sh b/dnsapi/dns_rackspace.sh index 159671f9..03e1fa68 100644 --- a/dnsapi/dns_rackspace.sh +++ b/dnsapi/dns_rackspace.sh @@ -73,7 +73,7 @@ _get_root_zone() { #not valid return 1 fi - if ! _rackspace_rest GET "$RACKSPACE_Tenant/domains"; then + if ! _rackspace_rest GET "$RACKSPACE_Tenant/domains/search?name=$h"; then return 1 fi _debug2 response "$response" From 0deea5393124f4ab34822932f8cf80e464046342 Mon Sep 17 00:00:00 2001 From: kref Date: Tue, 19 May 2020 13:27:00 +0800 Subject: [PATCH 0760/2234] fix octal escapes for printf %b format Stop it from misinterpreting a following digit as part of the escape sequence --- deploy/synology_dsm.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 5aef3b93..c8458c0a 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -125,11 +125,11 @@ synology_dsm_deploy() { _debug2 default "$default" _info "Generate form POST request" - nl="\015\012" + nl="\0015\0012" delim="--------------------------$(_utc_date | tr -d -- '-: ')" - content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\012" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\012" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\012" + content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\0012" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\0012" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\0012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}${default}" From adfa1704e2188828562004e5fab05b1a731749c2 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Tue, 19 May 2020 16:38:23 +0200 Subject: [PATCH 0761/2234] Update nonce calculation to use acme.sh methods instead of openssl command --- dnsapi/dns_transip.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index b5cea51b..8764c1c4 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -93,7 +93,7 @@ _transip_rest() { } _transip_get_token() { - nonce=$(openssl rand -hex 12) + nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex) data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key}\"}" _debug data "$data" From 2d5b4a00032ef6ed03f1b5b6baea3027dfef65c5 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Tue, 19 May 2020 16:39:49 +0200 Subject: [PATCH 0762/2234] Change if-statement for private keys to more portable version --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index df16c1e7..80f5c241 100755 --- a/acme.sh +++ b/acme.sh @@ -1003,7 +1003,7 @@ _sign() { _sign_openssl="${ACME_OPENSSL_BIN:-openssl} dgst -sign $keyfile " - if egrep -o "BEGIN( RSA)? PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then + if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; || if grep "BEGIN PRIVATE KEY" "$keyfile" >/dev/null 2>&1; $_sign_openssl -$alg | _base64 elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then if ! _signedECText="$($_sign_openssl -sha$__ECC_KEY_LEN | ${ACME_OPENSSL_BIN:-openssl} asn1parse -inform DER)"; then From 5d2777634a05cf71391e5e168e1f382d7964fe32 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Tue, 19 May 2020 16:43:39 +0200 Subject: [PATCH 0763/2234] Fix forgotten then --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 80f5c241..d3c357fc 100755 --- a/acme.sh +++ b/acme.sh @@ -1003,7 +1003,7 @@ _sign() { _sign_openssl="${ACME_OPENSSL_BIN:-openssl} dgst -sign $keyfile " - if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; || if grep "BEGIN PRIVATE KEY" "$keyfile" >/dev/null 2>&1; + if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; || if grep "BEGIN PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then $_sign_openssl -$alg | _base64 elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then if ! _signedECText="$($_sign_openssl -sha$__ECC_KEY_LEN | ${ACME_OPENSSL_BIN:-openssl} asn1parse -inform DER)"; then From 114f2a146542fe06ff7db6a763263e034debbedc Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 19 May 2020 23:26:58 +0800 Subject: [PATCH 0764/2234] fix https://github.com/acmesh-official/acme.sh/issues/2880 --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index dd47481d..c92a9980 100755 --- a/acme.sh +++ b/acme.sh @@ -1986,7 +1986,9 @@ _send_signed_request() { continue fi if [ "$ACME_VERSION" = "2" ]; then - if [ "$url" = "$ACME_NEW_ACCOUNT" ] || [ "$url" = "$ACME_REVOKE_CERT" ]; then + if [ "$url" = "$ACME_NEW_ACCOUNT" ]; then + protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}' + elif [ "$url" = "$ACME_REVOKE_CERT" ] && [ "$keyfile" != "$ACCOUNT_KEY_PATH" ]; then protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}' else protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"kid\": \"${ACCOUNT_URL}\""'}' From 63031fb278f8a627351d633a295d39432cb47b30 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Tue, 19 May 2020 20:04:23 +0200 Subject: [PATCH 0765/2234] bugfixes --- acme.sh | 2 +- dnsapi/dns_transip.sh | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d3c357fc..8a29cebf 100755 --- a/acme.sh +++ b/acme.sh @@ -1003,7 +1003,7 @@ _sign() { _sign_openssl="${ACME_OPENSSL_BIN:-openssl} dgst -sign $keyfile " - if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; || if grep "BEGIN PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then + if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || grep "BEGIN PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then $_sign_openssl -$alg | _base64 elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then if ! _signedECText="$($_sign_openssl -sha$__ECC_KEY_LEN | ${ACME_OPENSSL_BIN:-openssl} asn1parse -inform DER)"; then diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 8764c1c4..36c48ce3 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -94,6 +94,10 @@ _transip_rest() { _transip_get_token() { nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex) + nonce_old=$(openssl rand -hex 12) + nonce=${nonce:0:32} + _debug nonce "$nonce" + _debug nonce_old "$nonce_old" data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key}\"}" _debug data "$data" From 70619dd0b77f33ad2358b8adcde9aee555c8e44b Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Tue, 19 May 2020 20:07:14 +0200 Subject: [PATCH 0766/2234] Remove debugging --- dnsapi/dns_transip.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 36c48ce3..2b1d2284 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -94,10 +94,8 @@ _transip_rest() { _transip_get_token() { nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex) - nonce_old=$(openssl rand -hex 12) nonce=${nonce:0:32} _debug nonce "$nonce" - _debug nonce_old "$nonce_old" data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key}\"}" _debug data "$data" From 063562261e97e435e73a05ccfe7340c36b10d512 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Tue, 19 May 2020 23:09:16 +0200 Subject: [PATCH 0767/2234] Fix string truncation for POSIX --- dnsapi/dns_transip.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 2b1d2284..23debe0d 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -93,8 +93,7 @@ _transip_rest() { } _transip_get_token() { - nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex) - nonce=${nonce:0:32} + nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex | cut -c 1-32) _debug nonce "$nonce" data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key}\"}" From 59fd48cfe27219af0737b0735f66a35f209a2042 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 19 May 2020 22:34:19 +0800 Subject: [PATCH 0768/2234] support Retry-After header https://github.com/acmesh-official/acme.sh/issues/2939 --- acme.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/acme.sh b/acme.sh index 48c71df3..419e23df 100755 --- a/acme.sh +++ b/acme.sh @@ -4517,6 +4517,12 @@ $_authorizations_map" _info "Pending" elif [ "$status" = "processing" ]; then _info "Processing" + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ') + _debug "_retryafter" "$_retryafter" + if [ "$_retryafter" ]; then + _info "Retry after: $_retryafter" + _sleep $_retryafter + fi else _err "$d:Verify error:$response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" From a78a09f594936b503823c99f180acea79ba6355a Mon Sep 17 00:00:00 2001 From: PM Extra Date: Thu, 14 May 2020 17:15:31 +0800 Subject: [PATCH 0769/2234] Support multiple servers for SSH deployment. --- deploy/ssh.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index d71637a1..06d4b2b4 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -33,10 +33,7 @@ ssh_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" - _err_code=0 - _cmdstr="" - _backupprefix="" - _backupdir="" + _deploy_ssh_servers="" if [ -f "$DOMAIN_CONF" ]; then # shellcheck disable=SC1090 @@ -102,6 +99,18 @@ ssh_deploy() { _cleardomainconf Le_Deploy_ssh_multi_call fi + _deploy_ssh_servers=$Le_Deploy_ssh_server + for Le_Deploy_ssh_server in $_deploy_ssh_servers; do + _ssh_deploy + done +} + +_ssh_deploy() { + _err_code=0 + _cmdstr="" + _backupprefix="" + _backupdir="" + _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" From 427c278012cb40e9b5d5fb11f46b704941f33605 Mon Sep 17 00:00:00 2001 From: Dan Dascalescu Date: Fri, 22 May 2020 10:28:29 -0700 Subject: [PATCH 0770/2234] Fix sloppy English --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 419e23df..5539b32c 100755 --- a/acme.sh +++ b/acme.sh @@ -4299,7 +4299,7 @@ $_authorizations_map" if [ "$dns_entries" ]; then if [ -z "$Le_DNSSleep" ]; then - _info "Let's check each dns records now. Sleep 20 seconds first." + _info "Let's check each DNS record now. Sleep 20 seconds first." _sleep 20 if ! _check_dns_entries; then _err "check dns error." From e8defd821a9d6f838ea1591d8c719db879a726c8 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 23 May 2020 20:37:06 +0800 Subject: [PATCH 0771/2234] update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 249dc85f..d27a024e 100644 --- a/README.md +++ b/README.md @@ -246,7 +246,7 @@ More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-ce **(requires you to be root/sudoer, since it is required to interact with Apache server)** -If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`. +If you are running a web server, it is recommended to use the `Webroot mode`. Particularly, if you are running an Apache server, you can use Apache mode instead. This mode doesn't write any files to your web root folder. @@ -266,7 +266,7 @@ More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-ce **(requires you to be root/sudoer, since it is required to interact with Nginx server)** -If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`. +If you are running a web server, it is recommended to use the `Webroot mode`. Particularly, if you are running an nginx server, you can use nginx mode instead. This mode doesn't write any files to your web root folder. From 15dded712c6c255715887be7ee5b29775257c18b Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 24 May 2020 18:04:47 +0800 Subject: [PATCH 0772/2234] fix retry https://github.com/acmesh-official/acme.sh/issues/2939#issuecomment-632481658 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 5539b32c..682456a1 100755 --- a/acme.sh +++ b/acme.sh @@ -4517,7 +4517,7 @@ $_authorizations_map" _info "Pending" elif [ "$status" = "processing" ]; then _info "Processing" - _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ') + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') _debug "_retryafter" "$_retryafter" if [ "$_retryafter" ]; then _info "Retry after: $_retryafter" From 0ab14399ae1863e949639f78e5b3ac60501c9e46 Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Mon, 25 May 2020 12:00:54 -0400 Subject: [PATCH 0773/2234] Fix broken grep so that One984HOSTING_COOKIE actually gets set, and isn't left empty. --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index b7cb36d7..d84ea1f7 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -168,7 +168,7 @@ _1984hosting_login() { _debug2 response "$response" if [ "$response" = '{"loggedin": true, "ok": true}' ]; then - One984HOSTING_COOKIE="$(grep '^Set-Cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" + One984HOSTING_COOKIE="$(grep '^set-cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" export One984HOSTING_COOKIE _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" return 0 From 1fe8235a85821561ca49e3c563410870b81ea4ca Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 25 May 2020 20:28:05 +0200 Subject: [PATCH 0774/2234] Update acme.sh --- acme.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index 682456a1..0e3110a6 100755 --- a/acme.sh +++ b/acme.sh @@ -4517,12 +4517,6 @@ $_authorizations_map" _info "Pending" elif [ "$status" = "processing" ]; then _info "Processing" - _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') - _debug "_retryafter" "$_retryafter" - if [ "$_retryafter" ]; then - _info "Retry after: $_retryafter" - _sleep $_retryafter - fi else _err "$d:Verify error:$response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" @@ -4574,7 +4568,14 @@ $_authorizations_map" break elif _contains "$response" "\"processing\""; then _info "Order status is processing, lets sleep and retry." - _sleep 2 + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + _debug "_retryafter" "$_retryafter" + if [ "$_retryafter" ]; then + _info "Retry after: $_retryafter" + _sleep $_retryafter + else + _sleep 2 + fi else _err "Sign error, wrong status" _err "$response" From 025da9245039d897a46edbcb74604c029da08f91 Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Tue, 26 May 2020 02:00:05 -0400 Subject: [PATCH 0775/2234] Handle case insensitivity for HTTP/1.1 headers. --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index d84ea1f7..09f02796 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -168,7 +168,7 @@ _1984hosting_login() { _debug2 response "$response" if [ "$response" = '{"loggedin": true, "ok": true}' ]; then - One984HOSTING_COOKIE="$(grep '^set-cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" + One984HOSTING_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" export One984HOSTING_COOKIE _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" return 0 From f5f0680ec768e5978d90aa1a63f1e4c91d04ff06 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 18:49:39 +0200 Subject: [PATCH 0776/2234] Added support for custom domains --- dnsapi/dns_dynv6.sh | 66 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index cf39282b..4ffd7009 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -13,14 +13,18 @@ dns_dynv6_add() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exists on your dynv6 account" - return 1 + + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -44,14 +48,17 @@ dns_dynv6_rm() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exists on your dynv6 account" - return 1 + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 @@ -72,29 +79,30 @@ _generate_new_key() { return 1 fi } -#Usage: _acme-challenge.www.example.dynv6.net + +#Usage: _acme-challenge.www.example.dynv6.net "$_your_hosts" +#where _your_hosts is the output of ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts #returns #_host= example.dynv6.net #_record=_acme-challenge.www #aborts if not a valid domain _get_domain() { + #_your_hosts="$(ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts)" _full_domain="$1" - _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy'; then - _err "The hosts does not seem to be a dynv6 host" - return 1 - fi - _record="${_full_domain%.*}" - _record="${_record%.*}" - _record="${_record%.*}" - _debug "The record we are ging to use is $_record" - _host="$_full_domain" - while [ "$(echo "$_host" | grep -o '\.' | wc -l)" != "2" ]; do - _host="${_host#*.}" - done - _debug "And the host is $_host" - return 0 + _your_hosts="$2" + _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" + for l in $_your_hosts; do + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi + done + _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" + return 1 } # Usage: No input required @@ -103,7 +111,7 @@ _get_domain() { _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug Your key is "$dynv6_keyfile" + _debug "Your key is $dynv6_keyfile" if [ -z "$dynv6_keyfile" ]; then if [ -z "$KEY" ]; then _err "You did not specify a key to use with dynv6" From 6cc9f49d975a10ea41951de3efad0c2b5a1e2cc0 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 19:09:27 +0200 Subject: [PATCH 0777/2234] first attempt to make travis happy --- dnsapi/dns_dynv6.sh | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 4ffd7009..dce7ce5f 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,17 +14,10 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -50,19 +43,12 @@ dns_dynv6_rm() { _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 - } #################### Private functions below ################################## #Usage: No Input required @@ -93,13 +79,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 From f03904ebceaf77cede8bd99bee2917a334095751 Mon Sep 17 00:00:00 2001 From: Maarten den Braber Date: Tue, 9 Jun 2020 09:57:36 +0200 Subject: [PATCH 0778/2234] change to --output QUIET --- dnsapi/dns_lexicon.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index 34a95599..44bfa735 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -92,7 +92,7 @@ dns_lexicon_add() { _savedomainconf LEXICON_OPTS "$LEXICON_OPTS" # shellcheck disable=SC2086 - $lexicon_cmd "$PROVIDER" $LEXICON_OPTS create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" >/dev/null + $lexicon_cmd "$PROVIDER" $LEXICON_OPTS create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" --output QUIET } @@ -108,6 +108,6 @@ dns_lexicon_rm() { domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999) # shellcheck disable=SC2086 - $lexicon_cmd "$PROVIDER" $LEXICON_OPTS delete "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" >/dev/null + $lexicon_cmd "$PROVIDER" $LEXICON_OPTS delete "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" --output QUIET } From e9edecf34ab828ee257a0c0563969329d437e4e0 Mon Sep 17 00:00:00 2001 From: msamoylych Date: Wed, 24 Jun 2020 12:25:23 +0300 Subject: [PATCH 0779/2234] Update dns_hexonet.sh Remove useless & --- dnsapi/dns_hexonet.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh index f1503118..a8ffd3d1 100755 --- a/dnsapi/dns_hexonet.sh +++ b/dnsapi/dns_hexonet.sh @@ -42,7 +42,7 @@ dns_hexonet_add() { _debug _domain "$_domain" _debug "Getting txt records" - _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT" + _hexonet_rest "command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT" if ! _contains "$response" "CODE=200"; then _err "Error" @@ -88,7 +88,7 @@ dns_hexonet_rm() { _debug _domain "$_domain" _debug "Getting txt records" - _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT&RR=${txtvalue}" + _hexonet_rest "command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT&RR=${txtvalue}" if ! _contains "$response" "CODE=200"; then _err "Error" @@ -100,7 +100,7 @@ dns_hexonet_rm() { if [ "$count" = "0" ]; then _info "Don't need to remove." else - if ! _hexonet_rest "&command=UpdateDNSZone&dnszone=${_domain}.&delrr0='${_sub_domain}%20IN%20TXT%20\"${txtvalue}\""; then + if ! _hexonet_rest "command=UpdateDNSZone&dnszone=${_domain}.&delrr0='${_sub_domain}%20IN%20TXT%20\"${txtvalue}\""; then _err "Delete record error." return 1 fi @@ -126,7 +126,7 @@ _get_root() { return 1 fi - if ! _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}."; then + if ! _hexonet_rest "command=QueryDNSZoneRRList&dnszone=${h}."; then return 1 fi From a9d46297c402e93bb286083840f84514ab9f7c74 Mon Sep 17 00:00:00 2001 From: msamoylych Date: Wed, 24 Jun 2020 12:26:11 +0300 Subject: [PATCH 0780/2234] Update dns_hexonet.sh Fix removing DNS records --- dnsapi/dns_hexonet.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh index a8ffd3d1..525efe73 100755 --- a/dnsapi/dns_hexonet.sh +++ b/dnsapi/dns_hexonet.sh @@ -88,7 +88,7 @@ dns_hexonet_rm() { _debug _domain "$_domain" _debug "Getting txt records" - _hexonet_rest "command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT&RR=${txtvalue}" + _hexonet_rest "command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT&RR=${_sub_domain}%20IN%20TXT%20\"${txtvalue}\"" if ! _contains "$response" "CODE=200"; then _err "Error" @@ -100,7 +100,7 @@ dns_hexonet_rm() { if [ "$count" = "0" ]; then _info "Don't need to remove." else - if ! _hexonet_rest "command=UpdateDNSZone&dnszone=${_domain}.&delrr0='${_sub_domain}%20IN%20TXT%20\"${txtvalue}\""; then + if ! _hexonet_rest "command=UpdateDNSZone&dnszone=${_domain}.&delrr0=${_sub_domain}%20IN%20TXT%20\"${txtvalue}\""; then _err "Delete record error." return 1 fi From eca57beec178f39db00175ba63c3b0728a48d5ad Mon Sep 17 00:00:00 2001 From: Tony Gravagno Date: Mon, 29 Jun 2020 11:29:10 -0700 Subject: [PATCH 0781/2234] Issue #2850 : grammar corrections for "exists" and "exist". --- acme.sh | 10 +++++----- deploy/kong.sh | 4 ++-- dnsapi/dns_ali.sh | 1 + dnsapi/dns_dgon.sh | 4 ++-- dnsapi/dns_dynv6.sh | 4 ++-- dnsapi/dns_gd.sh | 2 +- dnsapi/dns_hetzner.sh | 2 +- dnsapi/dns_kinghost.sh | 2 +- 8 files changed, 15 insertions(+), 14 deletions(-) diff --git a/acme.sh b/acme.sh index 0e3110a6..9b67b9f7 100755 --- a/acme.sh +++ b/acme.sh @@ -188,28 +188,28 @@ _dlg_versions() { if _exists "${ACME_OPENSSL_BIN:-openssl}"; then ${ACME_OPENSSL_BIN:-openssl} version 2>&1 else - echo "$ACME_OPENSSL_BIN doesn't exists." + echo "$ACME_OPENSSL_BIN doesn't exist." fi echo "apache:" if [ "$_APACHECTL" ] && _exists "$_APACHECTL"; then $_APACHECTL -V 2>&1 else - echo "apache doesn't exists." + echo "apache doesn't exist." fi echo "nginx:" if _exists "nginx"; then nginx -V 2>&1 else - echo "nginx doesn't exists." + echo "nginx doesn't exist." fi echo "socat:" if _exists "socat"; then socat -V 2>&1 else - _debug "socat doesn't exists." + _debug "socat doesn't exist." fi } @@ -5519,7 +5519,7 @@ revoke() { fi fi else - _info "Domain key file doesn't exists." + _info "Domain key file doesn't exist." fi _info "Try account key." diff --git a/deploy/kong.sh b/deploy/kong.sh index d3a6bc47..1e1e310c 100755 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# If certificate already exist it will update only cert and key not touching other parameter -# If certificate doesn't exist it will only upload cert and key and not set other parameter +# If certificate already exists it will update only cert and key, not touching other parameters +# If certificate doesn't exist it will only upload cert and key, and not set other parameters # Note that we deploy full chain # Written by Geoffroi Genot diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 0c2365d7..c2105672 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -181,6 +181,7 @@ _describe_records_query() { _clean() { _check_exist_query "$_domain" "$_sub_domain" + # do not correct grammar here if ! _ali_rest "Check exist records" "ignore"; then return 1 fi diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh index c176afd3..515e87d5 100755 --- a/dnsapi/dns_dgon.sh +++ b/dnsapi/dns_dgon.sh @@ -22,7 +22,7 @@ dns_dgon_add() { txtvalue=$2 DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}" - # Check if API Key Exist + # Check if API Key Exists if [ -z "$DO_API_KEY" ]; then DO_API_KEY="" _err "You did not specify DigitalOcean API key." @@ -77,7 +77,7 @@ dns_dgon_rm() { txtvalue=$2 DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}" - # Check if API Key Exist + # Check if API Key Exists if [ -z "$DO_API_KEY" ]; then DO_API_KEY="" _err "You did not specify DigitalOcean API key." diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index cf39282b..819372c2 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -18,7 +18,7 @@ dns_dynv6_add() { if ! _contains "$_your_hosts" "$_host"; then _debug "The host is $_host and the record $_record" _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exists on your dynv6 account" + _err "The host $_host does not exist on your dynv6 account" return 1 fi _debug "found host on your account" @@ -49,7 +49,7 @@ dns_dynv6_rm() { if ! _contains "$_your_hosts" "$_host"; then _debug "The host is $_host and the record $_record" _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exists on your dynv6 account" + _err "The host $_host does not exist on your dynv6 account" return 1 fi _debug "found host on your account" diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh index 7cf47386..7f8efca9 100755 --- a/dnsapi/dns_gd.sh +++ b/dnsapi/dns_gd.sh @@ -91,7 +91,7 @@ dns_gd_rm() { fi if ! _contains "$response" "$txtvalue"; then - _info "The record is not existing, skip" + _info "The record does not exist, skip" return 0 fi diff --git a/dnsapi/dns_hetzner.sh b/dnsapi/dns_hetzner.sh index d994d665..5db0418c 100644 --- a/dnsapi/dns_hetzner.sh +++ b/dnsapi/dns_hetzner.sh @@ -155,7 +155,7 @@ _get_root() { if [ "$HETZNER_Zone_ID" ]; then _debug "Found, using: $HETZNER_Zone_ID" if ! _hetzner_rest GET "zones/${HETZNER_Zone_ID}"; then - _debug "Zone with id '$HETZNER_Zone_ID' not exists." + _debug "Zone with id '$HETZNER_Zone_ID' does not exist." _cleardomainconf "$domain_param_name" unset HETZNER_Zone_ID else diff --git a/dnsapi/dns_kinghost.sh b/dnsapi/dns_kinghost.sh index 898ab286..6253c71d 100644 --- a/dnsapi/dns_kinghost.sh +++ b/dnsapi/dns_kinghost.sh @@ -37,7 +37,7 @@ dns_kinghost_add() { _debug "Getting txt records" _kinghost_rest GET "dns" "name=$fulldomain&content=$txtvalue" - #This API call returns "status":"ok" if dns record does not exists + #This API call returns "status":"ok" if dns record does not exist #We are creating a new txt record here, so we expect the "ok" status if ! echo "$response" | grep '"status":"ok"' >/dev/null; then _err "Error" From 94787d537abad243a1a5787326e5fba86c972c06 Mon Sep 17 00:00:00 2001 From: Tony Gravagno Date: Mon, 29 Jun 2020 11:51:55 -0700 Subject: [PATCH 0782/2234] Issue #2849 Trivial variable name fix from apacheMajer to apacheMajor --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 9b67b9f7..28c39db4 100755 --- a/acme.sh +++ b/acme.sh @@ -2801,10 +2801,10 @@ _setApache() { apacheVer="$($_APACHECTL -V | grep "Server version:" | cut -d : -f 2 | cut -d " " -f 2 | cut -d '/' -f 2)" _debug "apacheVer" "$apacheVer" - apacheMajer="$(echo "$apacheVer" | cut -d . -f 1)" + apacheMajor="$(echo "$apacheVer" | cut -d . -f 1)" apacheMinor="$(echo "$apacheVer" | cut -d . -f 2)" - if [ "$apacheVer" ] && [ "$apacheMajer$apacheMinor" -ge "24" ]; then + if [ "$apacheVer" ] && [ "$apacheMajor$apacheMinor" -ge "24" ]; then echo " Alias /.well-known/acme-challenge $ACME_DIR From 8718ac0c4bf17372e7daff6b93c57cca1001c12a Mon Sep 17 00:00:00 2001 From: Matthew Date: Tue, 30 Jun 2020 02:22:08 -0400 Subject: [PATCH 0783/2234] duckdns doesn't permit subdomains or underscores --- dnsapi/dns_duckdns.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 711b81ee..aa7911d3 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -91,13 +91,13 @@ dns_duckdns_rm() { #################### Private functions below ################################## -#fulldomain=_acme-challenge.domain.duckdns.org +#fulldomain=acme-challenge-domain.duckdns.org #returns -# _duckdns_domain=domain +# _duckdns_domain=acme-challenge-domain _duckdns_get_domain() { # We'll extract the domain/username from full domain - _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '[.][^.][^.]*[.]duckdns.org' | cut -d . -f 2)" + _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | sed 's/^\([a-z0-9-]*\)\.duckdns\.org/\1/')" if [ -z "$_duckdns_domain" ]; then _err "Error extracting the domain." From 4539d236df65f8cc0592cfbe1f044141c251f270 Mon Sep 17 00:00:00 2001 From: Matthew Date: Tue, 30 Jun 2020 07:19:41 -0400 Subject: [PATCH 0784/2234] dns_duckdns.sh - correctly extract domain $fulldomain could be just 'domain.duckdns.org' if provided with --domain-alias or '_acme-challenge.domain.duckdns.org' otherwise. In the latter case, '_acme-challenge' is thrown away. Correctly extract 'domain' in both cases. --- dnsapi/dns_duckdns.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index aa7911d3..edfc48b0 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -91,13 +91,12 @@ dns_duckdns_rm() { #################### Private functions below ################################## -#fulldomain=acme-challenge-domain.duckdns.org -#returns -# _duckdns_domain=acme-challenge-domain +# fulldomain may be 'domain.duckdns.org' (if using --domain-alias) or '_acme-challenge.domain.duckdns.org' +# either way, return 'domain'. (duckdns does not allow further subdomains and restricts domains to [a-z0-9-].) _duckdns_get_domain() { # We'll extract the domain/username from full domain - _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | sed 's/^\([a-z0-9-]*\)\.duckdns\.org/\1/')" + _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '^(_acme-challenge\.)?[a-z0-9-]*\.duckdns\.org' | sed -E 's/^(_acme-challenge\.)?([a-z0-9-]*)\.duckdns\.org/\2/')" if [ -z "$_duckdns_domain" ]; then _err "Error extracting the domain." From cdf8f78962d45b856b9e28c7e95a3cae37f46cf1 Mon Sep 17 00:00:00 2001 From: Tom Sommer Date: Thu, 2 Jul 2020 09:47:05 +0200 Subject: [PATCH 0785/2234] unoeuro.com is now simply.com Maintaining the naming of the API (for backwards compatibility), but renaming hostname. --- dnsapi/dns_unoeuro.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_unoeuro.sh b/dnsapi/dns_unoeuro.sh index c4593a63..fb6ba4fd 100644 --- a/dnsapi/dns_unoeuro.sh +++ b/dnsapi/dns_unoeuro.sh @@ -5,7 +5,7 @@ # #UNO_User="UExxxxxx" -Uno_Api="https://api.unoeuro.com/1" +Uno_Api="https://api.simply.com/1" ######## Public functions ##################### From f60356e8c7f1bccc573f30a2cedc33c2d3771e64 Mon Sep 17 00:00:00 2001 From: Tom Sommer Date: Thu, 2 Jul 2020 09:48:05 +0200 Subject: [PATCH 0786/2234] Username not required to contain "UE" --- dnsapi/dns_unoeuro.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dnsapi/dns_unoeuro.sh b/dnsapi/dns_unoeuro.sh index fb6ba4fd..13ba8a00 100644 --- a/dnsapi/dns_unoeuro.sh +++ b/dnsapi/dns_unoeuro.sh @@ -24,12 +24,6 @@ dns_unoeuro_add() { return 1 fi - if ! _contains "$UNO_User" "UE"; then - _err "It seems that the UNO_User=$UNO_User is not a valid username." - _err "Please check and retry." - return 1 - fi - #save the api key and email to the account conf file. _saveaccountconf_mutable UNO_Key "$UNO_Key" _saveaccountconf_mutable UNO_User "$UNO_User" From 5d0dde5c154604f6a5420b8e6181573510a5631d Mon Sep 17 00:00:00 2001 From: snv Date: Thu, 2 Jul 2020 12:23:46 +0400 Subject: [PATCH 0787/2234] main changes --- dnsapi/dns_regru.sh | 71 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index 369f62ad..a952e31f 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -5,7 +5,6 @@ # # REGRU_API_Password="test" # -_domain=$_domain REGRU_API_URL="https://api.reg.ru/api/regru2" @@ -27,10 +26,17 @@ dns_regru_add() { _saveaccountconf_mutable REGRU_API_Username "$REGRU_API_Username" _saveaccountconf_mutable REGRU_API_Password "$REGRU_API_Password" - _info "Adding TXT record to ${fulldomain}" - response="$(_get "$REGRU_API_URL/zone/add_txt?input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json")" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain "$_domain" - if _contains "${response}" 'success'; then + _info "Adding TXT record to ${fulldomain}" + _regru_rest POST "zone/add_txt" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json" + + if ! _contains "${response}" 'error'; then return 0 fi _err "Could not create resource record, check logs" @@ -51,13 +57,64 @@ dns_regru_rm() { return 1 fi - _info "Deleting resource record $fulldomain" - response="$(_get "$REGRU_API_URL/zone/remove_record?input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json")" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain "$_domain" - if _contains "${response}" 'success'; then + _info "Deleting resource record $fulldomain" + _regru_rest POST "zone/remove_record" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json" + + if ! _contains "${response}" 'error'; then return 0 fi _err "Could not delete resource record, check logs" _err "${response}" return 1 } + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _domain=domain.com +_get_root() { + domain=$1 + + _regru_rest POST "service/get_list" "username=${REGRU_API_Username}&password=${REGRU_API_Password}&output_format=xml&servtype=domain" + domains_list=$(echo "${response}" | grep dname | sed -r "s/.*dname=\"([^\"]+)\".*/\\1/g") + + for ITEM in ${domains_list} + do + case "${domain}" in + *${ITEM}*) + _domain=${ITEM} + return 0 + ;; + esac + done + + return 1 +} + +#returns +# response +_regru_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + export _H1="Content-Type: application/x-www-form-urlencoded" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$REGRU_API_URL/$ep" "" "$m")" + else + response="$(_get "$REGRU_API_URL/$ep")" + fi + + _debug2 response "${response}" + return 0 +} \ No newline at end of file From c16757b03abae5ec9f0e8c8b32f2014ff4c56bbe Mon Sep 17 00:00:00 2001 From: snv Date: Thu, 2 Jul 2020 12:59:24 +0400 Subject: [PATCH 0788/2234] add some debug output and fix data in GET request --- dnsapi/dns_regru.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index a952e31f..1848480a 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -90,6 +90,7 @@ _get_root() { case "${domain}" in *${ITEM}*) _domain=${ITEM} + _debug _domain "${_domain}" return 0 ;; esac @@ -112,9 +113,9 @@ _regru_rest() { _debug data "$data" response="$(_post "$data" "$REGRU_API_URL/$ep" "" "$m")" else - response="$(_get "$REGRU_API_URL/$ep")" + response="$(_get "$REGRU_API_URL/$ep?$data")" fi - _debug2 response "${response}" + _debug response "${response}" return 0 } \ No newline at end of file From 44b9a8e7ed9a6ba0550d0d54bec4757148cff9a6 Mon Sep 17 00:00:00 2001 From: snv Date: Thu, 2 Jul 2020 13:18:37 +0400 Subject: [PATCH 0789/2234] fix new line at end of file --- dnsapi/dns_regru.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index 1848480a..f1a2b5ed 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -118,4 +118,4 @@ _regru_rest() { _debug response "${response}" return 0 -} \ No newline at end of file +} From 21718a69d39106b689faae151dbf7aeb259b5597 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 3 Jul 2020 07:48:38 -0400 Subject: [PATCH 0790/2234] Update dns_duckdns.sh Don't depend on eregex in sed --- dnsapi/dns_duckdns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index edfc48b0..11b685c0 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -96,7 +96,7 @@ dns_duckdns_rm() { _duckdns_get_domain() { # We'll extract the domain/username from full domain - _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '^(_acme-challenge\.)?[a-z0-9-]*\.duckdns\.org' | sed -E 's/^(_acme-challenge\.)?([a-z0-9-]*)\.duckdns\.org/\2/')" + _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '^(_acme-challenge\.)?[a-z0-9-]*\.duckdns\.org' | sed 's/^\(_acme-challenge\.\)\?\([a-z0-9-]*\)\.duckdns\.org/\2/')" if [ -z "$_duckdns_domain" ]; then _err "Error extracting the domain." From 1dffaba266b43401f93bfabb37080ea783ca1abf Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 7 Jul 2020 19:58:02 +0800 Subject: [PATCH 0791/2234] fix format --- dnsapi/dns_regru.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index f1a2b5ed..1f9eeafe 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -89,10 +89,10 @@ _get_root() { do case "${domain}" in *${ITEM}*) - _domain=${ITEM} - _debug _domain "${_domain}" - return 0 - ;; + _domain=${ITEM} + _debug _domain "${_domain}" + return 0 + ;; esac done From f00e289014e9001a19d44146be8eb8a0e89ff87d Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 7 Jul 2020 20:02:48 +0800 Subject: [PATCH 0792/2234] fix format --- dnsapi/dns_regru.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index 1f9eeafe..b5729fda 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -85,8 +85,7 @@ _get_root() { _regru_rest POST "service/get_list" "username=${REGRU_API_Username}&password=${REGRU_API_Password}&output_format=xml&servtype=domain" domains_list=$(echo "${response}" | grep dname | sed -r "s/.*dname=\"([^\"]+)\".*/\\1/g") - for ITEM in ${domains_list} - do + for ITEM in ${domains_list}; do case "${domain}" in *${ITEM}*) _domain=${ITEM} From dbc435506c90d5df5a676e39bf1ad1225e8975e4 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Tue, 7 Jul 2020 12:06:37 +0000 Subject: [PATCH 0793/2234] Fix typo candindates --- acme.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 28c39db4..d9df3a6f 100755 --- a/acme.sh +++ b/acme.sh @@ -4098,17 +4098,17 @@ $_authorizations_map" if [ "$ACME_VERSION" = "2" ]; then _idn_d="$(_idn "$d")" - _candindates="$(echo "$_authorizations_map" | grep -i "^$_idn_d,")" - _debug2 _candindates "$_candindates" - if [ "$(echo "$_candindates" | wc -l)" -gt 1 ]; then - for _can in $_candindates; do + _candidates="$(echo "$_authorizations_map" | grep -i "^$_idn_d,")" + _debug2 _candidates "$_candidates" + if [ "$(echo "$_candidates" | wc -l)" -gt 1 ]; then + for _can in $_candidates; do if _startswith "$(echo "$_can" | tr '.' '|')" "$(echo "$_idn_d" | tr '.' '|'),"; then - _candindates="$_can" + _candidates="$_can" break fi done fi - response="$(echo "$_candindates" | sed "s/$_idn_d,//")" + response="$(echo "$_candidates" | sed "s/$_idn_d,//")" _debug2 "response" "$response" if [ -z "$response" ]; then _err "get to authz error." From dd6c067832383c6b1b0552fe0e6eec404f455d5b Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 7 Jul 2020 20:52:00 +0800 Subject: [PATCH 0794/2234] fix format --- dnsapi/dns_lexicon.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index 44bfa735..19702343 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -92,7 +92,7 @@ dns_lexicon_add() { _savedomainconf LEXICON_OPTS "$LEXICON_OPTS" # shellcheck disable=SC2086 - $lexicon_cmd "$PROVIDER" $LEXICON_OPTS create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" --output QUIET + $lexicon_cmd "$PROVIDER" $LEXICON_OPTS create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" --output QUIET } From f02af8d481e0118419f4ac58ee8c006d5d9d4456 Mon Sep 17 00:00:00 2001 From: peterkelm Date: Tue, 7 Jul 2020 22:56:51 +0200 Subject: [PATCH 0795/2234] Reflect recent Variomedia API changes Spaces were recently removed from the JSON "response" returned by Variomedia's API. --- dnsapi/dns_variomedia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index 729cda5e..a35b8f0f 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -107,7 +107,7 @@ _get_root() { fi if _startswith "$response" "\{\"data\":"; then - if _contains "$response" "\"id\": \"$h\""; then + if _contains "$response" "\"id\":\"$h\""; then _sub_domain="$(echo "$fulldomain" | sed "s/\\.$h\$//")" _domain=$h return 0 From a3295476828342642ba65111ccd7ec98056b5917 Mon Sep 17 00:00:00 2001 From: grindsa Date: Wed, 8 Jul 2020 11:59:20 +0200 Subject: [PATCH 0796/2234] prepending for ecc signature leftpadding "0" if _ec_s and _ec_r are to short --- acme.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 28c39db4..eb13f652 100755 --- a/acme.sh +++ b/acme.sh @@ -1014,8 +1014,32 @@ _sign() { fi _debug3 "_signedECText" "$_signedECText" _ec_r="$(echo "$_signedECText" | _head_n 2 | _tail_n 1 | cut -d : -f 4 | tr -d "\r\n")" - _debug3 "_ec_r" "$_ec_r" _ec_s="$(echo "$_signedECText" | _head_n 3 | _tail_n 1 | cut -d : -f 4 | tr -d "\r\n")" + if [ "$__ECC_KEY_LEN" -eq "256" ]; then + while [ "${#_ec_r}" -lt "64" ]; do + _ec_r="0${_ec_r}" + done + while [ "${#_ec_s}" -lt "64" ]; do + _ec_s="0${_ec_s}" + done + fi + if [ "$__ECC_KEY_LEN" -eq "384" ]; then + while [ "${#_ec_r}" -lt "96" ]; do + _ec_r="0${_ec_r}" + done + while [ "${#_ec_s}" -lt "96" ]; do + _ec_s="0${_ec_s}" + done + fi + if [ "$__ECC_KEY_LEN" -eq "512" ]; then + while [ "${#_ec_r}" -lt "132" ]; do + _ec_r="0${_ec_r}" + done + while [ "${#_ec_s}" -lt "132" ]; do + _ec_s="0${_ec_s}" + done + fi + _debug3 "_ec_r" "$_ec_r" _debug3 "_ec_s" "$_ec_s" printf "%s" "$_ec_r$_ec_s" | _h2b | _base64 else From d8042289564c5207fd5fe4170ce49c2bb0d699a0 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 8 Jul 2020 22:22:06 +0800 Subject: [PATCH 0797/2234] fix https://github.com/acmesh-official/acme.sh/issues/3032 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5112bf07..f00d03bd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.10 +FROM alpine:3.12 RUN apk update -f \ && apk --no-cache add -f \ From aaca0b6f76c0725b6aa439d8128e5f17af78fa67 Mon Sep 17 00:00:00 2001 From: Vinton Huang Date: Sat, 11 Jul 2020 19:50:16 +0800 Subject: [PATCH 0798/2234] Update "Tested OS" section of README.md - Update openSUSE build badge file name (opensuse-leap.svg -> opensuse-leap-latest.svg) - Update link target of build badge (letest -> acmetest), for item 1-12, 15, 16, 18, 19, 21 - Update Proxmox document link for 5.2 and later --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index d27a024e..67402f29 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) # Who: - [FreeBSD.org](https://blog.crashed.org/letsencrypt-in-freebsd-org/) - [ruby-china.org](https://ruby-china.org/topics/31983) -- [Proxmox](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x_and_newer)) +- [Proxmox](https://pve.proxmox.com/wiki/Certificate_Management) - [pfsense](https://github.com/pfsense/FreeBSD-ports/pull/89) - [webfaction](https://community.webfaction.com/questions/19988/using-letsencrypt) - [Loadbalancer.org](https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty) @@ -46,27 +46,27 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) | NO | Status| Platform| |----|-------|---------| -|1|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Ubuntu -|2|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Debian -|3|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|CentOS -|4|[![](https://acmesh-official.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) -|5|[![](https://acmesh-official.github.io/acmetest/status/freebsd.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|FreeBSD -|6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|pfsense -|7|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|openSUSE -|8|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Alpine Linux (with curl) -|9|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Archlinux -|10|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|fedora -|11|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Kali Linux -|12|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Oracle Linux -|13|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh +|1|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu +|2|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian +|3|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS +|4|[![](https://acmesh-official.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) +|5|[![](https://acmesh-official.github.io/acmetest/status/freebsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|FreeBSD +|6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense +|7|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE +|8|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl) +|9|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux +|10|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora +|11|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux +|12|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux +|13|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) |14|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|15|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|OpenBSD -|16|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Mageia +|15|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD +|16|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia |17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) -|18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|SunOS/Solaris -|19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|Gentoo Linux +|18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris +|19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux |20|[![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh)|Mac OSX -|21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)|ClearLinux +|21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): From 01ebb6576d0b77367bd59f78c408832be9b85cc8 Mon Sep 17 00:00:00 2001 From: andrewheberle Date: Mon, 13 Jul 2020 09:31:47 +0800 Subject: [PATCH 0799/2234] Use base64 for reload Ensure that reload command is encoded with base64 so special characters in command do not wreck config on renewals --- deploy/docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/docker.sh b/deploy/docker.sh index 06d79855..451d5d00 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -91,7 +91,7 @@ docker_deploy() { _getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD _debug2 DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then - _savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" + _savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" "base64" fi _cid="$(_get_id "$DEPLOY_DOCKER_CONTAINER_LABEL")" From f80276584f4f1579e8c6736b03ba002460f30cf6 Mon Sep 17 00:00:00 2001 From: robertoetcheverryr Date: Sun, 12 Jul 2020 23:43:03 -0300 Subject: [PATCH 0800/2234] Added check for Authentication failure in dns_dynu module --- dnsapi/dns_dynu.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnsapi/dns_dynu.sh b/dnsapi/dns_dynu.sh index 506ef53e..406ef17d 100644 --- a/dnsapi/dns_dynu.sh +++ b/dnsapi/dns_dynu.sh @@ -216,6 +216,10 @@ _dynu_authentication() { _err "Authentication failed." return 1 fi + if _contains "$response" "Authentication Exception"; then + _err "Authentication failed." + return 1 + fi if _contains "$response" "access_token"; then Dynu_Token=$(printf "%s" "$response" | tr -d "{}" | cut -d , -f 1 | cut -d : -f 2 | cut -d '"' -f 2) fi From 6654d7a919686914d1db24e85f020dbdabc8b5ff Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 13 Jul 2020 20:56:58 +0800 Subject: [PATCH 0801/2234] fix format --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 52ea30a5..80aba9ae 100755 --- a/acme.sh +++ b/acme.sh @@ -1018,7 +1018,7 @@ _sign() { if [ "$__ECC_KEY_LEN" -eq "256" ]; then while [ "${#_ec_r}" -lt "64" ]; do _ec_r="0${_ec_r}" - done + done while [ "${#_ec_s}" -lt "64" ]; do _ec_s="0${_ec_s}" done @@ -1026,7 +1026,7 @@ _sign() { if [ "$__ECC_KEY_LEN" -eq "384" ]; then while [ "${#_ec_r}" -lt "96" ]; do _ec_r="0${_ec_r}" - done + done while [ "${#_ec_s}" -lt "96" ]; do _ec_s="0${_ec_s}" done @@ -1034,7 +1034,7 @@ _sign() { if [ "$__ECC_KEY_LEN" -eq "512" ]; then while [ "${#_ec_r}" -lt "132" ]; do _ec_r="0${_ec_r}" - done + done while [ "${#_ec_s}" -lt "132" ]; do _ec_s="0${_ec_s}" done From f31debc09c1e7f727c3cb0dabb7fd58a68275c0b Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 13 Jul 2020 21:03:57 +0800 Subject: [PATCH 0802/2234] fix format --- acme.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 80aba9ae..22eaaa86 100755 --- a/acme.sh +++ b/acme.sh @@ -1017,26 +1017,26 @@ _sign() { _ec_s="$(echo "$_signedECText" | _head_n 3 | _tail_n 1 | cut -d : -f 4 | tr -d "\r\n")" if [ "$__ECC_KEY_LEN" -eq "256" ]; then while [ "${#_ec_r}" -lt "64" ]; do - _ec_r="0${_ec_r}" + _ec_r="0${_ec_r}" done while [ "${#_ec_s}" -lt "64" ]; do - _ec_s="0${_ec_s}" + _ec_s="0${_ec_s}" done fi if [ "$__ECC_KEY_LEN" -eq "384" ]; then while [ "${#_ec_r}" -lt "96" ]; do - _ec_r="0${_ec_r}" + _ec_r="0${_ec_r}" done while [ "${#_ec_s}" -lt "96" ]; do - _ec_s="0${_ec_s}" + _ec_s="0${_ec_s}" done fi if [ "$__ECC_KEY_LEN" -eq "512" ]; then while [ "${#_ec_r}" -lt "132" ]; do - _ec_r="0${_ec_r}" + _ec_r="0${_ec_r}" done while [ "${#_ec_s}" -lt "132" ]; do - _ec_s="0${_ec_s}" + _ec_s="0${_ec_s}" done fi _debug3 "_ec_r" "$_ec_r" From f5411ac9ab9f40b0501d99132a561605a9e8d714 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:42:45 +0200 Subject: [PATCH 0803/2234] no supporting HTTP API as well --- dnsapi/dns_dynv6.sh | 263 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 219 insertions(+), 44 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index dce7ce5f..0fd6fa4c 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -1,32 +1,41 @@ #!/usr/bin/env sh #Author StefanAbl #Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"' +#or use the HTTP REST API by by specifying a token 'export DYNV6_TOKEN="value" #if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub + +dynv6_api="https://dynv6.com/api/v2" ######## Public functions ##################### # Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide -#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Usage: dns_dynv6_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dynv6_add() { fulldomain=$1 txtvalue=$2 _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 - fi - _debug "found host on your account" - returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" - _debug "Dynv6 returend this after record was added: $returnval" - if _contains "$returnval" "created"; then - return 0 - elif _contains "$returnval" "updated"; then - return 0 - else - _err "Something went wrong! it does not seem like the record was added succesfully" + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_add_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" + _debug "Dynv6 returned this after record was added: $returnval" + if _contains "$returnval" "created"; then + return 0 + elif _contains "$returnval" "updated"; then + return 0 + else + _err "Something went wrong! it does not seem like the record was added successfully" + return 1 + fi return 1 fi return 1 @@ -36,24 +45,29 @@ dns_dynv6_add() { dns_dynv6_rm() { fulldomain=$1 txtvalue=$2 - _info "Using dynv6 api" + _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_rm_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" + return 0 fi - _debug "found host on your account" - _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" - return 0 } #################### Private functions below ################################## #Usage: No Input required #returns -#dynv6_keyfile the path to the new keyfile that has been generated +#dynv6_keyfile the path to the new key file that has been generated _generate_new_key() { dynv6_keyfile="$(eval echo ~"$USER")/.ssh/dynv6" _info "Path to key file used: $dynv6_keyfile" @@ -94,22 +108,183 @@ _get_domain() { # Usage: No input required #returns #dynv6_keyfile path to the key that will be used -_get_keyfile() { - _debug "get keyfile method called" - dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug "Your key is $dynv6_keyfile" - if [ -z "$dynv6_keyfile" ]; then - if [ -z "$KEY" ]; then - _err "You did not specify a key to use with dynv6" - _info "Creating new dynv6 api key to add to dynv6.com" - _generate_new_key - _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" - _info "Hit Enter to contiue" - read -r _ - #save the credentials to the account conf file. - else - dynv6_keyfile="$KEY" +_get_authentication() { + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else + _debug "no HTTP token found. Looking for an SSH key" + dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" + _debug "Your key is $dynv6_keyfile" + if [ -z "$dynv6_keyfile" ]; then + if [ -z "$KEY" ]; then + _err "You did not specify a key to use with dynv6" + _info "Creating new dynv6 API key to add to dynv6.com" + _generate_new_key + _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" + _info "Hit Enter to continue" + read -r _ + #save the credentials to the account conf file. + else + dynv6_keyfile="$KEY" + fi + _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" fi - _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" fi } + + + +_dns_dynv6_add_http(){ +_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain" ;then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi +} + +_dns_dynv6_rm_http(){ + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain" ;then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ] ; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} + + +#get the zoneid for a specifc record or zone +#usage: _get_zone_id §record +#where $record is the record to get the id for +#returns _zone_id the id of the zone +_get_zone_id(){ + record="$1" + _debug "getting zone id for $record" + _dynv6_rest GET zones + + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" +} + +_get_zone_name(){ + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n'| tr -d '{'|grep name|tr -d '"')" + _zone_name="${_zone_name#name:}" +} + +#usaage _get_record_id $zone_id $record +# where zone_id is thevalue returned by _get_zone_id +# and record ist in the form _acme.www for an fqdn of _acme.www.example.com +# returns _record_id +_get_record_id(){ + _zone_id="$1" + record="$2" + value="$3" + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response" ; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi +} + +_get_record_id_from_response(){ + response="$1" + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id |tr -d '"'|tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 +} +#usage: _set_record TXT _acme_challenge.www longvalue 12345678 +#zone id is optional can also be set as vairable bevor calling this method +_set_record(){ + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" +} +_del_record(){ + _zone_id=$1 + _record_id=$2 + _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" +} + +_dynv6_rest() { + m=$1 #method GET,POST,DELETE or PUT + ep="$2" #the endpoint + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$dynv6_token" | tr -d '"') + + export _H1="Authorization: Bearer $token_trimmed" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" + else + response="$(_get "$dynv6_api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} + From f8c8330258da736f7deb9b5bbdda0f8e734b65a3 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:49:25 +0200 Subject: [PATCH 0804/2234] formatting --- dnsapi/dns_dynv6.sh | 206 ++++++++++++++++++++++---------------------- 1 file changed, 101 insertions(+), 105 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 0fd6fa4c..c41aef3a 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -18,7 +18,7 @@ dns_dynv6_add() { if [ "$dynv6_token" ]; then _dns_dynv6_add_http return $? - else + else _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -49,10 +49,10 @@ dns_dynv6_rm() { _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" _get_authentication - if [ "$dynv6_token" ]; then + if [ "$dynv6_token" ]; then _dns_dynv6_rm_http return $? - else + else _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -109,14 +109,14 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" - else + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" _debug "Your key is $dynv6_keyfile" @@ -137,142 +137,139 @@ _get_authentication() { fi } - - -_dns_dynv6_add_http(){ -_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain" ;then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _set_record TXT "$record" "$txtvalue" - if _contains "$response" "$txtvalue"; then - _info "Successfully added record" - return 0 - else - _err "Something went wrong while adding the record" - return 1 - fi -} - -_dns_dynv6_rm_http(){ +_dns_dynv6_add_http() { _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain" ;then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _get_record_id "$_zone_id" "$record" "$txtvalue" - _del_record "$_zone_id" "$_record_id" - if [ -z "$response" ] ; then - _info "Successfully deleted record" - return 0 - else - _err "Something went wrong while deleting the record" - return 1 - fi + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi } +_dns_dynv6_rm_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ]; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} #get the zoneid for a specifc record or zone #usage: _get_zone_id §record #where $record is the record to get the id for #returns _zone_id the id of the zone -_get_zone_id(){ +_get_zone_id() { record="$1" _debug "getting zone id for $record" _dynv6_rest GET zones - - zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" - #echo $zones - selected="" - for z in $zones; do - z="${z#name:}" - _debug zone: "$z" - if _contains "$record" "$z"; then - _debug "$z found in $record" - selected="$z" - fi - done - if [ -z "$selected" ]; then - _err "no zone found" - return 1 - fi - - zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" - _zone_id="${zone_id#id:}" - _debug "zone id: $_zone_id" + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" } -_get_zone_name(){ - _zone_id="$1" - _dynv6_rest GET zones/"$_zone_id" - _zone_name="$(echo "$response" | tr ',' '\n'| tr -d '{'|grep name|tr -d '"')" - _zone_name="${_zone_name#name:}" +_get_zone_name() { + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" + _zone_name="${_zone_name#name:}" } #usaage _get_record_id $zone_id $record # where zone_id is thevalue returned by _get_zone_id # and record ist in the form _acme.www for an fqdn of _acme.www.example.com # returns _record_id -_get_record_id(){ +_get_record_id() { _zone_id="$1" record="$2" value="$3" - _dynv6_rest GET "zones/$_zone_id/records" - if ! _get_record_id_from_response "$response" ; then - _err "no such record $record found in zone $_zone_id" - return 1 - fi + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response"; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi } -_get_record_id_from_response(){ +_get_record_id_from_response() { response="$1" - _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id |tr -d '"'|tr -d 'id:')" - #_record_id="${_record_id#id:}" - if [ -z "$_record_id" ]; then - _err "no such record: $record found in zone $_zone_id" - return 1 - fi - _debug "record id: $_record_id" - return 0 + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 } #usage: _set_record TXT _acme_challenge.www longvalue 12345678 #zone id is optional can also be set as vairable bevor calling this method -_set_record(){ - type="$1" - record="$2" - value="$3" - if [ "$4" ]; then - _zone_id="$4" - fi - data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" - #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' - echo "$data" - #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" - _dynv6_rest POST "zones/$_zone_id/records" "$data" +_set_record() { + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" } -_del_record(){ +_del_record() { _zone_id=$1 _record_id=$2 _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" } _dynv6_rest() { - m=$1 #method GET,POST,DELETE or PUT + m=$1 #method GET,POST,DELETE or PUT ep="$2" #the endpoint data="$3" _debug "$ep" token_trimmed=$(echo "$dynv6_token" | tr -d '"') - + export _H1="Authorization: Bearer $token_trimmed" export _H2="Content-Type: application/json" - + if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" @@ -287,4 +284,3 @@ _dynv6_rest() { _debug2 response "$response" return 0 } - From 65aa7b10844eeb9b2692e5e2731a4d4eda99d36e Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 16:01:46 +0200 Subject: [PATCH 0805/2234] formatting --- dnsapi/dns_dynv6.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index c41aef3a..e51e118a 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -109,13 +109,12 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" + dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" + if [ "$dynv6_token" ]; then + _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" + if [ "$DYNV6_TOKEN" ]; then + _saveaccountconf_mutable dynv6_token "$dynv6_token" + fi else _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" From e2a5af1cf7355f0c58d2f64b7c9579a5b6f32dea Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 14 Jul 2020 21:49:50 +0800 Subject: [PATCH 0806/2234] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 22eaaa86..f766ef2f 100755 --- a/acme.sh +++ b/acme.sh @@ -1039,7 +1039,7 @@ _sign() { _ec_s="0${_ec_s}" done fi - _debug3 "_ec_r" "$_ec_r" + _debug3 "_ec_r" "$_ec_r" _debug3 "_ec_s" "$_ec_s" printf "%s" "$_ec_r$_ec_s" | _h2b | _base64 else From 236e8cc95c28279d292706358e011f790912e1c2 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 15 Jul 2020 21:30:17 +0800 Subject: [PATCH 0807/2234] add gitads --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 67402f29..73532c65 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + + +acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial + GitAds + + + - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. - Support ACME v1 and ACME v2 From 5c295254bf73ae551869aede25c710efeabfaacb Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 15 Jul 2020 21:31:14 +0800 Subject: [PATCH 0808/2234] fix format --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 73532c65..0c69fb44 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial + + GitAds From d94f241d3cccf05589ac69d225b3cd4e442e357b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Wed, 15 Jul 2020 20:45:11 +0200 Subject: [PATCH 0809/2234] Upgrade Travis image --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 91da2731..a9785d0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: shell -dist: trusty +dist: bionic os: - linux From 9b23cd6d1998fada386cb8feeee5e73da578497e Mon Sep 17 00:00:00 2001 From: Andy Botting Date: Mon, 13 Jul 2020 15:53:15 +1000 Subject: [PATCH 0810/2234] Add OpenStack Barbican deploy support This provider relies on the the python-openstackclient and python-designateclient tools be installed and working, with either password or application credentials loaded in your env. --- deploy/openstack.sh | 262 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 deploy/openstack.sh diff --git a/deploy/openstack.sh b/deploy/openstack.sh new file mode 100644 index 00000000..42cf7848 --- /dev/null +++ b/deploy/openstack.sh @@ -0,0 +1,262 @@ +#!/usr/bin/env sh + +# OpenStack Barbican deploy hook +# +# This requires you to have OpenStackClient and python-barbicanclient +# installed. +# +# You will require Keystone V3 credentials loaded into your environment, which +# could be either password or v3applicationcredential type. +# +# Author: Andy Botting + +openstack_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if ! _exists openstack; then + _err "OpenStack client not found" + return 1 + fi + + _openstack_credentials || return $? + + _info "Generate import pkcs12" + _import_pkcs12="$(_mktemp)" + if ! _openstack_to_pkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca"; then + _err "Error creating pkcs12 certificate" + return 1 + fi + _debug _import_pkcs12 "$_import_pkcs12" + _base64_pkcs12=$(_base64 "multiline" < "$_import_pkcs12") + + secretHrefs=$(_openstack_get_secrets) + _debug secretHrefs "$secretHrefs" + _openstack_store_secret || return $? + + if [ -n "$secretHrefs" ]; then + _info "Cleaning up existing secret" + _openstack_delete_secrets || return $? + fi + + _info "Certificate successfully deployed" + return 0 +} + +_openstack_store_secret() { + if ! openstack secret store --name "$_cdomain." -t 'application/octet-stream' -e base64 --payload "$_base64_pkcs12"; then + _err "Failed to create OpenStack secret" + return 1 + fi + return +} + +_openstack_delete_secrets() { + echo "$secretHrefs" | while read -r secretHref; do + _info "Deleting old secret $secretHref" + if ! openstack secret delete "$secretHref"; then + _err "Failed to delete OpenStack secret" + return 1 + fi + done + return +} + +_openstack_get_secrets() { + if ! secretHrefs=$(openstack secret list -f value --name "$_cdomain." | cut -d' ' -f1); then + _err "Failed to list secrets" + return 1 + fi + echo "$secretHrefs" +} + +_openstack_to_pkcs() { + # The existing _toPkcs command can't allow an empty password, due to sh + # -z test, so copied here and forcing the empty password. + _cpfx="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + + ${ACME_OPENSSL_BIN:-openssl} pkcs12 -export -out "$_cpfx" -inkey "$_ckey" -in "$_ccert" -certfile "$_cca" -password "pass:" +} + +_openstack_credentials() { + _debug "Check OpenStack credentials" + + # If we have OS_AUTH_URL already set in the environment, then assume we want + # to use those, otherwise use stored credentials + if [ -n "$OS_AUTH_URL" ]; then + _debug "OS_AUTH_URL env var found, using environment" + else + _debug "OS_AUTH_URL not found, loading stored credentials" + OS_AUTH_URL="${OS_AUTH_URL:-$(_readaccountconf_mutable OS_AUTH_URL)}" + OS_IDENTITY_API_VERSION="${OS_IDENTITY_API_VERSION:-$(_readaccountconf_mutable OS_IDENTITY_API_VERSION)}" + OS_AUTH_TYPE="${OS_AUTH_TYPE:-$(_readaccountconf_mutable OS_AUTH_TYPE)}" + OS_APPLICATION_CREDENTIAL_ID="${OS_APPLICATION_CREDENTIAL_ID:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID)}" + OS_APPLICATION_CREDENTIAL_SECRET="${OS_APPLICATION_CREDENTIAL_SECRET:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET)}" + OS_USERNAME="${OS_USERNAME:-$(_readaccountconf_mutable OS_USERNAME)}" + OS_PASSWORD="${OS_PASSWORD:-$(_readaccountconf_mutable OS_PASSWORD)}" + OS_PROJECT_NAME="${OS_PROJECT_NAME:-$(_readaccountconf_mutable OS_PROJECT_NAME)}" + OS_PROJECT_ID="${OS_PROJECT_ID:-$(_readaccountconf_mutable OS_PROJECT_ID)}" + OS_USER_DOMAIN_NAME="${OS_USER_DOMAIN_NAME:-$(_readaccountconf_mutable OS_USER_DOMAIN_NAME)}" + OS_USER_DOMAIN_ID="${OS_USER_DOMAIN_ID:-$(_readaccountconf_mutable OS_USER_DOMAIN_ID)}" + OS_PROJECT_DOMAIN_NAME="${OS_PROJECT_DOMAIN_NAME:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_NAME)}" + OS_PROJECT_DOMAIN_ID="${OS_PROJECT_DOMAIN_ID:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_ID)}" + fi + + # Check each var and either save or clear it depending on whether its set. + # The helps us clear out old vars in the case where a user may want + # to switch between password and app creds + _debug "OS_AUTH_URL" "$OS_AUTH_URL" + if [ -n "$OS_AUTH_URL" ]; then + export OS_AUTH_URL + _saveaccountconf_mutable OS_AUTH_URL "$OS_AUTH_URL" + else + unset OS_AUTH_URL + _clearaccountconf SAVED_OS_AUTH_URL + fi + + _debug "OS_IDENTITY_API_VERSION" "$OS_IDENTITY_API_VERSION" + if [ -n "$OS_IDENTITY_API_VERSION" ]; then + export OS_IDENTITY_API_VERSION + _saveaccountconf_mutable OS_IDENTITY_API_VERSION "$OS_IDENTITY_API_VERSION" + else + unset OS_IDENTITY_API_VERSION + _clearaccountconf SAVED_OS_IDENTITY_API_VERSION + fi + + _debug "OS_AUTH_TYPE" "$OS_AUTH_TYPE" + if [ -n "$OS_AUTH_TYPE" ]; then + export OS_AUTH_TYPE + _saveaccountconf_mutable OS_AUTH_TYPE "$OS_AUTH_TYPE" + else + unset OS_AUTH_TYPE + _clearaccountconf SAVED_OS_AUTH_TYPE + fi + + _debug "OS_APPLICATION_CREDENTIAL_ID" "$OS_APPLICATION_CREDENTIAL_ID" + if [ -n "$OS_APPLICATION_CREDENTIAL_ID" ]; then + export OS_APPLICATION_CREDENTIAL_ID + _saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID "$OS_APPLICATION_CREDENTIAL_ID" + else + unset OS_APPLICATION_CREDENTIAL_ID + _clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_ID + fi + + _secure_debug "OS_APPLICATION_CREDENTIAL_SECRET" "$OS_APPLICATION_CREDENTIAL_SECRET" + if [ -n "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then + export OS_APPLICATION_CREDENTIAL_SECRET + _saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET "$OS_APPLICATION_CREDENTIAL_SECRET" + else + unset OS_APPLICATION_CREDENTIAL_SECRET + _clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_SECRET + fi + + _debug "OS_USERNAME" "$OS_USERNAME" + if [ -n "$OS_USERNAME" ]; then + export OS_USERNAME + _saveaccountconf_mutable OS_USERNAME "$OS_USERNAME" + else + unset OS_USERNAME + _clearaccountconf SAVED_OS_USERNAME + fi + + _secure_debug "OS_PASSWORD" "$OS_PASSWORD" + if [ -n "$OS_PASSWORD" ]; then + export OS_PASSWORD + _saveaccountconf_mutable OS_PASSWORD "$OS_PASSWORD" + else + unset OS_PASSWORD + _clearaccountconf SAVED_OS_PASSWORD + fi + + _debug "OS_PROJECT_NAME" "$OS_PROJECT_NAME" + if [ -n "$OS_PROJECT_NAME" ]; then + export OS_PROJECT_NAME + _saveaccountconf_mutable OS_PROJECT_NAME "$OS_PROJECT_NAME" + else + unset OS_PROJECT_NAME + _clearaccountconf SAVED_OS_PROJECT_NAME + fi + + _debug "OS_PROJECT_ID" "$OS_PROJECT_ID" + if [ -n "$OS_PROJECT_ID" ]; then + export OS_PROJECT_ID + _saveaccountconf_mutable OS_PROJECT_ID "$OS_PROJECT_ID" + else + unset OS_PROJECT_ID + _clearaccountconf SAVED_OS_PROJECT_ID + fi + + _debug "OS_USER_DOMAIN_NAME" "$OS_USER_DOMAIN_NAME" + if [ -n "$OS_USER_DOMAIN_NAME" ]; then + export OS_USER_DOMAIN_NAME + _saveaccountconf_mutable OS_USER_DOMAIN_NAME "$OS_USER_DOMAIN_NAME" + else + unset OS_USER_DOMAIN_NAME + _clearaccountconf SAVED_OS_USER_DOMAIN_NAME + fi + + _debug "OS_USER_DOMAIN_ID" "$OS_USER_DOMAIN_ID" + if [ -n "$OS_USER_DOMAIN_ID" ]; then + export OS_USER_DOMAIN_ID + _saveaccountconf_mutable OS_USER_DOMAIN_ID "$OS_USER_DOMAIN_ID" + else + unset OS_USER_DOMAIN_ID + _clearaccountconf SAVED_OS_USER_DOMAIN_ID + fi + + _debug "OS_PROJECT_DOMAIN_NAME" "$OS_PROJECT_DOMAIN_NAME" + if [ -n "$OS_PROJECT_DOMAIN_NAME" ]; then + export OS_PROJECT_DOMAIN_NAME + _saveaccountconf_mutable OS_PROJECT_DOMAIN_NAME "$OS_PROJECT_DOMAIN_NAME" + else + unset OS_PROJECT_DOMAIN_NAME + _clearaccountconf SAVED_OS_PROJECT_DOMAIN_NAME + fi + + _debug "OS_PROJECT_DOMAIN_ID" "$OS_PROJECT_DOMAIN_ID" + if [ -n "$OS_PROJECT_DOMAIN_ID" ]; then + export OS_PROJECT_DOMAIN_ID + _saveaccountconf_mutable OS_PROJECT_DOMAIN_ID "$OS_PROJECT_DOMAIN_ID" + else + unset OS_PROJECT_DOMAIN_ID + _clearaccountconf SAVED_OS_PROJECT_DOMAIN_ID + fi + + if [ "$OS_AUTH_TYPE" = "v3applicationcredential" ]; then + # Application Credential auth + if [ -z "$OS_APPLICATION_CREDENTIAL_ID" ] || [ -z "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then + _err "When using OpenStack application credentials, OS_APPLICATION_CREDENTIAL_ID" + _err "and OS_APPLICATION_CREDENTIAL_SECRET must be set." + _err "Please check your credentials and try again." + return 1 + fi + else + # Password auth + if [ -z "$OS_USERNAME" ] || [ -z "$OS_PASSWORD" ]; then + _err "OpenStack username or password not found." + _err "Please check your credentials and try again." + return 1 + fi + + if [ -z "$OS_PROJECT_NAME" ] && [ -z "$OS_PROJECT_ID" ]; then + _err "When using password authentication, OS_PROJECT_NAME or" + _err "OS_PROJECT_ID must be set." + _err "Please check your credentials and try again." + return 1 + fi + fi + + return 0 +} From aad9afad59fc5efd1c4da2de731324041de4ae76 Mon Sep 17 00:00:00 2001 From: Andy Botting Date: Mon, 13 Jul 2020 13:18:57 +1000 Subject: [PATCH 0811/2234] Add OpenStack Designate DNS API support This provider relies on the the python-openstackclient and python-designateclient tools be installed and working, with either password or application credentials loaded in your env. --- dnsapi/openstack.sh | 348 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100755 dnsapi/openstack.sh diff --git a/dnsapi/openstack.sh b/dnsapi/openstack.sh new file mode 100755 index 00000000..38619e6f --- /dev/null +++ b/dnsapi/openstack.sh @@ -0,0 +1,348 @@ +#!/usr/bin/env sh + +# OpenStack Designate API plugin +# +# This requires you to have OpenStackClient and python-desginateclient +# installed. +# +# You will require Keystone V3 credentials loaded into your environment, which +# could be either password or v3applicationcredential type. +# +# Author: Andy Botting + +######## Public functions ##################### + +# Usage: dns_openstack_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_openstack_add() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _dns_openstack_credentials || return $? + _dns_openstack_check_setup || return $? + _dns_openstack_find_zone || return $? + _dns_openstack_get_recordset || return $? + _debug _recordset_id "$_recordset_id" + if [ -n "$_recordset_id" ]; then + _dns_openstack_get_records || return $? + _debug _records "$_records" + fi + _dns_openstack_create_recordset || return $? +} + +# Usage: dns_openstack_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Remove the txt record after validation. +dns_openstack_rm() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _dns_openstack_credentials || return $? + _dns_openstack_check_setup || return $? + _dns_openstack_find_zone || return $? + _dns_openstack_get_recordset || return $? + _debug _recordset_id "$_recordset_id" + if [ -n "$_recordset_id" ]; then + _dns_openstack_get_records || return $? + _debug _records "$_records" + fi + _dns_openstack_delete_recordset || return $? +} + +#################### Private functions below ################################## + +_dns_openstack_create_recordset() { + + if [ -z "$_recordset_id" ]; then + _info "Creating a new recordset" + if ! _recordset_id=$(openstack recordset create -c id -f value --type TXT --record "$txtvalue" "$_zone_id" "$fulldomain."); then + _err "No recordset ID found after create" + return 1 + fi + else + _info "Updating existing recordset" + # Build new list of --record args for update + _record_args="--record $txtvalue" + for _rec in $_records; do + _record_args="$_record_args --record $_rec" + done + # shellcheck disable=SC2086 + if ! _recordset_id=$(openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain."); then + _err "Recordset update failed" + return 1 + fi + fi + + _max_retries=60 + _sleep_sec=5 + _retry_times=0 + while [ "$_retry_times" -lt "$_max_retries" ]; do + _retry_times=$(_math "$_retry_times" + 1) + _debug3 _retry_times "$_retry_times" + + _record_status=$(openstack recordset show -c status -f value "$_zone_id" "$_recordset_id") + _info "Recordset status is $_record_status" + if [ "$_record_status" = "ACTIVE" ]; then + return 0 + elif [ "$_record_status" = "ERROR" ]; then + return 1 + else + _sleep $_sleep_sec + fi + done + + _err "Recordset failed to become ACTIVE" + return 1 +} + +_dns_openstack_delete_recordset() { + + if [ "$_records" = "$txtvalue" ]; then + _info "Only one record found, deleting recordset" + if ! openstack recordset delete "$_zone_id" "$fulldomain." >/dev/null; then + _err "Failed to delete recordset" + return 1 + fi + else + _info "Found existing records, updating recordset" + # Build new list of --record args for update + _record_args="" + for _rec in $_records; do + if [ "$_rec" = "$txtvalue" ]; then + continue + fi + _record_args="$_record_args --record $_rec" + done + # shellcheck disable=SC2086 + if ! openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain." >/dev/null; then + _err "Recordset update failed" + return 1 + fi + fi +} + +_dns_openstack_get_root() { + # Take the full fqdn and strip away pieces until we get an exact zone name + # match. For example, _acme-challenge.something.domain.com might need to go + # into something.domain.com or domain.com + _zone_name=$1 + _zone_list=$2 + while [ "$_zone_name" != "" ]; do + _zone_name="$(echo "$_zone_name" | sed 's/[^.]*\.*//')" + echo "$_zone_list" | while read -r id name; do + if _startswith "$_zone_name." "$name"; then + echo "$id" + fi + done + done | _head_n 1 +} + +_dns_openstack_find_zone() { + if ! _zone_list="$(openstack zone list -c id -c name -f value)"; then + _err "Can't list zones. Check your OpenStack credentials" + return 1 + fi + _debug _zone_list "$_zone_list" + + if ! _zone_id="$(_dns_openstack_get_root "$fulldomain" "$_zone_list")"; then + _err "Can't find a matching zone. Check your OpenStack credentials" + return 1 + fi + _debug _zone_id "$_zone_id" +} + +_dns_openstack_get_records() { + if ! _records=$(openstack recordset show -c records -f value "$_zone_id" "$fulldomain."); then + _err "Failed to get records" + return 1 + fi + return 0 +} + +_dns_openstack_get_recordset() { + if ! _recordset_id=$(openstack recordset list -c id -f value --name "$fulldomain." "$_zone_id"); then + _err "Failed to get recordset" + return 1 + fi + return 0 +} + +_dns_openstack_check_setup() { + if ! _exists openstack; then + _err "OpenStack client not found" + return 1 + fi +} + +_dns_openstack_credentials() { + _debug "Check OpenStack credentials" + + # If we have OS_AUTH_URL already set in the environment, then assume we want + # to use those, otherwise use stored credentials + if [ -n "$OS_AUTH_URL" ]; then + _debug "OS_AUTH_URL env var found, using environment" + else + _debug "OS_AUTH_URL not found, loading stored credentials" + OS_AUTH_URL="${OS_AUTH_URL:-$(_readaccountconf_mutable OS_AUTH_URL)}" + OS_IDENTITY_API_VERSION="${OS_IDENTITY_API_VERSION:-$(_readaccountconf_mutable OS_IDENTITY_API_VERSION)}" + OS_AUTH_TYPE="${OS_AUTH_TYPE:-$(_readaccountconf_mutable OS_AUTH_TYPE)}" + OS_APPLICATION_CREDENTIAL_ID="${OS_APPLICATION_CREDENTIAL_ID:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID)}" + OS_APPLICATION_CREDENTIAL_SECRET="${OS_APPLICATION_CREDENTIAL_SECRET:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET)}" + OS_USERNAME="${OS_USERNAME:-$(_readaccountconf_mutable OS_USERNAME)}" + OS_PASSWORD="${OS_PASSWORD:-$(_readaccountconf_mutable OS_PASSWORD)}" + OS_PROJECT_NAME="${OS_PROJECT_NAME:-$(_readaccountconf_mutable OS_PROJECT_NAME)}" + OS_PROJECT_ID="${OS_PROJECT_ID:-$(_readaccountconf_mutable OS_PROJECT_ID)}" + OS_USER_DOMAIN_NAME="${OS_USER_DOMAIN_NAME:-$(_readaccountconf_mutable OS_USER_DOMAIN_NAME)}" + OS_USER_DOMAIN_ID="${OS_USER_DOMAIN_ID:-$(_readaccountconf_mutable OS_USER_DOMAIN_ID)}" + OS_PROJECT_DOMAIN_NAME="${OS_PROJECT_DOMAIN_NAME:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_NAME)}" + OS_PROJECT_DOMAIN_ID="${OS_PROJECT_DOMAIN_ID:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_ID)}" + fi + + # Check each var and either save or clear it depending on whether its set. + # The helps us clear out old vars in the case where a user may want + # to switch between password and app creds + _debug "OS_AUTH_URL" "$OS_AUTH_URL" + if [ -n "$OS_AUTH_URL" ]; then + export OS_AUTH_URL + _saveaccountconf_mutable OS_AUTH_URL "$OS_AUTH_URL" + else + unset OS_AUTH_URL + _clearaccountconf SAVED_OS_AUTH_URL + fi + + _debug "OS_IDENTITY_API_VERSION" "$OS_IDENTITY_API_VERSION" + if [ -n "$OS_IDENTITY_API_VERSION" ]; then + export OS_IDENTITY_API_VERSION + _saveaccountconf_mutable OS_IDENTITY_API_VERSION "$OS_IDENTITY_API_VERSION" + else + unset OS_IDENTITY_API_VERSION + _clearaccountconf SAVED_OS_IDENTITY_API_VERSION + fi + + _debug "OS_AUTH_TYPE" "$OS_AUTH_TYPE" + if [ -n "$OS_AUTH_TYPE" ]; then + export OS_AUTH_TYPE + _saveaccountconf_mutable OS_AUTH_TYPE "$OS_AUTH_TYPE" + else + unset OS_AUTH_TYPE + _clearaccountconf SAVED_OS_AUTH_TYPE + fi + + _debug "OS_APPLICATION_CREDENTIAL_ID" "$OS_APPLICATION_CREDENTIAL_ID" + if [ -n "$OS_APPLICATION_CREDENTIAL_ID" ]; then + export OS_APPLICATION_CREDENTIAL_ID + _saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID "$OS_APPLICATION_CREDENTIAL_ID" + else + unset OS_APPLICATION_CREDENTIAL_ID + _clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_ID + fi + + _secure_debug "OS_APPLICATION_CREDENTIAL_SECRET" "$OS_APPLICATION_CREDENTIAL_SECRET" + if [ -n "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then + export OS_APPLICATION_CREDENTIAL_SECRET + _saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET "$OS_APPLICATION_CREDENTIAL_SECRET" + else + unset OS_APPLICATION_CREDENTIAL_SECRET + _clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_SECRET + fi + + _debug "OS_USERNAME" "$OS_USERNAME" + if [ -n "$OS_USERNAME" ]; then + export OS_USERNAME + _saveaccountconf_mutable OS_USERNAME "$OS_USERNAME" + else + unset OS_USERNAME + _clearaccountconf SAVED_OS_USERNAME + fi + + _secure_debug "OS_PASSWORD" "$OS_PASSWORD" + if [ -n "$OS_PASSWORD" ]; then + export OS_PASSWORD + _saveaccountconf_mutable OS_PASSWORD "$OS_PASSWORD" + else + unset OS_PASSWORD + _clearaccountconf SAVED_OS_PASSWORD + fi + + _debug "OS_PROJECT_NAME" "$OS_PROJECT_NAME" + if [ -n "$OS_PROJECT_NAME" ]; then + export OS_PROJECT_NAME + _saveaccountconf_mutable OS_PROJECT_NAME "$OS_PROJECT_NAME" + else + unset OS_PROJECT_NAME + _clearaccountconf SAVED_OS_PROJECT_NAME + fi + + _debug "OS_PROJECT_ID" "$OS_PROJECT_ID" + if [ -n "$OS_PROJECT_ID" ]; then + export OS_PROJECT_ID + _saveaccountconf_mutable OS_PROJECT_ID "$OS_PROJECT_ID" + else + unset OS_PROJECT_ID + _clearaccountconf SAVED_OS_PROJECT_ID + fi + + _debug "OS_USER_DOMAIN_NAME" "$OS_USER_DOMAIN_NAME" + if [ -n "$OS_USER_DOMAIN_NAME" ]; then + export OS_USER_DOMAIN_NAME + _saveaccountconf_mutable OS_USER_DOMAIN_NAME "$OS_USER_DOMAIN_NAME" + else + unset OS_USER_DOMAIN_NAME + _clearaccountconf SAVED_OS_USER_DOMAIN_NAME + fi + + _debug "OS_USER_DOMAIN_ID" "$OS_USER_DOMAIN_ID" + if [ -n "$OS_USER_DOMAIN_ID" ]; then + export OS_USER_DOMAIN_ID + _saveaccountconf_mutable OS_USER_DOMAIN_ID "$OS_USER_DOMAIN_ID" + else + unset OS_USER_DOMAIN_ID + _clearaccountconf SAVED_OS_USER_DOMAIN_ID + fi + + _debug "OS_PROJECT_DOMAIN_NAME" "$OS_PROJECT_DOMAIN_NAME" + if [ -n "$OS_PROJECT_DOMAIN_NAME" ]; then + export OS_PROJECT_DOMAIN_NAME + _saveaccountconf_mutable OS_PROJECT_DOMAIN_NAME "$OS_PROJECT_DOMAIN_NAME" + else + unset OS_PROJECT_DOMAIN_NAME + _clearaccountconf SAVED_OS_PROJECT_DOMAIN_NAME + fi + + _debug "OS_PROJECT_DOMAIN_ID" "$OS_PROJECT_DOMAIN_ID" + if [ -n "$OS_PROJECT_DOMAIN_ID" ]; then + export OS_PROJECT_DOMAIN_ID + _saveaccountconf_mutable OS_PROJECT_DOMAIN_ID "$OS_PROJECT_DOMAIN_ID" + else + unset OS_PROJECT_DOMAIN_ID + _clearaccountconf SAVED_OS_PROJECT_DOMAIN_ID + fi + + if [ "$OS_AUTH_TYPE" = "v3applicationcredential" ]; then + # Application Credential auth + if [ -z "$OS_APPLICATION_CREDENTIAL_ID" ] || [ -z "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then + _err "When using OpenStack application credentials, OS_APPLICATION_CREDENTIAL_ID" + _err "and OS_APPLICATION_CREDENTIAL_SECRET must be set." + _err "Please check your credentials and try again." + return 1 + fi + else + # Password auth + if [ -z "$OS_USERNAME" ] || [ -z "$OS_PASSWORD" ]; then + _err "OpenStack username or password not found." + _err "Please check your credentials and try again." + return 1 + fi + + if [ -z "$OS_PROJECT_NAME" ] && [ -z "$OS_PROJECT_ID" ]; then + _err "When using password authentication, OS_PROJECT_NAME or" + _err "OS_PROJECT_ID must be set." + _err "Please check your credentials and try again." + return 1 + fi + fi + + return 0 +} From 3ce967d8e52df4d934fda63363953311f31d3932 Mon Sep 17 00:00:00 2001 From: Andy Botting Date: Thu, 16 Jul 2020 13:53:21 +1000 Subject: [PATCH 0812/2234] Fix CI test failure for deploy/openstack.sh --- deploy/openstack.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/openstack.sh b/deploy/openstack.sh index 42cf7848..f2058853 100644 --- a/deploy/openstack.sh +++ b/deploy/openstack.sh @@ -37,7 +37,7 @@ openstack_deploy() { return 1 fi _debug _import_pkcs12 "$_import_pkcs12" - _base64_pkcs12=$(_base64 "multiline" < "$_import_pkcs12") + _base64_pkcs12=$(_base64 "multiline" <"$_import_pkcs12") secretHrefs=$(_openstack_get_secrets) _debug secretHrefs "$secretHrefs" From 61613bee98b5d69c054f2842d01b71cb9bf2b890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:13:15 +0200 Subject: [PATCH 0813/2234] Fix SC2230 --- deploy/vault_cli.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/vault_cli.sh b/deploy/vault_cli.sh index 5395d87e..8b854137 100644 --- a/deploy/vault_cli.sh +++ b/deploy/vault_cli.sh @@ -43,7 +43,7 @@ vault_cli_deploy() { return 1 fi - VAULT_CMD=$(which vault) + VAULT_CMD=$(command -v vault) if [ ! $? ]; then _err "cannot find vault binary!" return 1 From fe4111a9f52382b138af2536426dab3c2588b79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:14:50 +0200 Subject: [PATCH 0814/2234] Fix SC2236 --- dnsapi/dns_cloudns.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_cloudns.sh b/dnsapi/dns_cloudns.sh index df824e86..381d17ec 100755 --- a/dnsapi/dns_cloudns.sh +++ b/dnsapi/dns_cloudns.sh @@ -69,7 +69,7 @@ dns_cloudns_rm() { for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g') - if [ ! -z "$record_id" ]; then + if [ -n "$record_id" ]; then _debug zone "$zone" _debug host "$host" _debug record "$record" @@ -91,7 +91,7 @@ dns_cloudns_rm() { #################### Private functions below ################################## _dns_cloudns_init_check() { - if [ ! -z "$CLOUDNS_INIT_CHECK_COMPLETED" ]; then + if [ -n "$CLOUDNS_INIT_CHECK_COMPLETED" ]; then return 0 fi @@ -164,7 +164,7 @@ _dns_cloudns_http_api_call() { _debug CLOUDNS_SUB_AUTH_ID "$CLOUDNS_SUB_AUTH_ID" _debug CLOUDNS_AUTH_PASSWORD "$CLOUDNS_AUTH_PASSWORD" - if [ ! -z "$CLOUDNS_SUB_AUTH_ID" ]; then + if [ -n "$CLOUDNS_SUB_AUTH_ID" ]; then auth_user="sub-auth-id=$CLOUDNS_SUB_AUTH_ID" else auth_user="auth-id=$CLOUDNS_AUTH_ID" From 49094120d927d4e846555564fb292212f4899a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:17:11 +0200 Subject: [PATCH 0815/2234] Fix SC2236 --- dnsapi/dns_cyon.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cyon.sh b/dnsapi/dns_cyon.sh index 8db3011d..2dca90c0 100644 --- a/dnsapi/dns_cyon.sh +++ b/dnsapi/dns_cyon.sh @@ -66,7 +66,7 @@ _cyon_load_credentials() { _debug "Save credentials to account.conf" _saveaccountconf CY_Username "${CY_Username}" _saveaccountconf CY_Password_B64 "$CY_Password_B64" - if [ ! -z "${CY_OTP_Secret}" ]; then + if [ -n "${CY_OTP_Secret}" ]; then _saveaccountconf CY_OTP_Secret "$CY_OTP_Secret" else _clearaccountconf CY_OTP_Secret @@ -164,7 +164,7 @@ _cyon_login() { # todo: instead of just checking if the env variable is defined, check if we actually need to do a 2FA auth request. # 2FA authentication with OTP? - if [ ! -z "${CY_OTP_Secret}" ]; then + if [ -n "${CY_OTP_Secret}" ]; then _info " - Authorising with OTP code..." if ! _exists oathtool; then From 14089f8c6af3c8808702e4f58801deb10e492ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:18:12 +0200 Subject: [PATCH 0816/2234] Fix SC2236 --- dnsapi/dns_dgon.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh index 515e87d5..ac14da48 100755 --- a/dnsapi/dns_dgon.sh +++ b/dnsapi/dns_dgon.sh @@ -122,12 +122,12 @@ dns_dgon_rm() { ## check for what we are looking for: "type":"A","name":"$_sub_domain" record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")" - if [ ! -z "$record" ]; then + if [ -n "$record" ]; then ## we found records rec_ids="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")" _debug rec_ids "$rec_ids" - if [ ! -z "$rec_ids" ]; then + if [ -n "$rec_ids" ]; then echo "$rec_ids" | while IFS= read -r rec_id; do ## delete the record ## delete URL for removing the one we dont want @@ -218,7 +218,7 @@ _get_base_domain() { ## we got part of a domain back - grep it out found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")" ## check if it exists - if [ ! -z "$found" ]; then + if [ -n "$found" ]; then ## exists - exit loop returning the parts sub_point=$(_math $i - 1) _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point") From eb9005ad744224e54b291532328b52d8d87e3431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:18:46 +0200 Subject: [PATCH 0817/2234] Fix SC2236 --- dnsapi/dns_yandex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index 5721f994..0a2c3330 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -25,7 +25,7 @@ dns_yandex_add() { _PDD_get_record_ids || return 1 _debug "Record_ids: $record_ids" - if [ ! -z "$record_ids" ]; then + if [ -n "$record_ids" ]; then _info "All existing $subdomain records from $domain will be removed at the very end." fi From f18f4c69f26a8606e6f95754ebebdc762242a88d Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Thu, 23 Jul 2020 13:53:53 +0100 Subject: [PATCH 0818/2234] Adds Docker multi-arch build support --- .github/workflows/dockerhub.yml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index f1c0025d..7b44f938 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -8,9 +8,19 @@ jobs: build: runs-on: ubuntu-latest steps: - - name: trigger - run: curl -X POST https://hub.docker.com/api/build/v1/source/1813a660-2ee5-4583-a238-dd54e9a6ebac/trigger/c8cd9f1f-f269-45bc-9750-a08327257f62/call/ - - - - + - name: checkout code + uses: actions/checkout@v2 + - name: install buildx + id: buildx + uses: crazy-max/ghaction-docker-buildx@v1 + with: + version: latest + - name: login to docker hub + run: | + echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin + - name: build the image + run: | + docker buildx build \ + --push \ + --tag neilpang/acme.sh:latest \ + --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . From 67360e93b8564228035b4a7604d3c70e887ff6e7 Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 24 Jul 2020 09:25:58 +0100 Subject: [PATCH 0819/2234] Correctly labels Docker images per branch --- .github/workflows/dockerhub.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 7b44f938..8c277827 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -18,9 +18,17 @@ jobs: - name: login to docker hub run: | echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - - name: build the image + - name: build and push the image (master branch) run: | docker buildx build \ --push \ --tag neilpang/acme.sh:latest \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . + if: ${{ github.ref == 'refs/heads/master' }} + - name: build and push the image (dev branch) + run: | + docker buildx build \ + --push \ + --tag neilpang/acme.sh:dev \ + --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . + if: ${{ github.ref == 'refs/heads/dev' }} From 6a0ed51f5ee7c1af00652890b34603dc5f4d201d Mon Sep 17 00:00:00 2001 From: Adrian Fedoreanu Date: Fri, 24 Jul 2020 16:28:34 +0200 Subject: [PATCH 0820/2234] replace response equals with contains --- dnsapi/dns_1984hosting.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 09f02796..bcb675ab 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -3,7 +3,7 @@ #So, here must be a method dns_1984hosting_add() #Which will be called by acme.sh to add the txt record to your api system. #returns 0 means success, otherwise error. -# + #Author: Adrian Fedoreanu #Report Bugs here: https://github.com/acmesh-official/acme.sh # or here... https://github.com/acmesh-official/acme.sh/issues/2851 @@ -100,7 +100,7 @@ _1984hosting_add_txt_record() { elif _contains "$response" ""; then _err "1984Hosting failed to add TXT record for $subdomain. Check $HTTP_HEADER file" return 1 - elif [ "$response" = '{"auth": false, "ok": false}' ]; then + elif _contains "$response" '"auth": false'; then _err "1984Hosting failed to add TXT record for $subdomain. Invalid or expired cookie" return 1 fi @@ -167,7 +167,7 @@ _1984hosting_login() { response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" - if [ "$response" = '{"loggedin": true, "ok": true}' ]; then + if _contains "$response" '"loggedin": true'; then One984HOSTING_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" export One984HOSTING_COOKIE _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" @@ -196,7 +196,7 @@ _check_cookie() { _authget "https://management.1984hosting.com/accounts/loginstatus/" response="$(echo "$_response" | _normalizeJson)" - if [ "$_response" = '{"ok": true}' ]; then + if _contains "$response" '"ok": true'; then _debug "Cached cookie still valid" return 0 fi From 4b35aef728eb3d35f3faac08f44e0615b6797e3e Mon Sep 17 00:00:00 2001 From: 12bbf7608ae1 <33011786+pdxgf1208@users.noreply.github.com> Date: Sat, 25 Jul 2020 21:48:11 +0800 Subject: [PATCH 0821/2234] Update dns_dynv6.sh Add support for domains like '*.v6.rocks' --- dnsapi/dns_dynv6.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 819372c2..50eda74b 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -80,7 +80,7 @@ _generate_new_key() { _get_domain() { _full_domain="$1" _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy'; then + if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks' ; then _err "The hosts does not seem to be a dynv6 host" return 1 fi From 5f5096e1d40f17acd414f20d582f43a634831e56 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 25 Jul 2020 21:48:35 -0600 Subject: [PATCH 0822/2234] Addressing issues found in DS218+ DSM DS218+ appears to have a slighly different DSM that sends back headers in lowercase. Reported by @BartSiwek in #2727 --- deploy/synology_dsm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index c57d50bc..2ec0ceb3 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -22,7 +22,7 @@ ######## Public functions ##################### _syno_get_cookie_data() { - grep "\W$1=" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' + grep -i "\W$1=" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' } #domain keyfile certfile cafile fullchain @@ -79,7 +79,7 @@ synology_dsm_deploy() { encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" encoded_did="$(printf "%s" "$SYNO_DID" | _url_encode)" response=$(_get "$_base_url/webman/login.cgi?username=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_id=$encoded_did" 1) - token=$(echo "$response" | grep "X-SYNO-TOKEN:" | sed -n 's/^X-SYNO-TOKEN: \(.*\)$/\1/p' | tr -d "\r\n") + token=$(echo "$response" | grep -i "X-SYNO-TOKEN:" | sed -n 's/^X-SYNO-TOKEN: \(.*\)$/\1/pI' | tr -d "\r\n") _debug3 response "$response" _debug token "$token" From 4f3f4e23e4f9ca5c11d381c435944c9229128f74 Mon Sep 17 00:00:00 2001 From: Vinton Huang Date: Mon, 27 Jul 2020 03:55:07 +0800 Subject: [PATCH 0823/2234] Fix failed test in acmetest. Item alpine:latest - test 12: le_test_standandalone_deactivate_v2 - Message of failed test [1]: /root/.acme.sh/acme.sh --deactivate -d testdocker.acme.sh [FAIL] - Reason of failure: left brace was not escaped. According to the standard [2], if special chars appear first in an ERE, it will produce undefined results. - egrep from busybox (and thus alpine) take it as an error, but egrep from GNU grep (included in most distros) and *BSD are more tolerant, just ignore it. - Fix: consider the right brace at the right-hand side of the ERE, the result string will not contain right brace. So the left-hand side should not contain left brace, too. [1] https://github.com/acmesh-official/acmetest/blob/446939706e07c26267d83f71e4d0b8b152b0d3de/logs/alpine-latest.out#L119 [2] 9.4.3 ERE Special Characters, The Open Group Base Specifications. https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index f766ef2f..04c60ee6 100755 --- a/acme.sh +++ b/acme.sh @@ -5642,7 +5642,7 @@ _deactivate() { _URL_NAME="uri" fi - entries="$(echo "$response" | _egrep_o "{ *\"type\":\"[^\"]*\", *\"status\": *\"valid\", *\"$_URL_NAME\"[^}]*")" + entries="$(echo "$response" | _egrep_o "[^{]*\"type\":\"[^\"]*\", *\"status\": *\"valid\", *\"$_URL_NAME\"[^}]*")" if [ -z "$entries" ]; then _info "No valid entries found." if [ -z "$thumbprint" ]; then From f190de39a6de6451a3922b745cc825898595f20b Mon Sep 17 00:00:00 2001 From: JP Mens Date: Mon, 27 Jul 2020 14:34:35 +0200 Subject: [PATCH 0824/2234] Remove unecessary word from README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c69fb44..7e49a714 100644 --- a/README.md +++ b/README.md @@ -309,7 +309,7 @@ https://github.com/acmesh-official/acme.sh/wiki/dnsapi See: https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode first. -If your dns provider doesn't support any api access, you can add the txt record by your hand. +If your dns provider doesn't support any api access, you can add the txt record by hand. ```bash acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com From 1f5cafc2d15eb60fef724f1854d731725b6d2bd2 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Tue, 28 Jul 2020 09:32:15 +0800 Subject: [PATCH 0825/2234] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0c69fb44..953b2c0e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") +[![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial From 5207e111e112cee233911873c21323d43db92bd5 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Sun, 2 Aug 2020 00:19:28 +0200 Subject: [PATCH 0826/2234] initial kapper.net DNS API support hopefully this time we get it right ;) Co-Authored-By: Harald Kapper --- dnsapi/dns_kappernet.sh | 141 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 dnsapi/dns_kappernet.sh diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh new file mode 100644 index 00000000..71dae73d --- /dev/null +++ b/dnsapi/dns_kappernet.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env sh + +# kapper.net domain api +# for further questions please contact: support@kapper.net + +#KAPPERNETDNS_Key="yourKAPPERNETapikey" +#KAPPERNETDNS_Secret="yourKAPPERNETapisecret" + +KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.1?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" + +############################################################################### +# called with +# fullhostname: something.example.com +# txtvalue: someacmegenerated string +dns_kappernet_add() { + fullhostname=$1 + txtvalue=$2 + + if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then + KAPPERNETDNS_Key="" + KAPPERNETDNS_Secret="" + _err "You haven't defined kapper.net api key and secret yet." + _err "Please send us mail to support@kapper.net get your key and secret." + return 1 + fi + + #store the api key and email to the account conf file. + _saveaccountconf KAPPERNETDNS_Key "$KAPPERNETDNS_Key" + _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" + _debug "Checking Domain ..." + if ! _get_root "$fullhostname"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "SUBDOMAIN: $_sub_domain" + _debug _domain "DOMAIN: $_domain" + + _info "Trying to add TXT DNS Record" + data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" + if _kappernet_api GET "action=new&subject=$_domain&data=$data"; then + + if _contains "$response" "{\"OK\":true"; then + _info "Waiting 120 seconds for DNS to spread the new record" + _sleep 120 + return 0 + else + _err "Error creating a TXT DNS Record: $fullhostname TXT $txtvalue" + _err "Error Message: $response" + return 1 + fi + fi + _err "Failed creating TXT Record" +} + +############################################################################### +# called with +# fullhostname: something.example.com +dns_kappernet_rm() { + fullhostname=$1 + txtvalue=$2 + + if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then + KAPPERNETDNS_Key="" + KAPPERNETDNS_Secret="" + _err "You haven't defined kapper.net api key and secret yet." + _err "Please send us mail to get your key and secret." + return 1 + fi + + #store the api key and email to the account conf file. + _saveaccountconf KAPPERNETDNS_Key "$KAPPERNETDNS_Key" + _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" + + _info "Trying to remove the TXT Record: $fullhostname" + + if _kappernet_api GET "action=del&subject=$fullhostname"; then + if _contains "$response" "{\"OK\":true"; then + return 0 + else + _err "Error deleting DNS Record: $fullhostname" + _err "Problem: $response" + return 1 + fi + fi + _err "Problem creating TXT DNS record" +} + +#################### Private functions below ################################## +# called with hostname +# e.g._acme-challenge.www.domain.com returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + if ! _kappernet_api GET "action=list&subject=$h"; then + return 1 + fi + if _contains "$response" '"OK":false'; then + _debug "$h not found" + else + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +################################################################################ +# calls the kapper.net DNS Panel API +# with +# method +# param +_kappernet_api() { + method=$1 + param="$2" + + _debug param "PARAMETER=$param" + url="$KAPPERNETDNS_Api&$param" + _debug url "URL=$url" + + if [ "$method" = "GET" ]; then + response="$(_get "$url")" + else + _err "Unsupported method" + return 1 + fi + + _debug2 response "$response" + return 0 +} From 494a1603e4a49cc894ac9a9a239e1fc29dc99fd1 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Sun, 2 Aug 2020 01:41:26 +0200 Subject: [PATCH 0827/2234] Update dns_kappernet.sh add issue-link in sourcecode Co-Authored-By: Harald Kapper --- dnsapi/dns_kappernet.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 71dae73d..75450549 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -2,6 +2,7 @@ # kapper.net domain api # for further questions please contact: support@kapper.net +# please report issues here: https://github.com/acmesh-official/acme.sh/issues/2977 #KAPPERNETDNS_Key="yourKAPPERNETapikey" #KAPPERNETDNS_Secret="yourKAPPERNETapisecret" From 2ba6a85eca0ab2aa1fe869f37639d87a9d22eb28 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Sun, 2 Aug 2020 15:59:46 +0200 Subject: [PATCH 0828/2234] fix multiple txt-records delete + API update new API version fix to delete specific TXT records for wildcard-certs with LE Co-Authored-By: Harald Kapper --- dnsapi/dns_kappernet.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 75450549..a059447a 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -7,7 +7,7 @@ #KAPPERNETDNS_Key="yourKAPPERNETapikey" #KAPPERNETDNS_Secret="yourKAPPERNETapisecret" -KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.1?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" +KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" ############################################################################### # called with @@ -73,8 +73,8 @@ dns_kappernet_rm() { _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" _info "Trying to remove the TXT Record: $fullhostname" - - if _kappernet_api GET "action=del&subject=$fullhostname"; then + data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" + if _kappernet_api GET "action=del&subject=$fullhostname&data=$data"; then if _contains "$response" "{\"OK\":true"; then return 0 else From 40cda9220aa3902b11cb9f38a7dc38b3efd89fc1 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 3 Aug 2020 21:22:32 +0800 Subject: [PATCH 0829/2234] fix https://github.com/acmesh-official/acme.sh/issues/3077 --- dnsapi/dns_azure.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index bf7cf2bf..28b6572a 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -172,7 +172,7 @@ dns_azure_rm() { _azure_rest GET "$acmeRecordURI" "" "$accesstoken" timestamp="$(_time)" if [ "$_code" = "200" ]; then - vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"" | grep -v "$txtvalue")" + vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"" | grep -v -- "$txtvalue")" values="" comma="" for v in $vlist; do From e8bcde31b778ecf1d3c880805b99c3caf322ccc2 Mon Sep 17 00:00:00 2001 From: Draevin Luke Date: Tue, 4 Aug 2020 16:33:24 -0700 Subject: [PATCH 0830/2234] Add Netlify API support --- dnsapi/dns_netlify.sh | 160 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 dnsapi/dns_netlify.sh diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh new file mode 100644 index 00000000..4da97f48 --- /dev/null +++ b/dnsapi/dns_netlify.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env sh + +#NETLIFY_ACCESS_TOKEN="xxxx" + +NETLIFY_HOST="api.netlify.com/api/v1/" +NETLIFY_URL="https://$NETLIFY_HOST" + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_netlify_add() { + fulldomain=$1 + txtvalue=$2 + + NETLIFY_ACCESS_TOKEN="${NETLIFY_ACCESS_TOKEN:-$(_readaccountconf_mutable NETLIFY_ACCESS_TOKEN)}" + + if [ -z "$NETLIFY_ACCESS_TOKEN" ]; then + NETLIFY_ACCESS_TOKEN="" + _err "Please specify your Netlify Access Token and try again." + return 1 + fi + + _info "Using Netlify" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN" + + if ! _get_root "$fulldomain" "$accesstoken"; then + _err "invalid domain" + return 1 + fi + + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + dnsRecordURI="dns_zones/$_domain_id/dns_records" + + body="{\"type\":\"TXT\", \"hostname\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"ttl\":\"10\"}" + + _netlify_rest POST "$dnsRecordURI" "$body" "$NETLIFY_ACCESS_TOKEN" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then + _info "validation value added" + return 0 + else + _err "error adding validation value ($_code)" + return 1 + fi + + _err "Not fully implemented!" + return 1 +} + +#Usage: dns_myapi_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Remove the txt record after validation. +dns_netlify_rm() { + _info "Using Netlify" + _debug txtdomain "$txtdomain" + _debug txt "$txt" + + _saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN" + + if ! _get_root "$txtdomain" "$accesstoken"; then + _err "invalid domain" + return 1 + fi + + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + dnsRecordURI="dns_zones/$_domain_id/dns_records" + + _netlify_rest GET "$dnsRecordURI" "" "$NETLIFY_ACCESS_TOKEN" + + _record_id=$(echo "$response" | _egrep_o "\"type\":\"TXT\",[^\}]*\"value\":\"$txt\"" | head -n 1 | _egrep_o "\"id\":\"[^\"\}]*\"" | cut -d : -f 2 | tr -d \" ) + _debug _record_id "$_record_id" + if [ "$_record_id" ]; then + _netlify_rest DELETE "$dnsRecordURI/$_record_id" "" "$NETLIFY_ACCESS_TOKEN" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + if [ "$_code" = "200" ] || [ "$_code" = '204' ]; then + _info "validation value removed" + return 0 + else + _err "error removing validation value ($_code)" + return 1 + fi + return 0 + fi + return 1 +} + +#################### Private functions below ################################## + +_get_root() { + domain=$1 + accesstoken=$2 + i=1 + p=1 + + _netlify_rest GET "dns_zones" "" "$accesstoken" + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug2 "Checking domain: $h" + if [ -z "$h" ]; then + #not valid + _err "Invalid domain" + return 1 + fi + + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + _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 + _sub_domain="@" + else + _sub_domain=$(echo "$domain" | cut -d . -f 1-$p) + fi + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_netlify_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$NETLIFY_ACCESS_TOKEN" | tr -d '"') + + export _H1="Content-Type: application/json" + export _H2="Authorization: Bearer $token_trimmed" + + :>"$HTTP_HEADER" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$NETLIFY_URL$ep" "" "$m")" + else + response="$(_get "$NETLIFY_URL$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} \ No newline at end of file From 70b49980cbed1f1c98d916dfe469512872aae171 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 9 Aug 2020 09:40:22 +0800 Subject: [PATCH 0831/2234] fix format --- dnsapi/dns_dynv6.sh | 2 +- dnsapi/dns_netlify.sh | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 50eda74b..3c222d3a 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -80,7 +80,7 @@ _generate_new_key() { _get_domain() { _full_domain="$1" _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks' ; then + if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks'; then _err "The hosts does not seem to be a dynv6 host" return 1 fi diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index 4da97f48..137ac1fb 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -57,6 +57,8 @@ dns_netlify_add() { #Remove the txt record after validation. dns_netlify_rm() { _info "Using Netlify" + txtdomain="$1" + txt="$2" _debug txtdomain "$txtdomain" _debug txt "$txt" @@ -70,12 +72,12 @@ dns_netlify_rm() { _debug _domain_id "$_domain_id" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - + dnsRecordURI="dns_zones/$_domain_id/dns_records" _netlify_rest GET "$dnsRecordURI" "" "$NETLIFY_ACCESS_TOKEN" - _record_id=$(echo "$response" | _egrep_o "\"type\":\"TXT\",[^\}]*\"value\":\"$txt\"" | head -n 1 | _egrep_o "\"id\":\"[^\"\}]*\"" | cut -d : -f 2 | tr -d \" ) + _record_id=$(echo "$response" | _egrep_o "\"type\":\"TXT\",[^\}]*\"value\":\"$txt\"" | head -n 1 | _egrep_o "\"id\":\"[^\"\}]*\"" | cut -d : -f 2 | tr -d \") _debug _record_id "$_record_id" if [ "$_record_id" ]; then _netlify_rest DELETE "$dnsRecordURI/$_record_id" "" "$NETLIFY_ACCESS_TOKEN" @@ -101,7 +103,7 @@ _get_root() { p=1 _netlify_rest GET "dns_zones" "" "$accesstoken" - + while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug2 "Checking domain: $h" @@ -112,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 @@ -157,4 +159,4 @@ _netlify_rest() { fi _debug2 response "$response" return 0 -} \ No newline at end of file +} From e932be0fb3b145a6c6cf161de74d29a96ea8a3d0 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 9 Aug 2020 09:34:43 +0800 Subject: [PATCH 0832/2234] eab --- acme.sh | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index 6a600087..1f6d2605 100755 --- a/acme.sh +++ b/acme.sh @@ -1507,6 +1507,19 @@ _url_replace() { tr '/+' '_-' | tr -d '= ' } +#base64 string +_durl_replace_base64() { + _l=$((${#1} % 4)) + if [ $_l -eq 2 ]; then + _s="$1"'==' + elif [ $_l -eq 3 ]; then + _s="$1"'=' + else + _s="$1" + fi + echo "$_s" | tr '_-' '/+' +} + _time2str() { #BSD if date -u -r "$1" 2>/dev/null; then @@ -3406,10 +3419,13 @@ _on_issue_success() { } +#account_key_length eab-kid eab-hmac-key registeraccount() { - _reg_length="$1" + _account_key_length="$1" + _eab_id="$2" + _eab_hmac_key="$3" _initpath - _regAccount "$_reg_length" + _regAccount "$_account_key_length" "$_eab_id" "$_eab_hmac_key" } __calcAccountKeyHash() { @@ -3424,6 +3440,8 @@ __calc_account_thumbprint() { _regAccount() { _initpath _reg_length="$1" + _eab_id="$2" + _eab_hmac_key="$3" _debug3 _regAccount "$_regAccount" _initAPI @@ -3448,12 +3466,41 @@ _regAccount() { if ! _calcjwk "$ACCOUNT_KEY_PATH"; then return 1 fi - + if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then + _savecaconf CA_EAB_KEY_ID "$_eab_id" + _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" + fi + _eab_id=$(_readcaconf "CA_EAB_KEY_ID") + _eab_hmac_key=$(_readcaconf "CA_EAB_HMAC_KEY") + _secure_debug3 _eab_id "$_eab_id" + _secure_debug3 _eab_hmac_key "$_eab_hmac_key" if [ "$ACME_VERSION" = "2" ]; then - regjson='{"termsOfServiceAgreed": true}' - if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"], "termsOfServiceAgreed": true}' + if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then + eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" + _debug3 eab_protected "$eab_protected" + + eab_protected64=$(printf "%s" "$eab_protected" | _base64 | _url_replace) + _debug3 eab_protected64 "$eab_protected64" + + eab_payload64=$(printf "%s" "$jwk" | _base64 | _url_replace) + _debug3 eab_payload64 "$eab_payload64" + + eab_sign_t="$eab_protected64.$eab_payload64" + _debug3 eab_sign_t "$eab_sign_t" + + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + _debug3 key_hex "$key_hex" + + eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) + _debug3 eab_signature "$eab_signature" + + externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" + _debug3 externalBinding "$externalBinding" fi + if [ "$ACCOUNT_EMAIL" ]; then + email_sg="\"contact\": [\"mailto:$ACCOUNT_EMAIL\"], " + fi + regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" else _reg_res="$ACME_NEW_ACCOUNT_RES" regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' @@ -6278,6 +6325,10 @@ Parameters: --log-level 1|2 Specifies the log level, default is 1. --syslog [0|3|6|7] Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. + --eab-kid EAB_KID Key Identifier for External Account Binding. + --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. + + These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6510,6 +6561,8 @@ _process() { _notify_level="" _notify_mode="" _revoke_reason="" + _eab_kid="" + _eab_hmac_key="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -6990,6 +7043,14 @@ _process() { fi shift ;; + --eab-kid) + _eab_kid="$2" + shift + ;; + --eab-hmac-key) + _eab_hmac_key="$2" + shift + ;; *) _err "Unknown parameter : $1" return 1 @@ -7086,7 +7147,7 @@ _process() { deactivate "$_domain,$_altdomains" ;; registeraccount) - registeraccount "$_accountkeylength" + registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key" ;; updateaccount) updateaccount From 7d20db93d3711b53dfc3bb435112f7ad1eaf1a9e Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Aug 2020 23:28:52 +0800 Subject: [PATCH 0833/2234] 1. Support short names for `--server` parameter, The valid values are: letsencrypt, letsencrypt_test, buypass, buypass_test and zerossl 2. Support Zerossl.com acme protocol. 3. Add "--set-default-ca --server xxxx" command to set the default CA to use. --- acme.sh | 93 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/acme.sh b/acme.sh index 1f6d2605..4bddab25 100755 --- a/acme.sh +++ b/acme.sh @@ -23,11 +23,27 @@ _SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY" LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory" -LETSENCRYPT_CA_V2="https://acme-v02.api.letsencrypt.org/directory" -LETSENCRYPT_STAGING_CA_V2="https://acme-staging-v02.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" -DEFAULT_CA=$LETSENCRYPT_CA_V2 -DEFAULT_STAGING_CA=$LETSENCRYPT_STAGING_CA_V2 +CA_BUYPASS="https://api.buypass.com/acme/directory" +CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" + +CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" + + +DEFAULT_CA=$CA_LETSENCRYPT_V2 +DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST + +CA_NAMES=" +letsencrypt +letsencrypt_test,letsencrypttest +buypass +buypass_test,buypasstest +zerossl +" + +CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" DEFAULT_ACCOUNT_EMAIL="" @@ -140,6 +156,8 @@ _SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo" _REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert" +_ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -2577,16 +2595,22 @@ _initpath() { fi if [ "$ACME_VERSION" = "2" ]; then - DEFAULT_CA="$LETSENCRYPT_CA_V2" - DEFAULT_STAGING_CA="$LETSENCRYPT_STAGING_CA_V2" + DEFAULT_CA="$CA_LETSENCRYPT_V2" + DEFAULT_STAGING_CA="$CA_LETSENCRYPT_V2_TEST" fi if [ -z "$ACME_DIRECTORY" ]; then - if [ -z "$STAGE" ]; then - ACME_DIRECTORY="$DEFAULT_CA" + default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") + _debug default_acme_server "$default_acme_server" + if [ "$default_acme_server" ]; then + ACME_DIRECTORY="$default_acme_server" else - ACME_DIRECTORY="$DEFAULT_STAGING_CA" - _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + if [ -z "$STAGE" ]; then + ACME_DIRECTORY="$DEFAULT_CA" + else + ACME_DIRECTORY="$DEFAULT_STAGING_CA" + _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + fi fi fi @@ -6301,6 +6325,7 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. + --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6344,7 +6369,7 @@ Parameters: --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. --config-home Specifies the home dir to save all the configurations. --useragent Specifies the user agent string. it will be saved for future use too. - --accountemail Specifies the account email, only valid for the '--install' and '--update-account' command. + --accountemail, -m Specifies the account email, only valid for the '--install' and '--update-account' command. --accountkey Specifies the account key path, only valid for the '--install' command. --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. @@ -6510,6 +6535,39 @@ _checkSudo() { return 0 } +#server +_selectServer() { + _server="$1" + _server_lower="$(echo "$_server" | _lower_case)" + _sindex=0 + for snames in $CA_NAMES; do + snames="$(echo "$snames" | _lower_case)" + _sindex="$(_math $_sindex + 1)" + _debug2 "_selectServer try snames" "$snames" + for sname in $(echo "$snames" | tr ',' ' '); do + if [ "$_server_lower" = "$sname" ]; then + _debug2 "_selectServer match $sname" + _serverdir="$(_getfield "$CA_SERVERS" $_sindex)" + _debug "Selected server: $_serverdir" + ACME_DIRECTORY="$_serverdir" + export ACME_DIRECTORY + return + fi + done + done + ACME_DIRECTORY="$_server" + export ACME_DIRECTORY +} + +#set default ca to $ACME_DIRECTORY +setdefaultca() { + if [ -z "$ACME_DIRECTORY" ]; then + _err "Please give a --server parameter." + return 1 + fi + _saveaccountconf "DEFAULT_ACME_SERVER" "$ACME_DIRECTORY" +} + _process() { _CMD="" _domain="" @@ -6652,6 +6710,9 @@ _process() { --set-notify) _CMD="setnotify" ;; + --set-default-ca) + _CMD="setdefaultca" + ;; --domain | -d) _dvalue="$2" @@ -6690,9 +6751,8 @@ _process() { STAGE="1" ;; --server) - ACME_DIRECTORY="$2" - _server="$ACME_DIRECTORY" - export ACME_DIRECTORY + _server="$2" + _selectServer "$_server" shift ;; --debug) @@ -6849,7 +6909,7 @@ _process() { USER_AGENT="$_useragent" shift ;; - --accountemail) + --accountemail | -m) _accountemail="$2" ACCOUNT_EMAIL="$_accountemail" shift @@ -7179,6 +7239,9 @@ _process() { setnotify) setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" ;; + setdefaultca) + setdefaultca + ;; *) if [ "$_CMD" ]; then _err "Invalid command: $_CMD" From 1e967eceef105f55e3e68c649ff6e77cf1c6e896 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Aug 2020 23:45:12 +0800 Subject: [PATCH 0834/2234] fix format --- acme.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 4bddab25..70795ff3 100755 --- a/acme.sh +++ b/acme.sh @@ -31,7 +31,6 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" - DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST @@ -3512,10 +3511,10 @@ _regAccount() { eab_sign_t="$eab_protected64.$eab_payload64" _debug3 eab_sign_t "$eab_sign_t" - key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" _debug3 key_hex "$key_hex" - eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) + eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) _debug3 eab_signature "$eab_signature" externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" @@ -7110,7 +7109,7 @@ _process() { --eab-hmac-key) _eab_hmac_key="$2" shift - ;; + ;; *) _err "Unknown parameter : $1" return 1 From edbe026b490d7da30a37a21d86142fc0bc31dcde Mon Sep 17 00:00:00 2001 From: Andy Botting Date: Wed, 12 Aug 2020 11:24:45 +1000 Subject: [PATCH 0835/2234] Rename openstack to dns_openstack Although the DNS API dev guide at https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide says `The script file name must be myapi.sh`, it should really be names dns_myapi.sh for consistency. --- dnsapi/{openstack.sh => dns_openstack.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dnsapi/{openstack.sh => dns_openstack.sh} (100%) diff --git a/dnsapi/openstack.sh b/dnsapi/dns_openstack.sh similarity index 100% rename from dnsapi/openstack.sh rename to dnsapi/dns_openstack.sh From 4e0de2237522c2c3814aefdd39751144c079fbcc Mon Sep 17 00:00:00 2001 From: Alexilmarranen Date: Wed, 12 Aug 2020 15:17:54 +0300 Subject: [PATCH 0836/2234] Issue2547 wrong url construction for multiple dns services Fix for problem in https://github.com/acmesh-official/acme.sh/issues/2547#issuecomment-672830796 --- dnsapi/dns_nic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 5052ee10..56170f87 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -166,7 +166,7 @@ _get_root() { if _contains "$_all_domains" "^$h$"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h - _service=$(printf "%s" "$response" | grep "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/") + _service=$(printf "%s" "$response" | grep -m 1 "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/") return 0 fi p="$i" From 8d811760a91be47927ed842b8d7f056704c13574 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:43:44 +0800 Subject: [PATCH 0837/2234] 1. move email to ca conf 2. get EAB credentials from Zerossl by email automatically --- README.md | 1 + acme.sh | 94 ++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 2da103b2..f5631475 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ https://github.com/acmesh-official/acmetest # Supported CA - Letsencrypt.org CA(default) +- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA) - [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) diff --git a/acme.sh b/acme.sh index 70795ff3..d359a4bb 100755 --- a/acme.sh +++ b/acme.sh @@ -30,6 +30,8 @@ CA_BUYPASS="https://api.buypass.com/acme/directory" CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" +_ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email" + DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST @@ -45,7 +47,6 @@ zerossl CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" -DEFAULT_ACCOUNT_EMAIL="" DEFAULT_ACCOUNT_KEY_LENGTH=2048 DEFAULT_DOMAIN_KEY_LENGTH=2048 @@ -3459,6 +3460,21 @@ __calc_account_thumbprint() { printf "%s" "$jwk" | tr -d ' ' | _digest "sha256" | _url_replace } +_getAccountEmail() { + if [ "$ACCOUNT_EMAIL" ]; then + echo "$ACCOUNT_EMAIL" + return 0 + fi + if [ -z "$CA_EMAIL" ]; then + CA_EMAIL="$(_readcaconf CA_EMAIL)" + fi + if [ "$CA_EMAIL" ]; then + echo "$CA_EMAIL" + return 0 + fi + _readaccountconf "ACCOUNT_EMAIL" +} + #keylength _regAccount() { _initpath @@ -3497,7 +3513,38 @@ _regAccount() { _eab_hmac_key=$(_readcaconf "CA_EAB_HMAC_KEY") _secure_debug3 _eab_id "$_eab_id" _secure_debug3 _eab_hmac_key "$_eab_hmac_key" + _email="$(_getAccountEmail)" + if [ "$_email" ]; then + _savecaconf "CA_EMAIL" "$_email" + fi if [ "$ACME_VERSION" = "2" ]; then + if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then + if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then + _info "No EAB credentials found for ZeroSSL, let's get one" + if [ -z "$_email" ]; then + _err "Please provide a email address for zerossl account." + return 1 + fi + _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) + if [ "$?" != "0" ]; then + _debug2 "$_eabresp" + _err "Can not get EAB credentials from zerossl." + return 1 + fi + _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_id" ]; then + _err "Can not resolve _eab_id"; + return 1 + fi + _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_hmac_key" ]; then + _err "Can not resolve _eab_hmac_key"; + return 1 + fi + _savecaconf CA_EAB_KEY_ID "$_eab_id" + _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" + fi + fi if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" _debug3 eab_protected "$eab_protected" @@ -3520,44 +3567,52 @@ _regAccount() { externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" _debug3 externalBinding "$externalBinding" fi - if [ "$ACCOUNT_EMAIL" ]; then - email_sg="\"contact\": [\"mailto:$ACCOUNT_EMAIL\"], " + if [ "$_email" ]; then + email_sg="\"contact\": [\"mailto:$_email\"], " fi regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" else _reg_res="$ACME_NEW_ACCOUNT_RES" regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' - if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$ACCOUNT_EMAIL'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' + if [ "$_email" ]; then + regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$_email'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' fi fi - _info "Registering account" + _info "Registering account: $ACME_DIRECTORY" if ! _send_signed_request "${ACME_NEW_ACCOUNT}" "$regjson"; then _err "Register account Error: $response" return 1 fi + _eabAlreadyBound="" if [ "$code" = "" ] || [ "$code" = '201' ]; then echo "$response" >"$ACCOUNT_JSON_PATH" _info "Registered" elif [ "$code" = '409' ] || [ "$code" = '200' ]; then _info "Already registered" + elif [ "$code" = '400' ] && _contains "$response" 'The account is not awaiting external account binding'; then + _info "Already register EAB." + _eabAlreadyBound=1 else _err "Register account Error: $response" return 1 fi - _debug2 responseHeaders "$responseHeaders" - _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" - _debug "_accUri" "$_accUri" - if [ -z "$_accUri" ]; then - _err "Can not find account id url." - _err "$responseHeaders" - return 1 + if [ -z "$_eabAlreadyBound" ]; then + _debug2 responseHeaders "$responseHeaders" + _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" + _debug "_accUri" "$_accUri" + if [ -z "$_accUri" ]; then + _err "Can not find account id url." + _err "$responseHeaders" + return 1 + fi + _savecaconf "ACCOUNT_URL" "$_accUri" + else + ACCOUNT_URL="$(_readcaconf ACCOUNT_URL)" fi - _savecaconf "ACCOUNT_URL" "$_accUri" export ACCOUNT_URL="$_accUri" CA_KEY_HASH="$(__calcAccountKeyHash)" @@ -3606,9 +3661,10 @@ updateaccount() { fi _initAPI + _email="$(_getAccountEmail)" if [ "$ACME_VERSION" = "2" ]; then if [ "$ACCOUNT_EMAIL" ]; then - updjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"]}' + updjson='{"contact": ["mailto:'$_email'"]}' else updjson='{"contact": []}' fi @@ -4036,7 +4092,7 @@ issue() { else _cleardomainconf Le_API fi - + _info "Using CA: $ACME_DIRECTORY" if [ "$_alt_domains" = "$NO_VALUE" ]; then _alt_domains="" fi @@ -6491,12 +6547,6 @@ _processAccountConf() { _saveaccountconf "USER_AGENT" "$USER_AGENT" fi - if [ "$_accountemail" ]; then - _saveaccountconf "ACCOUNT_EMAIL" "$_accountemail" - elif [ "$ACCOUNT_EMAIL" ] && [ "$ACCOUNT_EMAIL" != "$DEFAULT_ACCOUNT_EMAIL" ]; then - _saveaccountconf "ACCOUNT_EMAIL" "$ACCOUNT_EMAIL" - fi - if [ "$_openssl_bin" ]; then _saveaccountconf "ACME_OPENSSL_BIN" "$_openssl_bin" elif [ "$ACME_OPENSSL_BIN" ] && [ "$ACME_OPENSSL_BIN" != "$DEFAULT_OPENSSL_BIN" ]; then From 85503655ab3a98854e69a302c1eaad370711c1e3 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:47:17 +0800 Subject: [PATCH 0838/2234] Display ZeroSSL usage --- acme.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index d359a4bb..544555b9 100755 --- a/acme.sh +++ b/acme.sh @@ -3522,13 +3522,14 @@ _regAccount() { if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then _info "No EAB credentials found for ZeroSSL, let's get one" if [ -z "$_email" ]; then - _err "Please provide a email address for zerossl account." + _err "Please provide a email address for ZeroSSL account." + _err "See ZeroSSL usage: $_ZEROSSL_WIKI" return 1 fi _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) if [ "$?" != "0" ]; then _debug2 "$_eabresp" - _err "Can not get EAB credentials from zerossl." + _err "Can not get EAB credentials from ZeroSSL." return 1 fi _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" From f96d91cb6c518c93ba93c827228892b9ed36bc82 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 9 Aug 2020 09:34:43 +0800 Subject: [PATCH 0839/2234] eab --- acme.sh | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index 6a600087..1f6d2605 100755 --- a/acme.sh +++ b/acme.sh @@ -1507,6 +1507,19 @@ _url_replace() { tr '/+' '_-' | tr -d '= ' } +#base64 string +_durl_replace_base64() { + _l=$((${#1} % 4)) + if [ $_l -eq 2 ]; then + _s="$1"'==' + elif [ $_l -eq 3 ]; then + _s="$1"'=' + else + _s="$1" + fi + echo "$_s" | tr '_-' '/+' +} + _time2str() { #BSD if date -u -r "$1" 2>/dev/null; then @@ -3406,10 +3419,13 @@ _on_issue_success() { } +#account_key_length eab-kid eab-hmac-key registeraccount() { - _reg_length="$1" + _account_key_length="$1" + _eab_id="$2" + _eab_hmac_key="$3" _initpath - _regAccount "$_reg_length" + _regAccount "$_account_key_length" "$_eab_id" "$_eab_hmac_key" } __calcAccountKeyHash() { @@ -3424,6 +3440,8 @@ __calc_account_thumbprint() { _regAccount() { _initpath _reg_length="$1" + _eab_id="$2" + _eab_hmac_key="$3" _debug3 _regAccount "$_regAccount" _initAPI @@ -3448,12 +3466,41 @@ _regAccount() { if ! _calcjwk "$ACCOUNT_KEY_PATH"; then return 1 fi - + if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then + _savecaconf CA_EAB_KEY_ID "$_eab_id" + _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" + fi + _eab_id=$(_readcaconf "CA_EAB_KEY_ID") + _eab_hmac_key=$(_readcaconf "CA_EAB_HMAC_KEY") + _secure_debug3 _eab_id "$_eab_id" + _secure_debug3 _eab_hmac_key "$_eab_hmac_key" if [ "$ACME_VERSION" = "2" ]; then - regjson='{"termsOfServiceAgreed": true}' - if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"], "termsOfServiceAgreed": true}' + if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then + eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" + _debug3 eab_protected "$eab_protected" + + eab_protected64=$(printf "%s" "$eab_protected" | _base64 | _url_replace) + _debug3 eab_protected64 "$eab_protected64" + + eab_payload64=$(printf "%s" "$jwk" | _base64 | _url_replace) + _debug3 eab_payload64 "$eab_payload64" + + eab_sign_t="$eab_protected64.$eab_payload64" + _debug3 eab_sign_t "$eab_sign_t" + + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + _debug3 key_hex "$key_hex" + + eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) + _debug3 eab_signature "$eab_signature" + + externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" + _debug3 externalBinding "$externalBinding" fi + if [ "$ACCOUNT_EMAIL" ]; then + email_sg="\"contact\": [\"mailto:$ACCOUNT_EMAIL\"], " + fi + regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" else _reg_res="$ACME_NEW_ACCOUNT_RES" regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' @@ -6278,6 +6325,10 @@ Parameters: --log-level 1|2 Specifies the log level, default is 1. --syslog [0|3|6|7] Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. + --eab-kid EAB_KID Key Identifier for External Account Binding. + --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. + + These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6510,6 +6561,8 @@ _process() { _notify_level="" _notify_mode="" _revoke_reason="" + _eab_kid="" + _eab_hmac_key="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -6990,6 +7043,14 @@ _process() { fi shift ;; + --eab-kid) + _eab_kid="$2" + shift + ;; + --eab-hmac-key) + _eab_hmac_key="$2" + shift + ;; *) _err "Unknown parameter : $1" return 1 @@ -7086,7 +7147,7 @@ _process() { deactivate "$_domain,$_altdomains" ;; registeraccount) - registeraccount "$_accountkeylength" + registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key" ;; updateaccount) updateaccount From 737e9e48cac1e415d8405f9e7e9cabf131da52df Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Aug 2020 23:28:52 +0800 Subject: [PATCH 0840/2234] 1. Support short names for `--server` parameter, The valid values are: letsencrypt, letsencrypt_test, buypass, buypass_test and zerossl 2. Support Zerossl.com acme protocol. 3. Add "--set-default-ca --server xxxx" command to set the default CA to use. --- acme.sh | 93 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/acme.sh b/acme.sh index 1f6d2605..4bddab25 100755 --- a/acme.sh +++ b/acme.sh @@ -23,11 +23,27 @@ _SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY" LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory" -LETSENCRYPT_CA_V2="https://acme-v02.api.letsencrypt.org/directory" -LETSENCRYPT_STAGING_CA_V2="https://acme-staging-v02.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" -DEFAULT_CA=$LETSENCRYPT_CA_V2 -DEFAULT_STAGING_CA=$LETSENCRYPT_STAGING_CA_V2 +CA_BUYPASS="https://api.buypass.com/acme/directory" +CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" + +CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" + + +DEFAULT_CA=$CA_LETSENCRYPT_V2 +DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST + +CA_NAMES=" +letsencrypt +letsencrypt_test,letsencrypttest +buypass +buypass_test,buypasstest +zerossl +" + +CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" DEFAULT_ACCOUNT_EMAIL="" @@ -140,6 +156,8 @@ _SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo" _REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert" +_ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -2577,16 +2595,22 @@ _initpath() { fi if [ "$ACME_VERSION" = "2" ]; then - DEFAULT_CA="$LETSENCRYPT_CA_V2" - DEFAULT_STAGING_CA="$LETSENCRYPT_STAGING_CA_V2" + DEFAULT_CA="$CA_LETSENCRYPT_V2" + DEFAULT_STAGING_CA="$CA_LETSENCRYPT_V2_TEST" fi if [ -z "$ACME_DIRECTORY" ]; then - if [ -z "$STAGE" ]; then - ACME_DIRECTORY="$DEFAULT_CA" + default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") + _debug default_acme_server "$default_acme_server" + if [ "$default_acme_server" ]; then + ACME_DIRECTORY="$default_acme_server" else - ACME_DIRECTORY="$DEFAULT_STAGING_CA" - _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + if [ -z "$STAGE" ]; then + ACME_DIRECTORY="$DEFAULT_CA" + else + ACME_DIRECTORY="$DEFAULT_STAGING_CA" + _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + fi fi fi @@ -6301,6 +6325,7 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. + --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6344,7 +6369,7 @@ Parameters: --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. --config-home Specifies the home dir to save all the configurations. --useragent Specifies the user agent string. it will be saved for future use too. - --accountemail Specifies the account email, only valid for the '--install' and '--update-account' command. + --accountemail, -m Specifies the account email, only valid for the '--install' and '--update-account' command. --accountkey Specifies the account key path, only valid for the '--install' command. --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. @@ -6510,6 +6535,39 @@ _checkSudo() { return 0 } +#server +_selectServer() { + _server="$1" + _server_lower="$(echo "$_server" | _lower_case)" + _sindex=0 + for snames in $CA_NAMES; do + snames="$(echo "$snames" | _lower_case)" + _sindex="$(_math $_sindex + 1)" + _debug2 "_selectServer try snames" "$snames" + for sname in $(echo "$snames" | tr ',' ' '); do + if [ "$_server_lower" = "$sname" ]; then + _debug2 "_selectServer match $sname" + _serverdir="$(_getfield "$CA_SERVERS" $_sindex)" + _debug "Selected server: $_serverdir" + ACME_DIRECTORY="$_serverdir" + export ACME_DIRECTORY + return + fi + done + done + ACME_DIRECTORY="$_server" + export ACME_DIRECTORY +} + +#set default ca to $ACME_DIRECTORY +setdefaultca() { + if [ -z "$ACME_DIRECTORY" ]; then + _err "Please give a --server parameter." + return 1 + fi + _saveaccountconf "DEFAULT_ACME_SERVER" "$ACME_DIRECTORY" +} + _process() { _CMD="" _domain="" @@ -6652,6 +6710,9 @@ _process() { --set-notify) _CMD="setnotify" ;; + --set-default-ca) + _CMD="setdefaultca" + ;; --domain | -d) _dvalue="$2" @@ -6690,9 +6751,8 @@ _process() { STAGE="1" ;; --server) - ACME_DIRECTORY="$2" - _server="$ACME_DIRECTORY" - export ACME_DIRECTORY + _server="$2" + _selectServer "$_server" shift ;; --debug) @@ -6849,7 +6909,7 @@ _process() { USER_AGENT="$_useragent" shift ;; - --accountemail) + --accountemail | -m) _accountemail="$2" ACCOUNT_EMAIL="$_accountemail" shift @@ -7179,6 +7239,9 @@ _process() { setnotify) setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" ;; + setdefaultca) + setdefaultca + ;; *) if [ "$_CMD" ]; then _err "Invalid command: $_CMD" From d42ff227f1ce31f881d6f783874bc89733d0f007 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Aug 2020 23:45:12 +0800 Subject: [PATCH 0841/2234] fix format --- acme.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 4bddab25..70795ff3 100755 --- a/acme.sh +++ b/acme.sh @@ -31,7 +31,6 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" - DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST @@ -3512,10 +3511,10 @@ _regAccount() { eab_sign_t="$eab_protected64.$eab_payload64" _debug3 eab_sign_t "$eab_sign_t" - key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" _debug3 key_hex "$key_hex" - eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) + eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) _debug3 eab_signature "$eab_signature" externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" @@ -7110,7 +7109,7 @@ _process() { --eab-hmac-key) _eab_hmac_key="$2" shift - ;; + ;; *) _err "Unknown parameter : $1" return 1 From 389518e1b89e5bf9b353b10026d3f4b203410ff9 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:43:44 +0800 Subject: [PATCH 0842/2234] 1. move email to ca conf 2. get EAB credentials from Zerossl by email automatically --- README.md | 1 + acme.sh | 94 ++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 2da103b2..f5631475 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ https://github.com/acmesh-official/acmetest # Supported CA - Letsencrypt.org CA(default) +- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA) - [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) diff --git a/acme.sh b/acme.sh index 70795ff3..d359a4bb 100755 --- a/acme.sh +++ b/acme.sh @@ -30,6 +30,8 @@ CA_BUYPASS="https://api.buypass.com/acme/directory" CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" +_ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email" + DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST @@ -45,7 +47,6 @@ zerossl CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" -DEFAULT_ACCOUNT_EMAIL="" DEFAULT_ACCOUNT_KEY_LENGTH=2048 DEFAULT_DOMAIN_KEY_LENGTH=2048 @@ -3459,6 +3460,21 @@ __calc_account_thumbprint() { printf "%s" "$jwk" | tr -d ' ' | _digest "sha256" | _url_replace } +_getAccountEmail() { + if [ "$ACCOUNT_EMAIL" ]; then + echo "$ACCOUNT_EMAIL" + return 0 + fi + if [ -z "$CA_EMAIL" ]; then + CA_EMAIL="$(_readcaconf CA_EMAIL)" + fi + if [ "$CA_EMAIL" ]; then + echo "$CA_EMAIL" + return 0 + fi + _readaccountconf "ACCOUNT_EMAIL" +} + #keylength _regAccount() { _initpath @@ -3497,7 +3513,38 @@ _regAccount() { _eab_hmac_key=$(_readcaconf "CA_EAB_HMAC_KEY") _secure_debug3 _eab_id "$_eab_id" _secure_debug3 _eab_hmac_key "$_eab_hmac_key" + _email="$(_getAccountEmail)" + if [ "$_email" ]; then + _savecaconf "CA_EMAIL" "$_email" + fi if [ "$ACME_VERSION" = "2" ]; then + if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then + if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then + _info "No EAB credentials found for ZeroSSL, let's get one" + if [ -z "$_email" ]; then + _err "Please provide a email address for zerossl account." + return 1 + fi + _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) + if [ "$?" != "0" ]; then + _debug2 "$_eabresp" + _err "Can not get EAB credentials from zerossl." + return 1 + fi + _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_id" ]; then + _err "Can not resolve _eab_id"; + return 1 + fi + _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_hmac_key" ]; then + _err "Can not resolve _eab_hmac_key"; + return 1 + fi + _savecaconf CA_EAB_KEY_ID "$_eab_id" + _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" + fi + fi if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" _debug3 eab_protected "$eab_protected" @@ -3520,44 +3567,52 @@ _regAccount() { externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" _debug3 externalBinding "$externalBinding" fi - if [ "$ACCOUNT_EMAIL" ]; then - email_sg="\"contact\": [\"mailto:$ACCOUNT_EMAIL\"], " + if [ "$_email" ]; then + email_sg="\"contact\": [\"mailto:$_email\"], " fi regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" else _reg_res="$ACME_NEW_ACCOUNT_RES" regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' - if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$ACCOUNT_EMAIL'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' + if [ "$_email" ]; then + regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$_email'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' fi fi - _info "Registering account" + _info "Registering account: $ACME_DIRECTORY" if ! _send_signed_request "${ACME_NEW_ACCOUNT}" "$regjson"; then _err "Register account Error: $response" return 1 fi + _eabAlreadyBound="" if [ "$code" = "" ] || [ "$code" = '201' ]; then echo "$response" >"$ACCOUNT_JSON_PATH" _info "Registered" elif [ "$code" = '409' ] || [ "$code" = '200' ]; then _info "Already registered" + elif [ "$code" = '400' ] && _contains "$response" 'The account is not awaiting external account binding'; then + _info "Already register EAB." + _eabAlreadyBound=1 else _err "Register account Error: $response" return 1 fi - _debug2 responseHeaders "$responseHeaders" - _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" - _debug "_accUri" "$_accUri" - if [ -z "$_accUri" ]; then - _err "Can not find account id url." - _err "$responseHeaders" - return 1 + if [ -z "$_eabAlreadyBound" ]; then + _debug2 responseHeaders "$responseHeaders" + _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" + _debug "_accUri" "$_accUri" + if [ -z "$_accUri" ]; then + _err "Can not find account id url." + _err "$responseHeaders" + return 1 + fi + _savecaconf "ACCOUNT_URL" "$_accUri" + else + ACCOUNT_URL="$(_readcaconf ACCOUNT_URL)" fi - _savecaconf "ACCOUNT_URL" "$_accUri" export ACCOUNT_URL="$_accUri" CA_KEY_HASH="$(__calcAccountKeyHash)" @@ -3606,9 +3661,10 @@ updateaccount() { fi _initAPI + _email="$(_getAccountEmail)" if [ "$ACME_VERSION" = "2" ]; then if [ "$ACCOUNT_EMAIL" ]; then - updjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"]}' + updjson='{"contact": ["mailto:'$_email'"]}' else updjson='{"contact": []}' fi @@ -4036,7 +4092,7 @@ issue() { else _cleardomainconf Le_API fi - + _info "Using CA: $ACME_DIRECTORY" if [ "$_alt_domains" = "$NO_VALUE" ]; then _alt_domains="" fi @@ -6491,12 +6547,6 @@ _processAccountConf() { _saveaccountconf "USER_AGENT" "$USER_AGENT" fi - if [ "$_accountemail" ]; then - _saveaccountconf "ACCOUNT_EMAIL" "$_accountemail" - elif [ "$ACCOUNT_EMAIL" ] && [ "$ACCOUNT_EMAIL" != "$DEFAULT_ACCOUNT_EMAIL" ]; then - _saveaccountconf "ACCOUNT_EMAIL" "$ACCOUNT_EMAIL" - fi - if [ "$_openssl_bin" ]; then _saveaccountconf "ACME_OPENSSL_BIN" "$_openssl_bin" elif [ "$ACME_OPENSSL_BIN" ] && [ "$ACME_OPENSSL_BIN" != "$DEFAULT_OPENSSL_BIN" ]; then From 578c338d40781689dc6e1ce9ae6d12da92f03893 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:47:17 +0800 Subject: [PATCH 0843/2234] Display ZeroSSL usage --- acme.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index d359a4bb..544555b9 100755 --- a/acme.sh +++ b/acme.sh @@ -3522,13 +3522,14 @@ _regAccount() { if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then _info "No EAB credentials found for ZeroSSL, let's get one" if [ -z "$_email" ]; then - _err "Please provide a email address for zerossl account." + _err "Please provide a email address for ZeroSSL account." + _err "See ZeroSSL usage: $_ZEROSSL_WIKI" return 1 fi _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) if [ "$?" != "0" ]; then _debug2 "$_eabresp" - _err "Can not get EAB credentials from zerossl." + _err "Can not get EAB credentials from ZeroSSL." return 1 fi _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" From 365aa69afd04d732c14c6e0b8bf7509fcd0ffafb Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:48:21 +0800 Subject: [PATCH 0844/2234] fix format --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 544555b9..d57ff9a8 100755 --- a/acme.sh +++ b/acme.sh @@ -3534,12 +3534,12 @@ _regAccount() { fi _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" if [ -z "$_eab_id" ]; then - _err "Can not resolve _eab_id"; + _err "Can not resolve _eab_id" return 1 fi _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" if [ -z "$_eab_hmac_key" ]; then - _err "Can not resolve _eab_hmac_key"; + _err "Can not resolve _eab_hmac_key" return 1 fi _savecaconf CA_EAB_KEY_ID "$_eab_id" From df22f68088d28a6f7f020259afc222c989f6f9cd Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 21:25:35 +0800 Subject: [PATCH 0845/2234] Add info for set-default-ca --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index ea5676f9..bcfaa8b1 100755 --- a/acme.sh +++ b/acme.sh @@ -6618,6 +6618,7 @@ setdefaultca() { return 1 fi _saveaccountconf "DEFAULT_ACME_SERVER" "$ACME_DIRECTORY" + _info "Changed default CA to: $(__green "$ACME_DIRECTORY")" } _process() { From 269847d19dd396ca0c4885ff57e737839fa98296 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 21:45:20 +0800 Subject: [PATCH 0846/2234] Add CA name to the `--list` command output. --- acme.sh | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index bcfaa8b1..b7d45f5d 100755 --- a/acme.sh +++ b/acme.sh @@ -37,11 +37,11 @@ DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST CA_NAMES=" -letsencrypt -letsencrypt_test,letsencrypttest -buypass -buypass_test,buypasstest -zerossl +Letsencrypt.org,letsencrypt +Letsencrypt.org_test,letsencrypt_test,letsencrypttest +BuyPass.com,buypass +BuyPass.com_test,buypass_test,buypasstest +ZeroSSL.com,zerossl " CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" @@ -5254,7 +5254,7 @@ list() { _sep="|" if [ "$_raw" ]; then - printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}Created${_sep}Renew" + printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}CA${_sep}Created${_sep}Renew" for di in "${CERT_HOME}"/*.*/; do d=$(basename "$di") _debug d "$d" @@ -5266,7 +5266,8 @@ list() { DOMAIN_CONF="$di/$d.conf" if [ -f "$DOMAIN_CONF" ]; then . "$DOMAIN_CONF" - printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr" + _ca="$(_getCAShortName "$Le_API")" + printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr" fi ) done @@ -6611,6 +6612,27 @@ _selectServer() { export ACME_DIRECTORY } +#url +_getCAShortName() { + caurl="$1" + caurl_lower="$(echo $caurl | _lower_case)" + _sindex=0 + for surl in $(echo "$CA_SERVERS" | _lower_case | tr , ' '); do + _sindex="$(_math $_sindex + 1)" + if [ "$caurl_lower" = "$surl" ]; then + _nindex=0 + for snames in $CA_NAMES; do + _nindex="$(_math $_nindex + 1)" + if [ $_nindex -ge $_sindex ]; then + _getfield "$snames" 1 + return + fi + done + fi + done + echo "$caurl" +} + #set default ca to $ACME_DIRECTORY setdefaultca() { if [ -z "$ACME_DIRECTORY" ]; then From 1177cc3f29964db6983143a1d25d6758e7798e6d Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 22:09:37 +0800 Subject: [PATCH 0847/2234] fix format --- acme.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/acme.sh b/acme.sh index b7d45f5d..9505ae2c 100755 --- a/acme.sh +++ b/acme.sh @@ -32,7 +32,6 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" _ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email" - DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST From f1318636428eefaa0472f28902d2fd19a832a0c4 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Wed, 12 Aug 2020 23:48:11 +0200 Subject: [PATCH 0848/2234] now with "_saveaccountconf_mutable" _saveaccountconf_mutable instead of _saveaccountconf now used. Co-Authored-By: kapper.net support account <33451837+kappernet@users.noreply.github.com> --- dnsapi/dns_kappernet.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index a059447a..70a3ea23 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -26,8 +26,8 @@ dns_kappernet_add() { fi #store the api key and email to the account conf file. - _saveaccountconf KAPPERNETDNS_Key "$KAPPERNETDNS_Key" - _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" + _saveaccountconf_mutable KAPPERNETDNS_Key "$KAPPERNETDNS_Key" + _saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" _debug "Checking Domain ..." if ! _get_root "$fullhostname"; then _err "invalid domain" @@ -69,8 +69,8 @@ dns_kappernet_rm() { fi #store the api key and email to the account conf file. - _saveaccountconf KAPPERNETDNS_Key "$KAPPERNETDNS_Key" - _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" + _saveaccountconf_mutable KAPPERNETDNS_Key "$KAPPERNETDNS_Key" + _saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" _info "Trying to remove the TXT Record: $fullhostname" data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" From 0052ab7148a930183e39db4192ec250a3b84bfc0 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Thu, 13 Aug 2020 00:23:57 +0200 Subject: [PATCH 0849/2234] more mutable + style-update more mutable config-read-calls more details for TXT records info + errors; typo fixed (create instead of delete) --- dnsapi/dns_kappernet.sh | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 70a3ea23..47a871c1 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -17,11 +17,15 @@ dns_kappernet_add() { fullhostname=$1 txtvalue=$2 + KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}" + KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}" + if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then KAPPERNETDNS_Key="" KAPPERNETDNS_Secret="" - _err "You haven't defined kapper.net api key and secret yet." - _err "Please send us mail to support@kapper.net get your key and secret." + _err "Please specify your kapper.net api key and secret." + _err "If you have not received yours - send your mail to" + _err "support@kapper.net to get your key and secret." return 1 fi @@ -60,11 +64,15 @@ dns_kappernet_rm() { fullhostname=$1 txtvalue=$2 + KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}" + KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}" + if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then KAPPERNETDNS_Key="" KAPPERNETDNS_Secret="" - _err "You haven't defined kapper.net api key and secret yet." - _err "Please send us mail to get your key and secret." + _err "Please specify your kapper.net api key and secret." + _err "If you have not received yours - send your mail to" + _err "support@kapper.net to get your key and secret." return 1 fi @@ -72,18 +80,18 @@ dns_kappernet_rm() { _saveaccountconf_mutable KAPPERNETDNS_Key "$KAPPERNETDNS_Key" _saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" - _info "Trying to remove the TXT Record: $fullhostname" + _info "Trying to remove the TXT Record: $fullhostname containing $txtvalue" data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" if _kappernet_api GET "action=del&subject=$fullhostname&data=$data"; then if _contains "$response" "{\"OK\":true"; then return 0 else - _err "Error deleting DNS Record: $fullhostname" + _err "Error deleting DNS Record: $fullhostname containing $txtvalue" _err "Problem: $response" return 1 fi fi - _err "Problem creating TXT DNS record" + _err "Problem deleting TXT DNS record" } #################### Private functions below ################################## From 0415c050a5dbce75ed8bf89abb9ef2d361a1e589 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 13 Aug 2020 23:04:19 +0800 Subject: [PATCH 0850/2234] remove gitads --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index f5631475..e50489dc 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,6 @@ acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial - GitAds - - - - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. - Support ACME v1 and ACME v2 From a6d22e3b2215f85ca1f5cae7fa73adbc34697125 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 13 Aug 2020 23:12:30 +0800 Subject: [PATCH 0851/2234] 1. save the CA url anyway. 2. clear some code. --- acme.sh | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/acme.sh b/acme.sh index 9505ae2c..406a158d 100755 --- a/acme.sh +++ b/acme.sh @@ -52,9 +52,6 @@ DEFAULT_DOMAIN_KEY_LENGTH=2048 DEFAULT_OPENSSL_BIN="openssl" -_OLD_CA_HOST="https://acme-v01.api.letsencrypt.org" -_OLD_STAGE_CA_HOST="https://acme-staging.api.letsencrypt.org" - VTYPE_HTTP="http-01" VTYPE_DNS="dns-01" VTYPE_ALPN="tls-alpn-01" @@ -2595,11 +2592,6 @@ _initpath() { CA_HOME="$DEFAULT_CA_HOME" fi - if [ "$ACME_VERSION" = "2" ]; then - DEFAULT_CA="$CA_LETSENCRYPT_V2" - DEFAULT_STAGING_CA="$CA_LETSENCRYPT_V2_TEST" - fi - if [ -z "$ACME_DIRECTORY" ]; then default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") _debug default_acme_server "$default_acme_server" @@ -4088,12 +4080,9 @@ issue() { _cleardomainconf "Le_ChallengeAlias" fi - if [ "$ACME_DIRECTORY" != "$DEFAULT_CA" ]; then - Le_API="$ACME_DIRECTORY" - _savedomainconf "Le_API" "$Le_API" - else - _cleardomainconf Le_API - fi + Le_API="$ACME_DIRECTORY" + _savedomainconf "Le_API" "$Le_API" + _info "Using CA: $ACME_DIRECTORY" if [ "$_alt_domains" = "$NO_VALUE" ]; then _alt_domains="" @@ -4980,14 +4969,6 @@ renew() { fi if [ "$Le_API" ]; then - if [ "$_OLD_CA_HOST" = "$Le_API" ]; then - export Le_API="$DEFAULT_CA" - _savedomainconf Le_API "$Le_API" - fi - if [ "$_OLD_STAGE_CA_HOST" = "$Le_API" ]; then - export Le_API="$DEFAULT_STAGING_CA" - _savedomainconf Le_API "$Le_API" - fi export ACME_DIRECTORY="$Le_API" #reload ca configs ACCOUNT_KEY_PATH="" From b3a801df110d75886e15e8f6f10e8b1c77b0301a Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 15 Aug 2020 10:33:24 +0800 Subject: [PATCH 0852/2234] fix test endpoint --- acme.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index 406a158d..a7e6d7ef 100755 --- a/acme.sh +++ b/acme.sh @@ -2593,16 +2593,16 @@ _initpath() { fi if [ -z "$ACME_DIRECTORY" ]; then - default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") - _debug default_acme_server "$default_acme_server" - if [ "$default_acme_server" ]; then - ACME_DIRECTORY="$default_acme_server" + if [ "$STAGE" ]; then + ACME_DIRECTORY="$DEFAULT_STAGING_CA" + _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" else - if [ -z "$STAGE" ]; then - ACME_DIRECTORY="$DEFAULT_CA" + default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") + _debug default_acme_server "$default_acme_server" + if [ "$default_acme_server" ]; then + ACME_DIRECTORY="$default_acme_server" else - ACME_DIRECTORY="$DEFAULT_STAGING_CA" - _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + ACME_DIRECTORY="$DEFAULT_CA" fi fi fi From 95ef046d0a04836c465e720841cb3811ec7e2a3b Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 15 Aug 2020 12:32:15 +0800 Subject: [PATCH 0853/2234] fix https://github.com/acmesh-official/acme.sh/issues/3103 --- acme.sh | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index a7e6d7ef..d1e6f399 100755 --- a/acme.sh +++ b/acme.sh @@ -5228,13 +5228,17 @@ showcsr() { _info "KeyLength=$_csrkeylength" } +#listraw domain list() { _raw="$1" + _domain="$2" _initpath _sep="|" if [ "$_raw" ]; then - printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}CA${_sep}Created${_sep}Renew" + if [ -z "$_domain" ]; then + printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}CA${_sep}Created${_sep}Renew" + fi for di in "${CERT_HOME}"/*.*/; do d=$(basename "$di") _debug d "$d" @@ -5247,15 +5251,21 @@ list() { if [ -f "$DOMAIN_CONF" ]; then . "$DOMAIN_CONF" _ca="$(_getCAShortName "$Le_API")" - printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr" + if [ -z "$_domain" ]; then + printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr" + else + if [ "$_domain" = "$d" ]; then + cat "$DOMAIN_CONF" + fi + fi fi ) done else if _exists column; then - list "raw" | column -t -s "$_sep" + list "raw" "$_domain" | column -t -s "$_sep" else - list "raw" | tr "$_sep" '\t' + list "raw" "$_domain" | tr "$_sep" '\t' fi fi @@ -6595,6 +6605,9 @@ _selectServer() { #url _getCAShortName() { caurl="$1" + if [ -z "$caurl" ]; then + caurl="$DEFAULT_CA" + fi caurl_lower="$(echo $caurl | _lower_case)" _sindex=0 for surl in $(echo "$CA_SERVERS" | _lower_case | tr , ' '); do @@ -7271,7 +7284,7 @@ _process() { deactivateaccount ;; list) - list "$_listraw" + list "$_listraw" "$_domain" ;; installcronjob) installcronjob "$_confighome" ;; uninstallcronjob) uninstallcronjob ;; From e3ebd582ec62aacd77c73dbc11b7567492b00c51 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 16 Aug 2020 16:57:06 +0800 Subject: [PATCH 0854/2234] support "--preferred-chain" to select chain https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain --- acme.sh | 143 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 111 insertions(+), 32 deletions(-) diff --git a/acme.sh b/acme.sh index d1e6f399..e0f11e30 100755 --- a/acme.sh +++ b/acme.sh @@ -146,6 +146,8 @@ _DNS_ALIAS_WIKI="https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode" _DNS_MANUAL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode" +_DNS_API_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnsapi" + _NOTIFY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/notify" _SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo" @@ -156,6 +158,8 @@ _ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA" _SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server" +_PREFERRED_CHAIN_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -3985,6 +3989,20 @@ _check_dns_entries() { } +#file +_get_cert_issuer() { + _cfile="$1" + echo $(openssl x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2) +} + +#cert issuer +_match_issuer() { + _cfile="$1" + _missuer="$2" + _fissuer=$(_get_cert_issuer $_cfile) + [ "$_missuer" = "$_fissuer" ] +} + #webroot, domain domainlist keylength issue() { if [ -z "$2" ]; then @@ -4017,16 +4035,7 @@ issue() { _renew_hook="${12}" _local_addr="${13}" _challenge_alias="${14}" - #remove these later. - if [ "$_web_roots" = "dns-cf" ]; then - _web_roots="dns_cf" - fi - if [ "$_web_roots" = "dns-dp" ]; then - _web_roots="dns_dp" - fi - if [ "$_web_roots" = "dns-cx" ]; then - _web_roots="dns_cx" - fi + _preferred_chain="${15}" if [ ! "$IS_RENEW" ]; then _initpath "$_main_domain" "$_key_length" @@ -4079,6 +4088,11 @@ issue() { else _cleardomainconf "Le_ChallengeAlias" fi + if [ "$_preferred_chain" ]; then + _savedomainconf "Le_Preferred_Chain" "$_preferred_chain" "base64" + else + _cleardomainconf "Le_Preferred_Chain" + fi Le_API="$ACME_DIRECTORY" _savedomainconf "Le_API" "$Le_API" @@ -4746,7 +4760,7 @@ $_authorizations_map" _on_issue_err "$_post_hook" return 1 fi - _info "Download cert, Le_LinkCert: $Le_LinkCert" + _info "Downloading cert, Le_LinkCert: $Le_LinkCert" if ! _send_signed_request "$Le_LinkCert"; then _err "Sign failed, can not download cert:$Le_LinkCert." _err "$response" @@ -4755,17 +4769,36 @@ $_authorizations_map" fi echo "$response" >"$CERT_PATH" + _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" - if [ "$(grep -- "$BEGIN_CERT" "$CERT_PATH" | wc -l)" -gt "1" ]; then - _debug "Found cert chain" - cat "$CERT_PATH" >"$CERT_FULLCHAIN_PATH" - _end_n="$(grep -n -- "$END_CERT" "$CERT_FULLCHAIN_PATH" | _head_n 1 | cut -d : -f 1)" - _debug _end_n "$_end_n" - sed -n "1,${_end_n}p" "$CERT_FULLCHAIN_PATH" >"$CERT_PATH" - _end_n="$(_math $_end_n + 1)" - sed -n "${_end_n},9999p" "$CERT_FULLCHAIN_PATH" >"$CA_CERT_PATH" + if [ "$_preferred_chain" ]; then + _cert_issuer=$(_get_cert_issuer "$CA_CERT_PATH") + _debug _cert_issuer "$_cert_issuer" + if ! _match_issuer "$CA_CERT_PATH" "$_preferred_chain"; then + rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" + _debug2 "rels" "$rels" + for rel in $rels; do + _info "Try rel: $rel" + if ! _send_signed_request "$rel"; then + _err "Sign failed, can not download cert:$rel" + _err "$response" + continue + fi + _relcert="$CERT_PATH.alt" + _relfullchain="$CERT_FULLCHAIN_PATH.alt" + _relca="$CA_CERT_PATH.alt" + echo "$response" >"$_relcert" + _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" + if _match_issuer "$_relca" "$_preferred_chain"; then + _info "Matched issuer in: $rel" + cat $_relcert >"$CERT_PATH" + cat $_relfullchain >"$CERT_FULLCHAIN_PATH" + cat $_relca >"$CA_CERT_PATH" + break + fi + done + fi fi - else if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then _err "Sign failed. $response" @@ -4934,6 +4967,22 @@ $_authorizations_map" fi } +#in_out_cert out_fullchain out out_ca +_split_cert_chain() { + _certf="$1" + _fullchainf="$2" + _caf="$3" + if [ "$(grep -- "$BEGIN_CERT" "$_certf" | wc -l)" -gt "1" ]; then + _debug "Found cert chain" + cat "$_certf" >"$_fullchainf" + _end_n="$(grep -n -- "$END_CERT" "$_fullchainf" | _head_n 1 | cut -d : -f 1)" + _debug _end_n "$_end_n" + sed -n "1,${_end_n}p" "$_fullchainf" >"$_certf" + _end_n="$(_math $_end_n + 1)" + sed -n "${_end_n},9999p" "$_fullchainf" >"$_caf" + fi +} + #domain [isEcc] renew() { Le_Domain="$1" @@ -4994,7 +5043,7 @@ renew() { Le_PreHook="$(_readdomainconf Le_PreHook)" Le_PostHook="$(_readdomainconf Le_PostHook)" Le_RenewHook="$(_readdomainconf Le_RenewHook)" - 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" + issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain" res="$?" if [ "$res" != "0" ]; then return "$res" @@ -6379,19 +6428,34 @@ Commands: Parameters: --domain, -d domain.tld Specifies a domain, used to issue, renew or revoke etc. - --challenge-alias domain.tld The challenge domain alias for DNS alias mode: $_DNS_ALIAS_WIKI - --domain-alias domain.tld The domain alias for DNS alias mode: $_DNS_ALIAS_WIKI + --challenge-alias domain.tld The challenge domain alias for DNS alias mode. + See: $_DNS_ALIAS_WIKI + + --domain-alias domain.tld The domain alias for DNS alias mode. + See: $_DNS_ALIAS_WIKI + + --preferred-chain CHAIN If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. + If no match, the default offered chain will be used. (default: empty) + See: $_PREFERRED_CHAIN_WIKI + --force, -f Used to force to install or force to renew a cert immediately. --staging, --test Use staging server, just for test. --debug Output debug info. - --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for security. + --output-insecure Output all the sensitive messages. + By default all the credentials/sensitive messages are hidden from the output/debug/log for security. + --webroot, -w /path/to/webroot Specifies the web root folder for web root mode. --standalone Use standalone mode. --alpn Use standalone alpn mode. - --stateless Use stateless mode, see: $_STATELESS_WIKI + --stateless Use stateless mode. + See: $_STATELESS_WIKI + --apache Use apache mode. - --dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api. - --dnssleep 300 The time in seconds to wait for all the txt records to take effect in dns api mode. It's not necessary to use this by default, $PROJECT_NAME polls dns status automatically. + --dns [dns_hook] Use dns mode or dns api. + See: $_DNS_API_WIKI + + --dnssleep 300 The time in seconds to wait for all the txt records to propagate in dns api mode. + It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically. --keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. --accountkeylength, -ak [2048] Specifies the account key length: 2048, 3072, 4096 @@ -6412,7 +6476,9 @@ Parameters: --reloadcmd \"service nginx reload\" After issue/renew, it's used to reload the server. - --server SERVER ACME Directory Resource URI. See: $_SERVER_WIKI (default: $DEFAULT_CA) + --server SERVER ACME Directory Resource URI. (default: $DEFAULT_CA) + See: $_SERVER_WIKI + --accountconf Specifies a customized account config file. --home Specifies the home dir for $PROJECT_NAME. --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. @@ -6429,7 +6495,9 @@ Parameters: --insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted. --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. - --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. + --nocron Only valid for '--install' command, which means: do not install the default cron job. + In this case, the certs will not be renewed automatically. + --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. @@ -6446,7 +6514,9 @@ Parameters: --listen-v6 Force standalone/tls server to listen at ipv6. --openssl-bin Specifies a custom openssl bin location. --use-wget Force to use wget, if you have both curl and wget installed. - --yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode: $_DNS_MANUAL_WIKI + --yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode. + See: $_DNS_MANUAL_WIKI + --branch, -b Only valid for '--upgrade' command, specifies the branch name to upgrade to. --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. @@ -6454,11 +6524,15 @@ Parameters: 1: send notifications only when there is an error. 2: send notifications when a cert is successfully renewed, or there is an error. 3: send notifications when a cert is skipped, renewed, or error. + --notify-mode 0|1 Set notification mode. Default value is $NOTIFY_MODE_DEFAULT. 0: Bulk mode. Send all the domain's notifications in one message(mail). 1: Cert mode. Send a message for every single cert. + --notify-hook [hookname] Set the notify hook - --revoke-reason [0-10] The reason for '--revoke' command. See: $_REVOKE_WIKI + --revoke-reason [0-10] The reason for '--revoke' command. + See: $_REVOKE_WIKI + " } @@ -6689,6 +6763,7 @@ _process() { _revoke_reason="" _eab_kid="" _eab_hmac_key="" + _preferred_chain="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -7179,6 +7254,10 @@ _process() { _eab_hmac_key="$2" shift ;; + --preferred-chain) + _preferred_chain="$2" + shift + ;; *) _err "Unknown parameter : $1" return 1 @@ -7245,7 +7324,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" + 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" ;; deploy) deploy "$_domain" "$_deploy_hook" "$_ecc" From 0b531e9fbce6a8493a8a9b8af53fead0528af0f3 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 16 Aug 2020 16:59:08 +0800 Subject: [PATCH 0855/2234] fix format --- dnsapi/dns_kappernet.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 47a871c1..b3481c6c 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -25,7 +25,7 @@ dns_kappernet_add() { KAPPERNETDNS_Secret="" _err "Please specify your kapper.net api key and secret." _err "If you have not received yours - send your mail to" - _err "support@kapper.net to get your key and secret." + _err "support@kapper.net to get your key and secret." return 1 fi @@ -72,7 +72,7 @@ dns_kappernet_rm() { KAPPERNETDNS_Secret="" _err "Please specify your kapper.net api key and secret." _err "If you have not received yours - send your mail to" - _err "support@kapper.net to get your key and secret." + _err "support@kapper.net to get your key and secret." return 1 fi From bd04638d2779804524986c87d65f13f159460582 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 16 Aug 2020 17:36:24 +0800 Subject: [PATCH 0856/2234] minor --- acme.sh | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/acme.sh b/acme.sh index e0f11e30..bc64f377 100755 --- a/acme.sh +++ b/acme.sh @@ -1473,7 +1473,7 @@ createDomainKey() { _initpath "$domain" "$_cdl" - if [ ! -f "$CERT_KEY_PATH" ] || [ ! -s "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then + if [ ! -f "$CERT_KEY_PATH" ] || [ ! -s "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$_ACME_IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then if _createkey "$_cdl" "$CERT_KEY_PATH"; then _savedomainconf Le_Keylength "$_cdl" _info "The domain key is here: $(__green $CERT_KEY_PATH)" @@ -1483,7 +1483,7 @@ createDomainKey() { return 1 fi else - if [ "$IS_RENEW" ]; then + if [ "$_ACME_IS_RENEW" ]; then _info "Domain key exists, skip" return 0 else @@ -1509,7 +1509,7 @@ createCSR() { _initpath "$domain" "$_isEcc" - if [ -f "$CSR_PATH" ] && [ "$IS_RENEW" ] && [ -z "$FORCE" ]; then + if [ -f "$CSR_PATH" ] && [ "$_ACME_IS_RENEW" ] && [ -z "$FORCE" ]; then _info "CSR exists, skip" return fi @@ -2585,7 +2585,7 @@ _initpath() { . "$ACCOUNT_CONF_PATH" fi - if [ "$ACME_IN_CRON" ]; then + if [ "$_ACME_IN_CRON" ]; then if [ ! "$_USER_PATH_EXPORTED" ]; then _USER_PATH_EXPORTED=1 export PATH="$USER_PATH:$PATH" @@ -2599,7 +2599,7 @@ _initpath() { if [ -z "$ACME_DIRECTORY" ]; then if [ "$STAGE" ]; then ACME_DIRECTORY="$DEFAULT_STAGING_CA" - _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + _info "Using ACME_DIRECTORY: $ACME_DIRECTORY" else default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") _debug default_acme_server "$default_acme_server" @@ -3387,7 +3387,7 @@ _on_issue_err() { ) fi - if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "$W_DNS"; then + if [ "$_ACME_IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "$W_DNS"; then _err "$_DNS_MANUAL_ERR" fi @@ -3419,7 +3419,7 @@ _on_issue_success() { fi #run renew hook - if [ "$IS_RENEW" ] && [ "$_chk_renew_hook" ]; then + if [ "$_ACME_IS_RENEW" ] && [ "$_chk_renew_hook" ]; then _info "Run renew hook:'$_chk_renew_hook'" if ! ( export CERT_PATH @@ -4037,7 +4037,7 @@ issue() { _challenge_alias="${14}" _preferred_chain="${15}" - if [ ! "$IS_RENEW" ]; then + if [ -z "$_ACME_IS_RENEW" ]; then _initpath "$_main_domain" "$_key_length" mkdir -p "$DOMAIN_PATH" fi @@ -4689,7 +4689,8 @@ $_authorizations_map" der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" if [ "$ACME_VERSION" = "2" ]; then - _info "Lets finalize the order, Le_OrderFinalize: $Le_OrderFinalize" + _info "Lets finalize the order." + _info "Le_OrderFinalize" "$Le_OrderFinalize" if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then _err "Sign failed." _on_issue_err "$_post_hook" @@ -4760,7 +4761,8 @@ $_authorizations_map" _on_issue_err "$_post_hook" return 1 fi - _info "Downloading cert, Le_LinkCert: $Le_LinkCert" + _info "Downloading cert." + _info "Le_LinkCert" "$Le_LinkCert" if ! _send_signed_request "$Le_LinkCert"; then _err "Sign failed, can not download cert:$Le_LinkCert." _err "$response" @@ -4842,7 +4844,7 @@ $_authorizations_map" _info "Your cert key is in $(__green " $CERT_KEY_PATH ")" fi - if [ ! "$USER_PATH" ] || [ ! "$ACME_IN_CRON" ]; then + if [ ! "$USER_PATH" ] || [ ! "$_ACME_IN_CRON" ]; then USER_PATH="$PATH" _saveaccountconf "USER_PATH" "$USER_PATH" fi @@ -5033,12 +5035,12 @@ renew() { return "$RENEW_SKIP" fi - if [ "$ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then + if [ "$_ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then _info "Skip invalid cert for: $Le_Domain" return $RENEW_SKIP fi - IS_RENEW="1" + _ACME_IS_RENEW="1" Le_ReloadCmd="$(_readdomainconf Le_ReloadCmd)" Le_PreHook="$(_readdomainconf Le_PreHook)" Le_PostHook="$(_readdomainconf Le_PostHook)" @@ -5054,7 +5056,7 @@ renew() { res="$?" fi - IS_RENEW="" + _ACME_IS_RENEW="" return "$res" } @@ -5094,7 +5096,7 @@ renewAll() { _error_level="$NOTIFY_LEVEL_RENEW" _notify_code=0 fi - if [ "$ACME_IN_CRON" ]; then + if [ "$_ACME_IN_CRON" ]; then if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 @@ -5108,7 +5110,7 @@ renewAll() { _error_level="$NOTIFY_LEVEL_SKIP" _notify_code=$RENEW_SKIP fi - if [ "$ACME_IN_CRON" ]; then + if [ "$_ACME_IN_CRON" ]; then if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then _send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" @@ -5123,7 +5125,7 @@ renewAll() { _error_level="$NOTIFY_LEVEL_ERROR" _notify_code=1 fi - if [ "$ACME_IN_CRON" ]; then + if [ "$_ACME_IN_CRON" ]; then if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 @@ -5144,7 +5146,7 @@ renewAll() { done _debug _error_level "$_error_level" _debug _set_level "$_set_level" - if [ "$ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then + if [ "$_ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then _msg_subject="Renew" if [ "$_error_msg" ]; then @@ -5442,7 +5444,7 @@ _installcert() { if [ "$_real_cert" ]; then _info "Installing cert to:$_real_cert" - if [ -f "$_real_cert" ] && [ ! "$IS_RENEW" ]; then + if [ -f "$_real_cert" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_cert" "$_backup_path/cert.bak" fi cat "$CERT_PATH" >"$_real_cert" || return 1 @@ -5454,7 +5456,7 @@ _installcert() { echo "" >>"$_real_ca" cat "$CA_CERT_PATH" >>"$_real_ca" || return 1 else - if [ -f "$_real_ca" ] && [ ! "$IS_RENEW" ]; then + if [ -f "$_real_ca" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_ca" "$_backup_path/ca.bak" fi cat "$CA_CERT_PATH" >"$_real_ca" || return 1 @@ -5463,7 +5465,7 @@ _installcert() { if [ "$_real_key" ]; then _info "Installing key to:$_real_key" - if [ -f "$_real_key" ] && [ ! "$IS_RENEW" ]; then + if [ -f "$_real_key" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_key" "$_backup_path/key.bak" fi if [ -f "$_real_key" ]; then @@ -5476,7 +5478,7 @@ _installcert() { if [ "$_real_fullchain" ]; then _info "Installing full chain to:$_real_fullchain" - if [ -f "$_real_fullchain" ] && [ ! "$IS_RENEW" ]; then + if [ -f "$_real_fullchain" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_fullchain" "$_backup_path/fullchain.bak" fi cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain" || return 1 @@ -6093,7 +6095,7 @@ install() { _debug "Skip install cron job" fi - if [ "$ACME_IN_CRON" != "1" ]; then + if [ "$_ACME_IN_CRON" != "1" ]; then if ! _precheck "$_nocron"; then _err "Pre-check failed, can not install." return 1 @@ -6150,7 +6152,7 @@ install() { _info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY" - if [ "$ACME_IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then + if [ "$_ACME_IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then _installalias "$_c_home" fi @@ -6248,7 +6250,7 @@ _uninstallalias() { } cron() { - export ACME_IN_CRON=1 + export _ACME_IN_CRON=1 _initpath _info "$(__green "===Starting cron===")" if [ "$AUTO_UPGRADE" = "1" ]; then @@ -6269,7 +6271,7 @@ cron() { fi renewAll _ret="$?" - ACME_IN_CRON="" + _ACME_IN_CRON="" _info "$(__green "===End cron===")" exit $_ret } From d5d38b3331d2c4018ff4d5662e8a6f62d1055f9a Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:06:02 +0800 Subject: [PATCH 0857/2234] support multiple intermediate CA matching for `--preferred-chain` --- acme.sh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/acme.sh b/acme.sh index bc64f377..e7f6a5d9 100755 --- a/acme.sh +++ b/acme.sh @@ -3990,17 +3990,22 @@ _check_dns_entries() { } #file -_get_cert_issuer() { +_get_cert_issuers() { _cfile="$1" - echo $(openssl x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2) + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7"; then + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | openssl pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + else + ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + fi } #cert issuer _match_issuer() { _cfile="$1" _missuer="$2" - _fissuer=$(_get_cert_issuer $_cfile) - [ "$_missuer" = "$_fissuer" ] + _fissuers="$(_get_cert_issuers $_cfile)" + _debug2 _fissuers "$_fissuers" + _contains "$_fissuers" "$_missuer" } #webroot, domain domainlist keylength @@ -4773,10 +4778,8 @@ $_authorizations_map" echo "$response" >"$CERT_PATH" _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" - if [ "$_preferred_chain" ]; then - _cert_issuer=$(_get_cert_issuer "$CA_CERT_PATH") - _debug _cert_issuer "$_cert_issuer" - if ! _match_issuer "$CA_CERT_PATH" "$_preferred_chain"; then + if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then + if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" _debug2 "rels" "$rels" for rel in $rels; do @@ -4791,7 +4794,7 @@ $_authorizations_map" _relca="$CA_CERT_PATH.alt" echo "$response" >"$_relcert" _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" - if _match_issuer "$_relca" "$_preferred_chain"; then + if _match_issuer "$_relfullchain" "$_preferred_chain"; then _info "Matched issuer in: $rel" cat $_relcert >"$CERT_PATH" cat $_relfullchain >"$CERT_FULLCHAIN_PATH" From 19c4345162ddcba0d5c2b985f8739761c361582a Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:18:20 +0800 Subject: [PATCH 0858/2234] fix shfmt --- acme.sh | 1604 +++++++++++++++++------------------ deploy/exim4.sh | 4 +- deploy/ssh.sh | 10 +- deploy/vsftpd.sh | 6 +- dnsapi/dns_arvan.sh | 2 +- dnsapi/dns_aws.sh | 18 +- dnsapi/dns_azure.sh | 2 +- dnsapi/dns_conoha.sh | 6 +- dnsapi/dns_cyon.sh | 28 +- dnsapi/dns_da.sh | 34 +- dnsapi/dns_do.sh | 24 +- dnsapi/dns_easydns.sh | 2 +- dnsapi/dns_freedns.sh | 18 +- dnsapi/dns_gandi_livedns.sh | 16 +- dnsapi/dns_gcloud.sh | 12 +- dnsapi/dns_he.sh | 4 +- dnsapi/dns_hetzner.sh | 8 +- dnsapi/dns_ispconfig.sh | 74 +- dnsapi/dns_joker.sh | 2 +- dnsapi/dns_kappernet.sh | 8 +- dnsapi/dns_netlify.sh | 2 +- dnsapi/dns_one.sh | 4 +- dnsapi/dns_ovh.sh | 64 +- dnsapi/dns_pleskxml.sh | 41 +- dnsapi/dns_regru.sh | 10 +- notify/mail.sh | 52 +- notify/teams.sh | 18 +- notify/xmpp.sh | 14 +- 28 files changed, 1045 insertions(+), 1042 deletions(-) diff --git a/acme.sh b/acme.sh index e7f6a5d9..45e0c246 100755 --- a/acme.sh +++ b/acme.sh @@ -524,27 +524,27 @@ _math() { _h_char_2_dec() { _ch=$1 case "${_ch}" in - a | A) - printf "10" - ;; - b | B) - printf "11" - ;; - c | C) - printf "12" - ;; - d | D) - printf "13" - ;; - e | E) - printf "14" - ;; - f | F) - printf "15" - ;; - *) - printf "%s" "$_ch" - ;; + a | A) + printf "10" + ;; + b | B) + printf "11" + ;; + c | C) + printf "12" + ;; + d | D) + printf "13" + ;; + e | E) + printf "14" + ;; + f | F) + printf "15" + ;; + *) + printf "%s" "$_ch" + ;; esac } @@ -652,211 +652,211 @@ _url_encode() { for _hex_code in $_hex_str; do #upper case case "${_hex_code}" in - "41") - printf "%s" "A" - ;; - "42") - printf "%s" "B" - ;; - "43") - printf "%s" "C" - ;; - "44") - printf "%s" "D" - ;; - "45") - printf "%s" "E" - ;; - "46") - printf "%s" "F" - ;; - "47") - printf "%s" "G" - ;; - "48") - printf "%s" "H" - ;; - "49") - printf "%s" "I" - ;; - "4a") - printf "%s" "J" - ;; - "4b") - printf "%s" "K" - ;; - "4c") - printf "%s" "L" - ;; - "4d") - printf "%s" "M" - ;; - "4e") - printf "%s" "N" - ;; - "4f") - printf "%s" "O" - ;; - "50") - printf "%s" "P" - ;; - "51") - printf "%s" "Q" - ;; - "52") - printf "%s" "R" - ;; - "53") - printf "%s" "S" - ;; - "54") - printf "%s" "T" - ;; - "55") - printf "%s" "U" - ;; - "56") - printf "%s" "V" - ;; - "57") - printf "%s" "W" - ;; - "58") - printf "%s" "X" - ;; - "59") - printf "%s" "Y" - ;; - "5a") - printf "%s" "Z" - ;; + "41") + printf "%s" "A" + ;; + "42") + printf "%s" "B" + ;; + "43") + printf "%s" "C" + ;; + "44") + printf "%s" "D" + ;; + "45") + printf "%s" "E" + ;; + "46") + printf "%s" "F" + ;; + "47") + printf "%s" "G" + ;; + "48") + printf "%s" "H" + ;; + "49") + printf "%s" "I" + ;; + "4a") + printf "%s" "J" + ;; + "4b") + printf "%s" "K" + ;; + "4c") + printf "%s" "L" + ;; + "4d") + printf "%s" "M" + ;; + "4e") + printf "%s" "N" + ;; + "4f") + printf "%s" "O" + ;; + "50") + printf "%s" "P" + ;; + "51") + printf "%s" "Q" + ;; + "52") + printf "%s" "R" + ;; + "53") + printf "%s" "S" + ;; + "54") + printf "%s" "T" + ;; + "55") + printf "%s" "U" + ;; + "56") + printf "%s" "V" + ;; + "57") + printf "%s" "W" + ;; + "58") + printf "%s" "X" + ;; + "59") + printf "%s" "Y" + ;; + "5a") + printf "%s" "Z" + ;; #lower case - "61") - printf "%s" "a" - ;; - "62") - printf "%s" "b" - ;; - "63") - printf "%s" "c" - ;; - "64") - printf "%s" "d" - ;; - "65") - printf "%s" "e" - ;; - "66") - printf "%s" "f" - ;; - "67") - printf "%s" "g" - ;; - "68") - printf "%s" "h" - ;; - "69") - printf "%s" "i" - ;; - "6a") - printf "%s" "j" - ;; - "6b") - printf "%s" "k" - ;; - "6c") - printf "%s" "l" - ;; - "6d") - printf "%s" "m" - ;; - "6e") - printf "%s" "n" - ;; - "6f") - printf "%s" "o" - ;; - "70") - printf "%s" "p" - ;; - "71") - printf "%s" "q" - ;; - "72") - printf "%s" "r" - ;; - "73") - printf "%s" "s" - ;; - "74") - printf "%s" "t" - ;; - "75") - printf "%s" "u" - ;; - "76") - printf "%s" "v" - ;; - "77") - printf "%s" "w" - ;; - "78") - printf "%s" "x" - ;; - "79") - printf "%s" "y" - ;; - "7a") - printf "%s" "z" - ;; + "61") + printf "%s" "a" + ;; + "62") + printf "%s" "b" + ;; + "63") + printf "%s" "c" + ;; + "64") + printf "%s" "d" + ;; + "65") + printf "%s" "e" + ;; + "66") + printf "%s" "f" + ;; + "67") + printf "%s" "g" + ;; + "68") + printf "%s" "h" + ;; + "69") + printf "%s" "i" + ;; + "6a") + printf "%s" "j" + ;; + "6b") + printf "%s" "k" + ;; + "6c") + printf "%s" "l" + ;; + "6d") + printf "%s" "m" + ;; + "6e") + printf "%s" "n" + ;; + "6f") + printf "%s" "o" + ;; + "70") + printf "%s" "p" + ;; + "71") + printf "%s" "q" + ;; + "72") + printf "%s" "r" + ;; + "73") + printf "%s" "s" + ;; + "74") + printf "%s" "t" + ;; + "75") + printf "%s" "u" + ;; + "76") + printf "%s" "v" + ;; + "77") + printf "%s" "w" + ;; + "78") + printf "%s" "x" + ;; + "79") + printf "%s" "y" + ;; + "7a") + printf "%s" "z" + ;; #numbers - "30") - printf "%s" "0" - ;; - "31") - printf "%s" "1" - ;; - "32") - printf "%s" "2" - ;; - "33") - printf "%s" "3" - ;; - "34") - printf "%s" "4" - ;; - "35") - printf "%s" "5" - ;; - "36") - printf "%s" "6" - ;; - "37") - printf "%s" "7" - ;; - "38") - printf "%s" "8" - ;; - "39") - printf "%s" "9" - ;; - "2d") - printf "%s" "-" - ;; - "5f") - printf "%s" "_" - ;; - "2e") - printf "%s" "." - ;; - "7e") - printf "%s" "~" - ;; - #other hex - *) - printf '%%%s' "$_hex_code" - ;; + "30") + printf "%s" "0" + ;; + "31") + printf "%s" "1" + ;; + "32") + printf "%s" "2" + ;; + "33") + printf "%s" "3" + ;; + "34") + printf "%s" "4" + ;; + "35") + printf "%s" "5" + ;; + "36") + printf "%s" "6" + ;; + "37") + printf "%s" "7" + ;; + "38") + printf "%s" "8" + ;; + "39") + printf "%s" "9" + ;; + "2d") + printf "%s" "-" + ;; + "5f") + printf "%s" "_" + ;; + "2e") + printf "%s" "." + ;; + "7e") + printf "%s" "~" + ;; + #other hex + *) + printf '%%%s' "$_hex_code" + ;; esac done } @@ -1077,11 +1077,11 @@ _isEccKey() { return 1 fi - [ "$_length" != "1024" ] \ - && [ "$_length" != "2048" ] \ - && [ "$_length" != "3072" ] \ - && [ "$_length" != "4096" ] \ - && [ "$_length" != "8192" ] + [ "$_length" != "1024" ] && + [ "$_length" != "2048" ] && + [ "$_length" != "3072" ] && + [ "$_length" != "4096" ] && + [ "$_length" != "8192" ] } # _createkey 2048|ec-256 file @@ -1630,22 +1630,22 @@ _calcjwk() { crv_oid="$(${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^ASN1 OID:" | cut -d ":" -f 2 | tr -d " \r\n")" _debug3 crv_oid "$crv_oid" case "${crv_oid}" in - "prime256v1") - crv="P-256" - __ECC_KEY_LEN=256 - ;; - "secp384r1") - crv="P-384" - __ECC_KEY_LEN=384 - ;; - "secp521r1") - crv="P-521" - __ECC_KEY_LEN=512 - ;; - *) - _err "ECC oid : $crv_oid" - return 1 - ;; + "prime256v1") + crv="P-256" + __ECC_KEY_LEN=256 + ;; + "secp384r1") + crv="P-384" + __ECC_KEY_LEN=384 + ;; + "secp521r1") + crv="P-521" + __ECC_KEY_LEN=512 + ;; + *) + _err "ECC oid : $crv_oid" + return 1 + ;; esac _debug3 crv "$crv" fi @@ -6772,501 +6772,501 @@ _process() { while [ ${#} -gt 0 ]; do case "${1}" in - --help | -h) - showhelp - return - ;; - --version | -v) - version - return - ;; - --install) - _CMD="install" - ;; - --uninstall) - _CMD="uninstall" - ;; - --upgrade) - _CMD="upgrade" - ;; - --issue) - _CMD="issue" - ;; - --deploy) - _CMD="deploy" - ;; - --signcsr) - _CMD="signcsr" - ;; - --showcsr) - _CMD="showcsr" - ;; - --installcert | -i | --install-cert) - _CMD="installcert" - ;; - --renew | -r) - _CMD="renew" - ;; - --renewAll | --renewall | --renew-all) - _CMD="renewAll" - ;; - --revoke) - _CMD="revoke" - ;; - --remove) - _CMD="remove" - ;; - --list) - _CMD="list" - ;; - --installcronjob | --install-cronjob) - _CMD="installcronjob" - ;; - --uninstallcronjob | --uninstall-cronjob) - _CMD="uninstallcronjob" - ;; - --cron) - _CMD="cron" - ;; - --toPkcs) - _CMD="toPkcs" - ;; - --toPkcs8) - _CMD="toPkcs8" - ;; - --createAccountKey | --createaccountkey | -cak | --create-account-key) - _CMD="createAccountKey" - ;; - --createDomainKey | --createdomainkey | -cdk | --create-domain-key) - _CMD="createDomainKey" - ;; - --createCSR | --createcsr | -ccr) - _CMD="createCSR" - ;; - --deactivate) - _CMD="deactivate" - ;; - --updateaccount | --update-account) - _CMD="updateaccount" - ;; - --registeraccount | --register-account) - _CMD="registeraccount" - ;; - --deactivate-account) - _CMD="deactivateaccount" - ;; - --set-notify) - _CMD="setnotify" - ;; - --set-default-ca) - _CMD="setdefaultca" - ;; - --domain | -d) - _dvalue="$2" + --help | -h) + showhelp + return + ;; + --version | -v) + version + return + ;; + --install) + _CMD="install" + ;; + --uninstall) + _CMD="uninstall" + ;; + --upgrade) + _CMD="upgrade" + ;; + --issue) + _CMD="issue" + ;; + --deploy) + _CMD="deploy" + ;; + --signcsr) + _CMD="signcsr" + ;; + --showcsr) + _CMD="showcsr" + ;; + --installcert | -i | --install-cert) + _CMD="installcert" + ;; + --renew | -r) + _CMD="renew" + ;; + --renewAll | --renewall | --renew-all) + _CMD="renewAll" + ;; + --revoke) + _CMD="revoke" + ;; + --remove) + _CMD="remove" + ;; + --list) + _CMD="list" + ;; + --installcronjob | --install-cronjob) + _CMD="installcronjob" + ;; + --uninstallcronjob | --uninstall-cronjob) + _CMD="uninstallcronjob" + ;; + --cron) + _CMD="cron" + ;; + --toPkcs) + _CMD="toPkcs" + ;; + --toPkcs8) + _CMD="toPkcs8" + ;; + --createAccountKey | --createaccountkey | -cak | --create-account-key) + _CMD="createAccountKey" + ;; + --createDomainKey | --createdomainkey | -cdk | --create-domain-key) + _CMD="createDomainKey" + ;; + --createCSR | --createcsr | -ccr) + _CMD="createCSR" + ;; + --deactivate) + _CMD="deactivate" + ;; + --updateaccount | --update-account) + _CMD="updateaccount" + ;; + --registeraccount | --register-account) + _CMD="registeraccount" + ;; + --deactivate-account) + _CMD="deactivateaccount" + ;; + --set-notify) + _CMD="setnotify" + ;; + --set-default-ca) + _CMD="setdefaultca" + ;; + --domain | -d) + _dvalue="$2" - if [ "$_dvalue" ]; then - if _startswith "$_dvalue" "-"; then - _err "'$_dvalue' is not a valid domain for parameter '$1'" - return 1 - fi - if _is_idn "$_dvalue" && ! _exists idn; then - _err "It seems that $_dvalue is an IDN( Internationalized Domain Names), please install 'idn' command first." - return 1 - fi + if [ "$_dvalue" ]; then + if _startswith "$_dvalue" "-"; then + _err "'$_dvalue' is not a valid domain for parameter '$1'" + return 1 + fi + if _is_idn "$_dvalue" && ! _exists idn; then + _err "It seems that $_dvalue is an IDN( Internationalized Domain Names), please install 'idn' command first." + return 1 + fi - if _startswith "$_dvalue" "*."; then - _debug "Wildcard domain" - export ACME_VERSION=2 - fi - if [ -z "$_domain" ]; then - _domain="$_dvalue" + if _startswith "$_dvalue" "*."; then + _debug "Wildcard domain" + export ACME_VERSION=2 + fi + if [ -z "$_domain" ]; then + _domain="$_dvalue" + else + if [ "$_altdomains" = "$NO_VALUE" ]; then + _altdomains="$_dvalue" else - if [ "$_altdomains" = "$NO_VALUE" ]; then - _altdomains="$_dvalue" - else - _altdomains="$_altdomains,$_dvalue" - fi + _altdomains="$_altdomains,$_dvalue" fi fi + fi - shift - ;; + shift + ;; - --force | -f) - FORCE="1" - ;; - --staging | --test) - STAGE="1" - ;; - --server) - _server="$2" - _selectServer "$_server" + --force | -f) + FORCE="1" + ;; + --staging | --test) + STAGE="1" + ;; + --server) + _server="$2" + _selectServer "$_server" + shift + ;; + --debug) + if [ -z "$2" ] || _startswith "$2" "-"; then + DEBUG="$DEBUG_LEVEL_DEFAULT" + else + DEBUG="$2" shift - ;; - --debug) - if [ -z "$2" ] || _startswith "$2" "-"; then - DEBUG="$DEBUG_LEVEL_DEFAULT" - else - DEBUG="$2" - shift - fi - ;; - --output-insecure) - export OUTPUT_INSECURE=1 - ;; - --webroot | -w) + fi + ;; + --output-insecure) + export OUTPUT_INSECURE=1 + ;; + --webroot | -w) + wvalue="$2" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + shift + ;; + --challenge-alias) + cvalue="$2" + _challenge_alias="$_challenge_alias$cvalue," + shift + ;; + --domain-alias) + cvalue="$DNS_ALIAS_PREFIX$2" + _challenge_alias="$_challenge_alias$cvalue," + shift + ;; + --standalone) + wvalue="$NO_VALUE" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --alpn) + wvalue="$W_ALPN" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --stateless) + wvalue="$MODE_STATELESS" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --local-address) + lvalue="$2" + _local_address="$_local_address$lvalue," + shift + ;; + --apache) + wvalue="apache" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --nginx) + wvalue="$NGINX" + if [ "$2" ] && ! _startswith "$2" "-"; then + wvalue="$NGINX$2" + shift + fi + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --dns) + wvalue="$W_DNS" + if [ "$2" ] && ! _startswith "$2" "-"; then wvalue="$2" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi shift - ;; - --challenge-alias) - cvalue="$2" - _challenge_alias="$_challenge_alias$cvalue," - shift - ;; - --domain-alias) - cvalue="$DNS_ALIAS_PREFIX$2" - _challenge_alias="$_challenge_alias$cvalue," - shift - ;; - --standalone) - wvalue="$NO_VALUE" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --alpn) - wvalue="$W_ALPN" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --stateless) - wvalue="$MODE_STATELESS" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --local-address) - lvalue="$2" - _local_address="$_local_address$lvalue," - shift - ;; - --apache) - wvalue="apache" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --nginx) - wvalue="$NGINX" - if [ "$2" ] && ! _startswith "$2" "-"; then - wvalue="$NGINX$2" - shift - fi - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --dns) - wvalue="$W_DNS" - if [ "$2" ] && ! _startswith "$2" "-"; then - wvalue="$2" - shift - fi - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --dnssleep) - _dnssleep="$2" - Le_DNSSleep="$_dnssleep" - shift - ;; + fi + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --dnssleep) + _dnssleep="$2" + Le_DNSSleep="$_dnssleep" + shift + ;; - --keylength | -k) - _keylength="$2" - shift - ;; - --accountkeylength | -ak) - _accountkeylength="$2" - shift - ;; + --keylength | -k) + _keylength="$2" + shift + ;; + --accountkeylength | -ak) + _accountkeylength="$2" + shift + ;; - --cert-file | --certpath) - _cert_file="$2" - shift - ;; - --key-file | --keypath) - _key_file="$2" - shift - ;; - --ca-file | --capath) - _ca_file="$2" - shift - ;; - --fullchain-file | --fullchainpath) - _fullchain_file="$2" - shift - ;; - --reloadcmd | --reloadCmd) - _reloadcmd="$2" - shift - ;; - --password) - _password="$2" - shift - ;; - --accountconf) - _accountconf="$2" - ACCOUNT_CONF_PATH="$_accountconf" - shift - ;; - --home) - LE_WORKING_DIR="$2" - shift - ;; - --certhome | --cert-home) - _certhome="$2" - CERT_HOME="$_certhome" - shift - ;; - --config-home) - _confighome="$2" - LE_CONFIG_HOME="$_confighome" - shift - ;; - --useragent) - _useragent="$2" - USER_AGENT="$_useragent" - shift - ;; - --accountemail | -m) - _accountemail="$2" - ACCOUNT_EMAIL="$_accountemail" - shift - ;; - --accountkey) - _accountkey="$2" - ACCOUNT_KEY_PATH="$_accountkey" - shift - ;; - --days) - _days="$2" - Le_RenewalDays="$_days" - shift - ;; - --httpport) - _httpport="$2" - Le_HTTPPort="$_httpport" - shift - ;; - --tlsport) - _tlsport="$2" - Le_TLSPort="$_tlsport" - shift - ;; - --listraw) - _listraw="raw" - ;; - --stopRenewOnError | --stoprenewonerror | -se) - _stopRenewOnError="1" - ;; - --insecure) - #_insecure="1" - HTTPS_INSECURE="1" - ;; - --ca-bundle) - _ca_bundle="$(_readlink "$2")" - CA_BUNDLE="$_ca_bundle" - shift - ;; - --ca-path) - _ca_path="$2" - CA_PATH="$_ca_path" - shift - ;; - --nocron) - _nocron="1" - ;; - --noprofile) - _noprofile="1" - ;; - --no-color) - export ACME_NO_COLOR=1 - ;; - --force-color) - export ACME_FORCE_COLOR=1 - ;; - --ecc) - _ecc="isEcc" - ;; - --csr) - _csr="$2" - shift - ;; - --pre-hook) - _pre_hook="$2" - shift - ;; - --post-hook) - _post_hook="$2" - shift - ;; - --renew-hook) - _renew_hook="$2" - shift - ;; - --deploy-hook) - if [ -z "$2" ] || _startswith "$2" "-"; then - _usage "Please specify a value for '--deploy-hook'" - return 1 - fi - _deploy_hook="$_deploy_hook$2," - shift - ;; - --ocsp-must-staple | --ocsp) - Le_OCSP_Staple="1" - ;; - --always-force-new-domain-key) - if [ -z "$2" ] || _startswith "$2" "-"; then - Le_ForceNewDomainKey=1 - else - Le_ForceNewDomainKey="$2" - shift - fi - ;; - --yes-I-know-dns-manual-mode-enough-go-ahead-please) - export FORCE_DNS_MANUAL=1 - ;; - --log | --logfile) - _log="1" - _logfile="$2" - if _startswith "$_logfile" '-'; then - _logfile="" - else - shift - fi - LOG_FILE="$_logfile" - if [ -z "$LOG_LEVEL" ]; then - LOG_LEVEL="$DEFAULT_LOG_LEVEL" - fi - ;; - --log-level) - _log_level="$2" - LOG_LEVEL="$_log_level" - shift - ;; - --syslog) - if ! _startswith "$2" '-'; then - _syslog="$2" - shift - fi - if [ -z "$_syslog" ]; then - _syslog="$SYSLOG_LEVEL_DEFAULT" - fi - ;; - --auto-upgrade) - _auto_upgrade="$2" - if [ -z "$_auto_upgrade" ] || _startswith "$_auto_upgrade" '-'; then - _auto_upgrade="1" - else - shift - fi - AUTO_UPGRADE="$_auto_upgrade" - ;; - --listen-v4) - _listen_v4="1" - Le_Listen_V4="$_listen_v4" - ;; - --listen-v6) - _listen_v6="1" - Le_Listen_V6="$_listen_v6" - ;; - --openssl-bin) - _openssl_bin="$2" - ACME_OPENSSL_BIN="$_openssl_bin" - shift - ;; - --use-wget) - _use_wget="1" - ACME_USE_WGET="1" - ;; - --branch | -b) - export BRANCH="$2" - shift - ;; - --notify-hook) - _nhook="$2" - if _startswith "$_nhook" "-"; then - _err "'$_nhook' is not a hook name for '$1'" - return 1 - fi - if [ "$_notify_hook" ]; then - _notify_hook="$_notify_hook,$_nhook" - else - _notify_hook="$_nhook" - fi - shift - ;; - --notify-level) - _nlevel="$2" - if _startswith "$_nlevel" "-"; then - _err "'$_nlevel' is not a integer for '$1'" - return 1 - fi - _notify_level="$_nlevel" - shift - ;; - --notify-mode) - _nmode="$2" - if _startswith "$_nmode" "-"; then - _err "'$_nmode' is not a integer for '$1'" - return 1 - fi - _notify_mode="$_nmode" - shift - ;; - --revoke-reason) - _revoke_reason="$2" - if _startswith "$_revoke_reason" "-"; then - _err "'$_revoke_reason' is not a integer for '$1'" - return 1 - fi - shift - ;; - --eab-kid) - _eab_kid="$2" - shift - ;; - --eab-hmac-key) - _eab_hmac_key="$2" - shift - ;; - --preferred-chain) - _preferred_chain="$2" - shift - ;; - *) - _err "Unknown parameter : $1" + --cert-file | --certpath) + _cert_file="$2" + shift + ;; + --key-file | --keypath) + _key_file="$2" + shift + ;; + --ca-file | --capath) + _ca_file="$2" + shift + ;; + --fullchain-file | --fullchainpath) + _fullchain_file="$2" + shift + ;; + --reloadcmd | --reloadCmd) + _reloadcmd="$2" + shift + ;; + --password) + _password="$2" + shift + ;; + --accountconf) + _accountconf="$2" + ACCOUNT_CONF_PATH="$_accountconf" + shift + ;; + --home) + LE_WORKING_DIR="$2" + shift + ;; + --certhome | --cert-home) + _certhome="$2" + CERT_HOME="$_certhome" + shift + ;; + --config-home) + _confighome="$2" + LE_CONFIG_HOME="$_confighome" + shift + ;; + --useragent) + _useragent="$2" + USER_AGENT="$_useragent" + shift + ;; + --accountemail | -m) + _accountemail="$2" + ACCOUNT_EMAIL="$_accountemail" + shift + ;; + --accountkey) + _accountkey="$2" + ACCOUNT_KEY_PATH="$_accountkey" + shift + ;; + --days) + _days="$2" + Le_RenewalDays="$_days" + shift + ;; + --httpport) + _httpport="$2" + Le_HTTPPort="$_httpport" + shift + ;; + --tlsport) + _tlsport="$2" + Le_TLSPort="$_tlsport" + shift + ;; + --listraw) + _listraw="raw" + ;; + --stopRenewOnError | --stoprenewonerror | -se) + _stopRenewOnError="1" + ;; + --insecure) + #_insecure="1" + HTTPS_INSECURE="1" + ;; + --ca-bundle) + _ca_bundle="$(_readlink "$2")" + CA_BUNDLE="$_ca_bundle" + shift + ;; + --ca-path) + _ca_path="$2" + CA_PATH="$_ca_path" + shift + ;; + --nocron) + _nocron="1" + ;; + --noprofile) + _noprofile="1" + ;; + --no-color) + export ACME_NO_COLOR=1 + ;; + --force-color) + export ACME_FORCE_COLOR=1 + ;; + --ecc) + _ecc="isEcc" + ;; + --csr) + _csr="$2" + shift + ;; + --pre-hook) + _pre_hook="$2" + shift + ;; + --post-hook) + _post_hook="$2" + shift + ;; + --renew-hook) + _renew_hook="$2" + shift + ;; + --deploy-hook) + if [ -z "$2" ] || _startswith "$2" "-"; then + _usage "Please specify a value for '--deploy-hook'" return 1 - ;; + fi + _deploy_hook="$_deploy_hook$2," + shift + ;; + --ocsp-must-staple | --ocsp) + Le_OCSP_Staple="1" + ;; + --always-force-new-domain-key) + if [ -z "$2" ] || _startswith "$2" "-"; then + Le_ForceNewDomainKey=1 + else + Le_ForceNewDomainKey="$2" + shift + fi + ;; + --yes-I-know-dns-manual-mode-enough-go-ahead-please) + export FORCE_DNS_MANUAL=1 + ;; + --log | --logfile) + _log="1" + _logfile="$2" + if _startswith "$_logfile" '-'; then + _logfile="" + else + shift + fi + LOG_FILE="$_logfile" + if [ -z "$LOG_LEVEL" ]; then + LOG_LEVEL="$DEFAULT_LOG_LEVEL" + fi + ;; + --log-level) + _log_level="$2" + LOG_LEVEL="$_log_level" + shift + ;; + --syslog) + if ! _startswith "$2" '-'; then + _syslog="$2" + shift + fi + if [ -z "$_syslog" ]; then + _syslog="$SYSLOG_LEVEL_DEFAULT" + fi + ;; + --auto-upgrade) + _auto_upgrade="$2" + if [ -z "$_auto_upgrade" ] || _startswith "$_auto_upgrade" '-'; then + _auto_upgrade="1" + else + shift + fi + AUTO_UPGRADE="$_auto_upgrade" + ;; + --listen-v4) + _listen_v4="1" + Le_Listen_V4="$_listen_v4" + ;; + --listen-v6) + _listen_v6="1" + Le_Listen_V6="$_listen_v6" + ;; + --openssl-bin) + _openssl_bin="$2" + ACME_OPENSSL_BIN="$_openssl_bin" + shift + ;; + --use-wget) + _use_wget="1" + ACME_USE_WGET="1" + ;; + --branch | -b) + export BRANCH="$2" + shift + ;; + --notify-hook) + _nhook="$2" + if _startswith "$_nhook" "-"; then + _err "'$_nhook' is not a hook name for '$1'" + return 1 + fi + if [ "$_notify_hook" ]; then + _notify_hook="$_notify_hook,$_nhook" + else + _notify_hook="$_nhook" + fi + shift + ;; + --notify-level) + _nlevel="$2" + if _startswith "$_nlevel" "-"; then + _err "'$_nlevel' is not a integer for '$1'" + return 1 + fi + _notify_level="$_nlevel" + shift + ;; + --notify-mode) + _nmode="$2" + if _startswith "$_nmode" "-"; then + _err "'$_nmode' is not a integer for '$1'" + return 1 + fi + _notify_mode="$_nmode" + shift + ;; + --revoke-reason) + _revoke_reason="$2" + if _startswith "$_revoke_reason" "-"; then + _err "'$_revoke_reason' is not a integer for '$1'" + return 1 + fi + shift + ;; + --eab-kid) + _eab_kid="$2" + shift + ;; + --eab-hmac-key) + _eab_hmac_key="$2" + shift + ;; + --preferred-chain) + _preferred_chain="$2" + shift + ;; + *) + _err "Unknown parameter : $1" + return 1 + ;; esac shift 1 @@ -7325,82 +7325,82 @@ _process() { fi _debug "Running cmd: ${_CMD}" case "${_CMD}" in - install) install "$_nocron" "$_confighome" "$_noprofile" ;; - 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" - ;; - deploy) - deploy "$_domain" "$_deploy_hook" "$_ecc" - ;; - signcsr) - signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" - ;; - showcsr) - showcsr "$_csr" "$_domain" - ;; - installcert) - installcert "$_domain" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_ecc" - ;; - renew) - renew "$_domain" "$_ecc" - ;; - renewAll) - renewAll "$_stopRenewOnError" - ;; - revoke) - revoke "$_domain" "$_ecc" "$_revoke_reason" - ;; - remove) - remove "$_domain" "$_ecc" - ;; - deactivate) - deactivate "$_domain,$_altdomains" - ;; - registeraccount) - registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key" - ;; - updateaccount) - updateaccount - ;; - deactivateaccount) - deactivateaccount - ;; - list) - list "$_listraw" "$_domain" - ;; - installcronjob) installcronjob "$_confighome" ;; - uninstallcronjob) uninstallcronjob ;; - cron) cron ;; - toPkcs) - toPkcs "$_domain" "$_password" "$_ecc" - ;; - toPkcs8) - toPkcs8 "$_domain" "$_ecc" - ;; - createAccountKey) - createAccountKey "$_accountkeylength" - ;; - createDomainKey) - createDomainKey "$_domain" "$_keylength" - ;; - createCSR) - createCSR "$_domain" "$_altdomains" "$_ecc" - ;; - setnotify) - setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" - ;; - setdefaultca) - setdefaultca - ;; - *) - if [ "$_CMD" ]; then - _err "Invalid command: $_CMD" - fi - showhelp - return 1 - ;; + install) install "$_nocron" "$_confighome" "$_noprofile" ;; + 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" + ;; + deploy) + deploy "$_domain" "$_deploy_hook" "$_ecc" + ;; + signcsr) + signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" + ;; + showcsr) + showcsr "$_csr" "$_domain" + ;; + installcert) + installcert "$_domain" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_ecc" + ;; + renew) + renew "$_domain" "$_ecc" + ;; + renewAll) + renewAll "$_stopRenewOnError" + ;; + revoke) + revoke "$_domain" "$_ecc" "$_revoke_reason" + ;; + remove) + remove "$_domain" "$_ecc" + ;; + deactivate) + deactivate "$_domain,$_altdomains" + ;; + registeraccount) + registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key" + ;; + updateaccount) + updateaccount + ;; + deactivateaccount) + deactivateaccount + ;; + list) + list "$_listraw" "$_domain" + ;; + installcronjob) installcronjob "$_confighome" ;; + uninstallcronjob) uninstallcronjob ;; + cron) cron ;; + toPkcs) + toPkcs "$_domain" "$_password" "$_ecc" + ;; + toPkcs8) + toPkcs8 "$_domain" "$_ecc" + ;; + createAccountKey) + createAccountKey "$_accountkeylength" + ;; + createDomainKey) + createDomainKey "$_domain" "$_keylength" + ;; + createCSR) + createCSR "$_domain" "$_altdomains" "$_ecc" + ;; + setnotify) + setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" + ;; + setdefaultca) + setdefaultca + ;; + *) + if [ "$_CMD" ]; then + _err "Invalid command: $_CMD" + fi + showhelp + return 1 + ;; esac _ret="$?" if [ "$_ret" != "0" ]; then diff --git a/deploy/exim4.sh b/deploy/exim4.sh index 573f762b..260b8798 100644 --- a/deploy/exim4.sh +++ b/deploy/exim4.sh @@ -69,8 +69,8 @@ exim4_deploy() { cp "$_exim4_conf" "$_backup_conf" _info "Modify exim4 conf: $_exim4_conf" - if _setopt "$_exim4_conf" "tls_certificate" "=" "$_real_fullchain" \ - && _setopt "$_exim4_conf" "tls_privatekey" "=" "$_real_key"; then + if _setopt "$_exim4_conf" "tls_certificate" "=" "$_real_fullchain" && + _setopt "$_exim4_conf" "tls_privatekey" "=" "$_real_key"; then _info "Set config success!" else _err "Config exim4 server error, please report bug to us." diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 06d4b2b4..18de4aa6 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -195,8 +195,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ -n "$Le_Deploy_ssh_cafile" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] \ - || [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then + if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] || + [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then # if filename is same as previous file then append. _pipe=">>" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then @@ -222,9 +222,9 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ -n "$Le_Deploy_ssh_fullchain" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] \ - || [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] \ - || [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] || + [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] || + [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then # if filename is same as previous file then append. _pipe=">>" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then diff --git a/deploy/vsftpd.sh b/deploy/vsftpd.sh index ed44e709..8cf24e4f 100644 --- a/deploy/vsftpd.sh +++ b/deploy/vsftpd.sh @@ -65,9 +65,9 @@ vsftpd_deploy() { cp "$_vsftpd_conf" "$_backup_conf" _info "Modify vsftpd conf: $_vsftpd_conf" - if _setopt "$_vsftpd_conf" "rsa_cert_file" "=" "$_real_fullchain" \ - && _setopt "$_vsftpd_conf" "rsa_private_key_file" "=" "$_real_key" \ - && _setopt "$_vsftpd_conf" "ssl_enable" "=" "YES"; then + if _setopt "$_vsftpd_conf" "rsa_cert_file" "=" "$_real_fullchain" && + _setopt "$_vsftpd_conf" "rsa_private_key_file" "=" "$_real_key" && + _setopt "$_vsftpd_conf" "ssl_enable" "=" "YES"; then _info "Set config success!" else _err "Config vsftpd server error, please report bug to us." diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index edeb56ca..ca1f56c7 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -5,7 +5,7 @@ ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" #Author: Ehsan Aliakbar -#Report Bugs here: https://github.com/Neilpang/acme.sh +#Report Bugs here: https://github.com/Neilpang/acme.sh # ######## Public functions ##################### diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index ea4736c4..068c337c 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -222,21 +222,21 @@ _use_instance_role() { _use_metadata() { _aws_creds="$( - _get "$1" "" 1 \ - | _normalizeJson \ - | tr '{,}' '\n' \ - | while read -r _line; do + _get "$1" "" 1 | + _normalizeJson | + tr '{,}' '\n' | + while read -r _line; do _key="$(echo "${_line%%:*}" | tr -d '"')" _value="${_line#*:}" _debug3 "_key" "$_key" _secure_debug3 "_value" "$_value" case "$_key" in - AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;; - SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;; - Token) echo "AWS_SESSION_TOKEN=$_value" ;; + AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;; + SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;; + Token) echo "AWS_SESSION_TOKEN=$_value" ;; esac - done \ - | paste -sd' ' - + done | + paste -sd' ' - )" _secure_debug "_aws_creds" "$_aws_creds" diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 28b6572a..ce8a3fa7 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -220,7 +220,7 @@ _azure_rest() { export _H2="accept: application/json" export _H3="Content-Type: application/json" # clear headers from previous request to avoid getting wrong http code on timeouts - :>"$HTTP_HEADER" + : >"$HTTP_HEADER" _debug "$ep" if [ "$m" != "GET" ]; then _secure_debug2 "data $data" diff --git a/dnsapi/dns_conoha.sh b/dnsapi/dns_conoha.sh index d3bee130..ddc32074 100755 --- a/dnsapi/dns_conoha.sh +++ b/dnsapi/dns_conoha.sh @@ -115,9 +115,9 @@ dns_conoha_rm() { return 1 fi - record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' \ - | grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" \ - | _head_n 1 | cut -d : -f 2 | tr -d \") + record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' | + grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" | + _head_n 1 | cut -d : -f 2 | tr -d \") if [ -z "$record_id" ]; then _err "Can not get record id to remove." return 1 diff --git a/dnsapi/dns_cyon.sh b/dnsapi/dns_cyon.sh index 2dca90c0..2c08812b 100644 --- a/dnsapi/dns_cyon.sh +++ b/dnsapi/dns_cyon.sh @@ -18,23 +18,23 @@ ######## dns_cyon_add() { - _cyon_load_credentials \ - && _cyon_load_parameters "$@" \ - && _cyon_print_header "add" \ - && _cyon_login \ - && _cyon_change_domain_env \ - && _cyon_add_txt \ - && _cyon_logout + _cyon_load_credentials && + _cyon_load_parameters "$@" && + _cyon_print_header "add" && + _cyon_login && + _cyon_change_domain_env && + _cyon_add_txt && + _cyon_logout } dns_cyon_rm() { - _cyon_load_credentials \ - && _cyon_load_parameters "$@" \ - && _cyon_print_header "delete" \ - && _cyon_login \ - && _cyon_change_domain_env \ - && _cyon_delete_txt \ - && _cyon_logout + _cyon_load_credentials && + _cyon_load_parameters "$@" && + _cyon_print_header "delete" && + _cyon_login && + _cyon_change_domain_env && + _cyon_delete_txt && + _cyon_logout } ######################### diff --git a/dnsapi/dns_da.sh b/dnsapi/dns_da.sh index 4e9c4ef0..4d3e09b1 100755 --- a/dnsapi/dns_da.sh +++ b/dnsapi/dns_da.sh @@ -115,23 +115,23 @@ _da_api() { _debug response "$response" case "${cmd}" in - CMD_API_DNS_CONTROL) - # Parse the result in general - # error=0&text=Records Deleted&details= - # error=1&text=Cannot View Dns Record&details=No domain provided - err_field="$(_getfield "$response" 1 '&')" - txt_field="$(_getfield "$response" 2 '&')" - details_field="$(_getfield "$response" 3 '&')" - error="$(_getfield "$err_field" 2 '=')" - text="$(_getfield "$txt_field" 2 '=')" - details="$(_getfield "$details_field" 2 '=')" - _debug "error: ${error}, text: ${text}, details: ${details}" - if [ "$error" != "0" ]; then - _err "error $response" - return 1 - fi - ;; - CMD_API_SHOW_DOMAINS) ;; + CMD_API_DNS_CONTROL) + # Parse the result in general + # error=0&text=Records Deleted&details= + # error=1&text=Cannot View Dns Record&details=No domain provided + err_field="$(_getfield "$response" 1 '&')" + txt_field="$(_getfield "$response" 2 '&')" + details_field="$(_getfield "$response" 3 '&')" + error="$(_getfield "$err_field" 2 '=')" + text="$(_getfield "$txt_field" 2 '=')" + details="$(_getfield "$details_field" 2 '=')" + _debug "error: ${error}, text: ${text}, details: ${details}" + if [ "$error" != "0" ]; then + _err "error $response" + return 1 + fi + ;; + CMD_API_SHOW_DOMAINS) ;; esac return 0 } diff --git a/dnsapi/dns_do.sh b/dnsapi/dns_do.sh index 3a2f8f49..3850890c 100755 --- a/dnsapi/dns_do.sh +++ b/dnsapi/dns_do.sh @@ -67,14 +67,14 @@ _dns_do_list_rrs() { _err "getRRList origin ${_domain} failed" return 1 fi - _rr_list="$(echo "${response}" \ - | tr -d "\n\r\t" \ - | sed -e 's//\n/g' \ - | grep ">$(_regexcape "$fulldomain")" \ - | sed -e 's/<\/item>/\n/g' \ - | grep '>id[0-9]{1,16}<' \ - | tr -d '><')" + _rr_list="$(echo "${response}" | + tr -d "\n\r\t" | + sed -e 's//\n/g' | + grep ">$(_regexcape "$fulldomain")" | + sed -e 's/<\/item>/\n/g' | + grep '>id[0-9]{1,16}<' | + tr -d '><')" [ "${_rr_list}" ] } @@ -120,10 +120,10 @@ _get_root() { i=1 _dns_do_soap getDomainList - _all_domains="$(echo "${response}" \ - | tr -d "\n\r\t " \ - | _egrep_o 'domain]+>[^<]+' \ - | sed -e 's/^domain<\/key>]*>//g')" + _all_domains="$(echo "${response}" | + tr -d "\n\r\t " | + _egrep_o 'domain]+>[^<]+' | + sed -e 's/^domain<\/key>]*>//g')" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh index f466f1e2..ab47a0bc 100644 --- a/dnsapi/dns_easydns.sh +++ b/dnsapi/dns_easydns.sh @@ -3,7 +3,7 @@ ####################################################### # # easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh -# +# # API Documentation: https://sandbox.rest.easydns.net:3001/ # # Author: wurzelpanzer [wurzelpanzer@maximolider.net] diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 4a58931f..29cee430 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -303,10 +303,10 @@ _freedns_domain_id() { return 1 fi - domain_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ - | grep "$search_domain\|$search_domain(.*)" \ - | sed -n 's/.*\(edit\.php?edit_domain_id=[0-9a-zA-Z]*\).*/\1/p' \ - | cut -d = -f 2)" + domain_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' | + grep "$search_domain\|$search_domain(.*)" | + sed -n 's/.*\(edit\.php?edit_domain_id=[0-9a-zA-Z]*\).*/\1/p' | + cut -d = -f 2)" # The above beauty extracts domain ID from the html page... # strip out all blank space and new lines. Then insert newlines # before each table row @@ -349,11 +349,11 @@ _freedns_data_id() { return 1 fi - data_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ - | grep "$record_type" \ - | grep "$search_domain" \ - | sed -n 's/.*\(edit\.php?data_id=[0-9a-zA-Z]*\).*/\1/p' \ - | cut -d = -f 2)" + data_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' | + grep "$record_type" | + grep "$search_domain" | + sed -n 's/.*\(edit\.php?data_id=[0-9a-zA-Z]*\).*/\1/p' | + cut -d = -f 2)" # The above beauty extracts data ID from the html page... # strip out all blank space and new lines. Then insert newlines # before each table row diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh index cdda4775..87119521 100644 --- a/dnsapi/dns_gandi_livedns.sh +++ b/dnsapi/dns_gandi_livedns.sh @@ -69,9 +69,9 @@ dns_gandi_livedns_rm() { _gandi_livedns_rest PUT \ "domains/$_domain/records/$_sub_domain/TXT" \ - "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" \ - && _contains "$response" '{"message": "DNS Record Created"}' \ - && _info "Removing record $(__green "success")" + "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" && + _contains "$response" '{"message": "DNS Record Created"}' && + _info "Removing record $(__green "success")" } #################### Private functions below ################################## @@ -125,9 +125,9 @@ _dns_gandi_append_record() { fi _debug new_rrset_values "$_rrset_values" _gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \ - "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" \ - && _contains "$response" '{"message": "DNS Record Created"}' \ - && _info "Adding record $(__green "success")" + "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" && + _contains "$response" '{"message": "DNS Record Created"}' && + _info "Adding record $(__green "success")" } _dns_gandi_existing_rrset_values() { @@ -145,8 +145,8 @@ _dns_gandi_existing_rrset_values() { return 1 fi _debug "Already has TXT record." - _rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' \ - | _egrep_o '\[".*\"]') + _rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' | + _egrep_o '\[".*\"]') return 0 } diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index 6365b338..03060a8c 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -78,8 +78,8 @@ _dns_gcloud_execute_tr() { for i in $(seq 1 120); do if gcloud dns record-sets changes list \ --zone="$managedZone" \ - --filter='status != done' \ - | grep -q '^.*'; then + --filter='status != done' | + grep -q '^.*'; then _info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ($i/120)..." sleep 5 else @@ -137,11 +137,11 @@ _dns_gcloud_find_zone() { # List domains and find the zone with the deepest sub-domain (in case of some levels of delegation) if ! match=$(gcloud dns managed-zones list \ --format="value(name, dnsName)" \ - --filter="$filter" \ - | while read -r dnsName name; do + --filter="$filter" | + while read -r dnsName name; do printf "%s\t%s\t%s\n" "$(echo "$name" | awk -F"." '{print NF-1}')" "$dnsName" "$name" - done \ - | sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then + done | + sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then _err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?" return 1 fi diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index 5829e00e..ef09fa0a 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -101,8 +101,8 @@ dns_he_rm() { body="$body&hosted_dns_editzone=1" body="$body&hosted_dns_delrecord=1" body="$body&hosted_dns_delconfirm=delete" - _post "$body" "https://dns.he.net/" \ - | grep '
Successfully removed record.
' \ + _post "$body" "https://dns.he.net/" | + grep '
Successfully removed record.
' \ >/dev/null exit_code="$?" if [ "$exit_code" -eq 0 ]; then diff --git a/dnsapi/dns_hetzner.sh b/dnsapi/dns_hetzner.sh index 5db0418c..911d4a35 100644 --- a/dnsapi/dns_hetzner.sh +++ b/dnsapi/dns_hetzner.sh @@ -123,10 +123,10 @@ _find_record() { return 1 else _record_id=$( - echo "$response" \ - | grep -o "{[^\{\}]*\"name\":\"$_record_name\"[^\}]*}" \ - | grep "\"value\":\"$_record_value\"" \ - | while read -r record; do + echo "$response" | + grep -o "{[^\{\}]*\"name\":\"$_record_name\"[^\}]*}" | + grep "\"value\":\"$_record_value\"" | + while read -r record; do # test for type and if [ -n "$(echo "$record" | _egrep_o '"type":"TXT"')" ]; then echo "$record" | _egrep_o '"id":"[^"]*"' | cut -d : -f 2 | tr -d \" diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 2d8d6b0a..bd1e0391 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -95,29 +95,29 @@ _ISPC_getZoneInfo() { server_id=$(echo "${curResult}" | _egrep_o "server_id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Server ID: '${server_id}'" case "${server_id}" in - '' | *[!0-9]*) - _err "Server ID is not numeric." - return 1 - ;; - *) _info "Retrieved Server ID" ;; + '' | *[!0-9]*) + _err "Server ID is not numeric." + return 1 + ;; + *) _info "Retrieved Server ID" ;; esac zone=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Zone: '${zone}'" case "${zone}" in - '' | *[!0-9]*) - _err "Zone ID is not numeric." - return 1 - ;; - *) _info "Retrieved Zone ID" ;; + '' | *[!0-9]*) + _err "Zone ID is not numeric." + return 1 + ;; + *) _info "Retrieved Zone ID" ;; esac client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Client ID: '${client_id}'" case "${client_id}" in - '' | *[!0-9]*) - _err "Client ID is not numeric." - return 1 - ;; - *) _info "Retrieved Client ID." ;; + '' | *[!0-9]*) + _err "Client ID is not numeric." + return 1 + ;; + *) _info "Retrieved Client ID." ;; esac zoneFound="" zoneEnd="" @@ -135,11 +135,11 @@ _ISPC_addTxt() { record_id=$(echo "${curResult}" | _egrep_o "\"response.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Record ID: '${record_id}'" case "${record_id}" in - '' | *[!0-9]*) - _err "Couldn't add ACME Challenge TXT record to zone." - return 1 - ;; - *) _info "Added ACME Challenge TXT record to zone." ;; + '' | *[!0-9]*) + _err "Couldn't add ACME Challenge TXT record to zone." + return 1 + ;; + *) _info "Added ACME Challenge TXT record to zone." ;; esac } @@ -153,24 +153,24 @@ _ISPC_rmTxt() { record_id=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Record ID: '${record_id}'" case "${record_id}" in - '' | *[!0-9]*) - _err "Record ID is not numeric." + '' | *[!0-9]*) + _err "Record ID is not numeric." + return 1 + ;; + *) + unset IFS + _info "Retrieved Record ID." + curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\",\"update_serial\":true}" + curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")" + _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'" + _debug "Result of _ISPC_rmTxt: '$curResult'" + if _contains "${curResult}" '"code":"ok"'; then + _info "Removed ACME Challenge TXT record from zone." + else + _err "Couldn't remove ACME Challenge TXT record from zone." return 1 - ;; - *) - unset IFS - _info "Retrieved Record ID." - curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\",\"update_serial\":true}" - curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")" - _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'" - _debug "Result of _ISPC_rmTxt: '$curResult'" - if _contains "${curResult}" '"code":"ok"'; then - _info "Removed ACME Challenge TXT record from zone." - else - _err "Couldn't remove ACME Challenge TXT record from zone." - return 1 - fi - ;; + fi + ;; esac fi } diff --git a/dnsapi/dns_joker.sh b/dnsapi/dns_joker.sh index 5d50953e..78399a1d 100644 --- a/dnsapi/dns_joker.sh +++ b/dnsapi/dns_joker.sh @@ -100,7 +100,7 @@ _get_root() { fi # Try to remove a test record. With correct root domain, username and password this will return "OK: ..." regardless - # of record in question existing or not. + # of record in question existing or not. if _joker_rest "username=$JOKER_USERNAME&password=$JOKER_PASSWORD&zone=$h&label=jokerTXTUpdateTest&type=TXT&value="; then if _startswith "$response" "OK"; then _sub_domain="$(echo "$fulldomain" | sed "s/\\.$h\$//")" diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index b3481c6c..83a7e5f8 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -5,12 +5,12 @@ # please report issues here: https://github.com/acmesh-official/acme.sh/issues/2977 #KAPPERNETDNS_Key="yourKAPPERNETapikey" -#KAPPERNETDNS_Secret="yourKAPPERNETapisecret" +#KAPPERNETDNS_Secret="yourKAPPERNETapisecret" KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" ############################################################################### -# called with +# called with # fullhostname: something.example.com # txtvalue: someacmegenerated string dns_kappernet_add() { @@ -97,7 +97,7 @@ dns_kappernet_rm() { #################### Private functions below ################################## # called with hostname # e.g._acme-challenge.www.domain.com returns -# _sub_domain=_acme-challenge.www +# _sub_domain=_acme-challenge.www # _domain=domain.com _get_root() { domain=$1 @@ -127,7 +127,7 @@ _get_root() { ################################################################################ # calls the kapper.net DNS Panel API -# with +# with # method # param _kappernet_api() { diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index 137ac1fb..2ce13e2b 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -144,7 +144,7 @@ _netlify_rest() { export _H1="Content-Type: application/json" export _H2="Authorization: Bearer $token_trimmed" - :>"$HTTP_HEADER" + : >"$HTTP_HEADER" if [ "$m" != "GET" ]; then _debug data "$data" diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 96ef5969..890cc804 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -6,10 +6,10 @@ # Created: 2019-02-17 # Fixed by: @der-berni # Modified: 2020-04-07 -# +# # Use ONECOM_KeepCnameProxy to keep the CNAME DNS record # export ONECOM_KeepCnameProxy="1" -# +# # export ONECOM_User="username" # export ONECOM_Password="password" # diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 7c18d009..dda47dda 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -41,40 +41,40 @@ _ovh_get_api() { case "${_ogaep}" in - ovh-eu | ovheu) - printf "%s" $OVH_EU - return - ;; - ovh-ca | ovhca) - printf "%s" $OVH_CA - return - ;; - kimsufi-eu | kimsufieu) - printf "%s" $KSF_EU - return - ;; - kimsufi-ca | kimsufica) - printf "%s" $KSF_CA - return - ;; - soyoustart-eu | soyoustarteu) - printf "%s" $SYS_EU - return - ;; - soyoustart-ca | soyoustartca) - printf "%s" $SYS_CA - return - ;; - runabove-ca | runaboveca) - printf "%s" $RAV_CA - return - ;; + ovh-eu | ovheu) + printf "%s" $OVH_EU + return + ;; + ovh-ca | ovhca) + printf "%s" $OVH_CA + return + ;; + kimsufi-eu | kimsufieu) + printf "%s" $KSF_EU + return + ;; + kimsufi-ca | kimsufica) + printf "%s" $KSF_CA + return + ;; + soyoustart-eu | soyoustarteu) + printf "%s" $SYS_EU + return + ;; + soyoustart-ca | soyoustartca) + printf "%s" $SYS_CA + return + ;; + runabove-ca | runaboveca) + printf "%s" $RAV_CA + return + ;; - *) + *) - _err "Unknown parameter : $1" - return 1 - ;; + _err "Unknown parameter : $1" + return 1 + ;; esac } diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index fe18bef4..f5986827 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -136,11 +136,12 @@ dns_pleskxml_rm() { # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) # Also strip out spaces between tags, redundant and group tags and any tags - reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ - | sed 's# \{1,\}<\([a-zA-Z]\)#<\1#g;s###g;s#<[a-z][^/<>]*/>##g' \ - | grep "${root_domain_id}" \ - | grep '[0-9]\{1,\}' \ - | grep 'TXT' + reclist="$( + _api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | + sed 's# \{1,\}<\([a-zA-Z]\)#<\1#g;s###g;s#<[a-z][^/<>]*/>##g' | + grep "${root_domain_id}" | + grep '[0-9]\{1,\}' | + grep 'TXT' )" if [ -z "$reclist" ]; then @@ -151,10 +152,11 @@ dns_pleskxml_rm() { _debug "Got list of DNS TXT records for root domain '$root_domain_name':" _debug "$reclist" - recid="$(_value "$reclist" \ - | grep "${fulldomain}." \ - | grep "${txtvalue}" \ - | sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' + recid="$( + _value "$reclist" | + grep "${fulldomain}." | + grep "${txtvalue}" | + sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' )" if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then @@ -220,11 +222,11 @@ _countdots() { # Last line could change to instead, with suitable escaping of ['"/$], # if future Plesk XML API changes ever require extended regex _api_response_split() { - printf '%s' "$1" \ - | sed 's/^ +//;s/ +$//' \ - | tr -d '\n\r' \ - | sed "s/<\/\{0,1\}$2>/${NEWLINE}/g" \ - | grep "$3" + printf '%s' "$1" | + sed 's/^ +//;s/ +$//' | + tr -d '\n\r' | + sed "s/<\/\{0,1\}$2>/${NEWLINE}/g" | + grep "$3" } #################### Private functions below (DNS functions) ################################## @@ -261,14 +263,15 @@ _call_api() { elif [ "$statuslines_count_okay" -ne "$statuslines_count_total" ]; then # We have some status lines that aren't "ok". Any available details are in API response fields "status" "errcode" and "errtext" - # Workaround for basic regex: + # Workaround for basic regex: # - filter output to keep only lines like this: "SPACEStextSPACES" (shouldn't be necessary with prettyprint but guarantees subsequent code is ok) # - then edit the 3 "useful" error tokens individually and remove closing tags on all lines # - then filter again to remove all lines not edited (which will be the lines not starting A-Z) - errtext="$(_value "$pleskxml_prettyprint_result" \ - | grep '^ *<[a-z]\{1,\}>[^<]*<\/[a-z]\{1,\}> *$' \ - | sed 's/^ */Status: /;s/^ */Error code: /;s/^ */Error text: /;s/<\/.*$//' \ - | grep '^[A-Z]' + errtext="$( + _value "$pleskxml_prettyprint_result" | + grep '^ *<[a-z]\{1,\}>[^<]*<\/[a-z]\{1,\}> *$' | + sed 's/^ */Status: /;s/^ */Error code: /;s/^ */Error text: /;s/<\/.*$//' | + grep '^[A-Z]' )" fi diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index b5729fda..a50821eb 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -87,11 +87,11 @@ _get_root() { for ITEM in ${domains_list}; do case "${domain}" in - *${ITEM}*) - _domain=${ITEM} - _debug _domain "${_domain}" - return 0 - ;; + *${ITEM}*) + _domain=${ITEM} + _debug _domain "${_domain}" + return 0 + ;; esac done diff --git a/notify/mail.sh b/notify/mail.sh index 54b2a6d4..d33fd0d2 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -98,24 +98,24 @@ _mail_cmnd() { _MAIL_ARGS="" case $(basename "$_MAIL_BIN") in - sendmail) - if [ -n "$MAIL_FROM" ]; then - _MAIL_ARGS="-f '$MAIL_FROM'" - fi - ;; - mutt | mail) - _MAIL_ARGS="-s '$_subject'" - ;; - msmtp) - if [ -n "$MAIL_FROM" ]; then - _MAIL_ARGS="-f '$MAIL_FROM'" - fi + sendmail) + if [ -n "$MAIL_FROM" ]; then + _MAIL_ARGS="-f '$MAIL_FROM'" + fi + ;; + mutt | mail) + _MAIL_ARGS="-s '$_subject'" + ;; + msmtp) + if [ -n "$MAIL_FROM" ]; then + _MAIL_ARGS="-f '$MAIL_FROM'" + fi - if [ -n "$MAIL_MSMTP_ACCOUNT" ]; then - _MAIL_ARGS="$_MAIL_ARGS -a '$MAIL_MSMTP_ACCOUNT'" - fi - ;; - *) ;; + if [ -n "$MAIL_MSMTP_ACCOUNT" ]; then + _MAIL_ARGS="$_MAIL_ARGS -a '$MAIL_MSMTP_ACCOUNT'" + fi + ;; + *) ;; esac echo "'$_MAIL_BIN' $_MAIL_ARGS '$MAIL_TO'" @@ -123,16 +123,16 @@ _mail_cmnd() { _mail_body() { case $(basename "$_MAIL_BIN") in - sendmail | ssmtp | msmtp) - if [ -n "$MAIL_FROM" ]; then - echo "From: $MAIL_FROM" - fi + sendmail | ssmtp | msmtp) + if [ -n "$MAIL_FROM" ]; then + echo "From: $MAIL_FROM" + fi - echo "To: $MAIL_TO" - echo "Subject: $subject" - echo "Content-Type: $contenttype" - echo - ;; + echo "To: $MAIL_TO" + echo "Subject: $subject" + echo "Content-Type: $contenttype" + echo + ;; esac echo "$_content" diff --git a/notify/teams.sh b/notify/teams.sh index e50ea703..1bc5ed08 100644 --- a/notify/teams.sh +++ b/notify/teams.sh @@ -52,15 +52,15 @@ teams_send() { _content=$(echo "$_content" | _json_encode) case "$_statusCode" in - 0) - _color="${TEAMS_SUCCESS_COLOR:-$_color_success}" - ;; - 1) - _color="${TEAMS_ERROR_COLOR:-$_color_danger}" - ;; - 2) - _color="${TEAMS_SKIP_COLOR:-$_color_muted}" - ;; + 0) + _color="${TEAMS_SUCCESS_COLOR:-$_color_success}" + ;; + 1) + _color="${TEAMS_ERROR_COLOR:-$_color_danger}" + ;; + 2) + _color="${TEAMS_SKIP_COLOR:-$_color_muted}" + ;; esac _color=$(echo "$_color" | tr -cd 'a-fA-F0-9') diff --git a/notify/xmpp.sh b/notify/xmpp.sh index 580f471e..0ce1119e 100644 --- a/notify/xmpp.sh +++ b/notify/xmpp.sh @@ -71,13 +71,13 @@ _xmpp_bin() { _xmpp_cmnd() { case $(basename "$_XMPP_BIN") in - sendxmpp) - echo "'$_XMPP_BIN' '$XMPP_TO' $XMPP_BIN_ARGS" - ;; - *) - _err "Command $XMPP_BIN is not supported, use sendxmpp." - return 1 - ;; + sendxmpp) + echo "'$_XMPP_BIN' '$XMPP_TO' $XMPP_BIN_ARGS" + ;; + *) + _err "Command $XMPP_BIN is not supported, use sendxmpp." + return 1 + ;; esac } From 284de4ac5df7b42c611fee24c23a9420a7314c65 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:46:52 +0800 Subject: [PATCH 0859/2234] add actions --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..2eab1f34 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,20 @@ + + +name: CI +on:[push, pull_request] + +jobs: + formatCheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Shellcheck + run: sudo apt-get install -y shellcheck + - name: DoShellcheck + run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" + - name: Install shfmt + with: + SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 + run: curl -sSL ${{ SHFMT_URL }} -o ~/shfmt && chmod +x ~/shfmt + - name: shfmt + run: ~/shfmt -l -w -i 2 . ; git diff --exit-code && echo "shfmt OK" From f1338aca846a7842ecff52425d35320330b9efa2 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:49:09 +0800 Subject: [PATCH 0860/2234] fix --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2eab1f34..0a35e000 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,5 @@ - - name: CI -on:[push, pull_request] +on: [push, pull_request] jobs: formatCheck: From cf500cd817cc6cb1419a0a65f58e7814f63b690e Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:50:19 +0800 Subject: [PATCH 0861/2234] fix --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a35e000..af98aca6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" - name: Install shfmt with: - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 + SHFMT_URL: "https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64" run: curl -sSL ${{ SHFMT_URL }} -o ~/shfmt && chmod +x ~/shfmt - name: shfmt run: ~/shfmt -l -w -i 2 . ; git diff --exit-code && echo "shfmt OK" From d9e7cf659e609e5952950479f35ee9369711e0c5 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Mon, 17 Aug 2020 22:52:59 +0800 Subject: [PATCH 0862/2234] Update ci.yml --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af98aca6..eb2f9b46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,8 +11,6 @@ jobs: - name: DoShellcheck run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" - name: Install shfmt - with: - SHFMT_URL: "https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64" - run: curl -sSL ${{ SHFMT_URL }} -o ~/shfmt && chmod +x ~/shfmt + run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt - name: shfmt run: ~/shfmt -l -w -i 2 . ; git diff --exit-code && echo "shfmt OK" From 72235a5f72d97694da7f69ff0ae9ce26478ac34c Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 23:13:00 +0800 Subject: [PATCH 0863/2234] add shellcheck badge --- .github/workflows/{ci.yml => shellcheck.yml} | 2 +- README.md | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) rename .github/workflows/{ci.yml => shellcheck.yml} (94%) diff --git a/.github/workflows/ci.yml b/.github/workflows/shellcheck.yml similarity index 94% rename from .github/workflows/ci.yml rename to .github/workflows/shellcheck.yml index eb2f9b46..529f41e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/shellcheck.yml @@ -1,4 +1,4 @@ -name: CI +name: shellcheck on: [push, pull_request] jobs: diff --git a/README.md b/README.md index e50489dc..a2a40dc9 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) - [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +[![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") [![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") - +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial From de692d3dcce6743641236fa0b720fbaea93648a4 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Tue, 18 Aug 2020 13:14:00 +0300 Subject: [PATCH 0864/2234] Vault deploy hook --- Dockerfile | 1 + deploy/vault.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 deploy/vault.sh diff --git a/Dockerfile b/Dockerfile index f00d03bd..3109ffd2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ RUN apk update -f \ coreutils \ bind-tools \ curl \ + sed \ socat \ tzdata \ oath-toolkit-oathtool \ diff --git a/deploy/vault.sh b/deploy/vault.sh new file mode 100644 index 00000000..ae771967 --- /dev/null +++ b/deploy/vault.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env sh + +# Here is a script to deploy cert to hashicorp vault using curl +# (https://www.vaultproject.io/) +# +# it requires following environment variables: +# +# VAULT_PREFIX - this contains the prefix path in vault +# VAULT_ADDR - vault requires this to find your vault server +# +# additionally, you need to ensure that VAULT_TOKEN is avialable +# to access the vault server + +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +vault_deploy() { + + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + # validate required env vars + if [ -z "$VAULT_PREFIX" ]; then + _err "VAULT_PREFIX needs to be defined (contains prefix path in vault)" + return 1 + fi + + if [ -z "$VAULT_ADDR" ]; then + _err "VAULT_ADDR needs to be defined (contains vault connection address)" + return 1 + fi + + # JSON does not allow multiline strings. + # So replacing new-lines with "\n" here + _ckey=$(sed -z 's/\n/\\n/g' <"$2") + _ccert=$(sed -z 's/\n/\\n/g' <"$3") + _cca=$(sed -z 's/\n/\\n/g' <"$4") + _cfullchain=$(sed -z 's/\n/\\n/g' <"$5") + + URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain" + + if [ -n "$FABIO" ]; then + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" || return 1 + else + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_ccert\"}" "$URL/cert.pem" || return 1 + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_ckey\"}" "$URL/cert.key" || return 1 + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_cca\"}" "$URL/chain.pem" || return 1 + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" || return 1 + fi + +} From d8bd45c2bda3f520bc31d6510f6802ee736bf4a1 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Tue, 18 Aug 2020 13:53:48 +0200 Subject: [PATCH 0865/2234] Fix issue #2833 with backslash in JSON Backslash will be removed form JSON responses for each request and for the initial configuration request --- acme.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 45e0c246..1ba8734a 100755 --- a/acme.sh +++ b/acme.sh @@ -2086,7 +2086,7 @@ _send_signed_request() { _debug2 original "$response" if echo "$responseHeaders" | grep -i "Content-Type: *application/json" >/dev/null 2>&1; then - response="$(echo "$response" | _normalizeJson)" + response="$(echo "$response" | _normalizeJson | _json_decode)" fi _debug2 response "$response" @@ -2503,6 +2503,7 @@ _initAPI() { _err "Can not init api." return 1 fi + response=$(echo "$response" | _json_decode) _debug2 "response" "$response" ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'key-change" *: *"[^"]*"' | cut -d '"' -f 3) @@ -6428,7 +6429,7 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. - --set-default-ca Used with '--server' , to set the default CA to use to use. + --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6470,8 +6471,8 @@ Parameters: --eab-kid EAB_KID Key Identifier for External Account Binding. --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. - - + + These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6502,7 +6503,7 @@ Parameters: --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. - + --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. From ab47bf6451b4c9d01fc8a87eb0c8f2158707e607 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Tue, 18 Aug 2020 14:01:02 +0200 Subject: [PATCH 0866/2234] Removed content for clean pull request --- acme.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/acme.sh b/acme.sh index 1ba8734a..0827ad66 100755 --- a/acme.sh +++ b/acme.sh @@ -6429,7 +6429,6 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. - --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6471,8 +6470,6 @@ Parameters: --eab-kid EAB_KID Key Identifier for External Account Binding. --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. - - These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6503,7 +6500,6 @@ Parameters: --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. - --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. From 2d5f14388e976dac65974ee4284cc67a1378bc9d Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Tue, 18 Aug 2020 14:52:23 +0200 Subject: [PATCH 0867/2234] Revert "Removed content for clean pull request" This reverts commit ab47bf6451b4c9d01fc8a87eb0c8f2158707e607. --- acme.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/acme.sh b/acme.sh index 0827ad66..1ba8734a 100755 --- a/acme.sh +++ b/acme.sh @@ -6429,6 +6429,7 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. + --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6470,6 +6471,8 @@ Parameters: --eab-kid EAB_KID Key Identifier for External Account Binding. --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. + + These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6500,6 +6503,7 @@ Parameters: --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. + --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. From 9021f006f0eacc921da8aeca22b704129dee985e Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 18 Aug 2020 22:22:03 +0800 Subject: [PATCH 0868/2234] update shfmt --- .travis.yml | 2 +- README.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a9785d0c..2741e719 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ services: env: global: - - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64 + - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 install: diff --git a/README.md b/README.md index a2a40dc9..6a42fae6 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ acme.sh is being sponsored by the following tool; please help to support us by t - Support ACME v2 wildcard certs - Simple, powerful and very easy to use. You only need 3 minutes to learn it. - Bash, dash and sh compatible. -- Simplest shell script for Let's Encrypt free certificate client. - Purely written in Shell with no dependencies on python or the official Let's Encrypt client. - Just one script to issue, renew and install your certificates automatically. - DOES NOT require `root/sudoer` access. From 50fefc3bb00f528869b8cdeca29f0333c9602a65 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 18 Aug 2020 23:28:06 +0800 Subject: [PATCH 0869/2234] minor --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 45e0c246..84714324 100755 --- a/acme.sh +++ b/acme.sh @@ -36,8 +36,8 @@ DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST CA_NAMES=" -Letsencrypt.org,letsencrypt -Letsencrypt.org_test,letsencrypt_test,letsencrypttest +LetsEncrypt.org,letsencrypt +LetsEncrypt.org_test,letsencrypt_test,letsencrypttest BuyPass.com,buypass BuyPass.com_test,buypass_test,buypasstest ZeroSSL.com,zerossl From 956114fc4250cae30116f5d998c48ab827272945 Mon Sep 17 00:00:00 2001 From: Alexilmarranen Date: Wed, 19 Aug 2020 00:50:18 +0300 Subject: [PATCH 0870/2234] Issue2336 Add subdomain (3 and more) support Fix for issue in https://github.com/acmesh-official/acme.sh/issues/2336#issuecomment-670522738 --- dnsapi/dns_regru.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index b5729fda..469d8d20 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -33,8 +33,11 @@ dns_regru_add() { fi _debug _domain "$_domain" + _subdomain=$(echo "$fulldomain" | sed -r "s/.$_domain//") + _debug _subdomain "$_subdomain" + _info "Adding TXT record to ${fulldomain}" - _regru_rest POST "zone/add_txt" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json" + _regru_rest POST "zone/add_txt" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22${_subdomain}%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json" if ! _contains "${response}" 'error'; then return 0 @@ -64,8 +67,11 @@ dns_regru_rm() { fi _debug _domain "$_domain" + _subdomain=$(echo "$fulldomain" | sed -r "s/.$_domain//") + _debug _subdomain "$_subdomain" + _info "Deleting resource record $fulldomain" - _regru_rest POST "zone/remove_record" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json" + _regru_rest POST "zone/remove_record" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22${_subdomain}%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json" if ! _contains "${response}" 'error'; then return 0 From b7b01999d9616c44e006b41ac78143efadb875b0 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Thu, 20 Aug 2020 09:13:44 +0800 Subject: [PATCH 0871/2234] fix preferred chain for renewal fix https://github.com/acmesh-official/acme.sh/issues/3116 --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index c750757c..d1a08e6c 100755 --- a/acme.sh +++ b/acme.sh @@ -5049,6 +5049,7 @@ renew() { Le_PreHook="$(_readdomainconf Le_PreHook)" Le_PostHook="$(_readdomainconf Le_PostHook)" Le_RenewHook="$(_readdomainconf Le_RenewHook)" + Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)" issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain" res="$?" if [ "$res" != "0" ]; then From a70f377388dfab5163f99fbf456b73aecddf837e Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:18:53 +0800 Subject: [PATCH 0872/2234] add pebble --- .github/workflows/PebbleStrict.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/PebbleStrict.yml diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml new file mode 100644 index 00000000..20670eb2 --- /dev/null +++ b/.github/workflows/PebbleStrict.yml @@ -0,0 +1,25 @@ +name: PebbleStrict +on: [push, pull_request] + +jobs: + formatCheck: + runs-on: ubuntu-latest + env: + TestingDomain: example.com + TestingAltDomains: www.example.com + ACME_DIRECTORY: https://localhost:14000/dir + HTTPS_INSECURE: 1 + Le_HTTPPort: 5002 + TEST_LOCAL: 1 + TEST_CA: todo + + steps: + - uses: actions/checkout@v2 + - name: Run Pebble + run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d + - name: Set up Pebble + run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 + - name: Clone acmetest + run: git clone https://github.com/acmesh-official/acmetest.git && mv acme.sh acmetest/ + - name: Run acmetest + run: cd acmetest && ./letest.sh \ No newline at end of file From c131b63852b66305cb13f4d51acd424057a440f4 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:32:22 +0800 Subject: [PATCH 0873/2234] typo --- .github/workflows/PebbleStrict.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 20670eb2..1b31d791 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -2,7 +2,7 @@ name: PebbleStrict on: [push, pull_request] jobs: - formatCheck: + PebbleStrict: runs-on: ubuntu-latest env: TestingDomain: example.com From edd76f595a626a9e6d0b8e35ae3075d8ae84255e Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:37:23 +0800 Subject: [PATCH 0874/2234] fix dir --- .github/workflows/PebbleStrict.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 1b31d791..a1c56724 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run Pebble - run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d + run: cd "$GITHUB_WORKSPACE" && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d - name: Set up Pebble run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 - name: Clone acmetest - run: git clone https://github.com/acmesh-official/acmetest.git && mv acme.sh acmetest/ + run: cd "$GITHUB_WORKSPACE" && git clone https://github.com/acmesh-official/acmetest.git && mv acme.sh acmetest/ - name: Run acmetest run: cd acmetest && ./letest.sh \ No newline at end of file From b805ea9bf6155445bcba330f5a527ecf1893427c Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:52:42 +0800 Subject: [PATCH 0875/2234] fix dir --- .github/workflows/PebbleStrict.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index a1c56724..77ba5f3d 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run Pebble - run: cd "$GITHUB_WORKSPACE" && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d + run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d - name: Set up Pebble run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 - name: Clone acmetest - run: cd "$GITHUB_WORKSPACE" && git clone https://github.com/acmesh-official/acmetest.git && mv acme.sh acmetest/ + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd acmetest && ./letest.sh \ No newline at end of file + run: cd ../acmetest && ./letest.sh \ No newline at end of file From 3cd85fb3950c5140ed0308f8a05c30b17f5ec64a Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:54:27 +0800 Subject: [PATCH 0876/2234] install socat --- .github/workflows/PebbleStrict.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 77ba5f3d..836437fa 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -15,6 +15,8 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat - name: Run Pebble run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d - name: Set up Pebble From 7ddc2ccf1ab5ae19ae5671c74e4afbc09d294eaf Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 21:06:21 +0800 Subject: [PATCH 0877/2234] add TEST_CA --- .github/workflows/PebbleStrict.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 836437fa..a339f727 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -11,7 +11,7 @@ jobs: HTTPS_INSECURE: 1 Le_HTTPPort: 5002 TEST_LOCAL: 1 - TEST_CA: todo + TEST_CA: "Pebble Intermediate CA" steps: - uses: actions/checkout@v2 From c1668c9bdba0c860bb93f39e9e954bb80839e569 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 21:26:42 +0800 Subject: [PATCH 0878/2234] add pebble badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6a42fae6..3012f676 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") [![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial From 966c744992b8d00819ec4225cc4bb8eb45cf7931 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 21:41:36 +0800 Subject: [PATCH 0879/2234] minor, just move badge position --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3012f676..e0fcd679 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) +# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) + [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") [![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) + acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial From d9f9477a52d3e5e937b1e4b56a9eec7113e84e89 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Thu, 20 Aug 2020 21:44:37 +0800 Subject: [PATCH 0880/2234] move badge move badge --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e0fcd679..bf6ea06c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) +# An ACME Shell script: acme.sh +[![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) From c0fbe8237bbd4df2a32636e383419732a5b1b104 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Wed, 19 Aug 2020 13:33:08 +0200 Subject: [PATCH 0881/2234] reformat usage message for consistency & clarity --- acme.sh | 137 +++++++++++++++++++++++++------------------------------- 1 file changed, 62 insertions(+), 75 deletions(-) diff --git a/acme.sh b/acme.sh index d1a08e6c..a00e314f 100755 --- a/acme.sh +++ b/acme.sh @@ -6402,8 +6402,8 @@ showhelp() { version echo "Usage: $PROJECT_ENTRY command ...[parameters].... Commands: - --help, -h Show this help message. - --version, -v Show version info. + -h, --help Show this help message. + -v, --version Show version info. --install Install $PROJECT_NAME to your system. --uninstall Uninstall $PROJECT_NAME, and uninstall the cron job. --upgrade Upgrade $PROJECT_NAME to the latest code from $PROJECT. @@ -6411,7 +6411,7 @@ Commands: --signcsr Issue a cert from an existing csr. --deploy Deploy the cert to your server. --install-cert Install the issued cert to apache/nginx or any other server. - --renew, -r Renew a cert. + -r, --renew Renew a cert. --renew-all Renew all the certs. --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. @@ -6427,117 +6427,104 @@ Commands: --deactivate-account Deactivate the account. --create-account-key Create an account private key, professional use. --create-domain-key Create an domain private key, professional use. - --createCSR, -ccsr Create CSR , professional use. + -ccsr, --createCSR Create CSR, professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: - --domain, -d domain.tld Specifies a domain, used to issue, renew or revoke etc. - --challenge-alias domain.tld The challenge domain alias for DNS alias mode. + -d, --domain Specifies a domain, used to issue, renew or revoke etc. + --challenge-alias The challenge domain alias for DNS alias mode. See: $_DNS_ALIAS_WIKI - - --domain-alias domain.tld The domain alias for DNS alias mode. + --domain-alias The domain alias for DNS alias mode. See: $_DNS_ALIAS_WIKI - - --preferred-chain CHAIN If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. + --preferred-chain If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used. (default: empty) See: $_PREFERRED_CHAIN_WIKI - - --force, -f Used to force to install or force to renew a cert immediately. - --staging, --test Use staging server, just for test. - --debug Output debug info. + -f, --force Force install, force cert renewal or override sudo restrictions. + --staging, --test Use staging server, for testing. + --debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted. --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for security. - - --webroot, -w /path/to/webroot Specifies the web root folder for web root mode. + -w, --webroot Specifies the web root folder for web root mode. --standalone Use standalone mode. --alpn Use standalone alpn mode. --stateless Use stateless mode. See: $_STATELESS_WIKI - --apache Use apache mode. - --dns [dns_hook] Use dns mode or dns api. + --dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted. See: $_DNS_API_WIKI - - --dnssleep 300 The time in seconds to wait for all the txt records to propagate in dns api mode. + --dnssleep The time in seconds to wait for all the txt records to propagate in dns api mode. It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically. - - --keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. - --accountkeylength, -ak [2048] Specifies the account key length: 2048, 3072, 4096 - --log [/path/to/logfile] Specifies the log file. The default is: \"$DEFAULT_LOG_FILE\" if you don't give a file path here. - --log-level 1|2 Specifies the log level, default is 1. - --syslog [0|3|6|7] Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. - - --eab-kid EAB_KID Key Identifier for External Account Binding. - --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. + -k, --keylength Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. + -ak, --accountkeylength Specifies the account key length: 2048, 3072, 4096 + --log [/path/to/logfile] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted. + --log-level <1|2> Specifies the log level, default is 1. + --syslog <0|3|6|7> Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. + --eab-kid Key Identifier for External Account Binding. + --eab-hmac-key HMAC key for External Account Binding. These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: - --cert-file After issue/renew, the cert will be copied to this path. - --key-file After issue/renew, the key will be copied to this path. - --ca-file After issue/renew, the intermediate cert will be copied to this path. - --fullchain-file After issue/renew, the fullchain cert will be copied to this path. + --cert-file Path to copy the cert file to after issue/renew.. + --key-file Path to copy the key file to after issue/renew. + --ca-file Path to copy the intermediate cert file to after issue/renew. + --fullchain-file Path to copy the fullchain cert file to after issue/renew. - --reloadcmd \"service nginx reload\" After issue/renew, it's used to reload the server. + --reloadcmd Command to execute after issue/renew to reload the server. - --server SERVER ACME Directory Resource URI. (default: $DEFAULT_CA) + --server ACME Directory Resource URI. (default: $DEFAULT_CA) See: $_SERVER_WIKI - --accountconf Specifies a customized account config file. - --home Specifies the home dir for $PROJECT_NAME. - --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. - --config-home Specifies the home dir to save all the configurations. - --useragent Specifies the user agent string. it will be saved for future use too. - --accountemail, -m Specifies the account email, only valid for the '--install' and '--update-account' command. - --accountkey Specifies the account key path, only valid for the '--install' command. - --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. - --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. - --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer. - --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses. + --accountconf Specifies a customized account config file. + --home Specifies the home dir for $PROJECT_NAME. + --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. + --config-home Specifies the home dir to save all the configurations. + --useragent Specifies the user agent string. it will be saved for future use too. + -m, --accountemail Specifies the account email, only valid for the '--install' and '--update-account' command. + --accountkey Specifies the account key path, only valid for the '--install' command. + --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. + --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. + --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer. + --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses. --listraw Only used for '--list' command, list the certs in raw format. - --stopRenewOnError, -se Only valid for '--renew-all' command. Stop if one cert has error in renewal. + -se, --stopRenewOnError Only valid for '--renew-all' command. Stop if one cert has error in renewal. --insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted. - --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. - --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. + --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. + --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. - --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' - --csr Specifies the input csr. - --pre-hook Command to be run before obtaining any certificates. - --post-hook Command to be run after attempting to obtain/renew certificates. No matter the obtain/renew is success or failed. - --renew-hook Command to be run once for each successfully renewed certificate. - --deploy-hook The hook file to deploy cert - --ocsp-must-staple, --ocsp Generate ocsp must Staple extension. - --always-force-new-domain-key Generate new domain key when renewal. Otherwise, the domain key is not changed by default. - --auto-upgrade [0|1] Valid for '--upgrade' command, indicating whether to upgrade automatically in future. + --csr Specifies the input csr. + --pre-hook Command to be run before obtaining any certificates. + --post-hook Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed. + --renew-hook Command to be run after each successfully renewed certificate. + --deploy-hook The hook file to deploy cert + --ocsp, --ocsp-must-staple Generate OCSP-Must-Staple extension. + --always-force-new-domain-key Generate new domain key on renewal. Otherwise, the domain key is not changed by default. + --auto-upgrade [0|1] Valid for '--upgrade' command, indicating whether to upgrade automatically in future. Defaults to 1 if argument is omitted. --listen-v4 Force standalone/tls server to listen at ipv4. --listen-v6 Force standalone/tls server to listen at ipv6. - --openssl-bin Specifies a custom openssl bin location. + --openssl-bin Specifies a custom openssl bin location. --use-wget Force to use wget, if you have both curl and wget installed. - --yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode. + --yes-I-know-dns-manual-mode-enough-go-ahead-please Force use ofdns manual mode. See: $_DNS_MANUAL_WIKI - - --branch, -b Only valid for '--upgrade' command, specifies the branch name to upgrade to. - - --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. - 0: disabled, no notification will be sent. - 1: send notifications only when there is an error. - 2: send notifications when a cert is successfully renewed, or there is an error. - 3: send notifications when a cert is skipped, renewed, or error. - - --notify-mode 0|1 Set notification mode. Default value is $NOTIFY_MODE_DEFAULT. - 0: Bulk mode. Send all the domain's notifications in one message(mail). - 1: Cert mode. Send a message for every single cert. - - --notify-hook [hookname] Set the notify hook - --revoke-reason [0-10] The reason for '--revoke' command. + -b, --branch Only valid for '--upgrade' command, specifies the branch name to upgrade to. + --notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. + 0: disabled, no notification will be sent. + 1: send notifications only when there is an error. + 2: send notifications when a cert is successfully renewed, or there is an error. + 3: send notifications when a cert is skipped, renewed, or error. + --notify-mode <0|1> Set notification mode. Default value is $NOTIFY_MODE_DEFAULT. + 0: Bulk mode. Send all the domain's notifications in one message(mail). + 1: Cert mode. Send a message for every single cert. + --notify-hook Set the notify hook + --revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command. See: $_REVOKE_WIKI From d81369d63a79e3b0ea41d772b1dcafd332efa642 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Wed, 19 Aug 2020 17:37:51 +0200 Subject: [PATCH 0882/2234] add hyphenated options, fix wrong -ccr in usage() --- acme.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index a00e314f..76c55ca2 100755 --- a/acme.sh +++ b/acme.sh @@ -6410,27 +6410,27 @@ Commands: --issue Issue a cert. --signcsr Issue a cert from an existing csr. --deploy Deploy the cert to your server. - --install-cert Install the issued cert to apache/nginx or any other server. + -i, --install-cert Install the issued cert to apache/nginx or any other server. -r, --renew Renew a cert. --renew-all Renew all the certs. --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. --list List all the certs. - --showcsr Show the content of a csr. + --show-csr Show the content of a csr. --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. --uninstall-cronjob Uninstall the cron job. The 'uninstall' command can do this automatically. --cron Run cron job to renew all the certs. - --toPkcs Export the certificate and key to a pfx file. - --toPkcs8 Convert to pkcs8 format. + --to-pkcs Export the certificate and key to a pfx file. + --to-pkcs8 Convert to pkcs8 format. --update-account Update account info. --register-account Register account key. --deactivate-account Deactivate the account. --create-account-key Create an account private key, professional use. --create-domain-key Create an domain private key, professional use. - -ccsr, --createCSR Create CSR, professional use. + -ccr, --create-csr Create CSR, professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. - --set-default-ca Used with '--server' , to set the default CA to use to use. + --set-default-ca Used with '--server', to set the default CA to use to use. Parameters: @@ -6490,14 +6490,14 @@ Parameters: --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer. --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses. --listraw Only used for '--list' command, list the certs in raw format. - -se, --stopRenewOnError Only valid for '--renew-all' command. Stop if one cert has error in renewal. + -se, --stop-renew-on-error Only valid for '--renew-all' command. Stop if one cert has error in renewal. --insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted. --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. - --no-color Do not output color text. + --nocolor Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' --csr Specifies the input csr. @@ -6817,10 +6817,10 @@ _process() { --cron) _CMD="cron" ;; - --toPkcs) + --toPkcs | --to-pkcs) _CMD="toPkcs" ;; - --toPkcs8) + --toPkcs8 | --to-pkcs8) _CMD="toPkcs8" ;; --createAccountKey | --createaccountkey | -cak | --create-account-key) @@ -6829,7 +6829,7 @@ _process() { --createDomainKey | --createdomainkey | -cdk | --create-domain-key) _CMD="createDomainKey" ;; - --createCSR | --createcsr | -ccr) + --createCSR | --createcsr | -ccr | --create-csr) _CMD="createCSR" ;; --deactivate) @@ -7074,7 +7074,7 @@ _process() { --listraw) _listraw="raw" ;; - --stopRenewOnError | --stoprenewonerror | -se) + --stopRenewOnError | --stoprenewonerror | -se | --stop-renew-on-error) _stopRenewOnError="1" ;; --insecure) From 7decf768837d51b41bf474009e8e54368d4b4caf Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 08:33:37 +0200 Subject: [PATCH 0883/2234] group commands logically, rearrange option forms in _process() Commands have been reordered in showhelp() to a more consistent grouping, help > version > install > certs > csr > account > cron > other All option alternatives in _process() case statement have been reordered toshow the canonical variants first, legacy variants after. --- acme.sh | 58 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/acme.sh b/acme.sh index 76c55ca2..fc4b7e7c 100755 --- a/acme.sh +++ b/acme.sh @@ -6408,7 +6408,6 @@ Commands: --uninstall Uninstall $PROJECT_NAME, and uninstall the cron job. --upgrade Upgrade $PROJECT_NAME to the latest code from $PROJECT. --issue Issue a cert. - --signcsr Issue a cert from an existing csr. --deploy Deploy the cert to your server. -i, --install-cert Install the issued cert to apache/nginx or any other server. -r, --renew Renew a cert. @@ -6416,20 +6415,21 @@ Commands: --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. --list List all the certs. - --show-csr Show the content of a csr. - --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. - --uninstall-cronjob Uninstall the cron job. The 'uninstall' command can do this automatically. - --cron Run cron job to renew all the certs. --to-pkcs Export the certificate and key to a pfx file. --to-pkcs8 Convert to pkcs8 format. + --sign-csr Issue a cert from an existing csr. + --show-csr Show the content of a csr. + -ccr, --create-csr Create CSR, professional use. + --create-domain-key Create an domain private key, professional use. --update-account Update account info. --register-account Register account key. --deactivate-account Deactivate the account. --create-account-key Create an account private key, professional use. - --create-domain-key Create an domain private key, professional use. - -ccr, --create-csr Create CSR, professional use. - --deactivate Deactivate the domain authz, professional use. + --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. + --uninstall-cronjob Uninstall the cron job. The 'uninstall' command can do this automatically. + --cron Run cron job to renew all the certs. --set-notify Set the cron notification hook, level or mode. + --deactivate Deactivate the domain authz, professional use. --set-default-ca Used with '--server', to set the default CA to use to use. @@ -6784,19 +6784,19 @@ _process() { --deploy) _CMD="deploy" ;; - --signcsr) + --sign-csr | --signcsr) _CMD="signcsr" ;; - --showcsr) + --show-csr | --showcsr) _CMD="showcsr" ;; - --installcert | -i | --install-cert) + -i | --install-cert | --installcert) _CMD="installcert" ;; --renew | -r) _CMD="renew" ;; - --renewAll | --renewall | --renew-all) + --renew-all | --renewAll | --renewall) _CMD="renewAll" ;; --revoke) @@ -6808,37 +6808,37 @@ _process() { --list) _CMD="list" ;; - --installcronjob | --install-cronjob) + --install-cronjob | --installcronjob) _CMD="installcronjob" ;; - --uninstallcronjob | --uninstall-cronjob) + --uninstall-cronjob | --uninstallcronjob) _CMD="uninstallcronjob" ;; --cron) _CMD="cron" ;; - --toPkcs | --to-pkcs) + --to-pkcs | --toPkcs) _CMD="toPkcs" ;; - --toPkcs8 | --to-pkcs8) + --to-pkcs8 | --toPkcs8) _CMD="toPkcs8" ;; - --createAccountKey | --createaccountkey | -cak | --create-account-key) + --create-account-key | --createAccountKey | --createaccountkey | -cak) _CMD="createAccountKey" ;; - --createDomainKey | --createdomainkey | -cdk | --create-domain-key) + --create-domain-key | --createDomainKey | --createdomainkey | -cdk) _CMD="createDomainKey" ;; - --createCSR | --createcsr | -ccr | --create-csr) + -ccr | --create-csr | --createCSR | --createcsr) _CMD="createCSR" ;; --deactivate) _CMD="deactivate" ;; - --updateaccount | --update-account) + --update-account | --updateaccount) _CMD="updateaccount" ;; - --registeraccount | --register-account) + --register-account | --registeraccount) _CMD="registeraccount" ;; --deactivate-account) @@ -6850,7 +6850,7 @@ _process() { --set-default-ca) _CMD="setdefaultca" ;; - --domain | -d) + -d | --domain) _dvalue="$2" if [ "$_dvalue" ]; then @@ -6881,7 +6881,7 @@ _process() { shift ;; - --force | -f) + -f | --force) FORCE="1" ;; --staging | --test) @@ -6903,7 +6903,7 @@ _process() { --output-insecure) export OUTPUT_INSECURE=1 ;; - --webroot | -w) + -w | --webroot) wvalue="$2" if [ -z "$_webroot" ]; then _webroot="$wvalue" @@ -6993,7 +6993,7 @@ _process() { _keylength="$2" shift ;; - --accountkeylength | -ak) + -ak | --accountkeylength) _accountkeylength="$2" shift ;; @@ -7031,7 +7031,7 @@ _process() { LE_WORKING_DIR="$2" shift ;; - --certhome | --cert-home) + --cert-home | --certhome) _certhome="$2" CERT_HOME="$_certhome" shift @@ -7046,7 +7046,7 @@ _process() { USER_AGENT="$_useragent" shift ;; - --accountemail | -m) + -m | --accountemail) _accountemail="$2" ACCOUNT_EMAIL="$_accountemail" shift @@ -7074,7 +7074,7 @@ _process() { --listraw) _listraw="raw" ;; - --stopRenewOnError | --stoprenewonerror | -se | --stop-renew-on-error) + -se | --stop-renew-on-error | --stopRenewOnError | --stoprenewonerror) _stopRenewOnError="1" ;; --insecure) @@ -7097,7 +7097,7 @@ _process() { --noprofile) _noprofile="1" ;; - --no-color) + --nocolor | --no-color) export ACME_NO_COLOR=1 ;; --force-color) From b086afb2720731176ce63823409d4287516bbe24 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 09:00:58 +0200 Subject: [PATCH 0884/2234] fix some more issues in showhelp() --- acme.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index fc4b7e7c..3ac44d35 100755 --- a/acme.sh +++ b/acme.sh @@ -6447,7 +6447,7 @@ Parameters: --debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted. --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for security. - -w, --webroot Specifies the web root folder for web root mode. + -w, --webroot Specifies the web root folder for web root mode. --standalone Use standalone mode. --alpn Use standalone alpn mode. --stateless Use stateless mode. @@ -6459,7 +6459,7 @@ Parameters: It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically. -k, --keylength Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. -ak, --accountkeylength Specifies the account key length: 2048, 3072, 4096 - --log [/path/to/logfile] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted. + --log [file] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted. --log-level <1|2> Specifies the log level, default is 1. --syslog <0|3|6|7> Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. --eab-kid Key Identifier for External Account Binding. @@ -6468,11 +6468,10 @@ Parameters: These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: - --cert-file Path to copy the cert file to after issue/renew.. - --key-file Path to copy the key file to after issue/renew. - --ca-file Path to copy the intermediate cert file to after issue/renew. - --fullchain-file Path to copy the fullchain cert file to after issue/renew. - + --cert-file Path to copy the cert file to after issue/renew.. + --key-file Path to copy the key file to after issue/renew. + --ca-file Path to copy the intermediate cert file to after issue/renew. + --fullchain-file Path to copy the fullchain cert file to after issue/renew. --reloadcmd Command to execute after issue/renew to reload the server. --server ACME Directory Resource URI. (default: $DEFAULT_CA) From e7a6ff39f9b3ae514165d4773c326b68bd6a67d1 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 09:14:15 +0200 Subject: [PATCH 0885/2234] fix wrong indentation --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3ac44d35..990e422b 100755 --- a/acme.sh +++ b/acme.sh @@ -7045,7 +7045,7 @@ _process() { USER_AGENT="$_useragent" shift ;; - -m | --accountemail) + -m | --accountemail) _accountemail="$2" ACCOUNT_EMAIL="$_accountemail" shift From 58150f5dcd62a99eec2f4565d581e12358fbcf05 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 17:17:30 +0200 Subject: [PATCH 0886/2234] change --pkcs to --pkcs12 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 990e422b..22b5a580 100755 --- a/acme.sh +++ b/acme.sh @@ -6415,7 +6415,7 @@ Commands: --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. --list List all the certs. - --to-pkcs Export the certificate and key to a pfx file. + --to-pkcs12 Export the certificate and key to a pfx file. --to-pkcs8 Convert to pkcs8 format. --sign-csr Issue a cert from an existing csr. --show-csr Show the content of a csr. @@ -6816,7 +6816,7 @@ _process() { --cron) _CMD="cron" ;; - --to-pkcs | --toPkcs) + --to-pkcs12 | --toPkcs) _CMD="toPkcs" ;; --to-pkcs8 | --toPkcs8) From 07fdb087dccd9df358c2bdfef9b61c4208408fe7 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 17:23:40 +0200 Subject: [PATCH 0887/2234] fix typo --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 22b5a580..87cb927f 100755 --- a/acme.sh +++ b/acme.sh @@ -6511,7 +6511,7 @@ Parameters: --listen-v6 Force standalone/tls server to listen at ipv6. --openssl-bin Specifies a custom openssl bin location. --use-wget Force to use wget, if you have both curl and wget installed. - --yes-I-know-dns-manual-mode-enough-go-ahead-please Force use ofdns manual mode. + --yes-I-know-dns-manual-mode-enough-go-ahead-please Force use of dns manual mode. See: $_DNS_MANUAL_WIKI -b, --branch Only valid for '--upgrade' command, specifies the branch name to upgrade to. --notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. From 2910be82a4d5684490db30b2d2be6cdb8a17f086 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 09:54:47 +0200 Subject: [PATCH 0888/2234] revert change of --no-color option --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 87cb927f..d2424dee 100755 --- a/acme.sh +++ b/acme.sh @@ -6496,7 +6496,7 @@ Parameters: --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. - --nocolor Do not output color text. + --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' --csr Specifies the input csr. @@ -7096,7 +7096,7 @@ _process() { --noprofile) _noprofile="1" ;; - --nocolor | --no-color) + --no-color) export ACME_NO_COLOR=1 ;; --force-color) From 1521199e443bddf8e13eb695af3090c6d0a1586a Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 09:56:57 +0200 Subject: [PATCH 0889/2234] add hidden alias --to-pkcs for --to-pkcs12 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d2424dee..6719d1e6 100755 --- a/acme.sh +++ b/acme.sh @@ -6816,7 +6816,7 @@ _process() { --cron) _CMD="cron" ;; - --to-pkcs12 | --toPkcs) + --to-pkcs12 | --to-pkcs | --toPkcs) _CMD="toPkcs" ;; --to-pkcs8 | --toPkcs8) From a48c22d14fab2f29c95eefc04460adf4e3f7888a Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 09:58:58 +0200 Subject: [PATCH 0890/2234] add missing blank lines after links to wiki --- acme.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/acme.sh b/acme.sh index 6719d1e6..3679cc0b 100755 --- a/acme.sh +++ b/acme.sh @@ -6437,11 +6437,14 @@ Parameters: -d, --domain Specifies a domain, used to issue, renew or revoke etc. --challenge-alias The challenge domain alias for DNS alias mode. See: $_DNS_ALIAS_WIKI + --domain-alias The domain alias for DNS alias mode. See: $_DNS_ALIAS_WIKI + --preferred-chain If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used. (default: empty) See: $_PREFERRED_CHAIN_WIKI + -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. @@ -6452,9 +6455,11 @@ Parameters: --alpn Use standalone alpn mode. --stateless Use stateless mode. See: $_STATELESS_WIKI + --apache Use apache mode. --dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted. See: $_DNS_API_WIKI + --dnssleep The time in seconds to wait for all the txt records to propagate in dns api mode. It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically. -k, --keylength Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. @@ -6513,6 +6518,7 @@ Parameters: --use-wget Force to use wget, if you have both curl and wget installed. --yes-I-know-dns-manual-mode-enough-go-ahead-please Force use of dns manual mode. See: $_DNS_MANUAL_WIKI + -b, --branch Only valid for '--upgrade' command, specifies the branch name to upgrade to. --notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. 0: disabled, no notification will be sent. From 6fbf33c8f4f9a643f83caf279ff8ca292598f4d7 Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 21 Aug 2020 09:54:24 +0100 Subject: [PATCH 0891/2234] More changes --- .github/workflows/dockerhub.yml | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 8c277827..fc1db8e5 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -2,7 +2,12 @@ name: Build DockerHub on: push: - branches: [ master, dev ] + branches: + - master + - dev + - temp + tags: + - '*' jobs: build: @@ -12,23 +17,21 @@ jobs: uses: actions/checkout@v2 - name: install buildx id: buildx - uses: crazy-max/ghaction-docker-buildx@v1 + uses: crazy-max/ghaction-docker-buildx@v3 with: - version: latest + buildx-version: latest + qemu-version: latest - name: login to docker hub run: | echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - - name: build and push the image (master branch) + - name: build and push the image run: | + DOCKER_IMAGE_TAG=$(echo ${GITHUB_REF#refs/heads/} | sed 's/^master$/latest/') + [ "$DOCKER_IMAGE" == "latest" ] && AUTO_UPGRADE="1" || AUTO_UPGRADE="" + docker buildx build \ - --push \ - --tag neilpang/acme.sh:latest \ + --output "type=image,push=true" \ + --tag ei99070/acme.sh:${DOCKER_IMAGE_TAG} \ + --tag ei99070/acme.sh:${GITHUB_SHA} \ + --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . - if: ${{ github.ref == 'refs/heads/master' }} - - name: build and push the image (dev branch) - run: | - docker buildx build \ - --push \ - --tag neilpang/acme.sh:dev \ - --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . - if: ${{ github.ref == 'refs/heads/dev' }} From abc62b9348d6d01a0da8c17b6d6afe9e42ec84df Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 21 Aug 2020 10:34:43 +0100 Subject: [PATCH 0892/2234] more --- .github/workflows/dockerhub.yml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index fc1db8e5..4a5efc38 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -26,12 +26,25 @@ jobs: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - name: build and push the image run: | - DOCKER_IMAGE_TAG=$(echo ${GITHUB_REF#refs/heads/} | sed 's/^master$/latest/') - [ "$DOCKER_IMAGE" == "latest" ] && AUTO_UPGRADE="1" || AUTO_UPGRADE="" + DOCKER_IMAGE=ei99070/acme.sh + + if [[ $GITHUB_REF == refs/tags/* ]]; then + BRANCH_TAG=${GITHUB_REF#refs/tags/} + AUTO_UPGRADE=1 + fi + + if [[ $GITHUB_REF == refs/heads/* ]]; then + BRANCH_TAG=${GITHUB_REF#refs/heads/} + + if [[ $BRANCH_TAG == master ]]; then + BRANCH_TAG=latest + AUTO_UPGRADE=1 + fi + fi docker buildx build \ + --tag ${DOCKER_IMAGE}:${BRANCH_TAG} \ + --tag ${DOCKER_IMAGE}:${GITHUB_SHA} \ --output "type=image,push=true" \ - --tag ei99070/acme.sh:${DOCKER_IMAGE_TAG} \ - --tag ei99070/acme.sh:${GITHUB_SHA} \ --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . From fcb6198a823da64f1e02815f4d994d05bceb9fa0 Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 21 Aug 2020 10:55:07 +0100 Subject: [PATCH 0893/2234] More updated following PR comments --- .github/workflows/dockerhub.yml | 15 ++++++--------- Dockerfile | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index bd96a8de..cf65f4a6 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -3,8 +3,7 @@ name: Build DockerHub on: push: branches: - - master - - dev + - '*' tags: - '*' @@ -28,22 +27,20 @@ jobs: DOCKER_IMAGE=neilpang/acme.sh if [[ $GITHUB_REF == refs/tags/* ]]; then - BRANCH_TAG=${GITHUB_REF#refs/tags/} - AUTO_UPGRADE=1 + DOCKER_IMAGE_TAG=${GITHUB_REF#refs/tags/} fi if [[ $GITHUB_REF == refs/heads/* ]]; then - BRANCH_TAG=${GITHUB_REF#refs/heads/} + DOCKER_IMAGE_TAG=${GITHUB_REF#refs/heads/} - if [[ $BRANCH_TAG == master ]]; then - BRANCH_TAG=latest + if [[ $DOCKER_IMAGE_TAG == master ]]; then + DOCKER_IMAGE_TAG=latest AUTO_UPGRADE=1 fi fi docker buildx build \ - --tag ${DOCKER_IMAGE}:${BRANCH_TAG} \ - --tag ${DOCKER_IMAGE}:${GITHUB_SHA} \ + --tag ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG} \ --output "type=image,push=true" \ --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . diff --git a/Dockerfile b/Dockerfile index f00d03bd..a61c6ab4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ RUN apk update -f \ ENV LE_CONFIG_HOME /acme.sh -ENV AUTO_UPGRADE 1 +ARG AUTO_UPGRADE=1 #Install ADD ./ /install_acme.sh/ From 05477c1a0312215615241871c42b4376f9565027 Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 21 Aug 2020 11:03:53 +0100 Subject: [PATCH 0894/2234] Fixes Dockerfile --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index a61c6ab4..4cea3c06 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,6 +17,8 @@ ENV LE_CONFIG_HOME /acme.sh ARG AUTO_UPGRADE=1 +ENV AUTO_UPGRADE $AUTO_UPGRADE + #Install ADD ./ /install_acme.sh/ RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/ From 2e87e64bd1036b2d98f831a5a686003303b0c350 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 12:12:30 +0200 Subject: [PATCH 0895/2234] update individual Usage: messages to match showHelp --- acme.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/acme.sh b/acme.sh index 3679cc0b..168ab8da 100755 --- a/acme.sh +++ b/acme.sh @@ -1375,7 +1375,7 @@ toPkcs() { domain="$1" pfxPassword="$2" if [ -z "$domain" ]; then - _usage "Usage: $PROJECT_ENTRY --toPkcs -d domain [--password pfx-password]" + _usage "Usage: $PROJECT_ENTRY --to-pkcs12 --domain [--password ] [--ecc]" return 1 fi @@ -1396,7 +1396,7 @@ toPkcs8() { domain="$1" if [ -z "$domain" ]; then - _usage "Usage: $PROJECT_ENTRY --toPkcs8 -d domain [--ecc]" + _usage "Usage: $PROJECT_ENTRY --to-pkcs8 --domain [--ecc]" return 1 fi @@ -1416,7 +1416,7 @@ toPkcs8() { createAccountKey() { _info "Creating account key" if [ -z "$1" ]; then - _usage "Usage: $PROJECT_ENTRY --createAccountKey --accountkeylength 2048" + _usage "Usage: $PROJECT_ENTRY --create-account-key [--accountkeylength ]" return fi @@ -1459,7 +1459,7 @@ _create_account_key() { createDomainKey() { _info "Creating domain key" if [ -z "$1" ]; then - _usage "Usage: $PROJECT_ENTRY --createDomainKey -d domain.com [ --keylength 2048 ]" + _usage "Usage: $PROJECT_ENTRY --create-domain-key --domain [--keylength ]" return fi @@ -1499,7 +1499,7 @@ createDomainKey() { createCSR() { _info "Creating csr" if [ -z "$1" ]; then - _usage "Usage: $PROJECT_ENTRY --createCSR -d domain1.com [-d domain2.com -d domain3.com ... ]" + _usage "Usage: $PROJECT_ENTRY --create-csr --domain [--domain ...]" return fi @@ -2888,7 +2888,7 @@ Allow from all if _restoreApache; then _err "The apache config file is restored." else - _err "Sorry, The apache config file can not be restored, please report bug." + _err "Sorry, the apache config file can not be restored, please report bug." fi return 1 fi @@ -4012,7 +4012,7 @@ _match_issuer() { #webroot, domain domainlist keylength issue() { if [ -z "$2" ]; then - _usage "Usage: $PROJECT_ENTRY --issue -d a.com -w /path/to/webroot/a.com/ " + _usage "Usage: $PROJECT_ENTRY --issue --domain --webroot " return 1 fi if [ -z "$1" ]; then @@ -4993,7 +4993,7 @@ _split_cert_chain() { renew() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then - _usage "Usage: $PROJECT_ENTRY --renew -d domain.com [--ecc]" + _usage "Usage: $PROJECT_ENTRY --renew --domain [--ecc]" return 1 fi @@ -5003,7 +5003,7 @@ renew() { _info "$(__green "Renew: '$Le_Domain'")" if [ ! -f "$DOMAIN_CONF" ]; then - _info "'$Le_Domain' is not a issued domain, skip." + _info "'$Le_Domain' is not an issued domain, skip." return $RENEW_SKIP fi @@ -5082,7 +5082,7 @@ renewAll() { for di in "${CERT_HOME}"/*.*/; do _debug di "$di" if ! [ -d "$di" ]; then - _debug "Not directory, skip: $di" + _debug "Not a directory, skip: $di" continue fi d=$(basename "$di") @@ -5185,7 +5185,7 @@ signcsr() { _csrfile="$1" _csrW="$2" if [ -z "$_csrfile" ] || [ -z "$_csrW" ]; then - _usage "Usage: $PROJECT_ENTRY --signcsr --csr mycsr.csr -w /path/to/webroot/a.com/ " + _usage "Usage: $PROJECT_ENTRY --sign-csr --csr --webroot " return 1 fi @@ -5253,7 +5253,7 @@ showcsr() { _csrfile="$1" _csrd="$2" if [ -z "$_csrfile" ] && [ -z "$_csrd" ]; then - _usage "Usage: $PROJECT_ENTRY --showcsr --csr mycsr.csr" + _usage "Usage: $PROJECT_ENTRY --show-csr --csr " return 1 fi @@ -5370,7 +5370,7 @@ deploy() { _hooks="$2" _isEcc="$3" if [ -z "$_hooks" ]; then - _usage "Usage: $PROJECT_ENTRY --deploy -d domain.com --deploy-hook cpanel [--ecc] " + _usage "Usage: $PROJECT_ENTRY --deploy --domain --deploy-hook [--ecc] " return 1 fi @@ -5391,7 +5391,7 @@ deploy() { installcert() { _main_domain="$1" if [ -z "$_main_domain" ]; then - _usage "Usage: $PROJECT_ENTRY --installcert -d domain.com [--ecc] [--cert-file cert-file-path] [--key-file key-file-path] [--ca-file ca-cert-file-path] [ --reloadCmd reloadCmd] [--fullchain-file fullchain-path]" + _usage "Usage: $PROJECT_ENTRY --install-cert --domain [--ecc] [--cert-file ] [--key-file ] [--ca-file ] [ --reloadcmd ] [--fullchain-file ]" return 1 fi @@ -5670,7 +5670,7 @@ uninstallcronjob() { revoke() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then - _usage "Usage: $PROJECT_ENTRY --revoke -d domain.com [--ecc]" + _usage "Usage: $PROJECT_ENTRY --revoke --domain [--ecc]" return 1 fi @@ -5741,7 +5741,7 @@ revoke() { remove() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then - _usage "Usage: $PROJECT_ENTRY --remove -d domain.com [--ecc]" + _usage "Usage: $PROJECT_ENTRY --remove --domain [--ecc]" return 1 fi @@ -5901,7 +5901,7 @@ deactivate() { _initAPI _debug _d_domain_list "$_d_domain_list" if [ -z "$(echo $_d_domain_list | cut -d , -f 1)" ]; then - _usage "Usage: $PROJECT_ENTRY --deactivate -d domain.com [-d domain.com]" + _usage "Usage: $PROJECT_ENTRY --deactivate --domain [--domain ...]" return 1 fi for _d_dm in $(echo "$_d_domain_list" | tr ',' ' '); do @@ -6361,7 +6361,7 @@ setnotify() { _initpath if [ -z "$_nhook$_nlevel$_nmode" ]; then - _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook mailgun] [--notify-level $NOTIFY_LEVEL_DEFAULT] [--notify-mode $NOTIFY_MODE_DEFAULT]" + _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook ] [--notify-level <0|1|2|3>] [--notify-mode <0|1>]" _usage "$_NOTIFY_WIKI" return 1 fi @@ -6400,7 +6400,7 @@ setnotify() { showhelp() { _initpath version - echo "Usage: $PROJECT_ENTRY command ...[parameters].... + echo "Usage: $PROJECT_ENTRY ... [parameters ...] Commands: -h, --help Show this help message. -v, --version Show version info. From dd6c5c9eea7d76d9e6eb32c606cab2192430b7ab Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 12:15:45 +0200 Subject: [PATCH 0896/2234] add documentation for --password option --- acme.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acme.sh b/acme.sh index 168ab8da..3b56b8d6 100755 --- a/acme.sh +++ b/acme.sh @@ -6532,6 +6532,8 @@ Parameters: --revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command. See: $_REVOKE_WIKI + --password Add a password to exported pfx file. Use with --to-pkcs12. + " } From b67d663a388660ceb0a4f0f3ded422b25affb40d Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 12:19:26 +0200 Subject: [PATCH 0897/2234] fix wrong options listed in --ecc help entry --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3b56b8d6..b5fafa4b 100755 --- a/acme.sh +++ b/acme.sh @@ -6503,7 +6503,7 @@ Parameters: --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. - --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' + --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--to-pkcs12' and '--create-csr' --csr Specifies the input csr. --pre-hook Command to be run before obtaining any certificates. --post-hook Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed. From 328b6d1cc696b93c129e2ee165eb520fbbf22934 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 21 Aug 2020 18:19:26 +0800 Subject: [PATCH 0898/2234] add docker hub badge --- .github/workflows/shellcheck.yml | 2 +- README.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 529f41e1..a6f82d9e 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -1,4 +1,4 @@ -name: shellcheck +name: Shellcheck on: [push, pull_request] jobs: diff --git a/README.md b/README.md index bf6ea06c..812e5602 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) From a674e410e0ec9de7a5f98e2be103b0c53307908a Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Fri, 21 Aug 2020 17:15:18 -0400 Subject: [PATCH 0899/2234] initial commit --- dnsapi/dns_edgedns.sh | 379 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 379 insertions(+) create mode 100755 dnsapi/dns_edgedns.sh diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh new file mode 100755 index 00000000..75ef4f9b --- /dev/null +++ b/dnsapi/dns_edgedns.sh @@ -0,0 +1,379 @@ +#!/usr/bin/env sh + +# Akamai Edge DNS v2 API +# User must provide Open Edgegrid API credentials to the EdgeDNS installation. The remote user in EdgeDNS must have CRUD access to +# Edge DNS Zones and Recordsets, e.g. DNS—Zone Record Management authorization + +# Report bugs to https://control.akamai.com/apps/support-ui/#/contact-support + +# Values to export: +# --EITHER-- +# *** NOT IMPLEMENTED YET *** +# specify Edgegrid credentials file and section +# AKAMAI_EDGERC= +# AKAMAI_EDGERC_SECTION="default" +## --OR-- +# specify indiviual credentials +# export AKAMAI_HOST = +# export AKAMAI_ACCESS_TOKEN = +# export AKAMAI_CLIENT_TOKEN = +# export AKAMAI_CLIENT_SECRET = + +ACME_EDGEDNS_VERSION="0.1.0" + +######## Public functions ##################### + +# Usage: dns_edgedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record +# +dns_edgedns_add() { + fulldomain=$1 + txtvalue=$2 + + _debug "ENTERING DNS_EDGEDNS_ADD" + + _debug2 "fulldomain" "$fulldomain" + _debug2 "txtvalue" "$txtvalue" + + if ! _EDGEDNS_credentials; then + _err "$@" + return 1 + fi + + if ! _EDGEDNS_getZoneInfo "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + _debug2 "Add: zone" "${zone}" + acmeRecordURI=$(printf "%s/%s/names/%s/type/TXT" "${edge_endpoint}" "${zone}" "${fulldomain}") + _debug3 "Add URL" "$acmeRecordURI" + # Get existing TXT record + _edge_result=$(_edgedns_rest GET "$acmeRecordURI") + _api_status="$?" + if [ "$_api_status" -ne 0 ] && [ "$_edge_result" != "404" ]; then + _err "$(printf "Failure accessing Akamai Edge DNS API Server. Error: %s" "$_edge_result")" + return 1 + fi + rdata="\"$txtvalue\"" + record_op="POST" + if [ "$_api_status" -eq 0 ]; then + # record already exists. Get existing record data and update + record_op="PUT" + rdlist=$(echo -n "$response" | _egrep_o "\"rdata\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"") + _debug2 "existing TXT found" + _debug2 "record data" "$rdlist" + # value already there? + if _contains "$rdlist" "$txtvalue" ; then + return 0 + fi + comma="," + rdata="$rdata$comma\"${txtvalue}\"" + fi + _debug2 "new/updated rdata: " "${rdata}" + # Add the txtvalue TXT Record + body="{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":600, \"rdata\":"[${rdata}]"}" + _debug3 "Add body '${body}'" + _edge_result=$(_edgedns_rest "$record_op" "$acmeRecordURI" "$body") + _api_status="$?" + if [ "$_api_status" -eq 0 ]; then + _log "$(printf "Text value %s added to recordset %s" "${txtvalue}" "${fulldomain}")" + return 0 + else + _err "$(printf "error adding TXT record for validation. Error: %s" "$_edge_result")" + return 1 + fi +} + +# Usage: dns_edgedns_rm _acme-challenge.www.domain.com +# Used to delete txt record +# +dns_edgedns_rm() { + fulldomain=$1 +} + +#################### Private functions below ################################## + +_EDGEDNS_credentials() { + _debug "GettingEdge DNS credentials" + _log $(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION}) + args_missing=0 + if [ -z "${AKAMAI_ACCESS_TOKEN}" ]; then + AKAMAI_ACCESS_TOKEN="" + AKAMAI_CLIENT_TOKEN="" + AKAMAI_HOST="" + AKAMAI_CLIENT_SECRET="" + _err "AKAMAI_ACCESS_TOKEN is missing" + args_missing=1 + fi + if [ -z "$AKAMAI_CLIENT_TOKEN" ]; then + AKAMAI_ACCESS_TOKEN="" + AKAMAI_CLIENT_TOKEN="" + AKAMAI_HOST="" + AKAMAI_CLIENT_SECRET="" + _err "AKAMAI_CLIENT_TOKEN is missing" + args_missing=1 + fi + if [ -z "${AKAMAI_HOST}" ]; then + AKAMAI_ACCESS_TOKEN="" + AKAMAI_CLIENT_TOKEN="" + AKAMAI_HOST="" + AKAMAI_CLIENT_SECRET="" + _err "AKAMAI_HOST is missing" + args_missing=1 + fi + if [ -z "${AKAMAI_CLIENT_SECRET}" ]; then + AKAMAI_ACCESS_TOKEN="" + AKAMAI_CLIENT_TOKEN="" + AKAMAI_HOST="" + AKAMAI_CLIENT_SECRET="" + _err "AKAMAI_CLIENT_SECRET is missing" + args_missing=1 + fi + + if [ "${args_missing}" = 1 ]; then + _err "You have not properly specified the EdgeDNS Open Edgegrid API credentials. Please try again." + return 1 + else + _saveaccountconf_mutable AKAMAI_ACCESS_TOKEN "${AKAMAI_ACCESS_TOKEN}" + _saveaccountconf_mutable AKAMAI_CLIENT_TOKEN "${AKAMAI_CLIENT_TOKEN}" + _saveaccountconf_mutable AKAMAI_HOST "${AKAMAI_HOST}" + _saveaccountconf_mutable AKAMAI_CLIENT_SECRET "${AKAMAI_CLIENT_SECRET}" + # Set whether curl should use secure or insecure mode + fi + export HTTPS_INSECURE=0 # All Edgegrid API calls are secure + edge_endpoint=$(printf "https://%s/config-dns/v2/zones" "${AKAMAI_HOST}") + _debug3 "Edge API Endpoint:" "${edge_endpoint}" + +} + +_EDGEDNS_getZoneInfo() { + _debug "Getting Zoneinfo" + zoneEnd=false + curZone=$1 + while [ -n "${zoneEnd}" ]; do + # we can strip the first part of the fulldomain, since its just the _acme-challenge string + curZone="${curZone#*.}" + # suffix . needed for zone -> domain.tld. + # create zone get url + get_zone_url=$(printf "%s/%s" "${edge_endpoint}" "${curZone}") + _debug3 "Zone Get: " "${get_zone_url}" + curResult=$(_edgedns_rest GET "$get_zone_url") + retVal=$? + if [ $retVal -ne 0 ]; then + if ["$curResult" != "404" ]; then + _err "$(printf "Managed zone validation failed. Error response: %s" "$retVal")" + return 1 + fi + fi + + if _contains "${curResult}" "\"zone\":" ; then + _debug2 "Zone data" "${curResult}" + zone=$(echo -n "${curResult}" | _egrep_o "\"zone\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"") + _debug2 "Zone" "${zone}" + zoneFound="" + zoneEnd="" + return 0 + fi + + if [ "${curZone#*.}" != "$curZone" ]; then + _debug2 $(printf "%s still contains a '.' - so we can check next higher level" "$curZone") + else + zoneEnd=true + _err "Couldn't retrieve zone data." + return 1 + fi + done + _err "Failed to retrieve zone data." + return 2 +} + +_edgedns_headers="" + +_edgedns_rest() { + _debug "Handling API Request" + m=$1 + # Assume endpoint is complete path, including query args if applicable + ep=$2 + body_data=$3 + _edgedns_content_type="" + _request_url_path="$ep" + _request_body="$body_data" + _request_method="$m" + _edgedns_headers="" + tab="" + _edgedns_headers="${_edgedns_headers}${tab}Host: ${AKAMAI_HOST}" + tab="\t" + # Set in acme.sh _post/_get + #_edgedns_headers="${_edgedns_headers}${tab}User-Agent:ACME DNSAPI Edge DNS version ${ACME_EDGEDNS_VERSION}" + _edgedns_headers="${_edgedns_headers}${tab}Accept: application/json" + if [ "$m" != "GET" ] && [ "$m" != "DELETE" ] ; then + _edgedns_content_type="application/json;charset=UTF-8" + _utf8_body_data="$(echo -n "$ _request_body" | iconv -t utf-8)" + _utf8_body_len="$(echo -n "$_utf8_body_data" | awk '{print length}')" + _edgedns_headers="${_edgedns_headers}${tab}Content-Length: ${_utf8_body_len}" + fi + _made_auth_header=$(_edgedns_make_auth_header) + _edgedns_headers="${_edgedns_headers}${tab}Authorization: ${_made_auth_header}" + _secure_debug2 "Made Auth Header" "${_made_auth_header}" + hdr_indx=1 + work_header="${_edgedns_headers}${tab}" + _debug3 "work_header" "${work_header}" + while [ "${work_header}" ]; do + entry="${work_header%%\\t*}"; work_header="${work_header#*\\t}" + export "$(printf "_H%s=%s" "${hdr_indx}" "${entry}")" + _debug2 "Request Header " "${entry}" + hdr_indx=$(( hdr_indx + 1 )) + done + + # clear headers from previous request to avoid getting wrong http code on timeouts + :>"$HTTP_HEADER" + _debug "$ep" + if [ "$m" != "GET" ]; then + _debug "Method data" "$data" + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + response="$(_post "$_utf8_body_data" "$ep" false "$m")" + else + response="$(_get "$ep")" + fi + + _ret="$?" + _debug "response" "$response" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + _debug2 "http response code" "$_code" + + if [ "$_code" = "200" ] || [ "$_code" = "201" ]; then + # All good + response="$(echo "$response" | _normalizeJson)" + echo -n "${response}" + return 0 + fi + + if [ "$_code" = "204" ]; then + # Success, no body + echo -n "" + return 0 + fi + + if [ "$_code" = "400" ]; then + _err "Bad request presented" + _log "$(printf "Headers: %s" "$_edgedns_headers")" + _log "$(printf "Method: %s" "$_request_method")" + _log "$(printf "URL: %s" "$ep")" + _log "$(printf "Data: %s" "$data")" + fi + + if [ "$_code" = "403" ]; then + _err "access denied make sure your Edgegrid cedentials are correct." + fi + + echo "$_code" + return 1 +} + +_edgedns_eg_timestamp() { + _eg_timestamp=$(date -u "+%Y%m%dT%H:%M:%S+0000") +} + +_edgedns_new_nonce() { + _nonce=$(uuidgen -r) +} + +_edgedns_make_auth_header() { + _debug "Constructing Auth Header" + _edgedns_eg_timestamp + _edgedns_new_nonce + # "Unsigned authorization header: 'EG1-HMAC-SHA256 client_token=block;access_token=block;timestamp=20200806T14:16:33+0000;nonce=72cde72c-82d9-4721-9854-2ba057929d67;'" + _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "${AKAMAI_CLIENT_TOKEN}" "${AKAMAI_ACCESS_TOKEN}" "${_eg_timestamp}" "${_nonce}")" + _secure_debug2 "Unsigned Auth Header: " "$_auth_header" + + _sig="$(_edgedns_sign_request)" + _signed_auth_header="$(printf "%ssignature=%s" "${_auth_header}" "${_sig}")" + _secure_debug2 "Signed Auth Header: " "${_signed_auth_header}" + echo -n "${_signed_auth_header}" +} + +_edgedns_sign_request() { + _debug2 "Signing http request" + _signed_data=$(_edgedns_make_data_to_sign "${_auth_header}") + _secure_debug2 "Returned signed data" "$_signed_data" + _key=$(_edgedns_make_signing_key "${_eg_timestamp}") + _signed_req=$(_edgedns_base64_hmac_sha256 "$_signed_data" "$_key") + _secure_debug2 "Signed Request" "${_signed_req}" + echo -n "${_signed_req}" +} + +_edgedns_make_signing_key() { + _debug2 "Creating sigining key" + ts=$1 + _signing_key=$(_edgedns_base64_hmac_sha256 "$ts" "${AKAMAI_CLIENT_SECRET}") + _secure_debug2 "Signing Key" "${_signing_key}" + echo -n "${_signing_key}" + +} + +_edgedns_make_data_to_sign() { + _debug2 "Processing data to sign" + hdr=$1 + _secure_debug2 "hdr" "$hdr" + content_hash=$(_edgedns_make_content_hash) + path="$(echo -n "${_request_url_path}" |sed 's/https\?:\/\///')" + path="${path#*$AKAMAI_HOST}" + _debug "hier path" "${path}" + # dont expose headers to sign so use MT string + data="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "${_request_method}" "${AKAMAI_HOST}" "${path}" "" "${content_hash}" "$hdr")" + _secure_debug2 "Data to Sign" "${data}" + echo -n "${data}" +} + +_edgedns_make_content_hash() { + _debug2 "Generating content hash" + prep_body="" + _hash="" + _debug2 "Request method" "${_request_method}" + if [ "${_request_method}" != "POST" ] || [ -z "${_request_body}" ]; then + echo -n "${prep_body}" + return 0 + fi + prep_body="$(echo -n "${_request_body}")" + _debug2 "Req body" "${prep_body}" + _hash=$(_edgedns_base64_sha256 "${prep_body}") + _debug2 "Content hash" "${_hash}" + echo -n "${_hash}" +} + +_edgedns_base64_hmac_sha256() { + _debug2 "Generating hmac" + data=$1 + key=$2 + encoded_data="$(echo -n "${data}" | iconv -t utf-8)" + encoded_key="$(echo -n "${key}" | iconv -t utf-8)" + _secure_debug2 "encoded data" "${encoded_data}" + _secure_debug2 "encoded key" "${encoded_key}" + #key_hex="$(_durl_replace_base64 "$key" | _dbase64 | _hex_dump | tr -d ' ')" + #data_sig="$(printf "%s" "$encoded_data" | _hmac sha256 "${key_hex}" | _base64 | _url_replace)" + + data_sig="$(echo -n "$encoded_data" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hmac $encoded_key -binary | _base64)" + _secure_debug2 "data_sig:" "${data_sig}" + out="$(echo -n "${data_sig}" | iconv -f utf-8)" + _secure_debug2 "hmac" "${out}" + echo -n "${out}" +} + +_edgedns_base64_sha256() { + _debug2 "Creating sha256 digest" + trg=$1 + utf8_str="$(echo -n "${trg}" | iconv -t utf-8)" + _secure_debug2 "digest data" "$trg" + _secure_debug2 "encoded digest data" "${utf8_str}" + digest="$(echo -n "${trg}" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -binary | _base64)" + out="$(echo -n "${digest}" | iconv -f utf-8)" + _secure_debug2 "digest decode" "${out}" + echo -n "${out}" +} + +#_edgedns_parse_edgerc() { +# filepath=$1 +# section=$2 +#} + + From f511a5270590a7fc834df02470b4709629768bb7 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Mon, 24 Aug 2020 00:05:21 +0300 Subject: [PATCH 0900/2234] Using _post function --- deploy/vault.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/deploy/vault.sh b/deploy/vault.sh index ae771967..c51ceb0f 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -49,14 +49,15 @@ vault_deploy() { _cfullchain=$(sed -z 's/\n/\\n/g' <"$5") URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain" + export _H1="X-Vault-Token: $VAULT_TOKEN" if [ -n "$FABIO" ]; then - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" || return 1 + _post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" else - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_ccert\"}" "$URL/cert.pem" || return 1 - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_ckey\"}" "$URL/cert.key" || return 1 - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_cca\"}" "$URL/chain.pem" || return 1 - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" || return 1 + _post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" + _post "{\"value\": \"$_ckey\"}" "$URL/cert.key" + _post "{\"value\": \"$_cca\"}" "$URL/chain.pem" + _post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" fi } From d66c430e46fdaa7b7180cf619361d2d96da5262c Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Wed, 26 Aug 2020 16:11:11 -0400 Subject: [PATCH 0901/2234] debugging and cleanup --- dnsapi/dns_edgedns.sh | 281 ++++++++++++++++++++++++++---------------- 1 file changed, 175 insertions(+), 106 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 75ef4f9b..7be49761 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -29,9 +29,7 @@ ACME_EDGEDNS_VERSION="0.1.0" dns_edgedns_add() { fulldomain=$1 txtvalue=$2 - _debug "ENTERING DNS_EDGEDNS_ADD" - _debug2 "fulldomain" "$fulldomain" _debug2 "txtvalue" "$txtvalue" @@ -39,44 +37,53 @@ dns_edgedns_add() { _err "$@" return 1 fi - if ! _EDGEDNS_getZoneInfo "$fulldomain"; then _err "Invalid domain" return 1 fi - _debug2 "Add: zone" "${zone}" - acmeRecordURI=$(printf "%s/%s/names/%s/type/TXT" "${edge_endpoint}" "${zone}" "${fulldomain}") + _debug2 "Add: zone" "$zone" + acmeRecordURI=$(printf "%s/%s/names/%s/types/TXT" "$edge_endpoint" "$zone" "$fulldomain") _debug3 "Add URL" "$acmeRecordURI" # Get existing TXT record _edge_result=$(_edgedns_rest GET "$acmeRecordURI") _api_status="$?" - if [ "$_api_status" -ne 0 ] && [ "$_edge_result" != "404" ]; then - _err "$(printf "Failure accessing Akamai Edge DNS API Server. Error: %s" "$_edge_result")" - return 1 + _debug3 "_edge_result" "$_edge_result" + if [ "$_api_status" -ne 0 ]; then + if [ "$curResult" = "FATAL" ]; then + _err "$(printf "Fatal error: acme API function call : %s" "$retVal")" + fi + if [ "$_edge_result" != "404" ]; then + _err "$(printf "Failure accessing Akamai Edge DNS API Server. Error: %s" "$_edge_result")" + return 1 + fi fi - rdata="\"$txtvalue\"" + rdata="\"${txtvalue}\"" record_op="POST" if [ "$_api_status" -eq 0 ]; then # record already exists. Get existing record data and update record_op="PUT" - rdlist=$(echo -n "$response" | _egrep_o "\"rdata\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"") - _debug2 "existing TXT found" - _debug2 "record data" "$rdlist" + rdlist="${_edge_result#*\"rdata\":[}" + rdlist="${rdlist%%]*}" + rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\") + _debug3 "existing TXT found" + _debug3 "record data" "$rdlist" # value already there? if _contains "$rdlist" "$txtvalue" ; then return 0 fi - comma="," - rdata="$rdata$comma\"${txtvalue}\"" + _txt_val="" + while [ "$_txt_val" != "$rdlist" ] && [ "${rdlist}" ]; do + _txt_val="${rdlist%%,*}"; rdlist="${rdlist#*,}" + rdata="${rdata},\"${_txt_val}\"" + done fi - _debug2 "new/updated rdata: " "${rdata}" # Add the txtvalue TXT Record body="{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":600, \"rdata\":"[${rdata}]"}" _debug3 "Add body '${body}'" _edge_result=$(_edgedns_rest "$record_op" "$acmeRecordURI" "$body") _api_status="$?" if [ "$_api_status" -eq 0 ]; then - _log "$(printf "Text value %s added to recordset %s" "${txtvalue}" "${fulldomain}")" + _log "$(printf "Text value %s added to recordset %s" "$txtvalue" "$fulldomain")" return 0 else _err "$(printf "error adding TXT record for validation. Error: %s" "$_edge_result")" @@ -84,20 +91,89 @@ dns_edgedns_add() { fi } -# Usage: dns_edgedns_rm _acme-challenge.www.domain.com +# Usage: dns_edgedns_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Used to delete txt record # dns_edgedns_rm() { fulldomain=$1 + txtvalue=$2 + _debug "ENTERING DNS_EDGEDNS_RM" + _debug2 "fulldomain" "$fulldomain" + _debug2 "txtvalue" "$txtvalue" + + if ! _EDGEDNS_credentials; then + _err "$@" + return 1 + fi + if ! _EDGEDNS_getZoneInfo "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + _debug2 "RM: zone" "${zone}" + acmeRecordURI=$(printf "%s/%s/names/%s/types/TXT" "${edge_endpoint}" "$zone" "$fulldomain") + _debug3 "RM URL" "$acmeRecordURI" + # Get existing TXT record + _edge_result=$(_edgedns_rest GET "$acmeRecordURI") + _api_status="$?" + if [ "$_api_status" -ne 0 ]; then + if [ "$curResult" = "FATAL" ]; then + _err "$(printf "Fatal error: acme API function call : %s" "$retVal")" + fi + if [ "$_edge_result" != "404" ]; then + _err "$(printf "Failure accessing Akamai Edge DNS API Server. Error: %s" "$_edge_result")" + return 1 + fi + fi + _debug3 "_edge_result" "$_edge_result" + record_op="DELETE" + body="" + if [ "$_api_status" -eq 0 ]; then + # record already exists. Get existing record data and update + rdlist="${_edge_result#*\"rdata\":[}" + rdlist="${rdlist%%]*}" + rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\") + _debug3 "rdlist" "$rdlist" + if [ -n "$rdlist" ]; then + record_op="PUT" + comma="" + rdata="" + _txt_val="" + while [ "$_txt_val" != "$rdlist" ] && [ "$rdlist" ]; do + _txt_val="${rdlist%%,*}"; rdlist="${rdlist#*,}" + _debug3 "_txt_val" "$_txt_val" + _debug3 "txtvalue" "$txtvalue" + if ! _contains "$_txt_val" "$txtvalue" ; then + rdata="${rdata}${comma}\"${_txt_val}\"" + comma="," + fi + done + if [ -z "$rdata" ]; then + record_op="DELETE" + else + # Recreate the txtvalue TXT Record + body="{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":600, \"rdata\":"[${rdata}]"}" + _debug3 "body" "$body" + fi + fi + fi + _edge_result=$(_edgedns_rest "$record_op" "$acmeRecordURI" "$body") + _api_status="$?" + if [ "$_api_status" -eq 0 ]; then + _log "$(printf "Text value %s removed from recordset %s" "$txtvalue" "$fulldomain")" + return 0 + else + _err "$(printf "error removing TXT record for validation. Error: %s" "$_edge_result")" + return 1 + fi } #################### Private functions below ################################## _EDGEDNS_credentials() { _debug "GettingEdge DNS credentials" - _log $(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION}) + _log "$(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION})" args_missing=0 - if [ -z "${AKAMAI_ACCESS_TOKEN}" ]; then + if [ -z "$AKAMAI_ACCESS_TOKEN" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" AKAMAI_HOST="" @@ -113,7 +189,7 @@ _EDGEDNS_credentials() { _err "AKAMAI_CLIENT_TOKEN is missing" args_missing=1 fi - if [ -z "${AKAMAI_HOST}" ]; then + if [ -z "$AKAMAI_HOST" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" AKAMAI_HOST="" @@ -121,7 +197,7 @@ _EDGEDNS_credentials() { _err "AKAMAI_HOST is missing" args_missing=1 fi - if [ -z "${AKAMAI_CLIENT_SECRET}" ]; then + if [ -z "$AKAMAI_CLIENT_SECRET" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" AKAMAI_HOST="" @@ -130,19 +206,19 @@ _EDGEDNS_credentials() { args_missing=1 fi - if [ "${args_missing}" = 1 ]; then + if [ "$args_missing" = 1 ]; then _err "You have not properly specified the EdgeDNS Open Edgegrid API credentials. Please try again." return 1 else - _saveaccountconf_mutable AKAMAI_ACCESS_TOKEN "${AKAMAI_ACCESS_TOKEN}" - _saveaccountconf_mutable AKAMAI_CLIENT_TOKEN "${AKAMAI_CLIENT_TOKEN}" - _saveaccountconf_mutable AKAMAI_HOST "${AKAMAI_HOST}" - _saveaccountconf_mutable AKAMAI_CLIENT_SECRET "${AKAMAI_CLIENT_SECRET}" + _saveaccountconf_mutable AKAMAI_ACCESS_TOKEN "$AKAMAI_ACCESS_TOKEN" + _saveaccountconf_mutable AKAMAI_CLIENT_TOKEN "$AKAMAI_CLIENT_TOKEN" + _saveaccountconf_mutable AKAMAI_HOST "$AKAMAI_HOST" + _saveaccountconf_mutable AKAMAI_CLIENT_SECRET "$AKAMAI_CLIENT_SECRET" # Set whether curl should use secure or insecure mode fi export HTTPS_INSECURE=0 # All Edgegrid API calls are secure - edge_endpoint=$(printf "https://%s/config-dns/v2/zones" "${AKAMAI_HOST}") - _debug3 "Edge API Endpoint:" "${edge_endpoint}" + edge_endpoint=$(printf "https://%s/config-dns/v2/zones" "$AKAMAI_HOST") + _debug3 "Edge API Endpoint:" "$edge_endpoint" } @@ -150,33 +226,34 @@ _EDGEDNS_getZoneInfo() { _debug "Getting Zoneinfo" zoneEnd=false curZone=$1 - while [ -n "${zoneEnd}" ]; do + while [ -n "$zoneEnd" ]; do # we can strip the first part of the fulldomain, since its just the _acme-challenge string curZone="${curZone#*.}" # suffix . needed for zone -> domain.tld. # create zone get url - get_zone_url=$(printf "%s/%s" "${edge_endpoint}" "${curZone}") + get_zone_url=$(printf "%s/%s" "$edge_endpoint" "$curZone") _debug3 "Zone Get: " "${get_zone_url}" curResult=$(_edgedns_rest GET "$get_zone_url") retVal=$? - if [ $retVal -ne 0 ]; then - if ["$curResult" != "404" ]; then - _err "$(printf "Managed zone validation failed. Error response: %s" "$retVal")" + if [ "$retVal" -ne 0 ]; then + if [ "$curResult" = "FATAL" ]; then + _err "$(printf "Fatal error: acme API function call : %s" "$retVal")" + fi + if [ "$curResult" != "404" ]; then + err "$(printf "Managed zone validation failed. Error response: %s" "$retVal")" return 1 fi fi - - if _contains "${curResult}" "\"zone\":" ; then + if _contains "$curResult" "\"zone\":" ; then _debug2 "Zone data" "${curResult}" - zone=$(echo -n "${curResult}" | _egrep_o "\"zone\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"") - _debug2 "Zone" "${zone}" - zoneFound="" + zone=$(echo "${curResult}" | _egrep_o "\"zone\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"") + _debug3 "Zone" "${zone}" zoneEnd="" return 0 fi if [ "${curZone#*.}" != "$curZone" ]; then - _debug2 $(printf "%s still contains a '.' - so we can check next higher level" "$curZone") + _debug3 "$(printf "%s still contains a '.' - so we can check next higher level" "$curZone")" else zoneEnd=true _err "Couldn't retrieve zone data." @@ -205,52 +282,55 @@ _edgedns_rest() { tab="\t" # Set in acme.sh _post/_get #_edgedns_headers="${_edgedns_headers}${tab}User-Agent:ACME DNSAPI Edge DNS version ${ACME_EDGEDNS_VERSION}" - _edgedns_headers="${_edgedns_headers}${tab}Accept: application/json" + _edgedns_headers="${_edgedns_headers}${tab}Accept: application/json,*/*" if [ "$m" != "GET" ] && [ "$m" != "DELETE" ] ; then - _edgedns_content_type="application/json;charset=UTF-8" - _utf8_body_data="$(echo -n "$ _request_body" | iconv -t utf-8)" - _utf8_body_len="$(echo -n "$_utf8_body_data" | awk '{print length}')" - _edgedns_headers="${_edgedns_headers}${tab}Content-Length: ${_utf8_body_len}" + _edgedns_content_type="application/json" + _debug3 "_request_body" "$_request_body" + _body_len=$(echo "$_request_body" | tr -d "\n\r" | awk '{print length}') + _edgedns_headers="${_edgedns_headers}${tab}Content-Length: ${_body_len}" fi - _made_auth_header=$(_edgedns_make_auth_header) - _edgedns_headers="${_edgedns_headers}${tab}Authorization: ${_made_auth_header}" - _secure_debug2 "Made Auth Header" "${_made_auth_header}" + _edgedns_make_auth_header + _edgedns_headers="${_edgedns_headers}${tab}Authorization: ${_signed_auth_header}" + _secure_debug2 "Made Auth Header" "$_signed_auth_header" hdr_indx=1 work_header="${_edgedns_headers}${tab}" - _debug3 "work_header" "${work_header}" - while [ "${work_header}" ]; do + _debug3 "work_header" "$work_header" + while [ "$work_header" ]; do entry="${work_header%%\\t*}"; work_header="${work_header#*\\t}" - export "$(printf "_H%s=%s" "${hdr_indx}" "${entry}")" - _debug2 "Request Header " "${entry}" + export "$(printf "_H%s=%s" "$hdr_indx" "$entry")" + _debug2 "Request Header " "$entry" hdr_indx=$(( hdr_indx + 1 )) done # clear headers from previous request to avoid getting wrong http code on timeouts - :>"$HTTP_HEADER" - _debug "$ep" + : >"$HTTP_HEADER" + _debug2 "$ep" if [ "$m" != "GET" ]; then - _debug "Method data" "$data" + _debug3 "Method data" "$data" # body url [needbase64] [POST|PUT|DELETE] [ContentType] - response="$(_post "$_utf8_body_data" "$ep" false "$m")" + response=$(_post "$_request_body" "$ep" false "$m" "$_edgedns_content_type") else - response="$(_get "$ep")" + response=$(_get "$ep") fi - _ret="$?" - _debug "response" "$response" + if [ "$_ret" -ne 0 ]; then + _err "$(printf "acme.sh API function call failed. Error: %s" "$_ret")" + echo "FATAL" + return "$_ret" + fi + _debug2 "response" "${response}" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _debug2 "http response code" "$_code" - if [ "$_code" = "200" ] || [ "$_code" = "201" ]; then # All good - response="$(echo "$response" | _normalizeJson)" - echo -n "${response}" + response="$(echo "${response}" | _normalizeJson)" + echo "$response" return 0 fi if [ "$_code" = "204" ]; then # Success, no body - echo -n "" + echo "$_code" return 0 fi @@ -283,31 +363,30 @@ _edgedns_make_auth_header() { _edgedns_eg_timestamp _edgedns_new_nonce # "Unsigned authorization header: 'EG1-HMAC-SHA256 client_token=block;access_token=block;timestamp=20200806T14:16:33+0000;nonce=72cde72c-82d9-4721-9854-2ba057929d67;'" - _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "${AKAMAI_CLIENT_TOKEN}" "${AKAMAI_ACCESS_TOKEN}" "${_eg_timestamp}" "${_nonce}")" + _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "$AKAMAI_CLIENT_TOKEN" "$AKAMAI_ACCESS_TOKEN" "$_eg_timestamp" "$_nonce")" _secure_debug2 "Unsigned Auth Header: " "$_auth_header" - _sig="$(_edgedns_sign_request)" - _signed_auth_header="$(printf "%ssignature=%s" "${_auth_header}" "${_sig}")" + _edgedns_sign_request + _signed_auth_header="$(printf "%ssignature=%s" "$_auth_header" "$_signed_req")" _secure_debug2 "Signed Auth Header: " "${_signed_auth_header}" - echo -n "${_signed_auth_header}" } _edgedns_sign_request() { _debug2 "Signing http request" - _signed_data=$(_edgedns_make_data_to_sign "${_auth_header}") - _secure_debug2 "Returned signed data" "$_signed_data" - _key=$(_edgedns_make_signing_key "${_eg_timestamp}") - _signed_req=$(_edgedns_base64_hmac_sha256 "$_signed_data" "$_key") - _secure_debug2 "Signed Request" "${_signed_req}" - echo -n "${_signed_req}" + _edgedns_make_data_to_sign "$_auth_header" + _secure_debug2 "Returned signed data" "$_mdata" + _edgedns_make_signing_key "$_eg_timestamp" + _edgedns_base64_hmac_sha256 "$_mdata" "$_signing_key" + _signed_req="$_hmac_out" + _secure_debug2 "Signed Request" "$_signed_req" } _edgedns_make_signing_key() { _debug2 "Creating sigining key" ts=$1 - _signing_key=$(_edgedns_base64_hmac_sha256 "$ts" "${AKAMAI_CLIENT_SECRET}") - _secure_debug2 "Signing Key" "${_signing_key}" - echo -n "${_signing_key}" + _edgedns_base64_hmac_sha256 "$ts" "$AKAMAI_CLIENT_SECRET" + _signing_key="$_hmac_out" + _secure_debug2 "Signing Key" "$_signing_key" } @@ -315,60 +394,50 @@ _edgedns_make_data_to_sign() { _debug2 "Processing data to sign" hdr=$1 _secure_debug2 "hdr" "$hdr" - content_hash=$(_edgedns_make_content_hash) - path="$(echo -n "${_request_url_path}" |sed 's/https\?:\/\///')" + _edgedns_make_content_hash + path="$(echo "$_request_url_path" | tr -d "\n\r" | sed 's/https\?:\/\///')" path="${path#*$AKAMAI_HOST}" - _debug "hier path" "${path}" + _debug "hier path" "$path" # dont expose headers to sign so use MT string - data="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "${_request_method}" "${AKAMAI_HOST}" "${path}" "" "${content_hash}" "$hdr")" - _secure_debug2 "Data to Sign" "${data}" - echo -n "${data}" + _mdata="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "$_request_method" "$AKAMAI_HOST" "$path" "" "$_hash" "$hdr")" + _secure_debug2 "Data to Sign" "$_mdata" } _edgedns_make_content_hash() { _debug2 "Generating content hash" - prep_body="" _hash="" _debug2 "Request method" "${_request_method}" - if [ "${_request_method}" != "POST" ] || [ -z "${_request_body}" ]; then - echo -n "${prep_body}" + if [ "$_request_method" != "POST" ] || [ -z "$_request_body" ]; then return 0 fi - prep_body="$(echo -n "${_request_body}")" - _debug2 "Req body" "${prep_body}" - _hash=$(_edgedns_base64_sha256 "${prep_body}") - _debug2 "Content hash" "${_hash}" - echo -n "${_hash}" + _debug2 "Req body" "$_request_body" + _edgedns_base64_sha256 "$_request_body" + _hash="$_sha256_out" + _debug2 "Content hash" "$_hash" } _edgedns_base64_hmac_sha256() { _debug2 "Generating hmac" data=$1 key=$2 - encoded_data="$(echo -n "${data}" | iconv -t utf-8)" - encoded_key="$(echo -n "${key}" | iconv -t utf-8)" - _secure_debug2 "encoded data" "${encoded_data}" - _secure_debug2 "encoded key" "${encoded_key}" - #key_hex="$(_durl_replace_base64 "$key" | _dbase64 | _hex_dump | tr -d ' ')" - #data_sig="$(printf "%s" "$encoded_data" | _hmac sha256 "${key_hex}" | _base64 | _url_replace)" + encoded_data="$(echo "$data" | iconv -t utf-8)" + encoded_key="$(echo "$key" | iconv -t utf-8)" + _secure_debug2 "encoded data" "$encoded_data" + _secure_debug2 "encoded key" "$encoded_key" - data_sig="$(echo -n "$encoded_data" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hmac $encoded_key -binary | _base64)" - _secure_debug2 "data_sig:" "${data_sig}" - out="$(echo -n "${data_sig}" | iconv -f utf-8)" - _secure_debug2 "hmac" "${out}" - echo -n "${out}" + data_sig="$(echo "$encoded_data" | tr -d "\n\r" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hmac "$encoded_key" -binary | _base64)" + _secure_debug2 "data_sig:" "$data_sig" + _hmac_out="$(echo "$data_sig" | tr -d "\n\r" | iconv -f utf-8)" + _secure_debug2 "hmac" "$_hmac_out" } _edgedns_base64_sha256() { _debug2 "Creating sha256 digest" trg=$1 - utf8_str="$(echo -n "${trg}" | iconv -t utf-8)" _secure_debug2 "digest data" "$trg" - _secure_debug2 "encoded digest data" "${utf8_str}" - digest="$(echo -n "${trg}" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -binary | _base64)" - out="$(echo -n "${digest}" | iconv -f utf-8)" - _secure_debug2 "digest decode" "${out}" - echo -n "${out}" + digest="$(echo "$trg" | tr -d "\n\r" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -binary | _base64)" + _sha256_out="$(echo "$digest" | tr -d "\n\r" | iconv -f utf-8)" + _secure_debug2 "digest decode" "$_sha256_out" } #_edgedns_parse_edgerc() { From 281ee1a853936e6decbc755c5298f7551c8b52ac Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Wed, 26 Aug 2020 18:07:46 -0400 Subject: [PATCH 0902/2234] vetted by shfmt --- dnsapi/dns_edgedns.sh | 49 ++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 7be49761..2072637a 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -7,15 +7,15 @@ # Report bugs to https://control.akamai.com/apps/support-ui/#/contact-support # Values to export: -# --EITHER-- +# --EITHER-- # *** NOT IMPLEMENTED YET *** # specify Edgegrid credentials file and section -# AKAMAI_EDGERC= +# AKAMAI_EDGERC= # AKAMAI_EDGERC_SECTION="default" ## --OR-- # specify indiviual credentials # export AKAMAI_HOST = -# export AKAMAI_ACCESS_TOKEN = +# export AKAMAI_ACCESS_TOKEN = # export AKAMAI_CLIENT_TOKEN = # export AKAMAI_CLIENT_SECRET = @@ -32,7 +32,7 @@ dns_edgedns_add() { _debug "ENTERING DNS_EDGEDNS_ADD" _debug2 "fulldomain" "$fulldomain" _debug2 "txtvalue" "$txtvalue" - + if ! _EDGEDNS_credentials; then _err "$@" return 1 @@ -42,7 +42,7 @@ dns_edgedns_add() { return 1 fi _debug2 "Add: zone" "$zone" - acmeRecordURI=$(printf "%s/%s/names/%s/types/TXT" "$edge_endpoint" "$zone" "$fulldomain") + acmeRecordURI=$(printf "%s/%s/names/%s/types/TXT" "$edge_endpoint" "$zone" "$fulldomain") _debug3 "Add URL" "$acmeRecordURI" # Get existing TXT record _edge_result=$(_edgedns_rest GET "$acmeRecordURI") @@ -68,13 +68,14 @@ dns_edgedns_add() { _debug3 "existing TXT found" _debug3 "record data" "$rdlist" # value already there? - if _contains "$rdlist" "$txtvalue" ; then + if _contains "$rdlist" "$txtvalue"; then return 0 fi _txt_val="" while [ "$_txt_val" != "$rdlist" ] && [ "${rdlist}" ]; do - _txt_val="${rdlist%%,*}"; rdlist="${rdlist#*,}" - rdata="${rdata},\"${_txt_val}\"" + _txt_val="${rdlist%%,*}" + rdlist="${rdlist#*,}" + rdata="${rdata},\"${_txt_val}\"" done fi # Add the txtvalue TXT Record @@ -139,10 +140,11 @@ dns_edgedns_rm() { rdata="" _txt_val="" while [ "$_txt_val" != "$rdlist" ] && [ "$rdlist" ]; do - _txt_val="${rdlist%%,*}"; rdlist="${rdlist#*,}" + _txt_val="${rdlist%%,*}" + rdlist="${rdlist#*,}" _debug3 "_txt_val" "$_txt_val" _debug3 "txtvalue" "$txtvalue" - if ! _contains "$_txt_val" "$txtvalue" ; then + if ! _contains "$_txt_val" "$txtvalue"; then rdata="${rdata}${comma}\"${_txt_val}\"" comma="," fi @@ -170,7 +172,7 @@ dns_edgedns_rm() { #################### Private functions below ################################## _EDGEDNS_credentials() { - _debug "GettingEdge DNS credentials" + _debug "GettingEdge DNS credentials" _log "$(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION})" args_missing=0 if [ -z "$AKAMAI_ACCESS_TOKEN" ]; then @@ -216,7 +218,7 @@ _EDGEDNS_credentials() { _saveaccountconf_mutable AKAMAI_CLIENT_SECRET "$AKAMAI_CLIENT_SECRET" # Set whether curl should use secure or insecure mode fi - export HTTPS_INSECURE=0 # All Edgegrid API calls are secure + export HTTPS_INSECURE=0 # All Edgegrid API calls are secure edge_endpoint=$(printf "https://%s/config-dns/v2/zones" "$AKAMAI_HOST") _debug3 "Edge API Endpoint:" "$edge_endpoint" @@ -244,7 +246,7 @@ _EDGEDNS_getZoneInfo() { return 1 fi fi - if _contains "$curResult" "\"zone\":" ; then + if _contains "$curResult" "\"zone\":"; then _debug2 "Zone data" "${curResult}" zone=$(echo "${curResult}" | _egrep_o "\"zone\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"") _debug3 "Zone" "${zone}" @@ -283,7 +285,7 @@ _edgedns_rest() { # Set in acme.sh _post/_get #_edgedns_headers="${_edgedns_headers}${tab}User-Agent:ACME DNSAPI Edge DNS version ${ACME_EDGEDNS_VERSION}" _edgedns_headers="${_edgedns_headers}${tab}Accept: application/json,*/*" - if [ "$m" != "GET" ] && [ "$m" != "DELETE" ] ; then + if [ "$m" != "GET" ] && [ "$m" != "DELETE" ]; then _edgedns_content_type="application/json" _debug3 "_request_body" "$_request_body" _body_len=$(echo "$_request_body" | tr -d "\n\r" | awk '{print length}') @@ -295,13 +297,14 @@ _edgedns_rest() { hdr_indx=1 work_header="${_edgedns_headers}${tab}" _debug3 "work_header" "$work_header" - while [ "$work_header" ]; do - entry="${work_header%%\\t*}"; work_header="${work_header#*\\t}" + while [ "$work_header" ]; do + entry="${work_header%%\\t*}" + work_header="${work_header#*\\t}" export "$(printf "_H%s=%s" "$hdr_indx" "$entry")" _debug2 "Request Header " "$entry" - hdr_indx=$(( hdr_indx + 1 )) + hdr_indx=$((hdr_indx + 1)) done - + # clear headers from previous request to avoid getting wrong http code on timeouts : >"$HTTP_HEADER" _debug2 "$ep" @@ -360,15 +363,15 @@ _edgedns_new_nonce() { _edgedns_make_auth_header() { _debug "Constructing Auth Header" - _edgedns_eg_timestamp - _edgedns_new_nonce + _edgedns_eg_timestamp + _edgedns_new_nonce # "Unsigned authorization header: 'EG1-HMAC-SHA256 client_token=block;access_token=block;timestamp=20200806T14:16:33+0000;nonce=72cde72c-82d9-4721-9854-2ba057929d67;'" - _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "$AKAMAI_CLIENT_TOKEN" "$AKAMAI_ACCESS_TOKEN" "$_eg_timestamp" "$_nonce")" + _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "$AKAMAI_CLIENT_TOKEN" "$AKAMAI_ACCESS_TOKEN" "$_eg_timestamp" "$_nonce")" _secure_debug2 "Unsigned Auth Header: " "$_auth_header" _edgedns_sign_request _signed_auth_header="$(printf "%ssignature=%s" "$_auth_header" "$_signed_req")" - _secure_debug2 "Signed Auth Header: " "${_signed_auth_header}" + _secure_debug2 "Signed Auth Header: " "${_signed_auth_header}" } _edgedns_sign_request() { @@ -444,5 +447,3 @@ _edgedns_base64_sha256() { # filepath=$1 # section=$2 #} - - From 8d0e4851200ef060cb2344225acbd875b834d84f Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 27 Aug 2020 18:07:26 +0800 Subject: [PATCH 0903/2234] add set-default-ca --- Dockerfile | 1 + acme.sh | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 4cea3c06..2ccf6800 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,6 +54,7 @@ RUN for verb in help \ deactivate \ deactivate-account \ set-notify \ + set-default-ca \ ; do \ printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \ ; done diff --git a/acme.sh b/acme.sh index b5fafa4b..ad29669c 100755 --- a/acme.sh +++ b/acme.sh @@ -6430,7 +6430,8 @@ Commands: --cron Run cron job to renew all the certs. --set-notify Set the cron notification hook, level or mode. --deactivate Deactivate the domain authz, professional use. - --set-default-ca Used with '--server', to set the default CA to use to use. + --set-default-ca Used with '--server', Set the default CA to use. + See: $_SERVER_WIKI Parameters: From fdb96e91f1bc585bbb2145e999fdc83147fe4ab8 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 21:41:18 +0800 Subject: [PATCH 0904/2234] match issuer ignoring case --- acme.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/acme.sh b/acme.sh index ad29669c..891f0d81 100755 --- a/acme.sh +++ b/acme.sh @@ -4006,6 +4006,11 @@ _match_issuer() { _missuer="$2" _fissuers="$(_get_cert_issuers $_cfile)" _debug2 _fissuers "$_fissuers" + if _contains "$_fissuers" "$_missuer"; then + return 0 + fi + _fissuers="$(echo "$_fissuers" | _lower_case)" + _missuer="$(echo "$_missuer" | _lower_case)" _contains "$_fissuers" "$_missuer" } From cf7334eb7dc8293f321ebf5bb7123764d28279e0 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Thu, 27 Aug 2020 17:40:07 -0400 Subject: [PATCH 0905/2234] add alt nonce generation logic --- dnsapi/dns_edgedns.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 2072637a..f5705ee8 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -64,7 +64,7 @@ dns_edgedns_add() { record_op="PUT" rdlist="${_edge_result#*\"rdata\":[}" rdlist="${rdlist%%]*}" - rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\") + rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\\\") _debug3 "existing TXT found" _debug3 "record data" "$rdlist" # value already there? @@ -132,7 +132,7 @@ dns_edgedns_rm() { # record already exists. Get existing record data and update rdlist="${_edge_result#*\"rdata\":[}" rdlist="${rdlist%%]*}" - rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\") + rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\\\") _debug3 "rdlist" "$rdlist" if [ -n "$rdlist" ]; then record_op="PUT" @@ -355,10 +355,16 @@ _edgedns_rest() { _edgedns_eg_timestamp() { _eg_timestamp=$(date -u "+%Y%m%dT%H:%M:%S+0000") + _debug3 "_eg_timestamp" "$_eg_timestamp" } _edgedns_new_nonce() { _nonce=$(uuidgen -r) + _ret="$?" + if [ "$_ret" -ne 0 ]; then + _nonce=$(echo "EDGEDNS$(_time)" | _digest sha1 hex | cut -c 1-32) + fi + _debug3 "_nonce" "$_nonce" } _edgedns_make_auth_header() { From e4e6173efff2aa880eecb37509602c12eeac367e Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Fri, 28 Aug 2020 11:21:20 +0200 Subject: [PATCH 0906/2234] CleverReach Deploy API --- deploy/cleverreach.sh | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 deploy/cleverreach.sh diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh new file mode 100644 index 00000000..bf16ed34 --- /dev/null +++ b/deploy/cleverreach.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env sh +# Here is the script to deploy the cert to your CleverReach Account using the CleverReach REST API. +# Your OAuth needs the right scope, please contact CleverReach support for that. +# +# It requires that jq are in the $PATH. +# +# Written by Jan-Philipp Benecke +# Public domain, 2020 +# +# Following environment variables must be set: +# +#export DEPLOY_CLEVERREACH_CLIENT_ID=myid +#export DEPLOY_CLEVERREACH_CLIENT_SECRET=mysecret + +cleverreach_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + _cleverreach_client_id="${DEPLOY_CLEVERREACH_CLIENT_ID}" + _cleverreach_client_secret="${DEPLOY_CLEVERREACH_CLIENT_SECRET}" + + if [ -z "$_cleverreach_client_id" ]; then + _err "CleverReach Client ID is not found, please define DEPLOY_CLEVERREACH_CLIENT_ID." + return 1 + fi + if [ -z "$_cleverreach_client_secret" ]; then + _err "CleverReach client secret is not found, please define DEPLOY_CLEVERREACH_CLIENT_SECRET." + return 1 + fi + + _saveaccountconf DEPLOY_CLEVERREACH_CLIENT_ID "${_cleverreach_client_id}" + _saveaccountconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${_cleverreach_client_secret}" + + _info "Obtaining a CleverReach access token" + + _data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${_cleverreach_client_id}\", \"client_secret\": \"${_cleverreach_client_secret}\"}" + _auth_result="$(_post "$_data" "https://rest.cleverreach.com/oauth/token.php" "" "POST" "application/json")" + + _debug _data "$_data" + _debug _auth_result "$_auth_result" + + _access_token=$(echo "$_auth_result" | _json_decode | jq -r .access_token) + + _info "Uploading certificate and key to CleverReach" + + _certData="{\"cert\":\"$(cat $_cfullchain | _json_encode)\", \"key\":\"$(cat $_ckey | _json_encode)\"}" + export _H1="Authorization: Bearer ${_access_token}" + _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl/${_cdomain}" "" "POST" "application/json")" + + _debug "Destroying token at CleverReach" + _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" + + if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then + _info "Uploaded certificate successfully" + return 0 + else + _debug _add_cert_result "$_add_cert_result" + _err "Unable to update certificate" + return 1 + fi +} From 39a56884646f0a4038547037050cc8e14d560360 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Fri, 28 Aug 2020 11:28:06 +0200 Subject: [PATCH 0907/2234] Make CI happy --- deploy/cleverreach.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index bf16ed34..c22e69e1 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -52,12 +52,12 @@ cleverreach_deploy() { _info "Uploading certificate and key to CleverReach" - _certData="{\"cert\":\"$(cat $_cfullchain | _json_encode)\", \"key\":\"$(cat $_ckey | _json_encode)\"}" + _certData="{\"cert\":\"$(_json_encode < "$_cfullchain")\", \"key\":\"$(_json_encode < "$_ckey")\"}" export _H1="Authorization: Bearer ${_access_token}" _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl/${_cdomain}" "" "POST" "application/json")" _debug "Destroying token at CleverReach" - _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" + _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then _info "Uploaded certificate successfully" From 2a9c56d9e328716dd90503760a5834488a76c3a6 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Fri, 28 Aug 2020 11:30:23 +0200 Subject: [PATCH 0908/2234] Formatting for CI --- deploy/cleverreach.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index c22e69e1..d212846b 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -52,7 +52,7 @@ cleverreach_deploy() { _info "Uploading certificate and key to CleverReach" - _certData="{\"cert\":\"$(_json_encode < "$_cfullchain")\", \"key\":\"$(_json_encode < "$_ckey")\"}" + _certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}" export _H1="Authorization: Bearer ${_access_token}" _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl/${_cdomain}" "" "POST" "application/json")" From f1692b3436725e0f43d285d4fc46390ba8600584 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 20:10:12 +0800 Subject: [PATCH 0909/2234] begin 2.8.8 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 891f0d81..c36ce80e 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.7 +VER=2.8.8 PROJECT_NAME="acme.sh" From 1ad450d753959bf1231655d70899acfe222459cb Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 21:45:26 +0800 Subject: [PATCH 0910/2234] add ubuntu test in github actions --- .github/workflows/Ubuntu.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/Ubuntu.yml diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml new file mode 100644 index 00000000..1b89c28c --- /dev/null +++ b/.github/workflows/Ubuntu.yml @@ -0,0 +1,14 @@ +name: PebbleStrict +on: [push, pull_request] + +jobs: + PebbleStrict: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh From 5f4d08ada5962f9d3d0adfdba72af4d5a5c402c4 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 21:46:29 +0800 Subject: [PATCH 0911/2234] fix name --- .github/workflows/Ubuntu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 1b89c28c..523bfefb 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -1,8 +1,8 @@ -name: PebbleStrict +name: Ubuntu on: [push, pull_request] jobs: - PebbleStrict: + Ubuntu: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From 8017774bf398c13fe6d43d85d5e7189781216046 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 21:49:19 +0800 Subject: [PATCH 0912/2234] add token --- .github/workflows/Ubuntu.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 523bfefb..5c0859a4 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -4,6 +4,8 @@ on: [push, pull_request] jobs: Ubuntu: runs-on: ubuntu-latest + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} steps: - uses: actions/checkout@v2 - name: Install tools From e087bccd339e054790300297fbd3e6b0c53fdb55 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 22:17:10 +0800 Subject: [PATCH 0913/2234] remove travis --- .github/workflows/LetsEncrypt.yml | 30 +++++++++++++++++++++++++ .github/workflows/Ubuntu.yml | 16 ------------- .travis.yml | 37 ------------------------------- 3 files changed, 30 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/LetsEncrypt.yml delete mode 100644 .github/workflows/Ubuntu.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml new file mode 100644 index 00000000..83a1a931 --- /dev/null +++ b/.github/workflows/LetsEncrypt.yml @@ -0,0 +1,30 @@ +name: LetsEncrypt +on: [push, pull_request] + +jobs: + Ubuntu: + runs-on: ubuntu-latest + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh + + MacOS: + needs: Ubuntu + runs-on: macos-latest + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: brew update && brew install socat; + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh \ No newline at end of file diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml deleted file mode 100644 index 5c0859a4..00000000 --- a/.github/workflows/Ubuntu.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Ubuntu -on: [push, pull_request] - -jobs: - Ubuntu: - runs-on: ubuntu-latest - env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} - steps: - - uses: actions/checkout@v2 - - name: Install tools - run: sudo apt-get install -y socat - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - name: Run acmetest - run: cd ../acmetest && ./letest.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2741e719..00000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -language: shell -dist: bionic - -os: - - linux - - osx - -services: - - docker - -env: - global: - - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 - - -install: - - if [ "$TRAVIS_OS_NAME" = 'osx' ]; then - brew update && brew install socat; - export PATH="/usr/local/opt/openssl@1.1/bin:$PATH" ; - fi - -script: - - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" - - command -V openssl && openssl version - - if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -sSL $SHFMT_URL -o ~/shfmt && chmod +x ~/shfmt && ~/shfmt -l -w -i 2 . ; fi - - if [ "$TRAVIS_OS_NAME" = "linux" ]; then git diff --exit-code && echo "shfmt OK" ; fi - - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi - - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" ; fi - - cd .. - - git clone --depth 1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./rundocker.sh testplat ubuntu:latest ; fi - - if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ACME_OPENSSL_BIN="$ACME_OPENSSL_BIN" ./letest.sh ; fi - -matrix: - fast_finish: true - - From e66337a1db904359691c23133342998f492cb153 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 22:35:05 +0800 Subject: [PATCH 0914/2234] fix badge --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 812e5602..9b7d48cc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # An ACME Shell script: acme.sh -[![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) + +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) @@ -11,8 +12,6 @@ [![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") -acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial - - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. @@ -77,7 +76,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) |18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris |19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux -|20|[![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh)|Mac OSX +|20|[![Build Status](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX |21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): From f0c710b245be71acb4aa98dca8aee88f5f3788e5 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 09:32:38 +0800 Subject: [PATCH 0915/2234] Update LetsEncrypt.yml --- .github/workflows/LetsEncrypt.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 83a1a931..a239a9ca 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -6,6 +6,7 @@ jobs: runs-on: ubuntu-latest env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 - name: Install tools @@ -13,13 +14,14 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && ./letest.sh + run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh MacOS: needs: Ubuntu runs-on: macos-latest env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 - name: Install tools @@ -27,4 +29,4 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && ./letest.sh \ No newline at end of file + run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh From 339218508d2fd6ef34a2db283c0dea4dc123e8f4 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Fri, 28 Aug 2020 09:55:20 -0400 Subject: [PATCH 0916/2234] shfmt fixes --- dnsapi/dns_edgedns.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index f5705ee8..94cf809c 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -361,9 +361,9 @@ _edgedns_eg_timestamp() { _edgedns_new_nonce() { _nonce=$(uuidgen -r) _ret="$?" - if [ "$_ret" -ne 0 ]; then + if [ "$_ret" -ne 0 ]; then _nonce=$(echo "EDGEDNS$(_time)" | _digest sha1 hex | cut -c 1-32) - fi + fi _debug3 "_nonce" "$_nonce" } From f170ee9e598851dfc593beb6299fa8d459dd1969 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 23:18:05 +0800 Subject: [PATCH 0917/2234] add Windows --- .github/workflows/LetsEncrypt.yml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index a239a9ca..5145d006 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -17,8 +17,8 @@ jobs: run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh MacOS: - needs: Ubuntu runs-on: macos-latest + needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -30,3 +30,32 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh + + Windows: + runs-on: windows-latest + needs: MacOS + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 + steps: + - uses: actions/checkout@v2 + - name: Install cygwin base packages with chocolatey + run: | + choco config get cacheLocation + choco install cygwin + shell: cmd + - name: Install cygwin additional packages + run: | + C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,git + shell: cmd + - name: Set ENV + run: | + echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' + - name: Clone acmetest + shell: cmd + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + shell: cmd + run: cd ../acmetest && bash.exe -c ./letest.sh + + From 9f80df3fcb4989170e01e7432eb8bf0f1808176d Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 23:31:18 +0800 Subject: [PATCH 0918/2234] add unzip --- .github/workflows/LetsEncrypt.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 5145d006..86d9ad3e 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -42,11 +42,11 @@ jobs: - name: Install cygwin base packages with chocolatey run: | choco config get cacheLocation - choco install cygwin + choco install --no-progress cygwin shell: cmd - name: Install cygwin additional packages run: | - C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,git + C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git shell: cmd - name: Set ENV run: | From 763c05313beae4e25acee004f4debfd064f34dc6 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 23:54:39 +0800 Subject: [PATCH 0919/2234] 80 port of github windows server is already used. --- .github/workflows/LetsEncrypt.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 86d9ad3e..90a94982 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -37,6 +37,7 @@ jobs: env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 + Le_HTTPPort: 8888 steps: - uses: actions/checkout@v2 - name: Install cygwin base packages with chocolatey From 3b3d7eff3c95adc2893c2898b3b717d8476e69a1 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 00:35:33 +0800 Subject: [PATCH 0920/2234] remove \r --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 90a94982..23d1f055 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -54,7 +54,7 @@ jobs: echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' - name: Clone acmetest shell: cmd - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ && sed -i 's/\r//g' acmetest/acme.sh/acme.sh - name: Run acmetest shell: cmd run: cd ../acmetest && bash.exe -c ./letest.sh From 395fdc9d61701bd3a9fb4b1bb812663461a579ae Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 18:49:39 +0200 Subject: [PATCH 0921/2234] Added support for custom domains --- dnsapi/dns_dynv6.sh | 66 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 3c222d3a..f1471643 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -13,14 +13,18 @@ dns_dynv6_add() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exist on your dynv6 account" - return 1 + + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -44,14 +48,17 @@ dns_dynv6_rm() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exist on your dynv6 account" - return 1 + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 @@ -72,29 +79,30 @@ _generate_new_key() { return 1 fi } -#Usage: _acme-challenge.www.example.dynv6.net + +#Usage: _acme-challenge.www.example.dynv6.net "$_your_hosts" +#where _your_hosts is the output of ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts #returns #_host= example.dynv6.net #_record=_acme-challenge.www #aborts if not a valid domain _get_domain() { + #_your_hosts="$(ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts)" _full_domain="$1" - _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks'; then - _err "The hosts does not seem to be a dynv6 host" - return 1 - fi - _record="${_full_domain%.*}" - _record="${_record%.*}" - _record="${_record%.*}" - _debug "The record we are ging to use is $_record" - _host="$_full_domain" - while [ "$(echo "$_host" | grep -o '\.' | wc -l)" != "2" ]; do - _host="${_host#*.}" - done - _debug "And the host is $_host" - return 0 + _your_hosts="$2" + _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" + for l in $_your_hosts; do + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi + done + _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" + return 1 } # Usage: No input required @@ -103,7 +111,7 @@ _get_domain() { _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug Your key is "$dynv6_keyfile" + _debug "Your key is $dynv6_keyfile" if [ -z "$dynv6_keyfile" ]; then if [ -z "$KEY" ]; then _err "You did not specify a key to use with dynv6" From 0b539a597710a69e8aa2521fc8d0f4c48c6f1a0c Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 19:09:27 +0200 Subject: [PATCH 0922/2234] first attempt to make travis happy --- dnsapi/dns_dynv6.sh | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index f1471643..473bb243 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,17 +14,14 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" +<<<<<<< HEAD +======= +>>>>>>> first attempt to make travis happy if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -50,19 +47,12 @@ dns_dynv6_rm() { _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 - } #################### Private functions below ################################## #Usage: No Input required @@ -93,13 +83,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 From 0d4904f05dd9356a72caf7f5941bdcbdd975c654 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:42:45 +0200 Subject: [PATCH 0923/2234] no supporting HTTP API as well --- dnsapi/dns_dynv6.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 473bb243..dce7ce5f 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,10 +14,6 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" -<<<<<<< HEAD - -======= ->>>>>>> first attempt to make travis happy if ! _get_domain "$fulldomain" "$_your_hosts"; then _err "Host not found on your account" return 1 From 3cd7a2e6d6f6f6babee36e087abf98510c897f39 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:49:25 +0200 Subject: [PATCH 0924/2234] formatting --- dnsapi/dns_dynv6.sh | 212 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index dce7ce5f..5f36cef8 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -11,6 +11,7 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" @@ -27,6 +28,30 @@ dns_dynv6_add() { return 0 else _err "Something went wrong! it does not seem like the record was added succesfully" +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_add_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" + _debug "Dynv6 returned this after record was added: $returnval" + if _contains "$returnval" "created"; then + return 0 + elif _contains "$returnval" "updated"; then + return 0 + else + _err "Something went wrong! it does not seem like the record was added successfully" + return 1 + fi +>>>>>>> formatting return 1 fi return 1 @@ -39,12 +64,29 @@ dns_dynv6_rm() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then _err "Host not found on your account" return 1 +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_rm_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" + return 0 +>>>>>>> formatting fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" @@ -94,6 +136,7 @@ _get_domain() { # Usage: No input required #returns #dynv6_keyfile path to the key that will be used +<<<<<<< HEAD _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" @@ -111,5 +154,174 @@ _get_keyfile() { dynv6_keyfile="$KEY" fi _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" +======= +_get_authentication() { + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else + _debug "no HTTP token found. Looking for an SSH key" + dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" + _debug "Your key is $dynv6_keyfile" + if [ -z "$dynv6_keyfile" ]; then + if [ -z "$KEY" ]; then + _err "You did not specify a key to use with dynv6" + _info "Creating new dynv6 API key to add to dynv6.com" + _generate_new_key + _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" + _info "Hit Enter to continue" + read -r _ + #save the credentials to the account conf file. + else + dynv6_keyfile="$KEY" + fi + _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" + fi + fi +} + +_dns_dynv6_add_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi +} + +_dns_dynv6_rm_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ]; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} + +#get the zoneid for a specifc record or zone +#usage: _get_zone_id §record +#where $record is the record to get the id for +#returns _zone_id the id of the zone +_get_zone_id() { + record="$1" + _debug "getting zone id for $record" + _dynv6_rest GET zones + + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" +} + +_get_zone_name() { + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" + _zone_name="${_zone_name#name:}" +} + +#usaage _get_record_id $zone_id $record +# where zone_id is thevalue returned by _get_zone_id +# and record ist in the form _acme.www for an fqdn of _acme.www.example.com +# returns _record_id +_get_record_id() { + _zone_id="$1" + record="$2" + value="$3" + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response"; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi +} + +_get_record_id_from_response() { + response="$1" + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 +} +#usage: _set_record TXT _acme_challenge.www longvalue 12345678 +#zone id is optional can also be set as vairable bevor calling this method +_set_record() { + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" +} +_del_record() { + _zone_id=$1 + _record_id=$2 + _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" +} + +_dynv6_rest() { + m=$1 #method GET,POST,DELETE or PUT + ep="$2" #the endpoint + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$dynv6_token" | tr -d '"') + + export _H1="Authorization: Bearer $token_trimmed" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" + else + response="$(_get "$dynv6_api/$ep")" +>>>>>>> formatting fi } From c849738c6fbd15524e8e2047ffe10203101aa2a8 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 16:01:46 +0200 Subject: [PATCH 0925/2234] formatting --- dnsapi/dns_dynv6.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 5f36cef8..5ccab1a4 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -156,13 +156,12 @@ _get_keyfile() { _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" ======= _get_authentication() { - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" + dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" + if [ "$dynv6_token" ]; then + _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" + if [ "$DYNV6_TOKEN" ]; then + _saveaccountconf_mutable dynv6_token "$dynv6_token" + fi else _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" From 4632035581599994ed7a7349de002f2e260b76a8 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 01:32:10 +0800 Subject: [PATCH 0926/2234] no need to run for PR from dev to master --- .github/workflows/LetsEncrypt.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 23d1f055..4916c78b 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -1,5 +1,11 @@ name: LetsEncrypt -on: [push, pull_request] +on: + push: + branches: + - '*' + pull_request: + branches: + - dev jobs: Ubuntu: From 185b558561f8cbeef9598f97f6b8b18d2cdfe099 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Fri, 28 Aug 2020 19:46:45 +0200 Subject: [PATCH 0927/2234] fix shfmt error --- dnsapi/dns_dynv6.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index e51e118a..9efc9aeb 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -260,7 +260,7 @@ _del_record() { _dynv6_rest() { m=$1 #method GET,POST,DELETE or PUT - ep="$2" #the endpoint + ep="$2" #the endpoint data="$3" _debug "$ep" From 7d7e5bac123cff13061e3e957bf1ba4460e4e8b3 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 09:54:02 +0800 Subject: [PATCH 0928/2234] add comments --- .github/workflows/LetsEncrypt.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 4916c78b..ad31b752 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -43,6 +43,7 @@ jobs: env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 + #The 80 port is used by Windows server, we have to use a custom port, ngrok will also use this port. Le_HTTPPort: 8888 steps: - uses: actions/checkout@v2 From c2214cd4b509ed5b136fad91b59f02ca539bd8f5 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 13:06:58 +0800 Subject: [PATCH 0929/2234] minor --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b7d48cc..953c44a5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # An ACME Shell script: acme.sh -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) +![LetsEncrypt](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg) +![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) +![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) +![DockerHub](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) From 918c8f9295ac385ad5478746b35cc74179a3aacf Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 13:14:28 +0800 Subject: [PATCH 0930/2234] filer events --- .github/workflows/LetsEncrypt.yml | 5 +++++ .github/workflows/PebbleStrict.yml | 12 +++++++++++- .github/workflows/shellcheck.yml | 12 +++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index ad31b752..3af574a7 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -3,9 +3,14 @@ on: push: branches: - '*' + paths: + - '**.sh' pull_request: branches: - dev + paths: + - '**.sh' + jobs: Ubuntu: diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index a339f727..ffc2ccdc 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -1,5 +1,15 @@ name: PebbleStrict -on: [push, pull_request] +on: + push: + branches: + - '*' + paths: + - '**.sh' + pull_request: + branches: + - dev + paths: + - '**.sh' jobs: PebbleStrict: diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index a6f82d9e..402492ad 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -1,5 +1,15 @@ name: Shellcheck -on: [push, pull_request] +on: + push: + branches: + - '*' + paths: + - '**.sh' + pull_request: + branches: + - dev + paths: + - '**.sh' jobs: formatCheck: From b639683ac1c821f675b1ddd2f6b2c5539744c91e Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 14:11:11 +0800 Subject: [PATCH 0931/2234] don't run if "${{ secrets.NGROK_TOKEN }}" is not set. --- .github/workflows/LetsEncrypt.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 3af574a7..e9f0897d 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -15,6 +15,7 @@ on: jobs: Ubuntu: runs-on: ubuntu-latest + if: "${{ secrets.NGROK_TOKEN }}" env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -29,6 +30,7 @@ jobs: MacOS: runs-on: macos-latest + if: "${{ secrets.NGROK_TOKEN }}" needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} @@ -44,6 +46,7 @@ jobs: Windows: runs-on: windows-latest + if: "${{ secrets.NGROK_TOKEN }}" needs: MacOS env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} From e88180b4d5b7168c99bd10a85e51b885fdc5f9f8 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 14:19:17 +0800 Subject: [PATCH 0932/2234] fix if --- .github/workflows/LetsEncrypt.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index e9f0897d..3101205c 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -15,7 +15,7 @@ on: jobs: Ubuntu: runs-on: ubuntu-latest - if: "${{ secrets.NGROK_TOKEN }}" + if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -30,7 +30,7 @@ jobs: MacOS: runs-on: macos-latest - if: "${{ secrets.NGROK_TOKEN }}" + if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} @@ -46,7 +46,7 @@ jobs: Windows: runs-on: windows-latest - if: "${{ secrets.NGROK_TOKEN }}" + if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" needs: MacOS env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} From 70366a98bd596ba8d6bd8160251c3d08b5a48d7d Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 14:33:33 +0800 Subject: [PATCH 0933/2234] fix if --- .github/workflows/LetsEncrypt.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 3101205c..818e2d19 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -15,7 +15,7 @@ on: jobs: Ubuntu: runs-on: ubuntu-latest - if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" + if: "contains(secrets.NGROK_TOKEN, '-')" env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -30,7 +30,7 @@ jobs: MacOS: runs-on: macos-latest - if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" + if: "contains(secrets.NGROK_TOKEN, '-')" needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} @@ -46,7 +46,7 @@ jobs: Windows: runs-on: windows-latest - if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" + if: "contains(secrets.NGROK_TOKEN, '-')" needs: MacOS env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} From faaa7bfa3ae577161f24718c3f82cc6f80e56d0c Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 23:14:18 +0800 Subject: [PATCH 0934/2234] check token before run --- .github/workflows/LetsEncrypt.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 818e2d19..92d378c0 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -13,9 +13,23 @@ on: jobs: + CheckToken: + runs-on: ubuntu-latest + outputs: + hasToken: ${{ steps.step_one.outputs.hasToken }} + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + steps: + - name: Set the value + id: step_one + run: [ "$NGROK_TOKEN" ] && echo "::set-output name=hasToken::true" || echo "::set-output name=hasToken::false" + - name: Check the value + run: echo ${{ steps.step_one.outputs.hasToken }} + Ubuntu: runs-on: ubuntu-latest - if: "contains(secrets.NGROK_TOKEN, '-')" + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'true')" env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -30,7 +44,6 @@ jobs: MacOS: runs-on: macos-latest - if: "contains(secrets.NGROK_TOKEN, '-')" needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} @@ -46,7 +59,6 @@ jobs: Windows: runs-on: windows-latest - if: "contains(secrets.NGROK_TOKEN, '-')" needs: MacOS env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} From 900eedfc2e5f807e19c3981952fbcd3a0e5d7948 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 23:19:21 +0800 Subject: [PATCH 0935/2234] fix checktoken --- .github/workflows/LetsEncrypt.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 92d378c0..0dff3592 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -22,7 +22,12 @@ jobs: steps: - name: Set the value id: step_one - run: [ "$NGROK_TOKEN" ] && echo "::set-output name=hasToken::true" || echo "::set-output name=hasToken::false" + run: | + if [ "$NGROK_TOKEN" ] ; then + echo "::set-output name=hasToken::true" + else + echo "::set-output name=hasToken::false" + fi - name: Check the value run: echo ${{ steps.step_one.outputs.hasToken }} From 45cf5c4c0f150cb59a6c53680a45604a303f6f5f Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 23:23:07 +0800 Subject: [PATCH 0936/2234] trigger build --- .github/workflows/LetsEncrypt.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 0dff3592..57948e3a 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -5,6 +5,7 @@ on: - '*' paths: - '**.sh' + - '**.yml' pull_request: branches: - dev From 41754c92c3125feaf7d9a8a8c8c998ebfa2957e3 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 30 Aug 2020 23:26:10 +0800 Subject: [PATCH 0937/2234] --preserve-env --- .github/workflows/LetsEncrypt.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 57948e3a..afa4da68 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -46,7 +46,7 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh + run: cd ../acmetest && sudo --preserve-env ./letest.sh MacOS: runs-on: macos-latest @@ -61,7 +61,7 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh + run: cd ../acmetest && sudo --preserve-env ./letest.sh Windows: runs-on: windows-latest From 91a8b97cf47a108e0c2f9adda3542424c1e02f4b Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 18:49:39 +0200 Subject: [PATCH 0938/2234] Added support for custom domains --- dnsapi/dns_dynv6.sh | 66 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 3c222d3a..f1471643 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -13,14 +13,18 @@ dns_dynv6_add() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exist on your dynv6 account" - return 1 + + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -44,14 +48,17 @@ dns_dynv6_rm() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exist on your dynv6 account" - return 1 + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 @@ -72,29 +79,30 @@ _generate_new_key() { return 1 fi } -#Usage: _acme-challenge.www.example.dynv6.net + +#Usage: _acme-challenge.www.example.dynv6.net "$_your_hosts" +#where _your_hosts is the output of ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts #returns #_host= example.dynv6.net #_record=_acme-challenge.www #aborts if not a valid domain _get_domain() { + #_your_hosts="$(ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts)" _full_domain="$1" - _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks'; then - _err "The hosts does not seem to be a dynv6 host" - return 1 - fi - _record="${_full_domain%.*}" - _record="${_record%.*}" - _record="${_record%.*}" - _debug "The record we are ging to use is $_record" - _host="$_full_domain" - while [ "$(echo "$_host" | grep -o '\.' | wc -l)" != "2" ]; do - _host="${_host#*.}" - done - _debug "And the host is $_host" - return 0 + _your_hosts="$2" + _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" + for l in $_your_hosts; do + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi + done + _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" + return 1 } # Usage: No input required @@ -103,7 +111,7 @@ _get_domain() { _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug Your key is "$dynv6_keyfile" + _debug "Your key is $dynv6_keyfile" if [ -z "$dynv6_keyfile" ]; then if [ -z "$KEY" ]; then _err "You did not specify a key to use with dynv6" From a83b16e12ac83ec67374f5d6986d10e8e898b9b1 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 19:09:27 +0200 Subject: [PATCH 0939/2234] first attempt to make travis happy --- dnsapi/dns_dynv6.sh | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index f1471643..473bb243 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,17 +14,14 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" +<<<<<<< HEAD +======= +>>>>>>> first attempt to make travis happy if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -50,19 +47,12 @@ dns_dynv6_rm() { _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 - } #################### Private functions below ################################## #Usage: No Input required @@ -93,13 +83,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 From 06e7ebbdebfe6aa442140412cf901bb4b18eaa66 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:42:45 +0200 Subject: [PATCH 0940/2234] no supporting HTTP API as well --- dnsapi/dns_dynv6.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 473bb243..dce7ce5f 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,10 +14,6 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" -<<<<<<< HEAD - -======= ->>>>>>> first attempt to make travis happy if ! _get_domain "$fulldomain" "$_your_hosts"; then _err "Host not found on your account" return 1 From 9dd50899404b774a351bea75fd8f01deeb85f3ce Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:49:25 +0200 Subject: [PATCH 0941/2234] formatting --- dnsapi/dns_dynv6.sh | 212 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index dce7ce5f..5f36cef8 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -11,6 +11,7 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" @@ -27,6 +28,30 @@ dns_dynv6_add() { return 0 else _err "Something went wrong! it does not seem like the record was added succesfully" +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_add_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" + _debug "Dynv6 returned this after record was added: $returnval" + if _contains "$returnval" "created"; then + return 0 + elif _contains "$returnval" "updated"; then + return 0 + else + _err "Something went wrong! it does not seem like the record was added successfully" + return 1 + fi +>>>>>>> formatting return 1 fi return 1 @@ -39,12 +64,29 @@ dns_dynv6_rm() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then _err "Host not found on your account" return 1 +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_rm_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" + return 0 +>>>>>>> formatting fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" @@ -94,6 +136,7 @@ _get_domain() { # Usage: No input required #returns #dynv6_keyfile path to the key that will be used +<<<<<<< HEAD _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" @@ -111,5 +154,174 @@ _get_keyfile() { dynv6_keyfile="$KEY" fi _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" +======= +_get_authentication() { + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else + _debug "no HTTP token found. Looking for an SSH key" + dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" + _debug "Your key is $dynv6_keyfile" + if [ -z "$dynv6_keyfile" ]; then + if [ -z "$KEY" ]; then + _err "You did not specify a key to use with dynv6" + _info "Creating new dynv6 API key to add to dynv6.com" + _generate_new_key + _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" + _info "Hit Enter to continue" + read -r _ + #save the credentials to the account conf file. + else + dynv6_keyfile="$KEY" + fi + _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" + fi + fi +} + +_dns_dynv6_add_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi +} + +_dns_dynv6_rm_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ]; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} + +#get the zoneid for a specifc record or zone +#usage: _get_zone_id §record +#where $record is the record to get the id for +#returns _zone_id the id of the zone +_get_zone_id() { + record="$1" + _debug "getting zone id for $record" + _dynv6_rest GET zones + + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" +} + +_get_zone_name() { + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" + _zone_name="${_zone_name#name:}" +} + +#usaage _get_record_id $zone_id $record +# where zone_id is thevalue returned by _get_zone_id +# and record ist in the form _acme.www for an fqdn of _acme.www.example.com +# returns _record_id +_get_record_id() { + _zone_id="$1" + record="$2" + value="$3" + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response"; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi +} + +_get_record_id_from_response() { + response="$1" + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 +} +#usage: _set_record TXT _acme_challenge.www longvalue 12345678 +#zone id is optional can also be set as vairable bevor calling this method +_set_record() { + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" +} +_del_record() { + _zone_id=$1 + _record_id=$2 + _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" +} + +_dynv6_rest() { + m=$1 #method GET,POST,DELETE or PUT + ep="$2" #the endpoint + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$dynv6_token" | tr -d '"') + + export _H1="Authorization: Bearer $token_trimmed" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" + else + response="$(_get "$dynv6_api/$ep")" +>>>>>>> formatting fi } From 551316bcb6a2a3140972bf7e06bfc84d4ac1f5e8 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 16:01:46 +0200 Subject: [PATCH 0942/2234] formatting --- dnsapi/dns_dynv6.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 5f36cef8..5ccab1a4 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -156,13 +156,12 @@ _get_keyfile() { _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" ======= _get_authentication() { - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" + dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" + if [ "$dynv6_token" ]; then + _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" + if [ "$DYNV6_TOKEN" ]; then + _saveaccountconf_mutable dynv6_token "$dynv6_token" + fi else _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" From 943d419f98ce81b4896b012ad25e2c2c1b570ae3 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 18:49:39 +0200 Subject: [PATCH 0943/2234] Added support for custom domains --- dnsapi/dns_dynv6.sh | 70 +++++++-------------------------------------- 1 file changed, 10 insertions(+), 60 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 5ccab1a4..51d2df48 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -11,24 +11,7 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" -<<<<<<< HEAD - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 - fi - _debug "found host on your account" - returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" - _debug "Dynv6 returend this after record was added: $returnval" - if _contains "$returnval" "created"; then - return 0 - elif _contains "$returnval" "updated"; then - return 0 - else - _err "Something went wrong! it does not seem like the record was added succesfully" -======= + _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_add_http @@ -51,7 +34,6 @@ dns_dynv6_add() { _err "Something went wrong! it does not seem like the record was added successfully" return 1 fi ->>>>>>> formatting return 1 fi return 1 @@ -61,17 +43,9 @@ dns_dynv6_add() { dns_dynv6_rm() { fulldomain=$1 txtvalue=$2 - _info "Using dynv6 api" + _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" -<<<<<<< HEAD - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 -======= _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_rm_http @@ -86,11 +60,7 @@ dns_dynv6_rm() { _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 ->>>>>>> formatting fi - _debug "found host on your account" - _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" - return 0 } #################### Private functions below ################################## #Usage: No Input required @@ -121,13 +91,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 @@ -136,25 +106,6 @@ _get_domain() { # Usage: No input required #returns #dynv6_keyfile path to the key that will be used -<<<<<<< HEAD -_get_keyfile() { - _debug "get keyfile method called" - dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug "Your key is $dynv6_keyfile" - if [ -z "$dynv6_keyfile" ]; then - if [ -z "$KEY" ]; then - _err "You did not specify a key to use with dynv6" - _info "Creating new dynv6 api key to add to dynv6.com" - _generate_new_key - _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" - _info "Hit Enter to contiue" - read -r _ - #save the credentials to the account conf file. - else - dynv6_keyfile="$KEY" - fi - _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" -======= _get_authentication() { dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" if [ "$dynv6_token" ]; then @@ -307,7 +258,7 @@ _del_record() { _dynv6_rest() { m=$1 #method GET,POST,DELETE or PUT - ep="$2" #the endpoint + ep="$2" #the endpoint data="$3" _debug "$ep" @@ -321,6 +272,5 @@ _dynv6_rest() { response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" else response="$(_get "$dynv6_api/$ep")" ->>>>>>> formatting fi } From 90e2064d720ec1e3e72790ae78354e98cd637135 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 19:09:27 +0200 Subject: [PATCH 0944/2234] first attempt to make travis happy --- dnsapi/dns_dynv6.sh | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 51d2df48..dbb36255 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -11,11 +11,28 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_add_http return $? +======= + _get_keyfile + _info "using keyfile $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" + _debug "Dynv6 returend this after record was added: $returnval" + if _contains "$returnval" "created"; then + return 0 + elif _contains "$returnval" "updated"; then + return 0 +>>>>>>> first attempt to make travis happy else _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" @@ -46,6 +63,7 @@ dns_dynv6_rm() { _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_rm_http @@ -61,6 +79,18 @@ dns_dynv6_rm() { _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 fi +======= + _get_keyfile + _info "using keyfile $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" + return 0 +>>>>>>> first attempt to make travis happy } #################### Private functions below ################################## #Usage: No Input required @@ -91,13 +121,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 From 9190ce37011453be1bbf236c359b81a36b5bf8bc Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:42:45 +0200 Subject: [PATCH 0945/2234] no supporting HTTP API as well --- dnsapi/dns_dynv6.sh | 193 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index dbb36255..9c6d330d 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh #Author StefanAbl #Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"' +#or use the HTTP REST API by by specifying a token 'export DYNV6_TOKEN="value" #if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub + +dynv6_api="https://dynv6.com/api/v2" ######## Public functions ##################### # Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide -#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Usage: dns_dynv6_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dynv6_add() { fulldomain=$1 txtvalue=$2 @@ -12,11 +15,15 @@ dns_dynv6_add() { _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> no supporting HTTP API as well _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_add_http return $? +<<<<<<< HEAD ======= _get_keyfile _info "using keyfile $dynv6_keyfile" @@ -34,6 +41,9 @@ dns_dynv6_add() { return 0 >>>>>>> first attempt to make travis happy else +======= + else +>>>>>>> no supporting HTTP API as well _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -63,12 +73,20 @@ dns_dynv6_rm() { _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD <<<<<<< HEAD _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_rm_http return $? else +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_rm_http + return $? + else +>>>>>>> no supporting HTTP API as well _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -78,6 +96,7 @@ dns_dynv6_rm() { _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 +<<<<<<< HEAD fi ======= _get_keyfile @@ -91,11 +110,14 @@ dns_dynv6_rm() { _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 >>>>>>> first attempt to make travis happy +======= + fi +>>>>>>> no supporting HTTP API as well } #################### Private functions below ################################## #Usage: No Input required #returns -#dynv6_keyfile the path to the new keyfile that has been generated +#dynv6_keyfile the path to the new key file that has been generated _generate_new_key() { dynv6_keyfile="$(eval echo ~"$USER")/.ssh/dynv6" _info "Path to key file used: $dynv6_keyfile" @@ -137,6 +159,7 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { +<<<<<<< HEAD dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" if [ "$dynv6_token" ]; then _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" @@ -144,6 +167,16 @@ _get_authentication() { _saveaccountconf_mutable dynv6_token "$dynv6_token" fi else +======= + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else +>>>>>>> no supporting HTTP API as well _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" _debug "Your key is $dynv6_keyfile" @@ -160,6 +193,7 @@ _get_authentication() { dynv6_keyfile="$KEY" fi _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" +<<<<<<< HEAD fi fi } @@ -302,5 +336,160 @@ _dynv6_rest() { response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" else response="$(_get "$dynv6_api/$ep")" +======= + fi +>>>>>>> no supporting HTTP API as well fi } + + + +_dns_dynv6_add_http(){ +_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain" ;then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi +} + +_dns_dynv6_rm_http(){ + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain" ;then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ] ; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} + + +#get the zoneid for a specifc record or zone +#usage: _get_zone_id §record +#where $record is the record to get the id for +#returns _zone_id the id of the zone +_get_zone_id(){ + record="$1" + _debug "getting zone id for $record" + _dynv6_rest GET zones + + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" +} + +_get_zone_name(){ + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n'| tr -d '{'|grep name|tr -d '"')" + _zone_name="${_zone_name#name:}" +} + +#usaage _get_record_id $zone_id $record +# where zone_id is thevalue returned by _get_zone_id +# and record ist in the form _acme.www for an fqdn of _acme.www.example.com +# returns _record_id +_get_record_id(){ + _zone_id="$1" + record="$2" + value="$3" + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response" ; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi +} + +_get_record_id_from_response(){ + response="$1" + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id |tr -d '"'|tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 +} +#usage: _set_record TXT _acme_challenge.www longvalue 12345678 +#zone id is optional can also be set as vairable bevor calling this method +_set_record(){ + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" +} +_del_record(){ + _zone_id=$1 + _record_id=$2 + _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" +} + +_dynv6_rest() { + m=$1 #method GET,POST,DELETE or PUT + ep="$2" #the endpoint + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$dynv6_token" | tr -d '"') + + export _H1="Authorization: Bearer $token_trimmed" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" + else + response="$(_get "$dynv6_api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} + From 6651801b3f958c8b2a0e2afad67b1b27cc85a46b Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:49:25 +0200 Subject: [PATCH 0946/2234] formatting --- dnsapi/dns_dynv6.sh | 205 ++++++++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 95 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 9c6d330d..4ab278ce 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -24,6 +24,7 @@ dns_dynv6_add() { _dns_dynv6_add_http return $? <<<<<<< HEAD +<<<<<<< HEAD ======= _get_keyfile _info "using keyfile $dynv6_keyfile" @@ -44,6 +45,9 @@ dns_dynv6_add() { ======= else >>>>>>> no supporting HTTP API as well +======= + else +>>>>>>> formatting _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -82,11 +86,15 @@ dns_dynv6_rm() { else ======= _get_authentication - if [ "$dynv6_token" ]; then + if [ "$dynv6_token" ]; then _dns_dynv6_rm_http return $? +<<<<<<< HEAD else >>>>>>> no supporting HTTP API as well +======= + else +>>>>>>> formatting _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -159,6 +167,7 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { +<<<<<<< HEAD <<<<<<< HEAD dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" if [ "$dynv6_token" ]; then @@ -177,6 +186,16 @@ _get_authentication() { dynv6_token="$(_readaccountconf_mutable dynv6_token)" else >>>>>>> no supporting HTTP API as well +======= + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else +>>>>>>> formatting _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" _debug "Your key is $dynv6_keyfile" @@ -342,142 +361,139 @@ _dynv6_rest() { fi } - - -_dns_dynv6_add_http(){ -_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain" ;then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _set_record TXT "$record" "$txtvalue" - if _contains "$response" "$txtvalue"; then - _info "Successfully added record" - return 0 - else - _err "Something went wrong while adding the record" - return 1 - fi -} - -_dns_dynv6_rm_http(){ +_dns_dynv6_add_http() { _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain" ;then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _get_record_id "$_zone_id" "$record" "$txtvalue" - _del_record "$_zone_id" "$_record_id" - if [ -z "$response" ] ; then - _info "Successfully deleted record" - return 0 - else - _err "Something went wrong while deleting the record" - return 1 - fi + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi } +_dns_dynv6_rm_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ]; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} #get the zoneid for a specifc record or zone #usage: _get_zone_id §record #where $record is the record to get the id for #returns _zone_id the id of the zone -_get_zone_id(){ +_get_zone_id() { record="$1" _debug "getting zone id for $record" _dynv6_rest GET zones - - zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" - #echo $zones - selected="" - for z in $zones; do - z="${z#name:}" - _debug zone: "$z" - if _contains "$record" "$z"; then - _debug "$z found in $record" - selected="$z" - fi - done - if [ -z "$selected" ]; then - _err "no zone found" - return 1 - fi - - zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" - _zone_id="${zone_id#id:}" - _debug "zone id: $_zone_id" + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" } -_get_zone_name(){ - _zone_id="$1" - _dynv6_rest GET zones/"$_zone_id" - _zone_name="$(echo "$response" | tr ',' '\n'| tr -d '{'|grep name|tr -d '"')" - _zone_name="${_zone_name#name:}" +_get_zone_name() { + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" + _zone_name="${_zone_name#name:}" } #usaage _get_record_id $zone_id $record # where zone_id is thevalue returned by _get_zone_id # and record ist in the form _acme.www for an fqdn of _acme.www.example.com # returns _record_id -_get_record_id(){ +_get_record_id() { _zone_id="$1" record="$2" value="$3" - _dynv6_rest GET "zones/$_zone_id/records" - if ! _get_record_id_from_response "$response" ; then - _err "no such record $record found in zone $_zone_id" - return 1 - fi + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response"; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi } -_get_record_id_from_response(){ +_get_record_id_from_response() { response="$1" - _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id |tr -d '"'|tr -d 'id:')" - #_record_id="${_record_id#id:}" - if [ -z "$_record_id" ]; then - _err "no such record: $record found in zone $_zone_id" - return 1 - fi - _debug "record id: $_record_id" - return 0 + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 } #usage: _set_record TXT _acme_challenge.www longvalue 12345678 #zone id is optional can also be set as vairable bevor calling this method -_set_record(){ - type="$1" - record="$2" - value="$3" - if [ "$4" ]; then - _zone_id="$4" - fi - data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" - #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' - echo "$data" - #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" - _dynv6_rest POST "zones/$_zone_id/records" "$data" +_set_record() { + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" } -_del_record(){ +_del_record() { _zone_id=$1 _record_id=$2 _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" } _dynv6_rest() { - m=$1 #method GET,POST,DELETE or PUT + m=$1 #method GET,POST,DELETE or PUT ep="$2" #the endpoint data="$3" _debug "$ep" token_trimmed=$(echo "$dynv6_token" | tr -d '"') - + export _H1="Authorization: Bearer $token_trimmed" export _H2="Content-Type: application/json" - + if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" @@ -492,4 +508,3 @@ _dynv6_rest() { _debug2 response "$response" return 0 } - From 8728389c881f83f72bb6f473093c055fc1cb91e1 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 16:01:46 +0200 Subject: [PATCH 0947/2234] formatting --- dnsapi/dns_dynv6.sh | 225 -------------------------------------------- 1 file changed, 225 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 4ab278ce..e51e118a 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,40 +14,11 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" -<<<<<<< HEAD -<<<<<<< HEAD - -======= ->>>>>>> no supporting HTTP API as well _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_add_http return $? -<<<<<<< HEAD -<<<<<<< HEAD -======= - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 - fi - _debug "found host on your account" - returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" - _debug "Dynv6 returend this after record was added: $returnval" - if _contains "$returnval" "created"; then - return 0 - elif _contains "$returnval" "updated"; then - return 0 ->>>>>>> first attempt to make travis happy else -======= - else ->>>>>>> no supporting HTTP API as well -======= - else ->>>>>>> formatting _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -77,24 +48,11 @@ dns_dynv6_rm() { _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" -<<<<<<< HEAD -<<<<<<< HEAD _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_rm_http return $? else -======= - _get_authentication - if [ "$dynv6_token" ]; then - _dns_dynv6_rm_http - return $? -<<<<<<< HEAD - else ->>>>>>> no supporting HTTP API as well -======= - else ->>>>>>> formatting _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -104,23 +62,7 @@ dns_dynv6_rm() { _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 -<<<<<<< HEAD fi -======= - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 - fi - _debug "found host on your account" - _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" - return 0 ->>>>>>> first attempt to make travis happy -======= - fi ->>>>>>> no supporting HTTP API as well } #################### Private functions below ################################## #Usage: No Input required @@ -167,8 +109,6 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { -<<<<<<< HEAD -<<<<<<< HEAD dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" if [ "$dynv6_token" ]; then _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" @@ -176,26 +116,6 @@ _get_authentication() { _saveaccountconf_mutable dynv6_token "$dynv6_token" fi else -======= - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" - else ->>>>>>> no supporting HTTP API as well -======= - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" - else ->>>>>>> formatting _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" _debug "Your key is $dynv6_keyfile" @@ -212,7 +132,6 @@ _get_authentication() { dynv6_keyfile="$KEY" fi _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" -<<<<<<< HEAD fi fi } @@ -339,150 +258,6 @@ _del_record() { _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" } -_dynv6_rest() { - m=$1 #method GET,POST,DELETE or PUT - ep="$2" #the endpoint - data="$3" - _debug "$ep" - - token_trimmed=$(echo "$dynv6_token" | tr -d '"') - - export _H1="Authorization: Bearer $token_trimmed" - export _H2="Content-Type: application/json" - - if [ "$m" != "GET" ]; then - _debug data "$data" - response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" - else - response="$(_get "$dynv6_api/$ep")" -======= - fi ->>>>>>> no supporting HTTP API as well - fi -} - -_dns_dynv6_add_http() { - _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain"; then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _set_record TXT "$record" "$txtvalue" - if _contains "$response" "$txtvalue"; then - _info "Successfully added record" - return 0 - else - _err "Something went wrong while adding the record" - return 1 - fi -} - -_dns_dynv6_rm_http() { - _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain"; then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _get_record_id "$_zone_id" "$record" "$txtvalue" - _del_record "$_zone_id" "$_record_id" - if [ -z "$response" ]; then - _info "Successfully deleted record" - return 0 - else - _err "Something went wrong while deleting the record" - return 1 - fi -} - -#get the zoneid for a specifc record or zone -#usage: _get_zone_id §record -#where $record is the record to get the id for -#returns _zone_id the id of the zone -_get_zone_id() { - record="$1" - _debug "getting zone id for $record" - _dynv6_rest GET zones - - zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" - #echo $zones - - selected="" - for z in $zones; do - z="${z#name:}" - _debug zone: "$z" - if _contains "$record" "$z"; then - _debug "$z found in $record" - selected="$z" - fi - done - if [ -z "$selected" ]; then - _err "no zone found" - return 1 - fi - - zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" - _zone_id="${zone_id#id:}" - _debug "zone id: $_zone_id" -} - -_get_zone_name() { - _zone_id="$1" - _dynv6_rest GET zones/"$_zone_id" - _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" - _zone_name="${_zone_name#name:}" -} - -#usaage _get_record_id $zone_id $record -# where zone_id is thevalue returned by _get_zone_id -# and record ist in the form _acme.www for an fqdn of _acme.www.example.com -# returns _record_id -_get_record_id() { - _zone_id="$1" - record="$2" - value="$3" - _dynv6_rest GET "zones/$_zone_id/records" - if ! _get_record_id_from_response "$response"; then - _err "no such record $record found in zone $_zone_id" - return 1 - fi -} - -_get_record_id_from_response() { - response="$1" - _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" - #_record_id="${_record_id#id:}" - if [ -z "$_record_id" ]; then - _err "no such record: $record found in zone $_zone_id" - return 1 - fi - _debug "record id: $_record_id" - return 0 -} -#usage: _set_record TXT _acme_challenge.www longvalue 12345678 -#zone id is optional can also be set as vairable bevor calling this method -_set_record() { - type="$1" - record="$2" - value="$3" - if [ "$4" ]; then - _zone_id="$4" - fi - data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" - #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' - echo "$data" - #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" - _dynv6_rest POST "zones/$_zone_id/records" "$data" -} -_del_record() { - _zone_id=$1 - _record_id=$2 - _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" -} - _dynv6_rest() { m=$1 #method GET,POST,DELETE or PUT ep="$2" #the endpoint From 4242354c036d42547eb5309d0892f0d055e6d2f4 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Fri, 28 Aug 2020 19:46:45 +0200 Subject: [PATCH 0948/2234] fix shfmt error --- dnsapi/dns_dynv6.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index e51e118a..9efc9aeb 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -260,7 +260,7 @@ _del_record() { _dynv6_rest() { m=$1 #method GET,POST,DELETE or PUT - ep="$2" #the endpoint + ep="$2" #the endpoint data="$3" _debug "$ep" From d73438a3979b303d19b3669bf3d73bbef22eb8dd Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Sep 2020 21:30:56 +0800 Subject: [PATCH 0949/2234] update comments --- .github/workflows/LetsEncrypt.yml | 5 ++++- acme.sh | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index afa4da68..5994fd9b 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -72,6 +72,9 @@ jobs: #The 80 port is used by Windows server, we have to use a custom port, ngrok will also use this port. Le_HTTPPort: 8888 steps: + - name: Set git to use LF + run: | + git config --global core.autocrlf false - uses: actions/checkout@v2 - name: Install cygwin base packages with chocolatey run: | @@ -87,7 +90,7 @@ jobs: echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' - name: Clone acmetest shell: cmd - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ && sed -i 's/\r//g' acmetest/acme.sh/acme.sh + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest shell: cmd run: cd ../acmetest && bash.exe -c ./letest.sh diff --git a/acme.sh b/acme.sh index c36ce80e..4c9fa96e 100755 --- a/acme.sh +++ b/acme.sh @@ -4978,7 +4978,7 @@ $_authorizations_map" fi } -#in_out_cert out_fullchain out out_ca +#in_out_cert out_fullchain out_ca _split_cert_chain() { _certf="$1" _fullchainf="$2" From d25b2890becb69edd2661d63074db0f6b450ab65 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Sep 2020 21:34:44 +0800 Subject: [PATCH 0950/2234] split shellcheck --- .github/workflows/LetsEncrypt.yml | 2 +- .github/workflows/shellcheck.yml | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 5994fd9b..16e42902 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -73,7 +73,7 @@ jobs: Le_HTTPPort: 8888 steps: - name: Set git to use LF - run: | + run: | git config --global core.autocrlf false - uses: actions/checkout@v2 - name: Install cygwin base packages with chocolatey diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 402492ad..099b9f7d 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -12,7 +12,7 @@ on: - '**.sh' jobs: - formatCheck: + ShellCheck: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -20,6 +20,11 @@ jobs: run: sudo apt-get install -y shellcheck - name: DoShellcheck run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" + + shfmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 - name: Install shfmt run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt - name: shfmt From 1f5b6a6a35c25785cf4681462138630c00ba9b03 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Sep 2020 21:39:44 +0800 Subject: [PATCH 0951/2234] fix filter to *.yml --- .github/workflows/LetsEncrypt.yml | 1 + .github/workflows/PebbleStrict.yml | 2 ++ .github/workflows/shellcheck.yml | 2 ++ 3 files changed, 5 insertions(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 16e42902..9a0175b5 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -11,6 +11,7 @@ on: - dev paths: - '**.sh' + - '**.yml' jobs: diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index ffc2ccdc..976e5373 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -5,11 +5,13 @@ on: - '*' paths: - '**.sh' + - '**.yml' pull_request: branches: - dev paths: - '**.sh' + - '**.yml' jobs: PebbleStrict: diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 099b9f7d..b22a2fd8 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -5,11 +5,13 @@ on: - '*' paths: - '**.sh' + - '**.yml' pull_request: branches: - dev paths: - '**.sh' + - '**.yml' jobs: ShellCheck: From 0c9c1ae673812c14aa4e8ac83831b31961ab9ade Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 2 Sep 2020 18:22:39 +0800 Subject: [PATCH 0952/2234] fix https://github.com/acmesh-official/acme.sh/issues/3140 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 4c9fa96e..40621515 100755 --- a/acme.sh +++ b/acme.sh @@ -4714,7 +4714,7 @@ $_authorizations_map" return 1 fi if [ -z "$Le_LinkOrder" ]; then - Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d ":" -f 2-)" + Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n \t" | cut -d ":" -f 2-)" fi _savedomainconf "Le_LinkOrder" "$Le_LinkOrder" From b5c382f929afc9dd7e4fcc3055079909e066d7be Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Thu, 3 Sep 2020 21:45:26 +0800 Subject: [PATCH 0953/2234] fix misaka.io api: breaking changes introduced by apiv1 --- dnsapi/dns_misaka.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_misaka.sh b/dnsapi/dns_misaka.sh index eed4170e..36ba5cfd 100755 --- a/dnsapi/dns_misaka.sh +++ b/dnsapi/dns_misaka.sh @@ -47,7 +47,7 @@ dns_misaka_add() { if [ "$count" = "0" ]; then _info "Adding record" - if _misaka_rest PUT "zones/${_domain}/recordsets/${_sub_domain}/TXT" "{\"records\":[{\"value\":\"\\\"$txtvalue\\\"\"}],\"filters\":[],\"ttl\":1}"; then + if _misaka_rest POST "zones/${_domain}/recordsets/${_sub_domain}/TXT" "{\"records\":[{\"value\":\"\\\"$txtvalue\\\"\"}],\"filters\":[],\"ttl\":1}"; then _debug response "$response" if _contains "$response" "$_sub_domain"; then _info "Added" @@ -61,7 +61,7 @@ dns_misaka_add() { else _info "Updating record" - _misaka_rest POST "zones/${_domain}/recordsets/${_sub_domain}/TXT?append=true" "{\"records\": [{\"value\": \"\\\"$txtvalue\\\"\"}],\"ttl\":1}" + _misaka_rest PUT "zones/${_domain}/recordsets/${_sub_domain}/TXT?append=true" "{\"records\": [{\"value\": \"\\\"$txtvalue\\\"\"}],\"ttl\":1}" if [ "$?" = "0" ] && _contains "$response" "$_sub_domain"; then _info "Updated!" #todo: check if the record takes effect From 2c7d2230b3c2f07127ef3ac4584e75b5f6d8a5b2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 4 Sep 2020 18:25:00 +0800 Subject: [PATCH 0954/2234] minor --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 40621515..3be3849d 100755 --- a/acme.sh +++ b/acme.sh @@ -956,9 +956,9 @@ _dbase64() { _checkcert() { _cf="$1" if [ "$DEBUG" ]; then - openssl x509 -noout -text -in "$_cf" + ${ACME_OPENSSL_BIN:-openssl} x509 -noout -text -in "$_cf" else - openssl x509 -noout -text -in "$_cf" >/dev/null 2>&1 + ${ACME_OPENSSL_BIN:-openssl} x509 -noout -text -in "$_cf" >/dev/null 2>&1 fi } @@ -3994,7 +3994,7 @@ _check_dns_entries() { _get_cert_issuers() { _cfile="$1" if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7"; then - ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | openssl pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 else ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 fi From 1e4ea900214e99f5676898948cf89139158a0278 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Sep 2020 11:26:53 +0800 Subject: [PATCH 0955/2234] add zerossl test --- .github/workflows/ZeroSSL.yml | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/ZeroSSL.yml diff --git a/.github/workflows/ZeroSSL.yml b/.github/workflows/ZeroSSL.yml new file mode 100644 index 00000000..97cb798b --- /dev/null +++ b/.github/workflows/ZeroSSL.yml @@ -0,0 +1,47 @@ +name: ZeroSSL +on: + push: + branches: + - '*' + paths: + - '**.sh' + - '**.yml' + + +jobs: + CheckToken: + runs-on: ubuntu-latest + outputs: + hasToken: ${{ steps.step_one.outputs.hasToken }} + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + steps: + - name: Set the value + id: step_one + run: | + if [ "$NGROK_TOKEN" ] ; then + echo "::set-output name=hasToken::true" + else + echo "::set-output name=hasToken::false" + fi + - name: Check the value + run: echo ${{ steps.step_one.outputs.hasToken }} + + ZeroSSL: + runs-on: ubuntu-latest + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'true')" + env: + ACME_DIRECTORY: https://acme.zerossl.com/v2/DV90 + TEST_LOCAL: 1 + TEST_CA: "ZeroSSL" + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh From 98124de362422b750ad3545eb68b595f4cf5597f Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Sep 2020 11:31:22 +0800 Subject: [PATCH 0956/2234] add email for zerossl --- .github/workflows/ZeroSSL.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ZeroSSL.yml b/.github/workflows/ZeroSSL.yml index 97cb798b..fd92d0fc 100644 --- a/.github/workflows/ZeroSSL.yml +++ b/.github/workflows/ZeroSSL.yml @@ -36,6 +36,7 @@ jobs: TEST_LOCAL: 1 TEST_CA: "ZeroSSL" NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + ACCOUNT_EMAIL: githubCI@acme.sh steps: - uses: actions/checkout@v2 From f405f4bbc445c49b304dcf37be4bbf52e6b9396f Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Sep 2020 12:22:09 +0800 Subject: [PATCH 0957/2234] fix zerossl --- .github/workflows/ZeroSSL.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ZeroSSL.yml b/.github/workflows/ZeroSSL.yml index fd92d0fc..e812ca13 100644 --- a/.github/workflows/ZeroSSL.yml +++ b/.github/workflows/ZeroSSL.yml @@ -45,4 +45,4 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && ./letest.sh + run: cd ../acmetest && sudo --preserve-env ./letest.sh From 6f62995c96029f1ef8d06d67bec5c1fd0d93d200 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Sep 2020 12:29:23 +0800 Subject: [PATCH 0958/2234] remove ZeroSSL test --- .github/workflows/ZeroSSL.yml | 48 ----------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 .github/workflows/ZeroSSL.yml diff --git a/.github/workflows/ZeroSSL.yml b/.github/workflows/ZeroSSL.yml deleted file mode 100644 index e812ca13..00000000 --- a/.github/workflows/ZeroSSL.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: ZeroSSL -on: - push: - branches: - - '*' - paths: - - '**.sh' - - '**.yml' - - -jobs: - CheckToken: - runs-on: ubuntu-latest - outputs: - hasToken: ${{ steps.step_one.outputs.hasToken }} - env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} - steps: - - name: Set the value - id: step_one - run: | - if [ "$NGROK_TOKEN" ] ; then - echo "::set-output name=hasToken::true" - else - echo "::set-output name=hasToken::false" - fi - - name: Check the value - run: echo ${{ steps.step_one.outputs.hasToken }} - - ZeroSSL: - runs-on: ubuntu-latest - needs: CheckToken - if: "contains(needs.CheckToken.outputs.hasToken, 'true')" - env: - ACME_DIRECTORY: https://acme.zerossl.com/v2/DV90 - TEST_LOCAL: 1 - TEST_CA: "ZeroSSL" - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} - ACCOUNT_EMAIL: githubCI@acme.sh - - steps: - - uses: actions/checkout@v2 - - name: Install tools - run: sudo apt-get install -y socat - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - name: Run acmetest - run: cd ../acmetest && sudo --preserve-env ./letest.sh From fabd26f85b40d0a6c9163c587672a5417c3075e5 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 8 Sep 2020 22:44:43 +0800 Subject: [PATCH 0959/2234] check token first --- .github/workflows/dockerhub.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index cf65f4a6..92308218 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -8,8 +8,28 @@ on: - '*' jobs: + CheckToken: + runs-on: ubuntu-latest + outputs: + hasToken: ${{ steps.step_one.outputs.hasToken }} + env: + DOCKER_PASSWORD : ${{ secrets.DOCKER_PASSWORD }} + steps: + - name: Set the value + id: step_one + run: | + if [ "$DOCKER_PASSWORD" ] ; then + echo "::set-output name=hasToken::true" + else + echo "::set-output name=hasToken::false" + fi + - name: Check the value + run: echo ${{ steps.step_one.outputs.hasToken }} + build: runs-on: ubuntu-latest + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'true')" steps: - name: checkout code uses: actions/checkout@v2 From c8ee9e64478b0ef5b0cc02402c8406e0051ff974 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 11 Sep 2020 23:11:26 +0800 Subject: [PATCH 0960/2234] add dns api check --- .github/workflows/DNS.yml | 132 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 .github/workflows/DNS.yml diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml new file mode 100644 index 00000000..eb6600f4 --- /dev/null +++ b/.github/workflows/DNS.yml @@ -0,0 +1,132 @@ +name: DNS +on: + push: + branches: + - 'dev' + paths: + - 'dnsapi/*.sh' + - '.github/workflows/DNS.yml' + pull_request: + branches: + - 'dev' + paths: + - 'dnsapi/*.sh' + - '.github/workflows/DNS.yml' + + +jobs: + CheckToken: + runs-on: ubuntu-latest + outputs: + hasToken: ${{ steps.step_one.outputs.hasToken }} + env: + ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + steps: + - name: Set the value + id: step_one + run: | + if [ "$${{ secrets.TokenName1 }}" ] ; then + echo "::set-output name=hasToken::true" + else + echo "::set-output name=hasToken::false" + fi + - name: Check the value + run: echo ${{ steps.step_one.outputs.hasToken }} + + Fail: + runs-on: ubuntu-latest + needs: CheckToken + if: "${{needs.CheckToken.outputs.hasToken}} == 'false'" + steps: + - name: Show help page + run: | + echo "Plese see this page to fix the error: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" + - name: Fail + if: "github.actor != 'Neilpang'" + run: false + + Docker: + runs-on: ubuntu-latest + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'true')" + env: + ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Set env file + run: cd ../acmetest && echo "${{ secrets.TokenName1 }}" >> env.list && echo "${{ secrets.TokenName2 }}" >> env.list && echo "TEST_DNS_NO_WILDCARD" >> env.list && echo "TEST_DNS_SLEEP" >> env.list + - name: Run acmetest + run: cd ../acmetest && ./rundocker.sh _cron + + MacOS: + runs-on: macos-latest + needs: Docker + env: + ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: brew update && brew install socat; + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh + + Windows: + runs-on: windows-latest + needs: MacOS + env: + ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - name: Set git to use LF + run: | + git config --global core.autocrlf false + - uses: actions/checkout@v2 + - name: Install cygwin base packages with chocolatey + run: | + choco config get cacheLocation + choco install --no-progress cygwin + shell: cmd + - name: Install cygwin additional packages + run: | + C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git + shell: cmd + - name: Set ENV + run: | + echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + shell: cmd + run: cd ../acmetest && bash.exe -c ./letest.sh + + From e7a6c17260731cf659c55cad9378d2187d846f2e Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 11 Sep 2020 23:35:27 +0800 Subject: [PATCH 0961/2234] fix dns check --- .github/workflows/DNS.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index eb6600f4..0f60ace2 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -20,12 +20,12 @@ jobs: outputs: hasToken: ${{ steps.step_one.outputs.hasToken }} env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + _ACME_CHECK_TOKEN_${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} steps: - name: Set the value id: step_one run: | - if [ "$${{ secrets.TokenName1 }}" ] ; then + if [ "$_ACME_CHECK_TOKEN_${{ secrets.TokenName1}}" ] ; then echo "::set-output name=hasToken::true" else echo "::set-output name=hasToken::false" @@ -36,9 +36,9 @@ jobs: Fail: runs-on: ubuntu-latest needs: CheckToken - if: "${{needs.CheckToken.outputs.hasToken}} == 'false'" + if: "contains(needs.CheckToken.outputs.hasToken, 'false')" steps: - - name: Show help page + - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" run: | echo "Plese see this page to fix the error: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" - name: Fail From b561666d803fadf8e226400d7115e92d8c43f1f6 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 12 Sep 2020 08:47:46 +0800 Subject: [PATCH 0962/2234] fix https://github.com/acmesh-official/acme.sh/issues/3159 --- dnsapi/dns_ovh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index dda47dda..f6f9689a 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -248,7 +248,7 @@ _ovh_authentication() { # _domain=domain.com _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From b147195189bc258d9fcf7b623f0154c8009c2741 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 12 Sep 2020 14:22:18 +0800 Subject: [PATCH 0963/2234] use testall target --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 0f60ace2..0274afcf 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -67,7 +67,7 @@ jobs: - name: Set env file run: cd ../acmetest && echo "${{ secrets.TokenName1 }}" >> env.list && echo "${{ secrets.TokenName2 }}" >> env.list && echo "TEST_DNS_NO_WILDCARD" >> env.list && echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest - run: cd ../acmetest && ./rundocker.sh _cron + run: cd ../acmetest && ./rundocker.sh testall MacOS: runs-on: macos-latest From 490a7d4a78b6b9282cf5769aa7cad44b54952c28 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Sep 2020 00:16:04 +0800 Subject: [PATCH 0964/2234] support more dns tokens --- .github/workflows/DNS.yml | 71 ++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 0274afcf..ae71d594 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -19,13 +19,11 @@ jobs: runs-on: ubuntu-latest outputs: hasToken: ${{ steps.step_one.outputs.hasToken }} - env: - _ACME_CHECK_TOKEN_${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} steps: - name: Set the value id: step_one run: | - if [ "$_ACME_CHECK_TOKEN_${{ secrets.TokenName1}}" ] ; then + if [ "${{secrets.TokenName1}}" ] ; then echo "::set-output name=hasToken::true" else echo "::set-output name=hasToken::false" @@ -50,11 +48,8 @@ jobs: needs: CheckToken if: "contains(needs.CheckToken.outputs.hasToken, 'true')" env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} - ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi @@ -65,7 +60,25 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Set env file - run: cd ../acmetest && echo "${{ secrets.TokenName1 }}" >> env.list && echo "${{ secrets.TokenName2 }}" >> env.list && echo "TEST_DNS_NO_WILDCARD" >> env.list && echo "TEST_DNS_SLEEP" >> env.list + run: | + cd ../acmetest + if [ "${{ secrets.TokenName1}}" ] ; then + echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> env.list + fi + if [ "${{ secrets.TokenName2}}" ] ; then + echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> env.list + fi + if [ "${{ secrets.TokenName3}}" ] ; then + echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> env.list + fi + if [ "${{ secrets.TokenName4}}" ] ; then + echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> env.list + fi + if [ "${{ secrets.TokenName5}}" ] ; then + echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list + fi + echo "TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall @@ -73,11 +86,8 @@ jobs: runs-on: macos-latest needs: Docker env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} - ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi @@ -90,17 +100,31 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && ./letest.sh + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh Windows: runs-on: windows-latest needs: MacOS env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} - ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi @@ -127,6 +151,23 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest shell: cmd - run: cd ../acmetest && bash.exe -c ./letest.sh + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + set ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + set ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + set ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + set ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + set ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + bash.exe -c ./letest.sh From b74a501fac2a8503e8d14a06d0ba6d966355ff56 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Sep 2020 21:51:21 +0800 Subject: [PATCH 0965/2234] fix for Windows --- .github/workflows/DNS.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index ae71d594..5591b8f1 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -150,24 +150,24 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - shell: cmd + shell: bash run: | if [ "${{ secrets.TokenName1}}" ] ; then - set ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} fi if [ "${{ secrets.TokenName2}}" ] ; then - set ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} fi if [ "${{ secrets.TokenName3}}" ] ; then - set ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} fi if [ "${{ secrets.TokenName4}}" ] ; then - set ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} fi if [ "${{ secrets.TokenName5}}" ] ; then - set ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} fi cd ../acmetest - bash.exe -c ./letest.sh + ./letest.sh From 5e3aa2db1d6af012d574cc5c71ee5a247b0c54e9 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Sep 2020 22:22:36 +0800 Subject: [PATCH 0966/2234] add debug info for duckdns --- dnsapi/dns_duckdns.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 11b685c0..7c2ecfb2 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -112,6 +112,9 @@ _duckdns_rest() { param="$2" _debug param "$param" url="$DuckDNS_API?$param" + if [ "$DEBUG" -gt 0 ]; then + url="$url&verbose=true" + fi _debug url "$url" # DuckDNS uses GET to update domain info From db24ca3dc19e246c7952ea5b8120dff14fc3acca Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Sep 2020 22:29:23 +0800 Subject: [PATCH 0967/2234] fix debug info --- dnsapi/dns_duckdns.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 7c2ecfb2..f0af2741 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -120,11 +120,13 @@ _duckdns_rest() { # DuckDNS uses GET to update domain info if [ "$method" = "GET" ]; then response="$(_get "$url")" + _debug2 response "$response" + if [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then + response="OK" + fi else _err "Unsupported method" return 1 fi - - _debug2 response "$response" return 0 } From 60fe987a5f8d43a6c67d048b79839200d7de5cf1 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 21 Sep 2020 19:57:10 +0800 Subject: [PATCH 0968/2234] enable for any branches. --- .github/workflows/DNS.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 5591b8f1..3ad9506b 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -1,8 +1,6 @@ name: DNS on: push: - branches: - - 'dev' paths: - 'dnsapi/*.sh' - '.github/workflows/DNS.yml' From 8694e0ad19f3320ab677cc72678a220d5b112b73 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Sep 2020 21:37:51 +0800 Subject: [PATCH 0969/2234] add freebsd --- .github/workflows/LetsEncrypt.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 9a0175b5..69ff35ff 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -96,4 +96,20 @@ jobs: shell: cmd run: cd ../acmetest && bash.exe -c ./letest.sh + FreeBSD: + runs-on: macos-latest + needs: Windows + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/freebsd@main + with: + envs: 'NGROK_TOKEN TEST_LOCAL' + prepare: pkg install -y socat + run: | + cd ../acmetest && ./letest.sh From 9073c4554f93dc0e934f206555e1b9b45fd59763 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Sep 2020 22:18:38 +0800 Subject: [PATCH 0970/2234] add curl to freebsd --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 69ff35ff..4a8d4336 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -109,7 +109,7 @@ jobs: - uses: vmactions/freebsd@main with: envs: 'NGROK_TOKEN TEST_LOCAL' - prepare: pkg install -y socat + prepare: pkg install -y socat curl run: | cd ../acmetest && ./letest.sh From 07979a13fb2d30c967111d93211ddbaa986171ca Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Sep 2020 22:57:26 +0800 Subject: [PATCH 0971/2234] add FreeBSD --- .github/workflows/DNS.yml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 3ad9506b..fd9a98b3 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -168,4 +168,42 @@ jobs: cd ../acmetest ./letest.sh + FreeBSD: + runs-on: macos-latest + needs: Windows + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/freebsd@main + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: pkg install -y socat curl + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + From be7b87cda32fb022d903e5c049ac02cf1a71d444 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 28 Sep 2020 21:50:20 +0800 Subject: [PATCH 0972/2234] fix message --- .github/workflows/DNS.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index fd9a98b3..191ae8c9 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -36,10 +36,10 @@ jobs: steps: - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" run: | - echo "Plese see this page to fix the error: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" - - name: Fail - if: "github.actor != 'Neilpang'" - run: false + echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" + if [ "${{github.actor}}" != "Neilpang" ]; then + false + fi Docker: runs-on: ubuntu-latest From f7e12b629f7bdf3b5f637189fafef0af37994f98 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Thu, 1 Oct 2020 11:26:29 +0200 Subject: [PATCH 0973/2234] Update CleverReach REST Endpoint --- deploy/cleverreach.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index d212846b..0fa07f4a 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -54,7 +54,7 @@ cleverreach_deploy() { _certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}" export _H1="Authorization: Bearer ${_access_token}" - _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl/${_cdomain}" "" "POST" "application/json")" + _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl" "" "POST" "application/json")" _debug "Destroying token at CleverReach" _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" From 238efb02c6c743a24142f724f0cee0223b66e033 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 16:17:16 +0800 Subject: [PATCH 0974/2234] update freebsd-vm --- .github/workflows/DNS.yml | 2 +- .github/workflows/LetsEncrypt.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 191ae8c9..1c0165c0 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,7 +183,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd@main + - uses: vmactions/freebsd-vm@v0.0.4 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 4a8d4336..ba5e933d 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,7 +106,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd@main + - uses: vmactions/freebsd-vm@v0.0.4 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl From c9ff536e245e17765a95bd06f41676536268cc23 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 16:20:27 +0800 Subject: [PATCH 0975/2234] minor --- .github/workflows/DNS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 1c0165c0..976aff56 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -206,4 +206,5 @@ jobs: cd ../acmetest ./letest.sh + From a017fbadd3b4debd2d605e35de883f5f39215b57 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 17:11:04 +0800 Subject: [PATCH 0976/2234] update badge --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 953c44a5..6fb88daf 100644 --- a/README.md +++ b/README.md @@ -57,26 +57,26 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) | NO | Status| Platform| |----|-------|---------| -|1|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu -|2|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian -|3|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS -|4|[![](https://acmesh-official.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) -|5|[![](https://acmesh-official.github.io/acmetest/status/freebsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|FreeBSD -|6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense -|7|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE -|8|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl) -|9|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux -|10|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora -|11|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux -|12|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux -|13|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) -|14|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|15|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD -|16|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia -|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) -|18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris -|19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux -|20|[![Build Status](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX +|1|[![MacOS](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX +|2|[![Windows](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included) +|3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD +|4|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense +|5|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD +|6|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris +|7|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu +|8|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian +|9|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS +|10|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE +|11|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl) +|12|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux +|13|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora +|14|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux +|15|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux +|16|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) +|17|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 +|18|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia +|19|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) +|20|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux |21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): From 4db7f6f59c64dcd3045365ef83629ea09b68337a Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 17:17:31 +0800 Subject: [PATCH 0977/2234] update badge --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6fb88daf..7215785c 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |1|[![MacOS](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX |2|[![Windows](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included) |3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD -|4|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense -|5|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD -|6|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris -|7|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu +|4|[![Ubuntu](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)| Ubuntu +|5|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense +|6|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD +|7|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris |8|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian |9|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS |10|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE From 8881a9f40e1ae697ec0004670cda032c5a17f1a1 Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Mon, 5 Oct 2020 15:46:18 +0200 Subject: [PATCH 0978/2234] Add BookMyName API support --- dnsapi/dns_bookmyname.sh | 93 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 dnsapi/dns_bookmyname.sh diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh new file mode 100644 index 00000000..188d93cb --- /dev/null +++ b/dnsapi/dns_bookmyname.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env sh + +#Here is a sample custom api script. +#This file name is "dns_bookmyname.sh" +#So, here must be a method dns_bookmyname_add() +#Which will be called by acme.sh to add the txt record to your api system. +#returns 0 means success, otherwise error. +# +#Author: Neilpang +#Report Bugs here: https://github.com/acmesh-official/acme.sh +# +######## Public functions ##################### + +# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide + + +# BMN urls: +# https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"' +# https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"' + +# Output: +#good: update done, cid 123456, domain id 456789, type txt, ip XXXXXXXX +#good: remove done 1, cid 123456, domain id 456789, ttl 300, type txt, ip XXXXXXXX + +# Be careful, BMN DNS servers can be slow to pick up changes; using dnssleep is thus advised. + +# Usage: +# export BOOKMYNAME_USERNAME="ABCDE-FREE" +# export BOOKMYNAME_PASSWORD="MyPassword" +# /usr/local/ssl/acme.sh/acme.sh --dns dns_bookmyname --dnssleep 600 --issue -d domain.tld + + +#Usage: dns_bookmyname_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_bookmyname_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using bookmyname" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}" + BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}" + + if [ -z "$BOOKMYNAME_USERNAME" ] || [ -z "$BOOKMYNAME_PASSWORD" ]; then + BOOKMYNAME_USERNAME="" + BOOKMYNAME_PASSWORD="" + _err "You didn't specify BookMyName username and password yet." + _err "Please specify them and try again." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable BOOKMYNAME_USERNAME "$BOOKMYNAME_USERNAME" + _saveaccountconf_mutable BOOKMYNAME_PASSWORD "$BOOKMYNAME_PASSWORD" + + + uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/" + data="?hostname=${fulldomain}&type=TXT&ttl=300&do=add&value=${txtvalue}" + result="$(_get "${uri}${data}")" + _debug "Result: $result" + + if ! _startswith "$result" 'good: update done, cid '; then + _err "Can't add $fulldomain" + return 1 + fi + +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_bookmyname_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using bookmyname" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}" + BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}" + + + uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/" + data="?hostname=${fulldomain}&type=TXT&ttl=300&do=remove&value=${txtvalue}" + result="$(_get "${uri}${data}")" + _debug "Result: $result" + + if ! _startswith "$result" 'good: remove done 1, cid '; then + _info "Can't remove $fulldomain" + fi + +} + +#################### Private functions below ################################## From 4ab5456a984eeafed71a6f56d1dda2830780c446 Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Mon, 5 Oct 2020 15:49:00 +0200 Subject: [PATCH 0979/2234] keep shfmt happy --- dnsapi/dns_bookmyname.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 188d93cb..99b3b680 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -13,7 +13,6 @@ # Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide - # BMN urls: # https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"' # https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"' @@ -29,7 +28,6 @@ # export BOOKMYNAME_PASSWORD="MyPassword" # /usr/local/ssl/acme.sh/acme.sh --dns dns_bookmyname --dnssleep 600 --issue -d domain.tld - #Usage: dns_bookmyname_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_bookmyname_add() { fulldomain=$1 @@ -53,7 +51,6 @@ dns_bookmyname_add() { _saveaccountconf_mutable BOOKMYNAME_USERNAME "$BOOKMYNAME_USERNAME" _saveaccountconf_mutable BOOKMYNAME_PASSWORD "$BOOKMYNAME_PASSWORD" - uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/" data="?hostname=${fulldomain}&type=TXT&ttl=300&do=add&value=${txtvalue}" result="$(_get "${uri}${data}")" @@ -78,7 +75,6 @@ dns_bookmyname_rm() { BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}" BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}" - uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/" data="?hostname=${fulldomain}&type=TXT&ttl=300&do=remove&value=${txtvalue}" result="$(_get "${uri}${data}")" From 7eea866869031a7a02aea7ada5c27edc37470458 Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Mon, 5 Oct 2020 15:57:52 +0200 Subject: [PATCH 0980/2234] BMN -> BookMyName --- dnsapi/dns_bookmyname.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 99b3b680..7acdea02 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -21,7 +21,7 @@ #good: update done, cid 123456, domain id 456789, type txt, ip XXXXXXXX #good: remove done 1, cid 123456, domain id 456789, ttl 300, type txt, ip XXXXXXXX -# Be careful, BMN DNS servers can be slow to pick up changes; using dnssleep is thus advised. +# Be careful, BookMyName DNS servers can be slow to pick up changes; using dnssleep is thus advised. # Usage: # export BOOKMYNAME_USERNAME="ABCDE-FREE" From 784b914e0741099feb1ccd22d2f09a91f09a0ded Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 9 Oct 2020 22:33:21 +0800 Subject: [PATCH 0981/2234] update freebsd --- .github/workflows/DNS.yml | 3 ++- .github/workflows/LetsEncrypt.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 976aff56..b06db229 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,10 +183,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl + usesh: true run: | if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index ba5e933d..d71f3ac1 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,10 +106,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl + usesh: true run: | cd ../acmetest && ./letest.sh From 4a60292f8284bc74c54d7f376bac70b2ded6ecd9 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 9 Oct 2020 22:33:21 +0800 Subject: [PATCH 0982/2234] update freebsd --- .github/workflows/DNS.yml | 3 ++- .github/workflows/LetsEncrypt.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 976aff56..b06db229 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,10 +183,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl + usesh: true run: | if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index ba5e933d..d71f3ac1 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,10 +106,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl + usesh: true run: | cd ../acmetest && ./letest.sh From d76fb566a258ad1bdefe0d7629493ca85fbcf51d Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Sat, 10 Oct 2020 11:02:47 +0200 Subject: [PATCH 0983/2234] no private functions --- dnsapi/dns_bookmyname.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 7acdea02..79e6b14d 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -85,5 +85,3 @@ dns_bookmyname_rm() { fi } - -#################### Private functions below ################################## From b71a088da73f4ecc3a4d3e4a79de0e838f532e5e Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Sat, 10 Oct 2020 11:46:32 +0200 Subject: [PATCH 0984/2234] Revert "no private functions" This reverts commit d76fb566a258ad1bdefe0d7629493ca85fbcf51d. --- dnsapi/dns_bookmyname.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 79e6b14d..7acdea02 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -85,3 +85,5 @@ dns_bookmyname_rm() { fi } + +#################### Private functions below ################################## From 05141b4f527d8aaacf75b9762e82affa1acac07c Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Mon, 21 Sep 2020 14:17:23 +0200 Subject: [PATCH 0985/2234] Added dnsapi/dns_infomaniak.sh --- dnsapi/dns_infomaniak.sh | 199 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100755 dnsapi/dns_infomaniak.sh diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh new file mode 100755 index 00000000..e2328a36 --- /dev/null +++ b/dnsapi/dns_infomaniak.sh @@ -0,0 +1,199 @@ +#!/usr/bin/env sh + +############################################################################### +# Infomaniak API integration +# +# To use this API you need visit the API dashboard of your account +# once logged into https://manager.infomaniak.com add /api/dashboard to the URL +# +# Please report bugs to +# https://github.com/acmesh-official/acme.sh/issues/3188 +# +# Note: the URL looks like this: +# https://manager.infomaniak.com/v3//api/dashboard +# Then generate a token with the scope Domain +# this is given as an environment variable INFOMANIAK_API_TOKEN +############################################################################### + +# base variables + +DEFAULT_INFOMANIAK_API_URL="https://api.infomaniak.com" +DEFAULT_INFOMANIAK_TTL=300 + +######## Public functions ##################### + +#Usage: dns_infomaniak_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_infomaniak_add() { + + INFOMANIAK_API_TOKEN="${INFOMANIAK_API_TOKEN:-$(_readaccountconf_mutable INFOMANIAK_API_TOKEN)}" + INFOMANIAK_API_URL="${INFOMANIAK_API_URL:-$(_readaccountconf_mutable INFOMANIAK_API_URL)}" + INFOMANIAK_TTL="${INFOMANIAK_TTL:-$(_readaccountconf_mutable INFOMANIAK_TTL)}" + + if [ -z "$INFOMANIAK_API_TOKEN" ]; then + INFOMANIAK_API_TOKEN="" + _err "Please provide a valid Infomaniak API token in variable INFOMANIAK_API_TOKEN" + return 1 + fi + + if [ -z "$INFOMANIAK_API_URL" ]; then + INFOMANIAK_API_URL="$DEFAULT_INFOMANIAK_API_URL" + fi + + if [ -z "$INFOMANIAK_TTL" ]; then + INFOMANIAK_TTL="$DEFAULT_INFOMANIAK_TTL" + fi + + #save the token to the account conf file. + _saveaccountconf_mutable INFOMANIAK_API_TOKEN "$INFOMANIAK_API_TOKEN" + + if [ "$INFOMANIAK_API_URL" != "$DEFAULT_INFOMANIAK_API_URL" ]; then + _saveaccountconf_mutable INFOMANIAK_API_URL "$INFOMANIAK_API_URL" + fi + + if [ "$INFOMANIAK_TTL" != "$DEFAULT_INFOMANIAK_TTL" ]; then + _saveaccountconf_mutable INFOMANIAK_TTL "$INFOMANIAK_TTL" + fi + + export _H1="Authorization: Bearer $INFOMANIAK_API_TOKEN" + export _H2="Content-Type: application/json" + + fulldomain="$1" + txtvalue="$2" + + _info "Infomaniak DNS API" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + fqdn=${fulldomain#_acme-challenge.} + + # guess which base domain to add record to + zone_and_id=$(_find_zone "$fqdn") + if [ -z "$zone_and_id" ]; then + _err "cannot find zone to modify" + return 1 + fi + zone=${zone_and_id% *} + domain_id=${zone_and_id#* } + + # extract first part of domain + key=${fulldomain%.$zone} + + _debug "zone:$zone id:$domain_id key:$key" + + # payload + data="{\"type\": \"TXT\", \"source\": \"$key\", \"target\": \"$txtvalue\", \"ttl\": $INFOMANIAK_TTL}" + + # API call + response=$(_post "$data" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record") + if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + _info "Record added" + _debug "Response: $response" + return 0 + fi + _err "could not create record" + _debug "Response: $response" + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_infomaniak_rm() { + + INFOMANIAK_API_TOKEN="${INFOMANIAK_API_TOKEN:-$(_readaccountconf_mutable INFOMANIAK_API_TOKEN)}" + INFOMANIAK_API_URL="${INFOMANIAK_API_URL:-$(_readaccountconf_mutable INFOMANIAK_API_URL)}" + INFOMANIAK_TTL="${INFOMANIAK_TTL:-$(_readaccountconf_mutable INFOMANIAK_TTL)}" + + if [ -z "$INFOMANIAK_API_TOKEN" ]; then + INFOMANIAK_API_TOKEN="" + _err "Please provide a valid Infomaniak API token in variable INFOMANIAK_API_TOKEN" + return 1 + fi + + if [ -z "$INFOMANIAK_API_URL" ]; then + INFOMANIAK_API_URL="$DEFAULT_INFOMANIAK_API_URL" + fi + + if [ -z "$INFOMANIAK_TTL" ]; then + INFOMANIAK_TTL="$DEFAULT_INFOMANIAK_TTL" + fi + + #save the token to the account conf file. + _saveaccountconf_mutable INFOMANIAK_API_TOKEN "$INFOMANIAK_API_TOKEN" + + if [ "$INFOMANIAK_API_URL" != "$DEFAULT_INFOMANIAK_API_URL" ]; then + _saveaccountconf_mutable INFOMANIAK_API_URL "$INFOMANIAK_API_URL" + fi + + if [ "$INFOMANIAK_TTL" != "$DEFAULT_INFOMANIAK_TTL" ]; then + _saveaccountconf_mutable INFOMANIAK_TTL "$INFOMANIAK_TTL" + fi + + export _H1="Authorization: Bearer $INFOMANIAK_API_TOKEN" + export _H2="ContentType: application/json" + + fulldomain=$1 + txtvalue=$2 + _info "Infomaniak DNS API" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + fqdn=${fulldomain#_acme-challenge.} + + # guess which base domain to add record to + zone_and_id=$(_find_zone "$fqdn") + if [ -z "$zone_and_id" ]; then + _err "cannot find zone to modify" + return 1 + fi + zone=${zone_and_id% *} + domain_id=${zone_and_id#* } + + # extract first part of domain + key=${fulldomain%.$zone} + + _debug "zone:$zone id:$domain_id key:$key" + + # find previous record + # shellcheck disable=SC1004 + record_id=$(_get "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record" | sed 's/.*"data":\[\(.*\)\]}/\1/; s/},{/}\ +{/g' | sed -n 's/.*"id":"*\([0-9]*\)"*.*"source_idn":"'"$fulldomain"'".*"target_idn":"'"$txtvalue"'".*/\1/p') + if [ -z "$record_id" ]; then + _err "could not find record to delete" + return 1 + fi + _debug "record_id: $record_id" + + # API call + response=$(_post "" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record/$record_id" "" DELETE) + if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + _info "Record deleted" + return 0 + fi + _err "could not delete record" + return 1 +} + +#################### Private functions below ################################## + +_get_domain_id() { + domain="$1" + + # shellcheck disable=SC1004 + _get "${INFOMANIAK_API_URL}/1/product?service_name=domain&customer_name=$domain" | sed 's/.*"data":\[{\(.*\)}\]}/\1/; s/,/\ +/g' | sed -n 's/^"id":\(.*\)/\1/p' +} + +_find_zone() { + zone="$1" + + # find domain in list, removing . parts sequentialy + while echo "$zone" | grep -q '\.'; do + _debug "testing $zone" + id=$(_get_domain_id "$zone") + if [ -n "$id" ]; then + echo "$zone $id" + return + fi + zone=${zone#*.} + done +} From 472dbd641ca9e545523ab059fc8316885906b482 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Fri, 2 Oct 2020 12:47:33 +0200 Subject: [PATCH 0986/2234] dnsapi/dns_infomaniak.sh: Replace grep by _contains --- dnsapi/dns_infomaniak.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh index e2328a36..765cf39d 100755 --- a/dnsapi/dns_infomaniak.sh +++ b/dnsapi/dns_infomaniak.sh @@ -85,7 +85,7 @@ dns_infomaniak_add() { # API call response=$(_post "$data" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record") - if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + if [ -n "$response" ] && echo "$response" | _contains '"result":"success"'; then _info "Record added" _debug "Response: $response" return 0 @@ -165,7 +165,7 @@ dns_infomaniak_rm() { # API call response=$(_post "" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record/$record_id" "" DELETE) - if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + if [ -n "$response" ] && echo "$response" | _contains '"result":"success"'; then _info "Record deleted" return 0 fi @@ -187,7 +187,7 @@ _find_zone() { zone="$1" # find domain in list, removing . parts sequentialy - while echo "$zone" | grep -q '\.'; do + while _contains "$zone" '\.'; do _debug "testing $zone" id=$(_get_domain_id "$zone") if [ -n "$id" ]; then From f864416e39753b66f26d8d3fa19cbb094493731a Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Thu, 8 Oct 2020 23:42:05 +0200 Subject: [PATCH 0987/2234] Fix DNS workflow use variables TEST_DNS_SLEEP and TEST_DNS_NO_WILDCARD --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index b06db229..1909cb03 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -75,8 +75,8 @@ jobs: if [ "${{ secrets.TokenName5}}" ] ; then echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list fi - echo "TEST_DNS_NO_WILDCARD" >> env.list - echo "TEST_DNS_SLEEP" >> env.list + echo "TEST_DNS_NO_WILDCARD=$TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_SLEEP=$TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall From e05dc99006f5548c20f5caec8b1a89a23ed492a0 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Sat, 10 Oct 2020 18:20:26 +0200 Subject: [PATCH 0988/2234] Revert "Fix DNS workflow use variables TEST_DNS_SLEEP and TEST_DNS_NO_WILDCARD" This reverts commit f864416e39753b66f26d8d3fa19cbb094493731a. --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 1909cb03..b06db229 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -75,8 +75,8 @@ jobs: if [ "${{ secrets.TokenName5}}" ] ; then echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list fi - echo "TEST_DNS_NO_WILDCARD=$TEST_DNS_NO_WILDCARD" >> env.list - echo "TEST_DNS_SLEEP=$TEST_DNS_SLEEP" >> env.list + echo "TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall From 0781e8cf12f09fad71d0d63ce59c49c701b35d50 Mon Sep 17 00:00:00 2001 From: Marcel Waldvogel Date: Mon, 12 Oct 2020 13:52:57 +0200 Subject: [PATCH 0989/2234] Use random hour for cron job The hour for the cron job isn't really random (as is the minute), but assuming acme.sh installation times are not correlated, neither will be the resulting cron start times. --- acme.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 3be3849d..eb8aca49 100755 --- a/acme.sh +++ b/acme.sh @@ -5590,6 +5590,7 @@ installcronjob() { fi _t=$(_time) random_minute=$(_math $_t % 60) + random_hour=$(_math $_t / 60 % 24) if ! _exists "$_CRONTAB" && _exists "fcrontab"; then _CRONTAB="fcrontab" @@ -5616,12 +5617,12 @@ installcronjob() { if _exists uname && uname -a | grep SunOS >/dev/null; then $_CRONTAB -l | { cat - echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" + echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" } | $_CRONTAB -- else $_CRONTAB -l | { cat - echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" + echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" } | $_CRONTAB - fi fi From 92dbe6cdf8eb7d3b07b84876db79032c1d41f9c6 Mon Sep 17 00:00:00 2001 From: Marcel Waldvogel Date: Mon, 12 Oct 2020 14:20:40 +0200 Subject: [PATCH 0990/2234] Simplify and clarify SunOS crontab differences --- acme.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index eb8aca49..2ea5ccd7 100755 --- a/acme.sh +++ b/acme.sh @@ -5615,16 +5615,14 @@ installcronjob() { _info "Installing cron job" if ! $_CRONTAB -l | grep "$PROJECT_ENTRY --cron"; then if _exists uname && uname -a | grep SunOS >/dev/null; then - $_CRONTAB -l | { - cat - echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" - } | $_CRONTAB -- + _CRONTAB_STDIN="$_CRONTAB --" else - $_CRONTAB -l | { - cat - echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" - } | $_CRONTAB - + _CRONTAB_STDIN="$_CRONTAB -" fi + $_CRONTAB -l | { + cat + echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" + } | $_CRONTAB_STDIN fi if [ "$?" != "0" ]; then _err "Install cron job failed. You need to manually renew your certs." From ea3e6dae93e76dfe79272c6cb9dd0c6b9acbb297 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Wed, 14 Oct 2020 14:49:09 -0400 Subject: [PATCH 0991/2234] remove uuidgen --- dnsapi/dns_edgedns.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 94cf809c..89e77936 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -359,11 +359,7 @@ _edgedns_eg_timestamp() { } _edgedns_new_nonce() { - _nonce=$(uuidgen -r) - _ret="$?" - if [ "$_ret" -ne 0 ]; then - _nonce=$(echo "EDGEDNS$(_time)" | _digest sha1 hex | cut -c 1-32) - fi + _nonce=$(echo "EDGEDNS$(_time)" | _digest sha1 hex | cut -c 1-32) _debug3 "_nonce" "$_nonce" } From 6bc00fc5e51c9cfa9319e4e44265b52d059230e2 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 16 Oct 2020 18:47:02 +0800 Subject: [PATCH 0992/2234] Update DNS.yml --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index b06db229..25d92137 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,7 +183,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.5 + - uses: vmactions/freebsd-vm@v0.0.7 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl From 348bae53fe04ce0723adba6921ea74292cd9af7a Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 16 Oct 2020 18:47:27 +0800 Subject: [PATCH 0993/2234] Update LetsEncrypt.yml --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index d71f3ac1..39e91161 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,7 +106,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.5 + - uses: vmactions/freebsd-vm@v0.0.7 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl From 6ad5ea169679e22de4f0314b312e886b03ac6bc7 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Fri, 16 Oct 2020 10:16:25 -0400 Subject: [PATCH 0994/2234] use _digest instead of openssl --- dnsapi/dns_edgedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 89e77936..7ab448d2 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -440,7 +440,7 @@ _edgedns_base64_sha256() { _debug2 "Creating sha256 digest" trg=$1 _secure_debug2 "digest data" "$trg" - digest="$(echo "$trg" | tr -d "\n\r" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -binary | _base64)" + digest="$(echo "$trg" | tr -d "\n\r" | _digest "sha256")" _sha256_out="$(echo "$digest" | tr -d "\n\r" | iconv -f utf-8)" _secure_debug2 "digest decode" "$_sha256_out" } From c61495df5239f7034531fc787bcd91d5deb42372 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Fri, 16 Oct 2020 10:32:01 -0400 Subject: [PATCH 0995/2234] fix format --- dnsapi/dns_edgedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 7ab448d2..05c8e886 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -440,7 +440,7 @@ _edgedns_base64_sha256() { _debug2 "Creating sha256 digest" trg=$1 _secure_debug2 "digest data" "$trg" - digest="$(echo "$trg" | tr -d "\n\r" | _digest "sha256")" + digest="$(echo "$trg" | tr -d "\n\r" | _digest "sha256")" _sha256_out="$(echo "$digest" | tr -d "\n\r" | iconv -f utf-8)" _secure_debug2 "digest decode" "$_sha256_out" } From 5dbfc2786d9a5eb6018dadbd4d834b58fef21087 Mon Sep 17 00:00:00 2001 From: Adrian Fedoreanu Date: Mon, 19 Oct 2020 20:45:52 +0200 Subject: [PATCH 0996/2234] fix dnsapi/dns_1984hosting --- dnsapi/dns_1984hosting.sh | 84 +++++++++++++++------------------------ 1 file changed, 33 insertions(+), 51 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index bcb675ab..d720c1c5 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -40,8 +40,35 @@ dns_1984hosting_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _1984hosting_add_txt_record "$_domain" "$_sub_domain" "$txtvalue" - return $? + _debug "Add TXT record $fulldomain with value '$txtvalue'" + value="$(printf '%s' "$txtvalue" | _url_encode)" + url="https://management.1984hosting.com/domains/entry/" + + postdata="entry=new" + postdata="$postdata&type=TXT" + postdata="$postdata&ttl=3600" + postdata="$postdata&zone=$_domain" + postdata="$postdata&host=$_sub_domain" + postdata="$postdata&rdata=%22$value%22" + _debug2 postdata "$postdata" + + _authpost "$postdata" "$url" + response="$(echo "$_response" | _normalizeJson)" + _debug2 response "$response" + + if _contains "$response" '"haserrors": true'; then + _err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post" + return 1 + elif _contains "$response" ""; then + _err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file" + return 1 + elif _contains "$response" '"auth": false'; then + _err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie" + return 1 + fi + + _info "Added acme challenge TXT record for $fulldomain at 1984Hosting" + return 0 } #Usage: fulldomain txtvalue @@ -67,57 +94,10 @@ dns_1984hosting_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _1984hosting_delete_txt_record "$_domain" "$_sub_domain" - return $? -} - -#################### Private functions below ################################## - -# usage _1984hosting_add_txt_record domain subdomain value -# returns 0 success -_1984hosting_add_txt_record() { - _debug "Add TXT record $1 with value '$3'" - domain="$1" - subdomain="$2" - value="$(printf '%s' "$3" | _url_encode)" - url="https://management.1984hosting.com/domains/entry/" - - postdata="entry=new" - postdata="$postdata&type=TXT" - postdata="$postdata&ttl=3600" - postdata="$postdata&zone=$domain" - postdata="$postdata&host=$subdomain" - postdata="$postdata&rdata=%22$value%22" - _debug2 postdata "$postdata" - - _authpost "$postdata" "$url" - response="$(echo "$_response" | _normalizeJson)" - _debug2 response "$response" - - if _contains "$response" '"haserrors": true'; then - _err "1984Hosting failed to add TXT record for $subdomain bad RC from _post" - return 1 - elif _contains "$response" ""; then - _err "1984Hosting failed to add TXT record for $subdomain. Check $HTTP_HEADER file" - return 1 - elif _contains "$response" '"auth": false'; then - _err "1984Hosting failed to add TXT record for $subdomain. Invalid or expired cookie" - return 1 - fi - - _info "Added acme challenge TXT record for $fulldomain at 1984Hosting" - return 0 -} - -# usage _1984hosting_delete_txt_record entry_id -# returns 0 success -_1984hosting_delete_txt_record() { _debug "Delete $fulldomain TXT record" - domain="$1" - subdomain="$2" url="https://management.1984hosting.com/domains" - _htmlget "$url" "$domain" + _htmlget "$url" "$_domain" _debug2 _response "$_response" zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" _debug2 zone_id "$zone_id" @@ -126,7 +106,7 @@ _1984hosting_delete_txt_record() { return 1 fi - _htmlget "$url/$zone_id" "$subdomain" + _htmlget "$url/$zone_id" "$_sub_domain" _debug2 _response "$_response" entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" _debug2 entry_id "$entry_id" @@ -148,6 +128,8 @@ _1984hosting_delete_txt_record() { return 0 } +#################### Private functions below ################################## + # usage: _1984hosting_login username password # returns 0 success _1984hosting_login() { From 23eccb2f20f4c2f3d5350d268fb94226b34712d7 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 21 Oct 2020 15:00:33 +0800 Subject: [PATCH 0997/2234] Update LetsEncrypt.yml --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 39e91161..5f0bba72 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -58,7 +58,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install tools - run: brew update && brew install socat; + run: brew install socat - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest From 5fd0e5add2b29c6e05b482c3c49bf82b9a905e22 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 21 Oct 2020 15:07:25 +0800 Subject: [PATCH 0998/2234] Update DNS.yml --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 25d92137..b7153506 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -94,7 +94,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install tools - run: brew update && brew install socat; + run: brew install socat - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest From d5674c85d7735f2f3cdf6e44c2f9f1059d844d20 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Fri, 21 Aug 2020 17:15:18 -0400 Subject: [PATCH 0999/2234] initial commit --- dnsapi/dns_edgedns.sh | 379 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 379 insertions(+) create mode 100755 dnsapi/dns_edgedns.sh diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh new file mode 100755 index 00000000..75ef4f9b --- /dev/null +++ b/dnsapi/dns_edgedns.sh @@ -0,0 +1,379 @@ +#!/usr/bin/env sh + +# Akamai Edge DNS v2 API +# User must provide Open Edgegrid API credentials to the EdgeDNS installation. The remote user in EdgeDNS must have CRUD access to +# Edge DNS Zones and Recordsets, e.g. DNS—Zone Record Management authorization + +# Report bugs to https://control.akamai.com/apps/support-ui/#/contact-support + +# Values to export: +# --EITHER-- +# *** NOT IMPLEMENTED YET *** +# specify Edgegrid credentials file and section +# AKAMAI_EDGERC= +# AKAMAI_EDGERC_SECTION="default" +## --OR-- +# specify indiviual credentials +# export AKAMAI_HOST = +# export AKAMAI_ACCESS_TOKEN = +# export AKAMAI_CLIENT_TOKEN = +# export AKAMAI_CLIENT_SECRET = + +ACME_EDGEDNS_VERSION="0.1.0" + +######## Public functions ##################### + +# Usage: dns_edgedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record +# +dns_edgedns_add() { + fulldomain=$1 + txtvalue=$2 + + _debug "ENTERING DNS_EDGEDNS_ADD" + + _debug2 "fulldomain" "$fulldomain" + _debug2 "txtvalue" "$txtvalue" + + if ! _EDGEDNS_credentials; then + _err "$@" + return 1 + fi + + if ! _EDGEDNS_getZoneInfo "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + _debug2 "Add: zone" "${zone}" + acmeRecordURI=$(printf "%s/%s/names/%s/type/TXT" "${edge_endpoint}" "${zone}" "${fulldomain}") + _debug3 "Add URL" "$acmeRecordURI" + # Get existing TXT record + _edge_result=$(_edgedns_rest GET "$acmeRecordURI") + _api_status="$?" + if [ "$_api_status" -ne 0 ] && [ "$_edge_result" != "404" ]; then + _err "$(printf "Failure accessing Akamai Edge DNS API Server. Error: %s" "$_edge_result")" + return 1 + fi + rdata="\"$txtvalue\"" + record_op="POST" + if [ "$_api_status" -eq 0 ]; then + # record already exists. Get existing record data and update + record_op="PUT" + rdlist=$(echo -n "$response" | _egrep_o "\"rdata\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"") + _debug2 "existing TXT found" + _debug2 "record data" "$rdlist" + # value already there? + if _contains "$rdlist" "$txtvalue" ; then + return 0 + fi + comma="," + rdata="$rdata$comma\"${txtvalue}\"" + fi + _debug2 "new/updated rdata: " "${rdata}" + # Add the txtvalue TXT Record + body="{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":600, \"rdata\":"[${rdata}]"}" + _debug3 "Add body '${body}'" + _edge_result=$(_edgedns_rest "$record_op" "$acmeRecordURI" "$body") + _api_status="$?" + if [ "$_api_status" -eq 0 ]; then + _log "$(printf "Text value %s added to recordset %s" "${txtvalue}" "${fulldomain}")" + return 0 + else + _err "$(printf "error adding TXT record for validation. Error: %s" "$_edge_result")" + return 1 + fi +} + +# Usage: dns_edgedns_rm _acme-challenge.www.domain.com +# Used to delete txt record +# +dns_edgedns_rm() { + fulldomain=$1 +} + +#################### Private functions below ################################## + +_EDGEDNS_credentials() { + _debug "GettingEdge DNS credentials" + _log $(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION}) + args_missing=0 + if [ -z "${AKAMAI_ACCESS_TOKEN}" ]; then + AKAMAI_ACCESS_TOKEN="" + AKAMAI_CLIENT_TOKEN="" + AKAMAI_HOST="" + AKAMAI_CLIENT_SECRET="" + _err "AKAMAI_ACCESS_TOKEN is missing" + args_missing=1 + fi + if [ -z "$AKAMAI_CLIENT_TOKEN" ]; then + AKAMAI_ACCESS_TOKEN="" + AKAMAI_CLIENT_TOKEN="" + AKAMAI_HOST="" + AKAMAI_CLIENT_SECRET="" + _err "AKAMAI_CLIENT_TOKEN is missing" + args_missing=1 + fi + if [ -z "${AKAMAI_HOST}" ]; then + AKAMAI_ACCESS_TOKEN="" + AKAMAI_CLIENT_TOKEN="" + AKAMAI_HOST="" + AKAMAI_CLIENT_SECRET="" + _err "AKAMAI_HOST is missing" + args_missing=1 + fi + if [ -z "${AKAMAI_CLIENT_SECRET}" ]; then + AKAMAI_ACCESS_TOKEN="" + AKAMAI_CLIENT_TOKEN="" + AKAMAI_HOST="" + AKAMAI_CLIENT_SECRET="" + _err "AKAMAI_CLIENT_SECRET is missing" + args_missing=1 + fi + + if [ "${args_missing}" = 1 ]; then + _err "You have not properly specified the EdgeDNS Open Edgegrid API credentials. Please try again." + return 1 + else + _saveaccountconf_mutable AKAMAI_ACCESS_TOKEN "${AKAMAI_ACCESS_TOKEN}" + _saveaccountconf_mutable AKAMAI_CLIENT_TOKEN "${AKAMAI_CLIENT_TOKEN}" + _saveaccountconf_mutable AKAMAI_HOST "${AKAMAI_HOST}" + _saveaccountconf_mutable AKAMAI_CLIENT_SECRET "${AKAMAI_CLIENT_SECRET}" + # Set whether curl should use secure or insecure mode + fi + export HTTPS_INSECURE=0 # All Edgegrid API calls are secure + edge_endpoint=$(printf "https://%s/config-dns/v2/zones" "${AKAMAI_HOST}") + _debug3 "Edge API Endpoint:" "${edge_endpoint}" + +} + +_EDGEDNS_getZoneInfo() { + _debug "Getting Zoneinfo" + zoneEnd=false + curZone=$1 + while [ -n "${zoneEnd}" ]; do + # we can strip the first part of the fulldomain, since its just the _acme-challenge string + curZone="${curZone#*.}" + # suffix . needed for zone -> domain.tld. + # create zone get url + get_zone_url=$(printf "%s/%s" "${edge_endpoint}" "${curZone}") + _debug3 "Zone Get: " "${get_zone_url}" + curResult=$(_edgedns_rest GET "$get_zone_url") + retVal=$? + if [ $retVal -ne 0 ]; then + if ["$curResult" != "404" ]; then + _err "$(printf "Managed zone validation failed. Error response: %s" "$retVal")" + return 1 + fi + fi + + if _contains "${curResult}" "\"zone\":" ; then + _debug2 "Zone data" "${curResult}" + zone=$(echo -n "${curResult}" | _egrep_o "\"zone\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"") + _debug2 "Zone" "${zone}" + zoneFound="" + zoneEnd="" + return 0 + fi + + if [ "${curZone#*.}" != "$curZone" ]; then + _debug2 $(printf "%s still contains a '.' - so we can check next higher level" "$curZone") + else + zoneEnd=true + _err "Couldn't retrieve zone data." + return 1 + fi + done + _err "Failed to retrieve zone data." + return 2 +} + +_edgedns_headers="" + +_edgedns_rest() { + _debug "Handling API Request" + m=$1 + # Assume endpoint is complete path, including query args if applicable + ep=$2 + body_data=$3 + _edgedns_content_type="" + _request_url_path="$ep" + _request_body="$body_data" + _request_method="$m" + _edgedns_headers="" + tab="" + _edgedns_headers="${_edgedns_headers}${tab}Host: ${AKAMAI_HOST}" + tab="\t" + # Set in acme.sh _post/_get + #_edgedns_headers="${_edgedns_headers}${tab}User-Agent:ACME DNSAPI Edge DNS version ${ACME_EDGEDNS_VERSION}" + _edgedns_headers="${_edgedns_headers}${tab}Accept: application/json" + if [ "$m" != "GET" ] && [ "$m" != "DELETE" ] ; then + _edgedns_content_type="application/json;charset=UTF-8" + _utf8_body_data="$(echo -n "$ _request_body" | iconv -t utf-8)" + _utf8_body_len="$(echo -n "$_utf8_body_data" | awk '{print length}')" + _edgedns_headers="${_edgedns_headers}${tab}Content-Length: ${_utf8_body_len}" + fi + _made_auth_header=$(_edgedns_make_auth_header) + _edgedns_headers="${_edgedns_headers}${tab}Authorization: ${_made_auth_header}" + _secure_debug2 "Made Auth Header" "${_made_auth_header}" + hdr_indx=1 + work_header="${_edgedns_headers}${tab}" + _debug3 "work_header" "${work_header}" + while [ "${work_header}" ]; do + entry="${work_header%%\\t*}"; work_header="${work_header#*\\t}" + export "$(printf "_H%s=%s" "${hdr_indx}" "${entry}")" + _debug2 "Request Header " "${entry}" + hdr_indx=$(( hdr_indx + 1 )) + done + + # clear headers from previous request to avoid getting wrong http code on timeouts + :>"$HTTP_HEADER" + _debug "$ep" + if [ "$m" != "GET" ]; then + _debug "Method data" "$data" + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + response="$(_post "$_utf8_body_data" "$ep" false "$m")" + else + response="$(_get "$ep")" + fi + + _ret="$?" + _debug "response" "$response" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + _debug2 "http response code" "$_code" + + if [ "$_code" = "200" ] || [ "$_code" = "201" ]; then + # All good + response="$(echo "$response" | _normalizeJson)" + echo -n "${response}" + return 0 + fi + + if [ "$_code" = "204" ]; then + # Success, no body + echo -n "" + return 0 + fi + + if [ "$_code" = "400" ]; then + _err "Bad request presented" + _log "$(printf "Headers: %s" "$_edgedns_headers")" + _log "$(printf "Method: %s" "$_request_method")" + _log "$(printf "URL: %s" "$ep")" + _log "$(printf "Data: %s" "$data")" + fi + + if [ "$_code" = "403" ]; then + _err "access denied make sure your Edgegrid cedentials are correct." + fi + + echo "$_code" + return 1 +} + +_edgedns_eg_timestamp() { + _eg_timestamp=$(date -u "+%Y%m%dT%H:%M:%S+0000") +} + +_edgedns_new_nonce() { + _nonce=$(uuidgen -r) +} + +_edgedns_make_auth_header() { + _debug "Constructing Auth Header" + _edgedns_eg_timestamp + _edgedns_new_nonce + # "Unsigned authorization header: 'EG1-HMAC-SHA256 client_token=block;access_token=block;timestamp=20200806T14:16:33+0000;nonce=72cde72c-82d9-4721-9854-2ba057929d67;'" + _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "${AKAMAI_CLIENT_TOKEN}" "${AKAMAI_ACCESS_TOKEN}" "${_eg_timestamp}" "${_nonce}")" + _secure_debug2 "Unsigned Auth Header: " "$_auth_header" + + _sig="$(_edgedns_sign_request)" + _signed_auth_header="$(printf "%ssignature=%s" "${_auth_header}" "${_sig}")" + _secure_debug2 "Signed Auth Header: " "${_signed_auth_header}" + echo -n "${_signed_auth_header}" +} + +_edgedns_sign_request() { + _debug2 "Signing http request" + _signed_data=$(_edgedns_make_data_to_sign "${_auth_header}") + _secure_debug2 "Returned signed data" "$_signed_data" + _key=$(_edgedns_make_signing_key "${_eg_timestamp}") + _signed_req=$(_edgedns_base64_hmac_sha256 "$_signed_data" "$_key") + _secure_debug2 "Signed Request" "${_signed_req}" + echo -n "${_signed_req}" +} + +_edgedns_make_signing_key() { + _debug2 "Creating sigining key" + ts=$1 + _signing_key=$(_edgedns_base64_hmac_sha256 "$ts" "${AKAMAI_CLIENT_SECRET}") + _secure_debug2 "Signing Key" "${_signing_key}" + echo -n "${_signing_key}" + +} + +_edgedns_make_data_to_sign() { + _debug2 "Processing data to sign" + hdr=$1 + _secure_debug2 "hdr" "$hdr" + content_hash=$(_edgedns_make_content_hash) + path="$(echo -n "${_request_url_path}" |sed 's/https\?:\/\///')" + path="${path#*$AKAMAI_HOST}" + _debug "hier path" "${path}" + # dont expose headers to sign so use MT string + data="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "${_request_method}" "${AKAMAI_HOST}" "${path}" "" "${content_hash}" "$hdr")" + _secure_debug2 "Data to Sign" "${data}" + echo -n "${data}" +} + +_edgedns_make_content_hash() { + _debug2 "Generating content hash" + prep_body="" + _hash="" + _debug2 "Request method" "${_request_method}" + if [ "${_request_method}" != "POST" ] || [ -z "${_request_body}" ]; then + echo -n "${prep_body}" + return 0 + fi + prep_body="$(echo -n "${_request_body}")" + _debug2 "Req body" "${prep_body}" + _hash=$(_edgedns_base64_sha256 "${prep_body}") + _debug2 "Content hash" "${_hash}" + echo -n "${_hash}" +} + +_edgedns_base64_hmac_sha256() { + _debug2 "Generating hmac" + data=$1 + key=$2 + encoded_data="$(echo -n "${data}" | iconv -t utf-8)" + encoded_key="$(echo -n "${key}" | iconv -t utf-8)" + _secure_debug2 "encoded data" "${encoded_data}" + _secure_debug2 "encoded key" "${encoded_key}" + #key_hex="$(_durl_replace_base64 "$key" | _dbase64 | _hex_dump | tr -d ' ')" + #data_sig="$(printf "%s" "$encoded_data" | _hmac sha256 "${key_hex}" | _base64 | _url_replace)" + + data_sig="$(echo -n "$encoded_data" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hmac $encoded_key -binary | _base64)" + _secure_debug2 "data_sig:" "${data_sig}" + out="$(echo -n "${data_sig}" | iconv -f utf-8)" + _secure_debug2 "hmac" "${out}" + echo -n "${out}" +} + +_edgedns_base64_sha256() { + _debug2 "Creating sha256 digest" + trg=$1 + utf8_str="$(echo -n "${trg}" | iconv -t utf-8)" + _secure_debug2 "digest data" "$trg" + _secure_debug2 "encoded digest data" "${utf8_str}" + digest="$(echo -n "${trg}" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -binary | _base64)" + out="$(echo -n "${digest}" | iconv -f utf-8)" + _secure_debug2 "digest decode" "${out}" + echo -n "${out}" +} + +#_edgedns_parse_edgerc() { +# filepath=$1 +# section=$2 +#} + + From 8e09e1b248ec77ae4954e6928b22dc083c9174be Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Wed, 26 Aug 2020 16:11:11 -0400 Subject: [PATCH 1000/2234] debugging and cleanup --- dnsapi/dns_edgedns.sh | 281 ++++++++++++++++++++++++++---------------- 1 file changed, 175 insertions(+), 106 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 75ef4f9b..7be49761 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -29,9 +29,7 @@ ACME_EDGEDNS_VERSION="0.1.0" dns_edgedns_add() { fulldomain=$1 txtvalue=$2 - _debug "ENTERING DNS_EDGEDNS_ADD" - _debug2 "fulldomain" "$fulldomain" _debug2 "txtvalue" "$txtvalue" @@ -39,44 +37,53 @@ dns_edgedns_add() { _err "$@" return 1 fi - if ! _EDGEDNS_getZoneInfo "$fulldomain"; then _err "Invalid domain" return 1 fi - _debug2 "Add: zone" "${zone}" - acmeRecordURI=$(printf "%s/%s/names/%s/type/TXT" "${edge_endpoint}" "${zone}" "${fulldomain}") + _debug2 "Add: zone" "$zone" + acmeRecordURI=$(printf "%s/%s/names/%s/types/TXT" "$edge_endpoint" "$zone" "$fulldomain") _debug3 "Add URL" "$acmeRecordURI" # Get existing TXT record _edge_result=$(_edgedns_rest GET "$acmeRecordURI") _api_status="$?" - if [ "$_api_status" -ne 0 ] && [ "$_edge_result" != "404" ]; then - _err "$(printf "Failure accessing Akamai Edge DNS API Server. Error: %s" "$_edge_result")" - return 1 + _debug3 "_edge_result" "$_edge_result" + if [ "$_api_status" -ne 0 ]; then + if [ "$curResult" = "FATAL" ]; then + _err "$(printf "Fatal error: acme API function call : %s" "$retVal")" + fi + if [ "$_edge_result" != "404" ]; then + _err "$(printf "Failure accessing Akamai Edge DNS API Server. Error: %s" "$_edge_result")" + return 1 + fi fi - rdata="\"$txtvalue\"" + rdata="\"${txtvalue}\"" record_op="POST" if [ "$_api_status" -eq 0 ]; then # record already exists. Get existing record data and update record_op="PUT" - rdlist=$(echo -n "$response" | _egrep_o "\"rdata\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"") - _debug2 "existing TXT found" - _debug2 "record data" "$rdlist" + rdlist="${_edge_result#*\"rdata\":[}" + rdlist="${rdlist%%]*}" + rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\") + _debug3 "existing TXT found" + _debug3 "record data" "$rdlist" # value already there? if _contains "$rdlist" "$txtvalue" ; then return 0 fi - comma="," - rdata="$rdata$comma\"${txtvalue}\"" + _txt_val="" + while [ "$_txt_val" != "$rdlist" ] && [ "${rdlist}" ]; do + _txt_val="${rdlist%%,*}"; rdlist="${rdlist#*,}" + rdata="${rdata},\"${_txt_val}\"" + done fi - _debug2 "new/updated rdata: " "${rdata}" # Add the txtvalue TXT Record body="{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":600, \"rdata\":"[${rdata}]"}" _debug3 "Add body '${body}'" _edge_result=$(_edgedns_rest "$record_op" "$acmeRecordURI" "$body") _api_status="$?" if [ "$_api_status" -eq 0 ]; then - _log "$(printf "Text value %s added to recordset %s" "${txtvalue}" "${fulldomain}")" + _log "$(printf "Text value %s added to recordset %s" "$txtvalue" "$fulldomain")" return 0 else _err "$(printf "error adding TXT record for validation. Error: %s" "$_edge_result")" @@ -84,20 +91,89 @@ dns_edgedns_add() { fi } -# Usage: dns_edgedns_rm _acme-challenge.www.domain.com +# Usage: dns_edgedns_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Used to delete txt record # dns_edgedns_rm() { fulldomain=$1 + txtvalue=$2 + _debug "ENTERING DNS_EDGEDNS_RM" + _debug2 "fulldomain" "$fulldomain" + _debug2 "txtvalue" "$txtvalue" + + if ! _EDGEDNS_credentials; then + _err "$@" + return 1 + fi + if ! _EDGEDNS_getZoneInfo "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + _debug2 "RM: zone" "${zone}" + acmeRecordURI=$(printf "%s/%s/names/%s/types/TXT" "${edge_endpoint}" "$zone" "$fulldomain") + _debug3 "RM URL" "$acmeRecordURI" + # Get existing TXT record + _edge_result=$(_edgedns_rest GET "$acmeRecordURI") + _api_status="$?" + if [ "$_api_status" -ne 0 ]; then + if [ "$curResult" = "FATAL" ]; then + _err "$(printf "Fatal error: acme API function call : %s" "$retVal")" + fi + if [ "$_edge_result" != "404" ]; then + _err "$(printf "Failure accessing Akamai Edge DNS API Server. Error: %s" "$_edge_result")" + return 1 + fi + fi + _debug3 "_edge_result" "$_edge_result" + record_op="DELETE" + body="" + if [ "$_api_status" -eq 0 ]; then + # record already exists. Get existing record data and update + rdlist="${_edge_result#*\"rdata\":[}" + rdlist="${rdlist%%]*}" + rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\") + _debug3 "rdlist" "$rdlist" + if [ -n "$rdlist" ]; then + record_op="PUT" + comma="" + rdata="" + _txt_val="" + while [ "$_txt_val" != "$rdlist" ] && [ "$rdlist" ]; do + _txt_val="${rdlist%%,*}"; rdlist="${rdlist#*,}" + _debug3 "_txt_val" "$_txt_val" + _debug3 "txtvalue" "$txtvalue" + if ! _contains "$_txt_val" "$txtvalue" ; then + rdata="${rdata}${comma}\"${_txt_val}\"" + comma="," + fi + done + if [ -z "$rdata" ]; then + record_op="DELETE" + else + # Recreate the txtvalue TXT Record + body="{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":600, \"rdata\":"[${rdata}]"}" + _debug3 "body" "$body" + fi + fi + fi + _edge_result=$(_edgedns_rest "$record_op" "$acmeRecordURI" "$body") + _api_status="$?" + if [ "$_api_status" -eq 0 ]; then + _log "$(printf "Text value %s removed from recordset %s" "$txtvalue" "$fulldomain")" + return 0 + else + _err "$(printf "error removing TXT record for validation. Error: %s" "$_edge_result")" + return 1 + fi } #################### Private functions below ################################## _EDGEDNS_credentials() { _debug "GettingEdge DNS credentials" - _log $(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION}) + _log "$(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION})" args_missing=0 - if [ -z "${AKAMAI_ACCESS_TOKEN}" ]; then + if [ -z "$AKAMAI_ACCESS_TOKEN" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" AKAMAI_HOST="" @@ -113,7 +189,7 @@ _EDGEDNS_credentials() { _err "AKAMAI_CLIENT_TOKEN is missing" args_missing=1 fi - if [ -z "${AKAMAI_HOST}" ]; then + if [ -z "$AKAMAI_HOST" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" AKAMAI_HOST="" @@ -121,7 +197,7 @@ _EDGEDNS_credentials() { _err "AKAMAI_HOST is missing" args_missing=1 fi - if [ -z "${AKAMAI_CLIENT_SECRET}" ]; then + if [ -z "$AKAMAI_CLIENT_SECRET" ]; then AKAMAI_ACCESS_TOKEN="" AKAMAI_CLIENT_TOKEN="" AKAMAI_HOST="" @@ -130,19 +206,19 @@ _EDGEDNS_credentials() { args_missing=1 fi - if [ "${args_missing}" = 1 ]; then + if [ "$args_missing" = 1 ]; then _err "You have not properly specified the EdgeDNS Open Edgegrid API credentials. Please try again." return 1 else - _saveaccountconf_mutable AKAMAI_ACCESS_TOKEN "${AKAMAI_ACCESS_TOKEN}" - _saveaccountconf_mutable AKAMAI_CLIENT_TOKEN "${AKAMAI_CLIENT_TOKEN}" - _saveaccountconf_mutable AKAMAI_HOST "${AKAMAI_HOST}" - _saveaccountconf_mutable AKAMAI_CLIENT_SECRET "${AKAMAI_CLIENT_SECRET}" + _saveaccountconf_mutable AKAMAI_ACCESS_TOKEN "$AKAMAI_ACCESS_TOKEN" + _saveaccountconf_mutable AKAMAI_CLIENT_TOKEN "$AKAMAI_CLIENT_TOKEN" + _saveaccountconf_mutable AKAMAI_HOST "$AKAMAI_HOST" + _saveaccountconf_mutable AKAMAI_CLIENT_SECRET "$AKAMAI_CLIENT_SECRET" # Set whether curl should use secure or insecure mode fi export HTTPS_INSECURE=0 # All Edgegrid API calls are secure - edge_endpoint=$(printf "https://%s/config-dns/v2/zones" "${AKAMAI_HOST}") - _debug3 "Edge API Endpoint:" "${edge_endpoint}" + edge_endpoint=$(printf "https://%s/config-dns/v2/zones" "$AKAMAI_HOST") + _debug3 "Edge API Endpoint:" "$edge_endpoint" } @@ -150,33 +226,34 @@ _EDGEDNS_getZoneInfo() { _debug "Getting Zoneinfo" zoneEnd=false curZone=$1 - while [ -n "${zoneEnd}" ]; do + while [ -n "$zoneEnd" ]; do # we can strip the first part of the fulldomain, since its just the _acme-challenge string curZone="${curZone#*.}" # suffix . needed for zone -> domain.tld. # create zone get url - get_zone_url=$(printf "%s/%s" "${edge_endpoint}" "${curZone}") + get_zone_url=$(printf "%s/%s" "$edge_endpoint" "$curZone") _debug3 "Zone Get: " "${get_zone_url}" curResult=$(_edgedns_rest GET "$get_zone_url") retVal=$? - if [ $retVal -ne 0 ]; then - if ["$curResult" != "404" ]; then - _err "$(printf "Managed zone validation failed. Error response: %s" "$retVal")" + if [ "$retVal" -ne 0 ]; then + if [ "$curResult" = "FATAL" ]; then + _err "$(printf "Fatal error: acme API function call : %s" "$retVal")" + fi + if [ "$curResult" != "404" ]; then + err "$(printf "Managed zone validation failed. Error response: %s" "$retVal")" return 1 fi fi - - if _contains "${curResult}" "\"zone\":" ; then + if _contains "$curResult" "\"zone\":" ; then _debug2 "Zone data" "${curResult}" - zone=$(echo -n "${curResult}" | _egrep_o "\"zone\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"") - _debug2 "Zone" "${zone}" - zoneFound="" + zone=$(echo "${curResult}" | _egrep_o "\"zone\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"") + _debug3 "Zone" "${zone}" zoneEnd="" return 0 fi if [ "${curZone#*.}" != "$curZone" ]; then - _debug2 $(printf "%s still contains a '.' - so we can check next higher level" "$curZone") + _debug3 "$(printf "%s still contains a '.' - so we can check next higher level" "$curZone")" else zoneEnd=true _err "Couldn't retrieve zone data." @@ -205,52 +282,55 @@ _edgedns_rest() { tab="\t" # Set in acme.sh _post/_get #_edgedns_headers="${_edgedns_headers}${tab}User-Agent:ACME DNSAPI Edge DNS version ${ACME_EDGEDNS_VERSION}" - _edgedns_headers="${_edgedns_headers}${tab}Accept: application/json" + _edgedns_headers="${_edgedns_headers}${tab}Accept: application/json,*/*" if [ "$m" != "GET" ] && [ "$m" != "DELETE" ] ; then - _edgedns_content_type="application/json;charset=UTF-8" - _utf8_body_data="$(echo -n "$ _request_body" | iconv -t utf-8)" - _utf8_body_len="$(echo -n "$_utf8_body_data" | awk '{print length}')" - _edgedns_headers="${_edgedns_headers}${tab}Content-Length: ${_utf8_body_len}" + _edgedns_content_type="application/json" + _debug3 "_request_body" "$_request_body" + _body_len=$(echo "$_request_body" | tr -d "\n\r" | awk '{print length}') + _edgedns_headers="${_edgedns_headers}${tab}Content-Length: ${_body_len}" fi - _made_auth_header=$(_edgedns_make_auth_header) - _edgedns_headers="${_edgedns_headers}${tab}Authorization: ${_made_auth_header}" - _secure_debug2 "Made Auth Header" "${_made_auth_header}" + _edgedns_make_auth_header + _edgedns_headers="${_edgedns_headers}${tab}Authorization: ${_signed_auth_header}" + _secure_debug2 "Made Auth Header" "$_signed_auth_header" hdr_indx=1 work_header="${_edgedns_headers}${tab}" - _debug3 "work_header" "${work_header}" - while [ "${work_header}" ]; do + _debug3 "work_header" "$work_header" + while [ "$work_header" ]; do entry="${work_header%%\\t*}"; work_header="${work_header#*\\t}" - export "$(printf "_H%s=%s" "${hdr_indx}" "${entry}")" - _debug2 "Request Header " "${entry}" + export "$(printf "_H%s=%s" "$hdr_indx" "$entry")" + _debug2 "Request Header " "$entry" hdr_indx=$(( hdr_indx + 1 )) done # clear headers from previous request to avoid getting wrong http code on timeouts - :>"$HTTP_HEADER" - _debug "$ep" + : >"$HTTP_HEADER" + _debug2 "$ep" if [ "$m" != "GET" ]; then - _debug "Method data" "$data" + _debug3 "Method data" "$data" # body url [needbase64] [POST|PUT|DELETE] [ContentType] - response="$(_post "$_utf8_body_data" "$ep" false "$m")" + response=$(_post "$_request_body" "$ep" false "$m" "$_edgedns_content_type") else - response="$(_get "$ep")" + response=$(_get "$ep") fi - _ret="$?" - _debug "response" "$response" + if [ "$_ret" -ne 0 ]; then + _err "$(printf "acme.sh API function call failed. Error: %s" "$_ret")" + echo "FATAL" + return "$_ret" + fi + _debug2 "response" "${response}" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _debug2 "http response code" "$_code" - if [ "$_code" = "200" ] || [ "$_code" = "201" ]; then # All good - response="$(echo "$response" | _normalizeJson)" - echo -n "${response}" + response="$(echo "${response}" | _normalizeJson)" + echo "$response" return 0 fi if [ "$_code" = "204" ]; then # Success, no body - echo -n "" + echo "$_code" return 0 fi @@ -283,31 +363,30 @@ _edgedns_make_auth_header() { _edgedns_eg_timestamp _edgedns_new_nonce # "Unsigned authorization header: 'EG1-HMAC-SHA256 client_token=block;access_token=block;timestamp=20200806T14:16:33+0000;nonce=72cde72c-82d9-4721-9854-2ba057929d67;'" - _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "${AKAMAI_CLIENT_TOKEN}" "${AKAMAI_ACCESS_TOKEN}" "${_eg_timestamp}" "${_nonce}")" + _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "$AKAMAI_CLIENT_TOKEN" "$AKAMAI_ACCESS_TOKEN" "$_eg_timestamp" "$_nonce")" _secure_debug2 "Unsigned Auth Header: " "$_auth_header" - _sig="$(_edgedns_sign_request)" - _signed_auth_header="$(printf "%ssignature=%s" "${_auth_header}" "${_sig}")" + _edgedns_sign_request + _signed_auth_header="$(printf "%ssignature=%s" "$_auth_header" "$_signed_req")" _secure_debug2 "Signed Auth Header: " "${_signed_auth_header}" - echo -n "${_signed_auth_header}" } _edgedns_sign_request() { _debug2 "Signing http request" - _signed_data=$(_edgedns_make_data_to_sign "${_auth_header}") - _secure_debug2 "Returned signed data" "$_signed_data" - _key=$(_edgedns_make_signing_key "${_eg_timestamp}") - _signed_req=$(_edgedns_base64_hmac_sha256 "$_signed_data" "$_key") - _secure_debug2 "Signed Request" "${_signed_req}" - echo -n "${_signed_req}" + _edgedns_make_data_to_sign "$_auth_header" + _secure_debug2 "Returned signed data" "$_mdata" + _edgedns_make_signing_key "$_eg_timestamp" + _edgedns_base64_hmac_sha256 "$_mdata" "$_signing_key" + _signed_req="$_hmac_out" + _secure_debug2 "Signed Request" "$_signed_req" } _edgedns_make_signing_key() { _debug2 "Creating sigining key" ts=$1 - _signing_key=$(_edgedns_base64_hmac_sha256 "$ts" "${AKAMAI_CLIENT_SECRET}") - _secure_debug2 "Signing Key" "${_signing_key}" - echo -n "${_signing_key}" + _edgedns_base64_hmac_sha256 "$ts" "$AKAMAI_CLIENT_SECRET" + _signing_key="$_hmac_out" + _secure_debug2 "Signing Key" "$_signing_key" } @@ -315,60 +394,50 @@ _edgedns_make_data_to_sign() { _debug2 "Processing data to sign" hdr=$1 _secure_debug2 "hdr" "$hdr" - content_hash=$(_edgedns_make_content_hash) - path="$(echo -n "${_request_url_path}" |sed 's/https\?:\/\///')" + _edgedns_make_content_hash + path="$(echo "$_request_url_path" | tr -d "\n\r" | sed 's/https\?:\/\///')" path="${path#*$AKAMAI_HOST}" - _debug "hier path" "${path}" + _debug "hier path" "$path" # dont expose headers to sign so use MT string - data="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "${_request_method}" "${AKAMAI_HOST}" "${path}" "" "${content_hash}" "$hdr")" - _secure_debug2 "Data to Sign" "${data}" - echo -n "${data}" + _mdata="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "$_request_method" "$AKAMAI_HOST" "$path" "" "$_hash" "$hdr")" + _secure_debug2 "Data to Sign" "$_mdata" } _edgedns_make_content_hash() { _debug2 "Generating content hash" - prep_body="" _hash="" _debug2 "Request method" "${_request_method}" - if [ "${_request_method}" != "POST" ] || [ -z "${_request_body}" ]; then - echo -n "${prep_body}" + if [ "$_request_method" != "POST" ] || [ -z "$_request_body" ]; then return 0 fi - prep_body="$(echo -n "${_request_body}")" - _debug2 "Req body" "${prep_body}" - _hash=$(_edgedns_base64_sha256 "${prep_body}") - _debug2 "Content hash" "${_hash}" - echo -n "${_hash}" + _debug2 "Req body" "$_request_body" + _edgedns_base64_sha256 "$_request_body" + _hash="$_sha256_out" + _debug2 "Content hash" "$_hash" } _edgedns_base64_hmac_sha256() { _debug2 "Generating hmac" data=$1 key=$2 - encoded_data="$(echo -n "${data}" | iconv -t utf-8)" - encoded_key="$(echo -n "${key}" | iconv -t utf-8)" - _secure_debug2 "encoded data" "${encoded_data}" - _secure_debug2 "encoded key" "${encoded_key}" - #key_hex="$(_durl_replace_base64 "$key" | _dbase64 | _hex_dump | tr -d ' ')" - #data_sig="$(printf "%s" "$encoded_data" | _hmac sha256 "${key_hex}" | _base64 | _url_replace)" + encoded_data="$(echo "$data" | iconv -t utf-8)" + encoded_key="$(echo "$key" | iconv -t utf-8)" + _secure_debug2 "encoded data" "$encoded_data" + _secure_debug2 "encoded key" "$encoded_key" - data_sig="$(echo -n "$encoded_data" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hmac $encoded_key -binary | _base64)" - _secure_debug2 "data_sig:" "${data_sig}" - out="$(echo -n "${data_sig}" | iconv -f utf-8)" - _secure_debug2 "hmac" "${out}" - echo -n "${out}" + data_sig="$(echo "$encoded_data" | tr -d "\n\r" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hmac "$encoded_key" -binary | _base64)" + _secure_debug2 "data_sig:" "$data_sig" + _hmac_out="$(echo "$data_sig" | tr -d "\n\r" | iconv -f utf-8)" + _secure_debug2 "hmac" "$_hmac_out" } _edgedns_base64_sha256() { _debug2 "Creating sha256 digest" trg=$1 - utf8_str="$(echo -n "${trg}" | iconv -t utf-8)" _secure_debug2 "digest data" "$trg" - _secure_debug2 "encoded digest data" "${utf8_str}" - digest="$(echo -n "${trg}" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -binary | _base64)" - out="$(echo -n "${digest}" | iconv -f utf-8)" - _secure_debug2 "digest decode" "${out}" - echo -n "${out}" + digest="$(echo "$trg" | tr -d "\n\r" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -binary | _base64)" + _sha256_out="$(echo "$digest" | tr -d "\n\r" | iconv -f utf-8)" + _secure_debug2 "digest decode" "$_sha256_out" } #_edgedns_parse_edgerc() { From 596a1764ef799eb08f8004f0ea68a15fc977376e Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Wed, 26 Aug 2020 18:07:46 -0400 Subject: [PATCH 1001/2234] vetted by shfmt --- dnsapi/dns_edgedns.sh | 49 ++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 7be49761..2072637a 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -7,15 +7,15 @@ # Report bugs to https://control.akamai.com/apps/support-ui/#/contact-support # Values to export: -# --EITHER-- +# --EITHER-- # *** NOT IMPLEMENTED YET *** # specify Edgegrid credentials file and section -# AKAMAI_EDGERC= +# AKAMAI_EDGERC= # AKAMAI_EDGERC_SECTION="default" ## --OR-- # specify indiviual credentials # export AKAMAI_HOST = -# export AKAMAI_ACCESS_TOKEN = +# export AKAMAI_ACCESS_TOKEN = # export AKAMAI_CLIENT_TOKEN = # export AKAMAI_CLIENT_SECRET = @@ -32,7 +32,7 @@ dns_edgedns_add() { _debug "ENTERING DNS_EDGEDNS_ADD" _debug2 "fulldomain" "$fulldomain" _debug2 "txtvalue" "$txtvalue" - + if ! _EDGEDNS_credentials; then _err "$@" return 1 @@ -42,7 +42,7 @@ dns_edgedns_add() { return 1 fi _debug2 "Add: zone" "$zone" - acmeRecordURI=$(printf "%s/%s/names/%s/types/TXT" "$edge_endpoint" "$zone" "$fulldomain") + acmeRecordURI=$(printf "%s/%s/names/%s/types/TXT" "$edge_endpoint" "$zone" "$fulldomain") _debug3 "Add URL" "$acmeRecordURI" # Get existing TXT record _edge_result=$(_edgedns_rest GET "$acmeRecordURI") @@ -68,13 +68,14 @@ dns_edgedns_add() { _debug3 "existing TXT found" _debug3 "record data" "$rdlist" # value already there? - if _contains "$rdlist" "$txtvalue" ; then + if _contains "$rdlist" "$txtvalue"; then return 0 fi _txt_val="" while [ "$_txt_val" != "$rdlist" ] && [ "${rdlist}" ]; do - _txt_val="${rdlist%%,*}"; rdlist="${rdlist#*,}" - rdata="${rdata},\"${_txt_val}\"" + _txt_val="${rdlist%%,*}" + rdlist="${rdlist#*,}" + rdata="${rdata},\"${_txt_val}\"" done fi # Add the txtvalue TXT Record @@ -139,10 +140,11 @@ dns_edgedns_rm() { rdata="" _txt_val="" while [ "$_txt_val" != "$rdlist" ] && [ "$rdlist" ]; do - _txt_val="${rdlist%%,*}"; rdlist="${rdlist#*,}" + _txt_val="${rdlist%%,*}" + rdlist="${rdlist#*,}" _debug3 "_txt_val" "$_txt_val" _debug3 "txtvalue" "$txtvalue" - if ! _contains "$_txt_val" "$txtvalue" ; then + if ! _contains "$_txt_val" "$txtvalue"; then rdata="${rdata}${comma}\"${_txt_val}\"" comma="," fi @@ -170,7 +172,7 @@ dns_edgedns_rm() { #################### Private functions below ################################## _EDGEDNS_credentials() { - _debug "GettingEdge DNS credentials" + _debug "GettingEdge DNS credentials" _log "$(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION})" args_missing=0 if [ -z "$AKAMAI_ACCESS_TOKEN" ]; then @@ -216,7 +218,7 @@ _EDGEDNS_credentials() { _saveaccountconf_mutable AKAMAI_CLIENT_SECRET "$AKAMAI_CLIENT_SECRET" # Set whether curl should use secure or insecure mode fi - export HTTPS_INSECURE=0 # All Edgegrid API calls are secure + export HTTPS_INSECURE=0 # All Edgegrid API calls are secure edge_endpoint=$(printf "https://%s/config-dns/v2/zones" "$AKAMAI_HOST") _debug3 "Edge API Endpoint:" "$edge_endpoint" @@ -244,7 +246,7 @@ _EDGEDNS_getZoneInfo() { return 1 fi fi - if _contains "$curResult" "\"zone\":" ; then + if _contains "$curResult" "\"zone\":"; then _debug2 "Zone data" "${curResult}" zone=$(echo "${curResult}" | _egrep_o "\"zone\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"") _debug3 "Zone" "${zone}" @@ -283,7 +285,7 @@ _edgedns_rest() { # Set in acme.sh _post/_get #_edgedns_headers="${_edgedns_headers}${tab}User-Agent:ACME DNSAPI Edge DNS version ${ACME_EDGEDNS_VERSION}" _edgedns_headers="${_edgedns_headers}${tab}Accept: application/json,*/*" - if [ "$m" != "GET" ] && [ "$m" != "DELETE" ] ; then + if [ "$m" != "GET" ] && [ "$m" != "DELETE" ]; then _edgedns_content_type="application/json" _debug3 "_request_body" "$_request_body" _body_len=$(echo "$_request_body" | tr -d "\n\r" | awk '{print length}') @@ -295,13 +297,14 @@ _edgedns_rest() { hdr_indx=1 work_header="${_edgedns_headers}${tab}" _debug3 "work_header" "$work_header" - while [ "$work_header" ]; do - entry="${work_header%%\\t*}"; work_header="${work_header#*\\t}" + while [ "$work_header" ]; do + entry="${work_header%%\\t*}" + work_header="${work_header#*\\t}" export "$(printf "_H%s=%s" "$hdr_indx" "$entry")" _debug2 "Request Header " "$entry" - hdr_indx=$(( hdr_indx + 1 )) + hdr_indx=$((hdr_indx + 1)) done - + # clear headers from previous request to avoid getting wrong http code on timeouts : >"$HTTP_HEADER" _debug2 "$ep" @@ -360,15 +363,15 @@ _edgedns_new_nonce() { _edgedns_make_auth_header() { _debug "Constructing Auth Header" - _edgedns_eg_timestamp - _edgedns_new_nonce + _edgedns_eg_timestamp + _edgedns_new_nonce # "Unsigned authorization header: 'EG1-HMAC-SHA256 client_token=block;access_token=block;timestamp=20200806T14:16:33+0000;nonce=72cde72c-82d9-4721-9854-2ba057929d67;'" - _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "$AKAMAI_CLIENT_TOKEN" "$AKAMAI_ACCESS_TOKEN" "$_eg_timestamp" "$_nonce")" + _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "$AKAMAI_CLIENT_TOKEN" "$AKAMAI_ACCESS_TOKEN" "$_eg_timestamp" "$_nonce")" _secure_debug2 "Unsigned Auth Header: " "$_auth_header" _edgedns_sign_request _signed_auth_header="$(printf "%ssignature=%s" "$_auth_header" "$_signed_req")" - _secure_debug2 "Signed Auth Header: " "${_signed_auth_header}" + _secure_debug2 "Signed Auth Header: " "${_signed_auth_header}" } _edgedns_sign_request() { @@ -444,5 +447,3 @@ _edgedns_base64_sha256() { # filepath=$1 # section=$2 #} - - From 9c28a04c65435b6f801f313b26c4633791d5cb94 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Thu, 27 Aug 2020 17:40:07 -0400 Subject: [PATCH 1002/2234] add alt nonce generation logic --- dnsapi/dns_edgedns.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 2072637a..f5705ee8 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -64,7 +64,7 @@ dns_edgedns_add() { record_op="PUT" rdlist="${_edge_result#*\"rdata\":[}" rdlist="${rdlist%%]*}" - rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\") + rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\\\") _debug3 "existing TXT found" _debug3 "record data" "$rdlist" # value already there? @@ -132,7 +132,7 @@ dns_edgedns_rm() { # record already exists. Get existing record data and update rdlist="${_edge_result#*\"rdata\":[}" rdlist="${rdlist%%]*}" - rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\") + rdlist=$(echo "$rdlist" | tr -d '"' | tr -d "\\\\") _debug3 "rdlist" "$rdlist" if [ -n "$rdlist" ]; then record_op="PUT" @@ -355,10 +355,16 @@ _edgedns_rest() { _edgedns_eg_timestamp() { _eg_timestamp=$(date -u "+%Y%m%dT%H:%M:%S+0000") + _debug3 "_eg_timestamp" "$_eg_timestamp" } _edgedns_new_nonce() { _nonce=$(uuidgen -r) + _ret="$?" + if [ "$_ret" -ne 0 ]; then + _nonce=$(echo "EDGEDNS$(_time)" | _digest sha1 hex | cut -c 1-32) + fi + _debug3 "_nonce" "$_nonce" } _edgedns_make_auth_header() { From 9801876a2f3d07f2fa7eba0f7e8cc07a09fe7ef4 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Fri, 28 Aug 2020 09:55:20 -0400 Subject: [PATCH 1003/2234] shfmt fixes --- dnsapi/dns_edgedns.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index f5705ee8..94cf809c 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -361,9 +361,9 @@ _edgedns_eg_timestamp() { _edgedns_new_nonce() { _nonce=$(uuidgen -r) _ret="$?" - if [ "$_ret" -ne 0 ]; then + if [ "$_ret" -ne 0 ]; then _nonce=$(echo "EDGEDNS$(_time)" | _digest sha1 hex | cut -c 1-32) - fi + fi _debug3 "_nonce" "$_nonce" } From 491842ea3431d645dae2022999a9a953385d3748 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 12 Sep 2020 08:47:46 +0800 Subject: [PATCH 1004/2234] fix https://github.com/acmesh-official/acme.sh/issues/3159 --- dnsapi/dns_ovh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index dda47dda..f6f9689a 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -248,7 +248,7 @@ _ovh_authentication() { # _domain=domain.com _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From 369cfc24138be9a0fb0c1227d17f4922e6043831 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 12 Sep 2020 14:22:18 +0800 Subject: [PATCH 1005/2234] use testall target --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 0f60ace2..0274afcf 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -67,7 +67,7 @@ jobs: - name: Set env file run: cd ../acmetest && echo "${{ secrets.TokenName1 }}" >> env.list && echo "${{ secrets.TokenName2 }}" >> env.list && echo "TEST_DNS_NO_WILDCARD" >> env.list && echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest - run: cd ../acmetest && ./rundocker.sh _cron + run: cd ../acmetest && ./rundocker.sh testall MacOS: runs-on: macos-latest From 4875ef045af0c2ef1d8f8442a12821df404ca16c Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Sep 2020 00:16:04 +0800 Subject: [PATCH 1006/2234] support more dns tokens --- .github/workflows/DNS.yml | 71 ++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 0274afcf..ae71d594 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -19,13 +19,11 @@ jobs: runs-on: ubuntu-latest outputs: hasToken: ${{ steps.step_one.outputs.hasToken }} - env: - _ACME_CHECK_TOKEN_${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} steps: - name: Set the value id: step_one run: | - if [ "$_ACME_CHECK_TOKEN_${{ secrets.TokenName1}}" ] ; then + if [ "${{secrets.TokenName1}}" ] ; then echo "::set-output name=hasToken::true" else echo "::set-output name=hasToken::false" @@ -50,11 +48,8 @@ jobs: needs: CheckToken if: "contains(needs.CheckToken.outputs.hasToken, 'true')" env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} - ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi @@ -65,7 +60,25 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Set env file - run: cd ../acmetest && echo "${{ secrets.TokenName1 }}" >> env.list && echo "${{ secrets.TokenName2 }}" >> env.list && echo "TEST_DNS_NO_WILDCARD" >> env.list && echo "TEST_DNS_SLEEP" >> env.list + run: | + cd ../acmetest + if [ "${{ secrets.TokenName1}}" ] ; then + echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> env.list + fi + if [ "${{ secrets.TokenName2}}" ] ; then + echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> env.list + fi + if [ "${{ secrets.TokenName3}}" ] ; then + echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> env.list + fi + if [ "${{ secrets.TokenName4}}" ] ; then + echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> env.list + fi + if [ "${{ secrets.TokenName5}}" ] ; then + echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list + fi + echo "TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall @@ -73,11 +86,8 @@ jobs: runs-on: macos-latest needs: Docker env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} - ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi @@ -90,17 +100,31 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && ./letest.sh + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh Windows: runs-on: windows-latest needs: MacOS env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} - ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi @@ -127,6 +151,23 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest shell: cmd - run: cd ../acmetest && bash.exe -c ./letest.sh + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + set ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + set ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + set ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + set ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + set ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + bash.exe -c ./letest.sh From 69c5291e52c7fe59721e5224f69cab9df12ac41e Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Sep 2020 21:51:21 +0800 Subject: [PATCH 1007/2234] fix for Windows --- .github/workflows/DNS.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index ae71d594..5591b8f1 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -150,24 +150,24 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - shell: cmd + shell: bash run: | if [ "${{ secrets.TokenName1}}" ] ; then - set ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} fi if [ "${{ secrets.TokenName2}}" ] ; then - set ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} fi if [ "${{ secrets.TokenName3}}" ] ; then - set ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} fi if [ "${{ secrets.TokenName4}}" ] ; then - set ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} fi if [ "${{ secrets.TokenName5}}" ] ; then - set ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} fi cd ../acmetest - bash.exe -c ./letest.sh + ./letest.sh From 576a146ed223f06cdf5dcbd3c984a6ae2cfe1873 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Sep 2020 22:22:36 +0800 Subject: [PATCH 1008/2234] add debug info for duckdns --- dnsapi/dns_duckdns.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 11b685c0..7c2ecfb2 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -112,6 +112,9 @@ _duckdns_rest() { param="$2" _debug param "$param" url="$DuckDNS_API?$param" + if [ "$DEBUG" -gt 0 ]; then + url="$url&verbose=true" + fi _debug url "$url" # DuckDNS uses GET to update domain info From 85736d697cf9068fb79fd53fdb67519b24c13b08 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Sep 2020 22:29:23 +0800 Subject: [PATCH 1009/2234] fix debug info --- dnsapi/dns_duckdns.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 7c2ecfb2..f0af2741 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -120,11 +120,13 @@ _duckdns_rest() { # DuckDNS uses GET to update domain info if [ "$method" = "GET" ]; then response="$(_get "$url")" + _debug2 response "$response" + if [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then + response="OK" + fi else _err "Unsupported method" return 1 fi - - _debug2 response "$response" return 0 } From ea724e343bab76850d8d3f5a76d700af451864b7 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 21 Sep 2020 19:57:10 +0800 Subject: [PATCH 1010/2234] enable for any branches. --- .github/workflows/DNS.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 5591b8f1..3ad9506b 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -1,8 +1,6 @@ name: DNS on: push: - branches: - - 'dev' paths: - 'dnsapi/*.sh' - '.github/workflows/DNS.yml' From 098ef976f7ce3c99052c0984359515ab95fde04e Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Sep 2020 21:37:51 +0800 Subject: [PATCH 1011/2234] add freebsd --- .github/workflows/LetsEncrypt.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 9a0175b5..69ff35ff 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -96,4 +96,20 @@ jobs: shell: cmd run: cd ../acmetest && bash.exe -c ./letest.sh + FreeBSD: + runs-on: macos-latest + needs: Windows + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/freebsd@main + with: + envs: 'NGROK_TOKEN TEST_LOCAL' + prepare: pkg install -y socat + run: | + cd ../acmetest && ./letest.sh From 182d150eaa0a48b1ebe5b0d1fd13bd175d16eee9 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Sep 2020 22:18:38 +0800 Subject: [PATCH 1012/2234] add curl to freebsd --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 69ff35ff..4a8d4336 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -109,7 +109,7 @@ jobs: - uses: vmactions/freebsd@main with: envs: 'NGROK_TOKEN TEST_LOCAL' - prepare: pkg install -y socat + prepare: pkg install -y socat curl run: | cd ../acmetest && ./letest.sh From 27ec69fb97260b180ab919314d8cced1d062a2ab Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Sep 2020 22:57:26 +0800 Subject: [PATCH 1013/2234] add FreeBSD --- .github/workflows/DNS.yml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 3ad9506b..fd9a98b3 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -168,4 +168,42 @@ jobs: cd ../acmetest ./letest.sh + FreeBSD: + runs-on: macos-latest + needs: Windows + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/freebsd@main + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: pkg install -y socat curl + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + From 7616e94fd313025cc6c0386ee0997b1e1981cd76 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 28 Sep 2020 21:50:20 +0800 Subject: [PATCH 1014/2234] fix message --- .github/workflows/DNS.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index fd9a98b3..191ae8c9 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -36,10 +36,10 @@ jobs: steps: - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" run: | - echo "Plese see this page to fix the error: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" - - name: Fail - if: "github.actor != 'Neilpang'" - run: false + echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" + if [ "${{github.actor}}" != "Neilpang" ]; then + false + fi Docker: runs-on: ubuntu-latest From 967096f01ce2daa819ae082c2d9fba098af8a752 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 16:17:16 +0800 Subject: [PATCH 1015/2234] update freebsd-vm --- .github/workflows/DNS.yml | 2 +- .github/workflows/LetsEncrypt.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 191ae8c9..1c0165c0 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,7 +183,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd@main + - uses: vmactions/freebsd-vm@v0.0.4 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 4a8d4336..ba5e933d 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,7 +106,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd@main + - uses: vmactions/freebsd-vm@v0.0.4 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl From 71f00a9efd5d458b03a96a98f5718bd9d12899b3 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 16:20:27 +0800 Subject: [PATCH 1016/2234] minor --- .github/workflows/DNS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 1c0165c0..976aff56 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -206,4 +206,5 @@ jobs: cd ../acmetest ./letest.sh + From a160b798cac43e8cc7cda355b3ef5e58b9e56b28 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 17:11:04 +0800 Subject: [PATCH 1017/2234] update badge --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 953c44a5..6fb88daf 100644 --- a/README.md +++ b/README.md @@ -57,26 +57,26 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) | NO | Status| Platform| |----|-------|---------| -|1|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu -|2|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian -|3|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS -|4|[![](https://acmesh-official.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) -|5|[![](https://acmesh-official.github.io/acmetest/status/freebsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|FreeBSD -|6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense -|7|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE -|8|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl) -|9|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux -|10|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora -|11|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux -|12|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux -|13|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) -|14|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|15|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD -|16|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia -|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) -|18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris -|19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux -|20|[![Build Status](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX +|1|[![MacOS](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX +|2|[![Windows](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included) +|3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD +|4|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense +|5|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD +|6|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris +|7|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu +|8|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian +|9|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS +|10|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE +|11|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl) +|12|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux +|13|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora +|14|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux +|15|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux +|16|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) +|17|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 +|18|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia +|19|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) +|20|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux |21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): From 13c1f4ab19c1f2ff6f9f8335425de8d18861ad45 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 17:17:31 +0800 Subject: [PATCH 1018/2234] update badge --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6fb88daf..7215785c 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |1|[![MacOS](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX |2|[![Windows](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included) |3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD -|4|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense -|5|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD -|6|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris -|7|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu +|4|[![Ubuntu](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)| Ubuntu +|5|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense +|6|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD +|7|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris |8|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian |9|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS |10|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE From 2340c55d762269c06cae13f310649c758d739729 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 9 Oct 2020 22:33:21 +0800 Subject: [PATCH 1019/2234] update freebsd --- .github/workflows/DNS.yml | 3 ++- .github/workflows/LetsEncrypt.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 976aff56..b06db229 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,10 +183,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl + usesh: true run: | if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index ba5e933d..d71f3ac1 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,10 +106,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl + usesh: true run: | cd ../acmetest && ./letest.sh From 25468f55ffbca9a78330221404571786f9f229a5 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Mon, 21 Sep 2020 14:17:23 +0200 Subject: [PATCH 1020/2234] Added dnsapi/dns_infomaniak.sh --- dnsapi/dns_infomaniak.sh | 199 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100755 dnsapi/dns_infomaniak.sh diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh new file mode 100755 index 00000000..e2328a36 --- /dev/null +++ b/dnsapi/dns_infomaniak.sh @@ -0,0 +1,199 @@ +#!/usr/bin/env sh + +############################################################################### +# Infomaniak API integration +# +# To use this API you need visit the API dashboard of your account +# once logged into https://manager.infomaniak.com add /api/dashboard to the URL +# +# Please report bugs to +# https://github.com/acmesh-official/acme.sh/issues/3188 +# +# Note: the URL looks like this: +# https://manager.infomaniak.com/v3//api/dashboard +# Then generate a token with the scope Domain +# this is given as an environment variable INFOMANIAK_API_TOKEN +############################################################################### + +# base variables + +DEFAULT_INFOMANIAK_API_URL="https://api.infomaniak.com" +DEFAULT_INFOMANIAK_TTL=300 + +######## Public functions ##################### + +#Usage: dns_infomaniak_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_infomaniak_add() { + + INFOMANIAK_API_TOKEN="${INFOMANIAK_API_TOKEN:-$(_readaccountconf_mutable INFOMANIAK_API_TOKEN)}" + INFOMANIAK_API_URL="${INFOMANIAK_API_URL:-$(_readaccountconf_mutable INFOMANIAK_API_URL)}" + INFOMANIAK_TTL="${INFOMANIAK_TTL:-$(_readaccountconf_mutable INFOMANIAK_TTL)}" + + if [ -z "$INFOMANIAK_API_TOKEN" ]; then + INFOMANIAK_API_TOKEN="" + _err "Please provide a valid Infomaniak API token in variable INFOMANIAK_API_TOKEN" + return 1 + fi + + if [ -z "$INFOMANIAK_API_URL" ]; then + INFOMANIAK_API_URL="$DEFAULT_INFOMANIAK_API_URL" + fi + + if [ -z "$INFOMANIAK_TTL" ]; then + INFOMANIAK_TTL="$DEFAULT_INFOMANIAK_TTL" + fi + + #save the token to the account conf file. + _saveaccountconf_mutable INFOMANIAK_API_TOKEN "$INFOMANIAK_API_TOKEN" + + if [ "$INFOMANIAK_API_URL" != "$DEFAULT_INFOMANIAK_API_URL" ]; then + _saveaccountconf_mutable INFOMANIAK_API_URL "$INFOMANIAK_API_URL" + fi + + if [ "$INFOMANIAK_TTL" != "$DEFAULT_INFOMANIAK_TTL" ]; then + _saveaccountconf_mutable INFOMANIAK_TTL "$INFOMANIAK_TTL" + fi + + export _H1="Authorization: Bearer $INFOMANIAK_API_TOKEN" + export _H2="Content-Type: application/json" + + fulldomain="$1" + txtvalue="$2" + + _info "Infomaniak DNS API" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + fqdn=${fulldomain#_acme-challenge.} + + # guess which base domain to add record to + zone_and_id=$(_find_zone "$fqdn") + if [ -z "$zone_and_id" ]; then + _err "cannot find zone to modify" + return 1 + fi + zone=${zone_and_id% *} + domain_id=${zone_and_id#* } + + # extract first part of domain + key=${fulldomain%.$zone} + + _debug "zone:$zone id:$domain_id key:$key" + + # payload + data="{\"type\": \"TXT\", \"source\": \"$key\", \"target\": \"$txtvalue\", \"ttl\": $INFOMANIAK_TTL}" + + # API call + response=$(_post "$data" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record") + if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + _info "Record added" + _debug "Response: $response" + return 0 + fi + _err "could not create record" + _debug "Response: $response" + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_infomaniak_rm() { + + INFOMANIAK_API_TOKEN="${INFOMANIAK_API_TOKEN:-$(_readaccountconf_mutable INFOMANIAK_API_TOKEN)}" + INFOMANIAK_API_URL="${INFOMANIAK_API_URL:-$(_readaccountconf_mutable INFOMANIAK_API_URL)}" + INFOMANIAK_TTL="${INFOMANIAK_TTL:-$(_readaccountconf_mutable INFOMANIAK_TTL)}" + + if [ -z "$INFOMANIAK_API_TOKEN" ]; then + INFOMANIAK_API_TOKEN="" + _err "Please provide a valid Infomaniak API token in variable INFOMANIAK_API_TOKEN" + return 1 + fi + + if [ -z "$INFOMANIAK_API_URL" ]; then + INFOMANIAK_API_URL="$DEFAULT_INFOMANIAK_API_URL" + fi + + if [ -z "$INFOMANIAK_TTL" ]; then + INFOMANIAK_TTL="$DEFAULT_INFOMANIAK_TTL" + fi + + #save the token to the account conf file. + _saveaccountconf_mutable INFOMANIAK_API_TOKEN "$INFOMANIAK_API_TOKEN" + + if [ "$INFOMANIAK_API_URL" != "$DEFAULT_INFOMANIAK_API_URL" ]; then + _saveaccountconf_mutable INFOMANIAK_API_URL "$INFOMANIAK_API_URL" + fi + + if [ "$INFOMANIAK_TTL" != "$DEFAULT_INFOMANIAK_TTL" ]; then + _saveaccountconf_mutable INFOMANIAK_TTL "$INFOMANIAK_TTL" + fi + + export _H1="Authorization: Bearer $INFOMANIAK_API_TOKEN" + export _H2="ContentType: application/json" + + fulldomain=$1 + txtvalue=$2 + _info "Infomaniak DNS API" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + fqdn=${fulldomain#_acme-challenge.} + + # guess which base domain to add record to + zone_and_id=$(_find_zone "$fqdn") + if [ -z "$zone_and_id" ]; then + _err "cannot find zone to modify" + return 1 + fi + zone=${zone_and_id% *} + domain_id=${zone_and_id#* } + + # extract first part of domain + key=${fulldomain%.$zone} + + _debug "zone:$zone id:$domain_id key:$key" + + # find previous record + # shellcheck disable=SC1004 + record_id=$(_get "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record" | sed 's/.*"data":\[\(.*\)\]}/\1/; s/},{/}\ +{/g' | sed -n 's/.*"id":"*\([0-9]*\)"*.*"source_idn":"'"$fulldomain"'".*"target_idn":"'"$txtvalue"'".*/\1/p') + if [ -z "$record_id" ]; then + _err "could not find record to delete" + return 1 + fi + _debug "record_id: $record_id" + + # API call + response=$(_post "" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record/$record_id" "" DELETE) + if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + _info "Record deleted" + return 0 + fi + _err "could not delete record" + return 1 +} + +#################### Private functions below ################################## + +_get_domain_id() { + domain="$1" + + # shellcheck disable=SC1004 + _get "${INFOMANIAK_API_URL}/1/product?service_name=domain&customer_name=$domain" | sed 's/.*"data":\[{\(.*\)}\]}/\1/; s/,/\ +/g' | sed -n 's/^"id":\(.*\)/\1/p' +} + +_find_zone() { + zone="$1" + + # find domain in list, removing . parts sequentialy + while echo "$zone" | grep -q '\.'; do + _debug "testing $zone" + id=$(_get_domain_id "$zone") + if [ -n "$id" ]; then + echo "$zone $id" + return + fi + zone=${zone#*.} + done +} From 15fa0c264f7cfd8bc9542ec18a1c7cb407e7404e Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Fri, 2 Oct 2020 12:47:33 +0200 Subject: [PATCH 1021/2234] dnsapi/dns_infomaniak.sh: Replace grep by _contains --- dnsapi/dns_infomaniak.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh index e2328a36..765cf39d 100755 --- a/dnsapi/dns_infomaniak.sh +++ b/dnsapi/dns_infomaniak.sh @@ -85,7 +85,7 @@ dns_infomaniak_add() { # API call response=$(_post "$data" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record") - if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + if [ -n "$response" ] && echo "$response" | _contains '"result":"success"'; then _info "Record added" _debug "Response: $response" return 0 @@ -165,7 +165,7 @@ dns_infomaniak_rm() { # API call response=$(_post "" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record/$record_id" "" DELETE) - if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + if [ -n "$response" ] && echo "$response" | _contains '"result":"success"'; then _info "Record deleted" return 0 fi @@ -187,7 +187,7 @@ _find_zone() { zone="$1" # find domain in list, removing . parts sequentialy - while echo "$zone" | grep -q '\.'; do + while _contains "$zone" '\.'; do _debug "testing $zone" id=$(_get_domain_id "$zone") if [ -n "$id" ]; then From c6617ebc9faf47e08ee21f23dee9ce839974af27 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Thu, 8 Oct 2020 23:42:05 +0200 Subject: [PATCH 1022/2234] Fix DNS workflow use variables TEST_DNS_SLEEP and TEST_DNS_NO_WILDCARD --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index b06db229..1909cb03 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -75,8 +75,8 @@ jobs: if [ "${{ secrets.TokenName5}}" ] ; then echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list fi - echo "TEST_DNS_NO_WILDCARD" >> env.list - echo "TEST_DNS_SLEEP" >> env.list + echo "TEST_DNS_NO_WILDCARD=$TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_SLEEP=$TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall From ff8fe7e01857afd3c18d94e4a529ddefac85da4e Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Sat, 10 Oct 2020 18:20:26 +0200 Subject: [PATCH 1023/2234] Revert "Fix DNS workflow use variables TEST_DNS_SLEEP and TEST_DNS_NO_WILDCARD" This reverts commit f864416e39753b66f26d8d3fa19cbb094493731a. --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 1909cb03..b06db229 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -75,8 +75,8 @@ jobs: if [ "${{ secrets.TokenName5}}" ] ; then echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list fi - echo "TEST_DNS_NO_WILDCARD=$TEST_DNS_NO_WILDCARD" >> env.list - echo "TEST_DNS_SLEEP=$TEST_DNS_SLEEP" >> env.list + echo "TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall From 5aff548794a9569a38a439014cc36073c0ff38b8 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Wed, 14 Oct 2020 14:49:09 -0400 Subject: [PATCH 1024/2234] remove uuidgen --- dnsapi/dns_edgedns.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 94cf809c..89e77936 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -359,11 +359,7 @@ _edgedns_eg_timestamp() { } _edgedns_new_nonce() { - _nonce=$(uuidgen -r) - _ret="$?" - if [ "$_ret" -ne 0 ]; then - _nonce=$(echo "EDGEDNS$(_time)" | _digest sha1 hex | cut -c 1-32) - fi + _nonce=$(echo "EDGEDNS$(_time)" | _digest sha1 hex | cut -c 1-32) _debug3 "_nonce" "$_nonce" } From 054a62de6073492457bf35e406f743d2c1eb5477 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 16 Oct 2020 18:47:02 +0800 Subject: [PATCH 1025/2234] Update DNS.yml --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index b06db229..25d92137 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,7 +183,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.5 + - uses: vmactions/freebsd-vm@v0.0.7 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl From 23088bc89778d48b183a9c26789b4d4f4ee53b4c Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 16 Oct 2020 18:47:27 +0800 Subject: [PATCH 1026/2234] Update LetsEncrypt.yml --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index d71f3ac1..39e91161 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,7 +106,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.5 + - uses: vmactions/freebsd-vm@v0.0.7 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl From 9ab16bdbb36462db2b63b0a2362369e1d1f5e91b Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Fri, 16 Oct 2020 10:16:25 -0400 Subject: [PATCH 1027/2234] use _digest instead of openssl --- dnsapi/dns_edgedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 89e77936..7ab448d2 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -440,7 +440,7 @@ _edgedns_base64_sha256() { _debug2 "Creating sha256 digest" trg=$1 _secure_debug2 "digest data" "$trg" - digest="$(echo "$trg" | tr -d "\n\r" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -binary | _base64)" + digest="$(echo "$trg" | tr -d "\n\r" | _digest "sha256")" _sha256_out="$(echo "$digest" | tr -d "\n\r" | iconv -f utf-8)" _secure_debug2 "digest decode" "$_sha256_out" } From 6b20993d2a54b30642ef4987a0370307c4d6dfd4 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Fri, 16 Oct 2020 10:32:01 -0400 Subject: [PATCH 1028/2234] fix format --- dnsapi/dns_edgedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 7ab448d2..05c8e886 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -440,7 +440,7 @@ _edgedns_base64_sha256() { _debug2 "Creating sha256 digest" trg=$1 _secure_debug2 "digest data" "$trg" - digest="$(echo "$trg" | tr -d "\n\r" | _digest "sha256")" + digest="$(echo "$trg" | tr -d "\n\r" | _digest "sha256")" _sha256_out="$(echo "$digest" | tr -d "\n\r" | iconv -f utf-8)" _secure_debug2 "digest decode" "$_sha256_out" } From 27a54bcbaa666da69eea8256d73fe6ce4648ba64 Mon Sep 17 00:00:00 2001 From: Adrian Fedoreanu Date: Mon, 19 Oct 2020 20:45:52 +0200 Subject: [PATCH 1029/2234] fix dnsapi/dns_1984hosting --- dnsapi/dns_1984hosting.sh | 84 +++++++++++++++------------------------ 1 file changed, 33 insertions(+), 51 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index bcb675ab..d720c1c5 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -40,8 +40,35 @@ dns_1984hosting_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _1984hosting_add_txt_record "$_domain" "$_sub_domain" "$txtvalue" - return $? + _debug "Add TXT record $fulldomain with value '$txtvalue'" + value="$(printf '%s' "$txtvalue" | _url_encode)" + url="https://management.1984hosting.com/domains/entry/" + + postdata="entry=new" + postdata="$postdata&type=TXT" + postdata="$postdata&ttl=3600" + postdata="$postdata&zone=$_domain" + postdata="$postdata&host=$_sub_domain" + postdata="$postdata&rdata=%22$value%22" + _debug2 postdata "$postdata" + + _authpost "$postdata" "$url" + response="$(echo "$_response" | _normalizeJson)" + _debug2 response "$response" + + if _contains "$response" '"haserrors": true'; then + _err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post" + return 1 + elif _contains "$response" ""; then + _err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file" + return 1 + elif _contains "$response" '"auth": false'; then + _err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie" + return 1 + fi + + _info "Added acme challenge TXT record for $fulldomain at 1984Hosting" + return 0 } #Usage: fulldomain txtvalue @@ -67,57 +94,10 @@ dns_1984hosting_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _1984hosting_delete_txt_record "$_domain" "$_sub_domain" - return $? -} - -#################### Private functions below ################################## - -# usage _1984hosting_add_txt_record domain subdomain value -# returns 0 success -_1984hosting_add_txt_record() { - _debug "Add TXT record $1 with value '$3'" - domain="$1" - subdomain="$2" - value="$(printf '%s' "$3" | _url_encode)" - url="https://management.1984hosting.com/domains/entry/" - - postdata="entry=new" - postdata="$postdata&type=TXT" - postdata="$postdata&ttl=3600" - postdata="$postdata&zone=$domain" - postdata="$postdata&host=$subdomain" - postdata="$postdata&rdata=%22$value%22" - _debug2 postdata "$postdata" - - _authpost "$postdata" "$url" - response="$(echo "$_response" | _normalizeJson)" - _debug2 response "$response" - - if _contains "$response" '"haserrors": true'; then - _err "1984Hosting failed to add TXT record for $subdomain bad RC from _post" - return 1 - elif _contains "$response" ""; then - _err "1984Hosting failed to add TXT record for $subdomain. Check $HTTP_HEADER file" - return 1 - elif _contains "$response" '"auth": false'; then - _err "1984Hosting failed to add TXT record for $subdomain. Invalid or expired cookie" - return 1 - fi - - _info "Added acme challenge TXT record for $fulldomain at 1984Hosting" - return 0 -} - -# usage _1984hosting_delete_txt_record entry_id -# returns 0 success -_1984hosting_delete_txt_record() { _debug "Delete $fulldomain TXT record" - domain="$1" - subdomain="$2" url="https://management.1984hosting.com/domains" - _htmlget "$url" "$domain" + _htmlget "$url" "$_domain" _debug2 _response "$_response" zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" _debug2 zone_id "$zone_id" @@ -126,7 +106,7 @@ _1984hosting_delete_txt_record() { return 1 fi - _htmlget "$url/$zone_id" "$subdomain" + _htmlget "$url/$zone_id" "$_sub_domain" _debug2 _response "$_response" entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" _debug2 entry_id "$entry_id" @@ -148,6 +128,8 @@ _1984hosting_delete_txt_record() { return 0 } +#################### Private functions below ################################## + # usage: _1984hosting_login username password # returns 0 success _1984hosting_login() { From b025ed60579e194140a75062e8bb6ef5d42b6c00 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 21 Oct 2020 15:00:33 +0800 Subject: [PATCH 1030/2234] Update LetsEncrypt.yml --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 39e91161..5f0bba72 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -58,7 +58,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install tools - run: brew update && brew install socat; + run: brew install socat - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest From 1db963361c4b832c048b8d85fe302d37b5d41cec Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Wed, 28 Oct 2020 13:50:40 +0100 Subject: [PATCH 1031/2234] Rework based on review from Neilpang --- deploy/cleverreach.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index 0fa07f4a..552d8149 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -2,8 +2,6 @@ # Here is the script to deploy the cert to your CleverReach Account using the CleverReach REST API. # Your OAuth needs the right scope, please contact CleverReach support for that. # -# It requires that jq are in the $PATH. -# # Written by Jan-Philipp Benecke # Public domain, 2020 # @@ -25,30 +23,32 @@ cleverreach_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _cleverreach_client_id="${DEPLOY_CLEVERREACH_CLIENT_ID}" - _cleverreach_client_secret="${DEPLOY_CLEVERREACH_CLIENT_SECRET}" + _getdeployconf DEPLOY_CLEVERREACH_CLIENT_ID + _getdeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET - if [ -z "$_cleverreach_client_id" ]; then + if [ -z "${DEPLOY_CLEVERREACH_CLIENT_ID}" ]; then _err "CleverReach Client ID is not found, please define DEPLOY_CLEVERREACH_CLIENT_ID." return 1 fi - if [ -z "$_cleverreach_client_secret" ]; then + if [ -z "${DEPLOY_CLEVERREACH_CLIENT_SECRET}" ]; then _err "CleverReach client secret is not found, please define DEPLOY_CLEVERREACH_CLIENT_SECRET." return 1 fi - _saveaccountconf DEPLOY_CLEVERREACH_CLIENT_ID "${_cleverreach_client_id}" - _saveaccountconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${_cleverreach_client_secret}" + _savedeployconf DEPLOY_CLEVERREACH_CLIENT_ID "${DEPLOY_CLEVERREACH_CLIENT_ID}" + _savedeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${DEPLOY_CLEVERREACH_CLIENT_SECRET}" _info "Obtaining a CleverReach access token" - _data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${_cleverreach_client_id}\", \"client_secret\": \"${_cleverreach_client_secret}\"}" + _data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${DEPLOY_CLEVERREACH_CLIENT_ID}\", \"client_secret\": \"${DEPLOY_CLEVERREACH_CLIENT_SECRET}\"}" _auth_result="$(_post "$_data" "https://rest.cleverreach.com/oauth/token.php" "" "POST" "application/json")" _debug _data "$_data" _debug _auth_result "$_auth_result" - _access_token=$(echo "$_auth_result" | _json_decode | jq -r .access_token) + _regex=".*\"access_token\":\"\([-._0-9A-Za-z]*\)\".*$" + _debug _regex "$_regex" + _access_token=$(echo "$_auth_result" | _json_decode | sed -n "s/$_regex/\1/p") _info "Uploading certificate and key to CleverReach" From aa85d0ffeba66fd438a2f1d5312b919e731cb8be Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Wed, 28 Oct 2020 09:05:14 -0400 Subject: [PATCH 1032/2234] trigger commit --- dnsapi/dns_edgedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 05c8e886..1b3996cf 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -8,7 +8,7 @@ # Values to export: # --EITHER-- -# *** NOT IMPLEMENTED YET *** +# *** TBD. NOT IMPLEMENTED YET *** # specify Edgegrid credentials file and section # AKAMAI_EDGERC= # AKAMAI_EDGERC_SECTION="default" From df60a2248a6ce4f1f3c7675be0305feb3b88cf7d Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Wed, 28 Oct 2020 15:20:24 -0400 Subject: [PATCH 1033/2234] fix typo --- dnsapi/dns_edgedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 1b3996cf..8ed6e5d2 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -242,7 +242,7 @@ _EDGEDNS_getZoneInfo() { _err "$(printf "Fatal error: acme API function call : %s" "$retVal")" fi if [ "$curResult" != "404" ]; then - err "$(printf "Managed zone validation failed. Error response: %s" "$retVal")" + _err "$(printf "Managed zone validation failed. Error response: %s" "$retVal")" return 1 fi fi From 7cc30c268b6c1f79be55fa3a8d31ec50892a4a78 Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 11:14:44 +0100 Subject: [PATCH 1034/2234] Script to use with Anexia CloudDNS --- dnsapi/dns_anx.sh | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 dnsapi/dns_anx.sh diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh new file mode 100644 index 00000000..9865adc2 --- /dev/null +++ b/dnsapi/dns_anx.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env sh + +#ANX_Token="xxxx" + +ANX_API='https://engine.anexia-it.com/api/clouddns/v1' + +######## Public functions ##################### + +dns_anx_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Using ANX CDNS API" + + ANX_Token="${ANX_Token:-$(_readaccountconf_mutable ANX_Token)}" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + if [ "$ANX_Token" ]; then + _saveaccountconf_mutable ANX_Token "$ANX_Token" + else + _err "You didn't specify a ANEXIA Engine API token." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + # Always add records, wildcard need two records with the same name + _anx_rest POST "zone.json/${_domain}/records" "{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"rdata\":\"$txtvalue\"}" + if _contains "$response" "$txtvalue"; then + return 0 + else + return 1 + fi +} + +dns_anx_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Using ANX CDNS API" + + ANX_Token="${ANX_Token:-$(_readaccountconf_mutable ANX_Token)}" + + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _get_record_id + + if _is_uuid "$_record_id"; then + if ! _anx_rest DELETE "zone.json/${_domain}/records/$_record_id"; then + _err "Delete record" + return 1 + fi + else + _info "No record found." + fi + echo "$response" | tr -d " " | grep \"status\":\"OK\" >/dev/null +} + +#################### Private functions below ################################## + +_is_uuid() { + pattern='^\{?[A-Z0-9a-z]{8}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{12}\}?$' + if echo "$1" | _egrep_o "$pattern" >/dev/null; then + return 0 + fi + return 1 +} + +_get_record_id() { + _debug subdomain "$_sub_domain" + _debug domain "$_domain" + + if _anx_rest GET "zone.json/${_domain}/records?name=$_sub_domain&type=TXT"; then + _debug response "$response" + if _contains "$response" "\"name\":\"$_sub_domain\"" >/dev/null; then + _record_id=$(printf "%s\n" "$response" | _egrep_o "\[.\"identifier\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") + else + _record_id='' + fi + else + _err "Search existing record" + fi +} + +_anx_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + export _H1="Content-Type: application/json" + export _H2="Authorization: Token $ANX_Token" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "${ANX_API}/$ep" "" "$m")" + else + response="$(_get "${ANX_API}/$ep")" + fi + + # shellcheck disable=SC2181 + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug response "$response" + return 0 +} + + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + # Does a zone with that name exist? + _anx_rest GET "zone.json/$h" + # shellcheck disable=SC2154 + if [ "$code" -ne 200 ]; then + continue + fi + + if _contains "$response" "\"name\":\"$h\""; 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 +} From fe54d5b8aeef06a7244e08c380af68eaea9884bc Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 12:51:49 +0100 Subject: [PATCH 1035/2234] fixed spacing in two lines --- dnsapi/dns_anx.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index 9865adc2..66430d3e 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -19,8 +19,8 @@ dns_anx_add() { if [ "$ANX_Token" ]; then _saveaccountconf_mutable ANX_Token "$ANX_Token" else - _err "You didn't specify a ANEXIA Engine API token." - return 1 + _err "You didn't specify a ANEXIA Engine API token." + return 1 fi _debug "First detect the root zone" From bc62d49fc900e2f5b31881e02c432433435ae245 Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 13:04:29 +0100 Subject: [PATCH 1036/2234] removed empty line to make shfmt happy --- dnsapi/dns_anx.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index 66430d3e..b84fac8c 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -119,7 +119,6 @@ _anx_rest() { return 0 } - #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www From 92bbdce4351028909e83c189dc77ab313b3684d4 Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 13:35:53 +0100 Subject: [PATCH 1037/2234] changed comment --- dnsapi/dns_anx.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index b84fac8c..027f6820 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -1,5 +1,6 @@ #!/usr/bin/env sh +### Anexia CloudDNS acme.sh hook #ANX_Token="xxxx" ANX_API='https://engine.anexia-it.com/api/clouddns/v1' From 812333e9aef404d3b5e7b5f0cdfa935b20c3895c Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 14:01:08 +0100 Subject: [PATCH 1038/2234] Changed comment once more --- dnsapi/dns_anx.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index 027f6820..8c46e405 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -1,6 +1,8 @@ #!/usr/bin/env sh -### Anexia CloudDNS acme.sh hook +# Anexia CloudDNS acme.sh hook +# Author: MA + #ANX_Token="xxxx" ANX_API='https://engine.anexia-it.com/api/clouddns/v1' From d58fb2bbc01f8d2596c5365db9e644d1fc99773a Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Fri, 30 Oct 2020 14:13:32 +0100 Subject: [PATCH 1039/2234] Speedup for _get_root function --- dnsapi/dns_anx.sh | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index 8c46e405..c1a1130a 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -122,15 +122,13 @@ _anx_rest() { return 0 } -#_acme-challenge.www.domain.com -#returns -# _sub_domain=_acme-challenge.www -# _domain=domain.com _get_root() { domain=$1 i=1 p=1 + _anx_rest GET "zone.json" + while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug h "$h" @@ -139,13 +137,6 @@ _get_root() { return 1 fi - # Does a zone with that name exist? - _anx_rest GET "zone.json/$h" - # shellcheck disable=SC2154 - if [ "$code" -ne 200 ]; then - continue - fi - if _contains "$response" "\"name\":\"$h\""; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From cc40110d7e339fe2d314776142266bda7d870ba5 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Fri, 30 Oct 2020 13:12:45 -0400 Subject: [PATCH 1040/2234] refactored sig timestamp generation --- dnsapi/dns_edgedns.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 8ed6e5d2..7c47cc0b 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -41,6 +41,7 @@ dns_edgedns_add() { _err "Invalid domain" return 1 fi + _debug2 "Add: zone" "$zone" acmeRecordURI=$(printf "%s/%s/names/%s/types/TXT" "$edge_endpoint" "$zone" "$fulldomain") _debug3 "Add URL" "$acmeRecordURI" @@ -354,19 +355,31 @@ _edgedns_rest() { } _edgedns_eg_timestamp() { - _eg_timestamp=$(date -u "+%Y%m%dT%H:%M:%S+0000") - _debug3 "_eg_timestamp" "$_eg_timestamp" + _debug "Generating signature Timestamp" + _debug3 "Retriving ntp time" + _timeheaders="$(_get "https://www.ntp.org" "onlyheader")" + _debug3 "_timeheaders" "$_timeheaders" + _ntpdate="$(echo "$_timeheaders" | grep -i "Date:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n")" + _debug3 "_ntpdate" "$_ntpdate" + _ntpdate="$(echo "${_ntpdate}" | sed -e 's/^[[:space:]]*//')" + _debug3 "_NTPDATE" "$_ntpdate" + _ntptime="$(echo "${_ntpdate}" | _head_n 1 | cut -d " " -f 5 | tr -d "\r\n")" + _debug3 "_ntptime" "$_ntptime" + _eg_timestamp=$(date -u "+%Y%m%dT") + _eg_timestamp="$(printf "%s%s+0000" "$_eg_timestamp" "$_ntptime")" + _debug "_eg_timestamp" "$_eg_timestamp" } _edgedns_new_nonce() { + _debug "Generating Nonce" _nonce=$(echo "EDGEDNS$(_time)" | _digest sha1 hex | cut -c 1-32) _debug3 "_nonce" "$_nonce" } _edgedns_make_auth_header() { _debug "Constructing Auth Header" - _edgedns_eg_timestamp _edgedns_new_nonce + _edgedns_eg_timestamp # "Unsigned authorization header: 'EG1-HMAC-SHA256 client_token=block;access_token=block;timestamp=20200806T14:16:33+0000;nonce=72cde72c-82d9-4721-9854-2ba057929d67;'" _auth_header="$(printf "EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;" "$AKAMAI_CLIENT_TOKEN" "$AKAMAI_ACCESS_TOKEN" "$_eg_timestamp" "$_nonce")" _secure_debug2 "Unsigned Auth Header: " "$_auth_header" From 9fcd1040650b80e2799e048e7089882f48a804a7 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Mon, 2 Nov 2020 13:35:12 +0300 Subject: [PATCH 1041/2234] Use _getdeployconf for env vars --- deploy/vault.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/vault.sh b/deploy/vault.sh index c51ceb0f..e742b0fb 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -31,11 +31,13 @@ vault_deploy() { _debug _cfullchain "$_cfullchain" # validate required env vars + _getdeployconf VAULT_PREFIX if [ -z "$VAULT_PREFIX" ]; then _err "VAULT_PREFIX needs to be defined (contains prefix path in vault)" return 1 fi + _getdeployconf VAULT_ADDR if [ -z "$VAULT_ADDR" ]; then _err "VAULT_ADDR needs to be defined (contains vault connection address)" return 1 From e203e9837577cf2b8f976baf19a29a1ed1ef2654 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Mon, 2 Nov 2020 16:46:09 +0300 Subject: [PATCH 1042/2234] Use _savedeployconf --- deploy/vault.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/vault.sh b/deploy/vault.sh index e742b0fb..70c80444 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -36,12 +36,14 @@ vault_deploy() { _err "VAULT_PREFIX needs to be defined (contains prefix path in vault)" return 1 fi + _savedeployconf VAULT_PREFIX "$VAULT_PREFIX" _getdeployconf VAULT_ADDR if [ -z "$VAULT_ADDR" ]; then _err "VAULT_ADDR needs to be defined (contains vault connection address)" return 1 fi + _savedeployconf VAULT_ADDR "$VAULT_ADDR" # JSON does not allow multiline strings. # So replacing new-lines with "\n" here From 075dc1e4e95f3668eeee94ad916a3e7142e7282e Mon Sep 17 00:00:00 2001 From: MaxPeal <30347730+MaxPeal@users.noreply.github.com> Date: Thu, 5 Nov 2020 01:25:07 +0100 Subject: [PATCH 1043/2234] add linux/ppc64le and linux/s390x --- .github/workflows/dockerhub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 92308218..89915af7 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -63,4 +63,4 @@ jobs: --tag ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG} \ --output "type=image,push=true" \ --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ - --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . + --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386,linux/ppc64le,linux/s390x . From 7530266330afcf09f2cebfc8b8775dec5dbe8f03 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 9 Nov 2020 20:14:22 +0800 Subject: [PATCH 1044/2234] remove dependency to md5 and awk --- deploy/fritzbox.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/fritzbox.sh b/deploy/fritzbox.sh index 21ea6cfd..89b19806 100644 --- a/deploy/fritzbox.sh +++ b/deploy/fritzbox.sh @@ -64,9 +64,9 @@ fritzbox_deploy() { _info "Log in to the FRITZ!Box" _fritzbox_challenge="$(_get "${_fritzbox_url}/login_sid.lua" | sed -e 's/^.*//' -e 's/<\/Challenge>.*$//')" if _exists iconv; then - _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | md5sum | awk '{print $1}')" + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | _digest md5 hex)" else - _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | md5sum | awk '{print $1}')" + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | _digest md5 hex)" fi _fritzbox_sid="$(_get "${_fritzbox_url}/login_sid.lua?sid=0000000000000000&username=${_fritzbox_username}&response=${_fritzbox_challenge}-${_fritzbox_hash}" | sed -e 's/^.*//' -e 's/<\/SID>.*$//')" From d866b3df1f1342794e428975e489a7a942ab6941 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Mon, 9 Nov 2020 10:16:57 -0500 Subject: [PATCH 1045/2234] convert key to hex before calling _hmac --- dnsapi/dns_edgedns.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 7c47cc0b..3b9e0032 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -443,7 +443,9 @@ _edgedns_base64_hmac_sha256() { _secure_debug2 "encoded data" "$encoded_data" _secure_debug2 "encoded key" "$encoded_key" - data_sig="$(echo "$encoded_data" | tr -d "\n\r" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hmac "$encoded_key" -binary | _base64)" + encoded_key_hex=$(printf "%s" "$encoded_key" | _hex_dump | tr -d ' ') + data_sig="$(echo "$encoded_data" | tr -d "\n\r" | _hmac sha256 $encoded_key_hex | _base64)" + _secure_debug2 "data_sig:" "$data_sig" _hmac_out="$(echo "$data_sig" | tr -d "\n\r" | iconv -f utf-8)" _secure_debug2 "hmac" "$_hmac_out" From c490dd1563d9d069221a0bcf946722cb9a5038a0 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Mon, 9 Nov 2020 10:36:12 -0500 Subject: [PATCH 1046/2234] add quotes to resolve shell check failure --- dnsapi/dns_edgedns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 3b9e0032..2e5c7d30 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -444,7 +444,7 @@ _edgedns_base64_hmac_sha256() { _secure_debug2 "encoded key" "$encoded_key" encoded_key_hex=$(printf "%s" "$encoded_key" | _hex_dump | tr -d ' ') - data_sig="$(echo "$encoded_data" | tr -d "\n\r" | _hmac sha256 $encoded_key_hex | _base64)" + data_sig="$(echo "$encoded_data" | tr -d "\n\r" | _hmac sha256 "$encoded_key_hex" | _base64)" _secure_debug2 "data_sig:" "$data_sig" _hmac_out="$(echo "$data_sig" | tr -d "\n\r" | iconv -f utf-8)" From a077132d825e6176add7b87f3abf66f81fe48b7f Mon Sep 17 00:00:00 2001 From: tsoybe <51762970+tsoybe@users.noreply.github.com> Date: Thu, 12 Nov 2020 22:04:05 +0100 Subject: [PATCH 1047/2234] Update dns_desec.sh ttl must be greater than or equal 3600, see https://desec.readthedocs.io/en/latest/dns/domains.html#domain-object --- dnsapi/dns_desec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index 61d080bd..a2e4d887 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -61,7 +61,7 @@ dns_desec_add() { fi _debug txtvalues "$txtvalues" _info "Adding record" - body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]" + body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":3600}]" if _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body"; then if _contains "$response" "$txtvalue"; then From 7dfc5a78bae3f4da640c3cb53b3eedd588c04837 Mon Sep 17 00:00:00 2001 From: tsoybe <51762970+tsoybe@users.noreply.github.com> Date: Thu, 12 Nov 2020 22:09:31 +0100 Subject: [PATCH 1048/2234] Update dns_desec.sh Deletion to --- dnsapi/dns_desec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index a2e4d887..f64660a8 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -130,7 +130,7 @@ dns_desec_rm() { _debug txtvalues "$txtvalues" _info "Deleting record" - body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]" + body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":3600}]" _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body" if [ "$_code" = "200" ]; then _info "Deleted, OK" From b19cb0805cfe72aec1cea8b1f4fc9e5921cf0d4e Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Tue, 17 Nov 2020 13:19:55 +0100 Subject: [PATCH 1049/2234] Adds dnsapi support for Simply.com --- dnsapi/dns_simply.sh | 240 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 dnsapi/dns_simply.sh diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh new file mode 100644 index 00000000..25dd9ff3 --- /dev/null +++ b/dnsapi/dns_simply.sh @@ -0,0 +1,240 @@ +#!/usr/bin/env sh + +# +#SIMPLY_AccountName="accountname" +# +#SIMPLY_ApiKey="apikey" +# +#SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" + +SIMPLY_Api="https://api.simply.com/1" +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_simply_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _simply_load_config; then + return 1 + fi + + _simply_save_config + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + + if ! _simply_add_record "$_domain" "$_sub_domain" "$txtvalue"; then + _err "Could not add DNS record" + return 1 + fi + + return 0 +} + +dns_simply_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _simply_load_config; then + return 1 + fi + + _simply_save_config + + _debug "First detect the root zone" + + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug "$txtvalue" + + _debug "Getting existing records" + + if ! _simply_get_all_records "$_domain"; then + _err "invalid domain" + return 1 + fi + + records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/') + record_array=(`echo $records |tr -d ' ' | tr ';' ' '`) + nr_of_deleted_records=0 + + for (( i=0; i<=${#record_array[@]}; i++ )); do + + record="${record_array[$i]}" + + if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then + + _info "Deleting record: $record" + + record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` + + if [[ $record_id -gt 0 ]]; then + + if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then + _err "Record with id $record_id could not be deleted" + return 1 + fi + + nr_of_deleted_records=1 + break + else + _err "Fetching record_id could not be done, this should not happen, exiting function. Failing record is $record" + break + fi + fi + + done + + if [[ $nr_of_deleted_records -eq 0 ]]; then + _err "No record deleted, the DNS record needs to be removed manually." + else + _info "Deleted $nr_of_deleted_records record" + fi + + return 0 +} + +#################### Private functions below ################################## + +_simply_load_config() { + SIMPLY_Api="${SIMPLY_Api:-$(_readaccountconf_mutable SIMPLY_Api)}" + SIMPLY_AccountName="${SIMPLY_AccountName:-$(_readaccountconf_mutable SIMPLY_AccountName)}" + SIMPLY_ApiKey="${SIMPLY_ApiKey:-$(_readaccountconf_mutable SIMPLY_ApiKey)}" + + if [ -z "$SIMPLY_Api" ]; then + SIMPLY_Api="$SIMPLY_Api_Default" + fi + + if [ -z "$SIMPLY_AccountName" ] || [ -z "$SIMPLY_ApiKey" ]; then + SIMPLY_AccountName="" + SIMPLY_ApiKey="" + + _err "A valid Simply API account and apikey not provided." + _err "Please provide a valid API user and try again." + + return 1 + fi + + return 0 +} + +_simply_save_config() { + if [ "$SIMPLY_Api" != "$SIMPLY_Api_Default" ]; then + _saveaccountconf_mutable SIMPLY_Api "$SIMPLY_Api" + fi + _saveaccountconf_mutable SIMPLY_AccountName "$SIMPLY_AccountName" + _saveaccountconf_mutable SIMPLY_ApiKey "$SIMPLY_ApiKey" +} + +_simply_get_all_records() { + domain=$1 + + if ! _simply_rest GET "my/products/$domain/dns/records"; then + return 1 + fi + + return 0 +} + +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _simply_rest GET "my/products/$h/dns"; then + return 1 + fi + + if _contains "$response" '"code":"NOT_FOUND"'; then + _debug "$h not found" + else + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +_simply_add_record() { + domain=$1 + sub_domain=$2 + txtval=$3 + + data="{\"name\": \"$sub_domain\", \"type\":\"TXT\", \"data\": \"$txtval\", \"priority\":0, \"ttl\": 3600}" + + if ! _simply_rest POST "my/products/$domain/dns/records" "$data"; then + _err "Adding record not successfull!" + return 1 + fi + + return 0 +} + +_simply_delete_record() { + domain=$1 + sub_domain=$2 + record_id=$3 + + _debug "Delete record with id $record_id" + + if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id"; then + _err "Deleting record not successfull!" + return 1 + fi + + return 0 +} + +_simply_rest() { + m=$1 + ep="$2" + data="$3" + + _debug "Data: $data" + _debug "Methodcall: $ep" + _debug "Call type: $m" + + export _H1="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + response="$(_post "$data" "$SIMPLY_Api/$SIMPLY_AccountName/$SIMPLY_ApiKey/$ep" "" "$m")" + else + response="$(_get "$SIMPLY_Api/$SIMPLY_AccountName/$SIMPLY_ApiKey/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + + _debug2 response "$response" + + if _contains "$response" "Invalid account authorization"; then + _err "It seems that your api key or accountnumber is not correct." + return 1 + fi + return 0 +} From bcc1b7b48a1c848bf675e1757f896f7a18a7776e Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Tue, 17 Nov 2020 13:49:32 +0100 Subject: [PATCH 1050/2234] Fix comments --- dnsapi/dns_simply.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 25dd9ff3..3914e1ab 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -59,7 +59,7 @@ dns_simply_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "$txtvalue" + _debug txtvalue "$txtvalue" _debug "Getting existing records" @@ -78,9 +78,9 @@ dns_simply_rm() { if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then - _info "Deleting record: $record" - record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` + + _info "Deleting record $record" if [[ $record_id -gt 0 ]]; then @@ -198,7 +198,7 @@ _simply_delete_record() { sub_domain=$2 record_id=$3 - _debug "Delete record with id $record_id" + _debug record_id "Delete record with id $record_id" if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id"; then _err "Deleting record not successfull!" @@ -213,9 +213,9 @@ _simply_rest() { ep="$2" data="$3" - _debug "Data: $data" - _debug "Methodcall: $ep" - _debug "Call type: $m" + _debug2 data "$data" + _debug2 ep "$ep" + _debug2 m "$m" export _H1="Content-Type: application/json" From c60613fbcbea3c9518df45ff6ec99ef5de5266f4 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Tue, 17 Nov 2020 14:20:45 +0100 Subject: [PATCH 1051/2234] Fix indentation and added some debug messages --- dnsapi/dns_simply.sh | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 3914e1ab..8fb56585 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -61,7 +61,7 @@ dns_simply_rm() { _debug _domain "$_domain" _debug txtvalue "$txtvalue" - _debug "Getting existing records" + _info "Getting all existing records" if ! _simply_get_all_records "$_domain"; then _err "invalid domain" @@ -71,31 +71,34 @@ dns_simply_rm() { records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/') record_array=(`echo $records |tr -d ' ' | tr ';' ' '`) nr_of_deleted_records=0 + + _info "Fetching txt record.." for (( i=0; i<=${#record_array[@]}; i++ )); do - record="${record_array[$i]}" + record="${record_array[$i]}" + _debug record "$record" - if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then + if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then - record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` + record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` - _info "Deleting record $record" + _info "Deleting record $record" - if [[ $record_id -gt 0 ]]; then + if [[ $record_id -gt 0 ]]; then - if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then - _err "Record with id $record_id could not be deleted" - return 1 + if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then + _err "Record with id $record_id could not be deleted" + return 1 + fi + + nr_of_deleted_records=1 + break + else + _err "Fetching record_id could not be done, this should not happen, exiting function. Failing record is $record" + break fi - - nr_of_deleted_records=1 - break - else - _err "Fetching record_id could not be done, this should not happen, exiting function. Failing record is $record" - break fi - fi done From 6ee38ceaba06e3ba9da63bb480f4b53cc4c76aa5 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 17 Nov 2020 22:50:40 +0800 Subject: [PATCH 1052/2234] fix https://github.com/acmesh-official/acme.sh/issues/3252 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3be3849d..456383bd 100755 --- a/acme.sh +++ b/acme.sh @@ -3993,7 +3993,7 @@ _check_dns_entries() { #file _get_cert_issuers() { _cfile="$1" - if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7"; then + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 else ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 From c349e9aabe5a3affa35d8c18292427edb0067b9d Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 18 Nov 2020 21:19:10 +0800 Subject: [PATCH 1053/2234] fix set-env --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 5f0bba72..c4d3167c 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -88,7 +88,7 @@ jobs: shell: cmd - name: Set ENV run: | - echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' + echo "PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin" >> $GITHUB_ENV - name: Clone acmetest shell: cmd run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ From 6cf0eb9e1d5b8f831c44b93adfcb8b9d5fe1d405 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 14:52:32 +0100 Subject: [PATCH 1054/2234] Fix CI-errors --- dnsapi/dns_simply.sh | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 8fb56585..9deceb25 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -7,7 +7,7 @@ # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" -SIMPLY_Api="https://api.simply.com/1" +SIMPLY_Api_Default="https://api.simply.com/1" ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -22,6 +22,7 @@ dns_simply_add() { _simply_save_config _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 @@ -69,23 +70,28 @@ dns_simply_rm() { fi records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/') - record_array=(`echo $records |tr -d ' ' | tr ';' ' '`) - nr_of_deleted_records=0 - - _info "Fetching txt record.." + record_array=$(echo $records |tr -d ' ' | tr ';' ' ') - for (( i=0; i<=${#record_array[@]}; i++ )); do - - record="${record_array[$i]}" + nr_of_deleted_records=0 + _info "Fetching txt record" + + for record in $record_array; do _debug record "$record" + + record_data=$(echo $record | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) + record_type=$(echo $record | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + + _debug2 record_data "$record_data" + _debug2 record_type "$record_type" + + if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then - if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then - - record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` + record_id=$(echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) _info "Deleting record $record" - - if [[ $record_id -gt 0 ]]; then + _debug2 record_id "$record_id" + + if [ "$record_id" -gt 0 ]; then if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then _err "Record with id $record_id could not be deleted" @@ -102,7 +108,7 @@ dns_simply_rm() { done - if [[ $nr_of_deleted_records -eq 0 ]]; then + if [ "$nr_of_deleted_records" -eq 0 ]; then _err "No record deleted, the DNS record needs to be removed manually." else _info "Deleted $nr_of_deleted_records record" From b20d8f195ba879c4af5f35f2910541d8bbf58383 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:12:22 +0100 Subject: [PATCH 1055/2234] Add double quotes to variables --- dnsapi/dns_simply.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 9deceb25..30211f7a 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -69,26 +69,25 @@ dns_simply_rm() { return 1 fi - records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/') - record_array=$(echo $records |tr -d ' ' | tr ';' ' ') + records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/' | tr "\n" ' '| tr -d ' ' | tr ';' ' ') nr_of_deleted_records=0 _info "Fetching txt record" - for record in $record_array; do + for record in $records; do _debug record "$record" - record_data=$(echo $record | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) - record_type=$(echo $record | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) + record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) _debug2 record_data "$record_data" _debug2 record_type "$record_type" if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then - record_id=$(echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) + record_id=$(echo "$record" | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) - _info "Deleting record $record" + _info "Deleting record $record" _debug2 record_id "$record_id" if [ "$record_id" -gt 0 ]; then From 2b8561f27d2376f4e7b1a8f45783e62227cadf35 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 18 Nov 2020 22:23:36 +0800 Subject: [PATCH 1056/2234] fix set-env --- .github/workflows/DNS.yml | 2 +- .github/workflows/LetsEncrypt.yml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index b7153506..c41851b8 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -144,7 +144,7 @@ jobs: shell: cmd - name: Set ENV run: | - echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' + echo "PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index c4d3167c..b5468ff6 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -89,6 +89,9 @@ jobs: - name: Set ENV run: | echo "PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin" >> $GITHUB_ENV + - name: Check ENV + run: | + echo "PATH=$PATH" - name: Clone acmetest shell: cmd run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ From 6ef66399f8accca401e0c55d24cb74624617bea6 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:37:26 +0100 Subject: [PATCH 1057/2234] Removed spaces on empty lines --- dnsapi/dns_simply.sh | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 30211f7a..6f2464ef 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -21,8 +21,7 @@ dns_simply_add() { _simply_save_config - _debug "First detect the root zone" - + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 @@ -36,8 +35,7 @@ dns_simply_add() { if ! _simply_add_record "$_domain" "$_sub_domain" "$txtvalue"; then _err "Could not add DNS record" return 1 - fi - + fi return 0 } @@ -126,7 +124,7 @@ _simply_load_config() { if [ -z "$SIMPLY_Api" ]; then SIMPLY_Api="$SIMPLY_Api_Default" fi - + if [ -z "$SIMPLY_AccountName" ] || [ -z "$SIMPLY_ApiKey" ]; then SIMPLY_AccountName="" SIMPLY_ApiKey="" @@ -149,8 +147,8 @@ _simply_save_config() { } _simply_get_all_records() { - domain=$1 - + domain=$1 + if ! _simply_rest GET "my/products/$domain/dns/records"; then return 1 fi @@ -190,14 +188,14 @@ _simply_add_record() { domain=$1 sub_domain=$2 txtval=$3 - + data="{\"name\": \"$sub_domain\", \"type\":\"TXT\", \"data\": \"$txtval\", \"priority\":0, \"ttl\": 3600}" if ! _simply_rest POST "my/products/$domain/dns/records" "$data"; then _err "Adding record not successfull!" return 1 fi - + return 0 } @@ -205,14 +203,14 @@ _simply_delete_record() { domain=$1 sub_domain=$2 record_id=$3 - + _debug record_id "Delete record with id $record_id" - + if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id"; then _err "Deleting record not successfull!" return 1 fi - + return 0 } @@ -220,7 +218,7 @@ _simply_rest() { m=$1 ep="$2" data="$3" - + _debug2 data "$data" _debug2 ep "$ep" _debug2 m "$m" @@ -237,12 +235,13 @@ _simply_rest() { _err "error $ep" return 1 fi - + _debug2 response "$response" - + if _contains "$response" "Invalid account authorization"; then _err "It seems that your api key or accountnumber is not correct." return 1 fi + return 0 } From c7116d40caf9e3b9bc48e77b34bcc255b0609083 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:46:16 +0100 Subject: [PATCH 1058/2234] Removes tabs and trailing spaces --- dnsapi/dns_simply.sh | 45 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 6f2464ef..bf383019 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -21,28 +21,29 @@ dns_simply_add() { _simply_save_config - _debug "First detect the root zone" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 fi - + _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" _info "Adding record" - if ! _simply_add_record "$_domain" "$_sub_domain" "$txtvalue"; then + if ! _simply_add_record "$_domain" "$_sub_domain" "$txtvalue"; then _err "Could not add DNS record" return 1 - fi + fi return 0 } dns_simply_rm() { fulldomain=$1 txtvalue=$2 - + if ! _simply_load_config; then return 1 fi @@ -61,12 +62,12 @@ dns_simply_rm() { _debug txtvalue "$txtvalue" _info "Getting all existing records" - + if ! _simply_get_all_records "$_domain"; then _err "invalid domain" return 1 fi - + records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/' | tr "\n" ' '| tr -d ' ' | tr ';' ' ') nr_of_deleted_records=0 @@ -74,27 +75,27 @@ dns_simply_rm() { for record in $records; do _debug record "$record" - - record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) - record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) - - _debug2 record_data "$record_data" - _debug2 record_type "$record_type" - - if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then + record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) + record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + + _debug2 record_data "$record_data" + _debug2 record_type "$record_type" + + if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then + record_id=$(echo "$record" | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) - + _info "Deleting record $record" _debug2 record_id "$record_id" - + if [ "$record_id" -gt 0 ]; then - + if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then _err "Record with id $record_id could not be deleted" return 1 fi - + nr_of_deleted_records=1 break else @@ -102,7 +103,7 @@ dns_simply_rm() { break fi fi - + done if [ "$nr_of_deleted_records" -eq 0 ]; then @@ -110,7 +111,7 @@ dns_simply_rm() { else _info "Deleted $nr_of_deleted_records record" fi - + return 0 } @@ -242,6 +243,6 @@ _simply_rest() { _err "It seems that your api key or accountnumber is not correct." return 1 fi - + return 0 } From f90f8824bb6034d90c47e6dae7acad54ffa0a056 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:52:46 +0100 Subject: [PATCH 1059/2234] Fix code style problems --- dnsapi/dns_simply.sh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index bf383019..379f1b42 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -22,7 +22,6 @@ dns_simply_add() { _simply_save_config _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 @@ -68,19 +67,19 @@ dns_simply_rm() { return 1 fi - records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/' | tr "\n" ' '| tr -d ' ' | tr ';' ' ') + records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/' | tr "\n" ' ' | tr -d ' ' | tr ';' ' ') nr_of_deleted_records=0 _info "Fetching txt record" - for record in $records; do + for record in $records; do _debug record "$record" - - record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) - record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) - _debug2 record_data "$record_data" - _debug2 record_type "$record_type" + record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) + record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + + _debug2 record_data "$record_data" + _debug2 record_type "$record_type" if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then @@ -98,7 +97,7 @@ dns_simply_rm() { nr_of_deleted_records=1 break - else + else _err "Fetching record_id could not be done, this should not happen, exiting function. Failing record is $record" break fi @@ -107,7 +106,7 @@ dns_simply_rm() { done if [ "$nr_of_deleted_records" -eq 0 ]; then - _err "No record deleted, the DNS record needs to be removed manually." + _err "No record deleted, the DNS record needs to be removed manually." else _info "Deleted $nr_of_deleted_records record" fi From 3274f9f155acb6f5ec13b9b56c8166c0fb6cc537 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:55:02 +0100 Subject: [PATCH 1060/2234] Fix code style problems --- dnsapi/dns_simply.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 379f1b42..9a9133e6 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -50,7 +50,7 @@ dns_simply_rm() { _simply_save_config _debug "First detect the root zone" - + if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 @@ -80,7 +80,7 @@ dns_simply_rm() { _debug2 record_data "$record_data" _debug2 record_type "$record_type" - + if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then record_id=$(echo "$record" | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) From 11b980f574c567361d720ea3421b68b668240b39 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 18 Nov 2020 23:16:36 +0800 Subject: [PATCH 1061/2234] fix set-env --- .github/workflows/DNS.yml | 3 ++- .github/workflows/LetsEncrypt.yml | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index c41851b8..748628dd 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -143,8 +143,9 @@ jobs: C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git shell: cmd - name: Set ENV + shell: cmd run: | - echo "PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin" >> $GITHUB_ENV + echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV% - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index b5468ff6..16b7e779 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -87,11 +87,13 @@ jobs: C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git shell: cmd - name: Set ENV + shell: cmd run: | - echo "PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin" >> $GITHUB_ENV + echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV% - name: Check ENV + shell: cmd run: | - echo "PATH=$PATH" + echo "PATH=%PATH%" - name: Clone acmetest shell: cmd run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ From 1e2d2abbdf668a2d307a07363d5e6e265d2dbee2 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 18:01:02 +0100 Subject: [PATCH 1062/2234] Fix comment --- dnsapi/dns_simply.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 9a9133e6..d053dcf6 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -8,8 +8,8 @@ #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" SIMPLY_Api_Default="https://api.simply.com/1" -######## Public functions ##################### +######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_simply_add() { fulldomain=$1 From 199ca77c2a07dc6821df516f8cba7662c018ba4e Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 19 Nov 2020 20:14:28 +0800 Subject: [PATCH 1063/2234] fix for PebbleStrict mode test. --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 456383bd..1e4b1152 100755 --- a/acme.sh +++ b/acme.sh @@ -5823,7 +5823,7 @@ _deactivate() { _URL_NAME="uri" fi - entries="$(echo "$response" | _egrep_o "[^{]*\"type\":\"[^\"]*\", *\"status\": *\"valid\", *\"$_URL_NAME\"[^}]*")" + entries="$(echo "$response" | tr '][' '=' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")" if [ -z "$entries" ]; then _info "No valid entries found." if [ -z "$thumbprint" ]; then @@ -5866,7 +5866,7 @@ _deactivate() { _debug _vtype "$_vtype" _info "Found $_vtype" - uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')" + uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*\"" | tr -d '" ' | cut -d : -f 2-)" _debug uri "$uri" if [ "$_d_type" ] && [ "$_d_type" != "$_vtype" ]; then From 1a163243ec280f0d776d838ddfebac57db5c75b5 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 22 Nov 2020 12:19:52 +0800 Subject: [PATCH 1064/2234] fix https://github.com/acmesh-official/acme.sh/issues/3259 --- dnsapi/dns_dpi.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_dpi.sh b/dnsapi/dns_dpi.sh index 831150a9..9cbf4d51 100755 --- a/dnsapi/dns_dpi.sh +++ b/dnsapi/dns_dpi.sh @@ -75,7 +75,7 @@ dns_dpi_rm() { return 1 fi - _contains "$response" "Action completed successful" + _contains "$response" "Operation successful" } @@ -93,7 +93,7 @@ add_record() { return 1 fi - _contains "$response" "Action completed successful" || _contains "$response" "Domain record already exists" + _contains "$response" "Operation successful" || _contains "$response" "Domain record already exists" } #################### Private functions below ################################## @@ -117,7 +117,7 @@ _get_root() { return 1 fi - if _contains "$response" "Action completed successful"; then + if _contains "$response" "Operation successful"; then _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then From 2e97b20f94bff7bd1e464ed49e95ba8c3f3c2618 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 22 Nov 2020 11:22:54 +0100 Subject: [PATCH 1065/2234] Added World4You DNS API --- dnsapi/dns_world4you.sh | 159 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 dnsapi/dns_world4you.sh diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh new file mode 100644 index 00000000..ec5a0e47 --- /dev/null +++ b/dnsapi/dns_world4you.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env sh + +# World4You - www.world4you.com +# Lorenz Stechauner, 2020 - https://www.github.com/NerLOR + +WORLD4YOU_API="https://my.world4you.com/en" + +################ Public functions ################ + +# Usage: dns_world4you_add +dns_world4you_add() { + fqdn="$1" + value="$2" + _info "Using world4you" + _debug fulldomain "$fqdn" + _debug txtvalue "$value" + + tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") + + _login + if [ "$?" != 0 ]; then + return 1 + fi + + export _H1="Cookie: W4YSESSID=$sessid" + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\)<.*$/\1/') + if [ -z "$paketnr" ]; then + _err "Unable to parse paketnr" + return 3 + fi + _debug paketnr "$paketnr" + + export _H1="Cookie: W4YSESSID=$sessid" + form=$(_get "$WORLD4YOU_API/$paketnr/dns") + formiddp=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/') + formidttl=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/') + form_token=$(echo "$form" | grep 'AddDnsRecordForm\[_token\]' | sed 's/^.*name="AddDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/') + if [ -z "$formiddp" ]; then + _err "Unable to parse form" + return 3 + fi + + _ORIG_ACME_CURL="$_ACME_CURL" + _ACME_CURL=$(echo "$_ACME_CURL" | sed 's/ -L / /') + + body="AddDnsRecordForm[name]=$record&AddDnsRecordForm[dnsType][type]=TXT&\ +AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\ +AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_token" + _info "Adding record..." + ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded') + + _ACME_CURL="$_ORIG_ACME_CURL" + + success=$(grep '302\|200' <"$HTTP_HEADER") + if [ "$success" ]; then + return 0 + else + _err "$(head -n 1 <"$HTTP_HEADER")" + return 2 + fi +} + +# Usage: dns_world4you_rm +dns_world4you_rm() { + fqdn="$1" + value="$2" + _info "Using world4you" + _debug fulldomain "$fqdn" + _debug txtvalue "$value" + + tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") + + _login + if [ "$?" != 0 ]; then + return 1 + fi + + export _H1="Cookie: W4YSESSID=$sessid" + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + if [ -z "$paketnr" ]; then + _err "Unable to parse paketnr" + return 3 + fi + _debug paketnr "$paketnr" + + form=$(_get "$WORLD4YOU_API/$paketnr/dns") + formiddp=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/') + formidttl=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/') + form_token=$(echo "$form" | grep 'DeleteDnsRecordForm\[_token\]' | sed 's/^.*name="DeleteDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/') + if [ -z "$formiddp" ]; then + _err "Unable to parse form" + return 3 + fi + + recordid=$(printf "TXT:%s.:\"%s\"" "$fqdn" "$value" | _base64) + _debug recordid "$recordid" + + _ORIG_ACME_CURL="$_ACME_CURL" + _ACME_CURL=$(echo "$_ACME_CURL" | sed 's/ -L / /') + + body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[aktivPaket]=$paketnr&\ +DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[uniqueFormIdTTL]=$formidttl&\ +DeleteDnsRecordForm[_token]=$form_token" + _info "Removing record..." + ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/deleteRecord" '' POST 'application/x-www-form-urlencoded') + + _ACME_CURL="$_ORIG_ACME_CURL" + + success=$(grep '302\|200' <"$HTTP_HEADER") + if [ "$success" ]; then + return 0 + else + _err "$(head -n 1 <"$HTTP_HEADER")" + return 2 + fi +} + +################ Private functions ################ + +# Usage: _login +_login() { + WORLD4YOU_USERNAME="${WORLD4YOU_USERNAME:-$(_readaccountconf_mutable WORLD4YOU_USERNAME)}" + WORLD4YOU_PASSWORD="${WORLD4YOU_PASSWORD:-$(_readaccountconf_mutable WORLD4YOU_PASSWORD)}" + + if [ -z "$WORLD4YOU_USERNAME" ] || [ -z "$WORLD4YOU_PASSWORD" ]; then + WORLD4YOU_USERNAME="" + WORLD4YOU_PASSWORD="" + _err "You don't specified world4you username and password yet." + _err "Usage: export WORLD4YOU_USERNAME=" + _err "Usage: export WORLD4YOU_PASSWORD=" + return 2 + fi + + _saveaccountconf_mutable WORLD4YOU_USERNAME "$WORLD4YOU_USERNAME" + _saveaccountconf_mutable WORLD4YOU_PASSWORD "$WORLD4YOU_PASSWORD" + + _info "Logging in..." + + username="$WORLD4YOU_USERNAME" + password="$WORLD4YOU_PASSWORD" + csrf_token=$(_get "$WORLD4YOU_API/login" | grep '_csrf_token' | sed 's/^.*]*value=\"\([^"]*\)\".*$/\1/') + sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/') + + export _H1="Cookie: W4YSESSID=$sessid" + export _H2="X-Requested-With: XMLHttpRequest" + body="_username=$username&_password=$password&_csrf_token=$csrf_token" + ret=$(_post "$body" "$WORLD4YOU_API/login" '' POST 'application/x-www-form-urlencoded') + unset _H2 + _debug ret "$ret" + if _contains "$ret" "\"success\":true"; then + _info "Successfully logged in" + sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/') + else + _err "Unable to log in: $(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')" + return 1 + fi +} From cc8f2afce9ed2009565f65fa81369d7a96f18d74 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 22 Nov 2020 21:41:22 +0800 Subject: [PATCH 1066/2234] fix for Solaris, and add Solaris to Github actions --- .github/workflows/DNS.yml | 37 +++++++++++++++++++++++++++++++ .github/workflows/LetsEncrypt.yml | 26 ++++++++++++++++++++++ acme.sh | 4 ++-- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 748628dd..5dc2d453 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -208,5 +208,42 @@ jobs: cd ../acmetest ./letest.sh + Solaris: + runs-on: macos-latest + needs: FreeBSD + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/solaris-vm@v0.0.1 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: pkgutil -y -i socat curl + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 16b7e779..8d0c4eb0 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -119,3 +119,29 @@ jobs: run: | cd ../acmetest && ./letest.sh + Solaris: + runs-on: macos-latest + needs: FreeBSD + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 + steps: + - uses: actions/checkout@v2 + - uses: vmactions/ngrok-tunnel@v0.0.1 + id: ngrok + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.ngrok.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/solaris-vm@v0.0.1 + with: + envs: 'TEST_LOCAL TestingDomain' + nat: | + "8080": "80" + prepare: pkgutil -y -i socat curl + run: | + cd ../acmetest && ./letest.sh + diff --git a/acme.sh b/acme.sh index 1e4b1152..e549f7c8 100755 --- a/acme.sh +++ b/acme.sh @@ -2086,7 +2086,7 @@ _send_signed_request() { _debug2 original "$response" if echo "$responseHeaders" | grep -i "Content-Type: *application/json" >/dev/null 2>&1; then - response="$(echo "$response" | _normalizeJson | _json_decode)" + response="$(echo "$response" | _json_decode | _normalizeJson)" fi _debug2 response "$response" @@ -5823,7 +5823,7 @@ _deactivate() { _URL_NAME="uri" fi - entries="$(echo "$response" | tr '][' '=' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")" + entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")" if [ -z "$entries" ]; then _info "No valid entries found." if [ -z "$thumbprint" ]; then From 349429b76e534313a4989794707fc1463399cfb2 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 22 Nov 2020 21:55:55 +0800 Subject: [PATCH 1067/2234] fix solaris badge --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7215785c..cd747666 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |1|[![MacOS](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX |2|[![Windows](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included) |3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD -|4|[![Ubuntu](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)| Ubuntu -|5|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense -|6|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD -|7|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris +|4|[![Solaris](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Solaris +|5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)| Ubuntu +|6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense +|7|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD |8|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian |9|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS |10|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE From b8e5c0d8988522acbad8e0346d8a69fe024fcdd1 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sun, 22 Nov 2020 22:34:21 +0800 Subject: [PATCH 1068/2234] feat: Add huaweicloud intl dnsapi --- dnsapi/dns_huaweicloud.sh | 199 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 dnsapi/dns_huaweicloud.sh diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh new file mode 100644 index 00000000..69ab14be --- /dev/null +++ b/dnsapi/dns_huaweicloud.sh @@ -0,0 +1,199 @@ +#!/usr/bin/env sh + +# HUAWEICLOUD_Username +# HUAWEICLOUD_Password +# HUAWEICLOUD_ProjectID + +iam_api="https://iam.myhuaweicloud.com" +dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" + +######## Public functions ##################### + +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record +# +# Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/zh-cn_topic_0132421999.html +# + +dns_huaweicloud_add() { + fulldomain=$1 + txtvalue=$2 + + HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" + HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" + HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" + _debug2 "${token}" + zoneid="$(_get_zoneid "${token}" "${fulldomain}")" + _debug "${zoneid}" + + _debug "Adding Record" + _add_record "${token}" "${fulldomain}" "${txtvalue}" + ret="$?" + if [ "${ret}" != "0" ]; then + _err "dns_huaweicloud: Error adding record." + return 1 + fi + + # Do saving work if all succeeded + _saveaccountconf_mutable HUAWEICLOUD_Username "${HUAWEICLOUD_Username}" + _saveaccountconf_mutable HUAWEICLOUD_Password "${HUAWEICLOUD_Password}" + _saveaccountconf_mutable HUAWEICLOUD_ProjectID "${HUAWEICLOUD_ProjectID}" + return 0 +} + +# Usage: fulldomain txtvalue +# Used to remove the txt record after validation +# +# Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/dns_api_64005.html +# + +dns_huaweicloud_rm() { + fulldomain=$1 + txtvalue=$2 + + HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" + HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" + HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" + _debug2 "${token}" + zoneid="$(_get_zoneid "${token}" "${fulldomain}")" + _debug "${zoneid}" + record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" + _debug "Record Set ID is: ${record_id}" + while [ "${record_id}" != "0" ]; do + _debug "Adding Record" + _rm_record "${token}" "${zoneid}" "${record_id}" + record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" + done + return 0 +} + +################### Private functions below ################################## + +# _get_zoneid +# +# _token=$1 +# _domain_string=$2 +# +# printf "%s" "${_zoneid}" +_get_zoneid() { + _token=$1 + _domain_string=$2 + export _H1="X-Auth-Token: ${_token}" + + i=1 + while true; do + h=$(printf "%s" "${_domain_string}" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + _debug "$h" + response=$(_get "${dns_api}/v2/zones?name=${h}") + + if _contains "${response}" "id"; then + _debug "Get Zone ID Success." + _zoneid=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") + printf "%s" "${_zoneid}" + return 0 + fi + + i=$(_math "$i" + 1) + done + return 1 +} + +_get_recordset_id() { + _token=$1 + _domain=$2 + _zoneid=$3 + export _H1="X-Auth-Token: ${_token}" + + response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}") + if _contains "${response}" "id"; then + _id="$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")" + printf "%s" "${_id}" + return 0 + fi + printf "%s" "0" + return 1 +} + +_add_record() { + _token=$1 + _domain=$2 + _txtvalue=$3 + body="{ + \"name\": \"${_domain}.\", + \"description\": \"ACME Challenge\", + \"type\": \"TXT\", + \"ttl\": 1, + \"records\": [ + \"\\\"${_txtvalue}\\\"\" + ] + }" + _debug2 "${body}" + export _H2="Content-Type: application/json" + export _H1="X-Auth-Token: ${_token}" + + _post "${body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + if [ "$_code" != "202" ]; then + _err "dns_huaweicloud: http code ${_code}" + return 1 + fi + return 0 +} + +_rm_record() { + _token=$1 + _zone_id=$2 + _record_id=$3 + + export _H2="Content-Type: application/json" + export _H1="X-Auth-Token: ${_token}" + + _post "${body}" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" + return 0 +} + +_get_token() { + _username=$1 + _password=$2 + _project=$3 + + _debug "Getting Token" + body="{ + \"auth\": { + \"identity\": { + \"methods\": [ + \"password\" + ], + \"password\": { + \"user\": { + \"name\": \"${_username}\", + \"password\": \"${_password}\", + \"domain\": { + \"name\": \"${_username}\" + } + } + } + }, + \"scope\": { + \"project\": { + \"id\": \"${_project}\" + } + } + } + }" + export _H1="Content-Type: application/json;charset=utf8" + _post "${body}" "${iam_api}/v3/auth/tokens" >/dev/null + _code=$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n") + _token=$(grep "^X-Subject-Token" "$HTTP_HEADER" | cut -d " " -f 2-) + _debug2 "${_code}" + printf "%s" "${_token}" + return 0 +} From 7db592d27a7be071033d221cb57cf33bb5ae206a Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sun, 22 Nov 2020 22:56:47 +0800 Subject: [PATCH 1069/2234] fix: fix failing ci test --- dnsapi/dns_huaweicloud.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 69ab14be..4aee6410 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -63,6 +63,8 @@ dns_huaweicloud_rm() { _debug "${zoneid}" record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" _debug "Record Set ID is: ${record_id}" + + # Remove all records while [ "${record_id}" != "0" ]; do _debug "Adding Record" _rm_record "${token}" "${zoneid}" "${record_id}" From 28ce1c1249bc2297d3588adfa49c2974d0353c3d Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 00:20:38 +0800 Subject: [PATCH 1070/2234] fix: fix wrong debug output --- dnsapi/dns_huaweicloud.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 4aee6410..56ba19ef 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -66,7 +66,7 @@ dns_huaweicloud_rm() { # Remove all records while [ "${record_id}" != "0" ]; do - _debug "Adding Record" + _debug "Removing Record" _rm_record "${token}" "${zoneid}" "${record_id}" record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" done @@ -158,7 +158,7 @@ _rm_record() { export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" - _post "${body}" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" + _post "${body}" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" >/dev/null return 0 } From e01fb503592f4c9fd4a58edfc8aa1b445396cf2e Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 00:32:50 +0800 Subject: [PATCH 1071/2234] feat: add env var check --- dnsapi/dns_huaweicloud.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 56ba19ef..0f08bcdf 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -57,6 +57,11 @@ dns_huaweicloud_rm() { HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ]; then + _err "Please provide enough information" + return 1 + fi + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" _debug2 "${token}" zoneid="$(_get_zoneid "${token}" "${fulldomain}")" From f6f6550bfbf19c0b3554d531787a33b20b9ddd83 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 14:25:48 +0800 Subject: [PATCH 1072/2234] feat: add very tricky method to adapt to non-intuitive huaweicloud api --- dnsapi/dns_huaweicloud.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 0f08bcdf..2b891b38 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -23,6 +23,11 @@ dns_huaweicloud_add() { HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ]; then + _err "Not enough info provided to dns_huaweicloud!" + return 1 + fi + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" _debug2 "${token}" zoneid="$(_get_zoneid "${token}" "${fulldomain}")" @@ -133,15 +138,36 @@ _add_record() { _token=$1 _domain=$2 _txtvalue=$3 + + # Get Existing Records + export _H1="X-Auth-Token: ${_token}" + response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}") + _exist_record=$(echo "${response}" | sed ':a;N;$!ba;s/\n/ /g' | grep -o '"records":[^]]*' | sed 's/\"records\"\: \[//g') + _debug "${_exist_record}" + + # Check if record exist + # Generate body data body="{ \"name\": \"${_domain}.\", \"description\": \"ACME Challenge\", \"type\": \"TXT\", \"ttl\": 1, \"records\": [ + ${_exist_record}, \"\\\"${_txtvalue}\\\"\" ] }" + if [ -z "${_exist_record}" ]; then + body="{ + \"name\": \"${_domain}.\", + \"description\": \"ACME Challenge\", + \"type\": \"TXT\", + \"ttl\": 1, + \"records\": [ + \"\\\"${_txtvalue}\\\"\" + ] + }" + fi _debug2 "${body}" export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" From 5d0657c49a0d2ac6f50981f91c6a95cfe490ae15 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 14:57:33 +0800 Subject: [PATCH 1073/2234] fix: fix adding record before removing --- dnsapi/dns_huaweicloud.sh | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 2b891b38..625588d1 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -141,13 +141,15 @@ _add_record() { # Get Existing Records export _H1="X-Auth-Token: ${_token}" - response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}") - _exist_record=$(echo "${response}" | sed ':a;N;$!ba;s/\n/ /g' | grep -o '"records":[^]]*' | sed 's/\"records\"\: \[//g') + response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") + + _debug "${response}" + _exist_record=$(echo "${response}" | sed ':a;N;$!ba;s/\n/ /g' | grep -o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist # Generate body data - body="{ + _post_body="{ \"name\": \"${_domain}.\", \"description\": \"ACME Challenge\", \"type\": \"TXT\", @@ -158,7 +160,7 @@ _add_record() { ] }" if [ -z "${_exist_record}" ]; then - body="{ + _post_body="{ \"name\": \"${_domain}.\", \"description\": \"ACME Challenge\", \"type\": \"TXT\", @@ -168,19 +170,38 @@ _add_record() { ] }" fi - _debug2 "${body}" + + _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" + _debug "Record Set ID is: ${_record_id}" + + # Remove all records + while [ "${_record_id}" != "0" ]; do + _debug "Removing Record" + _rm_record "${_token}" "${zoneid}" "${_record_id}" + _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" + _debug "${_record_id}" + done + + # Add brand new records with all old and new records export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" - _post "${body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null + _debug "${_post_body}" + sleep 2 + _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" if [ "$_code" != "202" ]; then _err "dns_huaweicloud: http code ${_code}" + sleep 60 return 1 fi return 0 } +# _rm_record $token $zoneid $recordid +# assume ${dns_api} exist +# no output +# return 0 _rm_record() { _token=$1 _zone_id=$2 @@ -189,8 +210,8 @@ _rm_record() { export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" - _post "${body}" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" >/dev/null - return 0 + _post "" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" >/dev/null + return $? } _get_token() { From 65c06da275c49b1675d46af91d8e0e0e366cf29e Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Tue, 17 Nov 2020 13:19:55 +0100 Subject: [PATCH 1074/2234] Adds dnsapi support for Simply.com --- dnsapi/dns_simply.sh | 240 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 dnsapi/dns_simply.sh diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh new file mode 100644 index 00000000..25dd9ff3 --- /dev/null +++ b/dnsapi/dns_simply.sh @@ -0,0 +1,240 @@ +#!/usr/bin/env sh + +# +#SIMPLY_AccountName="accountname" +# +#SIMPLY_ApiKey="apikey" +# +#SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" + +SIMPLY_Api="https://api.simply.com/1" +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_simply_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _simply_load_config; then + return 1 + fi + + _simply_save_config + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + + if ! _simply_add_record "$_domain" "$_sub_domain" "$txtvalue"; then + _err "Could not add DNS record" + return 1 + fi + + return 0 +} + +dns_simply_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _simply_load_config; then + return 1 + fi + + _simply_save_config + + _debug "First detect the root zone" + + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug "$txtvalue" + + _debug "Getting existing records" + + if ! _simply_get_all_records "$_domain"; then + _err "invalid domain" + return 1 + fi + + records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/') + record_array=(`echo $records |tr -d ' ' | tr ';' ' '`) + nr_of_deleted_records=0 + + for (( i=0; i<=${#record_array[@]}; i++ )); do + + record="${record_array[$i]}" + + if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then + + _info "Deleting record: $record" + + record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` + + if [[ $record_id -gt 0 ]]; then + + if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then + _err "Record with id $record_id could not be deleted" + return 1 + fi + + nr_of_deleted_records=1 + break + else + _err "Fetching record_id could not be done, this should not happen, exiting function. Failing record is $record" + break + fi + fi + + done + + if [[ $nr_of_deleted_records -eq 0 ]]; then + _err "No record deleted, the DNS record needs to be removed manually." + else + _info "Deleted $nr_of_deleted_records record" + fi + + return 0 +} + +#################### Private functions below ################################## + +_simply_load_config() { + SIMPLY_Api="${SIMPLY_Api:-$(_readaccountconf_mutable SIMPLY_Api)}" + SIMPLY_AccountName="${SIMPLY_AccountName:-$(_readaccountconf_mutable SIMPLY_AccountName)}" + SIMPLY_ApiKey="${SIMPLY_ApiKey:-$(_readaccountconf_mutable SIMPLY_ApiKey)}" + + if [ -z "$SIMPLY_Api" ]; then + SIMPLY_Api="$SIMPLY_Api_Default" + fi + + if [ -z "$SIMPLY_AccountName" ] || [ -z "$SIMPLY_ApiKey" ]; then + SIMPLY_AccountName="" + SIMPLY_ApiKey="" + + _err "A valid Simply API account and apikey not provided." + _err "Please provide a valid API user and try again." + + return 1 + fi + + return 0 +} + +_simply_save_config() { + if [ "$SIMPLY_Api" != "$SIMPLY_Api_Default" ]; then + _saveaccountconf_mutable SIMPLY_Api "$SIMPLY_Api" + fi + _saveaccountconf_mutable SIMPLY_AccountName "$SIMPLY_AccountName" + _saveaccountconf_mutable SIMPLY_ApiKey "$SIMPLY_ApiKey" +} + +_simply_get_all_records() { + domain=$1 + + if ! _simply_rest GET "my/products/$domain/dns/records"; then + return 1 + fi + + return 0 +} + +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _simply_rest GET "my/products/$h/dns"; then + return 1 + fi + + if _contains "$response" '"code":"NOT_FOUND"'; then + _debug "$h not found" + else + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +_simply_add_record() { + domain=$1 + sub_domain=$2 + txtval=$3 + + data="{\"name\": \"$sub_domain\", \"type\":\"TXT\", \"data\": \"$txtval\", \"priority\":0, \"ttl\": 3600}" + + if ! _simply_rest POST "my/products/$domain/dns/records" "$data"; then + _err "Adding record not successfull!" + return 1 + fi + + return 0 +} + +_simply_delete_record() { + domain=$1 + sub_domain=$2 + record_id=$3 + + _debug "Delete record with id $record_id" + + if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id"; then + _err "Deleting record not successfull!" + return 1 + fi + + return 0 +} + +_simply_rest() { + m=$1 + ep="$2" + data="$3" + + _debug "Data: $data" + _debug "Methodcall: $ep" + _debug "Call type: $m" + + export _H1="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + response="$(_post "$data" "$SIMPLY_Api/$SIMPLY_AccountName/$SIMPLY_ApiKey/$ep" "" "$m")" + else + response="$(_get "$SIMPLY_Api/$SIMPLY_AccountName/$SIMPLY_ApiKey/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + + _debug2 response "$response" + + if _contains "$response" "Invalid account authorization"; then + _err "It seems that your api key or accountnumber is not correct." + return 1 + fi + return 0 +} From 81c496d96c4fe5b4aa4de3e47cc7d40f017af194 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Tue, 17 Nov 2020 13:49:32 +0100 Subject: [PATCH 1075/2234] Fix comments --- dnsapi/dns_simply.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 25dd9ff3..3914e1ab 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -59,7 +59,7 @@ dns_simply_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "$txtvalue" + _debug txtvalue "$txtvalue" _debug "Getting existing records" @@ -78,9 +78,9 @@ dns_simply_rm() { if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then - _info "Deleting record: $record" - record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` + + _info "Deleting record $record" if [[ $record_id -gt 0 ]]; then @@ -198,7 +198,7 @@ _simply_delete_record() { sub_domain=$2 record_id=$3 - _debug "Delete record with id $record_id" + _debug record_id "Delete record with id $record_id" if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id"; then _err "Deleting record not successfull!" @@ -213,9 +213,9 @@ _simply_rest() { ep="$2" data="$3" - _debug "Data: $data" - _debug "Methodcall: $ep" - _debug "Call type: $m" + _debug2 data "$data" + _debug2 ep "$ep" + _debug2 m "$m" export _H1="Content-Type: application/json" From 4284777556d11747015273051f260a60b539e392 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Tue, 17 Nov 2020 14:20:45 +0100 Subject: [PATCH 1076/2234] Fix indentation and added some debug messages --- dnsapi/dns_simply.sh | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 3914e1ab..8fb56585 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -61,7 +61,7 @@ dns_simply_rm() { _debug _domain "$_domain" _debug txtvalue "$txtvalue" - _debug "Getting existing records" + _info "Getting all existing records" if ! _simply_get_all_records "$_domain"; then _err "invalid domain" @@ -71,31 +71,34 @@ dns_simply_rm() { records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/') record_array=(`echo $records |tr -d ' ' | tr ';' ' '`) nr_of_deleted_records=0 + + _info "Fetching txt record.." for (( i=0; i<=${#record_array[@]}; i++ )); do - record="${record_array[$i]}" + record="${record_array[$i]}" + _debug record "$record" - if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then + if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then - record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` + record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` - _info "Deleting record $record" + _info "Deleting record $record" - if [[ $record_id -gt 0 ]]; then + if [[ $record_id -gt 0 ]]; then - if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then - _err "Record with id $record_id could not be deleted" - return 1 + if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then + _err "Record with id $record_id could not be deleted" + return 1 + fi + + nr_of_deleted_records=1 + break + else + _err "Fetching record_id could not be done, this should not happen, exiting function. Failing record is $record" + break fi - - nr_of_deleted_records=1 - break - else - _err "Fetching record_id could not be done, this should not happen, exiting function. Failing record is $record" - break fi - fi done From 8e64329d05edf4035460f08aacf244d5f68dbb44 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 14:52:32 +0100 Subject: [PATCH 1077/2234] Fix CI-errors --- dnsapi/dns_simply.sh | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 8fb56585..9deceb25 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -7,7 +7,7 @@ # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" -SIMPLY_Api="https://api.simply.com/1" +SIMPLY_Api_Default="https://api.simply.com/1" ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -22,6 +22,7 @@ dns_simply_add() { _simply_save_config _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 @@ -69,23 +70,28 @@ dns_simply_rm() { fi records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/') - record_array=(`echo $records |tr -d ' ' | tr ';' ' '`) - nr_of_deleted_records=0 - - _info "Fetching txt record.." + record_array=$(echo $records |tr -d ' ' | tr ';' ' ') - for (( i=0; i<=${#record_array[@]}; i++ )); do - - record="${record_array[$i]}" + nr_of_deleted_records=0 + _info "Fetching txt record" + + for record in $record_array; do _debug record "$record" + + record_data=$(echo $record | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) + record_type=$(echo $record | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + + _debug2 record_data "$record_data" + _debug2 record_type "$record_type" + + if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then - if [[ "$record" == *"$txtvalue"* && "$record" == *"TXT"* ]]; then - - record_id=`echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2` + record_id=$(echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) _info "Deleting record $record" - - if [[ $record_id -gt 0 ]]; then + _debug2 record_id "$record_id" + + if [ "$record_id" -gt 0 ]; then if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then _err "Record with id $record_id could not be deleted" @@ -102,7 +108,7 @@ dns_simply_rm() { done - if [[ $nr_of_deleted_records -eq 0 ]]; then + if [ "$nr_of_deleted_records" -eq 0 ]; then _err "No record deleted, the DNS record needs to be removed manually." else _info "Deleted $nr_of_deleted_records record" From 449f00f9606268112c215450ef233bc051767db1 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:12:22 +0100 Subject: [PATCH 1078/2234] Add double quotes to variables --- dnsapi/dns_simply.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 9deceb25..30211f7a 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -69,26 +69,25 @@ dns_simply_rm() { return 1 fi - records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/') - record_array=$(echo $records |tr -d ' ' | tr ';' ' ') + records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/' | tr "\n" ' '| tr -d ' ' | tr ';' ' ') nr_of_deleted_records=0 _info "Fetching txt record" - for record in $record_array; do + for record in $records; do _debug record "$record" - record_data=$(echo $record | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) - record_type=$(echo $record | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) + record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) _debug2 record_data "$record_data" _debug2 record_type "$record_type" if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then - record_id=$(echo $record | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) + record_id=$(echo "$record" | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) - _info "Deleting record $record" + _info "Deleting record $record" _debug2 record_id "$record_id" if [ "$record_id" -gt 0 ]; then From 9ad05e640d83ae368ff690c14306e0cad085c338 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:37:26 +0100 Subject: [PATCH 1079/2234] Removed spaces on empty lines --- dnsapi/dns_simply.sh | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 30211f7a..6f2464ef 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -21,8 +21,7 @@ dns_simply_add() { _simply_save_config - _debug "First detect the root zone" - + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 @@ -36,8 +35,7 @@ dns_simply_add() { if ! _simply_add_record "$_domain" "$_sub_domain" "$txtvalue"; then _err "Could not add DNS record" return 1 - fi - + fi return 0 } @@ -126,7 +124,7 @@ _simply_load_config() { if [ -z "$SIMPLY_Api" ]; then SIMPLY_Api="$SIMPLY_Api_Default" fi - + if [ -z "$SIMPLY_AccountName" ] || [ -z "$SIMPLY_ApiKey" ]; then SIMPLY_AccountName="" SIMPLY_ApiKey="" @@ -149,8 +147,8 @@ _simply_save_config() { } _simply_get_all_records() { - domain=$1 - + domain=$1 + if ! _simply_rest GET "my/products/$domain/dns/records"; then return 1 fi @@ -190,14 +188,14 @@ _simply_add_record() { domain=$1 sub_domain=$2 txtval=$3 - + data="{\"name\": \"$sub_domain\", \"type\":\"TXT\", \"data\": \"$txtval\", \"priority\":0, \"ttl\": 3600}" if ! _simply_rest POST "my/products/$domain/dns/records" "$data"; then _err "Adding record not successfull!" return 1 fi - + return 0 } @@ -205,14 +203,14 @@ _simply_delete_record() { domain=$1 sub_domain=$2 record_id=$3 - + _debug record_id "Delete record with id $record_id" - + if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id"; then _err "Deleting record not successfull!" return 1 fi - + return 0 } @@ -220,7 +218,7 @@ _simply_rest() { m=$1 ep="$2" data="$3" - + _debug2 data "$data" _debug2 ep "$ep" _debug2 m "$m" @@ -237,12 +235,13 @@ _simply_rest() { _err "error $ep" return 1 fi - + _debug2 response "$response" - + if _contains "$response" "Invalid account authorization"; then _err "It seems that your api key or accountnumber is not correct." return 1 fi + return 0 } From fcb97f802f8c19852bb56216716d17395f4441cf Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:46:16 +0100 Subject: [PATCH 1080/2234] Removes tabs and trailing spaces --- dnsapi/dns_simply.sh | 45 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 6f2464ef..bf383019 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -21,28 +21,29 @@ dns_simply_add() { _simply_save_config - _debug "First detect the root zone" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 fi - + _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" _info "Adding record" - if ! _simply_add_record "$_domain" "$_sub_domain" "$txtvalue"; then + if ! _simply_add_record "$_domain" "$_sub_domain" "$txtvalue"; then _err "Could not add DNS record" return 1 - fi + fi return 0 } dns_simply_rm() { fulldomain=$1 txtvalue=$2 - + if ! _simply_load_config; then return 1 fi @@ -61,12 +62,12 @@ dns_simply_rm() { _debug txtvalue "$txtvalue" _info "Getting all existing records" - + if ! _simply_get_all_records "$_domain"; then _err "invalid domain" return 1 fi - + records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/' | tr "\n" ' '| tr -d ' ' | tr ';' ' ') nr_of_deleted_records=0 @@ -74,27 +75,27 @@ dns_simply_rm() { for record in $records; do _debug record "$record" - - record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) - record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) - - _debug2 record_data "$record_data" - _debug2 record_type "$record_type" - - if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then + record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) + record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + + _debug2 record_data "$record_data" + _debug2 record_type "$record_type" + + if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then + record_id=$(echo "$record" | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) - + _info "Deleting record $record" _debug2 record_id "$record_id" - + if [ "$record_id" -gt 0 ]; then - + if ! _simply_delete_record "$_domain" "$_sub_domain" "$record_id"; then _err "Record with id $record_id could not be deleted" return 1 fi - + nr_of_deleted_records=1 break else @@ -102,7 +103,7 @@ dns_simply_rm() { break fi fi - + done if [ "$nr_of_deleted_records" -eq 0 ]; then @@ -110,7 +111,7 @@ dns_simply_rm() { else _info "Deleted $nr_of_deleted_records record" fi - + return 0 } @@ -242,6 +243,6 @@ _simply_rest() { _err "It seems that your api key or accountnumber is not correct." return 1 fi - + return 0 } From 29d0a1714e3d7a33e55617c1f11573b2a44eafef Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:52:46 +0100 Subject: [PATCH 1081/2234] Fix code style problems --- dnsapi/dns_simply.sh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index bf383019..379f1b42 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -22,7 +22,6 @@ dns_simply_add() { _simply_save_config _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 @@ -68,19 +67,19 @@ dns_simply_rm() { return 1 fi - records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/' | tr "\n" ' '| tr -d ' ' | tr ';' ' ') + records=$(echo "$response" | tr '{' "\n" | grep 'record_id\|type\|data\|\name' | sed 's/\"record_id/;\"record_id/' | tr "\n" ' ' | tr -d ' ' | tr ';' ' ') nr_of_deleted_records=0 _info "Fetching txt record" - for record in $records; do + for record in $records; do _debug record "$record" - - record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) - record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) - _debug2 record_data "$record_data" - _debug2 record_type "$record_type" + record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) + record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + + _debug2 record_data "$record_data" + _debug2 record_type "$record_type" if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then @@ -98,7 +97,7 @@ dns_simply_rm() { nr_of_deleted_records=1 break - else + else _err "Fetching record_id could not be done, this should not happen, exiting function. Failing record is $record" break fi @@ -107,7 +106,7 @@ dns_simply_rm() { done if [ "$nr_of_deleted_records" -eq 0 ]; then - _err "No record deleted, the DNS record needs to be removed manually." + _err "No record deleted, the DNS record needs to be removed manually." else _info "Deleted $nr_of_deleted_records record" fi From 30f359e6427f289c0181375f4f2b9300c1e27a09 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:55:02 +0100 Subject: [PATCH 1082/2234] Fix code style problems --- dnsapi/dns_simply.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 379f1b42..9a9133e6 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -50,7 +50,7 @@ dns_simply_rm() { _simply_save_config _debug "First detect the root zone" - + if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 @@ -80,7 +80,7 @@ dns_simply_rm() { _debug2 record_data "$record_data" _debug2 record_type "$record_type" - + if [ "$record_data" = "$txtvalue" ] && [ "$record_type" = "TXT" ]; then record_id=$(echo "$record" | cut -d "," -f 1 | grep "record_id" | cut -d ":" -f 2) From 69bdbaed410c8bb38ed5a67f031b30e8420ab6bc Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 18:01:02 +0100 Subject: [PATCH 1083/2234] Fix comment --- dnsapi/dns_simply.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 9a9133e6..d053dcf6 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -8,8 +8,8 @@ #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" SIMPLY_Api_Default="https://api.simply.com/1" -######## Public functions ##################### +######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_simply_add() { fulldomain=$1 From e35ef7594993665e8f472a99e0a6d392cc80e44d Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 22:18:57 +0800 Subject: [PATCH 1084/2234] fix: fix solaris sed and grep issue --- dnsapi/dns_huaweicloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 625588d1..11f231bc 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -144,7 +144,7 @@ _add_record() { response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") _debug "${response}" - _exist_record=$(echo "${response}" | sed ':a;N;$!ba;s/\n/ /g' | grep -o '"records":[^]]*' | sed 's/\"records\"\:\[//g') + _exist_record=$(echo "${response}" | sed -e ':a' -e 'N;$!ba;' -e 's/\n/ /g' | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist From 83a4db3b31f7fb91c4a6c9a3fed447c92d486092 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 23:46:06 +0800 Subject: [PATCH 1085/2234] fix: remove sed before grep, but lead to less robusty --- dnsapi/dns_huaweicloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 11f231bc..36be21a3 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -144,7 +144,7 @@ _add_record() { response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") _debug "${response}" - _exist_record=$(echo "${response}" | sed -e ':a' -e 'N;$!ba;' -e 's/\n/ /g' | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') + _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist From c4ddddd4344e728e3273634cb58583fe62e4022f Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 24 Nov 2020 10:05:34 +0800 Subject: [PATCH 1086/2234] refactor: remove dirty debug code - add tr to replace sed for robusty - add comments --- dnsapi/dns_huaweicloud.sh | 42 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 36be21a3..a7ca619f 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -23,8 +23,9 @@ dns_huaweicloud_add() { HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" - if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ]; then - _err "Not enough info provided to dns_huaweicloud!" + # Check information + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then + _err "Not enough information provided to dns_huaweicloud!" return 1 fi @@ -62,8 +63,9 @@ dns_huaweicloud_rm() { HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" - if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ]; then - _err "Please provide enough information" + # Check information + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then + _err "Not enough information provided to dns_huaweicloud!" return 1 fi @@ -75,6 +77,8 @@ dns_huaweicloud_rm() { _debug "Record Set ID is: ${record_id}" # Remove all records + # Therotically HuaweiCloud does not allow more than one record set + # But remove them recurringly to increase robusty while [ "${record_id}" != "0" ]; do _debug "Removing Record" _rm_record "${token}" "${zoneid}" "${record_id}" @@ -143,22 +147,12 @@ _add_record() { export _H1="X-Auth-Token: ${_token}" response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") - _debug "${response}" - _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') + _debug2 "${response}" + _exist_record=$(echo "${response}" | tr -d "\\r\\n" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist # Generate body data - _post_body="{ - \"name\": \"${_domain}.\", - \"description\": \"ACME Challenge\", - \"type\": \"TXT\", - \"ttl\": 1, - \"records\": [ - ${_exist_record}, - \"\\\"${_txtvalue}\\\"\" - ] - }" if [ -z "${_exist_record}" ]; then _post_body="{ \"name\": \"${_domain}.\", @@ -169,6 +163,17 @@ _add_record() { \"\\\"${_txtvalue}\\\"\" ] }" + else + _post_body="{ + \"name\": \"${_domain}.\", + \"description\": \"ACME Challenge\", + \"type\": \"TXT\", + \"ttl\": 1, + \"records\": [ + ${_exist_record}, + \"\\\"${_txtvalue}\\\"\" + ] + }" fi _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" @@ -179,20 +184,17 @@ _add_record() { _debug "Removing Record" _rm_record "${_token}" "${zoneid}" "${_record_id}" _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" - _debug "${_record_id}" done # Add brand new records with all old and new records export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" - _debug "${_post_body}" - sleep 2 + _debug2 "${_post_body}" _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" if [ "$_code" != "202" ]; then _err "dns_huaweicloud: http code ${_code}" - sleep 60 return 1 fi return 0 From fd511966a75e416a1c8cd00783305228e960bc37 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 24 Nov 2020 12:58:16 +0800 Subject: [PATCH 1087/2234] fix: revert adding tr to replace sed --- dnsapi/dns_huaweicloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index a7ca619f..74fec2a9 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -148,7 +148,7 @@ _add_record() { response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") _debug2 "${response}" - _exist_record=$(echo "${response}" | tr -d "\\r\\n" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') + _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist From 996f53373e490fc37e9373b1ff575f42cae5b7f0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 13 Nov 2020 19:58:21 +0800 Subject: [PATCH 1088/2234] fix https://github.com/acmesh-official/acme.sh/issues/3250 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index e549f7c8..b234fb26 100755 --- a/acme.sh +++ b/acme.sh @@ -6649,8 +6649,8 @@ _checkSudo() { return 0 fi if [ -n "$SUDO_COMMAND" ]; then - #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s` - _endswith "$SUDO_COMMAND" /bin/su || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1 + #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s`, or `sudo su acmeuser1` + _endswith "$SUDO_COMMAND" /bin/su || _contains "$SUDO_COMMAND" "/bin/su " || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1 return $? fi #otherwise From d7cafe25ff642ca6e32da27992e2e0e9a4017e14 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Thu, 26 Nov 2020 13:59:18 +0100 Subject: [PATCH 1089/2234] World4You using _egrep_o --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index ec5a0e47..b58ea89a 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -15,7 +15,7 @@ dns_world4you_add() { _debug fulldomain "$fqdn" _debug txtvalue "$value" - tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + tld=$(echo "$fqdn" | _egrep_o '[^.]*\.[^.]*$') record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") _login @@ -69,7 +69,7 @@ dns_world4you_rm() { _debug fulldomain "$fqdn" _debug txtvalue "$value" - tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + tld=$(echo "$fqdn" | _egrep_o '[^.]*\.[^.]*$') record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") _login From d639c7be392206e8cbcfd6215166450dc5b554c8 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 22 Nov 2020 11:22:54 +0100 Subject: [PATCH 1090/2234] Added World4You DNS API --- dnsapi/dns_world4you.sh | 159 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 dnsapi/dns_world4you.sh diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh new file mode 100644 index 00000000..ec5a0e47 --- /dev/null +++ b/dnsapi/dns_world4you.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env sh + +# World4You - www.world4you.com +# Lorenz Stechauner, 2020 - https://www.github.com/NerLOR + +WORLD4YOU_API="https://my.world4you.com/en" + +################ Public functions ################ + +# Usage: dns_world4you_add +dns_world4you_add() { + fqdn="$1" + value="$2" + _info "Using world4you" + _debug fulldomain "$fqdn" + _debug txtvalue "$value" + + tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") + + _login + if [ "$?" != 0 ]; then + return 1 + fi + + export _H1="Cookie: W4YSESSID=$sessid" + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\)<.*$/\1/') + if [ -z "$paketnr" ]; then + _err "Unable to parse paketnr" + return 3 + fi + _debug paketnr "$paketnr" + + export _H1="Cookie: W4YSESSID=$sessid" + form=$(_get "$WORLD4YOU_API/$paketnr/dns") + formiddp=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/') + formidttl=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/') + form_token=$(echo "$form" | grep 'AddDnsRecordForm\[_token\]' | sed 's/^.*name="AddDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/') + if [ -z "$formiddp" ]; then + _err "Unable to parse form" + return 3 + fi + + _ORIG_ACME_CURL="$_ACME_CURL" + _ACME_CURL=$(echo "$_ACME_CURL" | sed 's/ -L / /') + + body="AddDnsRecordForm[name]=$record&AddDnsRecordForm[dnsType][type]=TXT&\ +AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\ +AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_token" + _info "Adding record..." + ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded') + + _ACME_CURL="$_ORIG_ACME_CURL" + + success=$(grep '302\|200' <"$HTTP_HEADER") + if [ "$success" ]; then + return 0 + else + _err "$(head -n 1 <"$HTTP_HEADER")" + return 2 + fi +} + +# Usage: dns_world4you_rm +dns_world4you_rm() { + fqdn="$1" + value="$2" + _info "Using world4you" + _debug fulldomain "$fqdn" + _debug txtvalue "$value" + + tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") + + _login + if [ "$?" != 0 ]; then + return 1 + fi + + export _H1="Cookie: W4YSESSID=$sessid" + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + if [ -z "$paketnr" ]; then + _err "Unable to parse paketnr" + return 3 + fi + _debug paketnr "$paketnr" + + form=$(_get "$WORLD4YOU_API/$paketnr/dns") + formiddp=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/') + formidttl=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/') + form_token=$(echo "$form" | grep 'DeleteDnsRecordForm\[_token\]' | sed 's/^.*name="DeleteDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/') + if [ -z "$formiddp" ]; then + _err "Unable to parse form" + return 3 + fi + + recordid=$(printf "TXT:%s.:\"%s\"" "$fqdn" "$value" | _base64) + _debug recordid "$recordid" + + _ORIG_ACME_CURL="$_ACME_CURL" + _ACME_CURL=$(echo "$_ACME_CURL" | sed 's/ -L / /') + + body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[aktivPaket]=$paketnr&\ +DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[uniqueFormIdTTL]=$formidttl&\ +DeleteDnsRecordForm[_token]=$form_token" + _info "Removing record..." + ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/deleteRecord" '' POST 'application/x-www-form-urlencoded') + + _ACME_CURL="$_ORIG_ACME_CURL" + + success=$(grep '302\|200' <"$HTTP_HEADER") + if [ "$success" ]; then + return 0 + else + _err "$(head -n 1 <"$HTTP_HEADER")" + return 2 + fi +} + +################ Private functions ################ + +# Usage: _login +_login() { + WORLD4YOU_USERNAME="${WORLD4YOU_USERNAME:-$(_readaccountconf_mutable WORLD4YOU_USERNAME)}" + WORLD4YOU_PASSWORD="${WORLD4YOU_PASSWORD:-$(_readaccountconf_mutable WORLD4YOU_PASSWORD)}" + + if [ -z "$WORLD4YOU_USERNAME" ] || [ -z "$WORLD4YOU_PASSWORD" ]; then + WORLD4YOU_USERNAME="" + WORLD4YOU_PASSWORD="" + _err "You don't specified world4you username and password yet." + _err "Usage: export WORLD4YOU_USERNAME=" + _err "Usage: export WORLD4YOU_PASSWORD=" + return 2 + fi + + _saveaccountconf_mutable WORLD4YOU_USERNAME "$WORLD4YOU_USERNAME" + _saveaccountconf_mutable WORLD4YOU_PASSWORD "$WORLD4YOU_PASSWORD" + + _info "Logging in..." + + username="$WORLD4YOU_USERNAME" + password="$WORLD4YOU_PASSWORD" + csrf_token=$(_get "$WORLD4YOU_API/login" | grep '_csrf_token' | sed 's/^.*]*value=\"\([^"]*\)\".*$/\1/') + sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/') + + export _H1="Cookie: W4YSESSID=$sessid" + export _H2="X-Requested-With: XMLHttpRequest" + body="_username=$username&_password=$password&_csrf_token=$csrf_token" + ret=$(_post "$body" "$WORLD4YOU_API/login" '' POST 'application/x-www-form-urlencoded') + unset _H2 + _debug ret "$ret" + if _contains "$ret" "\"success\":true"; then + _info "Successfully logged in" + sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/') + else + _err "Unable to log in: $(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')" + return 1 + fi +} From 95235d69c20484d340d44d21950a76f6492e3c7e Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Thu, 26 Nov 2020 13:59:18 +0100 Subject: [PATCH 1091/2234] World4You using _egrep_o --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index ec5a0e47..b58ea89a 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -15,7 +15,7 @@ dns_world4you_add() { _debug fulldomain "$fqdn" _debug txtvalue "$value" - tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + tld=$(echo "$fqdn" | _egrep_o '[^.]*\.[^.]*$') record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") _login @@ -69,7 +69,7 @@ dns_world4you_rm() { _debug fulldomain "$fqdn" _debug txtvalue "$value" - tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + tld=$(echo "$fqdn" | _egrep_o '[^.]*\.[^.]*$') record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") _login From bb3cc1130b22335f5664878635db43293b367194 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 19:34:16 +0100 Subject: [PATCH 1092/2234] World4You using ggrep in solaris --- dnsapi/dns_world4you.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index b58ea89a..db52cda1 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -24,7 +24,7 @@ dns_world4you_add() { fi export _H1="Cookie: W4YSESSID=$sessid" - paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\)<.*$/\1/') + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | _ggrep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\)<.*$/\1/') if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -78,7 +78,7 @@ dns_world4you_rm() { fi export _H1="Cookie: W4YSESSID=$sessid" - paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | _ggrep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -157,3 +157,13 @@ _login() { return 1 fi } + +_ggrep() { + if _exists "ggrep"; then + ggrep $@ + return $? + else + grep $@ + return $? + fi +} From 268eaddad8845ed35af46a4f7ac36d2859a8d074 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 19:35:53 +0100 Subject: [PATCH 1093/2234] World4You shellcheck --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index db52cda1..fbc5fe40 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -160,10 +160,10 @@ _login() { _ggrep() { if _exists "ggrep"; then - ggrep $@ + ggrep "$@" return $? else - grep $@ + grep "$@" return $? fi } From 339ff8ca773e196613db5ca29f651893c3227682 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:12:11 +0100 Subject: [PATCH 1094/2234] World4You domain root fix --- dnsapi/dns_world4you.sh | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index fbc5fe40..502e8631 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -4,6 +4,7 @@ # Lorenz Stechauner, 2020 - https://www.github.com/NerLOR WORLD4YOU_API="https://my.world4you.com/en" +PAKETNR='' ################ Public functions ################ @@ -24,7 +25,9 @@ dns_world4you_add() { fi export _H1="Cookie: W4YSESSID=$sessid" - paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | _ggrep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\)<.*$/\1/') + form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") + _get_paketnr "$tld" "$form" + paketnr="$PAKETNR" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -78,7 +81,9 @@ dns_world4you_rm() { fi export _H1="Cookie: W4YSESSID=$sessid" - paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | _ggrep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") + _get_paketnr "$tld" "$form" + paketnr="$PAKETNR" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -158,6 +163,25 @@ _login() { fi } +# Usage _get_paketnr +_get_paketnr() { + tld="$1" + form="$2" + + domains=($(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/')) + paketnrs=($(echo "$form" | _ggrep -B 3 -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed -n '1~5p' | sed 's/^.*>\([0-9][0-9]*\).*$/\1/')) + + total="${#domains[*]}" + for (( i=0; i<=$(( $total - 1 )); i++ )); do + domain="${domains[$i]}" + if [ $(echo "$domain" | grep "$tld\$") ]; then + PAKETNR="${paketnrs[$i]}" + return 0 + fi + done + return 1 +} + _ggrep() { if _exists "ggrep"; then ggrep "$@" From 2e15371d616a3b83c4cdc3b51176edf2d1d2966d Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:22:50 +0100 Subject: [PATCH 1095/2234] World4You posix shell --- dnsapi/dns_world4you.sh | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 502e8631..8e12dd5f 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -168,18 +168,19 @@ _get_paketnr() { tld="$1" form="$2" - domains=($(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/')) - paketnrs=($(echo "$form" | _ggrep -B 3 -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed -n '1~5p' | sed 's/^.*>\([0-9][0-9]*\).*$/\1/')) - - total="${#domains[*]}" - for (( i=0; i<=$(( $total - 1 )); i++ )); do - domain="${domains[$i]}" + domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') + domain='' + for domain in $domains; do if [ $(echo "$domain" | grep "$tld\$") ]; then - PAKETNR="${paketnrs[$i]}" - return 0 + break fi done - return 1 + if [ -z "$domain" ]; then + return 1 + fi + + PAKETNR=$(echo "$form" | _ggrep -B 3 "^\\s*$domain\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + return 0 } _ggrep() { From 42583cf3bb6d4ea091491533d33d1717f746065f Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:25:29 +0100 Subject: [PATCH 1096/2234] World4You Shellcheck --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 8e12dd5f..e1585801 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -171,7 +171,7 @@ _get_paketnr() { domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if [ $(echo "$domain" | grep "$tld\$") ]; then + if [ "$(echo "$domain" | grep -q "$tld\$")" ]; then break fi done From 198b8400597881a82bf8c3cc1f14edf32068862a Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:27:10 +0100 Subject: [PATCH 1097/2234] World4You grep -q --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index e1585801..2be5a6b9 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -171,7 +171,7 @@ _get_paketnr() { domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if [ "$(echo "$domain" | grep -q "$tld\$")" ]; then + if $(echo "$domain" | grep -q "$tld\$"; then break fi done From dcb4cb3a1e439661b4f0fd2d1b63fa61c78b0f1a Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:28:25 +0100 Subject: [PATCH 1098/2234] World4You Bugfix --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 2be5a6b9..e1ced163 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -171,7 +171,7 @@ _get_paketnr() { domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if $(echo "$domain" | grep -q "$tld\$"; then + if $(echo "$domain" | grep -q "$tld\$"); then break fi done From f3987b453c4115fb19a565dfe4850fd2dff0d595 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:29:31 +0100 Subject: [PATCH 1099/2234] World4You Bugfix 2 --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index e1ced163..4c0be782 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -171,7 +171,7 @@ _get_paketnr() { domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if $(echo "$domain" | grep -q "$tld\$"); then + if echo "$domain" | grep -q "$tld\$"; then break fi done From 9474933070bf18c5cfc0a298f3da54790be141af Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sat, 28 Nov 2020 08:50:47 +0100 Subject: [PATCH 1100/2234] World4You dns root parsing --- dnsapi/dns_world4you.sh | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 4c0be782..455418a5 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -5,6 +5,8 @@ WORLD4YOU_API="https://my.world4you.com/en" PAKETNR='' +TLD='' +RECORD='' ################ Public functions ################ @@ -16,9 +18,6 @@ dns_world4you_add() { _debug fulldomain "$fqdn" _debug txtvalue "$value" - tld=$(echo "$fqdn" | _egrep_o '[^.]*\.[^.]*$') - record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") - _login if [ "$?" != 0 ]; then return 1 @@ -26,8 +25,10 @@ dns_world4you_add() { export _H1="Cookie: W4YSESSID=$sessid" form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") - _get_paketnr "$tld" "$form" + _get_paketnr "$fqdn" "$form" paketnr="$PAKETNR" + tld="$TLD" + record="$RECORD" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -82,8 +83,10 @@ dns_world4you_rm() { export _H1="Cookie: W4YSESSID=$sessid" form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") - _get_paketnr "$tld" "$form" + _get_paketnr "$fqdn" "$form" paketnr="$PAKETNR" + tld="$TLD" + record="$RECORD" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -163,22 +166,25 @@ _login() { fi } -# Usage _get_paketnr +# Usage _get_paketnr _get_paketnr() { - tld="$1" + fqdn="$1" form="$2" domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if echo "$domain" | grep -q "$tld\$"; then + if echo "$fqdn" | grep -q "$domain\$"; then break fi + domain='' done if [ -z "$domain" ]; then return 1 fi + TLD="$domain" + RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))") PAKETNR=$(echo "$form" | _ggrep -B 3 "^\\s*$domain\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') return 0 } From ed01fd4edfd76fe96a1d38af3731f6efb46c904c Mon Sep 17 00:00:00 2001 From: Moritz H Date: Sat, 28 Nov 2020 15:22:14 +0100 Subject: [PATCH 1101/2234] uconv as fallback for iconv --- deploy/fritzbox.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/deploy/fritzbox.sh b/deploy/fritzbox.sh index 89b19806..2ca7ab7d 100644 --- a/deploy/fritzbox.sh +++ b/deploy/fritzbox.sh @@ -28,9 +28,11 @@ fritzbox_deploy() { _debug _cfullchain "$_cfullchain" if ! _exists iconv; then - if ! _exists perl; then - _err "iconv or perl not found" - return 1 + if ! _exists uconv; then + if ! _exists perl; then + _err "iconv or uconv or perl not found" + return 1 + fi fi fi @@ -65,6 +67,8 @@ fritzbox_deploy() { _fritzbox_challenge="$(_get "${_fritzbox_url}/login_sid.lua" | sed -e 's/^.*//' -e 's/<\/Challenge>.*$//')" if _exists iconv; then _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | _digest md5 hex)" + elif _exists uconv; then + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | uconv -f ASCII -t UTF16LE | _digest md5 hex)" else _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | _digest md5 hex)" fi From 0ed2659698ac08a175eb50ad1c5c27d69346bd2c Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sat, 28 Nov 2020 17:27:50 +0100 Subject: [PATCH 1102/2234] World4You using ggrep more often --- dnsapi/dns_world4you.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 455418a5..10c1628b 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -56,8 +56,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _ACME_CURL="$_ORIG_ACME_CURL" - success=$(grep '302\|200' <"$HTTP_HEADER") - if [ "$success" ]; then + if _ggrep -q '302\|200' <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" @@ -116,8 +115,7 @@ DeleteDnsRecordForm[_token]=$form_token" _ACME_CURL="$_ORIG_ACME_CURL" - success=$(grep '302\|200' <"$HTTP_HEADER") - if [ "$success" ]; then + if _ggrep -q '302\|200' <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" From 1987c32761cc8ae20263400ccbe8822c8f9911e3 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 09:34:52 +0100 Subject: [PATCH 1103/2234] World4You using _egrep_o instead of grep -E --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 10c1628b..bcb01619 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -169,7 +169,7 @@ _get_paketnr() { fqdn="$1" form="$2" - domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') + domains=$(echo "$form" | _egrep_o '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do if echo "$fqdn" | grep -q "$domain\$"; then From 9fee0805c41539d8cec2a56a694882b36141432d Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 09:40:35 +0100 Subject: [PATCH 1104/2234] World4You using /dev/null instead of grep -q --- dnsapi/dns_world4you.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index bcb01619..fff8089d 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -56,7 +56,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _ACME_CURL="$_ORIG_ACME_CURL" - if _ggrep -q '302\|200' <"$HTTP_HEADER"; then + if _ggrep '302\|200' >/dev/null <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" @@ -115,7 +115,7 @@ DeleteDnsRecordForm[_token]=$form_token" _ACME_CURL="$_ORIG_ACME_CURL" - if _ggrep -q '302\|200' <"$HTTP_HEADER"; then + if _ggrep '302\|200' >/dev/null <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" @@ -172,7 +172,7 @@ _get_paketnr() { domains=$(echo "$form" | _egrep_o '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if echo "$fqdn" | grep -q "$domain\$"; then + if echo "$fqdn" | grep "$domain\$" >/dev/null; then break fi domain='' From 2dd8527566fb37431abb84c52d526a7069345bea Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 10:33:46 +0100 Subject: [PATCH 1105/2234] World4You success on 302 instead of 302 or 200 --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index fff8089d..76acacf8 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -56,7 +56,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _ACME_CURL="$_ORIG_ACME_CURL" - if _ggrep '302\|200' >/dev/null <"$HTTP_HEADER"; then + if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" @@ -115,7 +115,7 @@ DeleteDnsRecordForm[_token]=$form_token" _ACME_CURL="$_ORIG_ACME_CURL" - if _ggrep '302\|200' >/dev/null <"$HTTP_HEADER"; then + if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" From 6c039d2ad080c58d36ea6775bbf2fbffa269a7cb Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 10:43:25 +0100 Subject: [PATCH 1106/2234] World4You removed _ggrep --- dnsapi/dns_world4you.sh | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 76acacf8..573c5ee6 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -183,16 +183,6 @@ _get_paketnr() { TLD="$domain" RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))") - PAKETNR=$(echo "$form" | _ggrep -B 3 "^\\s*$domain\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + PAKETNR=$(echo "$form" | _egrep_o "data-textfilter=\" $domain .* [0-9]*" | head -n 1 | _egrep_o "[0-9]*") return 0 } - -_ggrep() { - if _exists "ggrep"; then - ggrep "$@" - return $? - else - grep "$@" - return $? - fi -} From effa7fd57d2a36233f8c3f3d29bac0789a9a12b4 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 29 Nov 2020 18:39:11 +0800 Subject: [PATCH 1107/2234] add ACME_HTTP_NO_REDIRECTS and _resethttp to make http requests not follow redirects --- acme.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index b234fb26..dcbe3c9d 100755 --- a/acme.sh +++ b/acme.sh @@ -1722,6 +1722,14 @@ _mktemp() { _err "Can not create temp file." } +#clear all the https envs to cause _inithttp() to run next time. +_resethttp() { + __HTTP_INITIALIZED="" + _ACME_CURL="" + _ACME_WGET="" + ACME_HTTP_NO_REDIRECTS="" +} + _inithttp() { if [ -z "$HTTP_HEADER" ] || ! touch "$HTTP_HEADER"; then @@ -1737,7 +1745,10 @@ _inithttp() { fi if [ -z "$_ACME_CURL" ] && _exists "curl"; then - _ACME_CURL="curl -L --silent --dump-header $HTTP_HEADER " + _ACME_CURL="curl --silent --dump-header $HTTP_HEADER " + if [ -z "$ACME_HTTP_NO_REDIRECTS" ]; then + _ACME_CURL="$_ACME_CURL -L " + fi if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _CURL_DUMP="$(_mktemp)" _ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP " @@ -1756,6 +1767,9 @@ _inithttp() { if [ -z "$_ACME_WGET" ] && _exists "wget"; then _ACME_WGET="wget -q" + if [ "$ACME_HTTP_NO_REDIRECTS" ]; then + _ACME_WGET="$_ACME_WGET --max-redirect 0 " + fi if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _ACME_WGET="$_ACME_WGET -d " fi From 8ee5726e0cc1b3cf7e106363b958ed22472c8237 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 22 Nov 2020 11:22:54 +0100 Subject: [PATCH 1108/2234] Added World4You DNS API --- dnsapi/dns_world4you.sh | 159 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 dnsapi/dns_world4you.sh diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh new file mode 100644 index 00000000..ec5a0e47 --- /dev/null +++ b/dnsapi/dns_world4you.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env sh + +# World4You - www.world4you.com +# Lorenz Stechauner, 2020 - https://www.github.com/NerLOR + +WORLD4YOU_API="https://my.world4you.com/en" + +################ Public functions ################ + +# Usage: dns_world4you_add +dns_world4you_add() { + fqdn="$1" + value="$2" + _info "Using world4you" + _debug fulldomain "$fqdn" + _debug txtvalue "$value" + + tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") + + _login + if [ "$?" != 0 ]; then + return 1 + fi + + export _H1="Cookie: W4YSESSID=$sessid" + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\)<.*$/\1/') + if [ -z "$paketnr" ]; then + _err "Unable to parse paketnr" + return 3 + fi + _debug paketnr "$paketnr" + + export _H1="Cookie: W4YSESSID=$sessid" + form=$(_get "$WORLD4YOU_API/$paketnr/dns") + formiddp=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/') + formidttl=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/') + form_token=$(echo "$form" | grep 'AddDnsRecordForm\[_token\]' | sed 's/^.*name="AddDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/') + if [ -z "$formiddp" ]; then + _err "Unable to parse form" + return 3 + fi + + _ORIG_ACME_CURL="$_ACME_CURL" + _ACME_CURL=$(echo "$_ACME_CURL" | sed 's/ -L / /') + + body="AddDnsRecordForm[name]=$record&AddDnsRecordForm[dnsType][type]=TXT&\ +AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\ +AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_token" + _info "Adding record..." + ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded') + + _ACME_CURL="$_ORIG_ACME_CURL" + + success=$(grep '302\|200' <"$HTTP_HEADER") + if [ "$success" ]; then + return 0 + else + _err "$(head -n 1 <"$HTTP_HEADER")" + return 2 + fi +} + +# Usage: dns_world4you_rm +dns_world4you_rm() { + fqdn="$1" + value="$2" + _info "Using world4you" + _debug fulldomain "$fqdn" + _debug txtvalue "$value" + + tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") + + _login + if [ "$?" != 0 ]; then + return 1 + fi + + export _H1="Cookie: W4YSESSID=$sessid" + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + if [ -z "$paketnr" ]; then + _err "Unable to parse paketnr" + return 3 + fi + _debug paketnr "$paketnr" + + form=$(_get "$WORLD4YOU_API/$paketnr/dns") + formiddp=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/') + formidttl=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/') + form_token=$(echo "$form" | grep 'DeleteDnsRecordForm\[_token\]' | sed 's/^.*name="DeleteDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/') + if [ -z "$formiddp" ]; then + _err "Unable to parse form" + return 3 + fi + + recordid=$(printf "TXT:%s.:\"%s\"" "$fqdn" "$value" | _base64) + _debug recordid "$recordid" + + _ORIG_ACME_CURL="$_ACME_CURL" + _ACME_CURL=$(echo "$_ACME_CURL" | sed 's/ -L / /') + + body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[aktivPaket]=$paketnr&\ +DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[uniqueFormIdTTL]=$formidttl&\ +DeleteDnsRecordForm[_token]=$form_token" + _info "Removing record..." + ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/deleteRecord" '' POST 'application/x-www-form-urlencoded') + + _ACME_CURL="$_ORIG_ACME_CURL" + + success=$(grep '302\|200' <"$HTTP_HEADER") + if [ "$success" ]; then + return 0 + else + _err "$(head -n 1 <"$HTTP_HEADER")" + return 2 + fi +} + +################ Private functions ################ + +# Usage: _login +_login() { + WORLD4YOU_USERNAME="${WORLD4YOU_USERNAME:-$(_readaccountconf_mutable WORLD4YOU_USERNAME)}" + WORLD4YOU_PASSWORD="${WORLD4YOU_PASSWORD:-$(_readaccountconf_mutable WORLD4YOU_PASSWORD)}" + + if [ -z "$WORLD4YOU_USERNAME" ] || [ -z "$WORLD4YOU_PASSWORD" ]; then + WORLD4YOU_USERNAME="" + WORLD4YOU_PASSWORD="" + _err "You don't specified world4you username and password yet." + _err "Usage: export WORLD4YOU_USERNAME=" + _err "Usage: export WORLD4YOU_PASSWORD=" + return 2 + fi + + _saveaccountconf_mutable WORLD4YOU_USERNAME "$WORLD4YOU_USERNAME" + _saveaccountconf_mutable WORLD4YOU_PASSWORD "$WORLD4YOU_PASSWORD" + + _info "Logging in..." + + username="$WORLD4YOU_USERNAME" + password="$WORLD4YOU_PASSWORD" + csrf_token=$(_get "$WORLD4YOU_API/login" | grep '_csrf_token' | sed 's/^.*]*value=\"\([^"]*\)\".*$/\1/') + sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/') + + export _H1="Cookie: W4YSESSID=$sessid" + export _H2="X-Requested-With: XMLHttpRequest" + body="_username=$username&_password=$password&_csrf_token=$csrf_token" + ret=$(_post "$body" "$WORLD4YOU_API/login" '' POST 'application/x-www-form-urlencoded') + unset _H2 + _debug ret "$ret" + if _contains "$ret" "\"success\":true"; then + _info "Successfully logged in" + sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/') + else + _err "Unable to log in: $(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')" + return 1 + fi +} From f3b5d5ab7b7dcebc595ce281f13827f7d051dfbf Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Thu, 26 Nov 2020 13:59:18 +0100 Subject: [PATCH 1109/2234] World4You using _egrep_o --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index ec5a0e47..b58ea89a 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -15,7 +15,7 @@ dns_world4you_add() { _debug fulldomain "$fqdn" _debug txtvalue "$value" - tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + tld=$(echo "$fqdn" | _egrep_o '[^.]*\.[^.]*$') record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") _login @@ -69,7 +69,7 @@ dns_world4you_rm() { _debug fulldomain "$fqdn" _debug txtvalue "$value" - tld=$(echo "$fqdn" | grep -o '[^.]*\.[^.]*$') + tld=$(echo "$fqdn" | _egrep_o '[^.]*\.[^.]*$') record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") _login From 9449501537a84385f9431f411ecb8e0e41c8670a Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 19:34:16 +0100 Subject: [PATCH 1110/2234] World4You using ggrep in solaris --- dnsapi/dns_world4you.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index b58ea89a..db52cda1 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -24,7 +24,7 @@ dns_world4you_add() { fi export _H1="Cookie: W4YSESSID=$sessid" - paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\)<.*$/\1/') + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | _ggrep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\)<.*$/\1/') if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -78,7 +78,7 @@ dns_world4you_rm() { fi export _H1="Cookie: W4YSESSID=$sessid" - paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | grep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | _ggrep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -157,3 +157,13 @@ _login() { return 1 fi } + +_ggrep() { + if _exists "ggrep"; then + ggrep $@ + return $? + else + grep $@ + return $? + fi +} From f9dfd3b3485c03b3fae9e975dec50112fde26e57 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 19:35:53 +0100 Subject: [PATCH 1111/2234] World4You shellcheck --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index db52cda1..fbc5fe40 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -160,10 +160,10 @@ _login() { _ggrep() { if _exists "ggrep"; then - ggrep $@ + ggrep "$@" return $? else - grep $@ + grep "$@" return $? fi } From abe05456f785c222fd06a4062a2533b72f73a058 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:12:11 +0100 Subject: [PATCH 1112/2234] World4You domain root fix --- dnsapi/dns_world4you.sh | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index fbc5fe40..502e8631 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -4,6 +4,7 @@ # Lorenz Stechauner, 2020 - https://www.github.com/NerLOR WORLD4YOU_API="https://my.world4you.com/en" +PAKETNR='' ################ Public functions ################ @@ -24,7 +25,9 @@ dns_world4you_add() { fi export _H1="Cookie: W4YSESSID=$sessid" - paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | _ggrep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\)<.*$/\1/') + form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") + _get_paketnr "$tld" "$form" + paketnr="$PAKETNR" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -78,7 +81,9 @@ dns_world4you_rm() { fi export _H1="Cookie: W4YSESSID=$sessid" - paketnr=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht" | _ggrep -B 3 "^\\s*$tld\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") + _get_paketnr "$tld" "$form" + paketnr="$PAKETNR" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -158,6 +163,25 @@ _login() { fi } +# Usage _get_paketnr +_get_paketnr() { + tld="$1" + form="$2" + + domains=($(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/')) + paketnrs=($(echo "$form" | _ggrep -B 3 -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed -n '1~5p' | sed 's/^.*>\([0-9][0-9]*\).*$/\1/')) + + total="${#domains[*]}" + for (( i=0; i<=$(( $total - 1 )); i++ )); do + domain="${domains[$i]}" + if [ $(echo "$domain" | grep "$tld\$") ]; then + PAKETNR="${paketnrs[$i]}" + return 0 + fi + done + return 1 +} + _ggrep() { if _exists "ggrep"; then ggrep "$@" From ef9147512b20499ac57442f58d3d1bcfdbd9c9bf Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:22:50 +0100 Subject: [PATCH 1113/2234] World4You posix shell --- dnsapi/dns_world4you.sh | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 502e8631..8e12dd5f 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -168,18 +168,19 @@ _get_paketnr() { tld="$1" form="$2" - domains=($(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/')) - paketnrs=($(echo "$form" | _ggrep -B 3 -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed -n '1~5p' | sed 's/^.*>\([0-9][0-9]*\).*$/\1/')) - - total="${#domains[*]}" - for (( i=0; i<=$(( $total - 1 )); i++ )); do - domain="${domains[$i]}" + domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') + domain='' + for domain in $domains; do if [ $(echo "$domain" | grep "$tld\$") ]; then - PAKETNR="${paketnrs[$i]}" - return 0 + break fi done - return 1 + if [ -z "$domain" ]; then + return 1 + fi + + PAKETNR=$(echo "$form" | _ggrep -B 3 "^\\s*$domain\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + return 0 } _ggrep() { From 895da5cbf07eb333610a9b4acaf39e536ae7a9d9 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:25:29 +0100 Subject: [PATCH 1114/2234] World4You Shellcheck --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 8e12dd5f..e1585801 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -171,7 +171,7 @@ _get_paketnr() { domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if [ $(echo "$domain" | grep "$tld\$") ]; then + if [ "$(echo "$domain" | grep -q "$tld\$")" ]; then break fi done From 46611857195f9c53286738f44c11ed42a65805cc Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:27:10 +0100 Subject: [PATCH 1115/2234] World4You grep -q --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index e1585801..2be5a6b9 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -171,7 +171,7 @@ _get_paketnr() { domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if [ "$(echo "$domain" | grep -q "$tld\$")" ]; then + if $(echo "$domain" | grep -q "$tld\$"; then break fi done From 2edc4a79b9ff3c8668220b4d2a80624320c3b0fa Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:28:25 +0100 Subject: [PATCH 1116/2234] World4You Bugfix --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 2be5a6b9..e1ced163 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -171,7 +171,7 @@ _get_paketnr() { domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if $(echo "$domain" | grep -q "$tld\$"; then + if $(echo "$domain" | grep -q "$tld\$"); then break fi done From 13f6ec04d55b15f0620ee30d4f370c017425715a Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 27 Nov 2020 22:29:31 +0100 Subject: [PATCH 1117/2234] World4You Bugfix 2 --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index e1ced163..4c0be782 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -171,7 +171,7 @@ _get_paketnr() { domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if $(echo "$domain" | grep -q "$tld\$"); then + if echo "$domain" | grep -q "$tld\$"; then break fi done From 5cfe5e312b15846ed1711b6da35ca5c6f47c11b8 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sat, 28 Nov 2020 08:50:47 +0100 Subject: [PATCH 1118/2234] World4You dns root parsing --- dnsapi/dns_world4you.sh | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 4c0be782..455418a5 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -5,6 +5,8 @@ WORLD4YOU_API="https://my.world4you.com/en" PAKETNR='' +TLD='' +RECORD='' ################ Public functions ################ @@ -16,9 +18,6 @@ dns_world4you_add() { _debug fulldomain "$fqdn" _debug txtvalue "$value" - tld=$(echo "$fqdn" | _egrep_o '[^.]*\.[^.]*$') - record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") - _login if [ "$?" != 0 ]; then return 1 @@ -26,8 +25,10 @@ dns_world4you_add() { export _H1="Cookie: W4YSESSID=$sessid" form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") - _get_paketnr "$tld" "$form" + _get_paketnr "$fqdn" "$form" paketnr="$PAKETNR" + tld="$TLD" + record="$RECORD" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -82,8 +83,10 @@ dns_world4you_rm() { export _H1="Cookie: W4YSESSID=$sessid" form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") - _get_paketnr "$tld" "$form" + _get_paketnr "$fqdn" "$form" paketnr="$PAKETNR" + tld="$TLD" + record="$RECORD" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -163,22 +166,25 @@ _login() { fi } -# Usage _get_paketnr +# Usage _get_paketnr _get_paketnr() { - tld="$1" + fqdn="$1" form="$2" domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if echo "$domain" | grep -q "$tld\$"; then + if echo "$fqdn" | grep -q "$domain\$"; then break fi + domain='' done if [ -z "$domain" ]; then return 1 fi + TLD="$domain" + RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))") PAKETNR=$(echo "$form" | _ggrep -B 3 "^\\s*$domain\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') return 0 } From a0edb8f2ad8bbc193e52c10e052fbdf4541dcf80 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sat, 28 Nov 2020 17:27:50 +0100 Subject: [PATCH 1119/2234] World4You using ggrep more often --- dnsapi/dns_world4you.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 455418a5..10c1628b 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -56,8 +56,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _ACME_CURL="$_ORIG_ACME_CURL" - success=$(grep '302\|200' <"$HTTP_HEADER") - if [ "$success" ]; then + if _ggrep -q '302\|200' <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" @@ -116,8 +115,7 @@ DeleteDnsRecordForm[_token]=$form_token" _ACME_CURL="$_ORIG_ACME_CURL" - success=$(grep '302\|200' <"$HTTP_HEADER") - if [ "$success" ]; then + if _ggrep -q '302\|200' <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" From 35cab4ee7398edd9547acabeabc6937fec153ccf Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 09:34:52 +0100 Subject: [PATCH 1120/2234] World4You using _egrep_o instead of grep -E --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 10c1628b..bcb01619 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -169,7 +169,7 @@ _get_paketnr() { fqdn="$1" form="$2" - domains=$(echo "$form" | _ggrep -E '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') + domains=$(echo "$form" | _egrep_o '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do if echo "$fqdn" | grep -q "$domain\$"; then From 3d79d78134dd6f19be2e7f6f11be06c08450de79 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 09:40:35 +0100 Subject: [PATCH 1121/2234] World4You using /dev/null instead of grep -q --- dnsapi/dns_world4you.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index bcb01619..fff8089d 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -56,7 +56,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _ACME_CURL="$_ORIG_ACME_CURL" - if _ggrep -q '302\|200' <"$HTTP_HEADER"; then + if _ggrep '302\|200' >/dev/null <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" @@ -115,7 +115,7 @@ DeleteDnsRecordForm[_token]=$form_token" _ACME_CURL="$_ORIG_ACME_CURL" - if _ggrep -q '302\|200' <"$HTTP_HEADER"; then + if _ggrep '302\|200' >/dev/null <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" @@ -172,7 +172,7 @@ _get_paketnr() { domains=$(echo "$form" | _egrep_o '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if echo "$fqdn" | grep -q "$domain\$"; then + if echo "$fqdn" | grep "$domain\$" >/dev/null; then break fi domain='' From faf6c1671739af4ac9414423231da34ed6c6465c Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 10:33:46 +0100 Subject: [PATCH 1122/2234] World4You success on 302 instead of 302 or 200 --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index fff8089d..76acacf8 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -56,7 +56,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _ACME_CURL="$_ORIG_ACME_CURL" - if _ggrep '302\|200' >/dev/null <"$HTTP_HEADER"; then + if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" @@ -115,7 +115,7 @@ DeleteDnsRecordForm[_token]=$form_token" _ACME_CURL="$_ORIG_ACME_CURL" - if _ggrep '302\|200' >/dev/null <"$HTTP_HEADER"; then + if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 else _err "$(head -n 1 <"$HTTP_HEADER")" From c3d7f2f1708d13eb4d434fc27830a99f268e724a Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 10:43:25 +0100 Subject: [PATCH 1123/2234] World4You removed _ggrep --- dnsapi/dns_world4you.sh | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 76acacf8..573c5ee6 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -183,16 +183,6 @@ _get_paketnr() { TLD="$domain" RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))") - PAKETNR=$(echo "$form" | _ggrep -B 3 "^\\s*$domain\$" | head -n 1 | sed 's/^.*>\([0-9][0-9]*\).*$/\1/') + PAKETNR=$(echo "$form" | _egrep_o "data-textfilter=\" $domain .* [0-9]*" | head -n 1 | _egrep_o "[0-9]*") return 0 } - -_ggrep() { - if _exists "ggrep"; then - ggrep "$@" - return $? - else - grep "$@" - return $? - fi -} From 0dcf6771e736c6587d3dc064c95ad07059cbf2f6 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 11:51:16 +0100 Subject: [PATCH 1124/2234] World4you grammar --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 573c5ee6..87f6885f 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -133,7 +133,7 @@ _login() { if [ -z "$WORLD4YOU_USERNAME" ] || [ -z "$WORLD4YOU_PASSWORD" ]; then WORLD4YOU_USERNAME="" WORLD4YOU_PASSWORD="" - _err "You don't specified world4you username and password yet." + _err "You didn't specify world4you username and password yet." _err "Usage: export WORLD4YOU_USERNAME=" _err "Usage: export WORLD4YOU_PASSWORD=" return 2 From 1e3bb1f02b674e37d6dd15096782eea2e3cafb0a Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 11:51:59 +0100 Subject: [PATCH 1125/2234] World4You head_n --- dnsapi/dns_world4you.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 87f6885f..3db6db72 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -59,7 +59,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 else - _err "$(head -n 1 <"$HTTP_HEADER")" + _err "$(head_n 1 <"$HTTP_HEADER")" return 2 fi } @@ -118,7 +118,7 @@ DeleteDnsRecordForm[_token]=$form_token" if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 else - _err "$(head -n 1 <"$HTTP_HEADER")" + _err "$(head_n 1 <"$HTTP_HEADER")" return 2 fi } @@ -183,6 +183,6 @@ _get_paketnr() { TLD="$domain" RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))") - PAKETNR=$(echo "$form" | _egrep_o "data-textfilter=\" $domain .* [0-9]*" | head -n 1 | _egrep_o "[0-9]*") + PAKETNR=$(echo "$form" | _egrep_o "data-textfilter=\" $domain .* [0-9]*" | head_n 1 | _egrep_o "[0-9]*") return 0 } From bfccf29ccf9605df86f74a19b6d8156da590e2f1 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 11:55:22 +0100 Subject: [PATCH 1126/2234] World4You redirect fix --- dnsapi/dns_world4you.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 3db6db72..c8ad43c2 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -45,8 +45,8 @@ dns_world4you_add() { return 3 fi - _ORIG_ACME_CURL="$_ACME_CURL" - _ACME_CURL=$(echo "$_ACME_CURL" | sed 's/ -L / /') + ACME_HTTP_NO_REDIRECTS=1 + _resethttp body="AddDnsRecordForm[name]=$record&AddDnsRecordForm[dnsType][type]=TXT&\ AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\ @@ -54,7 +54,8 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _info "Adding record..." ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded') - _ACME_CURL="$_ORIG_ACME_CURL" + unset ACME_HTTP_NO_REDIRECTS + _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 @@ -104,8 +105,8 @@ dns_world4you_rm() { recordid=$(printf "TXT:%s.:\"%s\"" "$fqdn" "$value" | _base64) _debug recordid "$recordid" - _ORIG_ACME_CURL="$_ACME_CURL" - _ACME_CURL=$(echo "$_ACME_CURL" | sed 's/ -L / /') + ACME_HTTP_NO_REDIRECTS=1 + _resethttp body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[aktivPaket]=$paketnr&\ DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[uniqueFormIdTTL]=$formidttl&\ @@ -113,7 +114,8 @@ DeleteDnsRecordForm[_token]=$form_token" _info "Removing record..." ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/deleteRecord" '' POST 'application/x-www-form-urlencoded') - _ACME_CURL="$_ORIG_ACME_CURL" + unset ACME_HTTP_NO_REDIRECTS + _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 From 5f3e7f02ccb720a6367ce320b7b754842da4d9e6 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 11:55:49 +0100 Subject: [PATCH 1127/2234] World4You _head_n fix --- dnsapi/dns_world4you.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index c8ad43c2..2fcdc114 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -60,7 +60,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 else - _err "$(head_n 1 <"$HTTP_HEADER")" + _err "$(_head_n 1 <"$HTTP_HEADER")" return 2 fi } @@ -120,7 +120,7 @@ DeleteDnsRecordForm[_token]=$form_token" if grep '302' >/dev/null <"$HTTP_HEADER"; then return 0 else - _err "$(head_n 1 <"$HTTP_HEADER")" + _err "$(_head_n 1 <"$HTTP_HEADER")" return 2 fi } @@ -185,6 +185,6 @@ _get_paketnr() { TLD="$domain" RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))") - PAKETNR=$(echo "$form" | _egrep_o "data-textfilter=\" $domain .* [0-9]*" | head_n 1 | _egrep_o "[0-9]*") + PAKETNR=$(echo "$form" | _egrep_o "data-textfilter=\" $domain .* [0-9]*" | _head_n 1 | _egrep_o "[0-9]*") return 0 } From 342b48105fcd32048cb7a893fc9aa03f6308f0d7 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 12:02:05 +0100 Subject: [PATCH 1128/2234] World4You fix for no redirects --- dnsapi/dns_world4you.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 2fcdc114..0ea969a1 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -45,8 +45,8 @@ dns_world4you_add() { return 3 fi - ACME_HTTP_NO_REDIRECTS=1 _resethttp + ACME_HTTP_NO_REDIRECTS=1 body="AddDnsRecordForm[name]=$record&AddDnsRecordForm[dnsType][type]=TXT&\ AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\ @@ -54,7 +54,6 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _info "Adding record..." ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded') - unset ACME_HTTP_NO_REDIRECTS _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then @@ -105,8 +104,8 @@ dns_world4you_rm() { recordid=$(printf "TXT:%s.:\"%s\"" "$fqdn" "$value" | _base64) _debug recordid "$recordid" - ACME_HTTP_NO_REDIRECTS=1 _resethttp + ACME_HTTP_NO_REDIRECTS=1 body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[aktivPaket]=$paketnr&\ DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[uniqueFormIdTTL]=$formidttl&\ @@ -114,7 +113,6 @@ DeleteDnsRecordForm[_token]=$form_token" _info "Removing record..." ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/deleteRecord" '' POST 'application/x-www-form-urlencoded') - unset ACME_HTTP_NO_REDIRECTS _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then From fbcbc10174d325d7bafd7d37a686a8f05cdc37e3 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 12:03:51 +0100 Subject: [PATCH 1129/2234] World4You Shellcheck --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 0ea969a1..04d40945 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -46,7 +46,7 @@ dns_world4you_add() { fi _resethttp - ACME_HTTP_NO_REDIRECTS=1 + export ACME_HTTP_NO_REDIRECTS=1 body="AddDnsRecordForm[name]=$record&AddDnsRecordForm[dnsType][type]=TXT&\ AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\ @@ -105,7 +105,7 @@ dns_world4you_rm() { _debug recordid "$recordid" _resethttp - ACME_HTTP_NO_REDIRECTS=1 + export ACME_HTTP_NO_REDIRECTS=1 body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[aktivPaket]=$paketnr&\ DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[uniqueFormIdTTL]=$formidttl&\ From 48942de75e82210135e2b6c7c8bf8c57b9e698d5 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 13:59:33 +0100 Subject: [PATCH 1130/2234] World4You cleaning --- dnsapi/dns_world4you.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 04d40945..bed8db81 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -47,13 +47,11 @@ dns_world4you_add() { _resethttp export ACME_HTTP_NO_REDIRECTS=1 - body="AddDnsRecordForm[name]=$record&AddDnsRecordForm[dnsType][type]=TXT&\ AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_token" _info "Adding record..." ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded') - _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then @@ -72,9 +70,6 @@ dns_world4you_rm() { _debug fulldomain "$fqdn" _debug txtvalue "$value" - tld=$(echo "$fqdn" | _egrep_o '[^.]*\.[^.]*$') - record=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#tld} - 1))") - _login if [ "$?" != 0 ]; then return 1 @@ -106,13 +101,11 @@ dns_world4you_rm() { _resethttp export ACME_HTTP_NO_REDIRECTS=1 - body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[aktivPaket]=$paketnr&\ DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[uniqueFormIdTTL]=$formidttl&\ DeleteDnsRecordForm[_token]=$form_token" _info "Removing record..." ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/deleteRecord" '' POST 'application/x-www-form-urlencoded') - _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then From b7e6d98647b0006249973902980ee0bb20f82c5b Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 14:38:04 +0100 Subject: [PATCH 1131/2234] World4You grep fix --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index bed8db81..8254663a 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -162,7 +162,7 @@ _get_paketnr() { fqdn="$1" form="$2" - domains=$(echo "$form" | _egrep_o '^\s*([A-Za-z0-9_-]+\.)+[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') + domains=$(echo "$form" | grep '^ *[A-Za-z0-9_\.-]*\.[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do if echo "$fqdn" | grep "$domain\$" >/dev/null; then @@ -176,6 +176,6 @@ _get_paketnr() { TLD="$domain" RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))") - PAKETNR=$(echo "$form" | _egrep_o "data-textfilter=\" $domain .* [0-9]*" | _head_n 1 | _egrep_o "[0-9]*") + PAKETNR=$(echo "$form" | grep "data-textfilter=\" $domain " | _head_n 1 | sed 's/^.* \([0-9]*\) .*$/\1/') return 0 } From 3c309df6dd4d8975165d8e8555d4e5b938ea3c78 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 14:42:55 +0100 Subject: [PATCH 1132/2234] World4You shellcheck cleaning --- dnsapi/dns_world4you.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 8254663a..64491d08 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -27,8 +27,6 @@ dns_world4you_add() { form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") _get_paketnr "$fqdn" "$form" paketnr="$PAKETNR" - tld="$TLD" - record="$RECORD" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 @@ -47,7 +45,7 @@ dns_world4you_add() { _resethttp export ACME_HTTP_NO_REDIRECTS=1 - body="AddDnsRecordForm[name]=$record&AddDnsRecordForm[dnsType][type]=TXT&\ + body="AddDnsRecordForm[name]=$RECORD&AddDnsRecordForm[dnsType][type]=TXT&\ AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_token" _info "Adding record..." @@ -79,8 +77,6 @@ dns_world4you_rm() { form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") _get_paketnr "$fqdn" "$form" paketnr="$PAKETNR" - tld="$TLD" - record="$RECORD" if [ -z "$paketnr" ]; then _err "Unable to parse paketnr" return 3 From f665c73bb19d256bebfeed129813eb021e816ded Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 15:03:54 +0100 Subject: [PATCH 1133/2234] World4You fixed return value --- dnsapi/dns_world4you.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 64491d08..a89b029b 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -56,7 +56,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke return 0 else _err "$(_head_n 1 <"$HTTP_HEADER")" - return 2 + return 1 fi } @@ -108,7 +108,7 @@ DeleteDnsRecordForm[_token]=$form_token" return 0 else _err "$(_head_n 1 <"$HTTP_HEADER")" - return 2 + return 1 fi } @@ -125,7 +125,7 @@ _login() { _err "You didn't specify world4you username and password yet." _err "Usage: export WORLD4YOU_USERNAME=" _err "Usage: export WORLD4YOU_PASSWORD=" - return 2 + return 1 fi _saveaccountconf_mutable WORLD4YOU_USERNAME "$WORLD4YOU_USERNAME" From 40631f465eee608f4121177721c705157f29d84b Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 29 Nov 2020 15:22:41 +0100 Subject: [PATCH 1134/2234] World4You updated info strings --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index a89b029b..54cc1511 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -14,7 +14,7 @@ RECORD='' dns_world4you_add() { fqdn="$1" value="$2" - _info "Using world4you" + _info "Using world4you to add record" _debug fulldomain "$fqdn" _debug txtvalue "$value" @@ -64,7 +64,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke dns_world4you_rm() { fqdn="$1" value="$2" - _info "Using world4you" + _info "Using world4you to remove record" _debug fulldomain "$fqdn" _debug txtvalue "$value" From da839aae668227aa8d27e3a23ce2acfe5146de79 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 30 Nov 2020 17:57:25 +0100 Subject: [PATCH 1135/2234] World4You check response message --- dnsapi/dns_world4you.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 54cc1511..b35df75b 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -53,7 +53,13 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then - return 0 + msg=$(_get "$WORLD4YOU_API/$paketnr/dns" | tr '\n' '\t' | sed 's/^.*

[^\t]*\t *\([^\t]*\)\t.*/\1\n/') + if _contains "$msg" "successfully"; then + return 0 + else + _err "Unable to add record: $msg" + return 1 + fi else _err "$(_head_n 1 <"$HTTP_HEADER")" return 1 @@ -105,7 +111,13 @@ DeleteDnsRecordForm[_token]=$form_token" _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then - return 0 + msg=$(_get "$WORLD4YOU_API/$paketnr/dns" | tr '\n' '\t' | sed 's/^.*

[^\t]*\t *\([^\t]*\)\t.*/\1\n/') + if _contains "$msg" "successfully"; then + return 0 + else + _err "Unable to remove record: $msg" + return 1 + fi else _err "$(_head_n 1 <"$HTTP_HEADER")" return 1 From f38317d01f6805e5256a811e076f1c45c990a2e8 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 30 Nov 2020 19:56:48 +0100 Subject: [PATCH 1136/2234] World4You Mac debug --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index b35df75b..8b7f2eed 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -53,7 +53,7 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then - msg=$(_get "$WORLD4YOU_API/$paketnr/dns" | tr '\n' '\t' | sed 's/^.*

[^\t]*\t *\([^\t]*\)\t.*/\1\n/') + msg=$(_get "$WORLD4YOU_API/$paketnr/dns" | tr '\n' '\t' | sed 's/.*

[^\t]*\t *\([^\t]*\)\t.*/\1/') if _contains "$msg" "successfully"; then return 0 else @@ -111,7 +111,7 @@ DeleteDnsRecordForm[_token]=$form_token" _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then - msg=$(_get "$WORLD4YOU_API/$paketnr/dns" | tr '\n' '\t' | sed 's/^.*

[^\t]*\t *\([^\t]*\)\t.*/\1\n/') + msg=$(_get "$WORLD4YOU_API/$paketnr/dns" | tr '\n' '\t' | sed 's/.*

[^\t]*\t *\([^\t]*\)\t.*/\1/') if _contains "$msg" "successfully"; then return 0 else From be43cebf7de68575dcf96f7bdb609b53d9dfa5dc Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 30 Nov 2020 20:01:43 +0100 Subject: [PATCH 1137/2234] World4You Mac fix --- dnsapi/dns_world4you.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 8b7f2eed..24b8dd68 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -53,10 +53,11 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then - msg=$(_get "$WORLD4YOU_API/$paketnr/dns" | tr '\n' '\t' | sed 's/.*

[^\t]*\t *\([^\t]*\)\t.*/\1/') - if _contains "$msg" "successfully"; then + res=$(_get "$WORLD4YOU_API/$paketnr/dns") + if _contains "$res" "successfully"; then return 0 else + msg=$(echo "$res" | tr '\n' '\t' | sed 's/.*

[^\t]*\t *\([^\t]*\)\t.*/\1/') _err "Unable to add record: $msg" return 1 fi @@ -111,10 +112,11 @@ DeleteDnsRecordForm[_token]=$form_token" _resethttp if grep '302' >/dev/null <"$HTTP_HEADER"; then - msg=$(_get "$WORLD4YOU_API/$paketnr/dns" | tr '\n' '\t' | sed 's/.*

[^\t]*\t *\([^\t]*\)\t.*/\1/') - if _contains "$msg" "successfully"; then + res=$(_get "$WORLD4YOU_API/$paketnr/dns") + if _contains "$res" "successfully"; then return 0 else + msg=$(echo "$res" | tr '\n' '\t' | sed 's/.*

[^\t]*\t *\([^\t]*\)\t.*/\1/') _err "Unable to remove record: $msg" return 1 fi From 2bc627970ed38fbccd7316e7e4a868eb33cff94c Mon Sep 17 00:00:00 2001 From: Christian Burmeister Date: Tue, 1 Dec 2020 20:30:56 +0100 Subject: [PATCH 1138/2234] Update mailcow.sh I have modified the following things: Originally, "/data/assets/ssl/" is always appended to the varialbe ${_mailcow_path}. Since I use acme.sh as docker container, I only want to include the mailcow-ssl directory in the acem.sh container and not the complete mailcow directory. So now it is checked if the file generate_config.sh is in the directory (then it is the mailcow root directory, see https://github.com/mailcow/mailcow-dockerized) and only then "/data/assets/ssl/" is appended, in all other cases the passed variable is taken over unchanged. Because of the RP mailcow/mailcow-dockerized#2443 I have extended the script with ECC certificates. I adapted the reboot commands as described in the mailcow manual (https://mailcow.github.io/mailcow-dockerized-docs/firststeps-ssl/#how-to-use-your-own-certificate). --- deploy/mailcow.sh | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index 3a806e83..830bec04 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -27,26 +27,46 @@ mailcow_deploy() { return 1 fi - _ssl_path="${_mailcow_path}/data/assets/ssl/" + #Tests if _ssl_path is the mailcow root directory. + if [ -f "${_mailcow_path}/generate_config.sh" ]; then + _ssl_path="${_mailcow_path}/data/assets/ssl/" + else + _ssl_path="${_mailcow_path}" + fi + if [ ! -d "$_ssl_path" ]; then _err "Cannot find mailcow ssl path: $_ssl_path" return 1 fi + # ECC or RSA + if [ -z "${Le_Keylength}" ]; then + Le_Keylength="" + fi + if _isEccKey "${Le_Keylength}"; then + _info "ECC key type detected" + _cert_type="ecdsa" + _cert_name_prefix="ecdsa-" + else + _info "RSA key type detected" + _cert_type="rsa" + _cert_name_prefix="" + + fi _info "Copying key and cert" - _real_key="$_ssl_path/key.pem" + _real_key="$_ssl_path/${_cert_name_prefix}key.pem" if ! cat "$_ckey" >"$_real_key"; then _err "Error: write key file to: $_real_key" return 1 fi - _real_fullchain="$_ssl_path/cert.pem" + _real_fullchain="$_ssl_path/${_cert_name_prefix}cert.pem" if ! cat "$_cfullchain" >"$_real_fullchain"; then _err "Error: write cert file to: $_real_fullchain" return 1 fi - DEFAULT_MAILCOW_RELOAD="cd ${_mailcow_path} && docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow" + 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)" _reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}" _info "Run reload: $_reload" From 94bba4ac9c977194209b3829bc83f4b3b783aa9f Mon Sep 17 00:00:00 2001 From: Nate Date: Sun, 6 Dec 2020 22:45:42 +0700 Subject: [PATCH 1139/2234] Correct sed regex Corrects issue #3285. The '?' character after a group is not supported in POSIX Basic Regular Expressions. Replacing it with '\{0,1\}' retains the same functionality and also works on non-GNU systems. --- dnsapi/dns_duckdns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index f0af2741..41685147 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -96,7 +96,7 @@ dns_duckdns_rm() { _duckdns_get_domain() { # We'll extract the domain/username from full domain - _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '^(_acme-challenge\.)?[a-z0-9-]*\.duckdns\.org' | sed 's/^\(_acme-challenge\.\)\?\([a-z0-9-]*\)\.duckdns\.org/\2/')" + _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '^(_acme-challenge\.)?[a-z0-9-]*\.duckdns\.org' | sed 's/^\(_acme-challenge\.\)\{0,1\}\([a-z0-9-]*\)\.duckdns\.org/\2/')" if [ -z "$_duckdns_domain" ]; then _err "Error extracting the domain." From 671bd1022e92009873e596ab341d1cd3b1ec1c24 Mon Sep 17 00:00:00 2001 From: Van Hau TRAN Date: Sun, 6 Dec 2020 22:59:36 +0100 Subject: [PATCH 1140/2234] feat: add scaleway provider --- dnsapi/dns_scaleway.sh | 162 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100755 dnsapi/dns_scaleway.sh diff --git a/dnsapi/dns_scaleway.sh b/dnsapi/dns_scaleway.sh new file mode 100755 index 00000000..20397096 --- /dev/null +++ b/dnsapi/dns_scaleway.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env sh + +# Scaleway API +# https://developers.scaleway.com/en/products/domain/dns/api/ +# +# Requires Scaleway API token set in SCALEWAY_API_TOKEN + +######## Public functions ##################### + +SCALEWAY_API="https://api.scaleway.com/domain/v2beta1" + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_scaleway_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _scaleway_check_config; then + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + _scaleway_create_TXT_record "$_domain" "$_sub_domain" "$txtvalue" + _info "Record added." + + return 0 +} + +dns_scaleway_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _scaleway_check_config; then + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Deleting record" + _scaleway_create_TXT_record "$_domain" "$_sub_domain" "$txtvalue" + _info "Record deleted." + + return 0 +} + +#################### Private functions below ################################## + +_scaleway_check_config() { + SCALEWAY_API_TOKEN="${SCALEWAY_API_TOKEN:-$(_readaccountconf_mutable SCALEWAY_API_TOKEN)}" + if [ -z "$SCALEWAY_API_TOKEN" ]; then + _err "No API key specified for Scaleway API." + _err "Create your key and export it as SCALEWAY_API_TOKEN" + return 1 + fi + if ! _scaleway_rest GET "dns-zones"; then + _err "Invalid API key specified for Scaleway API." + return 1 + fi + + _saveaccountconf_mutable SCALEWAY_API_TOKEN "$SCALEWAY_API_TOKEN" + + return 0 +} + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + _scaleway_rest GET "dns-zones/$h/records" + + if ! _contains "$response" "subdomain not found" >/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 + _err "Unable to retrive DNS zone matching this domain" + return 1 +} + +_scaleway_create_TXT_record() { + txt_zone=$1 + txt_name=$2 + txt_value=$3 + + _scaleway_rest PATCH "dns-zones/$txt_zone/records" "{\"return_all_records\":false,\"changes\":[{\"add\":{\"records\":[{\"name\":\"$txt_name\",\"data\":\"$txt_value\",\"type\":\"TXT\",\"ttl\":60}]}}]}" + + if [ _contains "$response" "records"; then + return 0 + else + _err "error1 $response" + return 1 + fi +} + +_scaleway_delete_TXT_record() { + txt_zone=$1 + txt_name=$2 + txt_value=$3 + + _scaleway_rest PATCH "dns-zones/$txt_zone/records" "{\"return_all_records\":false,\"changes\":[{\"delete\":{\"id_fields\":{\"name\":\"$txt_name\",\"data\":\"$txt_value\",\"type\":\"TXT\"}}}]}" + + if [ _contains "$response" "records"; then + return 0 + else + _err "error2 $response" + return 1 + fi +} + +_scaleway_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + _scaleway_url="$SCALEWAY_API/$ep" + _debug2 _scaleway_url "$_scaleway_url" + export _H1="x-auth-token: $SCALEWAY_API_TOKEN" + export _H2="Accept: application/json" + export _H3="Content-Type: application/json" + + if [ "$data" ] || [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$_scaleway_url" "" "$m")" + else + response="$(_get "$_scaleway_url")" + fi + if [ "$?" != "0" ] || _contains "$response" "denied_authentication" || _contains "$response" "Method not allowed" || _contains "$response" "json parse error: unexpected EOF"; then + _err "error $response" + return 1 + fi + _debug2 response "$response" + return 0 +} From b5653a1c06e93f745e716a8860897b15a481affc Mon Sep 17 00:00:00 2001 From: Van Hau TRAN Date: Sun, 6 Dec 2020 23:14:25 +0100 Subject: [PATCH 1141/2234] feat: add comment and configure workflow ci test --- dnsapi/dns_scaleway.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_scaleway.sh b/dnsapi/dns_scaleway.sh index 20397096..abca5125 100755 --- a/dnsapi/dns_scaleway.sh +++ b/dnsapi/dns_scaleway.sh @@ -106,6 +106,7 @@ _get_root() { return 1 } +# this function add a TXT record _scaleway_create_TXT_record() { txt_zone=$1 txt_name=$2 @@ -121,6 +122,7 @@ _scaleway_create_TXT_record() { fi } +# this function delete a TXT record based on name and content _scaleway_delete_TXT_record() { txt_zone=$1 txt_name=$2 From 5127a9ae3cbc611047a42d041b8e5da50906d1da Mon Sep 17 00:00:00 2001 From: Van Hau TRAN Date: Sun, 6 Dec 2020 23:20:41 +0100 Subject: [PATCH 1142/2234] fix: shell if --- dnsapi/dns_scaleway.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_scaleway.sh b/dnsapi/dns_scaleway.sh index abca5125..778738f4 100755 --- a/dnsapi/dns_scaleway.sh +++ b/dnsapi/dns_scaleway.sh @@ -114,7 +114,7 @@ _scaleway_create_TXT_record() { _scaleway_rest PATCH "dns-zones/$txt_zone/records" "{\"return_all_records\":false,\"changes\":[{\"add\":{\"records\":[{\"name\":\"$txt_name\",\"data\":\"$txt_value\",\"type\":\"TXT\",\"ttl\":60}]}}]}" - if [ _contains "$response" "records"; then + if _contains "$response" "records"; then return 0 else _err "error1 $response" @@ -130,7 +130,7 @@ _scaleway_delete_TXT_record() { _scaleway_rest PATCH "dns-zones/$txt_zone/records" "{\"return_all_records\":false,\"changes\":[{\"delete\":{\"id_fields\":{\"name\":\"$txt_name\",\"data\":\"$txt_value\",\"type\":\"TXT\"}}}]}" - if [ _contains "$response" "records"; then + if _contains "$response" "records"; then return 0 else _err "error2 $response" From a0c2d312e9e1698076bbacf010c37d933427c2f0 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 7 Dec 2020 21:31:02 +0800 Subject: [PATCH 1143/2234] start 2.8.9 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index dcbe3c9d..ae387535 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.8 +VER=2.8.9 PROJECT_NAME="acme.sh" From 32b62d6d4f3424b0212ce1bf196c04353a23c838 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 7 Dec 2020 21:41:08 +0800 Subject: [PATCH 1144/2234] fix --- deploy/mailcow.sh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index 830bec04..babd5d28 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -27,11 +27,11 @@ mailcow_deploy() { return 1 fi - #Tests if _ssl_path is the mailcow root directory. + #Tests if _ssl_path is the mailcow root directory. if [ -f "${_mailcow_path}/generate_config.sh" ]; then _ssl_path="${_mailcow_path}/data/assets/ssl/" else - _ssl_path="${_mailcow_path}" + _ssl_path="${_mailcow_path}" fi if [ ! -d "$_ssl_path" ]; then @@ -41,17 +41,16 @@ mailcow_deploy() { # ECC or RSA if [ -z "${Le_Keylength}" ]; then - Le_Keylength="" + Le_Keylength="" fi if _isEccKey "${Le_Keylength}"; then - _info "ECC key type detected" - _cert_type="ecdsa" - _cert_name_prefix="ecdsa-" + _info "ECC key type detected" + _cert_type="ecdsa" + _cert_name_prefix="ecdsa-" else - _info "RSA key type detected" - _cert_type="rsa" - _cert_name_prefix="" - + _info "RSA key type detected" + _cert_type="rsa" + _cert_name_prefix="" fi _info "Copying key and cert" _real_key="$_ssl_path/${_cert_name_prefix}key.pem" From 174c87a192cb86749d83697a347624f33797e874 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 7 Dec 2020 21:42:31 +0800 Subject: [PATCH 1145/2234] fix --- deploy/mailcow.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index babd5d28..932956c0 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -49,7 +49,6 @@ mailcow_deploy() { _cert_name_prefix="ecdsa-" else _info "RSA key type detected" - _cert_type="rsa" _cert_name_prefix="" fi _info "Copying key and cert" From 8440d013f8cfd678c3a03677b949e18459920827 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 7 Dec 2020 22:01:30 +0800 Subject: [PATCH 1146/2234] fix --- deploy/mailcow.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index 932956c0..c3535e7e 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -45,7 +45,6 @@ mailcow_deploy() { fi if _isEccKey "${Le_Keylength}"; then _info "ECC key type detected" - _cert_type="ecdsa" _cert_name_prefix="ecdsa-" else _info "RSA key type detected" From 9b532584d6f3e33bf4c548f2f035799779a2c895 Mon Sep 17 00:00:00 2001 From: Van Hau TRAN Date: Tue, 8 Dec 2020 16:32:31 +0100 Subject: [PATCH 1147/2234] fix: fix delete txt record and error mngtt --- dnsapi/dns_scaleway.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_scaleway.sh b/dnsapi/dns_scaleway.sh index 778738f4..a0a0f318 100755 --- a/dnsapi/dns_scaleway.sh +++ b/dnsapi/dns_scaleway.sh @@ -29,6 +29,12 @@ dns_scaleway_add() { _info "Adding record" _scaleway_create_TXT_record "$_domain" "$_sub_domain" "$txtvalue" + if _contains "$response" "records"; then + return 0 + else + _err error "$response" + return 1 + fi _info "Record added." return 0 @@ -52,7 +58,13 @@ dns_scaleway_rm() { _debug _domain "$_domain" _info "Deleting record" - _scaleway_create_TXT_record "$_domain" "$_sub_domain" "$txtvalue" + _scaleway_delete_TXT_record "$_domain" "$_sub_domain" "$txtvalue" + if _contains "$response" "records"; then + return 0 + else + _err error "$response" + return 1 + fi _info "Record deleted." return 0 @@ -83,7 +95,7 @@ _scaleway_check_config() { # _domain=domain.com _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From 99d3a283efd9a6a6a5c6e5812aa829984cbb8cff Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 26 Sep 2020 19:38:18 -0600 Subject: [PATCH 1148/2234] Use POST for login This allows us to get the cookie and the token (as it appears to be only in the body in DSM 7.) HTTP_HEADERS is only guarenteed to be output with POST for both wget and curl. --- deploy/synology_dsm.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 2ec0ceb3..53ab5dd9 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -22,7 +22,7 @@ ######## Public functions ##################### _syno_get_cookie_data() { - grep -i "\W$1=" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' + grep -i "\W$1=" "$HTTP_HEADER" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' } #domain keyfile certfile cafile fullchain @@ -78,8 +78,8 @@ synology_dsm_deploy() { encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" encoded_did="$(printf "%s" "$SYNO_DID" | _url_encode)" - response=$(_get "$_base_url/webman/login.cgi?username=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_id=$encoded_did" 1) - token=$(echo "$response" | grep -i "X-SYNO-TOKEN:" | sed -n 's/^X-SYNO-TOKEN: \(.*\)$/\1/pI' | tr -d "\r\n") + response=$(_post "username=$encoded_username&passwd=$encoded_password&device_id=$encoded_did" "$_base_url/webman/login.cgi?enable_syno_token=yes") + token=$(echo "$response" | grep "SynoToken" | sed -n 's/.*"SynoToken" *: *"\([^"]*\).*/\1/p') _debug3 response "$response" _debug token "$token" @@ -89,7 +89,7 @@ synology_dsm_deploy() { return 1 fi - _H1="Cookie: $(echo "$response" | _syno_get_cookie_data "id"); $(echo "$response" | _syno_get_cookie_data "smid")" + _H1="Cookie: $(_syno_get_cookie_data "id"); $(_syno_get_cookie_data "smid")" _H2="X-SYNO-TOKEN: $token" export _H1 export _H2 From cc69285420a49f118acb37c77e3c8f9f73c19f7f Mon Sep 17 00:00:00 2001 From: Thijn Date: Wed, 9 Dec 2020 11:45:25 +0100 Subject: [PATCH 1149/2234] Fix synology_dsm deployhook for DSM 7 --- deploy/synology_dsm.sh | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 53ab5dd9..bca12d8d 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -73,13 +73,25 @@ synology_dsm_deploy() { _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" + _debug "Getting API version" + response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth") + api_version=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p') + _debug3 response "$response" + _debug3 api_version "$api_version" + # Login, get the token from JSON and session id from cookie _info "Logging into $SYNO_Hostname:$SYNO_Port" encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" - encoded_did="$(printf "%s" "$SYNO_DID" | _url_encode)" - response=$(_post "username=$encoded_username&passwd=$encoded_password&device_id=$encoded_did" "$_base_url/webman/login.cgi?enable_syno_token=yes") - token=$(echo "$response" | grep "SynoToken" | sed -n 's/.*"SynoToken" *: *"\([^"]*\).*/\1/p') + + if [ ! -z "$SYNO_DID" ]; then + _H1="Cookie: did=$SYNO_DID" + export _H1 + _debug3 H1 "${_H1}" + fi + + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&enable_device_token=yes&enable_syno_token=yes" "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version") + token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') _debug3 response "$response" _debug token "$token" @@ -88,13 +100,11 @@ synology_dsm_deploy() { _err "Check your username and password." return 1 fi + sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p') - _H1="Cookie: $(_syno_get_cookie_data "id"); $(_syno_get_cookie_data "smid")" - _H2="X-SYNO-TOKEN: $token" + _H1="X-SYNO-TOKEN: $token" export _H1 - export _H2 _debug2 H1 "${_H1}" - _debug2 H2 "${_H2}" # Now that we know the username and password are good, save them _savedeployconf SYNO_Username "$SYNO_Username" @@ -102,7 +112,7 @@ synology_dsm_deploy() { _savedeployconf SYNO_DID "$SYNO_DID" _info "Getting certificates in Synology DSM" - response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1" "$_base_url/webapi/entry.cgi") + response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") _debug3 response "$response" id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" @@ -135,7 +145,7 @@ synology_dsm_deploy() { content="${content%_}" # protect trailing \n _info "Upload certificate to the Synology DSM" - response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" "" "POST" "multipart/form-data; boundary=${delim}") + response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token&_sid=$sid" "" "POST" "multipart/form-data; boundary=${delim}") _debug3 response "$response" if ! echo "$response" | grep '"error":' >/dev/null; then From 7d7789ae96ef4061dfb97c41d45a7b017626d305 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Wed, 9 Dec 2020 20:35:50 -0700 Subject: [PATCH 1150/2234] Support DSM 6 and 7 Small changes for DSM 6: All fields (except enable_syno_token as explained below) must either be in the GET params or the POST params, you can't mix GET and POST params enable_syno_token=yes must be in both the GET and POST params. If enable_syno_token=yes is only in the POST fields, then DSM6 returns a synotoken of --------. If enable_syno_token=yes is only in the GET params, then it returns no synotoken at all. It must be in both to work. Need to use /webapi/auth.cgi instead of /webapi/entry.cgi Verified with DSM 6.2.3-25426 Update 2 and DSM 7.0-40850 --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index bca12d8d..edbc1e3e 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -90,7 +90,7 @@ synology_dsm_deploy() { _debug3 H1 "${_H1}" fi - response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&enable_device_token=yes&enable_syno_token=yes" "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version") + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') _debug3 response "$response" _debug token "$token" From 2635dfef9659a69d003cc2cb1f108a6c7de044a1 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Wed, 9 Dec 2020 21:01:44 -0700 Subject: [PATCH 1151/2234] Shellcheck linting Also removed unused code --- deploy/synology_dsm.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index edbc1e3e..35d33209 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -21,10 +21,6 @@ ######## Public functions ##################### -_syno_get_cookie_data() { - grep -i "\W$1=" "$HTTP_HEADER" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' -} - #domain keyfile certfile cafile fullchain synology_dsm_deploy() { @@ -84,7 +80,7 @@ synology_dsm_deploy() { encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" - if [ ! -z "$SYNO_DID" ]; then + if [ -n "$SYNO_DID" ]; then _H1="Cookie: did=$SYNO_DID" export _H1 _debug3 H1 "${_H1}" From 15fb47cb3d0220de6db1c5cf41ecffd03f532275 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 10 Dec 2020 20:21:57 +0800 Subject: [PATCH 1152/2234] fix https://github.com/acmesh-official/acme.sh/issues/3300 --- deploy/docker.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/docker.sh b/deploy/docker.sh index 451d5d00..3aa1b2cd 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -275,6 +275,7 @@ _check_curl_version() { if [ "$_major$_minor" -lt "740" ]; then _err "curl v$_cversion doesn't support unit socket" + _err "Please upgrade to curl 7.40 or later." return 1 fi if [ "$_major$_minor" -lt "750" ]; then From cee20c4eb96ec8ec3ad789ae5e3902689598b0ee Mon Sep 17 00:00:00 2001 From: jimp100 <35727302+jimp100@users.noreply.github.com> Date: Wed, 16 Dec 2020 10:11:43 +0000 Subject: [PATCH 1153/2234] Corrected regex for subdomains A fix to handle subdomains of a duckdns domain. I.e. subdomain.mydomain.duckdns.org Handles n number of subdomains --- dnsapi/dns_duckdns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 41685147..618e12c6 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -96,7 +96,7 @@ dns_duckdns_rm() { _duckdns_get_domain() { # We'll extract the domain/username from full domain - _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '^(_acme-challenge\.)?[a-z0-9-]*\.duckdns\.org' | sed 's/^\(_acme-challenge\.\)\{0,1\}\([a-z0-9-]*\)\.duckdns\.org/\2/')" + _duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '^(_acme-challenge\.)?([a-z0-9-]+\.)+duckdns\.org' | sed -n 's/^\([^.]\{1,\}\.\)*\([a-z0-9-]\{1,\}\)\.duckdns\.org$/\2/p;')" if [ -z "$_duckdns_domain" ]; then _err "Error extracting the domain." From 48b2a271cc81a7ab8bf2bc229aa59d58f88c493e Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 20 Dec 2020 20:17:05 +0100 Subject: [PATCH 1154/2234] World4You Bugfix unable to parse paketnr --- dnsapi/dns_world4you.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 24b8dd68..9d36f84d 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -185,7 +185,8 @@ _get_paketnr() { fi 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 " | _head_n 1 | sed 's/^.* \([0-9]*\) .*$/\1/') return 0 } From ac4ae85a4a5c07b4124da3a2e3efce1747db45c7 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 21 Dec 2020 09:39:09 +0100 Subject: [PATCH 1155/2234] World4You code refactor --- dnsapi/dns_world4you.sh | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 9d36f84d..6baccbd0 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -52,17 +52,26 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded') _resethttp - if grep '302' >/dev/null <"$HTTP_HEADER"; then + if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then res=$(_get "$WORLD4YOU_API/$paketnr/dns") 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 + echo "$ret" > 'error-01.html' + echo "$res" > 'error-02.html' + _err "View error-01.html and error-02.html for debugging" + fi return 1 fi else - _err "$(_head_n 1 <"$HTTP_HEADER")" + _err "$(_head_n 3 <"$HTTP_HEADER")" + _err "View $HTTP_HEADER for debugging" return 1 fi } @@ -111,17 +120,26 @@ DeleteDnsRecordForm[_token]=$form_token" ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/deleteRecord" '' POST 'application/x-www-form-urlencoded') _resethttp - if grep '302' >/dev/null <"$HTTP_HEADER"; then + if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then res=$(_get "$WORLD4YOU_API/$paketnr/dns") 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 + echo "$ret" > 'error-01.html' + echo "$res" > 'error-02.html' + _err "View error-01.html and error-02.html for debugging" + fi return 1 fi else - _err "$(_head_n 1 <"$HTTP_HEADER")" + _err "$(_head_n 3 <"$HTTP_HEADER")" + _err "View $HTTP_HEADER for debugging" return 1 fi } @@ -175,7 +193,7 @@ _get_paketnr() { domains=$(echo "$form" | grep '^ *[A-Za-z0-9_\.-]*\.[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') domain='' for domain in $domains; do - if echo "$fqdn" | grep "$domain\$" >/dev/null; then + if _contains "$fqdn" "$domain\$"; then break fi domain='' From cb90167c76fa2a88eea8d16c463b2e674d02c009 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 21 Dec 2020 09:41:05 +0100 Subject: [PATCH 1156/2234] World4You shellcheck --- dnsapi/dns_world4you.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 6baccbd0..9ab406f6 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -63,8 +63,8 @@ AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_toke fi _err "Unable to add record: $msg" if _contains "$msg" '^<\!DOCTYPE html>'; then - echo "$ret" > 'error-01.html' - echo "$res" > 'error-02.html' + echo "$ret" >'error-01.html' + echo "$res" >'error-02.html' _err "View error-01.html and error-02.html for debugging" fi return 1 @@ -131,8 +131,8 @@ DeleteDnsRecordForm[_token]=$form_token" fi _err "Unable to remove record: $msg" if _contains "$msg" '^<\!DOCTYPE html>'; then - echo "$ret" > 'error-01.html' - echo "$res" > 'error-02.html' + echo "$ret" >'error-01.html' + echo "$res" >'error-02.html' _err "View error-01.html and error-02.html for debugging" fi return 1 From 8a24275ba929d55ab3c3060b3c54239c2e2855ec Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Dec 2020 20:45:43 +0800 Subject: [PATCH 1157/2234] add dns check wiki --- acme.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/acme.sh b/acme.sh index ae387535..e78744c9 100755 --- a/acme.sh +++ b/acme.sh @@ -160,6 +160,8 @@ _SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server" _PREFERRED_CHAIN_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain" +_DNSCHECK_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnscheck" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -3958,6 +3960,8 @@ _check_dns_entries() { _end_time="$(_math "$_end_time" + 1200)" #let's check no more than 20 minutes. while [ "$(_time)" -le "$_end_time" ]; do + _info "You can use '--dnssleep' to disable public dns checks." + _info "See: $_DNSCHECK_WIKI" _left="" for entry in $dns_entries; do d=$(_getfield "$entry" 1) From a00046f9b299b1cff24dcdfeedfab2426100c144 Mon Sep 17 00:00:00 2001 From: Lukas Brocke Date: Thu, 24 Dec 2020 11:03:25 +0100 Subject: [PATCH 1158/2234] dnsapi/ionos: Add API support for IONOS DNS API The IONOS DNS API is in beta state, please read [1] on how to get started. PLEASE NOTE: The v2 wildcard certification creation [2] is not yet supported as the IONOS API doesn't allow the creation of multiple TXT records with the same domain name. [1] https://beta.developer.hosting.ionos.de/docs/getstarted [2] https://github.com/acmesh-official/acme.sh/issues/1261 --- dnsapi/dns_ionos.sh | 157 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100755 dnsapi/dns_ionos.sh diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh new file mode 100755 index 00000000..4d33e019 --- /dev/null +++ b/dnsapi/dns_ionos.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env sh + +# Supports IONOS DNS API Beta v1.0.0 +# +# Usage: +# Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh: +# +# $ export IONOS_PREFIX="..." +# $ export IONOS_SECRET="..." +# +# $ acme.sh --issue --dns dns_ionos ... + +IONOS_API="https://api.hosting.ionos.com/dns" +IONOS_ROUTE_ZONES="/v1/zones" + +IONOS_TXT_TTL=60 # minumum accepted by API +IONOS_TXT_PRIO=10 + +dns_ionos_add() { + fulldomain=$1 + txtvalue=$2 + + _ionos_init + + _body="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}" + + if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then + _info "TXT record for _sub_domain.$_domain has been created successfully." + return 0 + fi + + return 1 +} + +dns_ionos_rm() { + fulldomain=$1 + txtvalue=$2 + + _ionos_init + + if ! _ionos_get_record "$fulldomain" "$_zone_id"; then + _err "Could not find _acme-challenge TXT record." + return 1 + fi + + if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ -z "$response" ]; then + _info "TXT record for _sub_domain.$_domain has been deleted successfully." + return 0 + fi + + return 1 +} + +_ionos_init() { + IONOS_PREFIX="${IONOS_PREFIX:-$(_readaccountconf_mutable IONOS_PREFIX)}" + IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}" + + if [ -z "$IONOS_PREFIX" ] || [ -z "$IONOS_SECRET" ]; then + _err "You didn't specify an IONOS api prefix and secret yet." + _err "Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret." + _err "" + _err "Then set them before calling acme.sh:" + _err "\$ export IONOS_PREFIX=\"...\"" + _err "\$ export IONOS_SECRET=\"...\"" + _err "\$ acme.sh --issue -d ... --dns dns_ionos" + return 1 + fi + + _saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX" + _saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET" + + if ! _get_root "$fulldomain"; then + _err "Cannot find this domain in your IONOS account." + return 1 + fi +} + +_get_root() { + domain=$1 + i=2 + p=1 + + if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then + response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + return 1 + fi + + _zone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")" + if [ "$_zone" ]; then + _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"' ) + if [ "$_zone_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + + return 0 + fi + + return 1 + fi + + p=$i + i=$(_math "$i" + 1) + done + fi + + return 1 +} + +_ionos_get_record() { + fulldomain=$1 + zone_id=$2 + + if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then + response="$(echo "$response" | tr -d "\n" )" + + _record="$(echo "$response" | _egrep_o "{\"name\":\s*\"$fulldomain\".*}")" + if [ "$_record" ]; then + _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"' ) + + return 0 + fi + fi + + return 1 +} + +_ionos_rest() { + method="$1" + route="$2" + data="$3" + + IONOS_API_KEY="$(printf "%s.%s" "$IONOS_PREFIX" "$IONOS_SECRET")" + + export _H1="X-API-Key: $IONOS_API_KEY" + + if [ "$method" != "GET" ]; then + export _H2="Accept: application/json" + export _H3="Content-Type: application/json" + + response="$(_post "$data" "$IONOS_API$route" "" "$method")" + else + export _H2="Accept: */*" + + response="$(_get "$IONOS_API$route")" + fi + + if [ "$?" != "0" ]; then + _err "Error $route" + return 1 + fi + + return 0 +} From 22f7ac22d528a0efbaa6326d9812ffde6884f4bc Mon Sep 17 00:00:00 2001 From: Lukas Brocke Date: Thu, 24 Dec 2020 13:06:07 +0100 Subject: [PATCH 1159/2234] dnsapi/ionos: Run shfmt --- dnsapi/dns_ionos.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 4d33e019..fb6ba3f8 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -13,7 +13,7 @@ IONOS_API="https://api.hosting.ionos.com/dns" IONOS_ROUTE_ZONES="/v1/zones" -IONOS_TXT_TTL=60 # minumum accepted by API +IONOS_TXT_TTL=60 # minimum accepted by API IONOS_TXT_PRIO=10 dns_ionos_add() { @@ -25,7 +25,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 PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then - _info "TXT record for _sub_domain.$_domain has been created successfully." + _info "TXT record has been created successfully." return 0 fi @@ -44,7 +44,7 @@ dns_ionos_rm() { fi if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ -z "$response" ]; then - _info "TXT record for _sub_domain.$_domain has been deleted successfully." + _info "TXT record has been deleted successfully." return 0 fi @@ -54,7 +54,7 @@ dns_ionos_rm() { _ionos_init() { IONOS_PREFIX="${IONOS_PREFIX:-$(_readaccountconf_mutable IONOS_PREFIX)}" IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}" - + if [ -z "$IONOS_PREFIX" ] || [ -z "$IONOS_SECRET" ]; then _err "You didn't specify an IONOS api prefix and secret yet." _err "Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret." @@ -91,7 +91,7 @@ _get_root() { _zone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")" if [ "$_zone" ]; then - _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"' ) + _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') if [ "$_zone_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -115,13 +115,13 @@ _ionos_get_record() { zone_id=$2 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\":\s*\"$fulldomain\".*}")" if [ "$_record" ]; then - _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"' ) - - return 0 + _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + + return 0 fi fi From d6083c68fd3d174fb2ae6025d19965dcf332ac52 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 28 Dec 2020 21:10:22 +0800 Subject: [PATCH 1160/2234] add libidn --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 6b382242..4618efaf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ RUN apk update -f \ tzdata \ oath-toolkit-oathtool \ tar \ + libidn \ && rm -rf /var/cache/apk/* ENV LE_CONFIG_HOME /acme.sh From 10de4b6b7bc5f3c9d40214afb62d232b53ee7f89 Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Mon, 4 Jan 2021 18:41:02 +1300 Subject: [PATCH 1161/2234] Add Telegram notification script Requires: - API Token for a bot created with the Telegram Bot Father. - A Chat ID for a user/group that the bot has permission to post to. --- notify/telegram.sh | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 notify/telegram.sh diff --git a/notify/telegram.sh b/notify/telegram.sh new file mode 100644 index 00000000..ee2d93e2 --- /dev/null +++ b/notify/telegram.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +#Support Telegram Bots + +#TELEGRAM_BOT_APITOKEN="" +#TELEGRAM_BOT_CHATID="" + +telegram_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + TELEGRAM_BOT_APITOKEN="${TELEGRAM_BOT_APITOKEN:-$(_readaccountconf_mutable TELEGRAM_BOT_APITOKEN)}" + if [ -z "$TELEGRAM_BOT_APITOKEN" ]; then + TELEGRAM_BOT_APITOKEN="" + _err "You didn't specify a Telegram BOT API Token TELEGRAM_BOT_APITOKEN yet." + return 1 + fi + _saveaccountconf_mutable TELEGRAM_BOT_APITOKEN "$TELEGRAM_BOT_APITOKEN" + + TELEGRAM_BOT_CHATID="${TELEGRAM_BOT_CHATID:-$(_readaccountconf_mutable TELEGRAM_BOT_CHATID)}" + if [ -z "$TELEGRAM_BOT_CHATID" ]; then + TELEGRAM_BOT_CHATID="" + _err "You didn't specify a Telegram Chat id TELEGRAM_BOT_CHATID yet." + return 1 + fi + _saveaccountconf_mutable TELEGRAM_BOT_CHATID "$TELEGRAM_BOT_CHATID" + + _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" + _data="{\"text\": \"$_content\", " + _data="$_data\"chat_id\": \"$TELEGRAM_BOT_CHATID\", " + _data="$_data\"parse_mode\": \"markdown\", " + _data="$_data\"disable_web_page_preview\": \"1\"}" + + export _H1="Content-Type: application/json" + _telegram_bot_url="https://api.telegram.org/bot${TELEGRAM_BOT_APITOKEN}/sendMessage" + if _post "$_data" "$_telegram_bot_url"; then + # shellcheck disable=SC2154 + _message=$(printf "%s\n" "$response" | sed -ne 's/.*"ok":\([^,]*\).*/\1/p') + if [ "$_message" = "true" ]; then + _info "telegram send success." + return 0 + fi + fi + _err "telegram send error." + _err "$response" + return 1 +} From c59a8c9644b366f9c8ca17d7bd28a25de66a1799 Mon Sep 17 00:00:00 2001 From: Vahid Fardi Date: Tue, 5 Jan 2021 15:29:08 +0330 Subject: [PATCH 1162/2234] change arvan api script --- dnsapi/dns_arvan.sh | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index ca1f56c7..3c4ced15 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -3,7 +3,6 @@ #Arvan_Token="xxxx" ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" - #Author: Ehsan Aliakbar #Report Bugs here: https://github.com/Neilpang/acme.sh # @@ -38,6 +37,7 @@ dns_arvan_add() { _info "Adding record" if _arvan_rest POST "$_domain/dns-records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":{\"text\":\"$txtvalue\"},\"ttl\":120}"; then if _contains "$response" "$txtvalue"; then + _info "response id is $response" _info "Added, OK" return 0 elif _contains "$response" "Record Data is Duplicated"; then @@ -49,7 +49,7 @@ dns_arvan_add() { fi fi _err "Add txt record error." - return 1 + return 0 } #Usage: fulldomain txtvalue @@ -73,33 +73,21 @@ dns_arvan_rm() { _debug _domain "$_domain" _debug "Getting txt records" - shorted_txtvalue=$(printf "%s" "$txtvalue" | cut -d "-" -d "_" -f1) - _arvan_rest GET "${_domain}/dns-records?search=$shorted_txtvalue" - + _arvan_rest GET "${_domain}/dns-records" if ! printf "%s" "$response" | grep \"current_page\":1 >/dev/null; then _err "Error on Arvan Api" _err "Please create a github issue with debbug log" return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"total\":[^,]*" | cut -d : -f 2) - _debug count "$count" - if [ "$count" = "0" ]; then - _info "Don't need to remove." - else - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) - _debug "record_id" "$record_id" - if [ -z "$record_id" ]; then - _err "Can not get record id to remove." - return 1 - fi - if ! _arvan_rest "DELETE" "${_domain}/dns-records/$record_id"; then - _err "Delete record error." - return 1 - fi - _debug "$response" - _contains "$response" 'dns record deleted' + _record_id=$(echo "$response" | _egrep_o ".\"id\":\"[^\"]*\",\"type\":\"txt\",\"name\":\"_acme-challenge\",\"value\":{\"text\":\"$txtvalue\"}" | cut -d : -f 2 | cut -d , -f 1 | tr -d \") + if ! _arvan_rest "DELETE" "${_domain}/dns-records/${_record_id}"; then + _err "Error on Arvan Api" + return 1 fi + _debug "$response" + _contains "$response" 'dns record deleted' + return 0 } #################### Private functions below ################################## @@ -111,7 +99,7 @@ dns_arvan_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 - i=1 + i=2 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -121,12 +109,11 @@ _get_root() { return 1 fi - if ! _arvan_rest GET "?search=$h"; then + if ! _arvan_rest GET "$h"; then return 1 fi - - if _contains "$response" "\"domain\":\"$h\"" || _contains "$response" '"total":1'; then - _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if _contains "$response" "\"domain\":\"$h\""; then + _domain_id=$(echo "$response" | cut -d : -f 3 | cut -d , -f 1 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -146,7 +133,6 @@ _arvan_rest() { data="$3" token_trimmed=$(echo "$Arvan_Token" | tr -d '"') - export _H1="Authorization: $token_trimmed" if [ "$mtd" = "DELETE" ]; then @@ -160,4 +146,5 @@ _arvan_rest() { else response="$(_get "$ARVAN_API_URL/$ep$data")" fi + return 0 } From 2ec6215b1cbac352c006797ac8ed25f5cf7b50ac Mon Sep 17 00:00:00 2001 From: Vahid Fardi Date: Tue, 5 Jan 2021 17:10:41 +0330 Subject: [PATCH 1163/2234] change Author name --- dnsapi/dns_arvan.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 3c4ced15..a33504d0 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -1,10 +1,10 @@ #!/usr/bin/env sh -#Arvan_Token="xxxx" +#Arvan_Token="Apikey xxxx" ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" -#Author: Ehsan Aliakbar -#Report Bugs here: https://github.com/Neilpang/acme.sh +#Author: Vahid Fardi +#Report Bugs here: https://github.com/fvahid/acme.sh # ######## Public functions ##################### From d9a8b057c39baeb89d257484d867112fc09db0b6 Mon Sep 17 00:00:00 2001 From: Vahid Fardi Date: Tue, 5 Jan 2021 21:31:31 +0330 Subject: [PATCH 1164/2234] change name actor --- dnsapi/dns_arvan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index a33504d0..4c9217e5 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -4,7 +4,7 @@ ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" #Author: Vahid Fardi -#Report Bugs here: https://github.com/fvahid/acme.sh +#Report Bugs here: https://github.com/Neilpang/acme.sh # ######## Public functions ##################### From ab6b9006b7bdf42ee270646da58658a3762a617d Mon Sep 17 00:00:00 2001 From: James Edington Date: Fri, 8 Jan 2021 11:14:39 -0700 Subject: [PATCH 1165/2234] This is a general-purpose ACME client. We should be proud of this. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cd747666..f53578d4 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ https://github.com/acmesh-official/acmetest - [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA) - [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) +- Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA # Supported modes From c3a3d02beaaec48cf3caa041659c2390613c7503 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 10 Jan 2021 11:47:54 +0800 Subject: [PATCH 1166/2234] fix https://github.com/acmesh-official/acme.sh/issues/3156 --- dnsapi/dns_linode_v4.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index c2bebc57..9504afbf 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -106,6 +106,7 @@ dns_linode_v4_rm() { #################### Private functions below ################################## _Linode_API() { + LINODE_V4_API_KEY="${LINODE_V4_API_KEY:-$(_readaccountconf_mutable LINODE_V4_API_KEY)}" if [ -z "$LINODE_V4_API_KEY" ]; then LINODE_V4_API_KEY="" @@ -115,7 +116,7 @@ _Linode_API() { return 1 fi - _saveaccountconf LINODE_V4_API_KEY "$LINODE_V4_API_KEY" + _saveaccountconf_mutable LINODE_V4_API_KEY "$LINODE_V4_API_KEY" } #################### Private functions below ################################## From 1fff8dd30691e4808cded2e84ce0a3f41e89281b Mon Sep 17 00:00:00 2001 From: tyahin Date: Sun, 10 Jan 2021 12:39:12 +0300 Subject: [PATCH 1167/2234] deploy gcore_cdn fix auth --- deploy/gcore_cdn.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index a2a35f7b..738f8561 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -56,9 +56,9 @@ gcore_cdn_deploy() { _request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}" _debug _request "$_request" export _H1="Content-Type:application/json" - _response=$(_post "$_request" "https://api.gcdn.co/auth/signin") + _response=$(_post "$_request" "https://api.gcdn.co/auth/jwt/login") _debug _response "$_response" - _regex=".*\"token\":\"\([-._0-9A-Za-z]*\)\".*$" + _regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$" _debug _regex "$_regex" _token=$(echo "$_response" | sed -n "s/$_regex/\1/p") _debug _token "$_token" From 1eaf7c89b7c11703c9f49df91c85fe0f3b537225 Mon Sep 17 00:00:00 2001 From: tyahin Date: Sun, 10 Jan 2021 12:39:20 +0300 Subject: [PATCH 1168/2234] deploy gcore_cdn fix api --- deploy/gcore_cdn.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 738f8561..929a4d53 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -72,12 +72,15 @@ gcore_cdn_deploy() { export _H2="Authorization:Token $_token" _response=$(_get "https://api.gcdn.co/resources") _debug _response "$_response" - _regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})" + _regex="\"primary_resource\":null}," + _debug _regex "$_regex" + _response=$(echo "$_response" | sed 's/$_regex/$_regex\n/g') + _debug _response "$_response" _regex="^.*\"cname\":\"$_cdomain\".*$" _debug _regex "$_regex" - _resource=$(echo "$_response" | sed 's/},{/},\n{/g' | _egrep_o "$_regex") + _resource=$(echo "$_response" | _egrep_o "$_regex") _debug _resource "$_resource" - _regex=".*\"id\":\([0-9]*\).*\"rules\".*$" + _regex=".*\"id\":\([0-9]*\).*$" _debug _regex "$_regex" _resourceId=$(echo "$_resource" | sed -n "s/$_regex/\1/p") _debug _resourceId "$_resourceId" From 7ed7a57d926c913adc7f05905ffb5412d170e09b Mon Sep 17 00:00:00 2001 From: tyahin Date: Sun, 10 Jan 2021 12:44:56 +0300 Subject: [PATCH 1169/2234] deploy gcore_cdn fix syntax --- deploy/gcore_cdn.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index 929a4d53..f573a3aa 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -74,7 +74,7 @@ gcore_cdn_deploy() { _debug _response "$_response" _regex="\"primary_resource\":null}," _debug _regex "$_regex" - _response=$(echo "$_response" | sed 's/$_regex/$_regex\n/g') + _response=$(echo "$_response" | sed "s/$_regex/$_regex\n/g") _debug _response "$_response" _regex="^.*\"cname\":\"$_cdomain\".*$" _debug _regex "$_regex" From b79f63db7841d7344a7360b1c7068d98b6419c9b Mon Sep 17 00:00:00 2001 From: Stephen Dendtler Date: Sun, 10 Jan 2021 11:19:16 +0000 Subject: [PATCH 1170/2234] Added RackCorp API Integration --- dnsapi/dns_rackcorp.sh | 156 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 dnsapi/dns_rackcorp.sh diff --git a/dnsapi/dns_rackcorp.sh b/dnsapi/dns_rackcorp.sh new file mode 100644 index 00000000..7323473d --- /dev/null +++ b/dnsapi/dns_rackcorp.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env sh + +# Provider: RackCorp (www.rackcorp.com) +# Author: Stephen Dendtler (sdendtler@rackcorp.com) +# Report Bugs here: https://github.com/senjoo/acme.sh +# Alternate email contact: support@rackcorp.com +# +# You'll need an API key (Portal: ADMINISTRATION -> API) +# Set the environment variables as below: +# +# export RACKCORP_APIUUID="UUIDHERE" +# export RACKCORP_APISECRET="SECRETHERE" +# + +RACKCORP_API_ENDPOINT="https://api.rackcorp.net/api/rest/v2.4/json.php" + +######## Public functions ##################### + +dns_rackcorp_add() { + fulldomain="$1" + txtvalue="$2" + + _debug fulldomain="$fulldomain" + _debug txtvalue="$txtvalue" + + if ! _rackcorp_validate; then + return 1 + fi + + _debug "Searching for root zone" + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _lookup "$_lookup" + _debug _domain "$_domain" + + _info "Creating TXT record." + + if ! _rackcorp_api dns.record.create "\"name\":\"$_domain\",\"type\":\"TXT\",\"lookup\":\"$_lookup\",\"data\":\"$txtvalue\",\"ttl\":300"; then + return 1 + fi + + return 0 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_rackcorp_rm() { + fulldomain=$1 + txtvalue=$2 + + _debug fulldomain="$fulldomain" + _debug txtvalue="$txtvalue" + + if ! _rackcorp_validate; then + return 1 + fi + + _debug "Searching for root zone" + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _lookup "$_lookup" + _debug _domain "$_domain" + + _info "Creating TXT record." + + if ! _rackcorp_api dns.record.delete "\"name\":\"$_domain\",\"type\":\"TXT\",\"lookup\":\"$_lookup\",\"data\":\"$txtvalue\""; then + return 1 + fi + + return 0 +} + +#################### Private functions below ################################## +#_acme-challenge.domain.com +#returns +# _lookup=_acme-challenge +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + if ! _rackcorp_api dns.domain.getall "\"name\":\"$domain\""; then + return 1 + fi + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug searchhost "$h" + if [ -z "$h" ]; then + _err "Could not find domain for record $domain in RackCorp using the provided credentials" + #not valid + return 1 + fi + + _rackcorp_api dns.domain.getall "\"exactName\":\"$h\"" + + if _contains "$response" "\"matches\":1"; then + if _contains "$response" "\"name\":\"$h\""; then + _lookup=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + fi + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} + +_rackcorp_validate() { + RACKCORP_APIUUID="${RACKCORP_APIUUID:-$(_readaccountconf_mutable RACKCORP_APIUUID)}" + if [ -z "$RACKCORP_APIUUID" ]; then + RACKCORP_APIUUID="" + _err "You require a RackCorp API UUID (export RACKCORP_APIUUID=\"\")" + _err "Please login to the portal and create an API key and try again." + return 1 + fi + + _saveaccountconf_mutable RACKCORP_APIUUID "$RACKCORP_APIUUID" + + RACKCORP_APISECRET="${RACKCORP_APISECRET:-$(_readaccountconf_mutable RACKCORP_APISECRET)}" + if [ -z "$RACKCORP_APISECRET" ]; then + RACKCORP_APISECRET="" + _err "You require a RackCorp API secret (export RACKCORP_APISECRET=\"\")" + _err "Please login to the portal and create an API key and try again." + return 1 + fi + + _saveaccountconf_mutable RACKCORP_APISECRET "$RACKCORP_APISECRET" + + return 0 +} +_rackcorp_api() { + _rackcorpcmd=$1 + _rackcorpinputdata=$2 + _debug cmd "$_rackcorpcmd $_rackcorpinputdata" + + export _H1="Accept: application/json" + response="$(_post "{\"APIUUID\":\"$RACKCORP_APIUUID\",\"APISECRET\":\"$RACKCORP_APISECRET\",\"cmd\":\"$_rackcorpcmd\",$_rackcorpinputdata}" "$RACKCORP_API_ENDPOINT" "" "POST")" + + if [ "$?" != "0" ]; then + _err "error $response" + return 1 + fi + _debug2 response "$response" + if _contains "$response" "\"code\":\"OK\""; then + _debug code "OK" + else + _debug code "FAILED" + response="" + return 1 + fi + return 0 +} From 2e5a6e21cf27533fc772ca525c8a900e0c20f04c Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Mon, 11 Jan 2021 11:21:46 +1300 Subject: [PATCH 1171/2234] Correct shebang --- notify/telegram.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/telegram.sh b/notify/telegram.sh index ee2d93e2..2806206d 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env sh #Support Telegram Bots From 584cc6de2e0b465749eaf477c2a33f6843e2840a Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Mon, 11 Jan 2021 11:27:39 +1300 Subject: [PATCH 1172/2234] Avoid usage of sed -e --- notify/telegram.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/telegram.sh b/notify/telegram.sh index 2806206d..b1306ee1 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -37,7 +37,7 @@ telegram_send() { _telegram_bot_url="https://api.telegram.org/bot${TELEGRAM_BOT_APITOKEN}/sendMessage" if _post "$_data" "$_telegram_bot_url"; then # shellcheck disable=SC2154 - _message=$(printf "%s\n" "$response" | sed -ne 's/.*"ok":\([^,]*\).*/\1/p') + _message=$(printf "%s\n" "$response" | sed -n 's/.*"ok":\([^,]*\).*/\1/p') if [ "$_message" = "true" ]; then _info "telegram send success." return 0 From 500a005aacdee63d7fec6b1b78e97493657fa9ba Mon Sep 17 00:00:00 2001 From: Stephen Dendtler Date: Mon, 11 Jan 2021 13:03:42 +0000 Subject: [PATCH 1173/2234] _get_root now does not skip the first label of the domain --- dnsapi/dns_rackcorp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_rackcorp.sh b/dnsapi/dns_rackcorp.sh index 7323473d..6aabfddc 100644 --- a/dnsapi/dns_rackcorp.sh +++ b/dnsapi/dns_rackcorp.sh @@ -79,7 +79,7 @@ dns_rackcorp_rm() { # _domain=domain.com _get_root() { domain=$1 - i=2 + i=1 p=1 if ! _rackcorp_api dns.domain.getall "\"name\":\"$domain\""; then return 1 From 61549b4a745f45ec44335d9d2074b043acf8a559 Mon Sep 17 00:00:00 2001 From: Mark Challoner Date: Wed, 6 Jan 2021 20:20:21 +0000 Subject: [PATCH 1174/2234] Add Peplink deploy hook --- deploy/peplink.sh | 123 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 deploy/peplink.sh diff --git a/deploy/peplink.sh b/deploy/peplink.sh new file mode 100644 index 00000000..c4bd6242 --- /dev/null +++ b/deploy/peplink.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env sh + +# Script to deploy cert to Peplink Routers +# +# The following environment variables must be set: +# +# PEPLINK_Hostname - Peplink hostname +# PEPLINK_Username - Peplink username to login +# PEPLINK_Password - Peplink password to login +# +# The following environmental variables may be set if you don't like their +# default values: +# +# PEPLINK_Certtype - Certificate type to target for replacement +# defaults to "webadmin", can be one of: +# * "chub" (ContentHub) +# * "openvpn" (OpenVPN CA) +# * "portal" (Captive Portal SSL) +# * "webadmin" (Web Admin SSL) +# * "webproxy" (Proxy Root CA) +# * "wwan_ca" (Wi-Fi WAN CA) +# * "wwan_client" (Wi-Fi WAN Client) +# PEPLINK_Scheme - defaults to "https" +# PEPLINK_Port - defaults to "443" +# +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +_peplink_get_cookie_data() { + grep -i "\W$1=" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' +} + +#domain keyfile certfile cafile fullchain +peplink_deploy() { + + _cdomain="$1" + _ckey="$2" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _cfullchain "$_cfullchain" + _debug _ckey "$_ckey" + + # Get Hostname, Username and Password, but don't save until we successfully authenticate + _getdeployconf PEPLINK_Hostname + _getdeployconf PEPLINK_Username + _getdeployconf PEPLINK_Password + if [ -z "${PEPLINK_Hostname:-}" ] || [ -z "${PEPLINK_Username:-}" ] || [ -z "${PEPLINK_Password:-}" ]; then + _err "PEPLINK_Hostname & PEPLINK_Username & PEPLINK_Password must be set" + return 1 + fi + _debug2 PEPLINK_Hostname "$PEPLINK_Hostname" + _debug2 PEPLINK_Username "$PEPLINK_Username" + _secure_debug2 PEPLINK_Password "$PEPLINK_Password" + + # Optional certificate type, scheme, and port for Peplink + _getdeployconf PEPLINK_Certtype + _getdeployconf PEPLINK_Scheme + _getdeployconf PEPLINK_Port + + # Don't save the certificate type until we verify it exists and is supported + _savedeployconf PEPLINK_Scheme "$PEPLINK_Scheme" + _savedeployconf PEPLINK_Port "$PEPLINK_Port" + + # Default vaules for certificate type, scheme, and port + [ -n "${PEPLINK_Certtype}" ] || PEPLINK_Certtype="webadmin" + [ -n "${PEPLINK_Scheme}" ] || PEPLINK_Scheme="https" + [ -n "${PEPLINK_Port}" ] || PEPLINK_Port="443" + + _debug2 PEPLINK_Certtype "$PEPLINK_Certtype" + _debug2 PEPLINK_Scheme "$PEPLINK_Scheme" + _debug2 PEPLINK_Port "$PEPLINK_Port" + + _base_url="$PEPLINK_Scheme://$PEPLINK_Hostname:$PEPLINK_Port" + _debug _base_url "$_base_url" + + # Login, get the auth token from the cookie + _info "Logging into $PEPLINK_Hostname:$PEPLINK_Port" + encoded_username="$(printf "%s" "$PEPLINK_Username" | _url_encode)" + encoded_password="$(printf "%s" "$PEPLINK_Password" | _url_encode)" + response=$(_post "func=login&username=$encoded_username&password=$encoded_password" "$_base_url/cgi-bin/MANGA/api.cgi") + auth_token=$(_peplink_get_cookie_data "bauth" <"$HTTP_HEADER") + _debug3 response "$response" + _debug auth_token "$auth_token" + + if [ -z "$auth_token" ]; then + _err "Unable to authenticate to $PEPLINK_Hostname:$PEPLINK_Port using $PEPLINK_Scheme." + _err "Check your username and password." + return 1 + fi + + _H1="Cookie: $auth_token" + export _H1 + _debug2 H1 "${_H1}" + + # Now that we know the hostnameusername and password are good, save them + _savedeployconf PEPLINK_Hostname "$PEPLINK_Hostname" + _savedeployconf PEPLINK_Username "$PEPLINK_Username" + _savedeployconf PEPLINK_Password "$PEPLINK_Password" + + _info "Generate form POST request" + + encoded_key="$(_url_encode <"$_ckey")" + encoded_fullchain="$(_url_encode <"$_cfullchain")" + body="cert_type=$PEPLINK_Certtype&cert_uid=§ion=CERT_modify&key_pem=$encoded_key&key_pem_passphrase=&key_pem_passphrase_confirm=&cert_pem=$encoded_fullchain" + _debug3 body "$body" + + _info "Upload $PEPLINK_Certtype certificate to the Peplink" + + response=$(_post "$body" "$_base_url/cgi-bin/MANGA/admin.cgi") + _debug3 response "$response" + + if echo "$response" | grep 'Success' >/dev/null; then + # We've verified this certificate type is valid, so save it + _savedeployconf PEPLINK_Certtype "$PEPLINK_Certtype" + _info "Certificate was updated" + return 0 + else + _err "Unable to update certificate, error code $response" + return 1 + fi +} From 464022bea23fd5d8bdd219f5e033a86ab918c966 Mon Sep 17 00:00:00 2001 From: pssara Date: Fri, 15 Jan 2021 15:12:53 +0100 Subject: [PATCH 1175/2234] Fixed issue with ISP config where the Client ID was asumed to be the same as the SYS User ID --- dnsapi/dns_ispconfig.sh | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index bd1e0391..8be47f60 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -75,7 +75,7 @@ _ISPC_getZoneInfo() { # suffix . needed for zone -> domain.tld. curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"origin\":\"${curZone}.\"}}" curResult="$(_post "${curData}" "${ISPC_Api}?dns_zone_get")" - _debug "Calling _ISPC_getZoneInfo: '${curData}' '${ISPC_Api}?login'" + _debug "Calling _ISPC_getZoneInfo: '${curData}' '${ISPC_Api}?dns_zone_get'" _debug "Result of _ISPC_getZoneInfo: '$curResult'" if _contains "${curResult}" '"id":"'; then zoneFound=true @@ -110,18 +110,32 @@ _ISPC_getZoneInfo() { ;; *) _info "Retrieved Zone ID" ;; esac - client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2) - _debug "Client ID: '${client_id}'" - case "${client_id}" in + sys_userid=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + _debug "SYS User ID: '${sys_userid}'" + case "${sys_userid}" in '' | *[!0-9]*) - _err "Client ID is not numeric." + _err "SYS User ID is not numeric." return 1 ;; - *) _info "Retrieved Client ID." ;; + *) _info "Retrieved SYS User ID." ;; esac zoneFound="" zoneEnd="" fi + # Need to get client_id as it is different from sys_userid + curData="{\"session_id\":\"${sessionID}\",\"sys_userid\":\"${sys_userid}\"}" + curResult="$(_post "${curData}" "${ISPC_Api}?client_get_id")" + _debug "Calling _ISPC_ClientGetID: '${curData}' '${ISPC_Api}?client_get_id'" + _debug "Result of _ISPC_ClientGetID: '$curResult'" + client_id=$(echo "${curResult}" | _egrep_o "response.*" | cut -d ':' -f 2 | cut -d '"' -f 2 | tr -d '{}') + _debug "Client ID: '${client_id}'" + case "${client_id}" in + '' | *[!0-9]*) + _err "Client ID is not numeric." + return 1 + ;; + *) _info "Retrieved Client ID." ;; + esac } _ISPC_addTxt() { From 289f79bbb0dda768ec23e89e178adbf8af43112f Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 16 Jan 2021 23:50:57 +0800 Subject: [PATCH 1176/2234] fix format --- dnsapi/dns_ispconfig.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 8be47f60..e68ddd49 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -130,11 +130,11 @@ _ISPC_getZoneInfo() { client_id=$(echo "${curResult}" | _egrep_o "response.*" | cut -d ':' -f 2 | cut -d '"' -f 2 | tr -d '{}') _debug "Client ID: '${client_id}'" case "${client_id}" in - '' | *[!0-9]*) + '' | *[!0-9]*) _err "Client ID is not numeric." return 1 ;; - *) _info "Retrieved Client ID." ;; + *) _info "Retrieved Client ID." ;; esac } From d21e6235ad9df9df9452c08617728aaf55fae559 Mon Sep 17 00:00:00 2001 From: Lukas Brocke Date: Mon, 18 Jan 2021 14:35:08 +0100 Subject: [PATCH 1177/2234] dnsapi/ionos: Add support for v2 wildcard certificates --- dnsapi/dns_ionos.sh | 47 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index fb6ba3f8..a8cc36cf 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -20,9 +20,22 @@ dns_ionos_add() { fulldomain=$1 txtvalue=$2 - _ionos_init + if ! _ionos_init; then + return 1 + fi - _body="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}" + _new_record="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}" + + # As no POST route is supported by the API, check for existing records and include them in the PATCH request in order not delete them. + # This is required to support ACME v2 wildcard certificate creation, where two TXT records for the same domain name are created. + + _ionos_get_existing_records "$fulldomain" "$_zone_id" + + if [ "$_existing_records" ]; then + _body="[$_new_record,$_existing_records]" + else + _body="[$_new_record]" + fi if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then _info "TXT record has been created successfully." @@ -36,9 +49,11 @@ dns_ionos_rm() { fulldomain=$1 txtvalue=$2 - _ionos_init + if ! _ionos_init; then + return 1 + fi - if ! _ionos_get_record "$fulldomain" "$_zone_id"; then + if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then _err "Could not find _acme-challenge TXT record." return 1 fi @@ -81,7 +96,7 @@ _get_root() { p=1 if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then - response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" + response="$(echo "$response" | tr -d "\n")" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -89,9 +104,9 @@ _get_root() { return 1 fi - _zone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")" + _zone="$(echo "$response" | _egrep_o "\"name\":\"$h\".*?}")" if [ "$_zone" ]; then - _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + _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 _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -110,16 +125,28 @@ _get_root() { return 1 } -_ionos_get_record() { +_ionos_get_existing_records() { fulldomain=$1 zone_id=$2 if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then response="$(echo "$response" | tr -d "\n")" - _record="$(echo "$response" | _egrep_o "{\"name\":\s*\"$fulldomain\".*}")" + _existing_records="$(printf "%s\n" "$response" | _egrep_o "\"records\":\[.*?\]" | _head_n 1 | cut -d '[' -f 2 | sed 's/]//')" + fi +} + +_ionos_get_record() { + fulldomain=$1 + zone_id=$2 + txtrecord=$3 + + if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then + response="$(echo "$response" | tr -d "\n")" + + _record="$(echo "$response" | _egrep_o "\{\"name\":\"$fulldomain\"[^\}]*?\"type\":\"TXT\"[^\}]*?\"content\":\"\\\\\"$txtrecord\\\\\"\".*?\}")" if [ "$_record" ]; then - _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') return 0 fi From a9d88301064698558ebecc7d45b6e7edad61945a Mon Sep 17 00:00:00 2001 From: Lukas Brocke Date: Wed, 20 Jan 2021 21:08:58 +0100 Subject: [PATCH 1178/2234] dnsapi/ionos: Fixes for Solaris --- dnsapi/dns_ionos.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index a8cc36cf..54696d5d 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -104,9 +104,9 @@ _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 '\"') + _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 _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -132,7 +132,7 @@ _ionos_get_existing_records() { if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then response="$(echo "$response" | tr -d "\n")" - _existing_records="$(printf "%s\n" "$response" | _egrep_o "\"records\":\[.*?\]" | _head_n 1 | cut -d '[' -f 2 | sed 's/]//')" + _existing_records="$(printf "%s\n" "$response" | _egrep_o "\"records\":\[.*\]" | _head_n 1 | cut -d '[' -f 2 | sed 's/]//')" fi } @@ -144,9 +144,9 @@ _ionos_get_record() { if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then 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 '\"') + _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') return 0 fi From 5fbbc17376e7a248f35e191cca8053ca521ce88c Mon Sep 17 00:00:00 2001 From: MaysWind Date: Thu, 21 Jan 2021 22:15:23 +0800 Subject: [PATCH 1179/2234] update dnspod.com api --- dnsapi/dns_dpi.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_dpi.sh b/dnsapi/dns_dpi.sh index 9cbf4d51..2955effd 100755 --- a/dnsapi/dns_dpi.sh +++ b/dnsapi/dns_dpi.sh @@ -53,7 +53,7 @@ dns_dpi_rm() { return 1 fi - if ! _rest POST "Record.List" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain"; then + if ! _rest POST "Record.List" "login_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain"; then _err "Record.Lis error." return 1 fi @@ -63,14 +63,14 @@ dns_dpi_rm() { return 0 fi - record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'"$txtvalue"'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \") + record_id=$(echo "$response" | tr "{" "\n" | grep -- "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2) _debug record_id "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id." return 1 fi - if ! _rest POST "Record.Remove" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then + if ! _rest POST "Record.Remove" "login_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then _err "Record.Remove error." return 1 fi @@ -89,7 +89,7 @@ add_record() { _info "Adding record" - if ! _rest POST "Record.Create" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=default"; then + if ! _rest POST "Record.Create" "login_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=default"; then return 1 fi @@ -113,7 +113,7 @@ _get_root() { return 1 fi - if ! _rest POST "Domain.Info" "user_token=$DPI_Id,$DPI_Key&format=json&domain=$h"; then + if ! _rest POST "Domain.Info" "login_token=$DPI_Id,$DPI_Key&format=json&domain=$h"; then return 1 fi From f06aee21ebf9af3cfd49deb8a61f875eb3839738 Mon Sep 17 00:00:00 2001 From: Lukas Brocke Date: Thu, 21 Jan 2021 16:10:10 +0100 Subject: [PATCH 1180/2234] dnsapi/ionos: Change to root zone finding algorithm --- dnsapi/dns_ionos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 54696d5d..e6bd5000 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -92,7 +92,7 @@ _ionos_init() { _get_root() { domain=$1 - i=2 + i=1 p=1 if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then From f49e8ec5adb392f5abf1b7f60039cc80eac3f8f8 Mon Sep 17 00:00:00 2001 From: dgasaway Date: Mon, 25 Jan 2021 11:46:52 -0800 Subject: [PATCH 1181/2234] Change ipconfig.co to ifconfig.co URL https://ipconfig.co/ip does not currently work, and since https://ifconfig.co/ip is mentioned on the DNS API wiki page, I assume these messages were a typo. --- 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 2e389265..7ce39fa9 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -157,7 +157,7 @@ _namecheap_set_publicip() { if [ -z "$NAMECHEAP_SOURCEIP" ]; then _err "No Source IP specified for Namecheap API." - _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" + _err "Use your public ip address or an url to retrieve it (e.g. https://ifconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" return 1 else _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP" @@ -175,7 +175,7 @@ _namecheap_set_publicip() { _publicip=$(_get "$addr") else _err "No Source IP specified for Namecheap API." - _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" + _err "Use your public ip address or an url to retrieve it (e.g. https://ifconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" return 1 fi fi From 9366f4b40e2d2d557e458e98ecd0407edc381678 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Mon, 25 Jan 2021 21:55:07 +0100 Subject: [PATCH 1182/2234] Test original implementation by trgosk --- dnsapi/dns_websupport.sh | 208 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 dnsapi/dns_websupport.sh diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh new file mode 100644 index 00000000..1332a0aa --- /dev/null +++ b/dnsapi/dns_websupport.sh @@ -0,0 +1,208 @@ +#!/usr/bin/env sh + +#This is the websupport.sk api wrapper for acme.sh +# +#Author: trgo.sk +#Report Bugs here: https://github.com/trgosk/acme.sh + +#WS_ApiKey="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +#WS_ApiSecret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +WS_Api="https://rest.websupport.sk" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_websupport_add() { + fulldomain=$1 + txtvalue=$2 + + WS_ApiKey="${WS_ApiKey:-$(_readaccountconf_mutable WS_ApiKey)}" + WS_ApiSecret="${WS_ApiSecret:-$(_readaccountconf_mutable WS_ApiSecret)}" + + if [ "$WS_ApiKey" ] && [ "$WS_ApiSecret" ]; then + _saveaccountconf_mutable WS_ApiKey "$WS_ApiKey" + _saveaccountconf_mutable WS_ApiSecret "$WS_ApiSecret" + else + WS_ApiKey="" + WS_ApiSecret="" + _err "You didn't specify a api key and/or api secret yet." + _err "You can get yours from here https://admin.websupport.sk/en/auth/apiKey" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so + # we can not use updating anymore. + # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + # _debug count "$count" + # if [ "$count" = "0" ]; then + _info "Adding record" + if _ws_rest POST "/v1/user/self/zone/$_domain/record" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + return 0 + elif _contains "$response" "The record already exists"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_websupport_rm() { + fulldomain=$1 + txtvalue=$2 + + _debug2 fulldomain "$fulldomain" + _debug2 txtvalue "$txtvalue" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _ws_rest GET "/v1/user/self/zone/$_domain/record" + + if [ "$(printf "%s" "$response" | tr -d " " | grep -c \"items\")" -lt "1" ]; then + _err "Error: $response" + return 1 + fi + + record_line="$(_get_from_array "$response" "$txtvalue")" + _debug record_line "$record_line" + if [ -z "$record_line" ]; then + _info "Don't need to remove." + else + record_id=$(echo "$record_line" | _egrep_o "\"id\": *[^,]*" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ") + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _ws_rest DELETE "/v1/user/self/zone/$_domain/record/$record_id"; then + _err "Delete record error." + return 1 + fi + if [ "$(printf "%s" "$response" | tr -d " " | grep -c \"success\")" -lt "1" ]; then + return 1 + else + return 0 + fi + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _ws_rest GET "/v1/user/self/zone"; then + return 1 + fi + + if _contains "$response" "\"name\":\"$h\""; then + _domain_id=$(echo "$response" | _egrep_o "\[.\"id\": *[^,]*" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_ws_rest() { + me=$1 + pa="$2" + da="$3" + + _debug2 api_key "$WS_ApiKey" + _debug2 api_secret "$WS_ApiSecret" + + timestamp="$(date +%s)" + datez=$(date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -d@"$timestamp" +%Y-%m-%dT%H:%M:%S%z) + canonical_request="${me} ${pa} ${timestamp}" + alg="sha1" + signature_hash=$( (printf "%s" "$canonical_request" | ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -mac HMAC -macopt "key:$WS_ApiSecret" 2>/dev/null || printf "%s" "$canonical_request" | ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -hmac "$(printf "%s" "$WS_ApiSecret" | _h2b)") | cut -d = -f 2 | tr -d ' ') + basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" + + _debug2 method "$me" + _debug2 path "$pa" + _debug2 data "$da" + _debug2 timestamp "$timestamp" + _debug2 datez "$datez" + _debug2 canonical_request "$canonical_request" + _debug2 alg "$alg" + _debug2 signature_hash "$signature_hash" + _debug2 basicauth "$basicauth" + + export _H1="Accept: application/json" + export _H2="Content-Type: application/json" + export _H3="Authorization: Basic ${basicauth}" + export _H4="Date: ${datez}" + + _debug2 H1 "$_H1" + _debug2 H2 "$_H2" + _debug2 H3 "$_H3" + _debug2 H4 "$_H4" + + if [ "$me" != "GET" ]; then + _debug2 "${me} $WS_Api${pa}" + _debug data "$da" + response="$(_post "$da" "${WS_Api}${pa}" "" "$me")" + else + _debug2 "GET $WS_Api${pa}" + response="$(_get "$WS_Api${pa}")" + fi + + _debug2 response "$response" + return "$?" +} + +_get_from_array() { + va="$1" + fi="$2" + for i in $(echo "$va" | sed "s/{/ /g"); do + if _contains "$i" "$fi"; then + echo "$i" + break + fi + done +} From 92332fc385e288cd478218b7969238151cf4bcec Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Mon, 25 Jan 2021 22:01:41 +0100 Subject: [PATCH 1183/2234] Update dns_websupport.sh --- dnsapi/dns_websupport.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 1332a0aa..407e3485 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -206,3 +206,4 @@ _get_from_array() { fi done } + From 4956a580266240090ee777f9ffc5fd7a07991dca Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Mon, 25 Jan 2021 22:10:27 +0100 Subject: [PATCH 1184/2234] Update dns_websupport.sh --- dnsapi/dns_websupport.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 407e3485..1332a0aa 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -206,4 +206,3 @@ _get_from_array() { fi done } - From 77e8008752b02c2bcb3b8387df7975aef0748207 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 26 Jan 2021 22:10:53 +0800 Subject: [PATCH 1185/2234] fix docker build (#3383) * fix dockerhub * fix Co-authored-by: neil --- .github/workflows/dockerhub.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 89915af7..238fde3a 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -33,12 +33,10 @@ jobs: steps: - name: checkout code uses: actions/checkout@v2 - - name: install buildx - id: buildx - uses: crazy-max/ghaction-docker-buildx@v3 - with: - buildx-version: latest - qemu-version: latest + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 - name: login to docker hub run: | echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin From 58c4eaaf861fe6909b2ed766a8cd1c2be2b6e8d4 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 30 Jan 2021 11:27:18 +0800 Subject: [PATCH 1186/2234] fix online install (#3385) --- acme.sh | 59 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/acme.sh b/acme.sh index e78744c9..0d3a9e8c 100755 --- a/acme.sh +++ b/acme.sh @@ -6105,7 +6105,7 @@ _installalias() { } -# nocron confighome noprofile +# nocron confighome noprofile accountemail install() { if [ -z "$LE_WORKING_DIR" ]; then @@ -6115,6 +6115,8 @@ install() { _nocron="$1" _c_home="$2" _noprofile="$3" + _accountemail="$4" + if ! _initpath; then _err "Install failed." return 1 @@ -6233,6 +6235,10 @@ install() { fi fi + if [ "$_accountemail" ]; then + _saveaccountconf "ACCOUNT_EMAIL" "$_accountemail" + fi + _info OK } @@ -6511,7 +6517,7 @@ Parameters: --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. --config-home Specifies the home dir to save all the configurations. --useragent Specifies the user agent string. it will be saved for future use too. - -m, --accountemail Specifies the account email, only valid for the '--install' and '--update-account' command. + -m, --email Specifies the account email, only valid for the '--install' and '--update-account' command. --accountkey Specifies the account key path, only valid for the '--install' command. --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. @@ -6522,9 +6528,9 @@ Parameters: --insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted. --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. - --nocron Only valid for '--install' command, which means: do not install the default cron job. + --no-cron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. - --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. + --no-profile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--to-pkcs12' and '--create-csr' @@ -6562,18 +6568,18 @@ Parameters: " } -# nocron noprofile -_installOnline() { + +installOnline() { _info "Installing from online archive." - _nocron="$1" - _noprofile="$2" - if [ ! "$BRANCH" ]; then - BRANCH="master" + + _branch="$BRANCH" + if [ -z "$_branch" ]; then + _branch="master" fi - target="$PROJECT/archive/$BRANCH.tar.gz" + target="$PROJECT/archive/$_branch.tar.gz" _info "Downloading $target" - localname="$BRANCH.tar.gz" + localname="$_branch.tar.gz" if ! _get "$target" >$localname; then _err "Download error." return 1 @@ -6585,9 +6591,9 @@ _installOnline() { exit 1 fi - cd "$PROJECT_NAME-$BRANCH" + cd "$PROJECT_NAME-$_branch" chmod +x $PROJECT_ENTRY - if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then + if ./$PROJECT_ENTRY --install "$@"; then _info "Install success!" _initpath _saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)" @@ -6595,7 +6601,7 @@ _installOnline() { cd .. - rm -rf "$PROJECT_NAME-$BRANCH" + rm -rf "$PROJECT_NAME-$_branch" rm -f "$localname" ) } @@ -6623,7 +6629,7 @@ upgrade() { [ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0 export LE_WORKING_DIR cd "$LE_WORKING_DIR" - _installOnline "nocron" "noprofile" + installOnline "--nocron" "--noprofile" ); then _info "Upgrade success!" exit 0 @@ -6803,6 +6809,11 @@ _process() { --install) _CMD="install" ;; + --install-online) + shift + installOnline "$@" + return + ;; --uninstall) _CMD="uninstall" ;; @@ -7077,9 +7088,9 @@ _process() { USER_AGENT="$_useragent" shift ;; - -m | --accountemail) + -m | --email | --accountemail) _accountemail="$2" - ACCOUNT_EMAIL="$_accountemail" + export ACCOUNT_EMAIL="$_accountemail" shift ;; --accountkey) @@ -7122,10 +7133,10 @@ _process() { CA_PATH="$_ca_path" shift ;; - --nocron) + --no-cron | --nocron) _nocron="1" ;; - --noprofile) + --no-profile | --noprofile) _noprofile="1" ;; --no-color) @@ -7345,7 +7356,7 @@ _process() { fi _debug "Running cmd: ${_CMD}" case "${_CMD}" in - install) install "$_nocron" "$_confighome" "$_noprofile" ;; + install) install "$_nocron" "$_confighome" "$_noprofile" "$_accountemail" ;; uninstall) uninstall "$_nocron" ;; upgrade) upgrade ;; issue) @@ -7458,12 +7469,6 @@ _process() { } -if [ "$INSTALLONLINE" ]; then - INSTALLONLINE="" - _installOnline - exit -fi - main() { [ -z "$1" ] && showhelp && return if _startswith "$1" '-'; then _process "$@"; else "$@"; fi From 565ca81b30bd5a586f438035a0c7f2ff008714ce Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 30 Jan 2021 11:44:42 +0800 Subject: [PATCH 1187/2234] update readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f53578d4..edd6442f 100644 --- a/README.md +++ b/README.md @@ -110,13 +110,13 @@ https://github.com/acmesh-official/acmetest Check this project: https://github.com/acmesh-official/get.acme.sh ```bash -curl https://get.acme.sh | sh +curl https://get.acme.sh | sh -s email=my@example.com ``` Or: ```bash -wget -O - https://get.acme.sh | sh +wget -O - https://get.acme.sh | sh -s email=my@example.com ``` @@ -127,7 +127,7 @@ Clone this project and launch installation: ```bash git clone https://github.com/acmesh-official/acme.sh.git cd ./acme.sh -./acme.sh --install +./acme.sh --install -m my@example.com ``` You `don't have to be root` then, although `it is recommended`. From e6dea4c92c58886106661f0e56035560b1fccb19 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 30 Jan 2021 12:05:23 +0800 Subject: [PATCH 1188/2234] fix format --- acme.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/acme.sh b/acme.sh index 0d3a9e8c..a1ad4195 100755 --- a/acme.sh +++ b/acme.sh @@ -6568,7 +6568,6 @@ Parameters: " } - installOnline() { _info "Installing from online archive." From dadc70630b3b1fd1fc93805dde5b929e2e5b1f06 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Sun, 31 Jan 2021 22:02:11 +0100 Subject: [PATCH 1189/2234] Testing HMAC --- dnsapi/dns_websupport.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 1332a0aa..5136a8e1 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -156,11 +156,11 @@ _ws_rest() { _debug2 api_key "$WS_ApiKey" _debug2 api_secret "$WS_ApiSecret" - timestamp="$(date +%s)" + timestamp=$(_time) datez=$(date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -d@"$timestamp" +%Y-%m-%dT%H:%M:%S%z) canonical_request="${me} ${pa} ${timestamp}" alg="sha1" - signature_hash=$( (printf "%s" "$canonical_request" | ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -mac HMAC -macopt "key:$WS_ApiSecret" 2>/dev/null || printf "%s" "$canonical_request" | ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -hmac "$(printf "%s" "$WS_ApiSecret" | _h2b)") | cut -d = -f 2 | tr -d ' ') + signature_hash=$( (printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret" 2>/dev/null || printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret") basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From 7924e01b155b4b0ee0170c209687c3c68cdfdb76 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Sun, 31 Jan 2021 22:04:53 +0100 Subject: [PATCH 1190/2234] Added a forgotten ")" --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 5136a8e1..ca6b8a06 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -160,7 +160,7 @@ _ws_rest() { datez=$(date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -d@"$timestamp" +%Y-%m-%dT%H:%M:%S%z) canonical_request="${me} ${pa} ${timestamp}" alg="sha1" - signature_hash=$( (printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret" 2>/dev/null || printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret") + signature_hash=$( (printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret" 2>/dev/null || printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret")) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From 84dd864886c2bccacec04697abfe7a7d594b9705 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Sun, 31 Jan 2021 22:16:00 +0100 Subject: [PATCH 1191/2234] Simplified approach for the HMAC method --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index ca6b8a06..2ff93a5d 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -160,7 +160,7 @@ _ws_rest() { datez=$(date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -d@"$timestamp" +%Y-%m-%dT%H:%M:%S%z) canonical_request="${me} ${pa} ${timestamp}" alg="sha1" - signature_hash=$( (printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret" 2>/dev/null || printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret")) + signature_hash=$(printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret") basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From 76309601eb20222cab6a48b3dacbb9c07e39c709 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Sun, 31 Jan 2021 22:25:13 +0100 Subject: [PATCH 1192/2234] Update dns_websupport.sh --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 2ff93a5d..4b0026f8 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -160,7 +160,7 @@ _ws_rest() { datez=$(date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -d@"$timestamp" +%Y-%m-%dT%H:%M:%S%z) canonical_request="${me} ${pa} ${timestamp}" alg="sha1" - signature_hash=$(printf "%s" "$canonical_request" | _hmac "$alg" "$WS_ApiSecret") + signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From 0481f20c6b6acbe590f54194c4e709f3b159cb1a Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Mon, 1 Feb 2021 00:30:36 +0100 Subject: [PATCH 1193/2234] "datez" var and comments --- dnsapi/dns_websupport.sh | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 4b0026f8..731da0a6 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -1,18 +1,24 @@ #!/usr/bin/env sh -#This is the websupport.sk api wrapper for acme.sh +# This is the websupport.sk api wrapper for acme.sh # -#Author: trgo.sk -#Report Bugs here: https://github.com/trgosk/acme.sh - -#WS_ApiKey="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -#WS_ApiSecret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +# Original author: trgo.sk (https://github.com/trgosk) +# Tweaks by: akulumbeg (https://github.com/akulumbeg) +# +# Report Bugs here: https://github.com/akulumbeg/acme.sh +# +# Requirements: API Key and Secret from https://admin.websupport.sk/en/auth/apiKey +# +# WS_ApiKey="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +# (called "Identifier" in the WS Admin) +# +# WS_ApiSecret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +# (called "Secret key" in the WS Admin) WS_Api="https://rest.websupport.sk" ######## Public functions ##################### -#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_websupport_add() { fulldomain=$1 txtvalue=$2 @@ -26,7 +32,7 @@ dns_websupport_add() { else WS_ApiKey="" WS_ApiSecret="" - _err "You didn't specify a api key and/or api secret yet." + _err "You did not specify the API Key and/or API Secret" _err "You can get yours from here https://admin.websupport.sk/en/auth/apiKey" return 1 fi @@ -62,7 +68,6 @@ dns_websupport_add() { } -#fulldomain txtvalue dns_websupport_rm() { fulldomain=$1 txtvalue=$2 @@ -111,11 +116,8 @@ dns_websupport_rm() { } -#################### Private functions below ################################## -#_acme-challenge.www.domain.com -#returns -# _sub_domain=_acme-challenge.www -# _domain=domain.com +#################### Private Functions ################################## + _get_root() { domain=$1 i=1 @@ -157,9 +159,8 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez=$(date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -d@"$timestamp" +%Y-%m-%dT%H:%M:%S%z) + datez=$(printf "%s" "$(date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -d@"$timestamp" +%Y-%m-%dT%H:%M:%S%z)") canonical_request="${me} ${pa} ${timestamp}" - alg="sha1" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" @@ -169,7 +170,6 @@ _ws_rest() { _debug2 timestamp "$timestamp" _debug2 datez "$datez" _debug2 canonical_request "$canonical_request" - _debug2 alg "$alg" _debug2 signature_hash "$signature_hash" _debug2 basicauth "$basicauth" From 3014955ecec9a71a0db59b83641484bea71e7c0e Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Mon, 1 Feb 2021 18:16:15 +0100 Subject: [PATCH 1194/2234] Fix comments, error msg and time formatting --- dnsapi/dns_websupport.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 731da0a6..8950970b 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -1,12 +1,11 @@ #!/usr/bin/env sh -# This is the websupport.sk api wrapper for acme.sh +# Acme.sh DNS API wrapper for websupport.sk # # Original author: trgo.sk (https://github.com/trgosk) # Tweaks by: akulumbeg (https://github.com/akulumbeg) -# # Report Bugs here: https://github.com/akulumbeg/acme.sh -# + # Requirements: API Key and Secret from https://admin.websupport.sk/en/auth/apiKey # # WS_ApiKey="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" @@ -33,7 +32,7 @@ dns_websupport_add() { WS_ApiKey="" WS_ApiSecret="" _err "You did not specify the API Key and/or API Secret" - _err "You can get yours from here https://admin.websupport.sk/en/auth/apiKey" + _err "You can get the credentials from here https://admin.websupport.sk/en/auth/apiKey" return 1 fi @@ -159,7 +158,7 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez=$(printf "%s" "$(date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -d@"$timestamp" +%Y-%m-%dT%H:%M:%S%z)") + datez=$(printf "%s" "$(date -u -r "$timestamp" "+%Y-%m-%dT%H:%M:%S%z" 2>/dev/null || date -u -d@"$timestamp" "+%Y-%m-%dT%H:%M:%S%z")") canonical_request="${me} ${pa} ${timestamp}" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" From 5d4d53c3a10c7fdfe76c01f1270d40550d260ebc Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Mon, 1 Feb 2021 18:37:17 +0100 Subject: [PATCH 1195/2234] Testing datez change for Solaris --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 8950970b..c3a43f1e 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -158,7 +158,7 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez=$(printf "%s" "$(date -u -r "$timestamp" "+%Y-%m-%dT%H:%M:%S%z" 2>/dev/null || date -u -d@"$timestamp" "+%Y-%m-%dT%H:%M:%S%z")") + datez=$(printf "%s" "$(date -u -d@"$timestamp" "+%Y-%m-%dT%H:%M:%S%z" 2>/dev/null || date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z)") canonical_request="${me} ${pa} ${timestamp}" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" From 783a6110eff2bbb85c4ad7082ec43490a32eaeb2 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Mon, 1 Feb 2021 20:31:05 +0100 Subject: [PATCH 1196/2234] Yet another Solaris test --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index c3a43f1e..73543ea5 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -158,7 +158,7 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez=$(printf "%s" "$(date -u -d@"$timestamp" "+%Y-%m-%dT%H:%M:%S%z" 2>/dev/null || date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z)") + datez=$(date -u -d@"$timestamp" "+%Y-%m-%dT%H:%M:%S%z" 1>/dev/null 2>&1 || date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z) canonical_request="${me} ${pa} ${timestamp}" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" From 7984d8cdfb41a65f37940c0fe14502660b2f33a1 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Mon, 1 Feb 2021 20:43:22 +0100 Subject: [PATCH 1197/2234] And again --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 73543ea5..b145dc3e 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -158,7 +158,7 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez=$(date -u -d@"$timestamp" "+%Y-%m-%dT%H:%M:%S%z" 1>/dev/null 2>&1 || date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z) + datez=$(date -u -d@"$timestamp" "+%Y-%m-%dT%H:%M:%S%z" 2>/dev/null || date -u -r "$timestamp" "+%Y-%m-%dT%H:%M:%S%z") canonical_request="${me} ${pa} ${timestamp}" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" From 631398f700dfc41414862b1bee4b33ff4c0b3d7a Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 00:21:08 +0100 Subject: [PATCH 1198/2234] sed workaround for "datez" --- dnsapi/dns_websupport.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index b145dc3e..b30ac994 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -1,3 +1,4 @@ + #!/usr/bin/env sh # Acme.sh DNS API wrapper for websupport.sk @@ -158,7 +159,7 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez=$(date -u -d@"$timestamp" "+%Y-%m-%dT%H:%M:%S%z" 2>/dev/null || date -u -r "$timestamp" "+%Y-%m-%dT%H:%M:%S%z") + datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" From 3d338bba3c8e9b5f3fad16316264a8e91ac51d7d Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 00:31:46 +0100 Subject: [PATCH 1199/2234] Fixing the shebang accident --- dnsapi/dns_websupport.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index b30ac994..922e6819 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -1,4 +1,3 @@ - #!/usr/bin/env sh # Acme.sh DNS API wrapper for websupport.sk From 8dc55f417d9244ff5a3b81cc396308d43a57528b Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 10:13:36 +0100 Subject: [PATCH 1200/2234] Extra test - adding date -u -d Adding this to at least partially prevent the virtually nonexistent possibility of timestamp and _utc_date() mismatch. If the normal date -u -d does not get converted (looking at you Solaris!), the poor man's method with manipulating the _utc_date() string output kicks in. --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 922e6819..d69a6c00 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -158,7 +158,7 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")" + datez="$(date -u -d @"$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null/ || _utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" From ced6852735ffb77a215f94022f3835be9196b369 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 11:15:13 +0100 Subject: [PATCH 1201/2234] 2>/dev/null/ to 2>/dev/null Silly mistake with a "/" -.- --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index d69a6c00..143b07b2 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -158,7 +158,7 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez="$(date -u -d @"$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null/ || _utc_date | sed "s/ /T/" | sed "s/$/+0000/")" + datez="$(date -u -d @"$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || _utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" From 94917e315e50e001d55c539d6d2e9f79669679f6 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 11:18:22 +0100 Subject: [PATCH 1202/2234] Testing double 2>/dev/null into _utc_date with sed --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 143b07b2..797c1b57 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -158,7 +158,7 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez="$(date -u -d @"$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || _utc_date | sed "s/ /T/" | sed "s/$/+0000/")" + datez="$(date -u -d @"$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || _utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" From 433d9bfb020ad00c27e305e31499f718fe4ec9e4 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 15:11:53 +0100 Subject: [PATCH 1203/2234] Implementing/testing Neil's suggestions --- dnsapi/dns_websupport.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 797c1b57..5089d7c3 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -158,9 +158,9 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez="$(date -u -d @"$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || date -u -r "$timestamp" +%Y-%m-%dT%H:%M:%S%z 2>/dev/null || _utc_date | sed "s/ /T/" | sed "s/$/+0000/")" + datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/") canonical_request="${me} ${pa} ${timestamp}" - signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) + signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$WS_ApiSecret") basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From 9e146a8a5a80004ca65d08b30e977d0c135ed25c Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 15:15:17 +0100 Subject: [PATCH 1204/2234] Typo Forgot a quotation mark on line 161 --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 5089d7c3..de3d8b71 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -158,7 +158,7 @@ _ws_rest() { _debug2 api_secret "$WS_ApiSecret" timestamp=$(_time) - datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/") + datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$WS_ApiSecret") basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" From 6c9845b9f3838d56aaa76bcab4e9986334ca1432 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 15:18:39 +0100 Subject: [PATCH 1205/2234] adding the hex parameter to _hmac call --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index de3d8b71..e40a3729 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -160,7 +160,7 @@ _ws_rest() { timestamp=$(_time) datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" - signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$WS_ApiSecret") + signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$WS_ApiSecret" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From 3a383589465cadb87e72ade8c0755a1deb483b4c Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 15:22:53 +0100 Subject: [PATCH 1206/2234] Trying the original solution _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index e40a3729..922e6819 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -160,7 +160,7 @@ _ws_rest() { timestamp=$(_time) datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" - signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$WS_ApiSecret" hex) + signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From 2eda03f5dea919930d156c2cc8d6e976d173ec78 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 15:32:51 +0100 Subject: [PATCH 1207/2234] Changing the _hmac call into Neil's suggestion --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 922e6819..06ed9c78 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -160,7 +160,7 @@ _ws_rest() { timestamp=$(_time) datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" - signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) + signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$WS_ApiSecret" | _hex_dump | tr -d " ") basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From b8494ab3cca644039bfda425e12d1f5079cfeace Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 17:15:22 +0100 Subject: [PATCH 1208/2234] Update dns_websupport.sh --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 06ed9c78..ed14a279 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -160,7 +160,7 @@ _ws_rest() { timestamp=$(_time) datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" - signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$WS_ApiSecret" | _hex_dump | tr -d " ") + signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$("$WS_ApiSecret" | _hex_dump | tr -d " ")") basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From c8c727e6c652d45c826b05d783d695f2d066857d Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 17:21:33 +0100 Subject: [PATCH 1209/2234] added hex param to _hmac but removed "printf "s%" ... --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index ed14a279..773d693d 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -160,7 +160,7 @@ _ws_rest() { timestamp=$(_time) datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" - signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$("$WS_ApiSecret" | _hex_dump | tr -d " ")") + signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$("$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From 0021fb8a33df61c7578df4ff61a836eee16283a4 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 17:27:39 +0100 Subject: [PATCH 1210/2234] Changing the _hmac auth back It only works this way, apparently --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 773d693d..922e6819 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -160,7 +160,7 @@ _ws_rest() { timestamp=$(_time) datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")" canonical_request="${me} ${pa} ${timestamp}" - signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$("$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) + signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex) basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)" _debug2 method "$me" From 556c546b2ea6ee2d3db6fa41766c25653c02159b Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sat, 6 Feb 2021 22:48:25 +0100 Subject: [PATCH 1213/2234] Deploy Scipt for TrueNAs Server acme .sh deploy Scipt for TrueNAS Server that uses the REST API from TrueNAS. - Authentification with API Key - If HTTP redirect is configured, automatik switch to HTTPS - If WebDAV Certificate is the same as Web UI Certificate, Webdav Certificate get also an updated - If FTP Certificate is the same as Web UI Certificate, FTP Certificate get also an updated --- deploy/truenas.sh | 191 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 deploy/truenas.sh diff --git a/deploy/truenas.sh b/deploy/truenas.sh new file mode 100644 index 00000000..43d39a3d --- /dev/null +++ b/deploy/truenas.sh @@ -0,0 +1,191 @@ +#!/usr/local/bin/bash + +#Here is a scipt to deploy the cert to your TrueNAS using the REST API. +# https://www.truenas.com/docs/hub/additional-topics/api/rest_api.html +# +# Written by Frank Plass github@f-plass.de +# +# +# Following environment variables must be set: +# +# export DEPLOY_TRUENAS_APIKEY=" Date: Sat, 6 Feb 2021 23:03:07 +0100 Subject: [PATCH 1214/2234] Danksagung an danb35 --- deploy/truenas.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 43d39a3d..6a52e166 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -1,10 +1,11 @@ #!/usr/local/bin/bash -#Here is a scipt to deploy the cert to your TrueNAS using the REST API. +# Here is a scipt to deploy the cert to your TrueNAS using the REST API. # https://www.truenas.com/docs/hub/additional-topics/api/rest_api.html # # Written by Frank Plass github@f-plass.de -# +# https://github.com/danb35/deploy-freenas/blob/master/deploy_freenas.py +# Thanks to danb35 for your template! # # Following environment variables must be set: # From 0e341726d29b82b448248945e8e30d8fc3963043 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sat, 6 Feb 2021 23:20:52 +0100 Subject: [PATCH 1215/2234] Edits after DoShellcheck --- deploy/truenas.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 6a52e166..cfc3e7f7 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -121,7 +121,7 @@ truenas_deploy() { _activateData="{\"ui_certificate\": \"${_cert_id}\"}" _activate_result="$(_post "$_activateData" "$_api_url/system/general" "" "PUT" "application/json")" - _debug3 _activate_result $(echo "$_activate_result" ) + _debug3 _activate_result "$_activate_result" _info "Check if WebDAV certificate is the same as the WEB UI" @@ -133,7 +133,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 | sed -n 's/.*: \([0-9]\{1,\}\) }$/\1/p') if [ "$_webdav_new_cert_id" -eq "$_cert_id" ]; then _info "WebDAV Certificate update successfully" else @@ -157,7 +157,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 | sed -n 's/.*: \([0-9]\{1,\}\) }$/\1/p') if [ "$_ftp_new_cert_id" -eq "$_cert_id" ]; then _info "FTP Certificate update successfully" else From 4f7c2bf8c31786d11f58e85130c8f95db1f01557 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 16:12:24 +0100 Subject: [PATCH 1216/2234] Update truenas.sh --- deploy/truenas.sh | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index cfc3e7f7..f52ba89c 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -179,14 +179,9 @@ truenas_deploy() { _info "Reload WebUI from TrueNAS" - curl --silent -L --no-keepalive --user-agent "$USER_AGENT" "$_api_url/system/general/ui_restart" - ret=$? + _restart_UI=$(_get "$_api_url/system/general/ui_restart") - _debug CURL_RETURN "$ret" - if [ "$ret" != "0" ]; then - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" - return 1 - fi + _debug3 _restart_UI "$_restart_UI" - return 0 + return 0 } From ed46a078f9cec4c846f8ecdee414f8ff7d877d8f Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 16:35:51 +0100 Subject: [PATCH 1217/2234] Update truenas.sh --- deploy/truenas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index f52ba89c..8ccf226a 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -183,5 +183,5 @@ truenas_deploy() { _debug3 _restart_UI "$_restart_UI" - return 0 + return 0 } From c8a2308739ec70d1ba70e1cc1ead721e91e4bdb0 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 18:42:48 +0100 Subject: [PATCH 1218/2234] Update truenas.sh --- deploy/truenas.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 8ccf226a..37ddb2b0 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -179,9 +179,18 @@ truenas_deploy() { _info "Reload WebUI from TrueNAS" - _restart_UI=$(_get "$_api_url/system/general/ui_restart") + # the command + # _restart_UI=$(_get "$_api_url/system/general/ui_restart") + # throws the Error 52 + # for this command direct curl command + curl --silent -L --no-keepalive --user-agent "$USER_AGENT" -H "$_H1" "$_api_url/system/general/ui_restart" + ret=$? + _debug2 CURL_RETURN "$ret" - _debug3 _restart_UI "$_restart_UI" - - return 0 + if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ] && [ "$ret" == "52" ]; then + return 0 + else + _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" + return 1 + fi } From 05737b85eb263551234385bfd457fb204749063b Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 18:47:04 +0100 Subject: [PATCH 1219/2234] Update truenas.sh --- deploy/truenas.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 37ddb2b0..35631900 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -187,10 +187,10 @@ truenas_deploy() { ret=$? _debug2 CURL_RETURN "$ret" - if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ] && [ "$ret" == "52" ]; then - return 0 - else + if [ -z "$_add_cert_result" ] && [ -z "$_activate_result" ] && [ "$ret" != "52" ]; then _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" return 1 + else + return 0 fi } From 854e52052825fcdff2fad52cb1e048faa99e2383 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 19:02:03 +0100 Subject: [PATCH 1220/2234] Update truenas.sh --- deploy/truenas.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 35631900..ad83f760 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -184,13 +184,13 @@ truenas_deploy() { # throws the Error 52 # for this command direct curl command curl --silent -L --no-keepalive --user-agent "$USER_AGENT" -H "$_H1" "$_api_url/system/general/ui_restart" - ret=$? - _debug2 CURL_RETURN "$ret" + _ret=$? + _debug2 CURL_RETURN "$_ret" - if [ -z "$_add_cert_result" ] && [ -z "$_activate_result" ] && [ "$ret" != "52" ]; then - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" - return 1 - else + if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ] && [ "$ret" == "52" ]; then return 0 + else + _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" + return 1 fi } From 052c9be111fa1180479eb89a9e65ac69519d539e Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 19:12:39 +0100 Subject: [PATCH 1221/2234] Update truenas.sh --- deploy/truenas.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index ad83f760..f7d5c1cb 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -1,4 +1,4 @@ -#!/usr/local/bin/bash +#!/usr/bin/env sh # Here is a scipt to deploy the cert to your TrueNAS using the REST API. # https://www.truenas.com/docs/hub/additional-topics/api/rest_api.html @@ -187,7 +187,7 @@ truenas_deploy() { _ret=$? _debug2 CURL_RETURN "$_ret" - if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ] && [ "$ret" == "52" ]; then + if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ] && [ "$_ret" == "52" ]; then return 0 else _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" From f8c11a324a2bb4cd3ad19fd4bc9f6cda2156d412 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 19:19:04 +0100 Subject: [PATCH 1222/2234] Update truenas.sh --- deploy/truenas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index f7d5c1cb..5ca8f2af 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -187,7 +187,7 @@ truenas_deploy() { _ret=$? _debug2 CURL_RETURN "$_ret" - if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ] && [ "$_ret" == "52" ]; then + if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ] && [ "$_ret" = "52" ]; then return 0 else _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" From a836842a7eecf770e30bbe46243ff0c127d9ef56 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 21:20:56 +0100 Subject: [PATCH 1223/2234] Update truenas.sh --- deploy/truenas.sh | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 5ca8f2af..1b58cc90 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -43,11 +43,11 @@ truenas_deploy() { fi _secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" -# Optional hostname, scheme for TrueNAS + # Optional hostname, scheme for TrueNAS _getdeployconf DEPLOY_TRUENAS_HOSTNAME _getdeployconf DEPLOY_TRUENAS_SCHEME -# default values for hostname and scheme + # default values for hostname and scheme [ -n "${DEPLOY_TRUENAS_HOSTNAME}" ] || DEPLOY_TRUENAS_HOSTNAME="localhost" [ -n "${DEPLOY_TRUENAS_SCHEME}" ] || DEPLOY_TRUENAS_SCHEME="http" @@ -63,6 +63,7 @@ truenas_deploy() { _info "Testing Connection TrueNAS" _response=$(_get "$_api_url/system/state") _info "TrueNAS System State: $_response." + _debug _response "$_response" if [ -z "$_response" ]; then _err "Unable to authenticate to $_api_url." @@ -78,7 +79,6 @@ truenas_deploy() { _saveaccountconf DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME" _saveaccountconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" - _info "Getting active certificate from TrueNAS" _response=$(_get "$_api_url/system/general") _active_cert_id=$(echo "$_response" | grep -B2 '"name":' | grep 'id' | tr -d -- '"id: ,') @@ -88,7 +88,7 @@ truenas_deploy() { _debug Active_UI_Certificate_Name "$_active_cert_name" _debug Active_UI_http_redirect "$_param_httpsredirect" - if [ "$DEPLOY_TRUENAS_SCHEME" = "http" ] && [ "$_param_httpsredirect" = "true" ] ; then + if [ "$DEPLOY_TRUENAS_SCHEME" = "http" ] && [ "$_param_httpsredirect" = "true" ]; then _info "http Redirect active" _info "Setting DEPLOY_TRUENAS_SCHEME to 'https'" DEPLOY_TRUENAS_SCHEME="https" @@ -96,34 +96,29 @@ truenas_deploy() { _saveaccountconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" fi - _info "Upload new certifikate to TrueNAS" - _date_now() { - date -u "+%Y-%m-%d_%H%M%S" - } - _certname="Letsencrypt_$(_date_now)" + _certname="Letsencrypt_$(_utc_date | tr ' ' '_' | tr -d -- ':')" _debug3 _certname "$_certname" + return 0 + _certData="{\"create_type\": \"CERTIFICATE_CREATE_IMPORTED\", \"name\": \"${_certname}\", \"certificate\": \"$(_json_encode <"$_cfullchain")\", \"privatekey\": \"$(_json_encode <"$_ckey")\"}" _add_cert_result="$(_post "$_certData" "$_api_url/certificate" "" "POST" "application/json")" _debug3 _add_cert_result "$_add_cert_result" - _info "Getting Certificate list to get new Cert ID" _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" _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" _webdav_list=$(_get "$_api_url/webdav") _webdav_cert_id=$(echo "$_webdav_list" | grep '"certssl":' | tr -d -- '"certsl: ,') @@ -147,7 +142,6 @@ truenas_deploy() { _info "WebDAV certificate not set or not the same as Web UI" fi - _info "Check if FTP certificate is the same as the WEB UI" _ftp_list=$(_get "$_api_url/ftp") _ftp_cert_id=$(echo "$_ftp_list" | grep '"ssltls_certificate":' | tr -d -- '"certislfa:_ ,') @@ -171,18 +165,16 @@ truenas_deploy() { _info "FTP certificate not set or not the same as Web UI" fi - _info "Delete 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" # the command # _restart_UI=$(_get "$_api_url/system/general/ui_restart") # throws the Error 52 # for this command direct curl command + _info "Reload WebUI from TrueNAS" curl --silent -L --no-keepalive --user-agent "$USER_AGENT" -H "$_H1" "$_api_url/system/general/ui_restart" _ret=$? _debug2 CURL_RETURN "$_ret" @@ -193,4 +185,4 @@ truenas_deploy() { _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" return 1 fi -} +} \ No newline at end of file From a7ca010d4e3db0011d935cc710d7ba5e20352fc4 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 21:24:06 +0100 Subject: [PATCH 1224/2234] Update truenas.sh --- deploy/truenas.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 1b58cc90..27b67dce 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -100,8 +100,6 @@ truenas_deploy() { _certname="Letsencrypt_$(_utc_date | tr ' ' '_' | tr -d -- ':')" _debug3 _certname "$_certname" - return 0 - _certData="{\"create_type\": \"CERTIFICATE_CREATE_IMPORTED\", \"name\": \"${_certname}\", \"certificate\": \"$(_json_encode <"$_cfullchain")\", \"privatekey\": \"$(_json_encode <"$_ckey")\"}" _add_cert_result="$(_post "$_certData" "$_api_url/certificate" "" "POST" "application/json")" From 6f4c5fcc8738aabc26a188ca94361dbc32cb7705 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 7 Feb 2021 21:25:49 +0100 Subject: [PATCH 1225/2234] Update truenas.sh --- deploy/truenas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 27b67dce..e25523df 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -183,4 +183,4 @@ truenas_deploy() { _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" return 1 fi -} \ No newline at end of file +} From 987571ce91179ee33f5af0eac4bc49053312ce3b Mon Sep 17 00:00:00 2001 From: Gnought <1684105+gnought@users.noreply.github.com> Date: Thu, 11 Feb 2021 01:08:08 +0800 Subject: [PATCH 1226/2234] Updated --preferred-chain to issue ISRG properly To support different openssl crl2pkcs7 help cli format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index a1ad4195..749400e2 100755 --- a/acme.sh +++ b/acme.sh @@ -4011,7 +4011,7 @@ _check_dns_entries() { #file _get_cert_issuers() { _cfile="$1" - if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 else ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 From 8636d3139e34b245a512c56ff6a58a4e697241c3 Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 11 Feb 2021 11:20:18 +0100 Subject: [PATCH 1227/2234] dnsapi/pdns: also normalize json response in detecting root zone --- dnsapi/dns_pdns.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 8f07e8c4..28b35492 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -175,13 +175,13 @@ _get_root() { i=1 if _pdns_rest "GET" "/api/v1/servers/$PDNS_ServerId/zones"; then - _zones_response="$response" + _zones_response=$(echo "$response" | _normalizeJson) fi while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if _contains "$_zones_response" "\"name\": \"$h.\""; then + if _contains "$_zones_response" "\"name\":\"$h.\""; then _domain="$h." if [ -z "$h" ]; then _domain="=2E" From 12b1916599aa4e58fa4c74aa6d454a7f144eb1f5 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Feb 2021 16:22:31 +0800 Subject: [PATCH 1228/2234] Chain (#3408) * fix https://github.com/acmesh-official/acme.sh/issues/3384 match the issuer to the root CA cert subject * fix format * fix https://github.com/acmesh-official/acme.sh/issues/3384 * remove the alt files. https://github.com/acmesh-official/acme.sh/issues/3384 --- acme.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/acme.sh b/acme.sh index 749400e2..a9301e10 100755 --- a/acme.sh +++ b/acme.sh @@ -4009,12 +4009,42 @@ _check_dns_entries() { } #file -_get_cert_issuers() { +_get_chain_issuers() { _cfile="$1" if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then - ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 else - ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + _cindex=1 + for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do + _endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)" + _debug2 "_startn" "$_startn" + _debug2 "_endn" "$_endn" + if [ "$DEBUG" ]; then + _debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")" + fi + sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/" + _cindex=$(_math $_cindex + 1) + done + fi +} + +# +_get_chain_subjects() { + _cfile="$1" + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + else + _cindex=1 + for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do + _endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)" + _debug2 "_startn" "$_startn" + _debug2 "_endn" "$_endn" + if [ "$DEBUG" ]; then + _debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")" + fi + sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/" + _cindex=$(_math $_cindex + 1) + done fi } @@ -4022,14 +4052,12 @@ _get_cert_issuers() { _match_issuer() { _cfile="$1" _missuer="$2" - _fissuers="$(_get_cert_issuers $_cfile)" + _fissuers="$(_get_chain_issuers $_cfile)" _debug2 _fissuers "$_fissuers" - if _contains "$_fissuers" "$_missuer"; then - return 0 - fi - _fissuers="$(echo "$_fissuers" | _lower_case)" + _rootissuer="$(echo "$_fissuers" | _lower_case | _tail_n 1)" + _debug2 _rootissuer "$_rootissuer" _missuer="$(echo "$_missuer" | _lower_case)" - _contains "$_fissuers" "$_missuer" + _contains "$_rootissuer" "$_missuer" } #webroot, domain domainlist keylength @@ -4803,6 +4831,9 @@ $_authorizations_map" _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then + if [ "$DEBUG" ]; then + _debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" + fi if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" _debug2 "rels" "$rels" @@ -4818,13 +4849,22 @@ $_authorizations_map" _relca="$CA_CERT_PATH.alt" echo "$response" >"$_relcert" _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" + if [ "$DEBUG" ]; then + _debug "rel chain issuers: " "$(_get_chain_issuers "$_relfullchain")" + fi if _match_issuer "$_relfullchain" "$_preferred_chain"; then _info "Matched issuer in: $rel" cat $_relcert >"$CERT_PATH" cat $_relfullchain >"$CERT_FULLCHAIN_PATH" cat $_relca >"$CA_CERT_PATH" + rm -f "$_relcert" + rm -f "$_relfullchain" + rm -f "$_relca" break fi + rm -f "$_relcert" + rm -f "$_relfullchain" + rm -f "$_relca" done fi fi From d8163e9835e2587793b51cc07b5e81aff3f2da8c Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 13 Feb 2021 17:27:22 +0800 Subject: [PATCH 1229/2234] upgrade freebsd and solaris --- .github/workflows/LetsEncrypt.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 8d0c4eb0..7c398c09 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -111,7 +111,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.7 + - uses: vmactions/freebsd-vm@v0.1.2 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl @@ -136,7 +136,7 @@ jobs: run: echo "TestingDomain=${{steps.ngrok.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.1 + - uses: vmactions/solaris-vm@v0.0.3 with: envs: 'TEST_LOCAL TestingDomain' nat: | From b7c3e6099cf3cdf9ed7d0c46d3a1aa0858c7cf02 Mon Sep 17 00:00:00 2001 From: jerrm Date: Sat, 13 Feb 2021 05:58:44 -0500 Subject: [PATCH 1230/2234] duckdns - fix "integer expression expected" errors (#3397) * fix "integer expression expected" errors * duckdns fix * Update dns_duckdns.sh * Update dns_duckdns.sh --- dnsapi/dns_duckdns.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 618e12c6..d6e1dbdc 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -12,7 +12,7 @@ DuckDNS_API="https://www.duckdns.org/update" -######## Public functions ##################### +######## Public functions ###################### #Usage: dns_duckdns_add _acme-challenge.domain.duckdns.org "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_duckdns_add() { @@ -112,7 +112,7 @@ _duckdns_rest() { param="$2" _debug param "$param" url="$DuckDNS_API?$param" - if [ "$DEBUG" -gt 0 ]; then + if [ -n "$DEBUG" ] && [ "$DEBUG" -gt 0 ]; then url="$url&verbose=true" fi _debug url "$url" @@ -121,7 +121,7 @@ _duckdns_rest() { if [ "$method" = "GET" ]; then response="$(_get "$url")" _debug2 response "$response" - if [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then + if [ -n "$DEBUG" ] && [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then response="OK" fi else From 93fd6170a360a41034ea8033f8147de1b378a417 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sat, 13 Feb 2021 12:38:57 +0100 Subject: [PATCH 1231/2234] Update truenas.sh --- deploy/truenas.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index e25523df..be8fac12 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -75,9 +75,9 @@ truenas_deploy() { return 1 fi - _saveaccountconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" - _saveaccountconf DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME" - _saveaccountconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" + _savedeployconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" + _savedeployconf DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME" + _savedeployconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" _info "Getting active certificate from TrueNAS" _response=$(_get "$_api_url/system/general") @@ -93,7 +93,7 @@ truenas_deploy() { _info "Setting DEPLOY_TRUENAS_SCHEME to 'https'" DEPLOY_TRUENAS_SCHEME="https" _api_url="$DEPLOY_TRUENAS_SCHEME://$DEPLOY_TRUENAS_HOSTNAME/api/v2.0" - _saveaccountconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" + _savedeployconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" fi _info "Upload new certifikate to TrueNAS" From 1de9ffacb0e38a6a26291b088645638d0a3a890c Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 29 Dec 2020 16:28:38 -0800 Subject: [PATCH 1232/2234] Implement smtp notify hook Support notifications via direct SMTP server connection. Uses Python (2.7.x or 3.4+) to communicate with SMTP server. --- notify/smtp.sh | 185 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 6aa37ca3..367021c8 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -2,7 +2,103 @@ # support smtp +# This implementation uses Python (2 or 3), which is available in many environments. +# If you don't have Python, try "mail" notification instead of "smtp". + +# SMTP_FROM="from@example.com" # required +# SMTP_TO="to@example.com" # required +# SMTP_HOST="smtp.example.com" # required +# SMTP_PORT="25" # defaults to 25, 465 or 587 depending on SMTP_SECURE +# SMTP_SECURE="none" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) +# SMTP_USERNAME="" # set if SMTP server requires login +# SMTP_PASSWORD="" # set if SMTP server requires login +# SMTP_TIMEOUT="15" # seconds for SMTP operations to timeout +# SMTP_PYTHON="/path/to/python" # defaults to system python3 or python + smtp_send() { + # Find a Python interpreter: + SMTP_PYTHON="${SMTP_PYTHON:-$(_readaccountconf_mutable SMTP_PYTHON)}" + if [ "$SMTP_PYTHON" ]; then + if _exists "$SMTP_PYTHON"; then + _saveaccountconf_mutable SMTP_PYTHON "$SMTP_PYTHON" + else + _err "SMTP_PYTHON '$SMTP_PYTHON' does not exist." + return 1 + fi + else + # No SMTP_PYTHON setting; try to run default Python. + # (This is not saved with the conf.) + if _exists python3; then + SMTP_PYTHON="python3" + elif _exists python; then + SMTP_PYTHON="python" + else + _err "Can't locate Python interpreter; please define SMTP_PYTHON." + return 1 + fi + fi + _debug "SMTP_PYTHON" "$SMTP_PYTHON" + _debug "Python version" "$($SMTP_PYTHON --version 2>&1)" + + # Validate other settings: + SMTP_FROM="${SMTP_FROM:-$(_readaccountconf_mutable SMTP_FROM)}" + if [ -z "$SMTP_FROM" ]; then + _err "You must define SMTP_FROM as the sender email address." + return 1 + fi + + SMTP_TO="${SMTP_TO:-$(_readaccountconf_mutable SMTP_TO)}" + if [ -z "$SMTP_TO" ]; then + _err "You must define SMTP_TO as the recipient email address." + return 1 + fi + + SMTP_HOST="${SMTP_HOST:-$(_readaccountconf_mutable SMTP_HOST)}" + if [ -z "$SMTP_HOST" ]; then + _err "You must define SMTP_HOST as the SMTP server hostname." + return 1 + fi + SMTP_PORT="${SMTP_PORT:-$(_readaccountconf_mutable SMTP_PORT)}" + + SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" + SMTP_SECURE="${SMTP_SECURE:-none}" + case "$SMTP_SECURE" in + "none") SMTP_DEFAULT_PORT="25";; + "ssl") SMTP_DEFAULT_PORT="465";; + "tls") SMTP_DEFAULT_PORT="587";; + *) + _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." + return 1 + ;; + esac + + SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" + SMTP_PASSWORD="${SMTP_PASSWORD:-$(_readaccountconf_mutable SMTP_PASSWORD)}" + + SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" + SMTP_DEFAULT_TIMEOUT="15" + + _saveaccountconf_mutable SMTP_FROM "$SMTP_FROM" + _saveaccountconf_mutable SMTP_TO "$SMTP_TO" + _saveaccountconf_mutable SMTP_HOST "$SMTP_HOST" + _saveaccountconf_mutable SMTP_PORT "$SMTP_PORT" + _saveaccountconf_mutable SMTP_SECURE "$SMTP_SECURE" + _saveaccountconf_mutable SMTP_USERNAME "$SMTP_USERNAME" + _saveaccountconf_mutable SMTP_PASSWORD "$SMTP_PASSWORD" + _saveaccountconf_mutable SMTP_TIMEOUT "$SMTP_TIMEOUT" + + # Send the message: + if ! _smtp_send "$@"; then + _err "$smtp_send_output" + return 1 + fi + + return 0 +} + +# _send subject content statuscode +# Send the message via Python using SMTP_* settings +_smtp_send() { _subject="$1" _content="$2" _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped @@ -10,6 +106,91 @@ smtp_send() { _debug "_content" "$_content" _debug "_statusCode" "$_statusCode" - _err "Not implemented yet." - return 1 + _debug "SMTP_FROM" "$SMTP_FROM" + _debug "SMTP_TO" "$SMTP_TO" + _debug "SMTP_HOST" "$SMTP_HOST" + _debug "SMTP_PORT" "$SMTP_PORT" + _debug "SMTP_DEFAULT_PORT" "$SMTP_DEFAULT_PORT" + _debug "SMTP_SECURE" "$SMTP_SECURE" + _debug "SMTP_USERNAME" "$SMTP_USERNAME" + _secure_debug "SMTP_PASSWORD" "$SMTP_PASSWORD" + _debug "SMTP_TIMEOUT" "$SMTP_TIMEOUT" + _debug "SMTP_DEFAULT_TIMEOUT" "$SMTP_DEFAULT_TIMEOUT" + + if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then + # Output the SMTP server dialogue. (Note this will include SMTP_PASSWORD!) + smtp_debug="True" + else + smtp_debug="" + fi + + # language=Python + smtp_send_output="$($SMTP_PYTHON < Date: Tue, 29 Dec 2020 17:10:36 -0800 Subject: [PATCH 1233/2234] Make shfmt happy (I'm open to better ways of formatting the heredoc that embeds the Python script.) --- notify/smtp.sh | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 367021c8..6171cb9b 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -63,13 +63,13 @@ smtp_send() { SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" SMTP_SECURE="${SMTP_SECURE:-none}" case "$SMTP_SECURE" in - "none") SMTP_DEFAULT_PORT="25";; - "ssl") SMTP_DEFAULT_PORT="465";; - "tls") SMTP_DEFAULT_PORT="587";; - *) - _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." - return 1 - ;; + "none") SMTP_DEFAULT_PORT="25" ;; + "ssl") SMTP_DEFAULT_PORT="465" ;; + "tls") SMTP_DEFAULT_PORT="587" ;; + *) + _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." + return 1 + ;; esac SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" @@ -125,7 +125,8 @@ _smtp_send() { fi # language=Python - smtp_send_output="$($SMTP_PYTHON < Date: Mon, 11 Jan 2021 11:46:26 -0800 Subject: [PATCH 1234/2234] Only save config if send is successful --- notify/smtp.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 6171cb9b..092bb2b9 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -78,6 +78,13 @@ smtp_send() { SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" SMTP_DEFAULT_TIMEOUT="15" + # Send the message: + if ! _smtp_send "$@"; then + _err "$smtp_send_output" + return 1 + fi + + # Save remaining config if successful. (SMTP_PYTHON is saved earlier.) _saveaccountconf_mutable SMTP_FROM "$SMTP_FROM" _saveaccountconf_mutable SMTP_TO "$SMTP_TO" _saveaccountconf_mutable SMTP_HOST "$SMTP_HOST" @@ -87,12 +94,6 @@ smtp_send() { _saveaccountconf_mutable SMTP_PASSWORD "$SMTP_PASSWORD" _saveaccountconf_mutable SMTP_TIMEOUT "$SMTP_TIMEOUT" - # Send the message: - if ! _smtp_send "$@"; then - _err "$smtp_send_output" - return 1 - fi - return 0 } From fe273b3829511febe42f9b854ba921213f7bedbb Mon Sep 17 00:00:00 2001 From: medmunds Date: Mon, 11 Jan 2021 12:59:51 -0800 Subject: [PATCH 1235/2234] Add instructions for reporting bugs --- notify/smtp.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/notify/smtp.sh b/notify/smtp.sh index 092bb2b9..a74ce092 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -2,6 +2,8 @@ # support smtp +# Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3358 + # This implementation uses Python (2 or 3), which is available in many environments. # If you don't have Python, try "mail" notification instead of "smtp". From 557a747d55a91eb7f1ac97028decc5d141fb2466 Mon Sep 17 00:00:00 2001 From: medmunds Date: Sun, 14 Feb 2021 15:47:51 -0800 Subject: [PATCH 1236/2234] Prep for curl or Python; clean up SMTP_* variable usage --- notify/smtp.sh | 207 ++++++++++++++++++++++++++++--------------------- 1 file changed, 120 insertions(+), 87 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index a74ce092..cb29d0f7 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -4,8 +4,8 @@ # Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3358 -# This implementation uses Python (2 or 3), which is available in many environments. -# If you don't have Python, try "mail" notification instead of "smtp". +# This implementation uses either curl or Python (3 or 2.7). +# (See also the "mail" notify hook, which supports other ways to send mail.) # SMTP_FROM="from@example.com" # required # SMTP_TO="to@example.com" # required @@ -14,79 +14,132 @@ # SMTP_SECURE="none" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) # SMTP_USERNAME="" # set if SMTP server requires login # SMTP_PASSWORD="" # set if SMTP server requires login -# SMTP_TIMEOUT="15" # seconds for SMTP operations to timeout -# SMTP_PYTHON="/path/to/python" # defaults to system python3 or python +# SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout +# SMTP_BIN="/path/to/curl_or_python" # default finds first of curl, python3, or python on PATH +# subject content statuscode smtp_send() { - # Find a Python interpreter: - SMTP_PYTHON="${SMTP_PYTHON:-$(_readaccountconf_mutable SMTP_PYTHON)}" - if [ "$SMTP_PYTHON" ]; then - if _exists "$SMTP_PYTHON"; then - _saveaccountconf_mutable SMTP_PYTHON "$SMTP_PYTHON" - else - _err "SMTP_PYTHON '$SMTP_PYTHON' does not exist." - return 1 - fi - else - # No SMTP_PYTHON setting; try to run default Python. - # (This is not saved with the conf.) - if _exists python3; then - SMTP_PYTHON="python3" - elif _exists python; then - SMTP_PYTHON="python" - else - _err "Can't locate Python interpreter; please define SMTP_PYTHON." - return 1 - fi - fi - _debug "SMTP_PYTHON" "$SMTP_PYTHON" - _debug "Python version" "$($SMTP_PYTHON --version 2>&1)" + _SMTP_SUBJECT="$1" + _SMTP_CONTENT="$2" + # UNUSED: _statusCode="$3" # 0: success, 1: error 2($RENEW_SKIP): skipped - # Validate other settings: + # Load config: SMTP_FROM="${SMTP_FROM:-$(_readaccountconf_mutable SMTP_FROM)}" + SMTP_TO="${SMTP_TO:-$(_readaccountconf_mutable SMTP_TO)}" + SMTP_HOST="${SMTP_HOST:-$(_readaccountconf_mutable SMTP_HOST)}" + SMTP_PORT="${SMTP_PORT:-$(_readaccountconf_mutable SMTP_PORT)}" + SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" + SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" + SMTP_PASSWORD="${SMTP_PASSWORD:-$(_readaccountconf_mutable SMTP_PASSWORD)}" + SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" + SMTP_BIN="${SMTP_BIN:-$(_readaccountconf_mutable SMTP_BIN)}" + + _debug "SMTP_FROM" "$SMTP_FROM" + _debug "SMTP_TO" "$SMTP_TO" + _debug "SMTP_HOST" "$SMTP_HOST" + _debug "SMTP_PORT" "$SMTP_PORT" + _debug "SMTP_SECURE" "$SMTP_SECURE" + _debug "SMTP_USERNAME" "$SMTP_USERNAME" + _secure_debug "SMTP_PASSWORD" "$SMTP_PASSWORD" + _debug "SMTP_TIMEOUT" "$SMTP_TIMEOUT" + _debug "SMTP_BIN" "$SMTP_BIN" + + _debug "_SMTP_SUBJECT" "$_SMTP_SUBJECT" + _debug "_SMTP_CONTENT" "$_SMTP_CONTENT" + + # Validate config and apply defaults: + # _SMTP_* variables are the resolved (with defaults) versions of SMTP_*. + # (The _SMTP_* versions will not be stored in account conf.) + + if [ -n "$SMTP_BIN" ] && ! _exists "$SMTP_BIN"; then + _err "SMTP_BIN '$SMTP_BIN' does not exist." + return 1 + fi + _SMTP_BIN="$SMTP_BIN" + if [ -z "$_SMTP_BIN" ]; then + # Look for a command that can communicate with an SMTP server. + # (Please don't add sendmail, ssmtp, mutt, mail, or msmtp here. + # Those are already handled by the "mail" notify hook.) + for cmd in curl python3 python2.7 python pypy3 pypy; do + if _exists "$cmd"; then + _SMTP_BIN="$cmd" + break + fi + done + if [ -z "$_SMTP_BIN" ]; then + _err "The smtp notify-hook requires curl or Python, but can't find any." + _err 'If you have one of them, define SMTP_BIN="/path/to/curl_or_python".' + _err 'Otherwise, see if you can use the "mail" notify-hook instead.' + return 1 + fi + _debug "_SMTP_BIN" "$_SMTP_BIN" + fi + if [ -z "$SMTP_FROM" ]; then _err "You must define SMTP_FROM as the sender email address." return 1 fi + _SMTP_FROM="$SMTP_FROM" - SMTP_TO="${SMTP_TO:-$(_readaccountconf_mutable SMTP_TO)}" if [ -z "$SMTP_TO" ]; then _err "You must define SMTP_TO as the recipient email address." return 1 fi + _SMTP_TO="$SMTP_TO" - SMTP_HOST="${SMTP_HOST:-$(_readaccountconf_mutable SMTP_HOST)}" if [ -z "$SMTP_HOST" ]; then _err "You must define SMTP_HOST as the SMTP server hostname." return 1 fi - SMTP_PORT="${SMTP_PORT:-$(_readaccountconf_mutable SMTP_PORT)}" + _SMTP_HOST="$SMTP_HOST" - SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" - SMTP_SECURE="${SMTP_SECURE:-none}" - case "$SMTP_SECURE" in - "none") SMTP_DEFAULT_PORT="25" ;; - "ssl") SMTP_DEFAULT_PORT="465" ;; - "tls") SMTP_DEFAULT_PORT="587" ;; + _SMTP_SECURE="${SMTP_SECURE:-none}" + case "$_SMTP_SECURE" in + "none") smtp_default_port="25" ;; + "ssl") smtp_default_port="465" ;; + "tls") smtp_default_port="587" ;; *) _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." return 1 ;; esac - SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" - SMTP_PASSWORD="${SMTP_PASSWORD:-$(_readaccountconf_mutable SMTP_PASSWORD)}" + _SMTP_PORT="${SMTP_PORT:-$smtp_default_port}" + if [ -z "$SMTP_PORT" ]; then + _debug "_SMTP_PORT" "$_SMTP_PORT" + fi - SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" - SMTP_DEFAULT_TIMEOUT="15" + _SMTP_USERNAME="$SMTP_USERNAME" + _SMTP_PASSWORD="$SMTP_PASSWORD" + _SMTP_TIMEOUT="${SMTP_TIMEOUT:-30}" + + # Run with --debug 2 (or above) to echo the transcript of the SMTP session. + # Careful: this may include SMTP_PASSWORD in plaintext! + if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then + _SMTP_SHOW_TRANSCRIPT="True" + else + _SMTP_SHOW_TRANSCRIPT="" + fi # Send the message: - if ! _smtp_send "$@"; then - _err "$smtp_send_output" + case "$(basename "$_SMTP_BIN")" in + curl) _smtp_send=_smtp_send_curl ;; + py*) _smtp_send=_smtp_send_python ;; + *) + _err "Can't figure out how to invoke $_SMTP_BIN." + _err "Please re-run with --debug and report a bug." + return 1 + ;; + esac + + if ! smtp_output="$($_smtp_send)"; then + _err "Error sending message with $_SMTP_BIN." + _err "${smtp_output:-(No additional details; try --debug or --debug 2)}" return 1 fi - # Save remaining config if successful. (SMTP_PYTHON is saved earlier.) + # Save config only if send was successful: + _saveaccountconf_mutable SMTP_BIN "$SMTP_BIN" _saveaccountconf_mutable SMTP_FROM "$SMTP_FROM" _saveaccountconf_mutable SMTP_TO "$SMTP_TO" _saveaccountconf_mutable SMTP_HOST "$SMTP_HOST" @@ -99,37 +152,21 @@ smtp_send() { return 0 } -# _send subject content statuscode -# Send the message via Python using SMTP_* settings -_smtp_send() { - _subject="$1" - _content="$2" - _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped - _debug "_subject" "$_subject" - _debug "_content" "$_content" - _debug "_statusCode" "$_statusCode" - _debug "SMTP_FROM" "$SMTP_FROM" - _debug "SMTP_TO" "$SMTP_TO" - _debug "SMTP_HOST" "$SMTP_HOST" - _debug "SMTP_PORT" "$SMTP_PORT" - _debug "SMTP_DEFAULT_PORT" "$SMTP_DEFAULT_PORT" - _debug "SMTP_SECURE" "$SMTP_SECURE" - _debug "SMTP_USERNAME" "$SMTP_USERNAME" - _secure_debug "SMTP_PASSWORD" "$SMTP_PASSWORD" - _debug "SMTP_TIMEOUT" "$SMTP_TIMEOUT" - _debug "SMTP_DEFAULT_TIMEOUT" "$SMTP_DEFAULT_TIMEOUT" +# Send the message via curl using _SMTP_* variables +_smtp_send_curl() { + # TODO: implement + echo "_smtp_send_curl not implemented" + return 1 +} - if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then - # Output the SMTP server dialogue. (Note this will include SMTP_PASSWORD!) - smtp_debug="True" - else - smtp_debug="" - fi + +# Send the message via Python using _SMTP_* variables +_smtp_send_python() { + _debug "Python version" "$("$_SMTP_BIN" --version 2>&1)" # language=Python - smtp_send_output="$( - $SMTP_PYTHON < Date: Sun, 14 Feb 2021 19:56:23 -0800 Subject: [PATCH 1237/2234] Implement curl version of smtp notify-hook --- notify/smtp.sh | 111 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 6 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index cb29d0f7..44a5821f 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -127,14 +127,16 @@ smtp_send() { py*) _smtp_send=_smtp_send_python ;; *) _err "Can't figure out how to invoke $_SMTP_BIN." - _err "Please re-run with --debug and report a bug." + _err "Check your SMTP_BIN setting." return 1 ;; esac if ! smtp_output="$($_smtp_send)"; then _err "Error sending message with $_SMTP_BIN." - _err "${smtp_output:-(No additional details; try --debug or --debug 2)}" + if [ -n "$smtp_output" ]; then + _err "$smtp_output" + fi return 1 fi @@ -152,12 +154,109 @@ smtp_send() { return 0 } - # Send the message via curl using _SMTP_* variables _smtp_send_curl() { - # TODO: implement - echo "_smtp_send_curl not implemented" - return 1 + # curl passes --mail-from and --mail-rcpt directly to the SMTP protocol without + # additional parsing, and SMTP requires addr-spec only (no display names). + # In the future, maybe try to parse the addr-spec out for curl args (non-trivial). + if _email_has_display_name "$_SMTP_FROM"; then + _err "curl smtp only allows a simple email address in SMTP_FROM." + _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." + return 1 + fi + if _email_has_display_name "$_SMTP_TO"; then + _err "curl smtp only allows simple email addresses in SMTP_TO." + _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." + return 1 + fi + + # Build curl args in $@ + + case "$_SMTP_SECURE" in + none) + set -- --url "smtp://${_SMTP_HOST}:${_SMTP_PORT}" + ;; + ssl) + set -- --url "smtps://${_SMTP_HOST}:${_SMTP_PORT}" + ;; + tls) + set -- --url "smtp://${_SMTP_HOST}:${_SMTP_PORT}" --ssl-reqd + ;; + *) + # This will only occur if someone adds a new SMTP_SECURE option above + # without updating this code for it. + _err "Unhandled _SMTP_SECURE='$_SMTP_SECURE' in _smtp_send_curl" + _err "Please re-run with --debug and report a bug." + return 1 + ;; + esac + + set -- "$@" \ + --upload-file - \ + --mail-from "$_SMTP_FROM" \ + --max-time "$_SMTP_TIMEOUT" + + # Burst comma-separated $_SMTP_TO into individual --mail-rcpt args. + _to="${_SMTP_TO}," + while [ -n "$_to" ]; do + _rcpt="${_to%%,*}" + _to="${_to#*,}" + set -- "$@" --mail-rcpt "$_rcpt" + done + + _smtp_login="${_SMTP_USERNAME}:${_SMTP_PASSWORD}" + if [ "$_smtp_login" != ":" ]; then + set -- "$@" --user "$_smtp_login" + fi + + if [ "$_SMTP_SHOW_TRANSCRIPT" = "True" ]; then + set -- "$@" --verbose + else + set -- "$@" --silent --show-error + fi + + raw_message="$(_smtp_raw_message)" + + _debug2 "curl command:" "$_SMTP_BIN" "$*" + _debug2 "raw_message:\n$raw_message" + + echo "$raw_message" | "$_SMTP_BIN" "$@" +} + +# Output an RFC-822 / RFC-5322 email message using _SMTP_* variables +_smtp_raw_message() { + echo "From: $_SMTP_FROM" + echo "To: $_SMTP_TO" + echo "Subject: $(_mime_encoded_word "$_SMTP_SUBJECT")" + if _exists date; then + echo "Date: $(date +'%a, %-d %b %Y %H:%M:%S %z')" + fi + echo "Content-Type: text/plain; charset=utf-8" + echo "X-Mailer: acme.sh --notify-hook smtp" + echo + echo "$_SMTP_CONTENT" +} + +# Convert text to RFC-2047 MIME "encoded word" format if it contains non-ASCII chars +# text +_mime_encoded_word() { + _text="$1" + # (regex character ranges like [a-z] can be locale-dependent; enumerate ASCII chars to avoid that) + _ascii='] $`"'"[!#%&'()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ~^_abcdefghijklmnopqrstuvwxyz{|}~-" + if expr "$_text" : "^.*[^$_ascii]" >/dev/null; then + # At least one non-ASCII char; convert entire thing to encoded word + printf "%s" "=?UTF-8?B?$(printf "%s" "$_text" | _base64)?=" + else + # Just printable ASCII, no conversion needed + printf "%s" "$_text" + fi +} + +# Simple check for display name in an email address (< > or ") +# email +_email_has_display_name() { + _email="$1" + expr "$_email" : '^.*[<>"]' > /dev/null } From ffe7ef476439df04e1878ea08f0c6b3eb91653c6 Mon Sep 17 00:00:00 2001 From: medmunds Date: Sun, 14 Feb 2021 20:06:07 -0800 Subject: [PATCH 1238/2234] More than one blank line is an abomination, apparently I will not try to use whitespace to group code visually --- notify/smtp.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 44a5821f..c9927e3e 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -256,10 +256,9 @@ _mime_encoded_word() { # email _email_has_display_name() { _email="$1" - expr "$_email" : '^.*[<>"]' > /dev/null + expr "$_email" : '^.*[<>"]' >/dev/null } - # Send the message via Python using _SMTP_* variables _smtp_send_python() { _debug "Python version" "$("$_SMTP_BIN" --version 2>&1)" From bf8c33703c3b69de79a992f1ca84748fa4bc1707 Mon Sep 17 00:00:00 2001 From: Mike Edmunds Date: Sun, 14 Feb 2021 23:01:21 -0800 Subject: [PATCH 1239/2234] Fix: Unifi deploy hook support Unifi Cloud Key (#3327) * fix: unifi deploy hook also update Cloud Key nginx certs When running on a Unifi Cloud Key device, also deploy to /etc/ssl/private/cloudkey.{crt,key} and reload nginx. This makes the new cert available for the Cloud Key management app running via nginx on port 443 (as well as the port 8443 Unifi Controller app the deploy hook already supported). Fixes #3326 * Improve settings documentation comments * Improve Cloud Key pre-flight error messaging * Fix typo * Add support for UnifiOS (Cloud Key Gen2) Since UnifiOS does not use the Java keystore (like a Unifi Controller or Cloud Key Gen1 deploy), this also reworks the settings validation and error messaging somewhat. * PR review fixes * Detect unsupported Cloud Key java keystore location * Don't try to restart inactive services (and remove extra spaces from reload command) * Clean up error messages and internal variables * Change to _getdeployconf/_savedeployconf * Switch from cp to cat to preserve file permissions --- deploy/unifi.sh | 224 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 169 insertions(+), 55 deletions(-) diff --git a/deploy/unifi.sh b/deploy/unifi.sh index 184aa62e..a864135e 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -1,12 +1,43 @@ #!/usr/bin/env sh -#Here is a script to deploy cert to unifi server. +# Here is a script to deploy cert on a Unifi Controller or Cloud Key device. +# It supports: +# - self-hosted Unifi Controller +# - Unifi Cloud Key (Gen1/2/2+) +# - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only) +# Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359 #returns 0 means success, otherwise error. +# The deploy-hook automatically detects standard Unifi installations +# for each of the supported environments. Most users should not need +# to set any of these variables, but if you are running a self-hosted +# Controller with custom locations, set these as necessary before running +# the deploy hook. (Defaults shown below.) +# +# Settings for Unifi Controller: +# Location of Java keystore or unifi.keystore.jks file: #DEPLOY_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore" +# Keystore password (built into Unifi Controller, not a user-set password): #DEPLOY_UNIFI_KEYPASS="aircontrolenterprise" +# Command to restart Unifi Controller: #DEPLOY_UNIFI_RELOAD="service unifi restart" +# +# Settings for Unifi Cloud Key Gen1 (nginx admin pages): +# Directory where cloudkey.crt and cloudkey.key live: +#DEPLOY_UNIFI_CLOUDKEY_CERTDIR="/etc/ssl/private" +# Command to restart maintenance pages and Controller +# (same setting as above, default is updated when running on Cloud Key Gen1): +#DEPLOY_UNIFI_RELOAD="service nginx restart && service unifi restart" +# +# Settings for UnifiOS (Cloud Key Gen2): +# Directory where unifi-core.crt and unifi-core.key live: +#DEPLOY_UNIFI_CORE_CONFIG="/data/unifi-core/config/" +# Command to restart unifi-core: +#DEPLOY_UNIFI_RELOAD="systemctl restart unifi-core" +# +# At least one of DEPLOY_UNIFI_KEYSTORE, DEPLOY_UNIFI_CLOUDKEY_CERTDIR, +# or DEPLOY_UNIFI_CORE_CONFIG must exist to receive the deployed certs. ######## Public functions ##################### @@ -24,77 +55,160 @@ unifi_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - if ! _exists keytool; then - _err "keytool not found" - return 1 - fi + _getdeployconf DEPLOY_UNIFI_KEYSTORE + _getdeployconf DEPLOY_UNIFI_KEYPASS + _getdeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR + _getdeployconf DEPLOY_UNIFI_CORE_CONFIG + _getdeployconf DEPLOY_UNIFI_RELOAD - DEFAULT_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore" - _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-$DEFAULT_UNIFI_KEYSTORE}" - DEFAULT_UNIFI_KEYPASS="aircontrolenterprise" - _unifi_keypass="${DEPLOY_UNIFI_KEYPASS:-$DEFAULT_UNIFI_KEYPASS}" - DEFAULT_UNIFI_RELOAD="service unifi restart" - _reload="${DEPLOY_UNIFI_RELOAD:-$DEFAULT_UNIFI_RELOAD}" + _debug2 DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" + _debug2 DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" + _debug2 DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" + _debug2 DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG" + _debug2 DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" - _debug _unifi_keystore "$_unifi_keystore" - if [ ! -f "$_unifi_keystore" ]; then - if [ -z "$DEPLOY_UNIFI_KEYSTORE" ]; then - _err "unifi keystore is not found, please define DEPLOY_UNIFI_KEYSTORE" - return 1 - else - _err "It seems that the specified unifi keystore is not valid, please check." + # Space-separated list of environments detected and installed: + _services_updated="" + + # Default reload commands accumulated as we auto-detect environments: + _reload_cmd="" + + # Unifi Controller environment (self hosted or any Cloud Key) -- + # auto-detect by file /usr/lib/unifi/data/keystore: + _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}" + if [ -f "$_unifi_keystore" ]; then + _info "Installing certificate for Unifi Controller (Java keystore)" + _debug _unifi_keystore "$_unifi_keystore" + if ! _exists keytool; then + _err "keytool not found" return 1 fi - fi - if [ ! -w "$_unifi_keystore" ]; then - _err "The file $_unifi_keystore is not writable, please change the permission." + if [ ! -w "$_unifi_keystore" ]; then + _err "The file $_unifi_keystore is not writable, please change the permission." + return 1 + fi + + _unifi_keypass="${DEPLOY_UNIFI_KEYPASS:-aircontrolenterprise}" + + _debug "Generate import pkcs12" + _import_pkcs12="$(_mktemp)" + _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root + # shellcheck disable=SC2181 + if [ "$?" != "0" ]; then + _err "Error generating pkcs12. Please re-run with --debug and report a bug." + return 1 + fi + + _debug "Import into keystore: $_unifi_keystore" + if keytool -importkeystore \ + -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ + -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ + -alias unifi -noprompt; then + _debug "Import keystore success!" + rm "$_import_pkcs12" + else + _err "Error importing into Unifi Java keystore." + _err "Please re-run with --debug and report a bug." + rm "$_import_pkcs12" + return 1 + fi + + if systemctl -q is-active unifi; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart" + fi + _services_updated="${_services_updated} unifi" + _info "Install Unifi Controller certificate success!" + elif [ "$DEPLOY_UNIFI_KEYSTORE" ]; then + _err "The specified DEPLOY_UNIFI_KEYSTORE='$DEPLOY_UNIFI_KEYSTORE' is not valid, please check." return 1 fi - _info "Generate import pkcs12" - _import_pkcs12="$(_mktemp)" - _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root - if [ "$?" != "0" ]; then - _err "Oops, error creating import pkcs12, please report bug to us." + # Cloud Key environment (non-UnifiOS -- nginx serves admin pages) -- + # auto-detect by file /etc/ssl/private/cloudkey.key: + _cloudkey_certdir="${DEPLOY_UNIFI_CLOUDKEY_CERTDIR:-/etc/ssl/private}" + if [ -f "${_cloudkey_certdir}/cloudkey.key" ]; then + _info "Installing certificate for Cloud Key Gen1 (nginx admin pages)" + _debug _cloudkey_certdir "$_cloudkey_certdir" + if [ ! -w "$_cloudkey_certdir" ]; then + _err "The directory $_cloudkey_certdir is not writable; please check permissions." + return 1 + fi + # Cloud Key expects to load the keystore from /etc/ssl/private/unifi.keystore.jks. + # Normally /usr/lib/unifi/data/keystore is a symlink there (so the keystore was + # updated above), but if not, we don't know how to handle this installation: + if ! cmp -s "$_unifi_keystore" "${_cloudkey_certdir}/unifi.keystore.jks"; then + _err "Unsupported Cloud Key configuration: keystore not found at '${_cloudkey_certdir}/unifi.keystore.jks'" + return 1 + fi + + cat "$_cfullchain" >"${_cloudkey_certdir}/cloudkey.crt" + cat "$_ckey" >"${_cloudkey_certdir}/cloudkey.key" + (cd "$_cloudkey_certdir" && tar -cf cert.tar cloudkey.crt cloudkey.key unifi.keystore.jks) + + if systemctl -q is-active nginx; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }service nginx restart" + fi + _info "Install Cloud Key Gen1 certificate success!" + _services_updated="${_services_updated} nginx" + elif [ "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" ]; then + _err "The specified DEPLOY_UNIFI_CLOUDKEY_CERTDIR='$DEPLOY_UNIFI_CLOUDKEY_CERTDIR' is not valid, please check." return 1 fi - _info "Modify unifi keystore: $_unifi_keystore" - if keytool -importkeystore \ - -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ - -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ - -alias unifi -noprompt; then - _info "Import keystore success!" - rm "$_import_pkcs12" - else - _err "Import unifi keystore error, please report bug to us." - rm "$_import_pkcs12" + # UnifiOS environment -- auto-detect by /data/unifi-core/config/unifi-core.key: + _unifi_core_config="${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}" + if [ -f "${_unifi_core_config}/unifi-core.key" ]; then + _info "Installing certificate for UnifiOS" + _debug _unifi_core_config "$_unifi_core_config" + if [ ! -w "$_unifi_core_config" ]; then + _err "The directory $_unifi_core_config is not writable; please check permissions." + return 1 + fi + + cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" + cat "$_ckey" >"${_unifi_core_config}/unifi-core.key" + + if systemctl -q is-active unifi-core; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi-core" + fi + _info "Install UnifiOS certificate success!" + _services_updated="${_services_updated} unifi-core" + elif [ "$DEPLOY_UNIFI_CORE_CONFIG" ]; then + _err "The specified DEPLOY_UNIFI_CORE_CONFIG='$DEPLOY_UNIFI_CORE_CONFIG' is not valid, please check." return 1 fi - _info "Run reload: $_reload" - if eval "$_reload"; then + if [ -z "$_services_updated" ]; then + # None of the Unifi environments were auto-detected, so no deployment has occurred + # (and none of DEPLOY_UNIFI_{KEYSTORE,CLOUDKEY_CERTDIR,CORE_CONFIG} were set). + _err "Unable to detect Unifi environment in standard location." + _err "(This deploy hook must be run on the Unifi device, not a remote machine.)" + _err "For non-standard Unifi installations, set DEPLOY_UNIFI_KEYSTORE," + _err "DEPLOY_UNIFI_CLOUDKEY_CERTDIR, and/or DEPLOY_UNIFI_CORE_CONFIG as appropriate." + return 1 + fi + + _reload_cmd="${DEPLOY_UNIFI_RELOAD:-$_reload_cmd}" + if [ -z "$_reload_cmd" ]; then + _err "Certificates were installed for services:${_services_updated}," + _err "but none appear to be active. Please set DEPLOY_UNIFI_RELOAD" + _err "to a command that will restart the necessary services." + return 1 + fi + _info "Reload services (this may take some time): $_reload_cmd" + if eval "$_reload_cmd"; then _info "Reload success!" - if [ "$DEPLOY_UNIFI_KEYSTORE" ]; then - _savedomainconf DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" - else - _cleardomainconf DEPLOY_UNIFI_KEYSTORE - fi - if [ "$DEPLOY_UNIFI_KEYPASS" ]; then - _savedomainconf DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" - else - _cleardomainconf DEPLOY_UNIFI_KEYPASS - fi - if [ "$DEPLOY_UNIFI_RELOAD" ]; then - _savedomainconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" - else - _cleardomainconf DEPLOY_UNIFI_RELOAD - fi - return 0 else _err "Reload error" return 1 fi - return 0 + # Successful, so save all (non-default) config: + _savedeployconf DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" + _savedeployconf DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" + _savedeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" + _savedeployconf DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG" + _savedeployconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" + + return 0 } From 86639dbc026157aecf6652345b7461c5d18a4647 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 15 Feb 2021 15:18:49 +0800 Subject: [PATCH 1240/2234] feat: add huaweicloud error handling --- dnsapi/dns_huaweicloud.sh | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 74fec2a9..f7192725 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -5,7 +5,7 @@ # HUAWEICLOUD_ProjectID iam_api="https://iam.myhuaweicloud.com" -dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" +dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work ######## Public functions ##################### @@ -29,16 +29,27 @@ dns_huaweicloud_add() { return 1 fi + unset token # Clear token token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" - _debug2 "${token}" + if [ -z "${token}" ]; then # Check token + _err "dns_api(dns_huaweicloud): Error getting token." + return 1 + fi + _debug "Access token is: ${token}" + + unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" - _debug "${zoneid}" + if [ -z "${zoneid}" ]; then + _err "dns_api(dns_huaweicloud): Error getting zone id." + return 1 + fi + _debug "Zone ID is: ${zoneid}" _debug "Adding Record" _add_record "${token}" "${fulldomain}" "${txtvalue}" ret="$?" if [ "${ret}" != "0" ]; then - _err "dns_huaweicloud: Error adding record." + _err "dns_api(dns_huaweicloud): Error adding record." return 1 fi @@ -69,12 +80,21 @@ dns_huaweicloud_rm() { return 1 fi + unset token # Clear token token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" - _debug2 "${token}" + if [ -z "${token}" ]; then # Check token + _err "dns_api(dns_huaweicloud): Error getting token." + return 1 + fi + _debug "Access token is: ${token}" + + unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" - _debug "${zoneid}" - record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" - _debug "Record Set ID is: ${record_id}" + if [ -z "${zoneid}" ]; then + _err "dns_api(dns_huaweicloud): Error getting zone id." + return 1 + fi + _debug "Zone ID is: ${zoneid}" # Remove all records # Therotically HuaweiCloud does not allow more than one record set From 31f65b89bb5cfd3604ff2fd386e515e325560a0d Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 15 Feb 2021 15:19:18 +0800 Subject: [PATCH 1241/2234] fix: fix freebsd and solaris --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 5dc2d453..ed0426ad 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -184,7 +184,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.7 + - uses: vmactions/freebsd-vm@v0.1.2 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl @@ -223,7 +223,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.1 + - uses: vmactions/solaris-vm@v0.0.3 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat curl From 4528957235ce99809841f078d997558bf4f339da Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 15 Feb 2021 21:25:27 +0800 Subject: [PATCH 1242/2234] support openssl 3.0 fix https://github.com/acmesh-official/acme.sh/issues/3399 --- acme.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index a9301e10..2cb9dd00 100755 --- a/acme.sh +++ b/acme.sh @@ -1122,9 +1122,14 @@ _createkey() { fi fi + __traditional="" + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help genrsa 2>&1)" "-traditional"; then + __traditional="-traditional" + fi + if _isEccKey "$length"; then _debug "Using ec name: $eccname" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam $__traditional -name "$eccname" -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error ecc key name: $eccname" @@ -1132,7 +1137,7 @@ _createkey() { fi else _debug "Using RSA: $length" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa "$length" 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa $__traditional "$length" 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error rsa key: $length" From 906ef43c00129d07540cb712f035b844ced69cfc Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 15 Feb 2021 21:35:59 +0800 Subject: [PATCH 1243/2234] make the fix for rsa key only --- acme.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 2cb9dd00..5e9829a4 100755 --- a/acme.sh +++ b/acme.sh @@ -1122,14 +1122,9 @@ _createkey() { fi fi - __traditional="" - if _contains "$(${ACME_OPENSSL_BIN:-openssl} help genrsa 2>&1)" "-traditional"; then - __traditional="-traditional" - fi - if _isEccKey "$length"; then _debug "Using ec name: $eccname" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam $__traditional -name "$eccname" -genkey 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error ecc key name: $eccname" @@ -1137,6 +1132,10 @@ _createkey() { fi else _debug "Using RSA: $length" + __traditional="" + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help genrsa 2>&1)" "-traditional"; then + __traditional="-traditional" + fi if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa $__traditional "$length" 2>/dev/null)"; then echo "$_opkey" >"$f" else From 6ff75f9a9fe906ed1c1b9cbf637b0e749ba9e127 Mon Sep 17 00:00:00 2001 From: medmunds Date: Mon, 15 Feb 2021 12:23:48 -0800 Subject: [PATCH 1244/2234] Use PROJECT_NAME and VER for X-Mailer header Also add X-Mailer header to Python version --- notify/smtp.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index c9927e3e..bb71a563 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -112,6 +112,7 @@ smtp_send() { _SMTP_USERNAME="$SMTP_USERNAME" _SMTP_PASSWORD="$SMTP_PASSWORD" _SMTP_TIMEOUT="${SMTP_TIMEOUT:-30}" + _SMTP_X_MAILER="${PROJECT_NAME} ${VER} --notify-hook smtp" # Run with --debug 2 (or above) to echo the transcript of the SMTP session. # Careful: this may include SMTP_PASSWORD in plaintext! @@ -232,7 +233,7 @@ _smtp_raw_message() { echo "Date: $(date +'%a, %-d %b %Y %H:%M:%S %z')" fi echo "Content-Type: text/plain; charset=utf-8" - echo "X-Mailer: acme.sh --notify-hook smtp" + echo "X-Mailer: $_SMTP_X_MAILER" echo echo "$_SMTP_CONTENT" } @@ -286,6 +287,7 @@ smtp_secure = """$_SMTP_SECURE""" username = """$_SMTP_USERNAME""" password = """$_SMTP_PASSWORD""" timeout=int("""$_SMTP_TIMEOUT""") # seconds +x_mailer="""$_SMTP_X_MAILER""" from_email="""$_SMTP_FROM""" to_emails="""$_SMTP_TO""" # can be comma-separated @@ -301,6 +303,7 @@ except (AttributeError, TypeError): msg["Subject"] = subject msg["From"] = from_email msg["To"] = to_emails +msg["X-Mailer"] = x_mailer smtp = None try: From 585c0c381852ebc796018a79d02fdac3f5666773 Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 16 Feb 2021 09:33:39 -0800 Subject: [PATCH 1245/2234] Add _clearaccountconf_mutable() --- acme.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/acme.sh b/acme.sh index a9301e10..bb4134de 100755 --- a/acme.sh +++ b/acme.sh @@ -2279,6 +2279,13 @@ _clearaccountconf() { _clear_conf "$ACCOUNT_CONF_PATH" "$1" } +#key +_clearaccountconf_mutable() { + _clearaccountconf "SAVED_$1" + #remove later + _clearaccountconf "$1" +} + #_savecaconf key value _savecaconf() { _save_conf "$CA_CONF" "$1" "$2" From 6e77756d6a0b3d71f0ecc014d6336a8e6b025db1 Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 16 Feb 2021 12:49:27 -0800 Subject: [PATCH 1246/2234] Rework read/save config to not save default values Add and use _readaccountconf_mutable_default and _saveaccountconf_mutable_default helpers to capture common default value handling. New approach also eliminates need for separate underscore-prefixed version of each conf var. --- notify/smtp.sh | 253 +++++++++++++++++++++++++++++-------------------- 1 file changed, 148 insertions(+), 105 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index bb71a563..85801604 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -17,155 +17,150 @@ # SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout # SMTP_BIN="/path/to/curl_or_python" # default finds first of curl, python3, or python on PATH +SMTP_SECURE_DEFAULT="none" +SMTP_TIMEOUT_DEFAULT="30" + # subject content statuscode smtp_send() { - _SMTP_SUBJECT="$1" - _SMTP_CONTENT="$2" + SMTP_SUBJECT="$1" + SMTP_CONTENT="$2" # UNUSED: _statusCode="$3" # 0: success, 1: error 2($RENEW_SKIP): skipped - # Load config: - SMTP_FROM="${SMTP_FROM:-$(_readaccountconf_mutable SMTP_FROM)}" - SMTP_TO="${SMTP_TO:-$(_readaccountconf_mutable SMTP_TO)}" - SMTP_HOST="${SMTP_HOST:-$(_readaccountconf_mutable SMTP_HOST)}" - SMTP_PORT="${SMTP_PORT:-$(_readaccountconf_mutable SMTP_PORT)}" - SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" - SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" - SMTP_PASSWORD="${SMTP_PASSWORD:-$(_readaccountconf_mutable SMTP_PASSWORD)}" - SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" - SMTP_BIN="${SMTP_BIN:-$(_readaccountconf_mutable SMTP_BIN)}" - - _debug "SMTP_FROM" "$SMTP_FROM" - _debug "SMTP_TO" "$SMTP_TO" - _debug "SMTP_HOST" "$SMTP_HOST" - _debug "SMTP_PORT" "$SMTP_PORT" - _debug "SMTP_SECURE" "$SMTP_SECURE" - _debug "SMTP_USERNAME" "$SMTP_USERNAME" - _secure_debug "SMTP_PASSWORD" "$SMTP_PASSWORD" - _debug "SMTP_TIMEOUT" "$SMTP_TIMEOUT" - _debug "SMTP_BIN" "$SMTP_BIN" - - _debug "_SMTP_SUBJECT" "$_SMTP_SUBJECT" - _debug "_SMTP_CONTENT" "$_SMTP_CONTENT" - - # Validate config and apply defaults: - # _SMTP_* variables are the resolved (with defaults) versions of SMTP_*. - # (The _SMTP_* versions will not be stored in account conf.) - + # Load and validate config: + SMTP_BIN="$(_readaccountconf_mutable_default SMTP_BIN)" if [ -n "$SMTP_BIN" ] && ! _exists "$SMTP_BIN"; then _err "SMTP_BIN '$SMTP_BIN' does not exist." return 1 fi - _SMTP_BIN="$SMTP_BIN" - if [ -z "$_SMTP_BIN" ]; then + if [ -z "$SMTP_BIN" ]; then # Look for a command that can communicate with an SMTP server. # (Please don't add sendmail, ssmtp, mutt, mail, or msmtp here. # Those are already handled by the "mail" notify hook.) for cmd in curl python3 python2.7 python pypy3 pypy; do if _exists "$cmd"; then - _SMTP_BIN="$cmd" + SMTP_BIN="$cmd" break fi done - if [ -z "$_SMTP_BIN" ]; then + if [ -z "$SMTP_BIN" ]; then _err "The smtp notify-hook requires curl or Python, but can't find any." _err 'If you have one of them, define SMTP_BIN="/path/to/curl_or_python".' _err 'Otherwise, see if you can use the "mail" notify-hook instead.' return 1 fi - _debug "_SMTP_BIN" "$_SMTP_BIN" fi + _debug SMTP_BIN "$SMTP_BIN" + _saveaccountconf_mutable_default SMTP_BIN "$SMTP_BIN" + SMTP_FROM="$(_readaccountconf_mutable_default SMTP_FROM)" if [ -z "$SMTP_FROM" ]; then _err "You must define SMTP_FROM as the sender email address." return 1 fi - _SMTP_FROM="$SMTP_FROM" + _debug SMTP_FROM "$SMTP_FROM" + _saveaccountconf_mutable_default SMTP_FROM "$SMTP_FROM" + SMTP_TO="$(_readaccountconf_mutable_default SMTP_TO)" if [ -z "$SMTP_TO" ]; then _err "You must define SMTP_TO as the recipient email address." return 1 fi - _SMTP_TO="$SMTP_TO" + _debug SMTP_TO "$SMTP_TO" + _saveaccountconf_mutable_default SMTP_TO "$SMTP_TO" + SMTP_HOST="$(_readaccountconf_mutable_default SMTP_HOST)" if [ -z "$SMTP_HOST" ]; then _err "You must define SMTP_HOST as the SMTP server hostname." return 1 fi - _SMTP_HOST="$SMTP_HOST" + _debug SMTP_HOST "$SMTP_HOST" + _saveaccountconf_mutable_default SMTP_HOST "$SMTP_HOST" - _SMTP_SECURE="${SMTP_SECURE:-none}" - case "$_SMTP_SECURE" in - "none") smtp_default_port="25" ;; - "ssl") smtp_default_port="465" ;; - "tls") smtp_default_port="587" ;; + SMTP_SECURE="$(_readaccountconf_mutable_default SMTP_SECURE "$SMTP_SECURE_DEFAULT")" + case "$SMTP_SECURE" in + "none") smtp_port_default="25" ;; + "ssl") smtp_port_default="465" ;; + "tls") smtp_port_default="587" ;; *) _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." return 1 ;; esac + _debug SMTP_SECURE "$SMTP_SECURE" + _saveaccountconf_mutable_default SMTP_SECURE "$SMTP_SECURE" "$SMTP_SECURE_DEFAULT" - _SMTP_PORT="${SMTP_PORT:-$smtp_default_port}" - if [ -z "$SMTP_PORT" ]; then - _debug "_SMTP_PORT" "$_SMTP_PORT" - fi + SMTP_PORT="$(_readaccountconf_mutable_default SMTP_PORT "$smtp_port_default")" + case "$SMTP_PORT" in + *[!0-9]*) + _err "Invalid SMTP_PORT='$SMTP_PORT'. It must be a port number." + return 1 + ;; + esac + _debug SMTP_PORT "$SMTP_PORT" + _saveaccountconf_mutable_default SMTP_PORT "$SMTP_PORT" "$smtp_port_default" - _SMTP_USERNAME="$SMTP_USERNAME" - _SMTP_PASSWORD="$SMTP_PASSWORD" - _SMTP_TIMEOUT="${SMTP_TIMEOUT:-30}" - _SMTP_X_MAILER="${PROJECT_NAME} ${VER} --notify-hook smtp" + SMTP_USERNAME="$(_readaccountconf_mutable_default SMTP_USERNAME)" + _debug SMTP_USERNAME "$SMTP_USERNAME" + _saveaccountconf_mutable_default SMTP_USERNAME "$SMTP_USERNAME" + + SMTP_PASSWORD="$(_readaccountconf_mutable_default SMTP_PASSWORD)" + _secure_debug SMTP_PASSWORD "$SMTP_PASSWORD" + _saveaccountconf_mutable_default SMTP_PASSWORD "$SMTP_PASSWORD" + + SMTP_TIMEOUT="$(_readaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT_DEFAULT")" + _debug SMTP_TIMEOUT "$SMTP_TIMEOUT" + _saveaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT" "$SMTP_TIMEOUT_DEFAULT" + + SMTP_X_MAILER="${PROJECT_NAME} ${VER} --notify-hook smtp" # Run with --debug 2 (or above) to echo the transcript of the SMTP session. # Careful: this may include SMTP_PASSWORD in plaintext! if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then - _SMTP_SHOW_TRANSCRIPT="True" + SMTP_SHOW_TRANSCRIPT="True" else - _SMTP_SHOW_TRANSCRIPT="" + SMTP_SHOW_TRANSCRIPT="" fi + _debug SMTP_SUBJECT "$SMTP_SUBJECT" + _debug SMTP_CONTENT "$SMTP_CONTENT" + # Send the message: - case "$(basename "$_SMTP_BIN")" in + case "$(basename "$SMTP_BIN")" in curl) _smtp_send=_smtp_send_curl ;; py*) _smtp_send=_smtp_send_python ;; *) - _err "Can't figure out how to invoke $_SMTP_BIN." + _err "Can't figure out how to invoke '$SMTP_BIN'." _err "Check your SMTP_BIN setting." return 1 ;; esac if ! smtp_output="$($_smtp_send)"; then - _err "Error sending message with $_SMTP_BIN." + _err "Error sending message with $SMTP_BIN." if [ -n "$smtp_output" ]; then _err "$smtp_output" fi return 1 fi - # Save config only if send was successful: - _saveaccountconf_mutable SMTP_BIN "$SMTP_BIN" - _saveaccountconf_mutable SMTP_FROM "$SMTP_FROM" - _saveaccountconf_mutable SMTP_TO "$SMTP_TO" - _saveaccountconf_mutable SMTP_HOST "$SMTP_HOST" - _saveaccountconf_mutable SMTP_PORT "$SMTP_PORT" - _saveaccountconf_mutable SMTP_SECURE "$SMTP_SECURE" - _saveaccountconf_mutable SMTP_USERNAME "$SMTP_USERNAME" - _saveaccountconf_mutable SMTP_PASSWORD "$SMTP_PASSWORD" - _saveaccountconf_mutable SMTP_TIMEOUT "$SMTP_TIMEOUT" - return 0 } -# Send the message via curl using _SMTP_* variables +## +## curl smtp sending +## + +# Send the message via curl using SMTP_* variables _smtp_send_curl() { # curl passes --mail-from and --mail-rcpt directly to the SMTP protocol without # additional parsing, and SMTP requires addr-spec only (no display names). # In the future, maybe try to parse the addr-spec out for curl args (non-trivial). - if _email_has_display_name "$_SMTP_FROM"; then + if _email_has_display_name "$SMTP_FROM"; then _err "curl smtp only allows a simple email address in SMTP_FROM." _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." return 1 fi - if _email_has_display_name "$_SMTP_TO"; then + if _email_has_display_name "$SMTP_TO"; then _err "curl smtp only allows simple email addresses in SMTP_TO." _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." return 1 @@ -173,20 +168,20 @@ _smtp_send_curl() { # Build curl args in $@ - case "$_SMTP_SECURE" in + case "$SMTP_SECURE" in none) - set -- --url "smtp://${_SMTP_HOST}:${_SMTP_PORT}" + set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" ;; ssl) - set -- --url "smtps://${_SMTP_HOST}:${_SMTP_PORT}" + set -- --url "smtps://${SMTP_HOST}:${SMTP_PORT}" ;; tls) - set -- --url "smtp://${_SMTP_HOST}:${_SMTP_PORT}" --ssl-reqd + set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" --ssl-reqd ;; *) # This will only occur if someone adds a new SMTP_SECURE option above # without updating this code for it. - _err "Unhandled _SMTP_SECURE='$_SMTP_SECURE' in _smtp_send_curl" + _err "Unhandled SMTP_SECURE='$SMTP_SECURE' in _smtp_send_curl" _err "Please re-run with --debug and report a bug." return 1 ;; @@ -194,23 +189,23 @@ _smtp_send_curl() { set -- "$@" \ --upload-file - \ - --mail-from "$_SMTP_FROM" \ - --max-time "$_SMTP_TIMEOUT" + --mail-from "$SMTP_FROM" \ + --max-time "$SMTP_TIMEOUT" - # Burst comma-separated $_SMTP_TO into individual --mail-rcpt args. - _to="${_SMTP_TO}," + # Burst comma-separated $SMTP_TO into individual --mail-rcpt args. + _to="${SMTP_TO}," while [ -n "$_to" ]; do _rcpt="${_to%%,*}" _to="${_to#*,}" set -- "$@" --mail-rcpt "$_rcpt" done - _smtp_login="${_SMTP_USERNAME}:${_SMTP_PASSWORD}" + _smtp_login="${SMTP_USERNAME}:${SMTP_PASSWORD}" if [ "$_smtp_login" != ":" ]; then set -- "$@" --user "$_smtp_login" fi - if [ "$_SMTP_SHOW_TRANSCRIPT" = "True" ]; then + if [ "$SMTP_SHOW_TRANSCRIPT" = "True" ]; then set -- "$@" --verbose else set -- "$@" --silent --show-error @@ -218,24 +213,24 @@ _smtp_send_curl() { raw_message="$(_smtp_raw_message)" - _debug2 "curl command:" "$_SMTP_BIN" "$*" + _debug2 "curl command:" "$SMTP_BIN" "$*" _debug2 "raw_message:\n$raw_message" - echo "$raw_message" | "$_SMTP_BIN" "$@" + echo "$raw_message" | "$SMTP_BIN" "$@" } -# Output an RFC-822 / RFC-5322 email message using _SMTP_* variables +# Output an RFC-822 / RFC-5322 email message using SMTP_* variables _smtp_raw_message() { - echo "From: $_SMTP_FROM" - echo "To: $_SMTP_TO" - echo "Subject: $(_mime_encoded_word "$_SMTP_SUBJECT")" + echo "From: $SMTP_FROM" + echo "To: $SMTP_TO" + echo "Subject: $(_mime_encoded_word "$SMTP_SUBJECT")" if _exists date; then echo "Date: $(date +'%a, %-d %b %Y %H:%M:%S %z')" fi echo "Content-Type: text/plain; charset=utf-8" - echo "X-Mailer: $_SMTP_X_MAILER" + echo "X-Mailer: $SMTP_X_MAILER" echo - echo "$_SMTP_CONTENT" + echo "$SMTP_CONTENT" } # Convert text to RFC-2047 MIME "encoded word" format if it contains non-ASCII chars @@ -260,12 +255,16 @@ _email_has_display_name() { expr "$_email" : '^.*[<>"]' >/dev/null } -# Send the message via Python using _SMTP_* variables +## +## Python smtp sending +## + +# Send the message via Python using SMTP_* variables _smtp_send_python() { - _debug "Python version" "$("$_SMTP_BIN" --version 2>&1)" + _debug "Python version" "$("$SMTP_BIN" --version 2>&1)" # language=Python - "$_SMTP_BIN" < Date: Tue, 16 Feb 2021 13:13:26 -0800 Subject: [PATCH 1247/2234] Implement _rfc2822_date helper --- notify/smtp.sh | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 85801604..43536cd2 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -224,9 +224,7 @@ _smtp_raw_message() { echo "From: $SMTP_FROM" echo "To: $SMTP_TO" echo "Subject: $(_mime_encoded_word "$SMTP_SUBJECT")" - if _exists date; then - echo "Date: $(date +'%a, %-d %b %Y %H:%M:%S %z')" - fi + echo "Date: $(_rfc2822_date)" echo "Content-Type: text/plain; charset=utf-8" echo "X-Mailer: $SMTP_X_MAILER" echo @@ -248,6 +246,19 @@ _mime_encoded_word() { fi } +# Output current date in RFC-2822 Section 3.3 format as required in email headers +# (e.g., "Mon, 15 Feb 2021 14:22:01 -0800") +_rfc2822_date() { + # Notes: + # - this is deliberately not UTC, because it "SHOULD express local time" per spec + # - the spec requires weekday and month in the C locale (English), not localized + # - this date format specifier has been tested on Linux, Mac, Solaris and FreeBSD + _old_lc_time="$LC_TIME" + LC_TIME=C + date +'%a, %-d %b %Y %H:%M:%S %z' + LC_TIME="$_old_lc_time" +} + # Simple check for display name in an email address (< > or ") # email _email_has_display_name() { From 4b615cb3a92fad0d65e8868408debbd82ca0f32e Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 16 Feb 2021 14:02:09 -0800 Subject: [PATCH 1248/2234] Clean email headers and warn on unsupported address format Just in case, make sure CR or NL don't end up in an email header. --- notify/smtp.sh | 55 +++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 43536cd2..42c1487c 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -53,16 +53,28 @@ smtp_send() { _saveaccountconf_mutable_default SMTP_BIN "$SMTP_BIN" SMTP_FROM="$(_readaccountconf_mutable_default SMTP_FROM)" + SMTP_FROM="$(_clean_email_header "$SMTP_FROM")" if [ -z "$SMTP_FROM" ]; then _err "You must define SMTP_FROM as the sender email address." return 1 fi + if _email_has_display_name "$SMTP_FROM"; then + _err "SMTP_FROM must be only a simple email address (sender@example.com)." + _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." + return 1 + fi _debug SMTP_FROM "$SMTP_FROM" _saveaccountconf_mutable_default SMTP_FROM "$SMTP_FROM" SMTP_TO="$(_readaccountconf_mutable_default SMTP_TO)" + SMTP_TO="$(_clean_email_header "$SMTP_TO")" if [ -z "$SMTP_TO" ]; then - _err "You must define SMTP_TO as the recipient email address." + _err "You must define SMTP_TO as the recipient email address(es)." + return 1 + fi + if _email_has_display_name "$SMTP_TO"; then + _err "SMTP_TO must be only simple email addresses (to@example.com,to2@example.com)." + _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." return 1 fi _debug SMTP_TO "$SMTP_TO" @@ -111,7 +123,7 @@ smtp_send() { _debug SMTP_TIMEOUT "$SMTP_TIMEOUT" _saveaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT" "$SMTP_TIMEOUT_DEFAULT" - SMTP_X_MAILER="${PROJECT_NAME} ${VER} --notify-hook smtp" + SMTP_X_MAILER="$(_clean_email_header "$PROJECT_NAME $VER --notify-hook smtp")" # Run with --debug 2 (or above) to echo the transcript of the SMTP session. # Careful: this may include SMTP_PASSWORD in plaintext! @@ -121,6 +133,7 @@ smtp_send() { SMTP_SHOW_TRANSCRIPT="" fi + SMTP_SUBJECT=$(_clean_email_header "$SMTP_SUBJECT") _debug SMTP_SUBJECT "$SMTP_SUBJECT" _debug SMTP_CONTENT "$SMTP_CONTENT" @@ -146,28 +159,26 @@ smtp_send() { return 0 } +# Strip CR and NL from text to prevent MIME header injection +# text +_clean_email_header() { + printf "%s" "$(echo "$1" | tr -d "\r\n")" +} + +# Simple check for display name in an email address (< > or ") +# email +_email_has_display_name() { + _email="$1" + expr "$_email" : '^.*[<>"]' >/dev/null +} + ## ## curl smtp sending ## # Send the message via curl using SMTP_* variables _smtp_send_curl() { - # curl passes --mail-from and --mail-rcpt directly to the SMTP protocol without - # additional parsing, and SMTP requires addr-spec only (no display names). - # In the future, maybe try to parse the addr-spec out for curl args (non-trivial). - if _email_has_display_name "$SMTP_FROM"; then - _err "curl smtp only allows a simple email address in SMTP_FROM." - _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." - return 1 - fi - if _email_has_display_name "$SMTP_TO"; then - _err "curl smtp only allows simple email addresses in SMTP_TO." - _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." - return 1 - fi - # Build curl args in $@ - case "$SMTP_SECURE" in none) set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" @@ -219,7 +230,8 @@ _smtp_send_curl() { echo "$raw_message" | "$SMTP_BIN" "$@" } -# Output an RFC-822 / RFC-5322 email message using SMTP_* variables +# Output an RFC-822 / RFC-5322 email message using SMTP_* variables. +# (This assumes variables have already been cleaned for use in email headers.) _smtp_raw_message() { echo "From: $SMTP_FROM" echo "To: $SMTP_TO" @@ -259,13 +271,6 @@ _rfc2822_date() { LC_TIME="$_old_lc_time" } -# Simple check for display name in an email address (< > or ") -# email -_email_has_display_name() { - _email="$1" - expr "$_email" : '^.*[<>"]' >/dev/null -} - ## ## Python smtp sending ## From 5a182eddbf4ffafcc1b8a1b3757a49378f46af5f Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 16 Feb 2021 14:41:21 -0800 Subject: [PATCH 1249/2234] Clarify _readaccountconf_mutable_default --- notify/smtp.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 42c1487c..fabde79b 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -358,7 +358,7 @@ PYTHON # - if MY_CONF is set _empty_, output $default_value # (lets user `export MY_CONF=` to clear previous saved value # and return to default, without user having to know default) -# - otherwise if _readaccountconf_mutable $name is non-empty, return that +# - otherwise if _readaccountconf_mutable MY_CONF is non-empty, return that # (value of SAVED_MY_CONF from account.conf) # - otherwise output $default_value _readaccountconf_mutable_default() { @@ -366,8 +366,9 @@ _readaccountconf_mutable_default() { _default_value="$2" eval "_value=\"\$$_name\"" - eval "_explicit_empty_value=\"\${${_name}+empty}\"" - if [ -z "${_value}" ] && [ "${_explicit_empty_value:-}" != "empty" ]; then + eval "_name_is_set=\"\${${_name}+true}\"" + # ($_name_is_set is "true" if $$_name is set to anything, including empty) + if [ -z "${_value}" ] && [ "${_name_is_set:-}" != "true" ]; then _value="$(_readaccountconf_mutable "$_name")" fi if [ -z "${_value}" ]; then From 8f688e5e13b9cdc77134eb97dcc07435912dc4aa Mon Sep 17 00:00:00 2001 From: medmunds Date: Wed, 17 Feb 2021 09:46:13 -0800 Subject: [PATCH 1250/2234] Add Date email header in Python implementation --- notify/smtp.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/notify/smtp.sh b/notify/smtp.sh index fabde79b..0c698631 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -287,6 +287,7 @@ try: from email.message import EmailMessage except ImportError: from email.mime.text import MIMEText as EmailMessage # Python 2 + from email.utils import formatdate as rfc2822_date from smtplib import SMTP, SMTP_SSL, SMTPException from socket import error as SocketError except ImportError as err: @@ -318,6 +319,7 @@ except (AttributeError, TypeError): msg["Subject"] = subject msg["From"] = from_email msg["To"] = to_emails +msg["Date"] = rfc2822_date(localtime=True) msg["X-Mailer"] = x_mailer smtp = None From 28d9f00610b11254b43bf38d028524db859e588f Mon Sep 17 00:00:00 2001 From: medmunds Date: Wed, 17 Feb 2021 09:57:44 -0800 Subject: [PATCH 1251/2234] Use email.policy.default in Python 3 implementation Improves standards compatibility and utf-8 handling in Python 3.3-3.8. (email.policy.default becomes the default in Python 3.9.) --- notify/smtp.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 0c698631..69863206 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -285,8 +285,11 @@ _smtp_send_python() { try: try: from email.message import EmailMessage + from email.policy import default as email_policy_default except ImportError: - from email.mime.text import MIMEText as EmailMessage # Python 2 + # Python 2 (or < 3.3) + from email.mime.text import MIMEText as EmailMessage + email_policy_default = None from email.utils import formatdate as rfc2822_date from smtplib import SMTP, SMTP_SSL, SMTPException from socket import error as SocketError @@ -311,7 +314,7 @@ subject="""$SMTP_SUBJECT""" content="""$SMTP_CONTENT""" try: - msg = EmailMessage() + msg = EmailMessage(policy=email_policy_default) msg.set_content(content) except (AttributeError, TypeError): # Python 2 MIMEText From 6e49c4ffe006c45128c4ad8535e34e39b93901e2 Mon Sep 17 00:00:00 2001 From: medmunds Date: Wed, 17 Feb 2021 10:02:14 -0800 Subject: [PATCH 1252/2234] Prefer Python to curl when both available --- notify/smtp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 69863206..71020818 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -15,7 +15,7 @@ # SMTP_USERNAME="" # set if SMTP server requires login # SMTP_PASSWORD="" # set if SMTP server requires login # SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout -# SMTP_BIN="/path/to/curl_or_python" # default finds first of curl, python3, or python on PATH +# SMTP_BIN="/path/to/python_or_curl" # default finds first of python3, python2.7, python, pypy3, pypy, curl on PATH SMTP_SECURE_DEFAULT="none" SMTP_TIMEOUT_DEFAULT="30" @@ -36,7 +36,7 @@ smtp_send() { # Look for a command that can communicate with an SMTP server. # (Please don't add sendmail, ssmtp, mutt, mail, or msmtp here. # Those are already handled by the "mail" notify hook.) - for cmd in curl python3 python2.7 python pypy3 pypy; do + for cmd in python3 python2.7 python pypy3 pypy curl; do if _exists "$cmd"; then SMTP_BIN="$cmd" break From afe6f4030e9f7ec5c03146dd4dfe122d1ab7aab1 Mon Sep 17 00:00:00 2001 From: medmunds Date: Wed, 17 Feb 2021 11:39:16 -0800 Subject: [PATCH 1253/2234] Change default SMTP_SECURE to "tls" Secure by default. Also try to minimize configuration errors. (Many ESPs/ISPs require STARTTLS, and most support it.) --- notify/smtp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 71020818..293c665e 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -11,13 +11,13 @@ # SMTP_TO="to@example.com" # required # SMTP_HOST="smtp.example.com" # required # SMTP_PORT="25" # defaults to 25, 465 or 587 depending on SMTP_SECURE -# SMTP_SECURE="none" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) +# SMTP_SECURE="tls" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) # SMTP_USERNAME="" # set if SMTP server requires login # SMTP_PASSWORD="" # set if SMTP server requires login # SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout # SMTP_BIN="/path/to/python_or_curl" # default finds first of python3, python2.7, python, pypy3, pypy, curl on PATH -SMTP_SECURE_DEFAULT="none" +SMTP_SECURE_DEFAULT="tls" SMTP_TIMEOUT_DEFAULT="30" # subject content statuscode From 17f5e557ed07dfcc65d7ea808d2e27fbfc0acf7f Mon Sep 17 00:00:00 2001 From: czeming Date: Sat, 20 Feb 2021 17:16:33 +0800 Subject: [PATCH 1254/2234] Update dns_dp.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 没有encode中文字符会导致提交失败 --- dnsapi/dns_dp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 033fa5aa..9b8b7a8b 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -89,7 +89,7 @@ add_record() { _info "Adding record" - if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then + if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=%E9%BB%98%E8%AE%A4"; then return 1 fi From eacc00f7868dc01c8df4de43474910863fc12bed Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 21 Feb 2021 22:42:24 +0100 Subject: [PATCH 1255/2234] Update truenas.sh - check if curl exists - check if wget exist, then errortext and exit scipt - _get command "restartUI" wirh info about curl error 52 --- deploy/truenas.sh | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index be8fac12..1be4aeb0 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -35,6 +35,19 @@ truenas_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" + if _exists "curl"; then + _debug "curl found, no Message to restartUI error" + else + if _exists "wget"; then + _err "Until Version of TrueNAS is older than TrueNAS-12.0-U2 there are problems with using wget" + _err "There is a bug when using the API Call restartUI with wget" + _err "The API call does not give any response, whit wget the api call restartUI would be called about 20 times" + _err "Please use curl!" + _err "Bug Report at https://jira.ixsystems.com/browse/NAS-109435" + return 1 + fi + fi + _getdeployconf DEPLOY_TRUENAS_APIKEY if [ -z "$DEPLOY_TRUENAS_APIKEY" ]; then @@ -63,7 +76,6 @@ truenas_deploy() { _info "Testing Connection TrueNAS" _response=$(_get "$_api_url/system/state") _info "TrueNAS System State: $_response." - _debug _response "$_response" if [ -z "$_response" ]; then _err "Unable to authenticate to $_api_url." @@ -168,14 +180,12 @@ truenas_deploy() { _debug3 _delete_result "$_delete_result" - # the command - # _restart_UI=$(_get "$_api_url/system/general/ui_restart") - # throws the Error 52 - # for this command direct curl command _info "Reload WebUI from TrueNAS" - curl --silent -L --no-keepalive --user-agent "$USER_AGENT" -H "$_H1" "$_api_url/system/general/ui_restart" - _ret=$? - _debug2 CURL_RETURN "$_ret" + _restart_UI=$(_get "$_api_url/system/general/ui_restart") + _info "Until Version of TrueNAS is older than TrueNAS-12.0-U3 curl returns error 52" + _info "This is not a problem for tis scipt" + _info "See Bugreport: https://jira.ixsystems.com/browse/NAS-109435" + _debug2 _restart_UI "$_restart_UI" if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ] && [ "$_ret" = "52" ]; then return 0 From 4bb8e3a121442c3bb9b12cd54467608c551eeb4a Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Sun, 21 Feb 2021 22:48:31 +0100 Subject: [PATCH 1256/2234] Update truenas.sh -error handling --- deploy/truenas.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 1be4aeb0..7d8f3238 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -187,10 +187,10 @@ truenas_deploy() { _info "See Bugreport: https://jira.ixsystems.com/browse/NAS-109435" _debug2 _restart_UI "$_restart_UI" - if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ] && [ "$_ret" = "52" ]; then + if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ]; then return 0 else - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" + _err "Certupdate was not succesfull, please use --debug" return 1 fi } From a730a08161def8358a68a1662149e670e1af02f3 Mon Sep 17 00:00:00 2001 From: Geert Hendrickx Date: Tue, 23 Feb 2021 10:28:17 +0100 Subject: [PATCH 1257/2234] No need to include EC parameters explicitly with the private key. (they are embedded) --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 757ed7a5..3c66250e 100755 --- a/acme.sh +++ b/acme.sh @@ -1124,7 +1124,7 @@ _createkey() { if _isEccKey "$length"; then _debug "Using ec name: $eccname" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -noout -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error ecc key name: $eccname" From c5100219d15137f65799b1fb315affd1a6831218 Mon Sep 17 00:00:00 2001 From: Kristian Johansson Date: Wed, 24 Feb 2021 08:53:35 +0100 Subject: [PATCH 1258/2234] Fixes response handling and thereby allow issuing of subdomain certs --- dnsapi/dns_simply.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index d053dcf6..b38d0ed3 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -6,7 +6,7 @@ #SIMPLY_ApiKey="apikey" # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" - +SIMPLY_SUCCESS_CODE='"status": 200' SIMPLY_Api_Default="https://api.simply.com/1" ######## Public functions ##################### @@ -171,7 +171,7 @@ _get_root() { return 1 fi - if _contains "$response" '"code":"NOT_FOUND"'; then + if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then _debug "$h not found" else _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) @@ -196,6 +196,12 @@ _simply_add_record() { return 1 fi + if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then + _err "Call to API not sucessfull, see below message for more details" + _err "$response" + return 1 + fi + return 0 } @@ -211,6 +217,12 @@ _simply_delete_record() { return 1 fi + if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then + _err "Call to API not sucessfull, see below message for more details" + _err "$response" + return 1 + fi + return 0 } From 1917c4b04a17de47d5dc6e08946df6b5bf1b137f Mon Sep 17 00:00:00 2001 From: Kristian Johansson Date: Wed, 24 Feb 2021 17:34:28 +0100 Subject: [PATCH 1259/2234] Adds comment --- dnsapi/dns_simply.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index b38d0ed3..e0e05017 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -6,9 +6,11 @@ #SIMPLY_ApiKey="apikey" # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" -SIMPLY_SUCCESS_CODE='"status": 200' SIMPLY_Api_Default="https://api.simply.com/1" +#This is used for determining success of REST call +SIMPLY_SUCCESS_CODE='"status": 200' + ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_simply_add() { From 9a90fe37944ce23ecee6425a4b11f0594bb2165e Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 25 Feb 2021 07:45:22 +0800 Subject: [PATCH 1260/2234] fix https://github.com/acmesh-official/acme.sh/issues/3402 --- acme.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 3c66250e..24cda9c4 100755 --- a/acme.sh +++ b/acme.sh @@ -562,8 +562,16 @@ if _exists xargs && [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then fi _h2b() { - if _exists xxd && xxd -r -p 2>/dev/null; then - return + if _exists xxd; then + if _contains "$(xxd --help 2>&1)" "assumes -c30"; then + if xxd -r -p -c 9999 2>/dev/null; then + return + fi + else + if xxd -r -p 2>/dev/null; then + return + fi + fi fi hex=$(cat) From 5eb1469dbfe6c9f998817a7947e90bb942d8f87d Mon Sep 17 00:00:00 2001 From: Lukas Brocke Date: Tue, 23 Feb 2021 19:49:58 +0100 Subject: [PATCH 1261/2234] dnsapi/ionos: Use POST instead of PATCH for adding TXT record The API now supports a POST route for adding records. Therefore checking for already existing records and including them in a PATCH request is no longer necessary. --- dnsapi/dns_ionos.sh | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index e6bd5000..aaf8580f 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -24,20 +24,9 @@ dns_ionos_add() { return 1 fi - _new_record="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}" + _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" - # As no POST route is supported by the API, check for existing records and include them in the PATCH request in order not delete them. - # This is required to support ACME v2 wildcard certificate creation, where two TXT records for the same domain name are created. - - _ionos_get_existing_records "$fulldomain" "$_zone_id" - - if [ "$_existing_records" ]; then - _body="[$_new_record,$_existing_records]" - else - _body="[$_new_record]" - fi - - if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then + if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ -z "$response" ]; then _info "TXT record has been created successfully." return 0 fi @@ -125,17 +114,6 @@ _get_root() { return 1 } -_ionos_get_existing_records() { - fulldomain=$1 - zone_id=$2 - - if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then - response="$(echo "$response" | tr -d "\n")" - - _existing_records="$(printf "%s\n" "$response" | _egrep_o "\"records\":\[.*\]" | _head_n 1 | cut -d '[' -f 2 | sed 's/]//')" - fi -} - _ionos_get_record() { fulldomain=$1 zone_id=$2 @@ -168,7 +146,7 @@ _ionos_rest() { export _H2="Accept: application/json" export _H3="Content-Type: application/json" - response="$(_post "$data" "$IONOS_API$route" "" "$method")" + response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")" else export _H2="Accept: */*" From 0f494c9dd62fbbd27d03c6e6603cb96023910a01 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 1 Mar 2021 18:13:50 +0800 Subject: [PATCH 1262/2234] fix https://github.com/acmesh-official/acme.sh/issues/3433 --- acme.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/acme.sh b/acme.sh index 24cda9c4..748363e8 100755 --- a/acme.sh +++ b/acme.sh @@ -2133,6 +2133,12 @@ _send_signed_request() { _sleep $_sleep_retry_sec continue fi + if _contains "$_body" "The Replay Nonce is not recognized"; then + _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." + _CACHED_NONCE="" + _sleep $_sleep_retry_sec + continue + fi fi return 0 done From 3817ddef412d31daf00170c8f3afeadc4aa08e68 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 4 Mar 2021 21:38:51 +0800 Subject: [PATCH 1263/2234] fix https://github.com/acmesh-official/acme.sh/issues/3019 --- dnsapi/dns_namecheap.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 7ce39fa9..5e1f4791 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -208,7 +208,7 @@ _namecheap_parse_host() { _hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2) _hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2) _hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2) - _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2) + _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2 | _xml_decode) _hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2) _hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2) @@ -405,3 +405,11 @@ _namecheap_set_tld_sld() { done } + +_xml_decode() { + sed 's/"/"/g' +} + + + + From 52cfb9a041a4d00f0fe88a34f27e9c2e4b71715e Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 4 Mar 2021 21:50:54 +0800 Subject: [PATCH 1264/2234] fix format --- dnsapi/dns_namecheap.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 5e1f4791..e3dc7997 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -410,6 +410,3 @@ _xml_decode() { sed 's/"/"/g' } - - - From 89bb7e6b0ea5796da06ae47cefa847ff23e5523a Mon Sep 17 00:00:00 2001 From: wout Date: Wed, 10 Mar 2021 16:18:07 +0100 Subject: [PATCH 1265/2234] Add wildcard certificate support for dns_constellix --- dnsapi/dns_constellix.sh | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 42df710d..d0d3132a 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -30,16 +30,38 @@ dns_constellix_add() { return 1 fi - _info "Adding TXT record" - if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"add\":true,\"set\":{\"name\":\"${_sub_domain}\",\"ttl\":120,\"roundRobin\":[{\"value\":\"${txtvalue}\"}]}}]"; then - if printf -- "%s" "$response" | grep "{\"success\":\"1 record(s) added, 0 record(s) updated, 0 record(s) deleted\"}" >/dev/null; then - _info "Added" - return 0 + # To support wildcard certificates, try to find existig TXT record and update it. + _info "Search existing TXT record" + if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then + if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then + _info "Adding TXT record" + if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"add\":true,\"set\":{\"name\":\"${_sub_domain}\",\"ttl\":60,\"roundRobin\":[{\"value\":\"${txtvalue}\"}]}}]"; then + if printf -- "%s" "$response" | grep "{\"success\":\"1 record(s) added, 0 record(s) updated, 0 record(s) deleted\"}" >/dev/null; then + _info "Added" + return 0 + else + _err "Error adding TXT record" + fi + fi else - _err "Error adding TXT record" - return 1 + _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+" | cut -d ':' -f 2) + if _constellix_rest GET "domains/${_domain_id}/records/TXT/${_record_id}"; then + _new_rr_values=$(printf "%s\n" "$response" | _egrep_o "\"roundRobin\":\[.*?\]" | sed "s/\]$/,{\"value\":\"${txtvalue}\"}]/") + _debug _new_rr_values $_new_rr_values + _info "Updating TXT record" + if _constellix_rest PUT "domains/${_domain_id}/records/TXT/${_record_id}" "{\"name\":\"${_sub_domain}\",\"ttl\":60,${_new_rr_values}}"; then + if printf -- "%s" "$response" | grep "{\"success\":\"Record.*updated successfully\"}" >/dev/null; then + _info "Updated" + return 0 + else + _err "Error updating TXT record" + fi + fi + fi fi fi + + return 1 } # Usage: fulldomain txtvalue @@ -68,9 +90,10 @@ dns_constellix_rm() { return 0 else _err "Error removing TXT record" - return 1 fi fi + + return 1 } #################### Private functions below ################################## From 494a6e6090e4a8b3980f3c92d6d86ce3772e3da2 Mon Sep 17 00:00:00 2001 From: wout Date: Wed, 10 Mar 2021 16:32:09 +0100 Subject: [PATCH 1266/2234] Fix checks --- dnsapi/dns_constellix.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index d0d3132a..5c20a917 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -38,7 +38,7 @@ dns_constellix_add() { if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"add\":true,\"set\":{\"name\":\"${_sub_domain}\",\"ttl\":60,\"roundRobin\":[{\"value\":\"${txtvalue}\"}]}}]"; then if printf -- "%s" "$response" | grep "{\"success\":\"1 record(s) added, 0 record(s) updated, 0 record(s) deleted\"}" >/dev/null; then _info "Added" - return 0 + return 0 else _err "Error adding TXT record" fi @@ -47,7 +47,7 @@ dns_constellix_add() { _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+" | cut -d ':' -f 2) if _constellix_rest GET "domains/${_domain_id}/records/TXT/${_record_id}"; then _new_rr_values=$(printf "%s\n" "$response" | _egrep_o "\"roundRobin\":\[.*?\]" | sed "s/\]$/,{\"value\":\"${txtvalue}\"}]/") - _debug _new_rr_values $_new_rr_values + _debug _new_rr_values "$_new_rr_values" _info "Updating TXT record" if _constellix_rest PUT "domains/${_domain_id}/records/TXT/${_record_id}" "{\"name\":\"${_sub_domain}\",\"ttl\":60,${_new_rr_values}}"; then if printf -- "%s" "$response" | grep "{\"success\":\"Record.*updated successfully\"}" >/dev/null; then From 8fdfe673e8ccd69dfe8cfcd8acff641dd84dae24 Mon Sep 17 00:00:00 2001 From: wout Date: Wed, 10 Mar 2021 23:34:21 +0100 Subject: [PATCH 1267/2234] Improve the remove handling so it does not print errors --- dnsapi/dns_constellix.sh | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 5c20a917..fb4e278e 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -30,8 +30,8 @@ dns_constellix_add() { return 1 fi - # To support wildcard certificates, try to find existig TXT record and update it. - _info "Search existing TXT record" + # The TXT record might already exist when working with wilcard certificates. In that case, update the record by adding the new value. + _debug "Search TXT record" if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then _info "Adding TXT record" @@ -83,13 +83,22 @@ dns_constellix_rm() { return 1 fi - _info "Removing TXT record" - if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"delete\":true,\"filter\":{\"field\":\"name\",\"op\":\"eq\",\"value\":\"${_sub_domain}\"}}]"; then - if printf -- "%s" "$response" | grep "{\"success\":\"0 record(s) added, 0 record(s) updated, 1 record(s) deleted\"}" >/dev/null; then + # The TXT record might have been removed already when working with some wildcard certificates. + _debug "Search TXT record" + if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then + if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then _info "Removed" return 0 else - _err "Error removing TXT record" + _info "Removing TXT record" + if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"delete\":true,\"filter\":{\"field\":\"name\",\"op\":\"eq\",\"value\":\"${_sub_domain}\"}}]"; then + if printf -- "%s" "$response" | grep "{\"success\":\"0 record(s) added, 0 record(s) updated, 1 record(s) deleted\"}" >/dev/null; then + _info "Removed" + return 0 + else + _err "Error removing TXT record" + fi + fi fi fi From 928aa74e89b7aac0f1cddcb3e103a1b151aa34d7 Mon Sep 17 00:00:00 2001 From: wout Date: Wed, 10 Mar 2021 23:36:34 +0100 Subject: [PATCH 1268/2234] Fix typo --- dnsapi/dns_constellix.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index fb4e278e..75211a6f 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -30,7 +30,7 @@ dns_constellix_add() { return 1 fi - # The TXT record might already exist when working with wilcard certificates. In that case, update the record by adding the new value. + # The TXT record might already exist when working with wildcard certificates. In that case, update the record by adding the new value. _debug "Search TXT record" if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then From 8733635638875adfa8b201d4d89990b507ba86e8 Mon Sep 17 00:00:00 2001 From: anom-human <80478363+anom-human@users.noreply.github.com> Date: Thu, 11 Mar 2021 19:11:02 +0100 Subject: [PATCH 1269/2234] Update dns_servercow.sh to support wildcard certs Updated dns_servercow.sh to support txt records with multiple entries. This supports wildcard certificates that require txt records with the same name and different contents. --- dnsapi/dns_servercow.sh | 42 +++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index e73d85b0..39f16396 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -48,18 +48,44 @@ dns_servercow_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - - if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then - if printf -- "%s" "$response" | grep "ok" >/dev/null; then - _info "Added, OK" - return 0 + + # check whether a txt record already exists for the subdomain + if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then + _info "A txt record with the same name already exists." + # trim the string on the left + txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} + # trim the string on the right + txtvalue_old=${txtvalue_old%%\"*} + + _debug txtvalue_old "$txtvalue_old" + + _info "Add the new txtvalue to the existing txt record." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":[\"$txtvalue\",\"$txtvalue_old\"],\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added additional txtvalue, OK" + return 0 + else + _err "add txt record error." + return 1 + fi + fi + _err "add txt record error." + return 1 else + _info "There is no txt record with the name yet." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added, OK" + return 0 + else + _err "add txt record error." + return 1 + fi + fi _err "add txt record error." return 1 - fi fi - _err "add txt record error." - + return 1 } From 5c4bfbbd950d47d3fe33d4aee75a70499fd117c0 Mon Sep 17 00:00:00 2001 From: anom-human <80478363+anom-human@users.noreply.github.com> Date: Thu, 11 Mar 2021 20:25:49 +0100 Subject: [PATCH 1270/2234] Update dns_servercow.sh to support wildcard certs Updated dns_servercow.sh to support txt records with multiple entries. This supports wildcard certificates that require txt records with the same name and different contents. --- dnsapi/dns_servercow.sh | 64 ++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index 39f16396..f70a2294 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -48,44 +48,44 @@ dns_servercow_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - - # check whether a txt record already exists for the subdomain + + # check whether a txt record already exists for the subdomain if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then - _info "A txt record with the same name already exists." - # trim the string on the left - txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} - # trim the string on the right - txtvalue_old=${txtvalue_old%%\"*} - - _debug txtvalue_old "$txtvalue_old" - - _info "Add the new txtvalue to the existing txt record." - if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":[\"$txtvalue\",\"$txtvalue_old\"],\"ttl\":20}"; then - if printf -- "%s" "$response" | grep "ok" >/dev/null; then - _info "Added additional txtvalue, OK" - return 0 - else - _err "add txt record error." + _info "A txt record with the same name already exists." + # trim the string on the left + txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} + # trim the string on the right + txtvalue_old=${txtvalue_old%%\"*} + + _debug txtvalue_old "$txtvalue_old" + + _info "Add the new txtvalue to the existing txt record." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":[\"$txtvalue\",\"$txtvalue_old\"],\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added additional txtvalue, OK" + return 0 + else + _err "add txt record error." return 1 - fi fi - _err "add txt record error." - return 1 - else - _info "There is no txt record with the name yet." - if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then - if printf -- "%s" "$response" | grep "ok" >/dev/null; then - _info "Added, OK" - return 0 - else - _err "add txt record error." + fi + _err "add txt record error." + return 1 + else + _info "There is no txt record with the name yet." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added, OK" + return 0 + else + _err "add txt record error." return 1 - fi fi - _err "add txt record error." - return 1 + fi + _err "add txt record error." + return 1 fi - + return 1 } From 96a95ba9fefa05f88e11f500b98e00706d9c7419 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Mar 2021 20:43:25 +0800 Subject: [PATCH 1271/2234] fix https://github.com/acmesh-official/acme.sh/issues/3312 --- acme.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 748363e8..8d422719 100755 --- a/acme.sh +++ b/acme.sh @@ -5287,6 +5287,7 @@ signcsr() { _renew_hook="${10}" _local_addr="${11}" _challenge_alias="${12}" + _preferred_chain="${13}" _csrsubj=$(_readSubjectFromCSR "$_csrfile") if [ "$?" != "0" ]; then @@ -5333,7 +5334,7 @@ signcsr() { _info "Copy csr to: $CSR_PATH" cp "$_csrfile" "$CSR_PATH" - issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" + issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain" } @@ -7430,7 +7431,7 @@ _process() { deploy "$_domain" "$_deploy_hook" "$_ecc" ;; signcsr) - signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" + signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" ;; showcsr) showcsr "$_csr" "$_domain" From 3dbe5d872ba777d6fa5d9eb27d4a6cc7adbb5e0e Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Mar 2021 20:46:12 +0800 Subject: [PATCH 1272/2234] fix format --- dnsapi/dns_namecheap.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index e3dc7997..d15d6b0e 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -409,4 +409,3 @@ _namecheap_set_tld_sld() { _xml_decode() { sed 's/"/"/g' } - From 8eda5f36fb04df03b74e9c3330cd5e995b0ab840 Mon Sep 17 00:00:00 2001 From: Quentin Dreyer Date: Fri, 12 Mar 2021 12:03:36 +0100 Subject: [PATCH 1273/2234] feat: add dns_porkbun --- dnsapi/dns_porkbun.sh | 171 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 dnsapi/dns_porkbun.sh diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh new file mode 100644 index 00000000..05ecb781 --- /dev/null +++ b/dnsapi/dns_porkbun.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env sh + +# +#PORKBUN_API_KEY="pk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" +#PORKBUN_SECRET_API_KEY="sk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + +PORKBUN_Api="https://porkbun.com/api/json/v3" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_porkbun_add() { + fulldomain=$1 + txtvalue=$2 + + PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}" + PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}" + + if [ -z "$PORKBUN_API_KEY" ] || [ -z "$PORKBUN_SECRET_API_KEY" ]; then + PORKBUN_API_KEY='' + PORKBUN_SECRET_API_KEY='' + _err "You didn't specify a Porkbun api key and secret api key yet." + _err "You can get yours from here https://porkbun.com/account/api." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable PORKBUN_API_KEY "$PORKBUN_API_KEY" + _saveaccountconf_mutable PORKBUN_SECRET_API_KEY "$PORKBUN_SECRET_API_KEY" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _porkbun_rest POST "dns/retrieve/$_domain" + + if ! echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null; then + _err "Error $response" + return 1 + fi + + # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so + # we can not use updating anymore. + # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + # _debug count "$count" + # if [ "$count" = "0" ]; then + _info "Adding record" + if _porkbun_rest POST "dns/create/$_domain" "{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":120}"; then + if _contains "$response" '\"status\":"SUCCESS"'; then + _info "Added, OK" + return 0 + elif _contains "$response" "The record already exists"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error. ($response)" + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_porkbun_rm() { + fulldomain=$1 + txtvalue=$2 + + PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}" + PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _porkbun_rest POST "dns/retrieve/$_domain" + + if ! echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null; then + _err "Error: $response" + return 1 + fi + + count=$(echo "$response" | _egrep_o "\"count\": *[^,]*" | cut -d : -f 2 | tr -d " ") + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(echo "$response" | tr '{' '\n' | grep "$txtvalue" | cut -d, -f1 | cut -d: -f2 | tr -d \") + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _porkbun_rest POST "dns/delete/$_domain/$record_id"; then + _err "Delete record error." + return 1 + fi + echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + return 1 + fi + + if _porkbun_rest POST "dns/retrieve/$h"; then + if _contains "$response" "\"status\":\"SUCCESS\""; then + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" + _domain=$h + return 0 + else + _debug "Go to next level of $_domain" + fi + else + _debug "Go to next level of $_domain" + fi + i=$(_math "$i" + 1) + done + + return 1 +} + +_porkbun_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + api_key_trimmed=$(echo "$PORKBUN_API_KEY" | tr -d '"') + secret_api_key_trimmed=$(echo "$PORKBUN_SECRET_API_KEY" | tr -d '"') + + test -z "$data" && data="{" || data="$(echo $data | cut -d'}' -f1)," + data="$data\"apikey\":\"$api_key_trimmed\",\"secretapikey\":\"$secret_api_key_trimmed\"}" + + export _H1="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$PORKBUN_Api/$ep" "" "$m")" + else + response="$(_get "$PORKBUN_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 2e34e11b02bba4243fb6e4578c7f3d4ba364cd47 Mon Sep 17 00:00:00 2001 From: qkdreyer Date: Sat, 13 Mar 2021 14:53:43 +0100 Subject: [PATCH 1274/2234] fix: prevent rate limit --- dnsapi/dns_porkbun.sh | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index 05ecb781..18da6b2f 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -35,14 +35,6 @@ dns_porkbun_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "Getting txt records" - _porkbun_rest POST "dns/retrieve/$_domain" - - if ! echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null; then - _err "Error $response" - return 1 - fi - # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so # we can not use updating anymore. # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) @@ -81,14 +73,6 @@ dns_porkbun_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "Getting txt records" - _porkbun_rest POST "dns/retrieve/$_domain" - - if ! echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null; then - _err "Error: $response" - return 1 - fi - count=$(echo "$response" | _egrep_o "\"count\": *[^,]*" | cut -d : -f 2 | tr -d " ") _debug count "$count" if [ "$count" = "0" ]; then @@ -162,6 +146,8 @@ _porkbun_rest() { response="$(_get "$PORKBUN_Api/$ep")" fi + _sleep 3 # prevent rate limit + if [ "$?" != "0" ]; then _err "error $ep" return 1 From 2386d2e299561378b11eb6a72dac05e7449e2222 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Sat, 20 Mar 2021 15:26:32 +0100 Subject: [PATCH 1277/2234] String change --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 922e6819..3b5a8847 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -32,7 +32,7 @@ dns_websupport_add() { WS_ApiKey="" WS_ApiSecret="" _err "You did not specify the API Key and/or API Secret" - _err "You can get the credentials from here https://admin.websupport.sk/en/auth/apiKey" + _err "You can get the API credentials from here https://admin.websupport.sk/en/auth/apiKey" return 1 fi From c384ed960c138f4449e79293644c4d0ec937cef1 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Sat, 20 Mar 2021 16:01:09 +0100 Subject: [PATCH 1278/2234] Syncing with the original repo (#2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * change arvan api script * change Author name * change name actor * Updated --preferred-chain to issue ISRG properly To support different openssl crl2pkcs7 help cli format * dnsapi/pdns: also normalize json response in detecting root zone * Chain (#3408) * fix https://github.com/acmesh-official/acme.sh/issues/3384 match the issuer to the root CA cert subject * fix format * fix https://github.com/acmesh-official/acme.sh/issues/3384 * remove the alt files. https://github.com/acmesh-official/acme.sh/issues/3384 * upgrade freebsd and solaris * duckdns - fix "integer expression expected" errors (#3397) * fix "integer expression expected" errors * duckdns fix * Update dns_duckdns.sh * Update dns_duckdns.sh * Implement smtp notify hook Support notifications via direct SMTP server connection. Uses Python (2.7.x or 3.4+) to communicate with SMTP server. * Make shfmt happy (I'm open to better ways of formatting the heredoc that embeds the Python script.) * Only save config if send is successful * Add instructions for reporting bugs * Prep for curl or Python; clean up SMTP_* variable usage * Implement curl version of smtp notify-hook * More than one blank line is an abomination, apparently I will not try to use whitespace to group code visually * Fix: Unifi deploy hook support Unifi Cloud Key (#3327) * fix: unifi deploy hook also update Cloud Key nginx certs When running on a Unifi Cloud Key device, also deploy to /etc/ssl/private/cloudkey.{crt,key} and reload nginx. This makes the new cert available for the Cloud Key management app running via nginx on port 443 (as well as the port 8443 Unifi Controller app the deploy hook already supported). Fixes #3326 * Improve settings documentation comments * Improve Cloud Key pre-flight error messaging * Fix typo * Add support for UnifiOS (Cloud Key Gen2) Since UnifiOS does not use the Java keystore (like a Unifi Controller or Cloud Key Gen1 deploy), this also reworks the settings validation and error messaging somewhat. * PR review fixes * Detect unsupported Cloud Key java keystore location * Don't try to restart inactive services (and remove extra spaces from reload command) * Clean up error messages and internal variables * Change to _getdeployconf/_savedeployconf * Switch from cp to cat to preserve file permissions * feat: add huaweicloud error handling * fix: fix freebsd and solaris * support openssl 3.0 fix https://github.com/acmesh-official/acme.sh/issues/3399 * make the fix for rsa key only * Use PROJECT_NAME and VER for X-Mailer header Also add X-Mailer header to Python version * Add _clearaccountconf_mutable() * Rework read/save config to not save default values Add and use _readaccountconf_mutable_default and _saveaccountconf_mutable_default helpers to capture common default value handling. New approach also eliminates need for separate underscore-prefixed version of each conf var. * Implement _rfc2822_date helper * Clean email headers and warn on unsupported address format Just in case, make sure CR or NL don't end up in an email header. * Clarify _readaccountconf_mutable_default * Add Date email header in Python implementation * Use email.policy.default in Python 3 implementation Improves standards compatibility and utf-8 handling in Python 3.3-3.8. (email.policy.default becomes the default in Python 3.9.) * Prefer Python to curl when both available * Change default SMTP_SECURE to "tls" Secure by default. Also try to minimize configuration errors. (Many ESPs/ISPs require STARTTLS, and most support it.) * Update dns_dp.sh 没有encode中文字符会导致提交失败 * No need to include EC parameters explicitly with the private key. (they are embedded) * Fixes response handling and thereby allow issuing of subdomain certs * Adds comment * fix https://github.com/acmesh-official/acme.sh/issues/3402 * dnsapi/ionos: Use POST instead of PATCH for adding TXT record The API now supports a POST route for adding records. Therefore checking for already existing records and including them in a PATCH request is no longer necessary. * fix https://github.com/acmesh-official/acme.sh/issues/3433 * fix https://github.com/acmesh-official/acme.sh/issues/3019 * fix format * Update dns_servercow.sh to support wildcard certs Updated dns_servercow.sh to support txt records with multiple entries. This supports wildcard certificates that require txt records with the same name and different contents. * Update dns_servercow.sh to support wildcard certs Updated dns_servercow.sh to support txt records with multiple entries. This supports wildcard certificates that require txt records with the same name and different contents. * fix https://github.com/acmesh-official/acme.sh/issues/3312 * fix format * feat: add dns_porkbun * fix: prevent rate limit Co-authored-by: Vahid Fardi Co-authored-by: neil Co-authored-by: Gnought <1684105+gnought@users.noreply.github.com> Co-authored-by: manuel Co-authored-by: jerrm Co-authored-by: medmunds Co-authored-by: Mike Edmunds Co-authored-by: Easton Man Co-authored-by: czeming Co-authored-by: Geert Hendrickx Co-authored-by: Kristian Johansson Co-authored-by: Lukas Brocke Co-authored-by: anom-human <80478363+anom-human@users.noreply.github.com> Co-authored-by: neil Co-authored-by: Quentin Dreyer --- .github/workflows/DNS.yml | 4 +- .github/workflows/LetsEncrypt.yml | 4 +- acme.sh | 98 ++++++-- deploy/unifi.sh | 224 +++++++++++++---- dnsapi/dns_arvan.sh | 47 ++-- dnsapi/dns_dp.sh | 2 +- dnsapi/dns_duckdns.sh | 6 +- dnsapi/dns_huaweicloud.sh | 36 ++- dnsapi/dns_ionos.sh | 28 +-- dnsapi/dns_namecheap.sh | 6 +- dnsapi/dns_pdns.sh | 4 +- dnsapi/dns_porkbun.sh | 157 ++++++++++++ dnsapi/dns_servercow.sh | 42 +++- dnsapi/dns_simply.sh | 18 +- notify/smtp.sh | 402 +++++++++++++++++++++++++++++- 15 files changed, 914 insertions(+), 164 deletions(-) create mode 100644 dnsapi/dns_porkbun.sh diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 5dc2d453..ed0426ad 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -184,7 +184,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.7 + - uses: vmactions/freebsd-vm@v0.1.2 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl @@ -223,7 +223,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.1 + - uses: vmactions/solaris-vm@v0.0.3 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat curl diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 8d0c4eb0..7c398c09 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -111,7 +111,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.7 + - uses: vmactions/freebsd-vm@v0.1.2 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl @@ -136,7 +136,7 @@ jobs: run: echo "TestingDomain=${{steps.ngrok.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.1 + - uses: vmactions/solaris-vm@v0.0.3 with: envs: 'TEST_LOCAL TestingDomain' nat: | diff --git a/acme.sh b/acme.sh index a1ad4195..8d422719 100755 --- a/acme.sh +++ b/acme.sh @@ -562,8 +562,16 @@ if _exists xargs && [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then fi _h2b() { - if _exists xxd && xxd -r -p 2>/dev/null; then - return + if _exists xxd; then + if _contains "$(xxd --help 2>&1)" "assumes -c30"; then + if xxd -r -p -c 9999 2>/dev/null; then + return + fi + else + if xxd -r -p 2>/dev/null; then + return + fi + fi fi hex=$(cat) @@ -1124,7 +1132,7 @@ _createkey() { if _isEccKey "$length"; then _debug "Using ec name: $eccname" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -noout -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error ecc key name: $eccname" @@ -1132,7 +1140,11 @@ _createkey() { fi else _debug "Using RSA: $length" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa "$length" 2>/dev/null)"; then + __traditional="" + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help genrsa 2>&1)" "-traditional"; then + __traditional="-traditional" + fi + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa $__traditional "$length" 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error rsa key: $length" @@ -2121,6 +2133,12 @@ _send_signed_request() { _sleep $_sleep_retry_sec continue fi + if _contains "$_body" "The Replay Nonce is not recognized"; then + _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." + _CACHED_NONCE="" + _sleep $_sleep_retry_sec + continue + fi fi return 0 done @@ -2279,6 +2297,13 @@ _clearaccountconf() { _clear_conf "$ACCOUNT_CONF_PATH" "$1" } +#key +_clearaccountconf_mutable() { + _clearaccountconf "SAVED_$1" + #remove later + _clearaccountconf "$1" +} + #_savecaconf key value _savecaconf() { _save_conf "$CA_CONF" "$1" "$2" @@ -4009,12 +4034,42 @@ _check_dns_entries() { } #file -_get_cert_issuers() { +_get_chain_issuers() { _cfile="$1" - if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then - ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 else - ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + _cindex=1 + for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do + _endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)" + _debug2 "_startn" "$_startn" + _debug2 "_endn" "$_endn" + if [ "$DEBUG" ]; then + _debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")" + fi + sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/" + _cindex=$(_math $_cindex + 1) + done + fi +} + +# +_get_chain_subjects() { + _cfile="$1" + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + else + _cindex=1 + for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do + _endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)" + _debug2 "_startn" "$_startn" + _debug2 "_endn" "$_endn" + if [ "$DEBUG" ]; then + _debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")" + fi + sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/" + _cindex=$(_math $_cindex + 1) + done fi } @@ -4022,14 +4077,12 @@ _get_cert_issuers() { _match_issuer() { _cfile="$1" _missuer="$2" - _fissuers="$(_get_cert_issuers $_cfile)" + _fissuers="$(_get_chain_issuers $_cfile)" _debug2 _fissuers "$_fissuers" - if _contains "$_fissuers" "$_missuer"; then - return 0 - fi - _fissuers="$(echo "$_fissuers" | _lower_case)" + _rootissuer="$(echo "$_fissuers" | _lower_case | _tail_n 1)" + _debug2 _rootissuer "$_rootissuer" _missuer="$(echo "$_missuer" | _lower_case)" - _contains "$_fissuers" "$_missuer" + _contains "$_rootissuer" "$_missuer" } #webroot, domain domainlist keylength @@ -4803,6 +4856,9 @@ $_authorizations_map" _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then + if [ "$DEBUG" ]; then + _debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" + fi if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" _debug2 "rels" "$rels" @@ -4818,13 +4874,22 @@ $_authorizations_map" _relca="$CA_CERT_PATH.alt" echo "$response" >"$_relcert" _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" + if [ "$DEBUG" ]; then + _debug "rel chain issuers: " "$(_get_chain_issuers "$_relfullchain")" + fi if _match_issuer "$_relfullchain" "$_preferred_chain"; then _info "Matched issuer in: $rel" cat $_relcert >"$CERT_PATH" cat $_relfullchain >"$CERT_FULLCHAIN_PATH" cat $_relca >"$CA_CERT_PATH" + rm -f "$_relcert" + rm -f "$_relfullchain" + rm -f "$_relca" break fi + rm -f "$_relcert" + rm -f "$_relfullchain" + rm -f "$_relca" done fi fi @@ -5222,6 +5287,7 @@ signcsr() { _renew_hook="${10}" _local_addr="${11}" _challenge_alias="${12}" + _preferred_chain="${13}" _csrsubj=$(_readSubjectFromCSR "$_csrfile") if [ "$?" != "0" ]; then @@ -5268,7 +5334,7 @@ signcsr() { _info "Copy csr to: $CSR_PATH" cp "$_csrfile" "$CSR_PATH" - issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" + issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain" } @@ -7365,7 +7431,7 @@ _process() { deploy "$_domain" "$_deploy_hook" "$_ecc" ;; signcsr) - signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" + signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" ;; showcsr) showcsr "$_csr" "$_domain" diff --git a/deploy/unifi.sh b/deploy/unifi.sh index 184aa62e..a864135e 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -1,12 +1,43 @@ #!/usr/bin/env sh -#Here is a script to deploy cert to unifi server. +# Here is a script to deploy cert on a Unifi Controller or Cloud Key device. +# It supports: +# - self-hosted Unifi Controller +# - Unifi Cloud Key (Gen1/2/2+) +# - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only) +# Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359 #returns 0 means success, otherwise error. +# The deploy-hook automatically detects standard Unifi installations +# for each of the supported environments. Most users should not need +# to set any of these variables, but if you are running a self-hosted +# Controller with custom locations, set these as necessary before running +# the deploy hook. (Defaults shown below.) +# +# Settings for Unifi Controller: +# Location of Java keystore or unifi.keystore.jks file: #DEPLOY_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore" +# Keystore password (built into Unifi Controller, not a user-set password): #DEPLOY_UNIFI_KEYPASS="aircontrolenterprise" +# Command to restart Unifi Controller: #DEPLOY_UNIFI_RELOAD="service unifi restart" +# +# Settings for Unifi Cloud Key Gen1 (nginx admin pages): +# Directory where cloudkey.crt and cloudkey.key live: +#DEPLOY_UNIFI_CLOUDKEY_CERTDIR="/etc/ssl/private" +# Command to restart maintenance pages and Controller +# (same setting as above, default is updated when running on Cloud Key Gen1): +#DEPLOY_UNIFI_RELOAD="service nginx restart && service unifi restart" +# +# Settings for UnifiOS (Cloud Key Gen2): +# Directory where unifi-core.crt and unifi-core.key live: +#DEPLOY_UNIFI_CORE_CONFIG="/data/unifi-core/config/" +# Command to restart unifi-core: +#DEPLOY_UNIFI_RELOAD="systemctl restart unifi-core" +# +# At least one of DEPLOY_UNIFI_KEYSTORE, DEPLOY_UNIFI_CLOUDKEY_CERTDIR, +# or DEPLOY_UNIFI_CORE_CONFIG must exist to receive the deployed certs. ######## Public functions ##################### @@ -24,77 +55,160 @@ unifi_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - if ! _exists keytool; then - _err "keytool not found" - return 1 - fi + _getdeployconf DEPLOY_UNIFI_KEYSTORE + _getdeployconf DEPLOY_UNIFI_KEYPASS + _getdeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR + _getdeployconf DEPLOY_UNIFI_CORE_CONFIG + _getdeployconf DEPLOY_UNIFI_RELOAD - DEFAULT_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore" - _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-$DEFAULT_UNIFI_KEYSTORE}" - DEFAULT_UNIFI_KEYPASS="aircontrolenterprise" - _unifi_keypass="${DEPLOY_UNIFI_KEYPASS:-$DEFAULT_UNIFI_KEYPASS}" - DEFAULT_UNIFI_RELOAD="service unifi restart" - _reload="${DEPLOY_UNIFI_RELOAD:-$DEFAULT_UNIFI_RELOAD}" + _debug2 DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" + _debug2 DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" + _debug2 DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" + _debug2 DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG" + _debug2 DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" - _debug _unifi_keystore "$_unifi_keystore" - if [ ! -f "$_unifi_keystore" ]; then - if [ -z "$DEPLOY_UNIFI_KEYSTORE" ]; then - _err "unifi keystore is not found, please define DEPLOY_UNIFI_KEYSTORE" - return 1 - else - _err "It seems that the specified unifi keystore is not valid, please check." + # Space-separated list of environments detected and installed: + _services_updated="" + + # Default reload commands accumulated as we auto-detect environments: + _reload_cmd="" + + # Unifi Controller environment (self hosted or any Cloud Key) -- + # auto-detect by file /usr/lib/unifi/data/keystore: + _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}" + if [ -f "$_unifi_keystore" ]; then + _info "Installing certificate for Unifi Controller (Java keystore)" + _debug _unifi_keystore "$_unifi_keystore" + if ! _exists keytool; then + _err "keytool not found" return 1 fi - fi - if [ ! -w "$_unifi_keystore" ]; then - _err "The file $_unifi_keystore is not writable, please change the permission." + if [ ! -w "$_unifi_keystore" ]; then + _err "The file $_unifi_keystore is not writable, please change the permission." + return 1 + fi + + _unifi_keypass="${DEPLOY_UNIFI_KEYPASS:-aircontrolenterprise}" + + _debug "Generate import pkcs12" + _import_pkcs12="$(_mktemp)" + _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root + # shellcheck disable=SC2181 + if [ "$?" != "0" ]; then + _err "Error generating pkcs12. Please re-run with --debug and report a bug." + return 1 + fi + + _debug "Import into keystore: $_unifi_keystore" + if keytool -importkeystore \ + -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ + -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ + -alias unifi -noprompt; then + _debug "Import keystore success!" + rm "$_import_pkcs12" + else + _err "Error importing into Unifi Java keystore." + _err "Please re-run with --debug and report a bug." + rm "$_import_pkcs12" + return 1 + fi + + if systemctl -q is-active unifi; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart" + fi + _services_updated="${_services_updated} unifi" + _info "Install Unifi Controller certificate success!" + elif [ "$DEPLOY_UNIFI_KEYSTORE" ]; then + _err "The specified DEPLOY_UNIFI_KEYSTORE='$DEPLOY_UNIFI_KEYSTORE' is not valid, please check." return 1 fi - _info "Generate import pkcs12" - _import_pkcs12="$(_mktemp)" - _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root - if [ "$?" != "0" ]; then - _err "Oops, error creating import pkcs12, please report bug to us." + # Cloud Key environment (non-UnifiOS -- nginx serves admin pages) -- + # auto-detect by file /etc/ssl/private/cloudkey.key: + _cloudkey_certdir="${DEPLOY_UNIFI_CLOUDKEY_CERTDIR:-/etc/ssl/private}" + if [ -f "${_cloudkey_certdir}/cloudkey.key" ]; then + _info "Installing certificate for Cloud Key Gen1 (nginx admin pages)" + _debug _cloudkey_certdir "$_cloudkey_certdir" + if [ ! -w "$_cloudkey_certdir" ]; then + _err "The directory $_cloudkey_certdir is not writable; please check permissions." + return 1 + fi + # Cloud Key expects to load the keystore from /etc/ssl/private/unifi.keystore.jks. + # Normally /usr/lib/unifi/data/keystore is a symlink there (so the keystore was + # updated above), but if not, we don't know how to handle this installation: + if ! cmp -s "$_unifi_keystore" "${_cloudkey_certdir}/unifi.keystore.jks"; then + _err "Unsupported Cloud Key configuration: keystore not found at '${_cloudkey_certdir}/unifi.keystore.jks'" + return 1 + fi + + cat "$_cfullchain" >"${_cloudkey_certdir}/cloudkey.crt" + cat "$_ckey" >"${_cloudkey_certdir}/cloudkey.key" + (cd "$_cloudkey_certdir" && tar -cf cert.tar cloudkey.crt cloudkey.key unifi.keystore.jks) + + if systemctl -q is-active nginx; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }service nginx restart" + fi + _info "Install Cloud Key Gen1 certificate success!" + _services_updated="${_services_updated} nginx" + elif [ "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" ]; then + _err "The specified DEPLOY_UNIFI_CLOUDKEY_CERTDIR='$DEPLOY_UNIFI_CLOUDKEY_CERTDIR' is not valid, please check." return 1 fi - _info "Modify unifi keystore: $_unifi_keystore" - if keytool -importkeystore \ - -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ - -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ - -alias unifi -noprompt; then - _info "Import keystore success!" - rm "$_import_pkcs12" - else - _err "Import unifi keystore error, please report bug to us." - rm "$_import_pkcs12" + # UnifiOS environment -- auto-detect by /data/unifi-core/config/unifi-core.key: + _unifi_core_config="${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}" + if [ -f "${_unifi_core_config}/unifi-core.key" ]; then + _info "Installing certificate for UnifiOS" + _debug _unifi_core_config "$_unifi_core_config" + if [ ! -w "$_unifi_core_config" ]; then + _err "The directory $_unifi_core_config is not writable; please check permissions." + return 1 + fi + + cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" + cat "$_ckey" >"${_unifi_core_config}/unifi-core.key" + + if systemctl -q is-active unifi-core; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi-core" + fi + _info "Install UnifiOS certificate success!" + _services_updated="${_services_updated} unifi-core" + elif [ "$DEPLOY_UNIFI_CORE_CONFIG" ]; then + _err "The specified DEPLOY_UNIFI_CORE_CONFIG='$DEPLOY_UNIFI_CORE_CONFIG' is not valid, please check." return 1 fi - _info "Run reload: $_reload" - if eval "$_reload"; then + if [ -z "$_services_updated" ]; then + # None of the Unifi environments were auto-detected, so no deployment has occurred + # (and none of DEPLOY_UNIFI_{KEYSTORE,CLOUDKEY_CERTDIR,CORE_CONFIG} were set). + _err "Unable to detect Unifi environment in standard location." + _err "(This deploy hook must be run on the Unifi device, not a remote machine.)" + _err "For non-standard Unifi installations, set DEPLOY_UNIFI_KEYSTORE," + _err "DEPLOY_UNIFI_CLOUDKEY_CERTDIR, and/or DEPLOY_UNIFI_CORE_CONFIG as appropriate." + return 1 + fi + + _reload_cmd="${DEPLOY_UNIFI_RELOAD:-$_reload_cmd}" + if [ -z "$_reload_cmd" ]; then + _err "Certificates were installed for services:${_services_updated}," + _err "but none appear to be active. Please set DEPLOY_UNIFI_RELOAD" + _err "to a command that will restart the necessary services." + return 1 + fi + _info "Reload services (this may take some time): $_reload_cmd" + if eval "$_reload_cmd"; then _info "Reload success!" - if [ "$DEPLOY_UNIFI_KEYSTORE" ]; then - _savedomainconf DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" - else - _cleardomainconf DEPLOY_UNIFI_KEYSTORE - fi - if [ "$DEPLOY_UNIFI_KEYPASS" ]; then - _savedomainconf DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" - else - _cleardomainconf DEPLOY_UNIFI_KEYPASS - fi - if [ "$DEPLOY_UNIFI_RELOAD" ]; then - _savedomainconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" - else - _cleardomainconf DEPLOY_UNIFI_RELOAD - fi - return 0 else _err "Reload error" return 1 fi - return 0 + # Successful, so save all (non-default) config: + _savedeployconf DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" + _savedeployconf DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" + _savedeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" + _savedeployconf DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG" + _savedeployconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" + + return 0 } diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index ca1f56c7..4c9217e5 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -1,10 +1,9 @@ #!/usr/bin/env sh -#Arvan_Token="xxxx" +#Arvan_Token="Apikey xxxx" ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" - -#Author: Ehsan Aliakbar +#Author: Vahid Fardi #Report Bugs here: https://github.com/Neilpang/acme.sh # ######## Public functions ##################### @@ -38,6 +37,7 @@ dns_arvan_add() { _info "Adding record" if _arvan_rest POST "$_domain/dns-records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":{\"text\":\"$txtvalue\"},\"ttl\":120}"; then if _contains "$response" "$txtvalue"; then + _info "response id is $response" _info "Added, OK" return 0 elif _contains "$response" "Record Data is Duplicated"; then @@ -49,7 +49,7 @@ dns_arvan_add() { fi fi _err "Add txt record error." - return 1 + return 0 } #Usage: fulldomain txtvalue @@ -73,33 +73,21 @@ dns_arvan_rm() { _debug _domain "$_domain" _debug "Getting txt records" - shorted_txtvalue=$(printf "%s" "$txtvalue" | cut -d "-" -d "_" -f1) - _arvan_rest GET "${_domain}/dns-records?search=$shorted_txtvalue" - + _arvan_rest GET "${_domain}/dns-records" if ! printf "%s" "$response" | grep \"current_page\":1 >/dev/null; then _err "Error on Arvan Api" _err "Please create a github issue with debbug log" return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"total\":[^,]*" | cut -d : -f 2) - _debug count "$count" - if [ "$count" = "0" ]; then - _info "Don't need to remove." - else - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) - _debug "record_id" "$record_id" - if [ -z "$record_id" ]; then - _err "Can not get record id to remove." - return 1 - fi - if ! _arvan_rest "DELETE" "${_domain}/dns-records/$record_id"; then - _err "Delete record error." - return 1 - fi - _debug "$response" - _contains "$response" 'dns record deleted' + _record_id=$(echo "$response" | _egrep_o ".\"id\":\"[^\"]*\",\"type\":\"txt\",\"name\":\"_acme-challenge\",\"value\":{\"text\":\"$txtvalue\"}" | cut -d : -f 2 | cut -d , -f 1 | tr -d \") + if ! _arvan_rest "DELETE" "${_domain}/dns-records/${_record_id}"; then + _err "Error on Arvan Api" + return 1 fi + _debug "$response" + _contains "$response" 'dns record deleted' + return 0 } #################### Private functions below ################################## @@ -111,7 +99,7 @@ dns_arvan_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 - i=1 + i=2 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -121,12 +109,11 @@ _get_root() { return 1 fi - if ! _arvan_rest GET "?search=$h"; then + if ! _arvan_rest GET "$h"; then return 1 fi - - if _contains "$response" "\"domain\":\"$h\"" || _contains "$response" '"total":1'; then - _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if _contains "$response" "\"domain\":\"$h\""; then + _domain_id=$(echo "$response" | cut -d : -f 3 | cut -d , -f 1 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -146,7 +133,6 @@ _arvan_rest() { data="$3" token_trimmed=$(echo "$Arvan_Token" | tr -d '"') - export _H1="Authorization: $token_trimmed" if [ "$mtd" = "DELETE" ]; then @@ -160,4 +146,5 @@ _arvan_rest() { else response="$(_get "$ARVAN_API_URL/$ep$data")" fi + return 0 } diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 033fa5aa..9b8b7a8b 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -89,7 +89,7 @@ add_record() { _info "Adding record" - if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then + if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=%E9%BB%98%E8%AE%A4"; then return 1 fi diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 618e12c6..d6e1dbdc 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -12,7 +12,7 @@ DuckDNS_API="https://www.duckdns.org/update" -######## Public functions ##################### +######## Public functions ###################### #Usage: dns_duckdns_add _acme-challenge.domain.duckdns.org "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_duckdns_add() { @@ -112,7 +112,7 @@ _duckdns_rest() { param="$2" _debug param "$param" url="$DuckDNS_API?$param" - if [ "$DEBUG" -gt 0 ]; then + if [ -n "$DEBUG" ] && [ "$DEBUG" -gt 0 ]; then url="$url&verbose=true" fi _debug url "$url" @@ -121,7 +121,7 @@ _duckdns_rest() { if [ "$method" = "GET" ]; then response="$(_get "$url")" _debug2 response "$response" - if [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then + if [ -n "$DEBUG" ] && [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then response="OK" fi else diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 74fec2a9..f7192725 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -5,7 +5,7 @@ # HUAWEICLOUD_ProjectID iam_api="https://iam.myhuaweicloud.com" -dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" +dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work ######## Public functions ##################### @@ -29,16 +29,27 @@ dns_huaweicloud_add() { return 1 fi + unset token # Clear token token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" - _debug2 "${token}" + if [ -z "${token}" ]; then # Check token + _err "dns_api(dns_huaweicloud): Error getting token." + return 1 + fi + _debug "Access token is: ${token}" + + unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" - _debug "${zoneid}" + if [ -z "${zoneid}" ]; then + _err "dns_api(dns_huaweicloud): Error getting zone id." + return 1 + fi + _debug "Zone ID is: ${zoneid}" _debug "Adding Record" _add_record "${token}" "${fulldomain}" "${txtvalue}" ret="$?" if [ "${ret}" != "0" ]; then - _err "dns_huaweicloud: Error adding record." + _err "dns_api(dns_huaweicloud): Error adding record." return 1 fi @@ -69,12 +80,21 @@ dns_huaweicloud_rm() { return 1 fi + unset token # Clear token token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" - _debug2 "${token}" + if [ -z "${token}" ]; then # Check token + _err "dns_api(dns_huaweicloud): Error getting token." + return 1 + fi + _debug "Access token is: ${token}" + + unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" - _debug "${zoneid}" - record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" - _debug "Record Set ID is: ${record_id}" + if [ -z "${zoneid}" ]; then + _err "dns_api(dns_huaweicloud): Error getting zone id." + return 1 + fi + _debug "Zone ID is: ${zoneid}" # Remove all records # Therotically HuaweiCloud does not allow more than one record set diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index e6bd5000..aaf8580f 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -24,20 +24,9 @@ dns_ionos_add() { return 1 fi - _new_record="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}" + _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" - # As no POST route is supported by the API, check for existing records and include them in the PATCH request in order not delete them. - # This is required to support ACME v2 wildcard certificate creation, where two TXT records for the same domain name are created. - - _ionos_get_existing_records "$fulldomain" "$_zone_id" - - if [ "$_existing_records" ]; then - _body="[$_new_record,$_existing_records]" - else - _body="[$_new_record]" - fi - - if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then + if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ -z "$response" ]; then _info "TXT record has been created successfully." return 0 fi @@ -125,17 +114,6 @@ _get_root() { return 1 } -_ionos_get_existing_records() { - fulldomain=$1 - zone_id=$2 - - if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then - response="$(echo "$response" | tr -d "\n")" - - _existing_records="$(printf "%s\n" "$response" | _egrep_o "\"records\":\[.*\]" | _head_n 1 | cut -d '[' -f 2 | sed 's/]//')" - fi -} - _ionos_get_record() { fulldomain=$1 zone_id=$2 @@ -168,7 +146,7 @@ _ionos_rest() { export _H2="Accept: application/json" export _H3="Content-Type: application/json" - response="$(_post "$data" "$IONOS_API$route" "" "$method")" + response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")" else export _H2="Accept: */*" diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 7ce39fa9..d15d6b0e 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -208,7 +208,7 @@ _namecheap_parse_host() { _hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2) _hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2) _hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2) - _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2) + _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2 | _xml_decode) _hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2) _hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2) @@ -405,3 +405,7 @@ _namecheap_set_tld_sld() { done } + +_xml_decode() { + sed 's/"/"/g' +} diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 8f07e8c4..28b35492 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -175,13 +175,13 @@ _get_root() { i=1 if _pdns_rest "GET" "/api/v1/servers/$PDNS_ServerId/zones"; then - _zones_response="$response" + _zones_response=$(echo "$response" | _normalizeJson) fi while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if _contains "$_zones_response" "\"name\": \"$h.\""; then + if _contains "$_zones_response" "\"name\":\"$h.\""; then _domain="$h." if [ -z "$h" ]; then _domain="=2E" diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh new file mode 100644 index 00000000..18da6b2f --- /dev/null +++ b/dnsapi/dns_porkbun.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env sh + +# +#PORKBUN_API_KEY="pk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" +#PORKBUN_SECRET_API_KEY="sk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + +PORKBUN_Api="https://porkbun.com/api/json/v3" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_porkbun_add() { + fulldomain=$1 + txtvalue=$2 + + PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}" + PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}" + + if [ -z "$PORKBUN_API_KEY" ] || [ -z "$PORKBUN_SECRET_API_KEY" ]; then + PORKBUN_API_KEY='' + PORKBUN_SECRET_API_KEY='' + _err "You didn't specify a Porkbun api key and secret api key yet." + _err "You can get yours from here https://porkbun.com/account/api." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable PORKBUN_API_KEY "$PORKBUN_API_KEY" + _saveaccountconf_mutable PORKBUN_SECRET_API_KEY "$PORKBUN_SECRET_API_KEY" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so + # we can not use updating anymore. + # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + # _debug count "$count" + # if [ "$count" = "0" ]; then + _info "Adding record" + if _porkbun_rest POST "dns/create/$_domain" "{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":120}"; then + if _contains "$response" '\"status\":"SUCCESS"'; then + _info "Added, OK" + return 0 + elif _contains "$response" "The record already exists"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error. ($response)" + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_porkbun_rm() { + fulldomain=$1 + txtvalue=$2 + + PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}" + PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + count=$(echo "$response" | _egrep_o "\"count\": *[^,]*" | cut -d : -f 2 | tr -d " ") + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(echo "$response" | tr '{' '\n' | grep "$txtvalue" | cut -d, -f1 | cut -d: -f2 | tr -d \") + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _porkbun_rest POST "dns/delete/$_domain/$record_id"; then + _err "Delete record error." + return 1 + fi + echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + return 1 + fi + + if _porkbun_rest POST "dns/retrieve/$h"; then + if _contains "$response" "\"status\":\"SUCCESS\""; then + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" + _domain=$h + return 0 + else + _debug "Go to next level of $_domain" + fi + else + _debug "Go to next level of $_domain" + fi + i=$(_math "$i" + 1) + done + + return 1 +} + +_porkbun_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + api_key_trimmed=$(echo "$PORKBUN_API_KEY" | tr -d '"') + secret_api_key_trimmed=$(echo "$PORKBUN_SECRET_API_KEY" | tr -d '"') + + test -z "$data" && data="{" || data="$(echo $data | cut -d'}' -f1)," + data="$data\"apikey\":\"$api_key_trimmed\",\"secretapikey\":\"$secret_api_key_trimmed\"}" + + export _H1="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$PORKBUN_Api/$ep" "" "$m")" + else + response="$(_get "$PORKBUN_Api/$ep")" + fi + + _sleep 3 # prevent rate limit + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index e73d85b0..f70a2294 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -49,16 +49,42 @@ dns_servercow_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then - if printf -- "%s" "$response" | grep "ok" >/dev/null; then - _info "Added, OK" - return 0 - else - _err "add txt record error." - return 1 + # check whether a txt record already exists for the subdomain + if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then + _info "A txt record with the same name already exists." + # trim the string on the left + txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} + # trim the string on the right + txtvalue_old=${txtvalue_old%%\"*} + + _debug txtvalue_old "$txtvalue_old" + + _info "Add the new txtvalue to the existing txt record." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":[\"$txtvalue\",\"$txtvalue_old\"],\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added additional txtvalue, OK" + return 0 + else + _err "add txt record error." + return 1 + fi fi + _err "add txt record error." + return 1 + else + _info "There is no txt record with the name yet." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added, OK" + return 0 + else + _err "add txt record error." + return 1 + fi + fi + _err "add txt record error." + return 1 fi - _err "add txt record error." return 1 } diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index d053dcf6..e0e05017 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -6,9 +6,11 @@ #SIMPLY_ApiKey="apikey" # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" - SIMPLY_Api_Default="https://api.simply.com/1" +#This is used for determining success of REST call +SIMPLY_SUCCESS_CODE='"status": 200' + ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_simply_add() { @@ -171,7 +173,7 @@ _get_root() { return 1 fi - if _contains "$response" '"code":"NOT_FOUND"'; then + if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then _debug "$h not found" else _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) @@ -196,6 +198,12 @@ _simply_add_record() { return 1 fi + if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then + _err "Call to API not sucessfull, see below message for more details" + _err "$response" + return 1 + fi + return 0 } @@ -211,6 +219,12 @@ _simply_delete_record() { return 1 fi + if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then + _err "Call to API not sucessfull, see below message for more details" + _err "$response" + return 1 + fi + return 0 } diff --git a/notify/smtp.sh b/notify/smtp.sh index 6aa37ca3..293c665e 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -2,14 +2,398 @@ # support smtp -smtp_send() { - _subject="$1" - _content="$2" - _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped - _debug "_subject" "$_subject" - _debug "_content" "$_content" - _debug "_statusCode" "$_statusCode" +# Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3358 - _err "Not implemented yet." - return 1 +# This implementation uses either curl or Python (3 or 2.7). +# (See also the "mail" notify hook, which supports other ways to send mail.) + +# SMTP_FROM="from@example.com" # required +# SMTP_TO="to@example.com" # required +# SMTP_HOST="smtp.example.com" # required +# SMTP_PORT="25" # defaults to 25, 465 or 587 depending on SMTP_SECURE +# SMTP_SECURE="tls" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) +# SMTP_USERNAME="" # set if SMTP server requires login +# SMTP_PASSWORD="" # set if SMTP server requires login +# SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout +# SMTP_BIN="/path/to/python_or_curl" # default finds first of python3, python2.7, python, pypy3, pypy, curl on PATH + +SMTP_SECURE_DEFAULT="tls" +SMTP_TIMEOUT_DEFAULT="30" + +# subject content statuscode +smtp_send() { + SMTP_SUBJECT="$1" + SMTP_CONTENT="$2" + # UNUSED: _statusCode="$3" # 0: success, 1: error 2($RENEW_SKIP): skipped + + # Load and validate config: + SMTP_BIN="$(_readaccountconf_mutable_default SMTP_BIN)" + if [ -n "$SMTP_BIN" ] && ! _exists "$SMTP_BIN"; then + _err "SMTP_BIN '$SMTP_BIN' does not exist." + return 1 + fi + if [ -z "$SMTP_BIN" ]; then + # Look for a command that can communicate with an SMTP server. + # (Please don't add sendmail, ssmtp, mutt, mail, or msmtp here. + # Those are already handled by the "mail" notify hook.) + for cmd in python3 python2.7 python pypy3 pypy curl; do + if _exists "$cmd"; then + SMTP_BIN="$cmd" + break + fi + done + if [ -z "$SMTP_BIN" ]; then + _err "The smtp notify-hook requires curl or Python, but can't find any." + _err 'If you have one of them, define SMTP_BIN="/path/to/curl_or_python".' + _err 'Otherwise, see if you can use the "mail" notify-hook instead.' + return 1 + fi + fi + _debug SMTP_BIN "$SMTP_BIN" + _saveaccountconf_mutable_default SMTP_BIN "$SMTP_BIN" + + SMTP_FROM="$(_readaccountconf_mutable_default SMTP_FROM)" + SMTP_FROM="$(_clean_email_header "$SMTP_FROM")" + if [ -z "$SMTP_FROM" ]; then + _err "You must define SMTP_FROM as the sender email address." + return 1 + fi + if _email_has_display_name "$SMTP_FROM"; then + _err "SMTP_FROM must be only a simple email address (sender@example.com)." + _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." + return 1 + fi + _debug SMTP_FROM "$SMTP_FROM" + _saveaccountconf_mutable_default SMTP_FROM "$SMTP_FROM" + + SMTP_TO="$(_readaccountconf_mutable_default SMTP_TO)" + SMTP_TO="$(_clean_email_header "$SMTP_TO")" + if [ -z "$SMTP_TO" ]; then + _err "You must define SMTP_TO as the recipient email address(es)." + return 1 + fi + if _email_has_display_name "$SMTP_TO"; then + _err "SMTP_TO must be only simple email addresses (to@example.com,to2@example.com)." + _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." + return 1 + fi + _debug SMTP_TO "$SMTP_TO" + _saveaccountconf_mutable_default SMTP_TO "$SMTP_TO" + + SMTP_HOST="$(_readaccountconf_mutable_default SMTP_HOST)" + if [ -z "$SMTP_HOST" ]; then + _err "You must define SMTP_HOST as the SMTP server hostname." + return 1 + fi + _debug SMTP_HOST "$SMTP_HOST" + _saveaccountconf_mutable_default SMTP_HOST "$SMTP_HOST" + + SMTP_SECURE="$(_readaccountconf_mutable_default SMTP_SECURE "$SMTP_SECURE_DEFAULT")" + case "$SMTP_SECURE" in + "none") smtp_port_default="25" ;; + "ssl") smtp_port_default="465" ;; + "tls") smtp_port_default="587" ;; + *) + _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." + return 1 + ;; + esac + _debug SMTP_SECURE "$SMTP_SECURE" + _saveaccountconf_mutable_default SMTP_SECURE "$SMTP_SECURE" "$SMTP_SECURE_DEFAULT" + + SMTP_PORT="$(_readaccountconf_mutable_default SMTP_PORT "$smtp_port_default")" + case "$SMTP_PORT" in + *[!0-9]*) + _err "Invalid SMTP_PORT='$SMTP_PORT'. It must be a port number." + return 1 + ;; + esac + _debug SMTP_PORT "$SMTP_PORT" + _saveaccountconf_mutable_default SMTP_PORT "$SMTP_PORT" "$smtp_port_default" + + SMTP_USERNAME="$(_readaccountconf_mutable_default SMTP_USERNAME)" + _debug SMTP_USERNAME "$SMTP_USERNAME" + _saveaccountconf_mutable_default SMTP_USERNAME "$SMTP_USERNAME" + + SMTP_PASSWORD="$(_readaccountconf_mutable_default SMTP_PASSWORD)" + _secure_debug SMTP_PASSWORD "$SMTP_PASSWORD" + _saveaccountconf_mutable_default SMTP_PASSWORD "$SMTP_PASSWORD" + + SMTP_TIMEOUT="$(_readaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT_DEFAULT")" + _debug SMTP_TIMEOUT "$SMTP_TIMEOUT" + _saveaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT" "$SMTP_TIMEOUT_DEFAULT" + + SMTP_X_MAILER="$(_clean_email_header "$PROJECT_NAME $VER --notify-hook smtp")" + + # Run with --debug 2 (or above) to echo the transcript of the SMTP session. + # Careful: this may include SMTP_PASSWORD in plaintext! + if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then + SMTP_SHOW_TRANSCRIPT="True" + else + SMTP_SHOW_TRANSCRIPT="" + fi + + SMTP_SUBJECT=$(_clean_email_header "$SMTP_SUBJECT") + _debug SMTP_SUBJECT "$SMTP_SUBJECT" + _debug SMTP_CONTENT "$SMTP_CONTENT" + + # Send the message: + case "$(basename "$SMTP_BIN")" in + curl) _smtp_send=_smtp_send_curl ;; + py*) _smtp_send=_smtp_send_python ;; + *) + _err "Can't figure out how to invoke '$SMTP_BIN'." + _err "Check your SMTP_BIN setting." + return 1 + ;; + esac + + if ! smtp_output="$($_smtp_send)"; then + _err "Error sending message with $SMTP_BIN." + if [ -n "$smtp_output" ]; then + _err "$smtp_output" + fi + return 1 + fi + + return 0 +} + +# Strip CR and NL from text to prevent MIME header injection +# text +_clean_email_header() { + printf "%s" "$(echo "$1" | tr -d "\r\n")" +} + +# Simple check for display name in an email address (< > or ") +# email +_email_has_display_name() { + _email="$1" + expr "$_email" : '^.*[<>"]' >/dev/null +} + +## +## curl smtp sending +## + +# Send the message via curl using SMTP_* variables +_smtp_send_curl() { + # Build curl args in $@ + case "$SMTP_SECURE" in + none) + set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" + ;; + ssl) + set -- --url "smtps://${SMTP_HOST}:${SMTP_PORT}" + ;; + tls) + set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" --ssl-reqd + ;; + *) + # This will only occur if someone adds a new SMTP_SECURE option above + # without updating this code for it. + _err "Unhandled SMTP_SECURE='$SMTP_SECURE' in _smtp_send_curl" + _err "Please re-run with --debug and report a bug." + return 1 + ;; + esac + + set -- "$@" \ + --upload-file - \ + --mail-from "$SMTP_FROM" \ + --max-time "$SMTP_TIMEOUT" + + # Burst comma-separated $SMTP_TO into individual --mail-rcpt args. + _to="${SMTP_TO}," + while [ -n "$_to" ]; do + _rcpt="${_to%%,*}" + _to="${_to#*,}" + set -- "$@" --mail-rcpt "$_rcpt" + done + + _smtp_login="${SMTP_USERNAME}:${SMTP_PASSWORD}" + if [ "$_smtp_login" != ":" ]; then + set -- "$@" --user "$_smtp_login" + fi + + if [ "$SMTP_SHOW_TRANSCRIPT" = "True" ]; then + set -- "$@" --verbose + else + set -- "$@" --silent --show-error + fi + + raw_message="$(_smtp_raw_message)" + + _debug2 "curl command:" "$SMTP_BIN" "$*" + _debug2 "raw_message:\n$raw_message" + + echo "$raw_message" | "$SMTP_BIN" "$@" +} + +# Output an RFC-822 / RFC-5322 email message using SMTP_* variables. +# (This assumes variables have already been cleaned for use in email headers.) +_smtp_raw_message() { + echo "From: $SMTP_FROM" + echo "To: $SMTP_TO" + echo "Subject: $(_mime_encoded_word "$SMTP_SUBJECT")" + echo "Date: $(_rfc2822_date)" + echo "Content-Type: text/plain; charset=utf-8" + echo "X-Mailer: $SMTP_X_MAILER" + echo + echo "$SMTP_CONTENT" +} + +# Convert text to RFC-2047 MIME "encoded word" format if it contains non-ASCII chars +# text +_mime_encoded_word() { + _text="$1" + # (regex character ranges like [a-z] can be locale-dependent; enumerate ASCII chars to avoid that) + _ascii='] $`"'"[!#%&'()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ~^_abcdefghijklmnopqrstuvwxyz{|}~-" + if expr "$_text" : "^.*[^$_ascii]" >/dev/null; then + # At least one non-ASCII char; convert entire thing to encoded word + printf "%s" "=?UTF-8?B?$(printf "%s" "$_text" | _base64)?=" + else + # Just printable ASCII, no conversion needed + printf "%s" "$_text" + fi +} + +# Output current date in RFC-2822 Section 3.3 format as required in email headers +# (e.g., "Mon, 15 Feb 2021 14:22:01 -0800") +_rfc2822_date() { + # Notes: + # - this is deliberately not UTC, because it "SHOULD express local time" per spec + # - the spec requires weekday and month in the C locale (English), not localized + # - this date format specifier has been tested on Linux, Mac, Solaris and FreeBSD + _old_lc_time="$LC_TIME" + LC_TIME=C + date +'%a, %-d %b %Y %H:%M:%S %z' + LC_TIME="$_old_lc_time" +} + +## +## Python smtp sending +## + +# Send the message via Python using SMTP_* variables +_smtp_send_python() { + _debug "Python version" "$("$SMTP_BIN" --version 2>&1)" + + # language=Python + "$SMTP_BIN" < Date: Sun, 21 Mar 2021 22:46:35 +0800 Subject: [PATCH 1279/2234] fix freebsd --- .github/workflows/DNS.yml | 2 +- .github/workflows/LetsEncrypt.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index ed0426ad..5ff1f8ab 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -184,7 +184,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.2 + - uses: vmactions/freebsd-vm@v0.1.3 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 7c398c09..7193d88d 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -111,7 +111,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.2 + - uses: vmactions/freebsd-vm@v0.1.3 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl From 8de3698b230da82f4eac2d5e04a8a754d8d92faa Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Sun, 21 Mar 2021 16:16:38 +0100 Subject: [PATCH 1280/2234] Revert "Syncing with the original repo (#2)" This reverts commit c384ed960c138f4449e79293644c4d0ec937cef1. --- .github/workflows/DNS.yml | 4 +- .github/workflows/LetsEncrypt.yml | 4 +- acme.sh | 98 ++------ deploy/unifi.sh | 220 ++++------------ dnsapi/dns_arvan.sh | 47 ++-- dnsapi/dns_dp.sh | 2 +- dnsapi/dns_duckdns.sh | 6 +- dnsapi/dns_huaweicloud.sh | 36 +-- dnsapi/dns_ionos.sh | 28 ++- dnsapi/dns_namecheap.sh | 6 +- dnsapi/dns_pdns.sh | 4 +- dnsapi/dns_porkbun.sh | 157 ------------ dnsapi/dns_servercow.sh | 42 +--- dnsapi/dns_simply.sh | 18 +- notify/smtp.sh | 400 +----------------------------- 15 files changed, 161 insertions(+), 911 deletions(-) delete mode 100644 dnsapi/dns_porkbun.sh diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index ed0426ad..5dc2d453 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -184,7 +184,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.2 + - uses: vmactions/freebsd-vm@v0.0.7 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl @@ -223,7 +223,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.3 + - uses: vmactions/solaris-vm@v0.0.1 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat curl diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 7c398c09..8d0c4eb0 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -111,7 +111,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.2 + - uses: vmactions/freebsd-vm@v0.0.7 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl @@ -136,7 +136,7 @@ jobs: run: echo "TestingDomain=${{steps.ngrok.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.3 + - uses: vmactions/solaris-vm@v0.0.1 with: envs: 'TEST_LOCAL TestingDomain' nat: | diff --git a/acme.sh b/acme.sh index 8d422719..a1ad4195 100755 --- a/acme.sh +++ b/acme.sh @@ -562,16 +562,8 @@ if _exists xargs && [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then fi _h2b() { - if _exists xxd; then - if _contains "$(xxd --help 2>&1)" "assumes -c30"; then - if xxd -r -p -c 9999 2>/dev/null; then - return - fi - else - if xxd -r -p 2>/dev/null; then - return - fi - fi + if _exists xxd && xxd -r -p 2>/dev/null; then + return fi hex=$(cat) @@ -1132,7 +1124,7 @@ _createkey() { if _isEccKey "$length"; then _debug "Using ec name: $eccname" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -noout -genkey 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error ecc key name: $eccname" @@ -1140,11 +1132,7 @@ _createkey() { fi else _debug "Using RSA: $length" - __traditional="" - if _contains "$(${ACME_OPENSSL_BIN:-openssl} help genrsa 2>&1)" "-traditional"; then - __traditional="-traditional" - fi - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa $__traditional "$length" 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa "$length" 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error rsa key: $length" @@ -2133,12 +2121,6 @@ _send_signed_request() { _sleep $_sleep_retry_sec continue fi - if _contains "$_body" "The Replay Nonce is not recognized"; then - _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." - _CACHED_NONCE="" - _sleep $_sleep_retry_sec - continue - fi fi return 0 done @@ -2297,13 +2279,6 @@ _clearaccountconf() { _clear_conf "$ACCOUNT_CONF_PATH" "$1" } -#key -_clearaccountconf_mutable() { - _clearaccountconf "SAVED_$1" - #remove later - _clearaccountconf "$1" -} - #_savecaconf key value _savecaconf() { _save_conf "$CA_CONF" "$1" "$2" @@ -4034,42 +4009,12 @@ _check_dns_entries() { } #file -_get_chain_issuers() { +_get_cert_issuers() { _cfile="$1" - if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then - ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 else - _cindex=1 - for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do - _endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)" - _debug2 "_startn" "$_startn" - _debug2 "_endn" "$_endn" - if [ "$DEBUG" ]; then - _debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")" - fi - sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/" - _cindex=$(_math $_cindex + 1) - done - fi -} - -# -_get_chain_subjects() { - _cfile="$1" - if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then - ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 - else - _cindex=1 - for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do - _endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)" - _debug2 "_startn" "$_startn" - _debug2 "_endn" "$_endn" - if [ "$DEBUG" ]; then - _debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")" - fi - sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/" - _cindex=$(_math $_cindex + 1) - done + ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 fi } @@ -4077,12 +4022,14 @@ _get_chain_subjects() { _match_issuer() { _cfile="$1" _missuer="$2" - _fissuers="$(_get_chain_issuers $_cfile)" + _fissuers="$(_get_cert_issuers $_cfile)" _debug2 _fissuers "$_fissuers" - _rootissuer="$(echo "$_fissuers" | _lower_case | _tail_n 1)" - _debug2 _rootissuer "$_rootissuer" + if _contains "$_fissuers" "$_missuer"; then + return 0 + fi + _fissuers="$(echo "$_fissuers" | _lower_case)" _missuer="$(echo "$_missuer" | _lower_case)" - _contains "$_rootissuer" "$_missuer" + _contains "$_fissuers" "$_missuer" } #webroot, domain domainlist keylength @@ -4856,9 +4803,6 @@ $_authorizations_map" _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then - if [ "$DEBUG" ]; then - _debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" - fi if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" _debug2 "rels" "$rels" @@ -4874,22 +4818,13 @@ $_authorizations_map" _relca="$CA_CERT_PATH.alt" echo "$response" >"$_relcert" _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" - if [ "$DEBUG" ]; then - _debug "rel chain issuers: " "$(_get_chain_issuers "$_relfullchain")" - fi if _match_issuer "$_relfullchain" "$_preferred_chain"; then _info "Matched issuer in: $rel" cat $_relcert >"$CERT_PATH" cat $_relfullchain >"$CERT_FULLCHAIN_PATH" cat $_relca >"$CA_CERT_PATH" - rm -f "$_relcert" - rm -f "$_relfullchain" - rm -f "$_relca" break fi - rm -f "$_relcert" - rm -f "$_relfullchain" - rm -f "$_relca" done fi fi @@ -5287,7 +5222,6 @@ signcsr() { _renew_hook="${10}" _local_addr="${11}" _challenge_alias="${12}" - _preferred_chain="${13}" _csrsubj=$(_readSubjectFromCSR "$_csrfile") if [ "$?" != "0" ]; then @@ -5334,7 +5268,7 @@ signcsr() { _info "Copy csr to: $CSR_PATH" cp "$_csrfile" "$CSR_PATH" - issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain" + issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" } @@ -7431,7 +7365,7 @@ _process() { deploy "$_domain" "$_deploy_hook" "$_ecc" ;; signcsr) - signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" + signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" ;; showcsr) showcsr "$_csr" "$_domain" diff --git a/deploy/unifi.sh b/deploy/unifi.sh index a864135e..184aa62e 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -1,43 +1,12 @@ #!/usr/bin/env sh -# Here is a script to deploy cert on a Unifi Controller or Cloud Key device. -# It supports: -# - self-hosted Unifi Controller -# - Unifi Cloud Key (Gen1/2/2+) -# - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only) -# Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359 +#Here is a script to deploy cert to unifi server. #returns 0 means success, otherwise error. -# The deploy-hook automatically detects standard Unifi installations -# for each of the supported environments. Most users should not need -# to set any of these variables, but if you are running a self-hosted -# Controller with custom locations, set these as necessary before running -# the deploy hook. (Defaults shown below.) -# -# Settings for Unifi Controller: -# Location of Java keystore or unifi.keystore.jks file: #DEPLOY_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore" -# Keystore password (built into Unifi Controller, not a user-set password): #DEPLOY_UNIFI_KEYPASS="aircontrolenterprise" -# Command to restart Unifi Controller: #DEPLOY_UNIFI_RELOAD="service unifi restart" -# -# Settings for Unifi Cloud Key Gen1 (nginx admin pages): -# Directory where cloudkey.crt and cloudkey.key live: -#DEPLOY_UNIFI_CLOUDKEY_CERTDIR="/etc/ssl/private" -# Command to restart maintenance pages and Controller -# (same setting as above, default is updated when running on Cloud Key Gen1): -#DEPLOY_UNIFI_RELOAD="service nginx restart && service unifi restart" -# -# Settings for UnifiOS (Cloud Key Gen2): -# Directory where unifi-core.crt and unifi-core.key live: -#DEPLOY_UNIFI_CORE_CONFIG="/data/unifi-core/config/" -# Command to restart unifi-core: -#DEPLOY_UNIFI_RELOAD="systemctl restart unifi-core" -# -# At least one of DEPLOY_UNIFI_KEYSTORE, DEPLOY_UNIFI_CLOUDKEY_CERTDIR, -# or DEPLOY_UNIFI_CORE_CONFIG must exist to receive the deployed certs. ######## Public functions ##################### @@ -55,160 +24,77 @@ unifi_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _getdeployconf DEPLOY_UNIFI_KEYSTORE - _getdeployconf DEPLOY_UNIFI_KEYPASS - _getdeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR - _getdeployconf DEPLOY_UNIFI_CORE_CONFIG - _getdeployconf DEPLOY_UNIFI_RELOAD + if ! _exists keytool; then + _err "keytool not found" + return 1 + fi - _debug2 DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" - _debug2 DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" - _debug2 DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" - _debug2 DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG" - _debug2 DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" + DEFAULT_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore" + _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-$DEFAULT_UNIFI_KEYSTORE}" + DEFAULT_UNIFI_KEYPASS="aircontrolenterprise" + _unifi_keypass="${DEPLOY_UNIFI_KEYPASS:-$DEFAULT_UNIFI_KEYPASS}" + DEFAULT_UNIFI_RELOAD="service unifi restart" + _reload="${DEPLOY_UNIFI_RELOAD:-$DEFAULT_UNIFI_RELOAD}" - # Space-separated list of environments detected and installed: - _services_updated="" - - # Default reload commands accumulated as we auto-detect environments: - _reload_cmd="" - - # Unifi Controller environment (self hosted or any Cloud Key) -- - # auto-detect by file /usr/lib/unifi/data/keystore: - _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}" - if [ -f "$_unifi_keystore" ]; then - _info "Installing certificate for Unifi Controller (Java keystore)" - _debug _unifi_keystore "$_unifi_keystore" - if ! _exists keytool; then - _err "keytool not found" + _debug _unifi_keystore "$_unifi_keystore" + if [ ! -f "$_unifi_keystore" ]; then + if [ -z "$DEPLOY_UNIFI_KEYSTORE" ]; then + _err "unifi keystore is not found, please define DEPLOY_UNIFI_KEYSTORE" return 1 - fi - if [ ! -w "$_unifi_keystore" ]; then - _err "The file $_unifi_keystore is not writable, please change the permission." - return 1 - fi - - _unifi_keypass="${DEPLOY_UNIFI_KEYPASS:-aircontrolenterprise}" - - _debug "Generate import pkcs12" - _import_pkcs12="$(_mktemp)" - _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root - # shellcheck disable=SC2181 - if [ "$?" != "0" ]; then - _err "Error generating pkcs12. Please re-run with --debug and report a bug." - return 1 - fi - - _debug "Import into keystore: $_unifi_keystore" - if keytool -importkeystore \ - -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ - -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ - -alias unifi -noprompt; then - _debug "Import keystore success!" - rm "$_import_pkcs12" else - _err "Error importing into Unifi Java keystore." - _err "Please re-run with --debug and report a bug." - rm "$_import_pkcs12" + _err "It seems that the specified unifi keystore is not valid, please check." return 1 fi - - if systemctl -q is-active unifi; then - _reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart" - fi - _services_updated="${_services_updated} unifi" - _info "Install Unifi Controller certificate success!" - elif [ "$DEPLOY_UNIFI_KEYSTORE" ]; then - _err "The specified DEPLOY_UNIFI_KEYSTORE='$DEPLOY_UNIFI_KEYSTORE' is not valid, please check." + fi + if [ ! -w "$_unifi_keystore" ]; then + _err "The file $_unifi_keystore is not writable, please change the permission." return 1 fi - # Cloud Key environment (non-UnifiOS -- nginx serves admin pages) -- - # auto-detect by file /etc/ssl/private/cloudkey.key: - _cloudkey_certdir="${DEPLOY_UNIFI_CLOUDKEY_CERTDIR:-/etc/ssl/private}" - if [ -f "${_cloudkey_certdir}/cloudkey.key" ]; then - _info "Installing certificate for Cloud Key Gen1 (nginx admin pages)" - _debug _cloudkey_certdir "$_cloudkey_certdir" - if [ ! -w "$_cloudkey_certdir" ]; then - _err "The directory $_cloudkey_certdir is not writable; please check permissions." - return 1 - fi - # Cloud Key expects to load the keystore from /etc/ssl/private/unifi.keystore.jks. - # Normally /usr/lib/unifi/data/keystore is a symlink there (so the keystore was - # updated above), but if not, we don't know how to handle this installation: - if ! cmp -s "$_unifi_keystore" "${_cloudkey_certdir}/unifi.keystore.jks"; then - _err "Unsupported Cloud Key configuration: keystore not found at '${_cloudkey_certdir}/unifi.keystore.jks'" - return 1 - fi - - cat "$_cfullchain" >"${_cloudkey_certdir}/cloudkey.crt" - cat "$_ckey" >"${_cloudkey_certdir}/cloudkey.key" - (cd "$_cloudkey_certdir" && tar -cf cert.tar cloudkey.crt cloudkey.key unifi.keystore.jks) - - if systemctl -q is-active nginx; then - _reload_cmd="${_reload_cmd:+$_reload_cmd && }service nginx restart" - fi - _info "Install Cloud Key Gen1 certificate success!" - _services_updated="${_services_updated} nginx" - elif [ "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" ]; then - _err "The specified DEPLOY_UNIFI_CLOUDKEY_CERTDIR='$DEPLOY_UNIFI_CLOUDKEY_CERTDIR' is not valid, please check." + _info "Generate import pkcs12" + _import_pkcs12="$(_mktemp)" + _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root + if [ "$?" != "0" ]; then + _err "Oops, error creating import pkcs12, please report bug to us." return 1 fi - # UnifiOS environment -- auto-detect by /data/unifi-core/config/unifi-core.key: - _unifi_core_config="${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}" - if [ -f "${_unifi_core_config}/unifi-core.key" ]; then - _info "Installing certificate for UnifiOS" - _debug _unifi_core_config "$_unifi_core_config" - if [ ! -w "$_unifi_core_config" ]; then - _err "The directory $_unifi_core_config is not writable; please check permissions." - return 1 - fi - - cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" - cat "$_ckey" >"${_unifi_core_config}/unifi-core.key" - - if systemctl -q is-active unifi-core; then - _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi-core" - fi - _info "Install UnifiOS certificate success!" - _services_updated="${_services_updated} unifi-core" - elif [ "$DEPLOY_UNIFI_CORE_CONFIG" ]; then - _err "The specified DEPLOY_UNIFI_CORE_CONFIG='$DEPLOY_UNIFI_CORE_CONFIG' is not valid, please check." + _info "Modify unifi keystore: $_unifi_keystore" + if keytool -importkeystore \ + -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ + -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ + -alias unifi -noprompt; then + _info "Import keystore success!" + rm "$_import_pkcs12" + else + _err "Import unifi keystore error, please report bug to us." + rm "$_import_pkcs12" return 1 fi - if [ -z "$_services_updated" ]; then - # None of the Unifi environments were auto-detected, so no deployment has occurred - # (and none of DEPLOY_UNIFI_{KEYSTORE,CLOUDKEY_CERTDIR,CORE_CONFIG} were set). - _err "Unable to detect Unifi environment in standard location." - _err "(This deploy hook must be run on the Unifi device, not a remote machine.)" - _err "For non-standard Unifi installations, set DEPLOY_UNIFI_KEYSTORE," - _err "DEPLOY_UNIFI_CLOUDKEY_CERTDIR, and/or DEPLOY_UNIFI_CORE_CONFIG as appropriate." - return 1 - fi - - _reload_cmd="${DEPLOY_UNIFI_RELOAD:-$_reload_cmd}" - if [ -z "$_reload_cmd" ]; then - _err "Certificates were installed for services:${_services_updated}," - _err "but none appear to be active. Please set DEPLOY_UNIFI_RELOAD" - _err "to a command that will restart the necessary services." - return 1 - fi - _info "Reload services (this may take some time): $_reload_cmd" - if eval "$_reload_cmd"; then + _info "Run reload: $_reload" + if eval "$_reload"; then _info "Reload success!" + if [ "$DEPLOY_UNIFI_KEYSTORE" ]; then + _savedomainconf DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" + else + _cleardomainconf DEPLOY_UNIFI_KEYSTORE + fi + if [ "$DEPLOY_UNIFI_KEYPASS" ]; then + _savedomainconf DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" + else + _cleardomainconf DEPLOY_UNIFI_KEYPASS + fi + if [ "$DEPLOY_UNIFI_RELOAD" ]; then + _savedomainconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" + else + _cleardomainconf DEPLOY_UNIFI_RELOAD + fi + return 0 else _err "Reload error" return 1 fi - - # Successful, so save all (non-default) config: - _savedeployconf DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" - _savedeployconf DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" - _savedeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" - _savedeployconf DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG" - _savedeployconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" - return 0 + } diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 4c9217e5..ca1f56c7 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -1,9 +1,10 @@ #!/usr/bin/env sh -#Arvan_Token="Apikey xxxx" +#Arvan_Token="xxxx" ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" -#Author: Vahid Fardi + +#Author: Ehsan Aliakbar #Report Bugs here: https://github.com/Neilpang/acme.sh # ######## Public functions ##################### @@ -37,7 +38,6 @@ dns_arvan_add() { _info "Adding record" if _arvan_rest POST "$_domain/dns-records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":{\"text\":\"$txtvalue\"},\"ttl\":120}"; then if _contains "$response" "$txtvalue"; then - _info "response id is $response" _info "Added, OK" return 0 elif _contains "$response" "Record Data is Duplicated"; then @@ -49,7 +49,7 @@ dns_arvan_add() { fi fi _err "Add txt record error." - return 0 + return 1 } #Usage: fulldomain txtvalue @@ -73,21 +73,33 @@ dns_arvan_rm() { _debug _domain "$_domain" _debug "Getting txt records" - _arvan_rest GET "${_domain}/dns-records" + shorted_txtvalue=$(printf "%s" "$txtvalue" | cut -d "-" -d "_" -f1) + _arvan_rest GET "${_domain}/dns-records?search=$shorted_txtvalue" + if ! printf "%s" "$response" | grep \"current_page\":1 >/dev/null; then _err "Error on Arvan Api" _err "Please create a github issue with debbug log" return 1 fi - _record_id=$(echo "$response" | _egrep_o ".\"id\":\"[^\"]*\",\"type\":\"txt\",\"name\":\"_acme-challenge\",\"value\":{\"text\":\"$txtvalue\"}" | cut -d : -f 2 | cut -d , -f 1 | tr -d \") - if ! _arvan_rest "DELETE" "${_domain}/dns-records/${_record_id}"; then - _err "Error on Arvan Api" - return 1 + count=$(printf "%s\n" "$response" | _egrep_o "\"total\":[^,]*" | cut -d : -f 2) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _arvan_rest "DELETE" "${_domain}/dns-records/$record_id"; then + _err "Delete record error." + return 1 + fi + _debug "$response" + _contains "$response" 'dns record deleted' fi - _debug "$response" - _contains "$response" 'dns record deleted' - return 0 } #################### Private functions below ################################## @@ -99,7 +111,7 @@ dns_arvan_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -109,11 +121,12 @@ _get_root() { return 1 fi - if ! _arvan_rest GET "$h"; then + if ! _arvan_rest GET "?search=$h"; then return 1 fi - if _contains "$response" "\"domain\":\"$h\""; then - _domain_id=$(echo "$response" | cut -d : -f 3 | cut -d , -f 1 | tr -d \") + + if _contains "$response" "\"domain\":\"$h\"" || _contains "$response" '"total":1'; then + _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -133,6 +146,7 @@ _arvan_rest() { data="$3" token_trimmed=$(echo "$Arvan_Token" | tr -d '"') + export _H1="Authorization: $token_trimmed" if [ "$mtd" = "DELETE" ]; then @@ -146,5 +160,4 @@ _arvan_rest() { else response="$(_get "$ARVAN_API_URL/$ep$data")" fi - return 0 } diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 9b8b7a8b..033fa5aa 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -89,7 +89,7 @@ add_record() { _info "Adding record" - if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=%E9%BB%98%E8%AE%A4"; then + if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then return 1 fi diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index d6e1dbdc..618e12c6 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -12,7 +12,7 @@ DuckDNS_API="https://www.duckdns.org/update" -######## Public functions ###################### +######## Public functions ##################### #Usage: dns_duckdns_add _acme-challenge.domain.duckdns.org "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_duckdns_add() { @@ -112,7 +112,7 @@ _duckdns_rest() { param="$2" _debug param "$param" url="$DuckDNS_API?$param" - if [ -n "$DEBUG" ] && [ "$DEBUG" -gt 0 ]; then + if [ "$DEBUG" -gt 0 ]; then url="$url&verbose=true" fi _debug url "$url" @@ -121,7 +121,7 @@ _duckdns_rest() { if [ "$method" = "GET" ]; then response="$(_get "$url")" _debug2 response "$response" - if [ -n "$DEBUG" ] && [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then + if [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then response="OK" fi else diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index f7192725..74fec2a9 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -5,7 +5,7 @@ # HUAWEICLOUD_ProjectID iam_api="https://iam.myhuaweicloud.com" -dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work +dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" ######## Public functions ##################### @@ -29,27 +29,16 @@ dns_huaweicloud_add() { return 1 fi - unset token # Clear token token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" - if [ -z "${token}" ]; then # Check token - _err "dns_api(dns_huaweicloud): Error getting token." - return 1 - fi - _debug "Access token is: ${token}" - - unset zoneid + _debug2 "${token}" zoneid="$(_get_zoneid "${token}" "${fulldomain}")" - if [ -z "${zoneid}" ]; then - _err "dns_api(dns_huaweicloud): Error getting zone id." - return 1 - fi - _debug "Zone ID is: ${zoneid}" + _debug "${zoneid}" _debug "Adding Record" _add_record "${token}" "${fulldomain}" "${txtvalue}" ret="$?" if [ "${ret}" != "0" ]; then - _err "dns_api(dns_huaweicloud): Error adding record." + _err "dns_huaweicloud: Error adding record." return 1 fi @@ -80,21 +69,12 @@ dns_huaweicloud_rm() { return 1 fi - unset token # Clear token token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" - if [ -z "${token}" ]; then # Check token - _err "dns_api(dns_huaweicloud): Error getting token." - return 1 - fi - _debug "Access token is: ${token}" - - unset zoneid + _debug2 "${token}" zoneid="$(_get_zoneid "${token}" "${fulldomain}")" - if [ -z "${zoneid}" ]; then - _err "dns_api(dns_huaweicloud): Error getting zone id." - return 1 - fi - _debug "Zone ID is: ${zoneid}" + _debug "${zoneid}" + record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" + _debug "Record Set ID is: ${record_id}" # Remove all records # Therotically HuaweiCloud does not allow more than one record set diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index aaf8580f..e6bd5000 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -24,9 +24,20 @@ dns_ionos_add() { return 1 fi - _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" + _new_record="{\"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 + # As no POST route is supported by the API, check for existing records and include them in the PATCH request in order not delete them. + # This is required to support ACME v2 wildcard certificate creation, where two TXT records for the same domain name are created. + + _ionos_get_existing_records "$fulldomain" "$_zone_id" + + if [ "$_existing_records" ]; then + _body="[$_new_record,$_existing_records]" + else + _body="[$_new_record]" + fi + + if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then _info "TXT record has been created successfully." return 0 fi @@ -114,6 +125,17 @@ _get_root() { return 1 } +_ionos_get_existing_records() { + fulldomain=$1 + zone_id=$2 + + if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then + response="$(echo "$response" | tr -d "\n")" + + _existing_records="$(printf "%s\n" "$response" | _egrep_o "\"records\":\[.*\]" | _head_n 1 | cut -d '[' -f 2 | sed 's/]//')" + fi +} + _ionos_get_record() { fulldomain=$1 zone_id=$2 @@ -146,7 +168,7 @@ _ionos_rest() { 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")" else export _H2="Accept: */*" diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index d15d6b0e..7ce39fa9 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -208,7 +208,7 @@ _namecheap_parse_host() { _hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2) _hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2) _hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2) - _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2 | _xml_decode) + _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2) _hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2) _hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2) @@ -405,7 +405,3 @@ _namecheap_set_tld_sld() { done } - -_xml_decode() { - sed 's/"/"/g' -} diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 28b35492..8f07e8c4 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -175,13 +175,13 @@ _get_root() { i=1 if _pdns_rest "GET" "/api/v1/servers/$PDNS_ServerId/zones"; then - _zones_response=$(echo "$response" | _normalizeJson) + _zones_response="$response" fi while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if _contains "$_zones_response" "\"name\":\"$h.\""; then + if _contains "$_zones_response" "\"name\": \"$h.\""; then _domain="$h." if [ -z "$h" ]; then _domain="=2E" diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh deleted file mode 100644 index 18da6b2f..00000000 --- a/dnsapi/dns_porkbun.sh +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env sh - -# -#PORKBUN_API_KEY="pk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" -#PORKBUN_SECRET_API_KEY="sk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - -PORKBUN_Api="https://porkbun.com/api/json/v3" - -######## Public functions ##################### - -#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_porkbun_add() { - fulldomain=$1 - txtvalue=$2 - - PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}" - PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}" - - if [ -z "$PORKBUN_API_KEY" ] || [ -z "$PORKBUN_SECRET_API_KEY" ]; then - PORKBUN_API_KEY='' - PORKBUN_SECRET_API_KEY='' - _err "You didn't specify a Porkbun api key and secret api key yet." - _err "You can get yours from here https://porkbun.com/account/api." - return 1 - fi - - #save the credentials to the account conf file. - _saveaccountconf_mutable PORKBUN_API_KEY "$PORKBUN_API_KEY" - _saveaccountconf_mutable PORKBUN_SECRET_API_KEY "$PORKBUN_SECRET_API_KEY" - - _debug 'First detect the root zone' - if ! _get_root "$fulldomain"; then - return 1 - fi - _debug _sub_domain "$_sub_domain" - _debug _domain "$_domain" - - # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so - # we can not use updating anymore. - # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) - # _debug count "$count" - # if [ "$count" = "0" ]; then - _info "Adding record" - if _porkbun_rest POST "dns/create/$_domain" "{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":120}"; then - if _contains "$response" '\"status\":"SUCCESS"'; then - _info "Added, OK" - return 0 - elif _contains "$response" "The record already exists"; then - _info "Already exists, OK" - return 0 - else - _err "Add txt record error. ($response)" - return 1 - fi - fi - _err "Add txt record error." - return 1 - -} - -#fulldomain txtvalue -dns_porkbun_rm() { - fulldomain=$1 - txtvalue=$2 - - PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}" - PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}" - - _debug 'First detect the root zone' - if ! _get_root "$fulldomain"; then - return 1 - fi - _debug _sub_domain "$_sub_domain" - _debug _domain "$_domain" - - count=$(echo "$response" | _egrep_o "\"count\": *[^,]*" | cut -d : -f 2 | tr -d " ") - _debug count "$count" - if [ "$count" = "0" ]; then - _info "Don't need to remove." - else - record_id=$(echo "$response" | tr '{' '\n' | grep "$txtvalue" | cut -d, -f1 | cut -d: -f2 | tr -d \") - _debug "record_id" "$record_id" - if [ -z "$record_id" ]; then - _err "Can not get record id to remove." - return 1 - fi - if ! _porkbun_rest POST "dns/delete/$_domain/$record_id"; then - _err "Delete record error." - return 1 - fi - echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null - fi - -} - -#################### Private functions below ################################## -#_acme-challenge.www.domain.com -#returns -# _sub_domain=_acme-challenge.www -# _domain=domain.com -_get_root() { - domain=$1 - i=1 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug h "$h" - if [ -z "$h" ]; then - return 1 - fi - - if _porkbun_rest POST "dns/retrieve/$h"; then - if _contains "$response" "\"status\":\"SUCCESS\""; then - _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" - _domain=$h - return 0 - else - _debug "Go to next level of $_domain" - fi - else - _debug "Go to next level of $_domain" - fi - i=$(_math "$i" + 1) - done - - return 1 -} - -_porkbun_rest() { - m=$1 - ep="$2" - data="$3" - _debug "$ep" - - api_key_trimmed=$(echo "$PORKBUN_API_KEY" | tr -d '"') - secret_api_key_trimmed=$(echo "$PORKBUN_SECRET_API_KEY" | tr -d '"') - - test -z "$data" && data="{" || data="$(echo $data | cut -d'}' -f1)," - data="$data\"apikey\":\"$api_key_trimmed\",\"secretapikey\":\"$secret_api_key_trimmed\"}" - - export _H1="Content-Type: application/json" - - if [ "$m" != "GET" ]; then - _debug data "$data" - response="$(_post "$data" "$PORKBUN_Api/$ep" "" "$m")" - else - response="$(_get "$PORKBUN_Api/$ep")" - fi - - _sleep 3 # prevent rate limit - - if [ "$?" != "0" ]; then - _err "error $ep" - return 1 - fi - _debug2 response "$response" - return 0 -} diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index f70a2294..e73d85b0 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -49,42 +49,16 @@ dns_servercow_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - # check whether a txt record already exists for the subdomain - if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then - _info "A txt record with the same name already exists." - # trim the string on the left - txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} - # trim the string on the right - txtvalue_old=${txtvalue_old%%\"*} - - _debug txtvalue_old "$txtvalue_old" - - _info "Add the new txtvalue to the existing txt record." - if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":[\"$txtvalue\",\"$txtvalue_old\"],\"ttl\":20}"; then - if printf -- "%s" "$response" | grep "ok" >/dev/null; then - _info "Added additional txtvalue, OK" - return 0 - else - _err "add txt record error." - return 1 - fi + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added, OK" + return 0 + else + _err "add txt record error." + return 1 fi - _err "add txt record error." - return 1 - else - _info "There is no txt record with the name yet." - if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then - if printf -- "%s" "$response" | grep "ok" >/dev/null; then - _info "Added, OK" - return 0 - else - _err "add txt record error." - return 1 - fi - fi - _err "add txt record error." - return 1 fi + _err "add txt record error." return 1 } diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index e0e05017..d053dcf6 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -6,10 +6,8 @@ #SIMPLY_ApiKey="apikey" # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" -SIMPLY_Api_Default="https://api.simply.com/1" -#This is used for determining success of REST call -SIMPLY_SUCCESS_CODE='"status": 200' +SIMPLY_Api_Default="https://api.simply.com/1" ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -173,7 +171,7 @@ _get_root() { return 1 fi - if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then + if _contains "$response" '"code":"NOT_FOUND"'; then _debug "$h not found" else _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) @@ -198,12 +196,6 @@ _simply_add_record() { return 1 fi - if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then - _err "Call to API not sucessfull, see below message for more details" - _err "$response" - return 1 - fi - return 0 } @@ -219,12 +211,6 @@ _simply_delete_record() { return 1 fi - if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then - _err "Call to API not sucessfull, see below message for more details" - _err "$response" - return 1 - fi - return 0 } diff --git a/notify/smtp.sh b/notify/smtp.sh index 293c665e..6aa37ca3 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -2,398 +2,14 @@ # support smtp -# Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3358 - -# This implementation uses either curl or Python (3 or 2.7). -# (See also the "mail" notify hook, which supports other ways to send mail.) - -# SMTP_FROM="from@example.com" # required -# SMTP_TO="to@example.com" # required -# SMTP_HOST="smtp.example.com" # required -# SMTP_PORT="25" # defaults to 25, 465 or 587 depending on SMTP_SECURE -# SMTP_SECURE="tls" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) -# SMTP_USERNAME="" # set if SMTP server requires login -# SMTP_PASSWORD="" # set if SMTP server requires login -# SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout -# SMTP_BIN="/path/to/python_or_curl" # default finds first of python3, python2.7, python, pypy3, pypy, curl on PATH - -SMTP_SECURE_DEFAULT="tls" -SMTP_TIMEOUT_DEFAULT="30" - -# subject content statuscode smtp_send() { - SMTP_SUBJECT="$1" - SMTP_CONTENT="$2" - # UNUSED: _statusCode="$3" # 0: success, 1: error 2($RENEW_SKIP): skipped + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" - # Load and validate config: - SMTP_BIN="$(_readaccountconf_mutable_default SMTP_BIN)" - if [ -n "$SMTP_BIN" ] && ! _exists "$SMTP_BIN"; then - _err "SMTP_BIN '$SMTP_BIN' does not exist." - return 1 - fi - if [ -z "$SMTP_BIN" ]; then - # Look for a command that can communicate with an SMTP server. - # (Please don't add sendmail, ssmtp, mutt, mail, or msmtp here. - # Those are already handled by the "mail" notify hook.) - for cmd in python3 python2.7 python pypy3 pypy curl; do - if _exists "$cmd"; then - SMTP_BIN="$cmd" - break - fi - done - if [ -z "$SMTP_BIN" ]; then - _err "The smtp notify-hook requires curl or Python, but can't find any." - _err 'If you have one of them, define SMTP_BIN="/path/to/curl_or_python".' - _err 'Otherwise, see if you can use the "mail" notify-hook instead.' - return 1 - fi - fi - _debug SMTP_BIN "$SMTP_BIN" - _saveaccountconf_mutable_default SMTP_BIN "$SMTP_BIN" - - SMTP_FROM="$(_readaccountconf_mutable_default SMTP_FROM)" - SMTP_FROM="$(_clean_email_header "$SMTP_FROM")" - if [ -z "$SMTP_FROM" ]; then - _err "You must define SMTP_FROM as the sender email address." - return 1 - fi - if _email_has_display_name "$SMTP_FROM"; then - _err "SMTP_FROM must be only a simple email address (sender@example.com)." - _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." - return 1 - fi - _debug SMTP_FROM "$SMTP_FROM" - _saveaccountconf_mutable_default SMTP_FROM "$SMTP_FROM" - - SMTP_TO="$(_readaccountconf_mutable_default SMTP_TO)" - SMTP_TO="$(_clean_email_header "$SMTP_TO")" - if [ -z "$SMTP_TO" ]; then - _err "You must define SMTP_TO as the recipient email address(es)." - return 1 - fi - if _email_has_display_name "$SMTP_TO"; then - _err "SMTP_TO must be only simple email addresses (to@example.com,to2@example.com)." - _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." - return 1 - fi - _debug SMTP_TO "$SMTP_TO" - _saveaccountconf_mutable_default SMTP_TO "$SMTP_TO" - - SMTP_HOST="$(_readaccountconf_mutable_default SMTP_HOST)" - if [ -z "$SMTP_HOST" ]; then - _err "You must define SMTP_HOST as the SMTP server hostname." - return 1 - fi - _debug SMTP_HOST "$SMTP_HOST" - _saveaccountconf_mutable_default SMTP_HOST "$SMTP_HOST" - - SMTP_SECURE="$(_readaccountconf_mutable_default SMTP_SECURE "$SMTP_SECURE_DEFAULT")" - case "$SMTP_SECURE" in - "none") smtp_port_default="25" ;; - "ssl") smtp_port_default="465" ;; - "tls") smtp_port_default="587" ;; - *) - _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." - return 1 - ;; - esac - _debug SMTP_SECURE "$SMTP_SECURE" - _saveaccountconf_mutable_default SMTP_SECURE "$SMTP_SECURE" "$SMTP_SECURE_DEFAULT" - - SMTP_PORT="$(_readaccountconf_mutable_default SMTP_PORT "$smtp_port_default")" - case "$SMTP_PORT" in - *[!0-9]*) - _err "Invalid SMTP_PORT='$SMTP_PORT'. It must be a port number." - return 1 - ;; - esac - _debug SMTP_PORT "$SMTP_PORT" - _saveaccountconf_mutable_default SMTP_PORT "$SMTP_PORT" "$smtp_port_default" - - SMTP_USERNAME="$(_readaccountconf_mutable_default SMTP_USERNAME)" - _debug SMTP_USERNAME "$SMTP_USERNAME" - _saveaccountconf_mutable_default SMTP_USERNAME "$SMTP_USERNAME" - - SMTP_PASSWORD="$(_readaccountconf_mutable_default SMTP_PASSWORD)" - _secure_debug SMTP_PASSWORD "$SMTP_PASSWORD" - _saveaccountconf_mutable_default SMTP_PASSWORD "$SMTP_PASSWORD" - - SMTP_TIMEOUT="$(_readaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT_DEFAULT")" - _debug SMTP_TIMEOUT "$SMTP_TIMEOUT" - _saveaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT" "$SMTP_TIMEOUT_DEFAULT" - - SMTP_X_MAILER="$(_clean_email_header "$PROJECT_NAME $VER --notify-hook smtp")" - - # Run with --debug 2 (or above) to echo the transcript of the SMTP session. - # Careful: this may include SMTP_PASSWORD in plaintext! - if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then - SMTP_SHOW_TRANSCRIPT="True" - else - SMTP_SHOW_TRANSCRIPT="" - fi - - SMTP_SUBJECT=$(_clean_email_header "$SMTP_SUBJECT") - _debug SMTP_SUBJECT "$SMTP_SUBJECT" - _debug SMTP_CONTENT "$SMTP_CONTENT" - - # Send the message: - case "$(basename "$SMTP_BIN")" in - curl) _smtp_send=_smtp_send_curl ;; - py*) _smtp_send=_smtp_send_python ;; - *) - _err "Can't figure out how to invoke '$SMTP_BIN'." - _err "Check your SMTP_BIN setting." - return 1 - ;; - esac - - if ! smtp_output="$($_smtp_send)"; then - _err "Error sending message with $SMTP_BIN." - if [ -n "$smtp_output" ]; then - _err "$smtp_output" - fi - return 1 - fi - - return 0 -} - -# Strip CR and NL from text to prevent MIME header injection -# text -_clean_email_header() { - printf "%s" "$(echo "$1" | tr -d "\r\n")" -} - -# Simple check for display name in an email address (< > or ") -# email -_email_has_display_name() { - _email="$1" - expr "$_email" : '^.*[<>"]' >/dev/null -} - -## -## curl smtp sending -## - -# Send the message via curl using SMTP_* variables -_smtp_send_curl() { - # Build curl args in $@ - case "$SMTP_SECURE" in - none) - set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" - ;; - ssl) - set -- --url "smtps://${SMTP_HOST}:${SMTP_PORT}" - ;; - tls) - set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" --ssl-reqd - ;; - *) - # This will only occur if someone adds a new SMTP_SECURE option above - # without updating this code for it. - _err "Unhandled SMTP_SECURE='$SMTP_SECURE' in _smtp_send_curl" - _err "Please re-run with --debug and report a bug." - return 1 - ;; - esac - - set -- "$@" \ - --upload-file - \ - --mail-from "$SMTP_FROM" \ - --max-time "$SMTP_TIMEOUT" - - # Burst comma-separated $SMTP_TO into individual --mail-rcpt args. - _to="${SMTP_TO}," - while [ -n "$_to" ]; do - _rcpt="${_to%%,*}" - _to="${_to#*,}" - set -- "$@" --mail-rcpt "$_rcpt" - done - - _smtp_login="${SMTP_USERNAME}:${SMTP_PASSWORD}" - if [ "$_smtp_login" != ":" ]; then - set -- "$@" --user "$_smtp_login" - fi - - if [ "$SMTP_SHOW_TRANSCRIPT" = "True" ]; then - set -- "$@" --verbose - else - set -- "$@" --silent --show-error - fi - - raw_message="$(_smtp_raw_message)" - - _debug2 "curl command:" "$SMTP_BIN" "$*" - _debug2 "raw_message:\n$raw_message" - - echo "$raw_message" | "$SMTP_BIN" "$@" -} - -# Output an RFC-822 / RFC-5322 email message using SMTP_* variables. -# (This assumes variables have already been cleaned for use in email headers.) -_smtp_raw_message() { - echo "From: $SMTP_FROM" - echo "To: $SMTP_TO" - echo "Subject: $(_mime_encoded_word "$SMTP_SUBJECT")" - echo "Date: $(_rfc2822_date)" - echo "Content-Type: text/plain; charset=utf-8" - echo "X-Mailer: $SMTP_X_MAILER" - echo - echo "$SMTP_CONTENT" -} - -# Convert text to RFC-2047 MIME "encoded word" format if it contains non-ASCII chars -# text -_mime_encoded_word() { - _text="$1" - # (regex character ranges like [a-z] can be locale-dependent; enumerate ASCII chars to avoid that) - _ascii='] $`"'"[!#%&'()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ~^_abcdefghijklmnopqrstuvwxyz{|}~-" - if expr "$_text" : "^.*[^$_ascii]" >/dev/null; then - # At least one non-ASCII char; convert entire thing to encoded word - printf "%s" "=?UTF-8?B?$(printf "%s" "$_text" | _base64)?=" - else - # Just printable ASCII, no conversion needed - printf "%s" "$_text" - fi -} - -# Output current date in RFC-2822 Section 3.3 format as required in email headers -# (e.g., "Mon, 15 Feb 2021 14:22:01 -0800") -_rfc2822_date() { - # Notes: - # - this is deliberately not UTC, because it "SHOULD express local time" per spec - # - the spec requires weekday and month in the C locale (English), not localized - # - this date format specifier has been tested on Linux, Mac, Solaris and FreeBSD - _old_lc_time="$LC_TIME" - LC_TIME=C - date +'%a, %-d %b %Y %H:%M:%S %z' - LC_TIME="$_old_lc_time" -} - -## -## Python smtp sending -## - -# Send the message via Python using SMTP_* variables -_smtp_send_python() { - _debug "Python version" "$("$SMTP_BIN" --version 2>&1)" - - # language=Python - "$SMTP_BIN" < Date: Tue, 5 Jan 2021 15:29:08 +0330 Subject: [PATCH 1281/2234] change arvan api script --- dnsapi/dns_arvan.sh | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index ca1f56c7..3c4ced15 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -3,7 +3,6 @@ #Arvan_Token="xxxx" ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" - #Author: Ehsan Aliakbar #Report Bugs here: https://github.com/Neilpang/acme.sh # @@ -38,6 +37,7 @@ dns_arvan_add() { _info "Adding record" if _arvan_rest POST "$_domain/dns-records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":{\"text\":\"$txtvalue\"},\"ttl\":120}"; then if _contains "$response" "$txtvalue"; then + _info "response id is $response" _info "Added, OK" return 0 elif _contains "$response" "Record Data is Duplicated"; then @@ -49,7 +49,7 @@ dns_arvan_add() { fi fi _err "Add txt record error." - return 1 + return 0 } #Usage: fulldomain txtvalue @@ -73,33 +73,21 @@ dns_arvan_rm() { _debug _domain "$_domain" _debug "Getting txt records" - shorted_txtvalue=$(printf "%s" "$txtvalue" | cut -d "-" -d "_" -f1) - _arvan_rest GET "${_domain}/dns-records?search=$shorted_txtvalue" - + _arvan_rest GET "${_domain}/dns-records" if ! printf "%s" "$response" | grep \"current_page\":1 >/dev/null; then _err "Error on Arvan Api" _err "Please create a github issue with debbug log" return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"total\":[^,]*" | cut -d : -f 2) - _debug count "$count" - if [ "$count" = "0" ]; then - _info "Don't need to remove." - else - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) - _debug "record_id" "$record_id" - if [ -z "$record_id" ]; then - _err "Can not get record id to remove." - return 1 - fi - if ! _arvan_rest "DELETE" "${_domain}/dns-records/$record_id"; then - _err "Delete record error." - return 1 - fi - _debug "$response" - _contains "$response" 'dns record deleted' + _record_id=$(echo "$response" | _egrep_o ".\"id\":\"[^\"]*\",\"type\":\"txt\",\"name\":\"_acme-challenge\",\"value\":{\"text\":\"$txtvalue\"}" | cut -d : -f 2 | cut -d , -f 1 | tr -d \") + if ! _arvan_rest "DELETE" "${_domain}/dns-records/${_record_id}"; then + _err "Error on Arvan Api" + return 1 fi + _debug "$response" + _contains "$response" 'dns record deleted' + return 0 } #################### Private functions below ################################## @@ -111,7 +99,7 @@ dns_arvan_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 - i=1 + i=2 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -121,12 +109,11 @@ _get_root() { return 1 fi - if ! _arvan_rest GET "?search=$h"; then + if ! _arvan_rest GET "$h"; then return 1 fi - - if _contains "$response" "\"domain\":\"$h\"" || _contains "$response" '"total":1'; then - _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if _contains "$response" "\"domain\":\"$h\""; then + _domain_id=$(echo "$response" | cut -d : -f 3 | cut -d , -f 1 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -146,7 +133,6 @@ _arvan_rest() { data="$3" token_trimmed=$(echo "$Arvan_Token" | tr -d '"') - export _H1="Authorization: $token_trimmed" if [ "$mtd" = "DELETE" ]; then @@ -160,4 +146,5 @@ _arvan_rest() { else response="$(_get "$ARVAN_API_URL/$ep$data")" fi + return 0 } From e232565971b6090b6a23e47ce530d730bb1c22ef Mon Sep 17 00:00:00 2001 From: Vahid Fardi Date: Tue, 5 Jan 2021 17:10:41 +0330 Subject: [PATCH 1282/2234] change Author name --- dnsapi/dns_arvan.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 3c4ced15..a33504d0 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -1,10 +1,10 @@ #!/usr/bin/env sh -#Arvan_Token="xxxx" +#Arvan_Token="Apikey xxxx" ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" -#Author: Ehsan Aliakbar -#Report Bugs here: https://github.com/Neilpang/acme.sh +#Author: Vahid Fardi +#Report Bugs here: https://github.com/fvahid/acme.sh # ######## Public functions ##################### From 91a739af6e3d7d0aa4624343d83c53d4faea03a6 Mon Sep 17 00:00:00 2001 From: Vahid Fardi Date: Tue, 5 Jan 2021 21:31:31 +0330 Subject: [PATCH 1283/2234] change name actor --- dnsapi/dns_arvan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index a33504d0..4c9217e5 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -4,7 +4,7 @@ ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" #Author: Vahid Fardi -#Report Bugs here: https://github.com/fvahid/acme.sh +#Report Bugs here: https://github.com/Neilpang/acme.sh # ######## Public functions ##################### From 6502bdecbe0e556eda5d7a41dd7d4d7e677c885c Mon Sep 17 00:00:00 2001 From: Gnought <1684105+gnought@users.noreply.github.com> Date: Thu, 11 Feb 2021 01:08:08 +0800 Subject: [PATCH 1284/2234] Updated --preferred-chain to issue ISRG properly To support different openssl crl2pkcs7 help cli format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index a1ad4195..749400e2 100755 --- a/acme.sh +++ b/acme.sh @@ -4011,7 +4011,7 @@ _check_dns_entries() { #file _get_cert_issuers() { _cfile="$1" - if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 else ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 From 016dca654e959656242b392fcc3e26263e5f8241 Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 11 Feb 2021 11:20:18 +0100 Subject: [PATCH 1285/2234] dnsapi/pdns: also normalize json response in detecting root zone --- dnsapi/dns_pdns.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 8f07e8c4..28b35492 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -175,13 +175,13 @@ _get_root() { i=1 if _pdns_rest "GET" "/api/v1/servers/$PDNS_ServerId/zones"; then - _zones_response="$response" + _zones_response=$(echo "$response" | _normalizeJson) fi while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if _contains "$_zones_response" "\"name\": \"$h.\""; then + if _contains "$_zones_response" "\"name\":\"$h.\""; then _domain="$h." if [ -z "$h" ]; then _domain="=2E" From ac148ce0e979aa7c7eb3ade1add0cd69e9981dd0 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Feb 2021 16:22:31 +0800 Subject: [PATCH 1286/2234] Chain (#3408) * fix https://github.com/acmesh-official/acme.sh/issues/3384 match the issuer to the root CA cert subject * fix format * fix https://github.com/acmesh-official/acme.sh/issues/3384 * remove the alt files. https://github.com/acmesh-official/acme.sh/issues/3384 --- acme.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/acme.sh b/acme.sh index 749400e2..a9301e10 100755 --- a/acme.sh +++ b/acme.sh @@ -4009,12 +4009,42 @@ _check_dns_entries() { } #file -_get_cert_issuers() { +_get_chain_issuers() { _cfile="$1" if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then - ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 else - ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + _cindex=1 + for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do + _endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)" + _debug2 "_startn" "$_startn" + _debug2 "_endn" "$_endn" + if [ "$DEBUG" ]; then + _debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")" + fi + sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/" + _cindex=$(_math $_cindex + 1) + done + fi +} + +# +_get_chain_subjects() { + _cfile="$1" + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + else + _cindex=1 + for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do + _endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)" + _debug2 "_startn" "$_startn" + _debug2 "_endn" "$_endn" + if [ "$DEBUG" ]; then + _debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")" + fi + sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/" + _cindex=$(_math $_cindex + 1) + done fi } @@ -4022,14 +4052,12 @@ _get_cert_issuers() { _match_issuer() { _cfile="$1" _missuer="$2" - _fissuers="$(_get_cert_issuers $_cfile)" + _fissuers="$(_get_chain_issuers $_cfile)" _debug2 _fissuers "$_fissuers" - if _contains "$_fissuers" "$_missuer"; then - return 0 - fi - _fissuers="$(echo "$_fissuers" | _lower_case)" + _rootissuer="$(echo "$_fissuers" | _lower_case | _tail_n 1)" + _debug2 _rootissuer "$_rootissuer" _missuer="$(echo "$_missuer" | _lower_case)" - _contains "$_fissuers" "$_missuer" + _contains "$_rootissuer" "$_missuer" } #webroot, domain domainlist keylength @@ -4803,6 +4831,9 @@ $_authorizations_map" _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then + if [ "$DEBUG" ]; then + _debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" + fi if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" _debug2 "rels" "$rels" @@ -4818,13 +4849,22 @@ $_authorizations_map" _relca="$CA_CERT_PATH.alt" echo "$response" >"$_relcert" _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" + if [ "$DEBUG" ]; then + _debug "rel chain issuers: " "$(_get_chain_issuers "$_relfullchain")" + fi if _match_issuer "$_relfullchain" "$_preferred_chain"; then _info "Matched issuer in: $rel" cat $_relcert >"$CERT_PATH" cat $_relfullchain >"$CERT_FULLCHAIN_PATH" cat $_relca >"$CA_CERT_PATH" + rm -f "$_relcert" + rm -f "$_relfullchain" + rm -f "$_relca" break fi + rm -f "$_relcert" + rm -f "$_relfullchain" + rm -f "$_relca" done fi fi From fb5d72c29be41398d38c2f43032d3c13ac8d458a Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 13 Feb 2021 17:27:22 +0800 Subject: [PATCH 1287/2234] upgrade freebsd and solaris --- .github/workflows/LetsEncrypt.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 8d0c4eb0..7c398c09 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -111,7 +111,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.7 + - uses: vmactions/freebsd-vm@v0.1.2 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl @@ -136,7 +136,7 @@ jobs: run: echo "TestingDomain=${{steps.ngrok.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.1 + - uses: vmactions/solaris-vm@v0.0.3 with: envs: 'TEST_LOCAL TestingDomain' nat: | From b1988c7b67b7e077a68555594d174c4856b9c1f1 Mon Sep 17 00:00:00 2001 From: jerrm Date: Sat, 13 Feb 2021 05:58:44 -0500 Subject: [PATCH 1288/2234] duckdns - fix "integer expression expected" errors (#3397) * fix "integer expression expected" errors * duckdns fix * Update dns_duckdns.sh * Update dns_duckdns.sh --- dnsapi/dns_duckdns.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 618e12c6..d6e1dbdc 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -12,7 +12,7 @@ DuckDNS_API="https://www.duckdns.org/update" -######## Public functions ##################### +######## Public functions ###################### #Usage: dns_duckdns_add _acme-challenge.domain.duckdns.org "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_duckdns_add() { @@ -112,7 +112,7 @@ _duckdns_rest() { param="$2" _debug param "$param" url="$DuckDNS_API?$param" - if [ "$DEBUG" -gt 0 ]; then + if [ -n "$DEBUG" ] && [ "$DEBUG" -gt 0 ]; then url="$url&verbose=true" fi _debug url "$url" @@ -121,7 +121,7 @@ _duckdns_rest() { if [ "$method" = "GET" ]; then response="$(_get "$url")" _debug2 response "$response" - if [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then + if [ -n "$DEBUG" ] && [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then response="OK" fi else From 2d9506eb546f66947bf7e86d6bc6ccd9f5ddb621 Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 29 Dec 2020 16:28:38 -0800 Subject: [PATCH 1289/2234] Implement smtp notify hook Support notifications via direct SMTP server connection. Uses Python (2.7.x or 3.4+) to communicate with SMTP server. --- notify/smtp.sh | 185 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 6aa37ca3..367021c8 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -2,7 +2,103 @@ # support smtp +# This implementation uses Python (2 or 3), which is available in many environments. +# If you don't have Python, try "mail" notification instead of "smtp". + +# SMTP_FROM="from@example.com" # required +# SMTP_TO="to@example.com" # required +# SMTP_HOST="smtp.example.com" # required +# SMTP_PORT="25" # defaults to 25, 465 or 587 depending on SMTP_SECURE +# SMTP_SECURE="none" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) +# SMTP_USERNAME="" # set if SMTP server requires login +# SMTP_PASSWORD="" # set if SMTP server requires login +# SMTP_TIMEOUT="15" # seconds for SMTP operations to timeout +# SMTP_PYTHON="/path/to/python" # defaults to system python3 or python + smtp_send() { + # Find a Python interpreter: + SMTP_PYTHON="${SMTP_PYTHON:-$(_readaccountconf_mutable SMTP_PYTHON)}" + if [ "$SMTP_PYTHON" ]; then + if _exists "$SMTP_PYTHON"; then + _saveaccountconf_mutable SMTP_PYTHON "$SMTP_PYTHON" + else + _err "SMTP_PYTHON '$SMTP_PYTHON' does not exist." + return 1 + fi + else + # No SMTP_PYTHON setting; try to run default Python. + # (This is not saved with the conf.) + if _exists python3; then + SMTP_PYTHON="python3" + elif _exists python; then + SMTP_PYTHON="python" + else + _err "Can't locate Python interpreter; please define SMTP_PYTHON." + return 1 + fi + fi + _debug "SMTP_PYTHON" "$SMTP_PYTHON" + _debug "Python version" "$($SMTP_PYTHON --version 2>&1)" + + # Validate other settings: + SMTP_FROM="${SMTP_FROM:-$(_readaccountconf_mutable SMTP_FROM)}" + if [ -z "$SMTP_FROM" ]; then + _err "You must define SMTP_FROM as the sender email address." + return 1 + fi + + SMTP_TO="${SMTP_TO:-$(_readaccountconf_mutable SMTP_TO)}" + if [ -z "$SMTP_TO" ]; then + _err "You must define SMTP_TO as the recipient email address." + return 1 + fi + + SMTP_HOST="${SMTP_HOST:-$(_readaccountconf_mutable SMTP_HOST)}" + if [ -z "$SMTP_HOST" ]; then + _err "You must define SMTP_HOST as the SMTP server hostname." + return 1 + fi + SMTP_PORT="${SMTP_PORT:-$(_readaccountconf_mutable SMTP_PORT)}" + + SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" + SMTP_SECURE="${SMTP_SECURE:-none}" + case "$SMTP_SECURE" in + "none") SMTP_DEFAULT_PORT="25";; + "ssl") SMTP_DEFAULT_PORT="465";; + "tls") SMTP_DEFAULT_PORT="587";; + *) + _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." + return 1 + ;; + esac + + SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" + SMTP_PASSWORD="${SMTP_PASSWORD:-$(_readaccountconf_mutable SMTP_PASSWORD)}" + + SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" + SMTP_DEFAULT_TIMEOUT="15" + + _saveaccountconf_mutable SMTP_FROM "$SMTP_FROM" + _saveaccountconf_mutable SMTP_TO "$SMTP_TO" + _saveaccountconf_mutable SMTP_HOST "$SMTP_HOST" + _saveaccountconf_mutable SMTP_PORT "$SMTP_PORT" + _saveaccountconf_mutable SMTP_SECURE "$SMTP_SECURE" + _saveaccountconf_mutable SMTP_USERNAME "$SMTP_USERNAME" + _saveaccountconf_mutable SMTP_PASSWORD "$SMTP_PASSWORD" + _saveaccountconf_mutable SMTP_TIMEOUT "$SMTP_TIMEOUT" + + # Send the message: + if ! _smtp_send "$@"; then + _err "$smtp_send_output" + return 1 + fi + + return 0 +} + +# _send subject content statuscode +# Send the message via Python using SMTP_* settings +_smtp_send() { _subject="$1" _content="$2" _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped @@ -10,6 +106,91 @@ smtp_send() { _debug "_content" "$_content" _debug "_statusCode" "$_statusCode" - _err "Not implemented yet." - return 1 + _debug "SMTP_FROM" "$SMTP_FROM" + _debug "SMTP_TO" "$SMTP_TO" + _debug "SMTP_HOST" "$SMTP_HOST" + _debug "SMTP_PORT" "$SMTP_PORT" + _debug "SMTP_DEFAULT_PORT" "$SMTP_DEFAULT_PORT" + _debug "SMTP_SECURE" "$SMTP_SECURE" + _debug "SMTP_USERNAME" "$SMTP_USERNAME" + _secure_debug "SMTP_PASSWORD" "$SMTP_PASSWORD" + _debug "SMTP_TIMEOUT" "$SMTP_TIMEOUT" + _debug "SMTP_DEFAULT_TIMEOUT" "$SMTP_DEFAULT_TIMEOUT" + + if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then + # Output the SMTP server dialogue. (Note this will include SMTP_PASSWORD!) + smtp_debug="True" + else + smtp_debug="" + fi + + # language=Python + smtp_send_output="$($SMTP_PYTHON < Date: Tue, 29 Dec 2020 17:10:36 -0800 Subject: [PATCH 1290/2234] Make shfmt happy (I'm open to better ways of formatting the heredoc that embeds the Python script.) --- notify/smtp.sh | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 367021c8..6171cb9b 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -63,13 +63,13 @@ smtp_send() { SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" SMTP_SECURE="${SMTP_SECURE:-none}" case "$SMTP_SECURE" in - "none") SMTP_DEFAULT_PORT="25";; - "ssl") SMTP_DEFAULT_PORT="465";; - "tls") SMTP_DEFAULT_PORT="587";; - *) - _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." - return 1 - ;; + "none") SMTP_DEFAULT_PORT="25" ;; + "ssl") SMTP_DEFAULT_PORT="465" ;; + "tls") SMTP_DEFAULT_PORT="587" ;; + *) + _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." + return 1 + ;; esac SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" @@ -125,7 +125,8 @@ _smtp_send() { fi # language=Python - smtp_send_output="$($SMTP_PYTHON < Date: Mon, 11 Jan 2021 11:46:26 -0800 Subject: [PATCH 1291/2234] Only save config if send is successful --- notify/smtp.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 6171cb9b..092bb2b9 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -78,6 +78,13 @@ smtp_send() { SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" SMTP_DEFAULT_TIMEOUT="15" + # Send the message: + if ! _smtp_send "$@"; then + _err "$smtp_send_output" + return 1 + fi + + # Save remaining config if successful. (SMTP_PYTHON is saved earlier.) _saveaccountconf_mutable SMTP_FROM "$SMTP_FROM" _saveaccountconf_mutable SMTP_TO "$SMTP_TO" _saveaccountconf_mutable SMTP_HOST "$SMTP_HOST" @@ -87,12 +94,6 @@ smtp_send() { _saveaccountconf_mutable SMTP_PASSWORD "$SMTP_PASSWORD" _saveaccountconf_mutable SMTP_TIMEOUT "$SMTP_TIMEOUT" - # Send the message: - if ! _smtp_send "$@"; then - _err "$smtp_send_output" - return 1 - fi - return 0 } From e272fde95e260727de8ceaea05c2767a3eb6114f Mon Sep 17 00:00:00 2001 From: medmunds Date: Mon, 11 Jan 2021 12:59:51 -0800 Subject: [PATCH 1292/2234] Add instructions for reporting bugs --- notify/smtp.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/notify/smtp.sh b/notify/smtp.sh index 092bb2b9..a74ce092 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -2,6 +2,8 @@ # support smtp +# Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3358 + # This implementation uses Python (2 or 3), which is available in many environments. # If you don't have Python, try "mail" notification instead of "smtp". From 65a1b892e31ae3b5c2600965615d124c47b47955 Mon Sep 17 00:00:00 2001 From: medmunds Date: Sun, 14 Feb 2021 15:47:51 -0800 Subject: [PATCH 1293/2234] Prep for curl or Python; clean up SMTP_* variable usage --- notify/smtp.sh | 207 ++++++++++++++++++++++++++++--------------------- 1 file changed, 120 insertions(+), 87 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index a74ce092..cb29d0f7 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -4,8 +4,8 @@ # Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3358 -# This implementation uses Python (2 or 3), which is available in many environments. -# If you don't have Python, try "mail" notification instead of "smtp". +# This implementation uses either curl or Python (3 or 2.7). +# (See also the "mail" notify hook, which supports other ways to send mail.) # SMTP_FROM="from@example.com" # required # SMTP_TO="to@example.com" # required @@ -14,79 +14,132 @@ # SMTP_SECURE="none" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) # SMTP_USERNAME="" # set if SMTP server requires login # SMTP_PASSWORD="" # set if SMTP server requires login -# SMTP_TIMEOUT="15" # seconds for SMTP operations to timeout -# SMTP_PYTHON="/path/to/python" # defaults to system python3 or python +# SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout +# SMTP_BIN="/path/to/curl_or_python" # default finds first of curl, python3, or python on PATH +# subject content statuscode smtp_send() { - # Find a Python interpreter: - SMTP_PYTHON="${SMTP_PYTHON:-$(_readaccountconf_mutable SMTP_PYTHON)}" - if [ "$SMTP_PYTHON" ]; then - if _exists "$SMTP_PYTHON"; then - _saveaccountconf_mutable SMTP_PYTHON "$SMTP_PYTHON" - else - _err "SMTP_PYTHON '$SMTP_PYTHON' does not exist." - return 1 - fi - else - # No SMTP_PYTHON setting; try to run default Python. - # (This is not saved with the conf.) - if _exists python3; then - SMTP_PYTHON="python3" - elif _exists python; then - SMTP_PYTHON="python" - else - _err "Can't locate Python interpreter; please define SMTP_PYTHON." - return 1 - fi - fi - _debug "SMTP_PYTHON" "$SMTP_PYTHON" - _debug "Python version" "$($SMTP_PYTHON --version 2>&1)" + _SMTP_SUBJECT="$1" + _SMTP_CONTENT="$2" + # UNUSED: _statusCode="$3" # 0: success, 1: error 2($RENEW_SKIP): skipped - # Validate other settings: + # Load config: SMTP_FROM="${SMTP_FROM:-$(_readaccountconf_mutable SMTP_FROM)}" + SMTP_TO="${SMTP_TO:-$(_readaccountconf_mutable SMTP_TO)}" + SMTP_HOST="${SMTP_HOST:-$(_readaccountconf_mutable SMTP_HOST)}" + SMTP_PORT="${SMTP_PORT:-$(_readaccountconf_mutable SMTP_PORT)}" + SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" + SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" + SMTP_PASSWORD="${SMTP_PASSWORD:-$(_readaccountconf_mutable SMTP_PASSWORD)}" + SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" + SMTP_BIN="${SMTP_BIN:-$(_readaccountconf_mutable SMTP_BIN)}" + + _debug "SMTP_FROM" "$SMTP_FROM" + _debug "SMTP_TO" "$SMTP_TO" + _debug "SMTP_HOST" "$SMTP_HOST" + _debug "SMTP_PORT" "$SMTP_PORT" + _debug "SMTP_SECURE" "$SMTP_SECURE" + _debug "SMTP_USERNAME" "$SMTP_USERNAME" + _secure_debug "SMTP_PASSWORD" "$SMTP_PASSWORD" + _debug "SMTP_TIMEOUT" "$SMTP_TIMEOUT" + _debug "SMTP_BIN" "$SMTP_BIN" + + _debug "_SMTP_SUBJECT" "$_SMTP_SUBJECT" + _debug "_SMTP_CONTENT" "$_SMTP_CONTENT" + + # Validate config and apply defaults: + # _SMTP_* variables are the resolved (with defaults) versions of SMTP_*. + # (The _SMTP_* versions will not be stored in account conf.) + + if [ -n "$SMTP_BIN" ] && ! _exists "$SMTP_BIN"; then + _err "SMTP_BIN '$SMTP_BIN' does not exist." + return 1 + fi + _SMTP_BIN="$SMTP_BIN" + if [ -z "$_SMTP_BIN" ]; then + # Look for a command that can communicate with an SMTP server. + # (Please don't add sendmail, ssmtp, mutt, mail, or msmtp here. + # Those are already handled by the "mail" notify hook.) + for cmd in curl python3 python2.7 python pypy3 pypy; do + if _exists "$cmd"; then + _SMTP_BIN="$cmd" + break + fi + done + if [ -z "$_SMTP_BIN" ]; then + _err "The smtp notify-hook requires curl or Python, but can't find any." + _err 'If you have one of them, define SMTP_BIN="/path/to/curl_or_python".' + _err 'Otherwise, see if you can use the "mail" notify-hook instead.' + return 1 + fi + _debug "_SMTP_BIN" "$_SMTP_BIN" + fi + if [ -z "$SMTP_FROM" ]; then _err "You must define SMTP_FROM as the sender email address." return 1 fi + _SMTP_FROM="$SMTP_FROM" - SMTP_TO="${SMTP_TO:-$(_readaccountconf_mutable SMTP_TO)}" if [ -z "$SMTP_TO" ]; then _err "You must define SMTP_TO as the recipient email address." return 1 fi + _SMTP_TO="$SMTP_TO" - SMTP_HOST="${SMTP_HOST:-$(_readaccountconf_mutable SMTP_HOST)}" if [ -z "$SMTP_HOST" ]; then _err "You must define SMTP_HOST as the SMTP server hostname." return 1 fi - SMTP_PORT="${SMTP_PORT:-$(_readaccountconf_mutable SMTP_PORT)}" + _SMTP_HOST="$SMTP_HOST" - SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" - SMTP_SECURE="${SMTP_SECURE:-none}" - case "$SMTP_SECURE" in - "none") SMTP_DEFAULT_PORT="25" ;; - "ssl") SMTP_DEFAULT_PORT="465" ;; - "tls") SMTP_DEFAULT_PORT="587" ;; + _SMTP_SECURE="${SMTP_SECURE:-none}" + case "$_SMTP_SECURE" in + "none") smtp_default_port="25" ;; + "ssl") smtp_default_port="465" ;; + "tls") smtp_default_port="587" ;; *) _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." return 1 ;; esac - SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" - SMTP_PASSWORD="${SMTP_PASSWORD:-$(_readaccountconf_mutable SMTP_PASSWORD)}" + _SMTP_PORT="${SMTP_PORT:-$smtp_default_port}" + if [ -z "$SMTP_PORT" ]; then + _debug "_SMTP_PORT" "$_SMTP_PORT" + fi - SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" - SMTP_DEFAULT_TIMEOUT="15" + _SMTP_USERNAME="$SMTP_USERNAME" + _SMTP_PASSWORD="$SMTP_PASSWORD" + _SMTP_TIMEOUT="${SMTP_TIMEOUT:-30}" + + # Run with --debug 2 (or above) to echo the transcript of the SMTP session. + # Careful: this may include SMTP_PASSWORD in plaintext! + if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then + _SMTP_SHOW_TRANSCRIPT="True" + else + _SMTP_SHOW_TRANSCRIPT="" + fi # Send the message: - if ! _smtp_send "$@"; then - _err "$smtp_send_output" + case "$(basename "$_SMTP_BIN")" in + curl) _smtp_send=_smtp_send_curl ;; + py*) _smtp_send=_smtp_send_python ;; + *) + _err "Can't figure out how to invoke $_SMTP_BIN." + _err "Please re-run with --debug and report a bug." + return 1 + ;; + esac + + if ! smtp_output="$($_smtp_send)"; then + _err "Error sending message with $_SMTP_BIN." + _err "${smtp_output:-(No additional details; try --debug or --debug 2)}" return 1 fi - # Save remaining config if successful. (SMTP_PYTHON is saved earlier.) + # Save config only if send was successful: + _saveaccountconf_mutable SMTP_BIN "$SMTP_BIN" _saveaccountconf_mutable SMTP_FROM "$SMTP_FROM" _saveaccountconf_mutable SMTP_TO "$SMTP_TO" _saveaccountconf_mutable SMTP_HOST "$SMTP_HOST" @@ -99,37 +152,21 @@ smtp_send() { return 0 } -# _send subject content statuscode -# Send the message via Python using SMTP_* settings -_smtp_send() { - _subject="$1" - _content="$2" - _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped - _debug "_subject" "$_subject" - _debug "_content" "$_content" - _debug "_statusCode" "$_statusCode" - _debug "SMTP_FROM" "$SMTP_FROM" - _debug "SMTP_TO" "$SMTP_TO" - _debug "SMTP_HOST" "$SMTP_HOST" - _debug "SMTP_PORT" "$SMTP_PORT" - _debug "SMTP_DEFAULT_PORT" "$SMTP_DEFAULT_PORT" - _debug "SMTP_SECURE" "$SMTP_SECURE" - _debug "SMTP_USERNAME" "$SMTP_USERNAME" - _secure_debug "SMTP_PASSWORD" "$SMTP_PASSWORD" - _debug "SMTP_TIMEOUT" "$SMTP_TIMEOUT" - _debug "SMTP_DEFAULT_TIMEOUT" "$SMTP_DEFAULT_TIMEOUT" +# Send the message via curl using _SMTP_* variables +_smtp_send_curl() { + # TODO: implement + echo "_smtp_send_curl not implemented" + return 1 +} - if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then - # Output the SMTP server dialogue. (Note this will include SMTP_PASSWORD!) - smtp_debug="True" - else - smtp_debug="" - fi + +# Send the message via Python using _SMTP_* variables +_smtp_send_python() { + _debug "Python version" "$("$_SMTP_BIN" --version 2>&1)" # language=Python - smtp_send_output="$( - $SMTP_PYTHON < Date: Sun, 14 Feb 2021 19:56:23 -0800 Subject: [PATCH 1294/2234] Implement curl version of smtp notify-hook --- notify/smtp.sh | 111 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 6 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index cb29d0f7..44a5821f 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -127,14 +127,16 @@ smtp_send() { py*) _smtp_send=_smtp_send_python ;; *) _err "Can't figure out how to invoke $_SMTP_BIN." - _err "Please re-run with --debug and report a bug." + _err "Check your SMTP_BIN setting." return 1 ;; esac if ! smtp_output="$($_smtp_send)"; then _err "Error sending message with $_SMTP_BIN." - _err "${smtp_output:-(No additional details; try --debug or --debug 2)}" + if [ -n "$smtp_output" ]; then + _err "$smtp_output" + fi return 1 fi @@ -152,12 +154,109 @@ smtp_send() { return 0 } - # Send the message via curl using _SMTP_* variables _smtp_send_curl() { - # TODO: implement - echo "_smtp_send_curl not implemented" - return 1 + # curl passes --mail-from and --mail-rcpt directly to the SMTP protocol without + # additional parsing, and SMTP requires addr-spec only (no display names). + # In the future, maybe try to parse the addr-spec out for curl args (non-trivial). + if _email_has_display_name "$_SMTP_FROM"; then + _err "curl smtp only allows a simple email address in SMTP_FROM." + _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." + return 1 + fi + if _email_has_display_name "$_SMTP_TO"; then + _err "curl smtp only allows simple email addresses in SMTP_TO." + _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." + return 1 + fi + + # Build curl args in $@ + + case "$_SMTP_SECURE" in + none) + set -- --url "smtp://${_SMTP_HOST}:${_SMTP_PORT}" + ;; + ssl) + set -- --url "smtps://${_SMTP_HOST}:${_SMTP_PORT}" + ;; + tls) + set -- --url "smtp://${_SMTP_HOST}:${_SMTP_PORT}" --ssl-reqd + ;; + *) + # This will only occur if someone adds a new SMTP_SECURE option above + # without updating this code for it. + _err "Unhandled _SMTP_SECURE='$_SMTP_SECURE' in _smtp_send_curl" + _err "Please re-run with --debug and report a bug." + return 1 + ;; + esac + + set -- "$@" \ + --upload-file - \ + --mail-from "$_SMTP_FROM" \ + --max-time "$_SMTP_TIMEOUT" + + # Burst comma-separated $_SMTP_TO into individual --mail-rcpt args. + _to="${_SMTP_TO}," + while [ -n "$_to" ]; do + _rcpt="${_to%%,*}" + _to="${_to#*,}" + set -- "$@" --mail-rcpt "$_rcpt" + done + + _smtp_login="${_SMTP_USERNAME}:${_SMTP_PASSWORD}" + if [ "$_smtp_login" != ":" ]; then + set -- "$@" --user "$_smtp_login" + fi + + if [ "$_SMTP_SHOW_TRANSCRIPT" = "True" ]; then + set -- "$@" --verbose + else + set -- "$@" --silent --show-error + fi + + raw_message="$(_smtp_raw_message)" + + _debug2 "curl command:" "$_SMTP_BIN" "$*" + _debug2 "raw_message:\n$raw_message" + + echo "$raw_message" | "$_SMTP_BIN" "$@" +} + +# Output an RFC-822 / RFC-5322 email message using _SMTP_* variables +_smtp_raw_message() { + echo "From: $_SMTP_FROM" + echo "To: $_SMTP_TO" + echo "Subject: $(_mime_encoded_word "$_SMTP_SUBJECT")" + if _exists date; then + echo "Date: $(date +'%a, %-d %b %Y %H:%M:%S %z')" + fi + echo "Content-Type: text/plain; charset=utf-8" + echo "X-Mailer: acme.sh --notify-hook smtp" + echo + echo "$_SMTP_CONTENT" +} + +# Convert text to RFC-2047 MIME "encoded word" format if it contains non-ASCII chars +# text +_mime_encoded_word() { + _text="$1" + # (regex character ranges like [a-z] can be locale-dependent; enumerate ASCII chars to avoid that) + _ascii='] $`"'"[!#%&'()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ~^_abcdefghijklmnopqrstuvwxyz{|}~-" + if expr "$_text" : "^.*[^$_ascii]" >/dev/null; then + # At least one non-ASCII char; convert entire thing to encoded word + printf "%s" "=?UTF-8?B?$(printf "%s" "$_text" | _base64)?=" + else + # Just printable ASCII, no conversion needed + printf "%s" "$_text" + fi +} + +# Simple check for display name in an email address (< > or ") +# email +_email_has_display_name() { + _email="$1" + expr "$_email" : '^.*[<>"]' > /dev/null } From fe3e8a7bb6fc93daf938f965fbf0b260803c7b19 Mon Sep 17 00:00:00 2001 From: medmunds Date: Sun, 14 Feb 2021 20:06:07 -0800 Subject: [PATCH 1295/2234] More than one blank line is an abomination, apparently I will not try to use whitespace to group code visually --- notify/smtp.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 44a5821f..c9927e3e 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -256,10 +256,9 @@ _mime_encoded_word() { # email _email_has_display_name() { _email="$1" - expr "$_email" : '^.*[<>"]' > /dev/null + expr "$_email" : '^.*[<>"]' >/dev/null } - # Send the message via Python using _SMTP_* variables _smtp_send_python() { _debug "Python version" "$("$_SMTP_BIN" --version 2>&1)" From 06fb3d94767e475df2c4c0bcb418994f6554674e Mon Sep 17 00:00:00 2001 From: Mike Edmunds Date: Sun, 14 Feb 2021 23:01:21 -0800 Subject: [PATCH 1296/2234] Fix: Unifi deploy hook support Unifi Cloud Key (#3327) * fix: unifi deploy hook also update Cloud Key nginx certs When running on a Unifi Cloud Key device, also deploy to /etc/ssl/private/cloudkey.{crt,key} and reload nginx. This makes the new cert available for the Cloud Key management app running via nginx on port 443 (as well as the port 8443 Unifi Controller app the deploy hook already supported). Fixes #3326 * Improve settings documentation comments * Improve Cloud Key pre-flight error messaging * Fix typo * Add support for UnifiOS (Cloud Key Gen2) Since UnifiOS does not use the Java keystore (like a Unifi Controller or Cloud Key Gen1 deploy), this also reworks the settings validation and error messaging somewhat. * PR review fixes * Detect unsupported Cloud Key java keystore location * Don't try to restart inactive services (and remove extra spaces from reload command) * Clean up error messages and internal variables * Change to _getdeployconf/_savedeployconf * Switch from cp to cat to preserve file permissions --- deploy/unifi.sh | 224 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 169 insertions(+), 55 deletions(-) diff --git a/deploy/unifi.sh b/deploy/unifi.sh index 184aa62e..a864135e 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -1,12 +1,43 @@ #!/usr/bin/env sh -#Here is a script to deploy cert to unifi server. +# Here is a script to deploy cert on a Unifi Controller or Cloud Key device. +# It supports: +# - self-hosted Unifi Controller +# - Unifi Cloud Key (Gen1/2/2+) +# - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only) +# Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359 #returns 0 means success, otherwise error. +# The deploy-hook automatically detects standard Unifi installations +# for each of the supported environments. Most users should not need +# to set any of these variables, but if you are running a self-hosted +# Controller with custom locations, set these as necessary before running +# the deploy hook. (Defaults shown below.) +# +# Settings for Unifi Controller: +# Location of Java keystore or unifi.keystore.jks file: #DEPLOY_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore" +# Keystore password (built into Unifi Controller, not a user-set password): #DEPLOY_UNIFI_KEYPASS="aircontrolenterprise" +# Command to restart Unifi Controller: #DEPLOY_UNIFI_RELOAD="service unifi restart" +# +# Settings for Unifi Cloud Key Gen1 (nginx admin pages): +# Directory where cloudkey.crt and cloudkey.key live: +#DEPLOY_UNIFI_CLOUDKEY_CERTDIR="/etc/ssl/private" +# Command to restart maintenance pages and Controller +# (same setting as above, default is updated when running on Cloud Key Gen1): +#DEPLOY_UNIFI_RELOAD="service nginx restart && service unifi restart" +# +# Settings for UnifiOS (Cloud Key Gen2): +# Directory where unifi-core.crt and unifi-core.key live: +#DEPLOY_UNIFI_CORE_CONFIG="/data/unifi-core/config/" +# Command to restart unifi-core: +#DEPLOY_UNIFI_RELOAD="systemctl restart unifi-core" +# +# At least one of DEPLOY_UNIFI_KEYSTORE, DEPLOY_UNIFI_CLOUDKEY_CERTDIR, +# or DEPLOY_UNIFI_CORE_CONFIG must exist to receive the deployed certs. ######## Public functions ##################### @@ -24,77 +55,160 @@ unifi_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - if ! _exists keytool; then - _err "keytool not found" - return 1 - fi + _getdeployconf DEPLOY_UNIFI_KEYSTORE + _getdeployconf DEPLOY_UNIFI_KEYPASS + _getdeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR + _getdeployconf DEPLOY_UNIFI_CORE_CONFIG + _getdeployconf DEPLOY_UNIFI_RELOAD - DEFAULT_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore" - _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-$DEFAULT_UNIFI_KEYSTORE}" - DEFAULT_UNIFI_KEYPASS="aircontrolenterprise" - _unifi_keypass="${DEPLOY_UNIFI_KEYPASS:-$DEFAULT_UNIFI_KEYPASS}" - DEFAULT_UNIFI_RELOAD="service unifi restart" - _reload="${DEPLOY_UNIFI_RELOAD:-$DEFAULT_UNIFI_RELOAD}" + _debug2 DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" + _debug2 DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" + _debug2 DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" + _debug2 DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG" + _debug2 DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" - _debug _unifi_keystore "$_unifi_keystore" - if [ ! -f "$_unifi_keystore" ]; then - if [ -z "$DEPLOY_UNIFI_KEYSTORE" ]; then - _err "unifi keystore is not found, please define DEPLOY_UNIFI_KEYSTORE" - return 1 - else - _err "It seems that the specified unifi keystore is not valid, please check." + # Space-separated list of environments detected and installed: + _services_updated="" + + # Default reload commands accumulated as we auto-detect environments: + _reload_cmd="" + + # Unifi Controller environment (self hosted or any Cloud Key) -- + # auto-detect by file /usr/lib/unifi/data/keystore: + _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}" + if [ -f "$_unifi_keystore" ]; then + _info "Installing certificate for Unifi Controller (Java keystore)" + _debug _unifi_keystore "$_unifi_keystore" + if ! _exists keytool; then + _err "keytool not found" return 1 fi - fi - if [ ! -w "$_unifi_keystore" ]; then - _err "The file $_unifi_keystore is not writable, please change the permission." + if [ ! -w "$_unifi_keystore" ]; then + _err "The file $_unifi_keystore is not writable, please change the permission." + return 1 + fi + + _unifi_keypass="${DEPLOY_UNIFI_KEYPASS:-aircontrolenterprise}" + + _debug "Generate import pkcs12" + _import_pkcs12="$(_mktemp)" + _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root + # shellcheck disable=SC2181 + if [ "$?" != "0" ]; then + _err "Error generating pkcs12. Please re-run with --debug and report a bug." + return 1 + fi + + _debug "Import into keystore: $_unifi_keystore" + if keytool -importkeystore \ + -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ + -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ + -alias unifi -noprompt; then + _debug "Import keystore success!" + rm "$_import_pkcs12" + else + _err "Error importing into Unifi Java keystore." + _err "Please re-run with --debug and report a bug." + rm "$_import_pkcs12" + return 1 + fi + + if systemctl -q is-active unifi; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart" + fi + _services_updated="${_services_updated} unifi" + _info "Install Unifi Controller certificate success!" + elif [ "$DEPLOY_UNIFI_KEYSTORE" ]; then + _err "The specified DEPLOY_UNIFI_KEYSTORE='$DEPLOY_UNIFI_KEYSTORE' is not valid, please check." return 1 fi - _info "Generate import pkcs12" - _import_pkcs12="$(_mktemp)" - _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root - if [ "$?" != "0" ]; then - _err "Oops, error creating import pkcs12, please report bug to us." + # Cloud Key environment (non-UnifiOS -- nginx serves admin pages) -- + # auto-detect by file /etc/ssl/private/cloudkey.key: + _cloudkey_certdir="${DEPLOY_UNIFI_CLOUDKEY_CERTDIR:-/etc/ssl/private}" + if [ -f "${_cloudkey_certdir}/cloudkey.key" ]; then + _info "Installing certificate for Cloud Key Gen1 (nginx admin pages)" + _debug _cloudkey_certdir "$_cloudkey_certdir" + if [ ! -w "$_cloudkey_certdir" ]; then + _err "The directory $_cloudkey_certdir is not writable; please check permissions." + return 1 + fi + # Cloud Key expects to load the keystore from /etc/ssl/private/unifi.keystore.jks. + # Normally /usr/lib/unifi/data/keystore is a symlink there (so the keystore was + # updated above), but if not, we don't know how to handle this installation: + if ! cmp -s "$_unifi_keystore" "${_cloudkey_certdir}/unifi.keystore.jks"; then + _err "Unsupported Cloud Key configuration: keystore not found at '${_cloudkey_certdir}/unifi.keystore.jks'" + return 1 + fi + + cat "$_cfullchain" >"${_cloudkey_certdir}/cloudkey.crt" + cat "$_ckey" >"${_cloudkey_certdir}/cloudkey.key" + (cd "$_cloudkey_certdir" && tar -cf cert.tar cloudkey.crt cloudkey.key unifi.keystore.jks) + + if systemctl -q is-active nginx; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }service nginx restart" + fi + _info "Install Cloud Key Gen1 certificate success!" + _services_updated="${_services_updated} nginx" + elif [ "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" ]; then + _err "The specified DEPLOY_UNIFI_CLOUDKEY_CERTDIR='$DEPLOY_UNIFI_CLOUDKEY_CERTDIR' is not valid, please check." return 1 fi - _info "Modify unifi keystore: $_unifi_keystore" - if keytool -importkeystore \ - -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ - -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ - -alias unifi -noprompt; then - _info "Import keystore success!" - rm "$_import_pkcs12" - else - _err "Import unifi keystore error, please report bug to us." - rm "$_import_pkcs12" + # UnifiOS environment -- auto-detect by /data/unifi-core/config/unifi-core.key: + _unifi_core_config="${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}" + if [ -f "${_unifi_core_config}/unifi-core.key" ]; then + _info "Installing certificate for UnifiOS" + _debug _unifi_core_config "$_unifi_core_config" + if [ ! -w "$_unifi_core_config" ]; then + _err "The directory $_unifi_core_config is not writable; please check permissions." + return 1 + fi + + cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" + cat "$_ckey" >"${_unifi_core_config}/unifi-core.key" + + if systemctl -q is-active unifi-core; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi-core" + fi + _info "Install UnifiOS certificate success!" + _services_updated="${_services_updated} unifi-core" + elif [ "$DEPLOY_UNIFI_CORE_CONFIG" ]; then + _err "The specified DEPLOY_UNIFI_CORE_CONFIG='$DEPLOY_UNIFI_CORE_CONFIG' is not valid, please check." return 1 fi - _info "Run reload: $_reload" - if eval "$_reload"; then + if [ -z "$_services_updated" ]; then + # None of the Unifi environments were auto-detected, so no deployment has occurred + # (and none of DEPLOY_UNIFI_{KEYSTORE,CLOUDKEY_CERTDIR,CORE_CONFIG} were set). + _err "Unable to detect Unifi environment in standard location." + _err "(This deploy hook must be run on the Unifi device, not a remote machine.)" + _err "For non-standard Unifi installations, set DEPLOY_UNIFI_KEYSTORE," + _err "DEPLOY_UNIFI_CLOUDKEY_CERTDIR, and/or DEPLOY_UNIFI_CORE_CONFIG as appropriate." + return 1 + fi + + _reload_cmd="${DEPLOY_UNIFI_RELOAD:-$_reload_cmd}" + if [ -z "$_reload_cmd" ]; then + _err "Certificates were installed for services:${_services_updated}," + _err "but none appear to be active. Please set DEPLOY_UNIFI_RELOAD" + _err "to a command that will restart the necessary services." + return 1 + fi + _info "Reload services (this may take some time): $_reload_cmd" + if eval "$_reload_cmd"; then _info "Reload success!" - if [ "$DEPLOY_UNIFI_KEYSTORE" ]; then - _savedomainconf DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" - else - _cleardomainconf DEPLOY_UNIFI_KEYSTORE - fi - if [ "$DEPLOY_UNIFI_KEYPASS" ]; then - _savedomainconf DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" - else - _cleardomainconf DEPLOY_UNIFI_KEYPASS - fi - if [ "$DEPLOY_UNIFI_RELOAD" ]; then - _savedomainconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" - else - _cleardomainconf DEPLOY_UNIFI_RELOAD - fi - return 0 else _err "Reload error" return 1 fi - return 0 + # Successful, so save all (non-default) config: + _savedeployconf DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE" + _savedeployconf DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS" + _savedeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR" + _savedeployconf DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG" + _savedeployconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD" + + return 0 } From 8fbec785e826370974a3ccf68a9136fb617dcd7f Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 15 Feb 2021 15:18:49 +0800 Subject: [PATCH 1297/2234] feat: add huaweicloud error handling --- dnsapi/dns_huaweicloud.sh | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 74fec2a9..f7192725 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -5,7 +5,7 @@ # HUAWEICLOUD_ProjectID iam_api="https://iam.myhuaweicloud.com" -dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" +dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work ######## Public functions ##################### @@ -29,16 +29,27 @@ dns_huaweicloud_add() { return 1 fi + unset token # Clear token token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" - _debug2 "${token}" + if [ -z "${token}" ]; then # Check token + _err "dns_api(dns_huaweicloud): Error getting token." + return 1 + fi + _debug "Access token is: ${token}" + + unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" - _debug "${zoneid}" + if [ -z "${zoneid}" ]; then + _err "dns_api(dns_huaweicloud): Error getting zone id." + return 1 + fi + _debug "Zone ID is: ${zoneid}" _debug "Adding Record" _add_record "${token}" "${fulldomain}" "${txtvalue}" ret="$?" if [ "${ret}" != "0" ]; then - _err "dns_huaweicloud: Error adding record." + _err "dns_api(dns_huaweicloud): Error adding record." return 1 fi @@ -69,12 +80,21 @@ dns_huaweicloud_rm() { return 1 fi + unset token # Clear token token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" - _debug2 "${token}" + if [ -z "${token}" ]; then # Check token + _err "dns_api(dns_huaweicloud): Error getting token." + return 1 + fi + _debug "Access token is: ${token}" + + unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" - _debug "${zoneid}" - record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" - _debug "Record Set ID is: ${record_id}" + if [ -z "${zoneid}" ]; then + _err "dns_api(dns_huaweicloud): Error getting zone id." + return 1 + fi + _debug "Zone ID is: ${zoneid}" # Remove all records # Therotically HuaweiCloud does not allow more than one record set From c090c19bfee692b69a31984c5eb40d367f38592d Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 15 Feb 2021 15:19:18 +0800 Subject: [PATCH 1298/2234] fix: fix freebsd and solaris --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 5dc2d453..ed0426ad 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -184,7 +184,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.7 + - uses: vmactions/freebsd-vm@v0.1.2 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl @@ -223,7 +223,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.1 + - uses: vmactions/solaris-vm@v0.0.3 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat curl From fe0bee21b0a1a545e939357438f9c46d0cc13a7e Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 15 Feb 2021 21:25:27 +0800 Subject: [PATCH 1299/2234] support openssl 3.0 fix https://github.com/acmesh-official/acme.sh/issues/3399 --- acme.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index a9301e10..2cb9dd00 100755 --- a/acme.sh +++ b/acme.sh @@ -1122,9 +1122,14 @@ _createkey() { fi fi + __traditional="" + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help genrsa 2>&1)" "-traditional"; then + __traditional="-traditional" + fi + if _isEccKey "$length"; then _debug "Using ec name: $eccname" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam $__traditional -name "$eccname" -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error ecc key name: $eccname" @@ -1132,7 +1137,7 @@ _createkey() { fi else _debug "Using RSA: $length" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa "$length" 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa $__traditional "$length" 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error rsa key: $length" From ae5a6d330d139c150b6011664a9e55d7d5e899ed Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 15 Feb 2021 21:35:59 +0800 Subject: [PATCH 1300/2234] make the fix for rsa key only --- acme.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 2cb9dd00..5e9829a4 100755 --- a/acme.sh +++ b/acme.sh @@ -1122,14 +1122,9 @@ _createkey() { fi fi - __traditional="" - if _contains "$(${ACME_OPENSSL_BIN:-openssl} help genrsa 2>&1)" "-traditional"; then - __traditional="-traditional" - fi - if _isEccKey "$length"; then _debug "Using ec name: $eccname" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam $__traditional -name "$eccname" -genkey 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error ecc key name: $eccname" @@ -1137,6 +1132,10 @@ _createkey() { fi else _debug "Using RSA: $length" + __traditional="" + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help genrsa 2>&1)" "-traditional"; then + __traditional="-traditional" + fi if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa $__traditional "$length" 2>/dev/null)"; then echo "$_opkey" >"$f" else From dc8d91ea39e897679cf02ecb416758afa8df2ba3 Mon Sep 17 00:00:00 2001 From: medmunds Date: Mon, 15 Feb 2021 12:23:48 -0800 Subject: [PATCH 1301/2234] Use PROJECT_NAME and VER for X-Mailer header Also add X-Mailer header to Python version --- notify/smtp.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index c9927e3e..bb71a563 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -112,6 +112,7 @@ smtp_send() { _SMTP_USERNAME="$SMTP_USERNAME" _SMTP_PASSWORD="$SMTP_PASSWORD" _SMTP_TIMEOUT="${SMTP_TIMEOUT:-30}" + _SMTP_X_MAILER="${PROJECT_NAME} ${VER} --notify-hook smtp" # Run with --debug 2 (or above) to echo the transcript of the SMTP session. # Careful: this may include SMTP_PASSWORD in plaintext! @@ -232,7 +233,7 @@ _smtp_raw_message() { echo "Date: $(date +'%a, %-d %b %Y %H:%M:%S %z')" fi echo "Content-Type: text/plain; charset=utf-8" - echo "X-Mailer: acme.sh --notify-hook smtp" + echo "X-Mailer: $_SMTP_X_MAILER" echo echo "$_SMTP_CONTENT" } @@ -286,6 +287,7 @@ smtp_secure = """$_SMTP_SECURE""" username = """$_SMTP_USERNAME""" password = """$_SMTP_PASSWORD""" timeout=int("""$_SMTP_TIMEOUT""") # seconds +x_mailer="""$_SMTP_X_MAILER""" from_email="""$_SMTP_FROM""" to_emails="""$_SMTP_TO""" # can be comma-separated @@ -301,6 +303,7 @@ except (AttributeError, TypeError): msg["Subject"] = subject msg["From"] = from_email msg["To"] = to_emails +msg["X-Mailer"] = x_mailer smtp = None try: From d1cdc1c6a0e81fc1201b38869d52e67d192e94a2 Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 16 Feb 2021 09:33:39 -0800 Subject: [PATCH 1302/2234] Add _clearaccountconf_mutable() --- acme.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/acme.sh b/acme.sh index 5e9829a4..757ed7a5 100755 --- a/acme.sh +++ b/acme.sh @@ -2283,6 +2283,13 @@ _clearaccountconf() { _clear_conf "$ACCOUNT_CONF_PATH" "$1" } +#key +_clearaccountconf_mutable() { + _clearaccountconf "SAVED_$1" + #remove later + _clearaccountconf "$1" +} + #_savecaconf key value _savecaconf() { _save_conf "$CA_CONF" "$1" "$2" From d0445455200076f2470752fad648c61c2c48780c Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 16 Feb 2021 12:49:27 -0800 Subject: [PATCH 1303/2234] Rework read/save config to not save default values Add and use _readaccountconf_mutable_default and _saveaccountconf_mutable_default helpers to capture common default value handling. New approach also eliminates need for separate underscore-prefixed version of each conf var. --- notify/smtp.sh | 253 +++++++++++++++++++++++++++++-------------------- 1 file changed, 148 insertions(+), 105 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index bb71a563..85801604 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -17,155 +17,150 @@ # SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout # SMTP_BIN="/path/to/curl_or_python" # default finds first of curl, python3, or python on PATH +SMTP_SECURE_DEFAULT="none" +SMTP_TIMEOUT_DEFAULT="30" + # subject content statuscode smtp_send() { - _SMTP_SUBJECT="$1" - _SMTP_CONTENT="$2" + SMTP_SUBJECT="$1" + SMTP_CONTENT="$2" # UNUSED: _statusCode="$3" # 0: success, 1: error 2($RENEW_SKIP): skipped - # Load config: - SMTP_FROM="${SMTP_FROM:-$(_readaccountconf_mutable SMTP_FROM)}" - SMTP_TO="${SMTP_TO:-$(_readaccountconf_mutable SMTP_TO)}" - SMTP_HOST="${SMTP_HOST:-$(_readaccountconf_mutable SMTP_HOST)}" - SMTP_PORT="${SMTP_PORT:-$(_readaccountconf_mutable SMTP_PORT)}" - SMTP_SECURE="${SMTP_SECURE:-$(_readaccountconf_mutable SMTP_SECURE)}" - SMTP_USERNAME="${SMTP_USERNAME:-$(_readaccountconf_mutable SMTP_USERNAME)}" - SMTP_PASSWORD="${SMTP_PASSWORD:-$(_readaccountconf_mutable SMTP_PASSWORD)}" - SMTP_TIMEOUT="${SMTP_TIMEOUT:-$(_readaccountconf_mutable SMTP_TIMEOUT)}" - SMTP_BIN="${SMTP_BIN:-$(_readaccountconf_mutable SMTP_BIN)}" - - _debug "SMTP_FROM" "$SMTP_FROM" - _debug "SMTP_TO" "$SMTP_TO" - _debug "SMTP_HOST" "$SMTP_HOST" - _debug "SMTP_PORT" "$SMTP_PORT" - _debug "SMTP_SECURE" "$SMTP_SECURE" - _debug "SMTP_USERNAME" "$SMTP_USERNAME" - _secure_debug "SMTP_PASSWORD" "$SMTP_PASSWORD" - _debug "SMTP_TIMEOUT" "$SMTP_TIMEOUT" - _debug "SMTP_BIN" "$SMTP_BIN" - - _debug "_SMTP_SUBJECT" "$_SMTP_SUBJECT" - _debug "_SMTP_CONTENT" "$_SMTP_CONTENT" - - # Validate config and apply defaults: - # _SMTP_* variables are the resolved (with defaults) versions of SMTP_*. - # (The _SMTP_* versions will not be stored in account conf.) - + # Load and validate config: + SMTP_BIN="$(_readaccountconf_mutable_default SMTP_BIN)" if [ -n "$SMTP_BIN" ] && ! _exists "$SMTP_BIN"; then _err "SMTP_BIN '$SMTP_BIN' does not exist." return 1 fi - _SMTP_BIN="$SMTP_BIN" - if [ -z "$_SMTP_BIN" ]; then + if [ -z "$SMTP_BIN" ]; then # Look for a command that can communicate with an SMTP server. # (Please don't add sendmail, ssmtp, mutt, mail, or msmtp here. # Those are already handled by the "mail" notify hook.) for cmd in curl python3 python2.7 python pypy3 pypy; do if _exists "$cmd"; then - _SMTP_BIN="$cmd" + SMTP_BIN="$cmd" break fi done - if [ -z "$_SMTP_BIN" ]; then + if [ -z "$SMTP_BIN" ]; then _err "The smtp notify-hook requires curl or Python, but can't find any." _err 'If you have one of them, define SMTP_BIN="/path/to/curl_or_python".' _err 'Otherwise, see if you can use the "mail" notify-hook instead.' return 1 fi - _debug "_SMTP_BIN" "$_SMTP_BIN" fi + _debug SMTP_BIN "$SMTP_BIN" + _saveaccountconf_mutable_default SMTP_BIN "$SMTP_BIN" + SMTP_FROM="$(_readaccountconf_mutable_default SMTP_FROM)" if [ -z "$SMTP_FROM" ]; then _err "You must define SMTP_FROM as the sender email address." return 1 fi - _SMTP_FROM="$SMTP_FROM" + _debug SMTP_FROM "$SMTP_FROM" + _saveaccountconf_mutable_default SMTP_FROM "$SMTP_FROM" + SMTP_TO="$(_readaccountconf_mutable_default SMTP_TO)" if [ -z "$SMTP_TO" ]; then _err "You must define SMTP_TO as the recipient email address." return 1 fi - _SMTP_TO="$SMTP_TO" + _debug SMTP_TO "$SMTP_TO" + _saveaccountconf_mutable_default SMTP_TO "$SMTP_TO" + SMTP_HOST="$(_readaccountconf_mutable_default SMTP_HOST)" if [ -z "$SMTP_HOST" ]; then _err "You must define SMTP_HOST as the SMTP server hostname." return 1 fi - _SMTP_HOST="$SMTP_HOST" + _debug SMTP_HOST "$SMTP_HOST" + _saveaccountconf_mutable_default SMTP_HOST "$SMTP_HOST" - _SMTP_SECURE="${SMTP_SECURE:-none}" - case "$_SMTP_SECURE" in - "none") smtp_default_port="25" ;; - "ssl") smtp_default_port="465" ;; - "tls") smtp_default_port="587" ;; + SMTP_SECURE="$(_readaccountconf_mutable_default SMTP_SECURE "$SMTP_SECURE_DEFAULT")" + case "$SMTP_SECURE" in + "none") smtp_port_default="25" ;; + "ssl") smtp_port_default="465" ;; + "tls") smtp_port_default="587" ;; *) _err "Invalid SMTP_SECURE='$SMTP_SECURE'. It must be 'ssl', 'tls' or 'none'." return 1 ;; esac + _debug SMTP_SECURE "$SMTP_SECURE" + _saveaccountconf_mutable_default SMTP_SECURE "$SMTP_SECURE" "$SMTP_SECURE_DEFAULT" - _SMTP_PORT="${SMTP_PORT:-$smtp_default_port}" - if [ -z "$SMTP_PORT" ]; then - _debug "_SMTP_PORT" "$_SMTP_PORT" - fi + SMTP_PORT="$(_readaccountconf_mutable_default SMTP_PORT "$smtp_port_default")" + case "$SMTP_PORT" in + *[!0-9]*) + _err "Invalid SMTP_PORT='$SMTP_PORT'. It must be a port number." + return 1 + ;; + esac + _debug SMTP_PORT "$SMTP_PORT" + _saveaccountconf_mutable_default SMTP_PORT "$SMTP_PORT" "$smtp_port_default" - _SMTP_USERNAME="$SMTP_USERNAME" - _SMTP_PASSWORD="$SMTP_PASSWORD" - _SMTP_TIMEOUT="${SMTP_TIMEOUT:-30}" - _SMTP_X_MAILER="${PROJECT_NAME} ${VER} --notify-hook smtp" + SMTP_USERNAME="$(_readaccountconf_mutable_default SMTP_USERNAME)" + _debug SMTP_USERNAME "$SMTP_USERNAME" + _saveaccountconf_mutable_default SMTP_USERNAME "$SMTP_USERNAME" + + SMTP_PASSWORD="$(_readaccountconf_mutable_default SMTP_PASSWORD)" + _secure_debug SMTP_PASSWORD "$SMTP_PASSWORD" + _saveaccountconf_mutable_default SMTP_PASSWORD "$SMTP_PASSWORD" + + SMTP_TIMEOUT="$(_readaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT_DEFAULT")" + _debug SMTP_TIMEOUT "$SMTP_TIMEOUT" + _saveaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT" "$SMTP_TIMEOUT_DEFAULT" + + SMTP_X_MAILER="${PROJECT_NAME} ${VER} --notify-hook smtp" # Run with --debug 2 (or above) to echo the transcript of the SMTP session. # Careful: this may include SMTP_PASSWORD in plaintext! if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then - _SMTP_SHOW_TRANSCRIPT="True" + SMTP_SHOW_TRANSCRIPT="True" else - _SMTP_SHOW_TRANSCRIPT="" + SMTP_SHOW_TRANSCRIPT="" fi + _debug SMTP_SUBJECT "$SMTP_SUBJECT" + _debug SMTP_CONTENT "$SMTP_CONTENT" + # Send the message: - case "$(basename "$_SMTP_BIN")" in + case "$(basename "$SMTP_BIN")" in curl) _smtp_send=_smtp_send_curl ;; py*) _smtp_send=_smtp_send_python ;; *) - _err "Can't figure out how to invoke $_SMTP_BIN." + _err "Can't figure out how to invoke '$SMTP_BIN'." _err "Check your SMTP_BIN setting." return 1 ;; esac if ! smtp_output="$($_smtp_send)"; then - _err "Error sending message with $_SMTP_BIN." + _err "Error sending message with $SMTP_BIN." if [ -n "$smtp_output" ]; then _err "$smtp_output" fi return 1 fi - # Save config only if send was successful: - _saveaccountconf_mutable SMTP_BIN "$SMTP_BIN" - _saveaccountconf_mutable SMTP_FROM "$SMTP_FROM" - _saveaccountconf_mutable SMTP_TO "$SMTP_TO" - _saveaccountconf_mutable SMTP_HOST "$SMTP_HOST" - _saveaccountconf_mutable SMTP_PORT "$SMTP_PORT" - _saveaccountconf_mutable SMTP_SECURE "$SMTP_SECURE" - _saveaccountconf_mutable SMTP_USERNAME "$SMTP_USERNAME" - _saveaccountconf_mutable SMTP_PASSWORD "$SMTP_PASSWORD" - _saveaccountconf_mutable SMTP_TIMEOUT "$SMTP_TIMEOUT" - return 0 } -# Send the message via curl using _SMTP_* variables +## +## curl smtp sending +## + +# Send the message via curl using SMTP_* variables _smtp_send_curl() { # curl passes --mail-from and --mail-rcpt directly to the SMTP protocol without # additional parsing, and SMTP requires addr-spec only (no display names). # In the future, maybe try to parse the addr-spec out for curl args (non-trivial). - if _email_has_display_name "$_SMTP_FROM"; then + if _email_has_display_name "$SMTP_FROM"; then _err "curl smtp only allows a simple email address in SMTP_FROM." _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." return 1 fi - if _email_has_display_name "$_SMTP_TO"; then + if _email_has_display_name "$SMTP_TO"; then _err "curl smtp only allows simple email addresses in SMTP_TO." _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." return 1 @@ -173,20 +168,20 @@ _smtp_send_curl() { # Build curl args in $@ - case "$_SMTP_SECURE" in + case "$SMTP_SECURE" in none) - set -- --url "smtp://${_SMTP_HOST}:${_SMTP_PORT}" + set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" ;; ssl) - set -- --url "smtps://${_SMTP_HOST}:${_SMTP_PORT}" + set -- --url "smtps://${SMTP_HOST}:${SMTP_PORT}" ;; tls) - set -- --url "smtp://${_SMTP_HOST}:${_SMTP_PORT}" --ssl-reqd + set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" --ssl-reqd ;; *) # This will only occur if someone adds a new SMTP_SECURE option above # without updating this code for it. - _err "Unhandled _SMTP_SECURE='$_SMTP_SECURE' in _smtp_send_curl" + _err "Unhandled SMTP_SECURE='$SMTP_SECURE' in _smtp_send_curl" _err "Please re-run with --debug and report a bug." return 1 ;; @@ -194,23 +189,23 @@ _smtp_send_curl() { set -- "$@" \ --upload-file - \ - --mail-from "$_SMTP_FROM" \ - --max-time "$_SMTP_TIMEOUT" + --mail-from "$SMTP_FROM" \ + --max-time "$SMTP_TIMEOUT" - # Burst comma-separated $_SMTP_TO into individual --mail-rcpt args. - _to="${_SMTP_TO}," + # Burst comma-separated $SMTP_TO into individual --mail-rcpt args. + _to="${SMTP_TO}," while [ -n "$_to" ]; do _rcpt="${_to%%,*}" _to="${_to#*,}" set -- "$@" --mail-rcpt "$_rcpt" done - _smtp_login="${_SMTP_USERNAME}:${_SMTP_PASSWORD}" + _smtp_login="${SMTP_USERNAME}:${SMTP_PASSWORD}" if [ "$_smtp_login" != ":" ]; then set -- "$@" --user "$_smtp_login" fi - if [ "$_SMTP_SHOW_TRANSCRIPT" = "True" ]; then + if [ "$SMTP_SHOW_TRANSCRIPT" = "True" ]; then set -- "$@" --verbose else set -- "$@" --silent --show-error @@ -218,24 +213,24 @@ _smtp_send_curl() { raw_message="$(_smtp_raw_message)" - _debug2 "curl command:" "$_SMTP_BIN" "$*" + _debug2 "curl command:" "$SMTP_BIN" "$*" _debug2 "raw_message:\n$raw_message" - echo "$raw_message" | "$_SMTP_BIN" "$@" + echo "$raw_message" | "$SMTP_BIN" "$@" } -# Output an RFC-822 / RFC-5322 email message using _SMTP_* variables +# Output an RFC-822 / RFC-5322 email message using SMTP_* variables _smtp_raw_message() { - echo "From: $_SMTP_FROM" - echo "To: $_SMTP_TO" - echo "Subject: $(_mime_encoded_word "$_SMTP_SUBJECT")" + echo "From: $SMTP_FROM" + echo "To: $SMTP_TO" + echo "Subject: $(_mime_encoded_word "$SMTP_SUBJECT")" if _exists date; then echo "Date: $(date +'%a, %-d %b %Y %H:%M:%S %z')" fi echo "Content-Type: text/plain; charset=utf-8" - echo "X-Mailer: $_SMTP_X_MAILER" + echo "X-Mailer: $SMTP_X_MAILER" echo - echo "$_SMTP_CONTENT" + echo "$SMTP_CONTENT" } # Convert text to RFC-2047 MIME "encoded word" format if it contains non-ASCII chars @@ -260,12 +255,16 @@ _email_has_display_name() { expr "$_email" : '^.*[<>"]' >/dev/null } -# Send the message via Python using _SMTP_* variables +## +## Python smtp sending +## + +# Send the message via Python using SMTP_* variables _smtp_send_python() { - _debug "Python version" "$("$_SMTP_BIN" --version 2>&1)" + _debug "Python version" "$("$SMTP_BIN" --version 2>&1)" # language=Python - "$_SMTP_BIN" < Date: Tue, 16 Feb 2021 13:13:26 -0800 Subject: [PATCH 1304/2234] Implement _rfc2822_date helper --- notify/smtp.sh | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 85801604..43536cd2 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -224,9 +224,7 @@ _smtp_raw_message() { echo "From: $SMTP_FROM" echo "To: $SMTP_TO" echo "Subject: $(_mime_encoded_word "$SMTP_SUBJECT")" - if _exists date; then - echo "Date: $(date +'%a, %-d %b %Y %H:%M:%S %z')" - fi + echo "Date: $(_rfc2822_date)" echo "Content-Type: text/plain; charset=utf-8" echo "X-Mailer: $SMTP_X_MAILER" echo @@ -248,6 +246,19 @@ _mime_encoded_word() { fi } +# Output current date in RFC-2822 Section 3.3 format as required in email headers +# (e.g., "Mon, 15 Feb 2021 14:22:01 -0800") +_rfc2822_date() { + # Notes: + # - this is deliberately not UTC, because it "SHOULD express local time" per spec + # - the spec requires weekday and month in the C locale (English), not localized + # - this date format specifier has been tested on Linux, Mac, Solaris and FreeBSD + _old_lc_time="$LC_TIME" + LC_TIME=C + date +'%a, %-d %b %Y %H:%M:%S %z' + LC_TIME="$_old_lc_time" +} + # Simple check for display name in an email address (< > or ") # email _email_has_display_name() { From 1330a092fae83fbd831fb51f648209d1ed3b7bff Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 16 Feb 2021 14:02:09 -0800 Subject: [PATCH 1305/2234] Clean email headers and warn on unsupported address format Just in case, make sure CR or NL don't end up in an email header. --- notify/smtp.sh | 55 +++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 43536cd2..42c1487c 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -53,16 +53,28 @@ smtp_send() { _saveaccountconf_mutable_default SMTP_BIN "$SMTP_BIN" SMTP_FROM="$(_readaccountconf_mutable_default SMTP_FROM)" + SMTP_FROM="$(_clean_email_header "$SMTP_FROM")" if [ -z "$SMTP_FROM" ]; then _err "You must define SMTP_FROM as the sender email address." return 1 fi + if _email_has_display_name "$SMTP_FROM"; then + _err "SMTP_FROM must be only a simple email address (sender@example.com)." + _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." + return 1 + fi _debug SMTP_FROM "$SMTP_FROM" _saveaccountconf_mutable_default SMTP_FROM "$SMTP_FROM" SMTP_TO="$(_readaccountconf_mutable_default SMTP_TO)" + SMTP_TO="$(_clean_email_header "$SMTP_TO")" if [ -z "$SMTP_TO" ]; then - _err "You must define SMTP_TO as the recipient email address." + _err "You must define SMTP_TO as the recipient email address(es)." + return 1 + fi + if _email_has_display_name "$SMTP_TO"; then + _err "SMTP_TO must be only simple email addresses (to@example.com,to2@example.com)." + _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." return 1 fi _debug SMTP_TO "$SMTP_TO" @@ -111,7 +123,7 @@ smtp_send() { _debug SMTP_TIMEOUT "$SMTP_TIMEOUT" _saveaccountconf_mutable_default SMTP_TIMEOUT "$SMTP_TIMEOUT" "$SMTP_TIMEOUT_DEFAULT" - SMTP_X_MAILER="${PROJECT_NAME} ${VER} --notify-hook smtp" + SMTP_X_MAILER="$(_clean_email_header "$PROJECT_NAME $VER --notify-hook smtp")" # Run with --debug 2 (or above) to echo the transcript of the SMTP session. # Careful: this may include SMTP_PASSWORD in plaintext! @@ -121,6 +133,7 @@ smtp_send() { SMTP_SHOW_TRANSCRIPT="" fi + SMTP_SUBJECT=$(_clean_email_header "$SMTP_SUBJECT") _debug SMTP_SUBJECT "$SMTP_SUBJECT" _debug SMTP_CONTENT "$SMTP_CONTENT" @@ -146,28 +159,26 @@ smtp_send() { return 0 } +# Strip CR and NL from text to prevent MIME header injection +# text +_clean_email_header() { + printf "%s" "$(echo "$1" | tr -d "\r\n")" +} + +# Simple check for display name in an email address (< > or ") +# email +_email_has_display_name() { + _email="$1" + expr "$_email" : '^.*[<>"]' >/dev/null +} + ## ## curl smtp sending ## # Send the message via curl using SMTP_* variables _smtp_send_curl() { - # curl passes --mail-from and --mail-rcpt directly to the SMTP protocol without - # additional parsing, and SMTP requires addr-spec only (no display names). - # In the future, maybe try to parse the addr-spec out for curl args (non-trivial). - if _email_has_display_name "$SMTP_FROM"; then - _err "curl smtp only allows a simple email address in SMTP_FROM." - _err "Change your SMTP_FROM='$SMTP_FROM' to remove the display name." - return 1 - fi - if _email_has_display_name "$SMTP_TO"; then - _err "curl smtp only allows simple email addresses in SMTP_TO." - _err "Change your SMTP_TO='$SMTP_TO' to remove the display name(s)." - return 1 - fi - # Build curl args in $@ - case "$SMTP_SECURE" in none) set -- --url "smtp://${SMTP_HOST}:${SMTP_PORT}" @@ -219,7 +230,8 @@ _smtp_send_curl() { echo "$raw_message" | "$SMTP_BIN" "$@" } -# Output an RFC-822 / RFC-5322 email message using SMTP_* variables +# Output an RFC-822 / RFC-5322 email message using SMTP_* variables. +# (This assumes variables have already been cleaned for use in email headers.) _smtp_raw_message() { echo "From: $SMTP_FROM" echo "To: $SMTP_TO" @@ -259,13 +271,6 @@ _rfc2822_date() { LC_TIME="$_old_lc_time" } -# Simple check for display name in an email address (< > or ") -# email -_email_has_display_name() { - _email="$1" - expr "$_email" : '^.*[<>"]' >/dev/null -} - ## ## Python smtp sending ## From eb1606b086959eae973365fea6ba0fcad380f908 Mon Sep 17 00:00:00 2001 From: medmunds Date: Tue, 16 Feb 2021 14:41:21 -0800 Subject: [PATCH 1306/2234] Clarify _readaccountconf_mutable_default --- notify/smtp.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 42c1487c..fabde79b 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -358,7 +358,7 @@ PYTHON # - if MY_CONF is set _empty_, output $default_value # (lets user `export MY_CONF=` to clear previous saved value # and return to default, without user having to know default) -# - otherwise if _readaccountconf_mutable $name is non-empty, return that +# - otherwise if _readaccountconf_mutable MY_CONF is non-empty, return that # (value of SAVED_MY_CONF from account.conf) # - otherwise output $default_value _readaccountconf_mutable_default() { @@ -366,8 +366,9 @@ _readaccountconf_mutable_default() { _default_value="$2" eval "_value=\"\$$_name\"" - eval "_explicit_empty_value=\"\${${_name}+empty}\"" - if [ -z "${_value}" ] && [ "${_explicit_empty_value:-}" != "empty" ]; then + eval "_name_is_set=\"\${${_name}+true}\"" + # ($_name_is_set is "true" if $$_name is set to anything, including empty) + if [ -z "${_value}" ] && [ "${_name_is_set:-}" != "true" ]; then _value="$(_readaccountconf_mutable "$_name")" fi if [ -z "${_value}" ]; then From 3503474bb8e7d5647d20ceda988b398cab21cbca Mon Sep 17 00:00:00 2001 From: medmunds Date: Wed, 17 Feb 2021 09:46:13 -0800 Subject: [PATCH 1307/2234] Add Date email header in Python implementation --- notify/smtp.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/notify/smtp.sh b/notify/smtp.sh index fabde79b..0c698631 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -287,6 +287,7 @@ try: from email.message import EmailMessage except ImportError: from email.mime.text import MIMEText as EmailMessage # Python 2 + from email.utils import formatdate as rfc2822_date from smtplib import SMTP, SMTP_SSL, SMTPException from socket import error as SocketError except ImportError as err: @@ -318,6 +319,7 @@ except (AttributeError, TypeError): msg["Subject"] = subject msg["From"] = from_email msg["To"] = to_emails +msg["Date"] = rfc2822_date(localtime=True) msg["X-Mailer"] = x_mailer smtp = None From d8918ea1565b9ae6a575b78f0e6c14092710e8f2 Mon Sep 17 00:00:00 2001 From: medmunds Date: Wed, 17 Feb 2021 09:57:44 -0800 Subject: [PATCH 1308/2234] Use email.policy.default in Python 3 implementation Improves standards compatibility and utf-8 handling in Python 3.3-3.8. (email.policy.default becomes the default in Python 3.9.) --- notify/smtp.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 0c698631..69863206 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -285,8 +285,11 @@ _smtp_send_python() { try: try: from email.message import EmailMessage + from email.policy import default as email_policy_default except ImportError: - from email.mime.text import MIMEText as EmailMessage # Python 2 + # Python 2 (or < 3.3) + from email.mime.text import MIMEText as EmailMessage + email_policy_default = None from email.utils import formatdate as rfc2822_date from smtplib import SMTP, SMTP_SSL, SMTPException from socket import error as SocketError @@ -311,7 +314,7 @@ subject="""$SMTP_SUBJECT""" content="""$SMTP_CONTENT""" try: - msg = EmailMessage() + msg = EmailMessage(policy=email_policy_default) msg.set_content(content) except (AttributeError, TypeError): # Python 2 MIMEText From db967780641780ddaf35e01b0aaee50ffd160a50 Mon Sep 17 00:00:00 2001 From: medmunds Date: Wed, 17 Feb 2021 10:02:14 -0800 Subject: [PATCH 1309/2234] Prefer Python to curl when both available --- notify/smtp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 69863206..71020818 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -15,7 +15,7 @@ # SMTP_USERNAME="" # set if SMTP server requires login # SMTP_PASSWORD="" # set if SMTP server requires login # SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout -# SMTP_BIN="/path/to/curl_or_python" # default finds first of curl, python3, or python on PATH +# SMTP_BIN="/path/to/python_or_curl" # default finds first of python3, python2.7, python, pypy3, pypy, curl on PATH SMTP_SECURE_DEFAULT="none" SMTP_TIMEOUT_DEFAULT="30" @@ -36,7 +36,7 @@ smtp_send() { # Look for a command that can communicate with an SMTP server. # (Please don't add sendmail, ssmtp, mutt, mail, or msmtp here. # Those are already handled by the "mail" notify hook.) - for cmd in curl python3 python2.7 python pypy3 pypy; do + for cmd in python3 python2.7 python pypy3 pypy curl; do if _exists "$cmd"; then SMTP_BIN="$cmd" break From 06f51a5c34b418d991a672c8bbcd56b76f7b86ec Mon Sep 17 00:00:00 2001 From: medmunds Date: Wed, 17 Feb 2021 11:39:16 -0800 Subject: [PATCH 1310/2234] Change default SMTP_SECURE to "tls" Secure by default. Also try to minimize configuration errors. (Many ESPs/ISPs require STARTTLS, and most support it.) --- notify/smtp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 71020818..293c665e 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -11,13 +11,13 @@ # SMTP_TO="to@example.com" # required # SMTP_HOST="smtp.example.com" # required # SMTP_PORT="25" # defaults to 25, 465 or 587 depending on SMTP_SECURE -# SMTP_SECURE="none" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) +# SMTP_SECURE="tls" # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS) # SMTP_USERNAME="" # set if SMTP server requires login # SMTP_PASSWORD="" # set if SMTP server requires login # SMTP_TIMEOUT="30" # seconds for SMTP operations to timeout # SMTP_BIN="/path/to/python_or_curl" # default finds first of python3, python2.7, python, pypy3, pypy, curl on PATH -SMTP_SECURE_DEFAULT="none" +SMTP_SECURE_DEFAULT="tls" SMTP_TIMEOUT_DEFAULT="30" # subject content statuscode From d078ce794ee73b4c98d9d520e339c48de6bb7f30 Mon Sep 17 00:00:00 2001 From: czeming Date: Sat, 20 Feb 2021 17:16:33 +0800 Subject: [PATCH 1311/2234] Update dns_dp.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 没有encode中文字符会导致提交失败 --- dnsapi/dns_dp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 033fa5aa..9b8b7a8b 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -89,7 +89,7 @@ add_record() { _info "Adding record" - if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then + if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=%E9%BB%98%E8%AE%A4"; then return 1 fi From a290f63a15d9e8f8784e735da17c617476e89c51 Mon Sep 17 00:00:00 2001 From: Geert Hendrickx Date: Tue, 23 Feb 2021 10:28:17 +0100 Subject: [PATCH 1312/2234] No need to include EC parameters explicitly with the private key. (they are embedded) --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 757ed7a5..3c66250e 100755 --- a/acme.sh +++ b/acme.sh @@ -1124,7 +1124,7 @@ _createkey() { if _isEccKey "$length"; then _debug "Using ec name: $eccname" - if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then + if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -noout -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else _err "error ecc key name: $eccname" From b0f5ad75aee5fa70f7f4a83e9eb1a9ed6c025c77 Mon Sep 17 00:00:00 2001 From: Kristian Johansson Date: Wed, 24 Feb 2021 08:53:35 +0100 Subject: [PATCH 1313/2234] Fixes response handling and thereby allow issuing of subdomain certs --- dnsapi/dns_simply.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index d053dcf6..b38d0ed3 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -6,7 +6,7 @@ #SIMPLY_ApiKey="apikey" # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" - +SIMPLY_SUCCESS_CODE='"status": 200' SIMPLY_Api_Default="https://api.simply.com/1" ######## Public functions ##################### @@ -171,7 +171,7 @@ _get_root() { return 1 fi - if _contains "$response" '"code":"NOT_FOUND"'; then + if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then _debug "$h not found" else _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) @@ -196,6 +196,12 @@ _simply_add_record() { return 1 fi + if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then + _err "Call to API not sucessfull, see below message for more details" + _err "$response" + return 1 + fi + return 0 } @@ -211,6 +217,12 @@ _simply_delete_record() { return 1 fi + if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then + _err "Call to API not sucessfull, see below message for more details" + _err "$response" + return 1 + fi + return 0 } From 0fe3538331e8380cbab6d9707144a88ada534456 Mon Sep 17 00:00:00 2001 From: Kristian Johansson Date: Wed, 24 Feb 2021 17:34:28 +0100 Subject: [PATCH 1314/2234] Adds comment --- dnsapi/dns_simply.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index b38d0ed3..e0e05017 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -6,9 +6,11 @@ #SIMPLY_ApiKey="apikey" # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" -SIMPLY_SUCCESS_CODE='"status": 200' SIMPLY_Api_Default="https://api.simply.com/1" +#This is used for determining success of REST call +SIMPLY_SUCCESS_CODE='"status": 200' + ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_simply_add() { From 9e5ae30372a273fc5a3e279e370c637609c39a99 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 25 Feb 2021 07:45:22 +0800 Subject: [PATCH 1315/2234] fix https://github.com/acmesh-official/acme.sh/issues/3402 --- acme.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 3c66250e..24cda9c4 100755 --- a/acme.sh +++ b/acme.sh @@ -562,8 +562,16 @@ if _exists xargs && [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then fi _h2b() { - if _exists xxd && xxd -r -p 2>/dev/null; then - return + if _exists xxd; then + if _contains "$(xxd --help 2>&1)" "assumes -c30"; then + if xxd -r -p -c 9999 2>/dev/null; then + return + fi + else + if xxd -r -p 2>/dev/null; then + return + fi + fi fi hex=$(cat) From fd406af9623e8e67b710d8b0787b25850225ac3b Mon Sep 17 00:00:00 2001 From: Lukas Brocke Date: Tue, 23 Feb 2021 19:49:58 +0100 Subject: [PATCH 1316/2234] dnsapi/ionos: Use POST instead of PATCH for adding TXT record The API now supports a POST route for adding records. Therefore checking for already existing records and including them in a PATCH request is no longer necessary. --- dnsapi/dns_ionos.sh | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index e6bd5000..aaf8580f 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -24,20 +24,9 @@ dns_ionos_add() { return 1 fi - _new_record="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}" + _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" - # As no POST route is supported by the API, check for existing records and include them in the PATCH request in order not delete them. - # This is required to support ACME v2 wildcard certificate creation, where two TXT records for the same domain name are created. - - _ionos_get_existing_records "$fulldomain" "$_zone_id" - - if [ "$_existing_records" ]; then - _body="[$_new_record,$_existing_records]" - else - _body="[$_new_record]" - fi - - if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then + if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ -z "$response" ]; then _info "TXT record has been created successfully." return 0 fi @@ -125,17 +114,6 @@ _get_root() { return 1 } -_ionos_get_existing_records() { - fulldomain=$1 - zone_id=$2 - - if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then - response="$(echo "$response" | tr -d "\n")" - - _existing_records="$(printf "%s\n" "$response" | _egrep_o "\"records\":\[.*\]" | _head_n 1 | cut -d '[' -f 2 | sed 's/]//')" - fi -} - _ionos_get_record() { fulldomain=$1 zone_id=$2 @@ -168,7 +146,7 @@ _ionos_rest() { export _H2="Accept: application/json" export _H3="Content-Type: application/json" - response="$(_post "$data" "$IONOS_API$route" "" "$method")" + response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")" else export _H2="Accept: */*" From 5a30f5c00ef3e1a5a1d5c6284056abfcafe420f3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 1 Mar 2021 18:13:50 +0800 Subject: [PATCH 1317/2234] fix https://github.com/acmesh-official/acme.sh/issues/3433 --- acme.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/acme.sh b/acme.sh index 24cda9c4..748363e8 100755 --- a/acme.sh +++ b/acme.sh @@ -2133,6 +2133,12 @@ _send_signed_request() { _sleep $_sleep_retry_sec continue fi + if _contains "$_body" "The Replay Nonce is not recognized"; then + _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." + _CACHED_NONCE="" + _sleep $_sleep_retry_sec + continue + fi fi return 0 done From 7dce465c0662db6f5b55e5bbc8441e1f4ef13a84 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 4 Mar 2021 21:38:51 +0800 Subject: [PATCH 1318/2234] fix https://github.com/acmesh-official/acme.sh/issues/3019 --- dnsapi/dns_namecheap.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 7ce39fa9..5e1f4791 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -208,7 +208,7 @@ _namecheap_parse_host() { _hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2) _hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2) _hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2) - _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2) + _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2 | _xml_decode) _hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2) _hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2) @@ -405,3 +405,11 @@ _namecheap_set_tld_sld() { done } + +_xml_decode() { + sed 's/"/"/g' +} + + + + From d4fb313ff0363fd31f308a301ea7fbfccdb79f84 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 4 Mar 2021 21:50:54 +0800 Subject: [PATCH 1319/2234] fix format --- dnsapi/dns_namecheap.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 5e1f4791..e3dc7997 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -410,6 +410,3 @@ _xml_decode() { sed 's/"/"/g' } - - - From 923eece3f50f455c076da8e101a1c15ba3031653 Mon Sep 17 00:00:00 2001 From: anom-human <80478363+anom-human@users.noreply.github.com> Date: Thu, 11 Mar 2021 19:11:02 +0100 Subject: [PATCH 1320/2234] Update dns_servercow.sh to support wildcard certs Updated dns_servercow.sh to support txt records with multiple entries. This supports wildcard certificates that require txt records with the same name and different contents. --- dnsapi/dns_servercow.sh | 42 +++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index e73d85b0..39f16396 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -48,18 +48,44 @@ dns_servercow_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - - if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then - if printf -- "%s" "$response" | grep "ok" >/dev/null; then - _info "Added, OK" - return 0 + + # check whether a txt record already exists for the subdomain + if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then + _info "A txt record with the same name already exists." + # trim the string on the left + txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} + # trim the string on the right + txtvalue_old=${txtvalue_old%%\"*} + + _debug txtvalue_old "$txtvalue_old" + + _info "Add the new txtvalue to the existing txt record." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":[\"$txtvalue\",\"$txtvalue_old\"],\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added additional txtvalue, OK" + return 0 + else + _err "add txt record error." + return 1 + fi + fi + _err "add txt record error." + return 1 else + _info "There is no txt record with the name yet." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added, OK" + return 0 + else + _err "add txt record error." + return 1 + fi + fi _err "add txt record error." return 1 - fi fi - _err "add txt record error." - + return 1 } From 2cbf3f7e158567848e8451ff80754c32f3841b9c Mon Sep 17 00:00:00 2001 From: anom-human <80478363+anom-human@users.noreply.github.com> Date: Thu, 11 Mar 2021 20:25:49 +0100 Subject: [PATCH 1321/2234] Update dns_servercow.sh to support wildcard certs Updated dns_servercow.sh to support txt records with multiple entries. This supports wildcard certificates that require txt records with the same name and different contents. --- dnsapi/dns_servercow.sh | 64 ++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index 39f16396..f70a2294 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -48,44 +48,44 @@ dns_servercow_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - - # check whether a txt record already exists for the subdomain + + # check whether a txt record already exists for the subdomain if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then - _info "A txt record with the same name already exists." - # trim the string on the left - txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} - # trim the string on the right - txtvalue_old=${txtvalue_old%%\"*} - - _debug txtvalue_old "$txtvalue_old" - - _info "Add the new txtvalue to the existing txt record." - if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":[\"$txtvalue\",\"$txtvalue_old\"],\"ttl\":20}"; then - if printf -- "%s" "$response" | grep "ok" >/dev/null; then - _info "Added additional txtvalue, OK" - return 0 - else - _err "add txt record error." + _info "A txt record with the same name already exists." + # trim the string on the left + txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} + # trim the string on the right + txtvalue_old=${txtvalue_old%%\"*} + + _debug txtvalue_old "$txtvalue_old" + + _info "Add the new txtvalue to the existing txt record." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":[\"$txtvalue\",\"$txtvalue_old\"],\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added additional txtvalue, OK" + return 0 + else + _err "add txt record error." return 1 - fi fi - _err "add txt record error." - return 1 - else - _info "There is no txt record with the name yet." - if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then - if printf -- "%s" "$response" | grep "ok" >/dev/null; then - _info "Added, OK" - return 0 - else - _err "add txt record error." + fi + _err "add txt record error." + return 1 + else + _info "There is no txt record with the name yet." + if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then + if printf -- "%s" "$response" | grep "ok" >/dev/null; then + _info "Added, OK" + return 0 + else + _err "add txt record error." return 1 - fi fi - _err "add txt record error." - return 1 + fi + _err "add txt record error." + return 1 fi - + return 1 } From 69ee81654149962691513c3586254ce8bea4d890 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Mar 2021 20:43:25 +0800 Subject: [PATCH 1322/2234] fix https://github.com/acmesh-official/acme.sh/issues/3312 --- acme.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 748363e8..8d422719 100755 --- a/acme.sh +++ b/acme.sh @@ -5287,6 +5287,7 @@ signcsr() { _renew_hook="${10}" _local_addr="${11}" _challenge_alias="${12}" + _preferred_chain="${13}" _csrsubj=$(_readSubjectFromCSR "$_csrfile") if [ "$?" != "0" ]; then @@ -5333,7 +5334,7 @@ signcsr() { _info "Copy csr to: $CSR_PATH" cp "$_csrfile" "$CSR_PATH" - issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" + issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain" } @@ -7430,7 +7431,7 @@ _process() { deploy "$_domain" "$_deploy_hook" "$_ecc" ;; signcsr) - signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" + signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" ;; showcsr) showcsr "$_csr" "$_domain" From 2b2bce64579908642c340e9bebdbc526a03347ea Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Mar 2021 20:46:12 +0800 Subject: [PATCH 1323/2234] fix format --- dnsapi/dns_namecheap.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index e3dc7997..d15d6b0e 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -409,4 +409,3 @@ _namecheap_set_tld_sld() { _xml_decode() { sed 's/"/"/g' } - From 42ab98b83087cdf459520c895d567a7c81a17203 Mon Sep 17 00:00:00 2001 From: Quentin Dreyer Date: Fri, 12 Mar 2021 12:03:36 +0100 Subject: [PATCH 1324/2234] feat: add dns_porkbun --- dnsapi/dns_porkbun.sh | 171 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 dnsapi/dns_porkbun.sh diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh new file mode 100644 index 00000000..05ecb781 --- /dev/null +++ b/dnsapi/dns_porkbun.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env sh + +# +#PORKBUN_API_KEY="pk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" +#PORKBUN_SECRET_API_KEY="sk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + +PORKBUN_Api="https://porkbun.com/api/json/v3" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_porkbun_add() { + fulldomain=$1 + txtvalue=$2 + + PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}" + PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}" + + if [ -z "$PORKBUN_API_KEY" ] || [ -z "$PORKBUN_SECRET_API_KEY" ]; then + PORKBUN_API_KEY='' + PORKBUN_SECRET_API_KEY='' + _err "You didn't specify a Porkbun api key and secret api key yet." + _err "You can get yours from here https://porkbun.com/account/api." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable PORKBUN_API_KEY "$PORKBUN_API_KEY" + _saveaccountconf_mutable PORKBUN_SECRET_API_KEY "$PORKBUN_SECRET_API_KEY" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _porkbun_rest POST "dns/retrieve/$_domain" + + if ! echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null; then + _err "Error $response" + return 1 + fi + + # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so + # we can not use updating anymore. + # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + # _debug count "$count" + # if [ "$count" = "0" ]; then + _info "Adding record" + if _porkbun_rest POST "dns/create/$_domain" "{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":120}"; then + if _contains "$response" '\"status\":"SUCCESS"'; then + _info "Added, OK" + return 0 + elif _contains "$response" "The record already exists"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error. ($response)" + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_porkbun_rm() { + fulldomain=$1 + txtvalue=$2 + + PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}" + PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _porkbun_rest POST "dns/retrieve/$_domain" + + if ! echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null; then + _err "Error: $response" + return 1 + fi + + count=$(echo "$response" | _egrep_o "\"count\": *[^,]*" | cut -d : -f 2 | tr -d " ") + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(echo "$response" | tr '{' '\n' | grep "$txtvalue" | cut -d, -f1 | cut -d: -f2 | tr -d \") + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _porkbun_rest POST "dns/delete/$_domain/$record_id"; then + _err "Delete record error." + return 1 + fi + echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + return 1 + fi + + if _porkbun_rest POST "dns/retrieve/$h"; then + if _contains "$response" "\"status\":\"SUCCESS\""; then + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" + _domain=$h + return 0 + else + _debug "Go to next level of $_domain" + fi + else + _debug "Go to next level of $_domain" + fi + i=$(_math "$i" + 1) + done + + return 1 +} + +_porkbun_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + api_key_trimmed=$(echo "$PORKBUN_API_KEY" | tr -d '"') + secret_api_key_trimmed=$(echo "$PORKBUN_SECRET_API_KEY" | tr -d '"') + + test -z "$data" && data="{" || data="$(echo $data | cut -d'}' -f1)," + data="$data\"apikey\":\"$api_key_trimmed\",\"secretapikey\":\"$secret_api_key_trimmed\"}" + + export _H1="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$PORKBUN_Api/$ep" "" "$m")" + else + response="$(_get "$PORKBUN_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 4dd202742869c6cb840d7d76fa9ae03530b8fe1a Mon Sep 17 00:00:00 2001 From: qkdreyer Date: Sat, 13 Mar 2021 14:53:43 +0100 Subject: [PATCH 1325/2234] fix: prevent rate limit --- dnsapi/dns_porkbun.sh | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index 05ecb781..18da6b2f 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -35,14 +35,6 @@ dns_porkbun_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "Getting txt records" - _porkbun_rest POST "dns/retrieve/$_domain" - - if ! echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null; then - _err "Error $response" - return 1 - fi - # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so # we can not use updating anymore. # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) @@ -81,14 +73,6 @@ dns_porkbun_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "Getting txt records" - _porkbun_rest POST "dns/retrieve/$_domain" - - if ! echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null; then - _err "Error: $response" - return 1 - fi - count=$(echo "$response" | _egrep_o "\"count\": *[^,]*" | cut -d : -f 2 | tr -d " ") _debug count "$count" if [ "$count" = "0" ]; then @@ -162,6 +146,8 @@ _porkbun_rest() { response="$(_get "$PORKBUN_Api/$ep")" fi + _sleep 3 # prevent rate limit + if [ "$?" != "0" ]; then _err "error $ep" return 1 From e0d5b91388ad5b83d59454aa8db2bc50d3e2b301 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 21 Mar 2021 22:46:35 +0800 Subject: [PATCH 1326/2234] fix freebsd --- .github/workflows/DNS.yml | 2 +- .github/workflows/LetsEncrypt.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index ed0426ad..5ff1f8ab 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -184,7 +184,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.2 + - uses: vmactions/freebsd-vm@v0.1.3 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 7c398c09..7193d88d 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -111,7 +111,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.2 + - uses: vmactions/freebsd-vm@v0.1.3 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl From 051775b9b453b491418f8b23703bf0bc541f076e Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Sun, 21 Mar 2021 16:25:04 +0100 Subject: [PATCH 1327/2234] String update Hopefully the last one --- dnsapi/dns_websupport.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 3b5a8847..e824c9c0 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -32,7 +32,7 @@ dns_websupport_add() { WS_ApiKey="" WS_ApiSecret="" _err "You did not specify the API Key and/or API Secret" - _err "You can get the API credentials from here https://admin.websupport.sk/en/auth/apiKey" + _err "You can get the API login credentials from https://admin.websupport.sk/en/auth/apiKey" return 1 fi From 3c7be32ef50f6df4ced3a75f92305ba9555b7da9 Mon Sep 17 00:00:00 2001 From: emueller Date: Mon, 22 Mar 2021 15:12:27 +0100 Subject: [PATCH 1328/2234] fix _exists error message when MAIL_BIN env variable is not set --- notify/mail.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/notify/mail.sh b/notify/mail.sh index d33fd0d2..10e93f9a 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -78,8 +78,13 @@ mail_send() { _mail_bin() { _MAIL_BIN="" + _MAIL_BINS="sendmail ssmtp mutt mail msmtp" - for b in "$MAIL_BIN" sendmail ssmtp mutt mail msmtp; do + if [ -n "$MAIL_BIN" ]; then + _MAIL_BINS="$MAIL_BIN $_MAIL_BINS" + fi + + for b in $_MAIL_BINS; do if _exists "$b"; then _MAIL_BIN="$b" break From 37e3e2f9c2b829d0691e9d958d764bfc4eb7d03e Mon Sep 17 00:00:00 2001 From: emueller Date: Mon, 22 Mar 2021 15:32:02 +0100 Subject: [PATCH 1329/2234] fixed formating --- notify/mail.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/mail.sh b/notify/mail.sh index 10e93f9a..2be93cd8 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -78,7 +78,7 @@ mail_send() { _mail_bin() { _MAIL_BIN="" - _MAIL_BINS="sendmail ssmtp mutt mail msmtp" + _MAIL_BINS="sendmail ssmtp mutt mail msmtp" if [ -n "$MAIL_BIN" ]; then _MAIL_BINS="$MAIL_BIN $_MAIL_BINS" From 8adb8a69866a5a540ce3ee470872188e7c7c58dd Mon Sep 17 00:00:00 2001 From: wout Date: Tue, 23 Mar 2021 21:20:27 +0100 Subject: [PATCH 1330/2234] While [0-9]+ is a bit more correct than [0-9]*, the former does not seem to work on Solaris. --- dnsapi/dns_constellix.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 75211a6f..2c3b3265 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -44,7 +44,7 @@ dns_constellix_add() { fi fi else - _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+" | cut -d ':' -f 2) + _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2) if _constellix_rest GET "domains/${_domain_id}/records/TXT/${_record_id}"; then _new_rr_values=$(printf "%s\n" "$response" | _egrep_o "\"roundRobin\":\[.*?\]" | sed "s/\]$/,{\"value\":\"${txtvalue}\"}]/") _debug _new_rr_values "$_new_rr_values" @@ -123,7 +123,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\""; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+" | cut -d ':' -f 2) + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2) if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p) _domain="$h" From 6b7db22981085eb2e0b4473f72261f1a575f6899 Mon Sep 17 00:00:00 2001 From: wout Date: Wed, 24 Mar 2021 09:01:54 +0100 Subject: [PATCH 1331/2234] Catch the situation when the TXT record is updated with the same value --- dnsapi/dns_constellix.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 2c3b3265..914f79df 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -53,6 +53,9 @@ dns_constellix_add() { if printf -- "%s" "$response" | grep "{\"success\":\"Record.*updated successfully\"}" >/dev/null; then _info "Updated" return 0 + elif printf -- "%s" "$response" | grep "{\"errors\":\[\"Contents are identical\"\]}" >/dev/null; then + _info "Already exists, no need to update" + return 0 else _err "Error updating TXT record" fi From 3bfcd18a03e532d150b0076643d457aa7d244368 Mon Sep 17 00:00:00 2001 From: wout Date: Wed, 24 Mar 2021 13:56:14 +0100 Subject: [PATCH 1332/2234] Workaround for Solaris, as it does not support non-greedy regex --- dnsapi/dns_constellix.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 914f79df..69d216f0 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -46,7 +46,7 @@ dns_constellix_add() { else _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2) if _constellix_rest GET "domains/${_domain_id}/records/TXT/${_record_id}"; then - _new_rr_values=$(printf "%s\n" "$response" | _egrep_o "\"roundRobin\":\[.*?\]" | sed "s/\]$/,{\"value\":\"${txtvalue}\"}]/") + _new_rr_values=$(printf "%s\n" "$response" | _egrep_o '"roundRobin":\[[^]]*\]' | sed "s/\]$/,{\"value\":\"${txtvalue}\"}]/") _debug _new_rr_values "$_new_rr_values" _info "Updating TXT record" if _constellix_rest PUT "domains/${_domain_id}/records/TXT/${_record_id}" "{\"name\":\"${_sub_domain}\",\"ttl\":60,${_new_rr_values}}"; then From 1530abbd1aacf5877a7317f24f60d8fab96d9735 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Fri, 26 Mar 2021 15:37:12 +0100 Subject: [PATCH 1333/2234] Make uploading cert to subaccount possible --- deploy/cleverreach.sh | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index 552d8149..10670f34 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -25,6 +25,7 @@ cleverreach_deploy() { _getdeployconf DEPLOY_CLEVERREACH_CLIENT_ID _getdeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET + _getdeployconf DEPLOY_CLEVERREACH_SUBCLIENT_ID if [ -z "${DEPLOY_CLEVERREACH_CLIENT_ID}" ]; then _err "CleverReach Client ID is not found, please define DEPLOY_CLEVERREACH_CLIENT_ID." @@ -37,6 +38,7 @@ cleverreach_deploy() { _savedeployconf DEPLOY_CLEVERREACH_CLIENT_ID "${DEPLOY_CLEVERREACH_CLIENT_ID}" _savedeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${DEPLOY_CLEVERREACH_CLIENT_SECRET}" + _savedeployconf DEPLOY_CLEVERREACH_SUBCLIENT_ID "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" _info "Obtaining a CleverReach access token" @@ -50,14 +52,26 @@ cleverreach_deploy() { _debug _regex "$_regex" _access_token=$(echo "$_auth_result" | _json_decode | sed -n "s/$_regex/\1/p") + if ${DEPLOY_CLEVERREACH_SUBCLIENT_ID}; then + _info "Obtaining token for sub-client" + export _H1="Authorization: Bearer ${_access_token}" + _subclient_token_result="$(_get "https://rest.cleverreach.com/v3/clients/$DEPLOY_CLEVERREACH_SUBCLIENT_ID}/token")" + _access_token=$(echo "$_subclient_token_result" | _json_decode | sed -n "s/$_regex/\1/p") + + _debug "Destroying parent token at CleverReach" + _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" + fi + _info "Uploading certificate and key to CleverReach" _certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}" export _H1="Authorization: Bearer ${_access_token}" _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl" "" "POST" "application/json")" - _debug "Destroying token at CleverReach" - _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" + if ! ${DEPLOY_CLEVERREACH_SUBCLIENT_ID}; then + _debug "Destroying token at CleverReach" + _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" + fi if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then _info "Uploaded certificate successfully" From cc90f8346351f3d38617e4186e8edf9b9f17a490 Mon Sep 17 00:00:00 2001 From: Christophe Le Guern Date: Mon, 29 Mar 2021 15:10:14 +0200 Subject: [PATCH 1334/2234] Use 'vault kv put' instead of 'vault write' When using vault_cli with a kv2 path, it isn't working. I have the following error: ``` WARNING! The following warnings were returned from Vault: * Invalid path for a versioned K/V secrets engine. See the API docs for the appropriate API endpoints to use. If using the Vault CLI, use 'vault kv put' for this operation. ``` The new way to write data is to use `vault kv put`, it is compatible with kv1 and kv2. Ref: https://www.vaultproject.io/docs/commands#reading-and-writing-data ``` The original version of K/V used the common read and write operations. A more advanced K/V Version 2 engine was released in Vault 0.10 and introduced the kv get and kv put commands. ``` --- deploy/vault_cli.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/deploy/vault_cli.sh b/deploy/vault_cli.sh index 8b854137..cbb8cc59 100644 --- a/deploy/vault_cli.sh +++ b/deploy/vault_cli.sh @@ -50,12 +50,12 @@ vault_cli_deploy() { fi if [ -n "$FABIO" ]; then - $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1 + $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1 else - $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 - $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 - $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 - $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 + $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 + $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 + $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 + $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 fi } From d853a9ebbed913d752faceb86be29edaf82806a0 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Tue, 30 Mar 2021 09:13:32 +0200 Subject: [PATCH 1335/2234] Make uploading cert to subaccount possible --- deploy/cleverreach.sh | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index 10670f34..03fccc74 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -17,6 +17,8 @@ cleverreach_deploy() { _cca="$4" _cfullchain="$5" + _rest_endpoint="https://rest.cleverreach.com" + _debug _cdomain "$_cdomain" _debug _ckey "$_ckey" _debug _ccert "$_ccert" @@ -43,7 +45,7 @@ cleverreach_deploy() { _info "Obtaining a CleverReach access token" _data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${DEPLOY_CLEVERREACH_CLIENT_ID}\", \"client_secret\": \"${DEPLOY_CLEVERREACH_CLIENT_SECRET}\"}" - _auth_result="$(_post "$_data" "https://rest.cleverreach.com/oauth/token.php" "" "POST" "application/json")" + _auth_result="$(_post "$_data" "$_rest_endpoint/oauth/token.php" "" "POST" "application/json")" _debug _data "$_data" _debug _auth_result "$_auth_result" @@ -52,25 +54,31 @@ cleverreach_deploy() { _debug _regex "$_regex" _access_token=$(echo "$_auth_result" | _json_decode | sed -n "s/$_regex/\1/p") - if ${DEPLOY_CLEVERREACH_SUBCLIENT_ID}; then - _info "Obtaining token for sub-client" - export _H1="Authorization: Bearer ${_access_token}" - _subclient_token_result="$(_get "https://rest.cleverreach.com/v3/clients/$DEPLOY_CLEVERREACH_SUBCLIENT_ID}/token")" - _access_token=$(echo "$_subclient_token_result" | _json_decode | sed -n "s/$_regex/\1/p") + _debug _subclient "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" - _debug "Destroying parent token at CleverReach" - _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" + if ! [ -z "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" ]; then + _info "Obtaining token for sub-client ${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" + export _H1="Authorization: Bearer ${_access_token}" + _subclient_token_result="$(_get "$_rest_endpoint/v3/clients/$DEPLOY_CLEVERREACH_SUBCLIENT_ID/token")" + _access_token=$(echo "$_subclient_token_result" | sed -n "s/\"//p") + + _debug _subclient_token_result "$_access_token" + + _info "Destroying parent token at CleverReach, as it not needed anymore" + _destroy_result="$(_post "" "$_rest_endpoint/v3/oauth/token.json" "" "DELETE" "application/json")" + _debug _destroy_result "$_destroy_result" fi _info "Uploading certificate and key to CleverReach" _certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}" export _H1="Authorization: Bearer ${_access_token}" - _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl" "" "POST" "application/json")" + _add_cert_result="$(_post "$_certData" "$_rest_endpoint/v3/ssl" "" "POST" "application/json")" - if ! ${DEPLOY_CLEVERREACH_SUBCLIENT_ID}; then - _debug "Destroying token at CleverReach" - _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" + if [ -z "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" ]; then + _info "Destroying token at CleverReach, as it not needed anymore" + _destroy_result="$(_post "" "$_rest_endpoint/v3/oauth/token.json" "" "DELETE" "application/json")" + _debug _destroy_result "$_destroy_result" fi if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then From 2867ec509efae5136bf9cb4572bfd46eb7eba7fa Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Tue, 30 Mar 2021 09:18:33 +0200 Subject: [PATCH 1336/2234] Make CI happy --- deploy/cleverreach.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index 03fccc74..a460a139 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -56,7 +56,7 @@ cleverreach_deploy() { _debug _subclient "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" - if ! [ -z "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" ]; then + if [ -n "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" ]; then _info "Obtaining token for sub-client ${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" export _H1="Authorization: Bearer ${_access_token}" _subclient_token_result="$(_get "$_rest_endpoint/v3/clients/$DEPLOY_CLEVERREACH_SUBCLIENT_ID/token")" From e21f3e6c73253c5f8ddc57f640d055237c550552 Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Thu, 8 Apr 2021 16:36:42 +1200 Subject: [PATCH 1337/2234] Escape asterisks in notification content This messes with markdown parsing Signed-off-by: Mike Beattie --- notify/telegram.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/notify/telegram.sh b/notify/telegram.sh index b1306ee1..d9b375d0 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -27,6 +27,7 @@ telegram_send() { fi _saveaccountconf_mutable TELEGRAM_BOT_CHATID "$TELEGRAM_BOT_CHATID" + _content="$(printf "%s" "$_content" | sed -e 's/*/\\\\*/')" _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" _data="{\"text\": \"$_content\", " _data="$_data\"chat_id\": \"$TELEGRAM_BOT_CHATID\", " From 53d26e5c5c5a5ca5f650784dfe22be49d65b06cd Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Thu, 8 Apr 2021 16:37:27 +1200 Subject: [PATCH 1338/2234] Add debug output of $_data variable to aid diagnosis Signed-off-by: Mike Beattie --- notify/telegram.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/notify/telegram.sh b/notify/telegram.sh index d9b375d0..3e266040 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -34,6 +34,8 @@ telegram_send() { _data="$_data\"parse_mode\": \"markdown\", " _data="$_data\"disable_web_page_preview\": \"1\"}" + _debug "$_data" + export _H1="Content-Type: application/json" _telegram_bot_url="https://api.telegram.org/bot${TELEGRAM_BOT_APITOKEN}/sendMessage" if _post "$_data" "$_telegram_bot_url"; then From 39b09f8f87a45656b98d1e8e704783bff2d666ca Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Thu, 8 Apr 2021 16:38:00 +1200 Subject: [PATCH 1339/2234] Dump _post() call output to /dev/null Signed-off-by: Mike Beattie --- notify/telegram.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/telegram.sh b/notify/telegram.sh index 3e266040..c46bc1e2 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -38,7 +38,7 @@ telegram_send() { export _H1="Content-Type: application/json" _telegram_bot_url="https://api.telegram.org/bot${TELEGRAM_BOT_APITOKEN}/sendMessage" - if _post "$_data" "$_telegram_bot_url"; then + if _post "$_data" "$_telegram_bot_url" > /dev/null; then # shellcheck disable=SC2154 _message=$(printf "%s\n" "$response" | sed -n 's/.*"ok":\([^,]*\).*/\1/p') if [ "$_message" = "true" ]; then From fb079f9e50f4de51f44773ac1e24ea3ba81a8a50 Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Thu, 8 Apr 2021 16:44:22 +1200 Subject: [PATCH 1340/2234] Update telegram.sh (fix shellcheck failure) --- notify/telegram.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/telegram.sh b/notify/telegram.sh index c46bc1e2..d16f3a98 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -38,7 +38,7 @@ telegram_send() { export _H1="Content-Type: application/json" _telegram_bot_url="https://api.telegram.org/bot${TELEGRAM_BOT_APITOKEN}/sendMessage" - if _post "$_data" "$_telegram_bot_url" > /dev/null; then + if _post "$_data" "$_telegram_bot_url" >/dev/null; then # shellcheck disable=SC2154 _message=$(printf "%s\n" "$response" | sed -n 's/.*"ok":\([^,]*\).*/\1/p') if [ "$_message" = "true" ]; then From cfbc294832508d9ed18ef17f8517cc337141431d Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 14 Apr 2021 22:18:01 +0800 Subject: [PATCH 1341/2234] fix onecom api --- dnsapi/dns_one.sh | 55 +++-------------------------------------------- 1 file changed, 3 insertions(+), 52 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 890cc804..0a4b2a14 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -1,22 +1,10 @@ #!/usr/bin/env sh -# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- - # one.com ui wrapper for acme.sh -# Author: github: @diseq -# Created: 2019-02-17 -# Fixed by: @der-berni -# Modified: 2020-04-07 -# -# Use ONECOM_KeepCnameProxy to keep the CNAME DNS record -# export ONECOM_KeepCnameProxy="1" + # # export ONECOM_User="username" # export ONECOM_Password="password" -# -# Usage: -# acme.sh --issue --dns dns_one -d example.com -# -# only single domain supported atm + dns_one_add() { fulldomain=$1 @@ -36,26 +24,10 @@ dns_one_add() { subdomain="${_sub_domain}" maindomain=${_domain} - useProxy=0 - if [ "${_sub_domain}" = "_acme-challenge" ]; then - subdomain="proxy${_sub_domain}" - useProxy=1 - fi _debug subdomain "$subdomain" _debug maindomain "$maindomain" - if [ $useProxy -eq 1 ]; then - #Check if the CNAME exists - _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" - if [ -z "$id" ]; then - _info "$(__red "Add CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" - _dns_one_addrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" - - _info "Not valid yet, let's wait 1 hour to take effect." - _sleep 3600 - fi - fi #Check if the TXT exists _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" @@ -92,26 +64,8 @@ dns_one_rm() { subdomain="${_sub_domain}" maindomain=${_domain} - useProxy=0 - if [ "${_sub_domain}" = "_acme-challenge" ]; then - subdomain="proxy${_sub_domain}" - useProxy=1 - fi - _debug subdomain "$subdomain" _debug maindomain "$maindomain" - if [ $useProxy -eq 1 ]; then - if [ "$ONECOM_KeepCnameProxy" = "1" ]; then - _info "$(__red "Keeping CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" - else - #Check if the CNAME exists - _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" - if [ -n "$id" ]; then - _info "$(__red "Removing CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" - _dns_one_delrecord "$id" - fi - fi - fi #Check if the TXT exists _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" @@ -136,7 +90,7 @@ dns_one_rm() { # _domain=domain.com _get_root() { domain="$1" - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -163,8 +117,6 @@ _get_root() { _dns_one_login() { # get credentials - ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-$(_readaccountconf_mutable ONECOM_KeepCnameProxy)}" - ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-0}" ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then @@ -176,7 +128,6 @@ _dns_one_login() { fi #save the api key and email to the account conf file. - _saveaccountconf_mutable ONECOM_KeepCnameProxy "$ONECOM_KeepCnameProxy" _saveaccountconf_mutable ONECOM_User "$ONECOM_User" _saveaccountconf_mutable ONECOM_Password "$ONECOM_Password" From 1c58913eeb54911457f289c32ed52f52e2b82f53 Mon Sep 17 00:00:00 2001 From: Jasper Zonneveld Date: Fri, 26 Mar 2021 14:59:13 +0100 Subject: [PATCH 1342/2234] Add Aurora DNS API --- dnsapi/dns_aurora.sh | 171 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 dnsapi/dns_aurora.sh diff --git a/dnsapi/dns_aurora.sh b/dnsapi/dns_aurora.sh new file mode 100644 index 00000000..00f44739 --- /dev/null +++ b/dnsapi/dns_aurora.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env sh + +# +#AURORA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" +# +#AURORA_Secret="sdfsdfsdfljlbjkljlkjsdfoiwje" + +AURORA_Api="https://api.auroradns.eu" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_aurora_add() { + fulldomain=$1 + txtvalue=$2 + + AURORA_Key="${AURORA_Key:-$(_readaccountconf_mutable AURORA_Key)}" + AURORA_Secret="${AURORA_Secret:-$(_readaccountconf_mutable AURORA_Secret)}" + + if [ -z "$AURORA_Key" ] || [ -z "$AURORA_Secret" ]; then + AURORA_Key="" + AURORA_Secret="" + _err "You didn't specify an Aurora api key and secret yet." + _err "You can get yours from here https://cp.pcextreme.nl/auroradns/users." + return 1 + fi + + #save the api key and secret to the account conf file. + _saveaccountconf_mutable AURORA_Key "$AURORA_Key" + _saveaccountconf_mutable AURORA_Secret "$AURORA_Secret" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + if _aurora_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":300}"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + return 0 + elif _contains "$response" "RecordExistsError"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_aurora_rm() { + fulldomain=$1 + txtvalue=$2 + + AURORA_Key="${AURORA_Key:-$(_readaccountconf_mutable AURORA_Key)}" + AURORA_Secret="${AURORA_Secret:-$(_readaccountconf_mutable AURORA_Secret)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting records" + _aurora_rest GET "zones/${_domain_id}/records" + + if ! _contains "$response" "$txtvalue"; then + _info "Don't need to remove." + else + records=$(echo "$response" | _normalizeJson | tr -d "[]" | sed "s/},{/}|{/g" | tr "|" "\n") + if [ "$(echo "$records" | wc -l)" -le 2 ]; then + _err "Can not parse records." + return 1 + fi + record_id=$(echo "$records" | grep "\"type\": *\"TXT\"" | grep "\"name\": *\"$_sub_domain\"" | grep "\"content\": *\"$txtvalue\"" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _aurora_rest DELETE "zones/$_domain_id/records/$record_id"; then + _err "Delete record error." + return 1 + fi + 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=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _aurora_rest GET "zones/$h"; then + return 1 + fi + + if _contains "$response" "\"name\": \"$h\""; then + _domain_id=$(echo "$response" | _normalizeJson | tr -d "{}" | tr "," "\n" | grep "\"id\": *\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") + _debug _domain_id "$_domain_id" + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_aurora_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + key_trimmed=$(echo "$AURORA_Key" | tr -d '"') + secret_trimmed=$(echo "$AURORA_Secret" | tr -d '"') + + timestamp=$(date -u +"%Y%m%dT%H%M%SZ") + signature=$(printf "%s/%s%s" "$m" "$ep" "$timestamp" | _hmac sha256 "$(printf "%s" "$secret_trimmed" | _hex_dump | tr -d " ")" | _base64) + authorization=$(printf "AuroraDNSv1 %s" "$(printf "%s:%s" "$key_trimmed" "$signature" | _base64)") + + export _H1="Content-Type: application/json; charset=UTF-8" + export _H2="X-AuroraDNS-Date: $timestamp" + export _H3="Authorization: $authorization" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$AURORA_Api/$ep" "" "$m")" + else + response="$(_get "$AURORA_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From f3682f0e8e30899dab1fb3fbbf6b477f4a798c0d Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 17 Apr 2021 22:09:59 +0800 Subject: [PATCH 1343/2234] fix format --- dnsapi/dns_one.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 0a4b2a14..1565b767 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -5,7 +5,6 @@ # export ONECOM_User="username" # export ONECOM_Password="password" - dns_one_add() { fulldomain=$1 txtvalue=$2 @@ -24,11 +23,9 @@ dns_one_add() { subdomain="${_sub_domain}" maindomain=${_domain} - _debug subdomain "$subdomain" _debug maindomain "$maindomain" - #Check if the TXT exists _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" if [ -n "$id" ]; then From eb0c629fad119604d0944719ca2bfc5e70dbc97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eike-Christian=20M=C3=BCller?= Date: Thu, 29 Apr 2021 12:53:13 +0200 Subject: [PATCH 1344/2234] more simple mail.sh fix Reverted the original patch and changed it to the obvious simple solution provided by @Neilpang. --- notify/mail.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index 2be93cd8..2cbddb63 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -78,13 +78,8 @@ mail_send() { _mail_bin() { _MAIL_BIN="" - _MAIL_BINS="sendmail ssmtp mutt mail msmtp" - if [ -n "$MAIL_BIN" ]; then - _MAIL_BINS="$MAIL_BIN $_MAIL_BINS" - fi - - for b in $_MAIL_BINS; do + for b in $MAIL_BIN sendmail ssmtp mutt mail msmtp; do if _exists "$b"; then _MAIL_BIN="$b" break From 81b2d0732f6a8db79f7059c5fb0dccdf02783387 Mon Sep 17 00:00:00 2001 From: Jeff Goeke-Smith Date: Thu, 29 Apr 2021 16:46:32 -0400 Subject: [PATCH 1345/2234] arguments passed to printf are more generic On systems that /bin/sh is served by shells other than bash, or shells that don't implement the same syntax as the bash printf builtin, printf -- fails to produce the output necessary for standalone operation. The test case for this was SmartOS, which uses ksh93 as its /bin/sh. This change uses the more generic method of passing a format parameter of a single string, and then the argument to replace it with. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 8d422719..b408ed30 100755 --- a/acme.sh +++ b/acme.sh @@ -2357,7 +2357,7 @@ _startserver() { echo 'HTTP/1.0 200 OK'; \ echo 'Content-Length\: $_content_len'; \ echo ''; \ -printf -- '$content';" & +printf '%s' '$content';" & serverproc="$!" } From 91d37c78750d382d0edfec6f36e6c49bb834159c Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 1 May 2021 22:32:44 +0800 Subject: [PATCH 1346/2234] fix compatibility issue --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index b408ed30..2ec8ba57 100755 --- a/acme.sh +++ b/acme.sh @@ -2038,7 +2038,7 @@ _send_signed_request() { if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type" >/dev/null; then _headers="$(cat "$HTTP_HEADER")" _debug2 _headers "$_headers" - _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" + _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2 | cut -d , -f 1)" fi fi if [ -z "$_CACHED_NONCE" ]; then @@ -2118,7 +2118,7 @@ _send_signed_request() { fi _debug2 response "$response" - _CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" + _CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2 | cut -d , -f 1)" if ! _startswith "$code" "2"; then _body="$response" @@ -4720,7 +4720,7 @@ $_authorizations_map" _debug2 response "$response" status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"') - if [ "$status" = "valid" ]; then + if _contains "$status" "valid"; then _info "$(__green Success)" _stopserver "$serverproc" serverproc="" From f855862ade83a0fc61f409c21397202f7f781c63 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 2 May 2021 22:20:04 +0800 Subject: [PATCH 1347/2234] upgrade freebsd --- .github/workflows/DNS.yml | 2 +- .github/workflows/LetsEncrypt.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 5ff1f8ab..f8e501ed 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -184,7 +184,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.3 + - uses: vmactions/freebsd-vm@v0.1.4 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 7193d88d..ba9a5317 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -111,7 +111,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.3 + - uses: vmactions/freebsd-vm@v0.1.4 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl From 1a4a180e8cf0825a34a4df4810b43cc5990e47a3 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 2 May 2021 13:37:59 -0600 Subject: [PATCH 1348/2234] FIX: Synology sets "default" on wrong certificate For some DSM installs, it appears that setting the "default" flag to the string "false" actually sets it to true. This causes Synology to set the last updated certificate to be the default certificate. Using an empty string appears to still be accepted as a false-y value for DSMs where this isn't happening and corrects the behavior in the cases that it was. Credit to @Run-King for identifying the fix and @buxm for reporting. --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 35d33209..25d43efb 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -121,7 +121,7 @@ synology_dsm_deploy() { # we've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate" - default=false + default="" if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then default=true fi From 25a8240d12eb8884076242fb8adc4aa7f7bbaa84 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 3 May 2021 15:52:56 +0800 Subject: [PATCH 1349/2234] fix https://github.com/acmesh-official/acme.sh/issues/3421 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 2ec8ba57..4955a5d4 100755 --- a/acme.sh +++ b/acme.sh @@ -2266,7 +2266,7 @@ _getdeployconf() { return 0 # do nothing fi _saved=$(_readdomainconf "SAVED_$_rac_key") - eval "export $_rac_key=\"$_saved\"" + eval "export $_rac_key=\"\$_saved\"" } #_saveaccountconf key value base64encode From e65144a1053fa4a6a21d3a61f8be37202211d061 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 3 May 2021 16:35:42 +0800 Subject: [PATCH 1350/2234] fix https://github.com/acmesh-official/acme.sh/issues/3487 suppor Ali doh and dnspod doh. --- acme.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 4955a5d4..efed674b 100755 --- a/acme.sh +++ b/acme.sh @@ -102,6 +102,8 @@ DEBUG_LEVEL_NONE=0 DOH_CLOUDFLARE=1 DOH_GOOGLE=2 +DOH_ALI=3 +DOH_DP=4 HIDDEN_VALUE="[hidden](please add '--output-insecure' to see this value)" @@ -3916,7 +3918,15 @@ _ns_purge_cf() { #checks if cf server is available _ns_is_available_cf() { - if _get "https://cloudflare-dns.com" >/dev/null 2>&1; then + if _get "https://cloudflare-dns.com" "" 1 >/dev/null 2>&1; then + return 0 + else + return 1 + fi +} + +_ns_is_available_google() { + if _get "https://dns.google" "" 1 >/dev/null 2>&1; then return 0 else return 1 @@ -3931,6 +3941,38 @@ _ns_lookup_google() { _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type" } +_ns_is_available_ali() { + if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then + return 0 + else + return 1 + fi +} + +#domain, type +_ns_lookup_ali() { + _cf_ld="$1" + _cf_ld_type="$2" + _cf_ep="https://dns.alidns.com/resolve" + _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type" +} + +_ns_is_available_dp() { + if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then + return 0 + else + return 1 + fi +} + +#dnspod +_ns_lookup_dp() { + _cf_ld="$1" + _cf_ld_type="$2" + _cf_ep="https://doh.pub/dns-query" + _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type" +} + #domain, type _ns_lookup() { if [ -z "$DOH_USE" ]; then @@ -3938,16 +3980,28 @@ _ns_lookup() { if _ns_is_available_cf; then _debug "Use cloudflare doh server" export DOH_USE=$DOH_CLOUDFLARE - else + elif _ns_is_available_google; then _debug "Use google doh server" export DOH_USE=$DOH_GOOGLE + elif _ns_is_available_ali; then + _debug "Use aliyun doh server" + export DOH_USE=$DOH_ALI + else _ns_is_available_dp; + _debug "Use dns pod doh server" + export DOH_USE=$DOH_DP fi fi if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then _ns_lookup_cf "$@" - else + elif [ "$DOH_USE" = "$DOH_GOOGLE" ]; then _ns_lookup_google "$@" + elif [ "$DOH_USE" = "$DOH_ALI" ]; then + _ns_lookup_ali "$@" + elif [ "$DOH_USE" = "$DOH_DP" ]; then + _ns_lookup_dp "$@" + else + _err "Unknown doh provider: DOH_USE=$DOH_USE" fi } @@ -3972,7 +4026,7 @@ __purge_txt() { if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then _ns_purge_cf "$_p_txtdomain" "TXT" else - _debug "no purge api for google dns api, just sleep 5 secs" + _debug "no purge api for this doh api, just sleep 5 secs" _sleep 5 fi From e0c32ce7004cfe842bda3bf631cbcf92f37651b0 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 3 May 2021 16:42:09 +0800 Subject: [PATCH 1351/2234] minor --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index efed674b..d7ec50b4 100755 --- a/acme.sh +++ b/acme.sh @@ -3986,9 +3986,11 @@ _ns_lookup() { elif _ns_is_available_ali; then _debug "Use aliyun doh server" export DOH_USE=$DOH_ALI - else _ns_is_available_dp; + elif _ns_is_available_dp; _debug "Use dns pod doh server" export DOH_USE=$DOH_DP + else + _err "No doh" fi fi From 0a4ef171351db5eb7f02341e231801e80026d33e Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 3 May 2021 17:11:02 +0800 Subject: [PATCH 1352/2234] fix nginx relative path issue: https://github.com/acmesh-official/acme.sh/issues/1743 https://github.com/acmesh-official/acme.sh/issues/1914 --- acme.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/acme.sh b/acme.sh index d7ec50b4..36e33c7b 100755 --- a/acme.sh +++ b/acme.sh @@ -3098,6 +3098,11 @@ _checkConf() { _debug "Try include files" for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do _debug "check included $included" + if !_startswith "$included" "/" && _exists dirname; then + _relpath="$(dirname "$_c_file")" + _debug "_relpath" "$_relpath" + included="$_relpath/included" + fi if _checkConf "$1" "$included"; then return 0 fi From 290beb90a74ff617d9fdf006beb287fb9450d6e5 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 3 May 2021 17:14:54 +0800 Subject: [PATCH 1353/2234] minor --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 36e33c7b..0ea93cf7 100755 --- a/acme.sh +++ b/acme.sh @@ -3991,7 +3991,7 @@ _ns_lookup() { elif _ns_is_available_ali; then _debug "Use aliyun doh server" export DOH_USE=$DOH_ALI - elif _ns_is_available_dp; + elif _ns_is_available_dp; then _debug "Use dns pod doh server" export DOH_USE=$DOH_DP else From 0881cf13799e6d2ee8b1d8a969feac8d634e2c85 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 4 May 2021 13:32:59 +0800 Subject: [PATCH 1354/2234] start 2.9.0 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 0ea93cf7..9967e541 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.9 +VER=2.9.0 PROJECT_NAME="acme.sh" From c127903127077ac4ed515a0ed28cfac6384e88f4 Mon Sep 17 00:00:00 2001 From: Benoit Garret Date: Tue, 27 Apr 2021 16:03:40 +0200 Subject: [PATCH 1355/2234] Add Consul deploy hook --- deploy/consul.sh | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 deploy/consul.sh diff --git a/deploy/consul.sh b/deploy/consul.sh new file mode 100644 index 00000000..97aad380 --- /dev/null +++ b/deploy/consul.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env sh + +# Here is a script to deploy cert to hashicorp consul using curl +# (https://www.consul.io/) +# +# it requires following environment variables: +# +# CONSUL_PREFIX - this contains the prefix path in consul +# CONSUL_HTTP_ADDR - consul requires this to find your consul server +# +# additionally, you need to ensure that CONSUL_HTTP_TOKEN is available +# to access the consul server + +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +consul_deploy() { + + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + # validate required env vars + _getdeployconf CONSUL_PREFIX + if [ -z "$CONSUL_PREFIX" ]; then + _err "CONSUL_PREFIX needs to be defined (contains prefix path in vault)" + return 1 + fi + _savedeployconf CONSUL_PREFIX "$CONSUL_PREFIX" + + _getdeployconf CONSUL_HTTP_ADDR + if [ -z "$CONSUL_HTTP_ADDR" ]; then + _err "CONSUL_HTTP_ADDR needs to be defined (contains consul connection address)" + return 1 + fi + _savedeployconf CONSUL_HTTP_ADDR "$CONSUL_HTTP_ADDR" + + CONSUL_CMD=$(command -v consul) + + # force CLI, but the binary does not exist => error + if [ -n "$USE_CLI" ] && [ -z "$CONSUL_CMD" ]; then + _err "Cannot find the consul binary!" + return 1 + fi + + # use the CLI first + if [ -n "$USE_CLI" ] || [ -n "$CONSUL_CMD" ]; then + _info "Found consul binary, deploying with CLI" + consul_deploy_cli "$CONSUL_CMD" "$CONSUL_PREFIX" + else + _info "Did not find consul binary, deploying with API" + consul_deploy_api "$CONSUL_HTTP_ADDR" "$CONSUL_PREFIX" "$CONSUL_HTTP_TOKEN" + fi +} + +consul_deploy_api() { + CONSUL_HTTP_ADDR="$1" + CONSUL_PREFIX="$2" + CONSUL_HTTP_TOKEN="$3" + + URL="$CONSUL_HTTP_ADDR/v1/kv/$CONSUL_PREFIX" + export _H1="X-Consul-Token: $CONSUL_HTTP_TOKEN" + + if [ -n "$FABIO" ]; then + _post "$(cat "$_cfullchain")" "$URL/${_cdomain}-cert.pem" '' "PUT" || return 1 + _post "$(cat "$_ckey")" "$URL/${_cdomain}-key.pem" '' "PUT" || return 1 + else + _post "$(cat "$_ccert")" "$URL/${_cdomain}/cert.pem" '' "PUT" || return 1 + _post "$(cat "$_ckey")" "$URL/${_cdomain}/cert.key" '' "PUT" || return 1 + _post "$(cat "$_cca")" "$URL/${_cdomain}/chain.pem" '' "PUT" || return 1 + _post "$(cat "$_cfullchain")" "$URL/${_cdomain}/fullchain.pem" '' "PUT" || return 1 + fi +} + +consul_deploy_cli() { + CONSUL_CMD="$1" + CONSUL_PREFIX="$2" + + if [ -n "$FABIO" ]; then + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}-cert.pem" @"$_cfullchain" || return 1 + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}-key.pem" @"$_ckey" || return 1 + else + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 + fi +} From c5557fc488674892cb839c7a75816869428e582e Mon Sep 17 00:00:00 2001 From: Will Browning <20662079+willbrowningme@users.noreply.github.com> Date: Thu, 6 May 2021 16:51:43 +0100 Subject: [PATCH 1356/2234] Remove DEDYN_NAME variable from dns_desec.sh --- dnsapi/dns_desec.sh | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index f64660a8..495a6780 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -20,21 +20,17 @@ dns_desec_add() { _debug txtvalue "$txtvalue" DEDYN_TOKEN="${DEDYN_TOKEN:-$(_readaccountconf_mutable DEDYN_TOKEN)}" - DEDYN_NAME="${DEDYN_NAME:-$(_readaccountconf_mutable DEDYN_NAME)}" - if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then + if [ -z "$DEDYN_TOKEN" ]; then DEDYN_TOKEN="" - DEDYN_NAME="" - _err "You did not specify DEDYN_TOKEN and DEDYN_NAME yet." + _err "You did not specify DEDYN_TOKEN yet." _err "Please create your key and try again." _err "e.g." _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" - _err "export DEDYN_NAME=foobar.dedyn.io" return 1 fi - #save the api token and name to the account conf file. + #save the api token to the account conf file. _saveaccountconf_mutable DEDYN_TOKEN "$DEDYN_TOKEN" - _saveaccountconf_mutable DEDYN_NAME "$DEDYN_NAME" _debug "First detect the root zone" if ! _get_root "$fulldomain" "$REST_API/"; then @@ -47,7 +43,7 @@ dns_desec_add() { # Get existing TXT record _debug "Getting txt records" txtvalues="\"\\\"$txtvalue\\\"\"" - _desec_rest GET "$REST_API/$DEDYN_NAME/rrsets/$_sub_domain/TXT/" + _desec_rest GET "$REST_API/$_domain/rrsets/$_sub_domain/TXT/" if [ "$_code" = "200" ]; then oldtxtvalues="$(echo "$response" | _egrep_o "\"records\":\\[\"\\S*\"\\]" | cut -d : -f 2 | tr -d "[]\\\\\"" | sed "s/,/ /g")" @@ -63,7 +59,7 @@ dns_desec_add() { _info "Adding record" body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":3600}]" - if _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body"; then + if _desec_rest PUT "$REST_API/$_domain/rrsets/" "$body"; then if _contains "$response" "$txtvalue"; then _info "Added, OK" return 0 @@ -87,16 +83,13 @@ dns_desec_rm() { _debug txtvalue "$txtvalue" DEDYN_TOKEN="${DEDYN_TOKEN:-$(_readaccountconf_mutable DEDYN_TOKEN)}" - DEDYN_NAME="${DEDYN_NAME:-$(_readaccountconf_mutable DEDYN_NAME)}" - if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then + if [ -z "$DEDYN_TOKEN" ]; then DEDYN_TOKEN="" - DEDYN_NAME="" - _err "You did not specify DEDYN_TOKEN and DEDYN_NAME yet." + _err "You did not specify DEDYN_TOKEN yet." _err "Please create your key and try again." _err "e.g." _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" - _err "export DEDYN_NAME=foobar.dedyn.io" return 1 fi @@ -112,7 +105,7 @@ dns_desec_rm() { # Get existing TXT record _debug "Getting txt records" txtvalues="" - _desec_rest GET "$REST_API/$DEDYN_NAME/rrsets/$_sub_domain/TXT/" + _desec_rest GET "$REST_API/$_domain/rrsets/$_sub_domain/TXT/" if [ "$_code" = "200" ]; then oldtxtvalues="$(echo "$response" | _egrep_o "\"records\":\\[\"\\S*\"\\]" | cut -d : -f 2 | tr -d "[]\\\\\"" | sed "s/,/ /g")" @@ -131,7 +124,7 @@ dns_desec_rm() { _info "Deleting record" body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":3600}]" - _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body" + _desec_rest PUT "$REST_API/$_domain/rrsets/" "$body" if [ "$_code" = "200" ]; then _info "Deleted, OK" return 0 From 07afc4953ada485b51d514fc65b80c00669f751b Mon Sep 17 00:00:00 2001 From: Benoit Garret Date: Fri, 7 May 2021 12:12:30 +0200 Subject: [PATCH 1357/2234] Fix the shfmt check --- deploy/consul.sh | 124 +++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/deploy/consul.sh b/deploy/consul.sh index 97aad380..f93fb452 100644 --- a/deploy/consul.sh +++ b/deploy/consul.sh @@ -18,81 +18,81 @@ #domain keyfile certfile cafile fullchain consul_deploy() { - _cdomain="$1" - _ckey="$2" - _ccert="$3" - _cca="$4" - _cfullchain="$5" + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" - _debug _cdomain "$_cdomain" - _debug _ckey "$_ckey" - _debug _ccert "$_ccert" - _debug _cca "$_cca" - _debug _cfullchain "$_cfullchain" + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" - # validate required env vars - _getdeployconf CONSUL_PREFIX - if [ -z "$CONSUL_PREFIX" ]; then - _err "CONSUL_PREFIX needs to be defined (contains prefix path in vault)" - return 1 - fi - _savedeployconf CONSUL_PREFIX "$CONSUL_PREFIX" + # validate required env vars + _getdeployconf CONSUL_PREFIX + if [ -z "$CONSUL_PREFIX" ]; then + _err "CONSUL_PREFIX needs to be defined (contains prefix path in vault)" + return 1 + fi + _savedeployconf CONSUL_PREFIX "$CONSUL_PREFIX" - _getdeployconf CONSUL_HTTP_ADDR - if [ -z "$CONSUL_HTTP_ADDR" ]; then - _err "CONSUL_HTTP_ADDR needs to be defined (contains consul connection address)" - return 1 - fi - _savedeployconf CONSUL_HTTP_ADDR "$CONSUL_HTTP_ADDR" + _getdeployconf CONSUL_HTTP_ADDR + if [ -z "$CONSUL_HTTP_ADDR" ]; then + _err "CONSUL_HTTP_ADDR needs to be defined (contains consul connection address)" + return 1 + fi + _savedeployconf CONSUL_HTTP_ADDR "$CONSUL_HTTP_ADDR" - CONSUL_CMD=$(command -v consul) + CONSUL_CMD=$(command -v consul) - # force CLI, but the binary does not exist => error - if [ -n "$USE_CLI" ] && [ -z "$CONSUL_CMD" ]; then - _err "Cannot find the consul binary!" - return 1 - fi + # force CLI, but the binary does not exist => error + if [ -n "$USE_CLI" ] && [ -z "$CONSUL_CMD" ]; then + _err "Cannot find the consul binary!" + return 1 + fi - # use the CLI first - if [ -n "$USE_CLI" ] || [ -n "$CONSUL_CMD" ]; then - _info "Found consul binary, deploying with CLI" - consul_deploy_cli "$CONSUL_CMD" "$CONSUL_PREFIX" - else - _info "Did not find consul binary, deploying with API" - consul_deploy_api "$CONSUL_HTTP_ADDR" "$CONSUL_PREFIX" "$CONSUL_HTTP_TOKEN" - fi + # use the CLI first + if [ -n "$USE_CLI" ] || [ -n "$CONSUL_CMD" ]; then + _info "Found consul binary, deploying with CLI" + consul_deploy_cli "$CONSUL_CMD" "$CONSUL_PREFIX" + else + _info "Did not find consul binary, deploying with API" + consul_deploy_api "$CONSUL_HTTP_ADDR" "$CONSUL_PREFIX" "$CONSUL_HTTP_TOKEN" + fi } consul_deploy_api() { - CONSUL_HTTP_ADDR="$1" - CONSUL_PREFIX="$2" - CONSUL_HTTP_TOKEN="$3" + CONSUL_HTTP_ADDR="$1" + CONSUL_PREFIX="$2" + CONSUL_HTTP_TOKEN="$3" - URL="$CONSUL_HTTP_ADDR/v1/kv/$CONSUL_PREFIX" - export _H1="X-Consul-Token: $CONSUL_HTTP_TOKEN" + URL="$CONSUL_HTTP_ADDR/v1/kv/$CONSUL_PREFIX" + export _H1="X-Consul-Token: $CONSUL_HTTP_TOKEN" - if [ -n "$FABIO" ]; then - _post "$(cat "$_cfullchain")" "$URL/${_cdomain}-cert.pem" '' "PUT" || return 1 - _post "$(cat "$_ckey")" "$URL/${_cdomain}-key.pem" '' "PUT" || return 1 - else - _post "$(cat "$_ccert")" "$URL/${_cdomain}/cert.pem" '' "PUT" || return 1 - _post "$(cat "$_ckey")" "$URL/${_cdomain}/cert.key" '' "PUT" || return 1 - _post "$(cat "$_cca")" "$URL/${_cdomain}/chain.pem" '' "PUT" || return 1 - _post "$(cat "$_cfullchain")" "$URL/${_cdomain}/fullchain.pem" '' "PUT" || return 1 - fi + if [ -n "$FABIO" ]; then + _post "$(cat "$_cfullchain")" "$URL/${_cdomain}-cert.pem" '' "PUT" || return 1 + _post "$(cat "$_ckey")" "$URL/${_cdomain}-key.pem" '' "PUT" || return 1 + else + _post "$(cat "$_ccert")" "$URL/${_cdomain}/cert.pem" '' "PUT" || return 1 + _post "$(cat "$_ckey")" "$URL/${_cdomain}/cert.key" '' "PUT" || return 1 + _post "$(cat "$_cca")" "$URL/${_cdomain}/chain.pem" '' "PUT" || return 1 + _post "$(cat "$_cfullchain")" "$URL/${_cdomain}/fullchain.pem" '' "PUT" || return 1 + fi } consul_deploy_cli() { - CONSUL_CMD="$1" - CONSUL_PREFIX="$2" + CONSUL_CMD="$1" + CONSUL_PREFIX="$2" - if [ -n "$FABIO" ]; then - $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}-cert.pem" @"$_cfullchain" || return 1 - $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}-key.pem" @"$_ckey" || return 1 - else - $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 - $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 - $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 - $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 - fi + if [ -n "$FABIO" ]; then + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}-cert.pem" @"$_cfullchain" || return 1 + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}-key.pem" @"$_ckey" || return 1 + else + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 + $CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 + fi } From aa59c46c4cffb89717388824e766e3c6cc1990a9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 7 May 2021 21:49:47 +0800 Subject: [PATCH 1358/2234] fix https://github.com/acmesh-official/acme.sh/issues/3504 --- acme.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 9967e541..1f7bbda7 100755 --- a/acme.sh +++ b/acme.sh @@ -3578,6 +3578,7 @@ _regAccount() { _err "Can not get EAB credentials from ZeroSSL." return 1 fi + _debug2 "$_eabresp" _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" if [ -z "$_eab_id" ]; then _err "Can not resolve _eab_id" @@ -4781,7 +4782,7 @@ $_authorizations_map" _debug2 response "$response" status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"') - if _contains "$status" "valid"; then + if _contains "$status" '"valid"'; then _info "$(__green Success)" _stopserver "$serverproc" serverproc="" From aede5c486be6e5f55882dcdbdecb7512200ee5be Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 7 May 2021 22:02:40 +0800 Subject: [PATCH 1359/2234] fix https://github.com/acmesh-official/acme.sh/issues/3504 check invalid status first. --- acme.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index 1f7bbda7..4fa83744 100755 --- a/acme.sh +++ b/acme.sh @@ -4782,15 +4782,8 @@ $_authorizations_map" _debug2 response "$response" status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"') - if _contains "$status" '"valid"'; then - _info "$(__green Success)" - _stopserver "$serverproc" - serverproc="" - _clearupwebbroot "$_currentRoot" "$removelevel" "$token" - break - fi - if [ "$status" = "invalid" ]; then + if _contains "$status" "invalid"; then error="$(echo "$response" | _egrep_o '"error":\{[^\}]*')" _debug2 error "$error" errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)" @@ -4812,6 +4805,14 @@ $_authorizations_map" return 1 fi + if _contains "$status" "valid"; then + _info "$(__green Success)" + _stopserver "$serverproc" + serverproc="" + _clearupwebbroot "$_currentRoot" "$removelevel" "$token" + break + fi + if [ "$status" = "pending" ]; then _info "Pending" elif [ "$status" = "processing" ]; then From 46180435cc5fa58b48554c9e4c918d6f15f7d207 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 8 May 2021 21:09:56 +0800 Subject: [PATCH 1360/2234] minor --- dnsapi/dns_porkbun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index 18da6b2f..90caec4a 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -78,7 +78,7 @@ dns_porkbun_rm() { if [ "$count" = "0" ]; then _info "Don't need to remove." else - record_id=$(echo "$response" | tr '{' '\n' | grep "$txtvalue" | cut -d, -f1 | cut -d: -f2 | tr -d \") + record_id=$(echo "$response" | tr '{' '\n' | grep -- "$txtvalue" | cut -d, -f1 | cut -d: -f2 | tr -d \") _debug "record_id" "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id to remove." From 5ab9ca1c0decec857de744854c52b818fc43a642 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Wed, 19 May 2021 13:21:34 -0600 Subject: [PATCH 1361/2234] Better fix for Synology DSM setting wrong default As noted by @buxm, previous fix didn't work for all versions of DSM 6. The better fix appears to be simply not outputting the "as_default" parameter unless we are doing something with the default certificate. --- deploy/synology_dsm.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 25d43efb..d7e8ace8 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -121,12 +121,6 @@ synology_dsm_deploy() { # we've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate" - default="" - if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then - default=true - fi - _debug2 default "$default" - _info "Generate form POST request" nl="\0015\0012" delim="--------------------------$(_utc_date | tr -d -- '-: ')" @@ -135,7 +129,12 @@ synology_dsm_deploy() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\0012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}${default}" + if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then + _debug2 default "this is the default certificate" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}true" + else + _debug2 default "this is NOT the default certificate" + fi content="$content${nl}--$delim--${nl}" content="$(printf "%b_" "$content")" content="${content%_}" # protect trailing \n From af3ea2d4fd463f938505cd39f51d9a3fc0bd802e Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 22 May 2021 23:45:50 +0800 Subject: [PATCH 1362/2234] remove ACME v1 support --- acme.sh | 780 ++++++++++++++++++++++---------------------------------- 1 file changed, 299 insertions(+), 481 deletions(-) diff --git a/acme.sh b/acme.sh index 4fa83744..10eef019 100755 --- a/acme.sh +++ b/acme.sh @@ -20,9 +20,6 @@ _SUB_FOLDER_DEPLOY="deploy" _SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY" -LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" -LETSENCRYPT_STAGING_CA_V1="https://acme-staging.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" @@ -2072,17 +2069,15 @@ _send_signed_request() { _sleep 2 continue fi - if [ "$ACME_VERSION" = "2" ]; then - if [ "$url" = "$ACME_NEW_ACCOUNT" ]; then - protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}' - elif [ "$url" = "$ACME_REVOKE_CERT" ] && [ "$keyfile" != "$ACCOUNT_KEY_PATH" ]; then - protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}' - else - protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"kid\": \"${ACCOUNT_URL}\""'}' - fi - else + + if [ "$url" = "$ACME_NEW_ACCOUNT" ]; then protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}' + elif [ "$url" = "$ACME_REVOKE_CERT" ] && [ "$keyfile" != "$ACCOUNT_KEY_PATH" ]; then + protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}' + else + protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"kid\": \"${ACCOUNT_URL}\""'}' fi + _debug3 protected "$protected" protected64="$(printf "%s" "$protected" | _base64 | _url_replace)" @@ -2549,61 +2544,25 @@ _initAPI() { response=$(echo "$response" | _json_decode) _debug2 "response" "$response" - ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'key-change" *: *"[^"]*"' | cut -d '"' -f 3) - if [ -z "$ACME_KEY_CHANGE" ]; then - ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'keyChange" *: *"[^"]*"' | cut -d '"' -f 3) - fi + ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'keyChange" *: *"[^"]*"' | cut -d '"' -f 3) export ACME_KEY_CHANGE - ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'new-authz" *: *"[^"]*"' | cut -d '"' -f 3) - if [ -z "$ACME_NEW_AUTHZ" ]; then - ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'newAuthz" *: *"[^"]*"' | cut -d '"' -f 3) - fi + ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'newAuthz" *: *"[^"]*"' | cut -d '"' -f 3) export ACME_NEW_AUTHZ - ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'new-cert" *: *"[^"]*"' | cut -d '"' -f 3) - ACME_NEW_ORDER_RES="new-cert" - if [ -z "$ACME_NEW_ORDER" ]; then - ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'new-order" *: *"[^"]*"' | cut -d '"' -f 3) - ACME_NEW_ORDER_RES="new-order" - if [ -z "$ACME_NEW_ORDER" ]; then - ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'newOrder" *: *"[^"]*"' | cut -d '"' -f 3) - fi - fi + ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'newOrder" *: *"[^"]*"' | cut -d '"' -f 3) export ACME_NEW_ORDER - export ACME_NEW_ORDER_RES - ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'new-reg" *: *"[^"]*"' | cut -d '"' -f 3) - ACME_NEW_ACCOUNT_RES="new-reg" - if [ -z "$ACME_NEW_ACCOUNT" ]; then - ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'new-account" *: *"[^"]*"' | cut -d '"' -f 3) - ACME_NEW_ACCOUNT_RES="new-account" - if [ -z "$ACME_NEW_ACCOUNT" ]; then - ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'newAccount" *: *"[^"]*"' | cut -d '"' -f 3) - if [ "$ACME_NEW_ACCOUNT" ]; then - export ACME_VERSION=2 - fi - fi - fi + ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'newAccount" *: *"[^"]*"' | cut -d '"' -f 3) export ACME_NEW_ACCOUNT - export ACME_NEW_ACCOUNT_RES - ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revoke-cert" *: *"[^"]*"' | cut -d '"' -f 3) - if [ -z "$ACME_REVOKE_CERT" ]; then - ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revokeCert" *: *"[^"]*"' | cut -d '"' -f 3) - fi + ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revokeCert" *: *"[^"]*"' | cut -d '"' -f 3) export ACME_REVOKE_CERT - ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'new-nonce" *: *"[^"]*"' | cut -d '"' -f 3) - if [ -z "$ACME_NEW_NONCE" ]; then - ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'newNonce" *: *"[^"]*"' | cut -d '"' -f 3) - fi + ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'newNonce" *: *"[^"]*"' | cut -d '"' -f 3) export ACME_NEW_NONCE - ACME_AGREEMENT=$(echo "$response" | _egrep_o 'terms-of-service" *: *"[^"]*"' | cut -d '"' -f 3) - if [ -z "$ACME_AGREEMENT" ]; then - ACME_AGREEMENT=$(echo "$response" | _egrep_o 'termsOfService" *: *"[^"]*"' | cut -d '"' -f 3) - fi + ACME_AGREEMENT=$(echo "$response" | _egrep_o 'termsOfService" *: *"[^"]*"' | cut -d '"' -f 3) export ACME_AGREEMENT _debug "ACME_KEY_CHANGE" "$ACME_KEY_CHANGE" @@ -2613,7 +2572,6 @@ _initAPI() { _debug "ACME_REVOKE_CERT" "$ACME_REVOKE_CERT" _debug "ACME_AGREEMENT" "$ACME_AGREEMENT" _debug "ACME_NEW_NONCE" "$ACME_NEW_NONCE" - _debug "ACME_VERSION" "$ACME_VERSION" fi } @@ -3563,69 +3521,62 @@ _regAccount() { if [ "$_email" ]; then _savecaconf "CA_EMAIL" "$_email" fi - if [ "$ACME_VERSION" = "2" ]; then - if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then - if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then - _info "No EAB credentials found for ZeroSSL, let's get one" - if [ -z "$_email" ]; then - _err "Please provide a email address for ZeroSSL account." - _err "See ZeroSSL usage: $_ZEROSSL_WIKI" - return 1 - fi - _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) - if [ "$?" != "0" ]; then - _debug2 "$_eabresp" - _err "Can not get EAB credentials from ZeroSSL." - return 1 - fi - _debug2 "$_eabresp" - _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" - if [ -z "$_eab_id" ]; then - _err "Can not resolve _eab_id" - return 1 - fi - _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" - if [ -z "$_eab_hmac_key" ]; then - _err "Can not resolve _eab_hmac_key" - return 1 - fi - _savecaconf CA_EAB_KEY_ID "$_eab_id" - _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" + + if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then + if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then + _info "No EAB credentials found for ZeroSSL, let's get one" + if [ -z "$_email" ]; then + _err "Please provide a email address for ZeroSSL account." + _err "See ZeroSSL usage: $_ZEROSSL_WIKI" + return 1 fi - fi - if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then - eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" - _debug3 eab_protected "$eab_protected" - - eab_protected64=$(printf "%s" "$eab_protected" | _base64 | _url_replace) - _debug3 eab_protected64 "$eab_protected64" - - eab_payload64=$(printf "%s" "$jwk" | _base64 | _url_replace) - _debug3 eab_payload64 "$eab_payload64" - - eab_sign_t="$eab_protected64.$eab_payload64" - _debug3 eab_sign_t "$eab_sign_t" - - key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" - _debug3 key_hex "$key_hex" - - eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) - _debug3 eab_signature "$eab_signature" - - externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" - _debug3 externalBinding "$externalBinding" - fi - if [ "$_email" ]; then - email_sg="\"contact\": [\"mailto:$_email\"], " - fi - regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" - else - _reg_res="$ACME_NEW_ACCOUNT_RES" - regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' - if [ "$_email" ]; then - regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$_email'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' + _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) + if [ "$?" != "0" ]; then + _debug2 "$_eabresp" + _err "Can not get EAB credentials from ZeroSSL." + return 1 + fi + _debug2 "$_eabresp" + _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_id" ]; then + _err "Can not resolve _eab_id" + return 1 + fi + _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_hmac_key" ]; then + _err "Can not resolve _eab_hmac_key" + return 1 + fi + _savecaconf CA_EAB_KEY_ID "$_eab_id" + _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" fi fi + if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then + eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" + _debug3 eab_protected "$eab_protected" + + eab_protected64=$(printf "%s" "$eab_protected" | _base64 | _url_replace) + _debug3 eab_protected64 "$eab_protected64" + + eab_payload64=$(printf "%s" "$jwk" | _base64 | _url_replace) + _debug3 eab_payload64 "$eab_payload64" + + eab_sign_t="$eab_protected64.$eab_payload64" + _debug3 eab_sign_t "$eab_sign_t" + + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + _debug3 key_hex "$key_hex" + + eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) + _debug3 eab_signature "$eab_signature" + + externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" + _debug3 externalBinding "$externalBinding" + fi + if [ "$_email" ]; then + email_sg="\"contact\": [\"mailto:$_email\"], " + fi + regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" _info "Registering account: $ACME_DIRECTORY" @@ -3710,20 +3661,13 @@ updateaccount() { _initAPI _email="$(_getAccountEmail)" - if [ "$ACME_VERSION" = "2" ]; then - if [ "$ACCOUNT_EMAIL" ]; then - updjson='{"contact": ["mailto:'$_email'"]}' - else - updjson='{"contact": []}' - fi + + if [ "$ACCOUNT_EMAIL" ]; then + updjson='{"contact": ["mailto:'$_email'"]}' else - # ACMEv1: Updates happen the same way a registration is done. - # https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-6.3 - _regAccount - return + updjson='{"contact": []}' fi - # this part handles ACMEv2 account updates. _send_signed_request "$_accUri" "$updjson" if [ "$code" = '200' ]; then @@ -3768,11 +3712,8 @@ deactivateaccount() { fi _initAPI - if [ "$ACME_VERSION" = "2" ]; then - _djson="{\"status\":\"deactivated\"}" - else - _djson="{\"resource\": \"reg\", \"status\":\"deactivated\"}" - fi + _djson="{\"status\":\"deactivated\"}" + if _send_signed_request "$_accUri" "$_djson" && _contains "$response" '"deactivated"'; then _info "Deactivate account success for $_accUri." _accid=$(echo "$response" | _egrep_o "\"id\" *: *[^,]*," | cut -d : -f 2 | tr -d ' ,') @@ -3877,11 +3818,9 @@ __trigger_validation() { _debug2 _t_key_authz "$_t_key_authz" _t_vtype="$3" _debug2 _t_vtype "$_t_vtype" - if [ "$ACME_VERSION" = "2" ]; then - _send_signed_request "$_t_url" "{}" - else - _send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"type\": \"$_t_vtype\", \"keyAuthorization\": \"$_t_key_authz\"}" - fi + + _send_signed_request "$_t_url" "{}" + } #endpoint domain type @@ -4297,74 +4236,72 @@ issue() { sep='#' dvsep=',' if [ -z "$vlist" ]; then - if [ "$ACME_VERSION" = "2" ]; then - #make new order request - _identifiers="{\"type\":\"dns\",\"value\":\"$(_idn "$_main_domain")\"}" - _w_index=1 - while true; do - d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")" - _w_index="$(_math "$_w_index" + 1)" - _debug d "$d" - if [ -z "$d" ]; then - break - fi - _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn "$d")\"}" - done - _debug2 _identifiers "$_identifiers" - if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then - _err "Create new order error." - _clearup - _on_issue_err "$_post_hook" - return 1 + #make new order request + _identifiers="{\"type\":\"dns\",\"value\":\"$(_idn "$_main_domain")\"}" + _w_index=1 + while true; do + d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")" + _w_index="$(_math "$_w_index" + 1)" + _debug d "$d" + if [ -z "$d" ]; then + break 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)" - _debug Le_OrderFinalize "$Le_OrderFinalize" - if [ -z "$Le_OrderFinalize" ]; then - _err "Create new order error. Le_OrderFinalize not found. $response" - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - - #for dns manual mode - _savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize" - - _authorizations_seg="$(echo "$response" | _json_decode | _egrep_o '"authorizations" *: *\[[^\[]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" - _debug2 _authorizations_seg "$_authorizations_seg" - if [ -z "$_authorizations_seg" ]; then - _err "_authorizations_seg not found." - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - - #domain and authz map - _authorizations_map="" - for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do - _debug2 "_authz_url" "$_authz_url" - if ! _send_signed_request "$_authz_url"; then - _err "get to authz error." - _err "_authorizations_seg" "$_authorizations_seg" - _err "_authz_url" "$_authz_url" - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - - response="$(echo "$response" | _normalizeJson)" - _debug2 response "$response" - _d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2 | tr -d ' "')" - if _contains "$response" "\"wildcard\" *: *true"; then - _d="*.$_d" - fi - _debug2 _d "$_d" - _authorizations_map="$_d,$response -$_authorizations_map" - done - _debug2 _authorizations_map "$_authorizations_map" + _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn "$d")\"}" + done + _debug2 _identifiers "$_identifiers" + if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; 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)" + _debug Le_OrderFinalize "$Le_OrderFinalize" + if [ -z "$Le_OrderFinalize" ]; then + _err "Create new order error. Le_OrderFinalize not found. $response" + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + + #for dns manual mode + _savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize" + + _authorizations_seg="$(echo "$response" | _json_decode | _egrep_o '"authorizations" *: *\[[^\[]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" + _debug2 _authorizations_seg "$_authorizations_seg" + if [ -z "$_authorizations_seg" ]; then + _err "_authorizations_seg not found." + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + + #domain and authz map + _authorizations_map="" + for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do + _debug2 "_authz_url" "$_authz_url" + if ! _send_signed_request "$_authz_url"; then + _err "get to authz error." + _err "_authorizations_seg" "$_authorizations_seg" + _err "_authz_url" "$_authz_url" + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + + response="$(echo "$response" | _normalizeJson)" + _debug2 response "$response" + _d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2 | tr -d ' "')" + if _contains "$response" "\"wildcard\" *: *true"; then + _d="*.$_d" + fi + _debug2 _d "$_d" + _authorizations_map="$_d,$response +$_authorizations_map" + done + _debug2 _authorizations_map "$_authorizations_map" _index=0 _currentRoot="" @@ -4395,33 +4332,25 @@ $_authorizations_map" vtype="$VTYPE_ALPN" fi - if [ "$ACME_VERSION" = "2" ]; then - _idn_d="$(_idn "$d")" - _candidates="$(echo "$_authorizations_map" | grep -i "^$_idn_d,")" - _debug2 _candidates "$_candidates" - if [ "$(echo "$_candidates" | wc -l)" -gt 1 ]; then - for _can in $_candidates; do - if _startswith "$(echo "$_can" | tr '.' '|')" "$(echo "$_idn_d" | tr '.' '|'),"; then - _candidates="$_can" - break - fi - done - fi - response="$(echo "$_candidates" | sed "s/$_idn_d,//")" - _debug2 "response" "$response" - if [ -z "$response" ]; then - _err "get to authz error." - _err "_authorizations_map" "$_authorizations_map" - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - else - if ! __get_domain_new_authz "$d"; then - _clearup - _on_issue_err "$_post_hook" - return 1 - fi + _idn_d="$(_idn "$d")" + _candidates="$(echo "$_authorizations_map" | grep -i "^$_idn_d,")" + _debug2 _candidates "$_candidates" + if [ "$(echo "$_candidates" | wc -l)" -gt 1 ]; then + for _can in $_candidates; do + if _startswith "$(echo "$_can" | tr '.' '|')" "$(echo "$_idn_d" | tr '.' '|'),"; then + _candidates="$_can" + break + fi + done + fi + response="$(echo "$_candidates" | sed "s/$_idn_d,//")" + _debug2 "response" "$response" + if [ -z "$response" ]; then + _err "get to authz error." + _err "_authorizations_map" "$_authorizations_map" + _clearup + _on_issue_err "$_post_hook" + return 1 fi if [ -z "$thumbprint" ]; then @@ -4462,11 +4391,9 @@ $_authorizations_map" _on_issue_err "$_post_hook" return 1 fi - if [ "$ACME_VERSION" = "2" ]; then - uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" - else - uri="$(echo "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)" - fi + + uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" + _debug uri "$uri" if [ -z "$uri" ]; then @@ -4764,11 +4691,9 @@ $_authorizations_map" _debug "sleep 2 secs to verify" sleep 2 _debug "checking" - if [ "$ACME_VERSION" = "2" ]; then - _send_signed_request "$uri" - else - response="$(_get "$uri")" - fi + + _send_signed_request "$uri" + if [ "$?" != "0" ]; then _err "$d:Verify error:$response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" @@ -4833,150 +4758,128 @@ $_authorizations_map" _info "Verify finished, start to sign." der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" - if [ "$ACME_VERSION" = "2" ]; then - _info "Lets finalize the order." - _info "Le_OrderFinalize" "$Le_OrderFinalize" - if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then - _err "Sign failed." - _on_issue_err "$_post_hook" - return 1 - fi - if [ "$code" != "200" ]; then - _err "Sign failed, finalize code is not 200." - _err "$response" - _on_issue_err "$_post_hook" - return 1 - fi - if [ -z "$Le_LinkOrder" ]; then - Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n \t" | cut -d ":" -f 2-)" - fi - _savedomainconf "Le_LinkOrder" "$Le_LinkOrder" + _info "Lets finalize the order." + _info "Le_OrderFinalize" "$Le_OrderFinalize" + if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then + _err "Sign failed." + _on_issue_err "$_post_hook" + return 1 + fi + if [ "$code" != "200" ]; then + _err "Sign failed, finalize code is not 200." + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + if [ -z "$Le_LinkOrder" ]; then + Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n \t" | cut -d ":" -f 2-)" + fi - _link_cert_retry=0 - _MAX_CERT_RETRY=30 - while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do - if _contains "$response" "\"status\":\"valid\""; then - _debug "Order status is valid." - Le_LinkCert="$(echo "$response" | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" - _debug Le_LinkCert "$Le_LinkCert" - if [ -z "$Le_LinkCert" ]; then - _err "Sign error, can not find Le_LinkCert" - _err "$response" - _on_issue_err "$_post_hook" - return 1 - fi - break - elif _contains "$response" "\"processing\""; then - _info "Order status is processing, lets sleep and retry." - _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') - _debug "_retryafter" "$_retryafter" - if [ "$_retryafter" ]; then - _info "Retry after: $_retryafter" - _sleep $_retryafter - else - _sleep 2 - fi + _savedomainconf "Le_LinkOrder" "$Le_LinkOrder" + + _link_cert_retry=0 + _MAX_CERT_RETRY=30 + while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do + if _contains "$response" "\"status\":\"valid\""; then + _debug "Order status is valid." + Le_LinkCert="$(echo "$response" | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" + _debug Le_LinkCert "$Le_LinkCert" + if [ -z "$Le_LinkCert" ]; then + _err "Sign error, can not find Le_LinkCert" + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + break + elif _contains "$response" "\"processing\""; then + _info "Order status is processing, lets sleep and retry." + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + _debug "_retryafter" "$_retryafter" + if [ "$_retryafter" ]; then + _info "Retry after: $_retryafter" + _sleep $_retryafter else - _err "Sign error, wrong status" - _err "$response" - _on_issue_err "$_post_hook" - return 1 + _sleep 2 fi - #the order is processing, so we are going to poll order status - if [ -z "$Le_LinkOrder" ]; then - _err "Sign error, can not get order link location header" - _err "responseHeaders" "$responseHeaders" - _on_issue_err "$_post_hook" - return 1 - fi - _info "Polling order status: $Le_LinkOrder" - if ! _send_signed_request "$Le_LinkOrder"; then - _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder." - _err "$response" - _on_issue_err "$_post_hook" - return 1 - fi - _link_cert_retry="$(_math $_link_cert_retry + 1)" - done - - if [ -z "$Le_LinkCert" ]; then - _err "Sign failed, can not get Le_LinkCert, retry time limit." + else + _err "Sign error, wrong status" _err "$response" _on_issue_err "$_post_hook" return 1 fi - _info "Downloading cert." - _info "Le_LinkCert" "$Le_LinkCert" - if ! _send_signed_request "$Le_LinkCert"; then - _err "Sign failed, can not download cert:$Le_LinkCert." + #the order is processing, so we are going to poll order status + if [ -z "$Le_LinkOrder" ]; then + _err "Sign error, can not get order link location header" + _err "responseHeaders" "$responseHeaders" + _on_issue_err "$_post_hook" + return 1 + fi + _info "Polling order status: $Le_LinkOrder" + if ! _send_signed_request "$Le_LinkOrder"; then + _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder." _err "$response" _on_issue_err "$_post_hook" return 1 fi + _link_cert_retry="$(_math $_link_cert_retry + 1)" + done - echo "$response" >"$CERT_PATH" - _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" + if [ -z "$Le_LinkCert" ]; then + _err "Sign failed, can not get Le_LinkCert, retry time limit." + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi + _info "Downloading cert." + _info "Le_LinkCert" "$Le_LinkCert" + if ! _send_signed_request "$Le_LinkCert"; then + _err "Sign failed, can not download cert:$Le_LinkCert." + _err "$response" + _on_issue_err "$_post_hook" + return 1 + fi - if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then - if [ "$DEBUG" ]; then - _debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" - fi - if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then - rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" - _debug2 "rels" "$rels" - for rel in $rels; do - _info "Try rel: $rel" - if ! _send_signed_request "$rel"; then - _err "Sign failed, can not download cert:$rel" - _err "$response" - continue - fi - _relcert="$CERT_PATH.alt" - _relfullchain="$CERT_FULLCHAIN_PATH.alt" - _relca="$CA_CERT_PATH.alt" - echo "$response" >"$_relcert" - _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" - if [ "$DEBUG" ]; then - _debug "rel chain issuers: " "$(_get_chain_issuers "$_relfullchain")" - fi - if _match_issuer "$_relfullchain" "$_preferred_chain"; then - _info "Matched issuer in: $rel" - cat $_relcert >"$CERT_PATH" - cat $_relfullchain >"$CERT_FULLCHAIN_PATH" - cat $_relca >"$CA_CERT_PATH" - rm -f "$_relcert" - rm -f "$_relfullchain" - rm -f "$_relca" - break - fi + echo "$response" >"$CERT_PATH" + _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" + + if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then + if [ "$DEBUG" ]; then + _debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" + fi + if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then + rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" + _debug2 "rels" "$rels" + for rel in $rels; do + _info "Try rel: $rel" + if ! _send_signed_request "$rel"; then + _err "Sign failed, can not download cert:$rel" + _err "$response" + continue + fi + _relcert="$CERT_PATH.alt" + _relfullchain="$CERT_FULLCHAIN_PATH.alt" + _relca="$CA_CERT_PATH.alt" + echo "$response" >"$_relcert" + _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" + if [ "$DEBUG" ]; then + _debug "rel chain issuers: " "$(_get_chain_issuers "$_relfullchain")" + fi + if _match_issuer "$_relfullchain" "$_preferred_chain"; then + _info "Matched issuer in: $rel" + cat $_relcert >"$CERT_PATH" + cat $_relfullchain >"$CERT_FULLCHAIN_PATH" + cat $_relca >"$CA_CERT_PATH" rm -f "$_relcert" rm -f "$_relfullchain" rm -f "$_relca" - done - fi + break + fi + rm -f "$_relcert" + rm -f "$_relfullchain" + rm -f "$_relca" + done fi - else - if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then - _err "Sign failed. $response" - _on_issue_err "$_post_hook" - return 1 - fi - _rcert="$response" - Le_LinkCert="$(grep -i '^Location.*$' "$HTTP_HEADER" | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)" - echo "$BEGIN_CERT" >"$CERT_PATH" - - #if ! _get "$Le_LinkCert" | _base64 "multiline" >> "$CERT_PATH" ; then - # _debug "Get cert failed. Let's try last response." - # printf -- "%s" "$_rcert" | _dbase64 "multiline" | _base64 "multiline" >> "$CERT_PATH" - #fi - - if ! printf -- "%s" "$_rcert" | _dbase64 "multiline" | _base64 "multiline" >>"$CERT_PATH"; then - _debug "Try cert link." - _get "$Le_LinkCert" | _base64 "multiline" >>"$CERT_PATH" - fi - - echo "$END_CERT" >>"$CERT_PATH" fi _debug "Le_LinkCert" "$Le_LinkCert" @@ -5005,53 +4908,6 @@ $_authorizations_map" fi fi - if [ "$ACME_VERSION" = "2" ]; then - _debug "v2 chain." - else - cp "$CERT_PATH" "$CERT_FULLCHAIN_PATH" - Le_LinkIssuer=$(grep -i '^Link' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2 | cut -d ';' -f 1 | tr -d '<>') - - if [ "$Le_LinkIssuer" ]; then - if ! _contains "$Le_LinkIssuer" ":"; then - _info "$(__red "Relative issuer link found.")" - Le_LinkIssuer="$_ACME_SERVER_HOST$Le_LinkIssuer" - fi - _debug Le_LinkIssuer "$Le_LinkIssuer" - _savedomainconf "Le_LinkIssuer" "$Le_LinkIssuer" - - _link_issuer_retry=0 - _MAX_ISSUER_RETRY=5 - while [ "$_link_issuer_retry" -lt "$_MAX_ISSUER_RETRY" ]; do - _debug _link_issuer_retry "$_link_issuer_retry" - if [ "$ACME_VERSION" = "2" ]; then - if _send_signed_request "$Le_LinkIssuer"; then - echo "$response" >"$CA_CERT_PATH" - break - fi - else - if _get "$Le_LinkIssuer" >"$CA_CERT_PATH.der"; then - echo "$BEGIN_CERT" >"$CA_CERT_PATH" - _base64 "multiline" <"$CA_CERT_PATH.der" >>"$CA_CERT_PATH" - echo "$END_CERT" >>"$CA_CERT_PATH" - if ! _checkcert "$CA_CERT_PATH"; then - _err "Can not get the ca cert." - break - fi - cat "$CA_CERT_PATH" >>"$CERT_FULLCHAIN_PATH" - rm -f "$CA_CERT_PATH.der" - break - fi - fi - _link_issuer_retry=$(_math $_link_issuer_retry + 1) - _sleep "$_link_issuer_retry" - done - if [ "$_link_issuer_retry" = "$_MAX_ISSUER_RETRY" ]; then - _err "Max retry for issuer ca cert is reached." - fi - else - _debug "No Le_LinkIssuer header found." - fi - fi [ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in $(__green " $CA_CERT_PATH ")" [ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green " $CERT_FULLCHAIN_PATH ")" @@ -5165,15 +5021,6 @@ renew() { . "$DOMAIN_CONF" _debug Le_API "$Le_API" - if [ "$Le_API" = "$LETSENCRYPT_CA_V1" ]; then - _cleardomainconf Le_API - Le_API="$DEFAULT_CA" - fi - if [ "$Le_API" = "$LETSENCRYPT_STAGING_CA_V1" ]; then - _cleardomainconf Le_API - Le_API="$DEFAULT_STAGING_CA" - fi - if [ "$Le_API" ]; then export ACME_DIRECTORY="$Le_API" #reload ca configs @@ -5388,9 +5235,6 @@ signcsr() { return 1 fi - if [ -z "$ACME_VERSION" ] && _contains "$_csrsubj,$_csrdomainlist" "*."; then - export ACME_VERSION=2 - fi _initpath "$_csrsubj" "$_csrkeylength" mkdir -p "$DOMAIN_PATH" @@ -5851,11 +5695,8 @@ revoke() { _initAPI - if [ "$ACME_VERSION" = "2" ]; then - data="{\"certificate\": \"$cert\",\"reason\":$_reason}" - else - data="{\"resource\": \"revoke-cert\", \"certificate\": \"$cert\"}" - fi + data="{\"certificate\": \"$cert\",\"reason\":$_reason}" + uri="${ACME_REVOKE_CERT}" if [ -f "$CERT_KEY_PATH" ]; then @@ -5926,49 +5767,34 @@ _deactivate() { _d_type="$2" _initpath - if [ "$ACME_VERSION" = "2" ]; then - _identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}" - if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then - _err "Can not get domain new order." - return 1 - fi - _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" - _debug2 _authorizations_seg "$_authorizations_seg" - if [ -z "$_authorizations_seg" ]; then - _err "_authorizations_seg not found." - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - - authzUri="$_authorizations_seg" - _debug2 "authzUri" "$authzUri" - if ! _send_signed_request "$authzUri"; then - _err "get to authz error." - _err "_authorizations_seg" "$_authorizations_seg" - _err "authzUri" "$authzUri" - _clearup - _on_issue_err "$_post_hook" - return 1 - fi - - response="$(echo "$response" | _normalizeJson)" - _debug2 response "$response" - _URL_NAME="url" - else - if ! __get_domain_new_authz "$_d_domain"; then - _err "Can not get domain new authz token." - return 1 - fi - - authzUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n")" - _debug "authzUri" "$authzUri" - if [ "$code" ] && [ ! "$code" = '201' ]; then - _err "new-authz error: $response" - return 1 - fi - _URL_NAME="uri" + _identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}" + if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then + _err "Can not get domain new order." + return 1 fi + _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" + _debug2 _authorizations_seg "$_authorizations_seg" + if [ -z "$_authorizations_seg" ]; then + _err "_authorizations_seg not found." + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + + authzUri="$_authorizations_seg" + _debug2 "authzUri" "$authzUri" + if ! _send_signed_request "$authzUri"; then + _err "get to authz error." + _err "_authorizations_seg" "$_authorizations_seg" + _err "authzUri" "$authzUri" + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + + response="$(echo "$response" | _normalizeJson)" + _debug2 response "$response" + _URL_NAME="url" entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")" if [ -z "$entries" ]; then @@ -6023,11 +5849,7 @@ _deactivate() { _info "Deactivate: $_vtype" - if [ "$ACME_VERSION" = "2" ]; then - _djson="{\"status\":\"deactivated\"}" - else - _djson="{\"resource\": \"authz\", \"status\":\"deactivated\"}" - fi + _djson="{\"status\":\"deactivated\"}" if _send_signed_request "$authzUri" "$_djson" && _contains "$response" '"deactivated"'; then _info "Deactivate: $_vtype success." @@ -7033,10 +6855,6 @@ _process() { return 1 fi - if _startswith "$_dvalue" "*."; then - _debug "Wildcard domain" - export ACME_VERSION=2 - fi if [ -z "$_domain" ]; then _domain="$_dvalue" else From 7710a33b6c04c467eb1bda07fe940abd4ecaedf2 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 22 May 2021 23:48:39 +0800 Subject: [PATCH 1363/2234] fix format --- acme.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/acme.sh b/acme.sh index 10eef019..02014657 100755 --- a/acme.sh +++ b/acme.sh @@ -4758,7 +4758,6 @@ $_authorizations_map" _info "Verify finished, start to sign." der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" - _info "Lets finalize the order." _info "Le_OrderFinalize" "$Le_OrderFinalize" if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then From bf9b33acec1969e9c35e3ba7ae81fbd7e765186b Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 23 May 2021 23:12:46 +0800 Subject: [PATCH 1364/2234] use cloudflare tunnel to test --- .github/workflows/LetsEncrypt.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index ba9a5317..715f9db1 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -109,11 +109,20 @@ jobs: TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 + - uses: vmactions/cf-tunnel@v0.0.1 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0.1.4 with: - envs: 'NGROK_TOKEN TEST_LOCAL' + envs: 'NGROK_TOKEN TEST_LOCAL TestingDomain' + nat: | + "8080": "80" prepare: pkg install -y socat curl usesh: true run: | @@ -127,13 +136,13 @@ jobs: TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 - - uses: vmactions/ngrok-tunnel@v0.0.1 - id: ngrok + - uses: vmactions/cf-tunnel@v0.0.1 + id: tunnel with: protocol: http port: 8080 - name: Set envs - run: echo "TestingDomain=${{steps.ngrok.outputs.server}}" >> $GITHUB_ENV + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0.0.3 From 40e2ebed958771212bca807d53ff6588c8b9b207 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 23 May 2021 23:16:04 +0800 Subject: [PATCH 1365/2234] remove ngrok token --- .github/workflows/LetsEncrypt.yml | 33 ++----------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 715f9db1..fd79125f 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -15,30 +15,9 @@ on: jobs: - CheckToken: - runs-on: ubuntu-latest - outputs: - hasToken: ${{ steps.step_one.outputs.hasToken }} - env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} - steps: - - name: Set the value - id: step_one - run: | - if [ "$NGROK_TOKEN" ] ; then - echo "::set-output name=hasToken::true" - else - echo "::set-output name=hasToken::false" - fi - - name: Check the value - run: echo ${{ steps.step_one.outputs.hasToken }} - Ubuntu: runs-on: ubuntu-latest - needs: CheckToken - if: "contains(needs.CheckToken.outputs.hasToken, 'true')" env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 @@ -51,9 +30,7 @@ jobs: MacOS: runs-on: macos-latest - needs: Ubuntu env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 @@ -66,11 +43,9 @@ jobs: Windows: runs-on: windows-latest - needs: MacOS env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 - #The 80 port is used by Windows server, we have to use a custom port, ngrok will also use this port. + #The 80 port is used by Windows server, we have to use a custom port, tunnel will also use this port. Le_HTTPPort: 8888 steps: - name: Set git to use LF @@ -103,9 +78,7 @@ jobs: FreeBSD: runs-on: macos-latest - needs: Windows env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 @@ -120,7 +93,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0.1.4 with: - envs: 'NGROK_TOKEN TEST_LOCAL TestingDomain' + envs: 'TEST_LOCAL TestingDomain' nat: | "8080": "80" prepare: pkg install -y socat curl @@ -130,9 +103,7 @@ jobs: Solaris: runs-on: macos-latest - needs: FreeBSD env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 From 7909273a21434b507d3330a9c34a0687b6799bff Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 25 May 2021 21:57:15 +0800 Subject: [PATCH 1366/2234] add debug info --- dnsapi/dns_ionos.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index aaf8580f..c2c431bb 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -149,14 +149,15 @@ _ionos_rest() { response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")" else export _H2="Accept: */*" - + export _H3= response="$(_get "$IONOS_API$route")" fi if [ "$?" != "0" ]; then - _err "Error $route" + _err "Error $route: $response" return 1 fi + _debug2 "response" "$response" return 0 } From 74a4a788b142d9febe351da61a86636542aba2f9 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Wed, 26 May 2021 15:07:23 -0600 Subject: [PATCH 1367/2234] Make certificate descriptions sed safe This escapes special characters used in POSIX sed to prevent mismatches. e.g. `SYNO_Certficiate=*.example.com` would not match a description of "*.example.com" and would look to match any number of double quotes (the last character in the sed regex prior to certificate description), followed by any single character, followed by "example", followed by any character, followed by "com". After this change, it will properly match `*.example.com` and not `""zexamplefcom`. Additionally we now store the certificate description as base64 encoded to prevent issues with single quotes. Tested on DSM 7.0-41222 (VDSM) and DSM 6.2.4-25556 (DS1515+). --- deploy/synology_dsm.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index d7e8ace8..649a48da 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -66,6 +66,11 @@ synology_dsm_deploy() { _getdeployconf SYNO_Certificate _debug SYNO_Certificate "${SYNO_Certificate:-}" + if printf "%s" "$SYNO_Certificate" | grep '\\'; then + _err "Do not use a backslash (\) in your certificate description" + return 1 + fi + _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" @@ -110,7 +115,9 @@ synology_dsm_deploy() { _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") _debug3 response "$response" - id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") + escaped_certificate="$(printf "%s" "$SYNO_Certificate" | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g')" + _debug escaped_certificate "$escaped_certificate" + id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then @@ -119,7 +126,7 @@ synology_dsm_deploy() { fi # we've verified this certificate description is a thing, so save it - _savedeployconf SYNO_Certificate "$SYNO_Certificate" + _savedeployconf SYNO_Certificate "$SYNO_Certificate" "base64" _info "Generate form POST request" nl="\0015\0012" @@ -129,7 +136,7 @@ synology_dsm_deploy() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\0012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}" - if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then + if echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then _debug2 default "this is the default certificate" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}true" else From dcb51683c5204feda587c2944baaa50c8bf30632 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Wed, 26 May 2021 15:24:50 -0600 Subject: [PATCH 1368/2234] shellcheck cleanup shellcheck sees '\\' as trying to escape the trailing quote (see koalaman/shellcheck#1548 ). --- deploy/synology_dsm.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 649a48da..5a70c74e 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -66,6 +66,7 @@ synology_dsm_deploy() { _getdeployconf SYNO_Certificate _debug SYNO_Certificate "${SYNO_Certificate:-}" + # shellcheck disable=SC1003 # We are not trying to escape a single quote if printf "%s" "$SYNO_Certificate" | grep '\\'; then _err "Do not use a backslash (\) in your certificate description" return 1 From 7aa4b8247cf2aae0253977206b2d9a739f1bb4db Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 May 2021 15:17:11 +0800 Subject: [PATCH 1369/2234] upgrade cf-tunnel --- .github/workflows/LetsEncrypt.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index fd79125f..bdc9072e 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -82,7 +82,7 @@ jobs: TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.1 + - uses: vmactions/cf-tunnel@v0.0.2 id: tunnel with: protocol: http @@ -107,7 +107,7 @@ jobs: TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.1 + - uses: vmactions/cf-tunnel@v0.0.2 id: tunnel with: protocol: http From 1e5e3353f392f0bf9535d04fa55475a3aeb98bf7 Mon Sep 17 00:00:00 2001 From: Roman Zabaluev Date: Sun, 30 May 2021 18:17:39 +0300 Subject: [PATCH 1370/2234] Fix porkbun issues See gh-3450 --- dnsapi/dns_porkbun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index 90caec4a..ad4455b6 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -110,8 +110,8 @@ _get_root() { if _porkbun_rest POST "dns/retrieve/$h"; then if _contains "$response" "\"status\":\"SUCCESS\""; then - _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" _domain=$h + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" return 0 else _debug "Go to next level of $_domain" From 3891a52aeb28329dc5f8c8dd3f582489ed49609f Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Mon, 31 May 2021 15:12:11 -0400 Subject: [PATCH 1371/2234] change "$url" -> $url so the value of $url gets passed by reference, and the string "$url" does not erroneously get passed as a variable into _post() --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index d720c1c5..d7e558a1 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -145,7 +145,7 @@ _1984hosting_login() { password=$(printf '%s' "$One984HOSTING_Password" | _url_encode) url="https://management.1984hosting.com/accounts/checkuserauth/" - response="$(_post "username=$username&password=$password&otpkey=" "$url")" + response="$(_post "username=$username&password=$password&otpkey=" $url)" response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" From 5f9daa66408c751e76ba2b66366e3dc3e2e49ac1 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Jun 2021 21:23:00 +0800 Subject: [PATCH 1372/2234] check initAPI error --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 02014657..86ed4b43 100755 --- a/acme.sh +++ b/acme.sh @@ -4132,7 +4132,9 @@ issue() { _debug "Using ACME_DIRECTORY: $ACME_DIRECTORY" - _initAPI + if ! _initAPI; then + return 1 + fi if [ -f "$DOMAIN_CONF" ]; then Le_NextRenewTime=$(_readdomainconf Le_NextRenewTime) From f627a028869491be5f0f18704669b73121849a4b Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Jun 2021 21:24:37 +0800 Subject: [PATCH 1373/2234] add error message --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 86ed4b43..47eb5a9a 100755 --- a/acme.sh +++ b/acme.sh @@ -2538,7 +2538,7 @@ _initAPI() { response=$(_get "$_api_server") if [ "$?" != "0" ]; then _debug2 "response" "$response" - _err "Can not init api." + _err "Can not init api for: $_api_server." return 1 fi response=$(echo "$response" | _json_decode) From c2273d2c8e274201a7ccc11fd5ee27a0750d60b9 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Jun 2021 22:15:41 +0800 Subject: [PATCH 1374/2234] add debug info --- dnsapi/dns_1984hosting.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index d7e558a1..fee59127 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -194,7 +194,7 @@ _check_cookie() { # _domain=domain.com _get_root() { domain="$1" - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -220,6 +220,7 @@ _get_root() { _authget() { export _H1="Cookie: $One984HOSTING_COOKIE" _response=$(_get "$1") + _debug2 _response "$_response" } # truncate huge HTML response From d154118600bd1cf061a7afd233f2639bffbf4830 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Jun 2021 22:21:17 +0800 Subject: [PATCH 1375/2234] fix bug --- dnsapi/dns_1984hosting.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index fee59127..f371f2c1 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -177,7 +177,6 @@ _check_cookie() { fi _authget "https://management.1984hosting.com/accounts/loginstatus/" - response="$(echo "$_response" | _normalizeJson)" if _contains "$response" '"ok": true'; then _debug "Cached cookie still valid" return 0 @@ -205,7 +204,7 @@ _get_root() { fi _authget "https://management.1984hosting.com/domains/soacheck/?zone=$h&nameserver=ns0.1984.is." - if _contains "$_response" "serial"; then + if _contains "$_response" "serial" && ! _contains "$_response" 'null}'; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" return 0 @@ -219,7 +218,7 @@ _get_root() { # add extra headers to request _authget() { export _H1="Cookie: $One984HOSTING_COOKIE" - _response=$(_get "$1") + _response=$(_get "$1" | _normalizeJson) _debug2 _response "$_response" } From e353f66eaaec0f34f3ff3e993c5fd8f353dab9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Parunakian?= Date: Wed, 2 Jun 2021 16:06:08 +0200 Subject: [PATCH 1376/2234] Fix typo --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 47eb5a9a..01c889af 100755 --- a/acme.sh +++ b/acme.sh @@ -3056,7 +3056,7 @@ _checkConf() { _debug "Try include files" for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do _debug "check included $included" - if !_startswith "$included" "/" && _exists dirname; then + if ! _startswith "$included" "/" && _exists dirname; then _relpath="$(dirname "$_c_file")" _debug "_relpath" "$_relpath" included="$_relpath/included" From fd6a59202d13d11e49c48edeca11d22ad056f9a2 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 2 Jun 2021 23:06:12 +0800 Subject: [PATCH 1377/2234] start 3.0.0 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 47eb5a9a..c2bc7e23 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.9.0 +VER=3.0.0 PROJECT_NAME="acme.sh" From 6f88c81616f9d2ca81945564b51a3090d7b454b1 Mon Sep 17 00:00:00 2001 From: Avi Miller Date: Fri, 4 Jun 2021 19:20:23 +1000 Subject: [PATCH 1378/2234] Add DNS API plugin for Oracle Cloud Infrastructure DNS Service This plugin is has noticeably more required fields than most other plugins due to the requirement that all requests to the OCI REST API must be cryptographically signed by the client using the draft standard proposed in draft-cavage-http-signatures-08[1]. The OCI specific implementation details of the draft standard are documented in the Developer Guide[2]. NOTE: there is maximum allowed clock skew of five minutes between the client and the API endpoint. Requests will be denied if the skew is greater. This PR also includes a minor tweak to the Solaris job in the DNS workflow so that it uses the pre-installed GNU tools, curl and OpenSSL 1.1.1. Without these changes, the signature generation function does not work on Solaris. [1]: https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-08 [2]: https://docs.oracle.com/en-us/iaas/Content/API/Concepts/signingrequests.htm#five Signed-off-by: Avi Miller --- .github/workflows/DNS.yml | 10 +- dnsapi/dns_oci.sh | 246 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+), 5 deletions(-) create mode 100644 dnsapi/dns_oci.sh diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index f8e501ed..b00ef263 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -59,7 +59,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Set env file run: | - cd ../acmetest + cd ../acmetest if [ "${{ secrets.TokenName1}}" ] ; then echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> env.list fi @@ -75,7 +75,7 @@ jobs: if [ "${{ secrets.TokenName5}}" ] ; then echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list fi - echo "TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_NO_WILDCARD" >> env.list echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall @@ -226,8 +226,10 @@ jobs: - uses: vmactions/solaris-vm@v0.0.3 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' - prepare: pkgutil -y -i socat curl + prepare: pkgutil -y -i socat run: | + pkg set-mediator -v -I default@1.1 openssl + export PATH=/usr/gnu/bin:$PATH if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} fi @@ -245,5 +247,3 @@ jobs: fi cd ../acmetest ./letest.sh - - diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh new file mode 100644 index 00000000..2843a8ca --- /dev/null +++ b/dnsapi/dns_oci.sh @@ -0,0 +1,246 @@ +#!/usr/bin/env sh +# +# Acme.sh DNS API plugin for Oracle Cloud Infrastructure +# Copyright (c) 2021, Oracle and/or its affiliates +# +# Required environment variables: +# - OCI_TENANCY : OCID of tenancy that contains the target DNS zone +# - OCI_USER : OCID of user with permission to add/remove records from zones +# - OCI_FINGERPRINT: fingerprint of the public key for the user +# - OCI_PRIVATE_KEY: Path to private API signing key file in PEM format +# +# Optional environment variables: +# - OCI_KEY_PASSPHRASE: if the private key above s encrypted, the passphrase is required +# - OCI_REGION: Your home region will probably response the fastest +# + +dns_oci_add() { + _fqdn="$1" + _rdata="$2" + + if _oci_config; then + + if ! _get_zone "$_fqdn"; then + _err "Error: DNS Zone not found for $_fqdn." + return 1 + fi + + if [ "$_sub_domain" ] && [ "$_domain" ]; then + _add_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"ttl\": 30,\"operation\":\"ADD\"}]}" + response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_add_record_body") + if [ "$response" ]; then + _info "Success: added TXT record for ${_sub_domain}.${_domain}." + else + _err "Error: failed to add TXT record for ${_sub_domain}.${_domain}." + return 1 + fi + fi + + else + return 1 + fi + +} + +dns_oci_rm() { + _fqdn="$1" + _rdata="$2" + + if _oci_config; then + + if ! _get_zone "$_fqdn"; then + _err "Error: DNS Zone not found for $_fqdn." + return 1 + fi + + if [ "$_sub_domain" ] && [ "$_domain" ]; then + _remove_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"operation\":\"REMOVE\"}]}" + response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_remove_record_body") + if [ "$response" ]; then + _info "Success: removed TXT record for ${_sub_domain}.${_domain}." + else + _err "Error: failed to remove TXT record for ${_sub_domain}.${_domain}." + return 1 + fi + fi + + else + return 1 + fi + +} + +#################### Private functions below ################################## +_oci_config() { + + OCI_TENANCY="${OCI_TENANCY:-$(_readaccountconf_mutable OCI_TENANCY)}" + OCI_USER="${OCI_USER:-$(_readaccountconf_mutable OCI_USER)}" + OCI_FINGERPRINT="${OCI_FINGERPRINT:-$(_readaccountconf_mutable OCI_FINGERPRINT)}" + OCI_PRIVATE_KEY="${OCI_PRIVATE_KEY:-$(_readaccountconf_mutable OCI_PRIVATE_KEY)}" + OCI_KEY_PASSPHRASE="${OCI_KEY_PASSPHRASE:-$(_readaccountconf_mutable OCI_KEY_PASSPHRASE)}" + OCI_REGION="${OCI_REGION:-$(_readaccountconf_mutable OCI_REGION)}" + + _not_set="" + _ret=0 + + if [ -f "$OCI_PRIVATE_KEY" ]; then + OCI_PRIVATE_KEY="$(openssl enc -a -A <"$OCI_PRIVATE_KEY")" + fi + + if [ -z "$OCI_TENANCY" ]; then + _not_set="OCI_TENANCY " + fi + + if [ -z "$OCI_USER" ]; then + _not_set="${_not_set}OCI_USER " + fi + + if [ -z "$OCI_FINGERPRINT" ]; then + _not_set="${_not_set}OCI_FINGERPRINT " + fi + + if [ -z "$OCI_PRIVATE_KEY" ]; then + _not_set="${_not_set}OCI_PRIVATE_KEY" + fi + + if [ "$_not_set" ]; then + _err "Fatal: environment variable(s): ${_not_set} not set." + _ret=1 + else + _saveaccountconf_mutable OCI_TENANCY "$OCI_TENANCY" + _saveaccountconf_mutable OCI_USER "$OCI_USER" + _saveaccountconf_mutable OCI_FINGERPRINT "$OCI_FINGERPRINT" + _saveaccountconf_mutable OCI_PRIVATE_KEY "$OCI_PRIVATE_KEY" + fi + + if [ "$OCI_PRIVATE_KEY" ] && [ "$(printf "%s\n" "$OCI_PRIVATE_KEY" | wc -l)" -eq 1 ]; then + OCI_PRIVATE_KEY="$(echo "$OCI_PRIVATE_KEY" | openssl enc -d -a -A)" + _secure_debug3 OCI_PRIVATE_KEY "$OCI_PRIVATE_KEY" + fi + + if [ "$OCI_KEY_PASSPHRASE" ]; then + _saveaccountconf_mutable OCI_KEY_PASSPHRASE "$OCI_KEY_PASSPHRASE" + fi + + if [ "$OCI_REGION" ]; then + _saveaccountconf_mutable OCI_REGION "$OCI_REGION" + else + OCI_REGION="us-ashburn-1" + fi + + return $_ret + +} + +# _get_zone(): retrieves the Zone name and OCID +# +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_ociid=ocid1.dns-zone.oc1.. +_get_zone() { + domain=$1 + i=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + # not valid + return 1 + fi + + _domain_id=$(_signed_request "GET" "/20180115/zones/$h" "" "id") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + return 0 + fi + + p=$i + i=$(_math "$i" + 1) + done + return 1 + +} + +_signed_request() { + + _sig_method="$1" + _sig_target="$2" + _sig_body="$3" + _return_field="$4" + + _sig_host="dns.$OCI_REGION.oraclecloud.com" + _sig_keyId="$OCI_TENANCY/$OCI_USER/$OCI_FINGERPRINT" + _sig_alg="rsa-sha256" + _sig_version="1" + _sig_now="$(LC_ALL=C \date -u "+%a, %d %h %Y %H:%M:%S GMT")" + + if [ "$OCI_KEY_PASSPHRASE" ]; then + export OCI_KEY_PASSPHRASE="$OCI_KEY_PASSPHRASE" + _sig_passinArg="-passin env:OCI_KEY_PASSPHRASE" + fi + + _request_method=$(printf %s "$_sig_method" | _lower_case) + _curl_method=$(printf %s "$_sig_method" | _upper_case) + + _request_target="(request-target): $_request_method $_sig_target" + _date_header="date: $_sig_now" + _host_header="host: $_sig_host" + + _string_to_sign="$_request_target\n$_date_header\n$_host_header" + _sig_headers="(request-target) date host" + + if [ "$_sig_body" ]; then + _secure_debug3 _sig_body "$_sig_body" + _sig_body_sha256="x-content-sha256: $(printf %s "$_sig_body" | openssl dgst -binary -sha256 | openssl enc -e -base64)" + _sig_body_type="content-type: application/json" + _sig_body_length="content-length: ${#_sig_body}" + _string_to_sign="$_string_to_sign\n$_sig_body_sha256\n$_sig_body_type\n$_sig_body_length" + _sig_headers="$_sig_headers x-content-sha256 content-type content-length" + fi + + _tmp_file=$(_mktemp) + if [ -f "$_tmp_file" ]; then + printf '%s' "$OCI_PRIVATE_KEY" >"$_tmp_file" + # Double quoting the file and passphrase breaks openssl + # shellcheck disable=SC2086 + _signature=$(printf '%b' "$_string_to_sign" | openssl dgst -sha256 -sign $_tmp_file $_sig_passinArg | openssl enc -e -base64 | tr -d '\r\n') + rm -f "$_tmp_file" + fi + + _signed_header="Authorization: Signature version=\"$_sig_version\",keyId=\"$_sig_keyId\",algorithm=\"$_sig_alg\",headers=\"$_sig_headers\",signature=\"$_signature\"" + _secure_debug3 _signed_header "$_signed_header" + + if [ "$_curl_method" = "GET" ]; then + export _H1="$_date_header" + export _H2="$_signed_header" + _response="$(_get "https://${_sig_host}${_sig_target}")" + elif [ "$_curl_method" = "PATCH" ]; then + export _H1="$_date_header" + export _H2="$_sig_body_sha256" + export _H3="$_sig_body_type" + export _H4="$_sig_body_length" + export _H5="$_signed_header" + _response="$(_post "$_sig_body" "https://${_sig_host}${_sig_target}" "" "PATCH")" + else + _err "Unable to process method: $_curl_method." + fi + + _ret="$?" + if [ "$_return_field" ]; then + _response="$(echo "$_response" | sed 's/\\\"//g'))" + _return=$(echo "${_response}" | _egrep_o "\"$_return_field\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"") + else + _return="$_response" + fi + + printf "%s" "$_return" + return $_ret + +} From b19008d1b8b2ce4c276869a50e0bd0da775b07f6 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sat, 5 Jun 2021 22:38:45 -0400 Subject: [PATCH 1379/2234] fix dns_1984hosting_add() so checks for HTML responses are actually find HTML responses --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index f371f2c1..6708f890 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -59,7 +59,7 @@ dns_1984hosting_add() { if _contains "$response" '"haserrors": true'; then _err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post" return 1 - elif _contains "$response" ""; then + elif _contains "$response" "html>"; then _err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file" return 1 elif _contains "$response" '"auth": false'; then From a55cf40b1b5b64ea7e1259d165ecdc2996e1fe58 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sat, 5 Jun 2021 23:06:28 -0400 Subject: [PATCH 1380/2234] fix _get_root() so that it successfully gets the root domain --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index d720c1c5..9dc3cb98 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -205,7 +205,7 @@ _get_root() { fi _authget "https://management.1984hosting.com/domains/soacheck/?zone=$h&nameserver=ns0.1984.is." - if _contains "$_response" "serial"; then + if _contains "$_response" "serial" && ! _contains "$_response" "null"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" return 0 From 19d7c2b336de7f617d157f0f323dae8b2f636590 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Jun 2021 22:53:39 +0800 Subject: [PATCH 1381/2234] fix bug --- dnsapi/dns_vultr.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh index c7b52e84..84857966 100644 --- a/dnsapi/dns_vultr.sh +++ b/dnsapi/dns_vultr.sh @@ -33,7 +33,7 @@ dns_vultr_add() { _debug 'Getting txt records' _vultr_rest GET "dns/records?domain=$_domain" - if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then + if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then _err 'Error' return 1 fi @@ -73,12 +73,12 @@ dns_vultr_rm() { _debug 'Getting txt records' _vultr_rest GET "dns/records?domain=$_domain" - if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then + if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then _err 'Error' return 1 fi - _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)" + _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)" _debug _record_id "$_record_id" if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." From c0285fbc15e729096b59833395e70c2708af9322 Mon Sep 17 00:00:00 2001 From: Marcus Grando Date: Thu, 10 Jun 2021 11:45:53 -0300 Subject: [PATCH 1382/2234] Added Azion DNS API --- dnsapi/dns_azion.sh | 258 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 dnsapi/dns_azion.sh diff --git a/dnsapi/dns_azion.sh b/dnsapi/dns_azion.sh new file mode 100644 index 00000000..2c5e8fda --- /dev/null +++ b/dnsapi/dns_azion.sh @@ -0,0 +1,258 @@ +#!/usr/bin/env sh + +# +#AZION_Username="" +#AZION_Password="" +#AZION_Token="" +#AZION_ZoneID="" +# + +AZION_Api="https://api.azionapi.net" + +######## Public functions ######## + +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record +dns_azion_add() { + fulldomain=$1 + txtvalue=$2 + + AZION_Username="${AZION_Username:-$(_readaccountconf_mutable AZION_Username)}" + AZION_Password="${AZION_Password:-$(_readaccountconf_mutable AZION_Password)}" + AZION_Token="${AZION_Token:-$(_readaccountconf_mutable AZION_Token)}" + AZION_ZoneID="${AZION_ZoneID:-$(_readaccountconf_mutable AZION_ZoneID)}" + + if ! _contains "$AZION_Username" "@"; then + _err "It seems that the AZION_Username is not a valid email address. Revalidate your environments." + return 1 + fi + + if [ -z "$AZION_Token" ]; then + if [ -z "$AZION_Username" ] || [ -z "$AZION_Password" ]; then + _err "You didn't specified a AZION_Username/AZION_Password to generate Azion token." + return 1 + fi + _get_token + AZION_Token="${AZION_Token:-$(_readaccountconf_mutable AZION_Token)}" + fi + + _saveaccountconf_mutable AZION_Username "$AZION_Username" + _saveaccountconf_mutable AZION_Password "$AZION_Password" + _saveaccountconf_mutable AZION_Token "$AZION_Token" + _saveaccountconf_mutable AZION_ZoneID "$AZION_ZoneID" + + _debug "Detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Domain not found" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug _domain_id "$_domain_id" + + _info "Add or update record" + _get_record "$_sub_domain" + if [ "$record_id" ]; then + _payload="{\"record_type\": \"TXT\", \"entry\": \"$_sub_domain\", \"answers_list\": [$answers_list, \"$txtvalue\"], \"ttl\": 20}" + if _azion_rest PUT "intelligent_dns/$_domain_id/records/$record_id" "$_payload"; then + if _contains "$response" "$txtvalue"; then + _info "Record updated." + return 0 + fi + fi + else + _payload="{\"record_type\": \"TXT\", \"entry\": \"$_sub_domain\", \"answers_list\": [\"$txtvalue\"], \"ttl\": 20}" + if _azion_rest POST "intelligent_dns/$_domain_id/records" "$_payload"; then + if _contains "$response" "$txtvalue"; then + _info "Record added." + return 0 + fi + fi + fi + _err "Failed to add or update record." + return 1 +} + +# Usage: fulldomain txtvalue +# Used to remove the txt record after validation +dns_azion_rm() { + fulldomain=$1 + txtvalue=$2 + + AZION_Username="${AZION_Username:-$(_readaccountconf_mutable AZION_Username)}" + AZION_Password="${AZION_Password:-$(_readaccountconf_mutable AZION_Password)}" + AZION_Token="${AZION_Token:-$(_readaccountconf_mutable AZION_Token)}" + AZION_ZoneID="${AZION_ZoneID:-$(_readaccountconf_mutable AZION_ZoneID)}" + + if ! _contains "$AZION_Username" "@"; then + _err "It seems that the AZION_Username is not a valid email address. Revalidate your environments." + return 1 + fi + + if [ -z "$AZION_Token" ]; then + if [ -z "$AZION_Username" ] || [ -z "$AZION_Password" ]; then + _err "You didn't specified a AZION_Username/AZION_Password to generate Azion token." + return 1 + fi + _get_token + AZION_Token="${AZION_Token:-$(_readaccountconf_mutable AZION_Token)}" + fi + + _debug "Detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Domain not found" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug _domain_id "$_domain_id" + + _info "Removing record" + _get_record "$_sub_domain" + if [ "$record_id" ]; then + if _azion_rest DELETE "intelligent_dns/$_domain_id/records/$record_id"; then + _info "Record removed." + return 0 + else + _err "Failed to remove record." + return 1 + fi + else + _info "Record not found or already removed." + return 0 + fi +} + +#################### Private functions below ################################## +# Usage: _acme-challenge.www.domain.com +# returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=sdjkglgdfewsdfg +_get_root() { + domain=$1 + i=1 + p=1 + + # Use Zone ID directly if provided + if [ "$AZION_ZoneID" ]; then + if ! _azion_rest GET "intelligent_dns/$AZION_ZoneID"; then + return 1 + else + if _contains "$response" "\"domain\":\"" >/dev/null; then + _domain=$(echo "$response" | _egrep_o "\"domain\":\"[^\"]*\"" | cut -d : -f 2 | _head_n 1 | tr -d \") + if [ "$_domain" ]; then + _cutlength=$((${#domain} - ${#_domain} - 1)) + _sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cutlength") + _domain_id=$AZION_ZoneID + return 0 + else + return 1 + fi + else + return 1 + fi + fi + fi + + if ! _azion_rest GET "intelligent_dns"; 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" "\"domain\":\"$h\""; then + _domain_id=$(echo "$response" | tr '{' "\n" | grep "\"domain\":\"$h\"" | _egrep_o "\"id\":[0-9]*" | _head_n 1 | 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) + _domain=$h + _saveaccountconf_mutable AZION_ZoneID "$_domain_id" + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_get_record() { + _record=$1 + + AZION_ZoneID="${AZION_ZoneID:-$(_readaccountconf_mutable AZION_ZoneID)}" + + if ! _azion_rest GET "intelligent_dns/$AZION_ZoneID/records"; then + return 1 + fi + + if _contains "$response" "\"entry\":\"$_record\""; then + _json_record=$(echo "$response" | tr '{}' "\n" | grep "\"entry\":\"$_record\"") + if [ "$_json_record" ]; then + record_id=$(echo "$_json_record" | _egrep_o "\"record_id\":[0-9]*" | _head_n 1 | cut -d : -f 2 | tr -d \") + answers_list=$(echo "$_json_record" | _egrep_o "\"answers_list\":\[.*\]" | _head_n 1 | cut -d : -f 2 | tr -d \[\]) + return 0 + fi + return 1 + fi + return 1 +} + +_get_token() { + AZION_Username="${AZION_Username:-$(_readaccountconf_mutable AZION_Username)}" + AZION_Password="${AZION_Password:-$(_readaccountconf_mutable AZION_Password)}" + + _basic_auth=$(printf "%s:%s" "$AZION_Username" "$AZION_Password" | _base64) + _debug _basic_auth "$_basic_auth" + + export _H1="Accept: application/json; version=3" + export _H2="Content-Type: application/json" + export _H3="Authorization: Basic $_basic_auth" + + response="$(_post "" "$AZION_Api/tokens" "" "POST")" + _debug2 response "$response" + if _contains "$response" "\"token\":\"" >/dev/null; then + _azion_token=$(echo "$response" | _egrep_o "\"token\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") + _debug _azion_token "$_azion_token" + _saveaccountconf_mutable AZION_Token "$_azion_token" + else + _err "Failed to generate Azion token" + return 1 + fi +} + +_azion_rest() { + _method=$1 + _uri="$2" + _data="$3" + + AZION_Token="${AZION_Token:-$(_readaccountconf_mutable AZION_Token)}" + + export _H1="Accept: application/json; version=3" + export _H2="Content-Type: application/json" + export _H3="Authorization: token $AZION_Token" + + if [ "$_method" != "GET" ]; then + _debug _data "$_data" + response="$(_post "$_data" "$AZION_Api/$_uri" "" "$_method")" + else + response="$(_get "$AZION_Api/$_uri")" + fi + + _debug2 response "$response" + + if [ "$?" != "0" ]; then + _err "error $_method $_uri $_data" + return 1 + fi + return 0 +} From d0b514890a28d13e83bb06efcfb14651e83360c5 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 13 Jun 2021 14:29:26 +0800 Subject: [PATCH 1383/2234] change default ca to zerossl --- acme.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index bc9510d6..0b2eb9e6 100755 --- a/acme.sh +++ b/acme.sh @@ -29,7 +29,7 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" _ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email" -DEFAULT_CA=$CA_LETSENCRYPT_V2 +DEFAULT_CA=$CA_ZEROSSL DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST CA_NAMES=" @@ -3526,8 +3526,10 @@ _regAccount() { if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then _info "No EAB credentials found for ZeroSSL, let's get one" if [ -z "$_email" ]; then - _err "Please provide a email address for ZeroSSL account." - _err "See ZeroSSL usage: $_ZEROSSL_WIKI" + _info "$(__green "$PROJECT_NAME is using ZeroSSL as default CA now.")" + _info "$(__green "Please update your account with an email address first.")" + _info "$(__green "$PROJECT_ENTRY --register-account -m my@example.com")" + _info "See: $(__green "$_ZEROSSL_WIKI")" return 1 fi _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) @@ -3538,11 +3540,13 @@ _regAccount() { fi _debug2 "$_eabresp" _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" + _secure_debug2 _eab_id "$_eab_id" if [ -z "$_eab_id" ]; then _err "Can not resolve _eab_id" return 1 fi _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" + _secure_debug2 _eab_hmac_key "$_eab_hmac_key" if [ -z "$_eab_hmac_key" ]; then _err "Can not resolve _eab_hmac_key" return 1 @@ -3564,7 +3568,7 @@ _regAccount() { eab_sign_t="$eab_protected64.$eab_payload64" _debug3 eab_sign_t "$eab_sign_t" - key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 multi | _hex_dump | tr -d ' ')" _debug3 key_hex "$key_hex" eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) From 67c42c59116706572f720516117349a978f97940 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 13 Jun 2021 15:00:30 +0800 Subject: [PATCH 1384/2234] add zerossl --- .github/workflows/LetsEncrypt.yml | 48 ++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index bdc9072e..11137388 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -16,6 +16,9 @@ on: jobs: Ubuntu: + strategy: + matrix: + TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] runs-on: ubuntu-latest env: TEST_LOCAL: 1 @@ -24,11 +27,20 @@ jobs: - name: Install tools run: sudo apt-get install -y socat - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + run: | + cd .. \ + && git clone https://github.com/acmesh-official/acmetest.git \ + && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && sudo --preserve-env ./letest.sh + run: | + cd ../acmetest \ + && export ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ + && sudo --preserve-env ./letest.sh MacOS: + strategy: + matrix: + TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] runs-on: macos-latest env: TEST_LOCAL: 1 @@ -37,11 +49,20 @@ jobs: - name: Install tools run: brew install socat - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + run: | + cd .. \ + && git clone https://github.com/acmesh-official/acmetest.git \ + && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && sudo --preserve-env ./letest.sh + run: | + cd ../acmetest \ + && export ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ + && sudo --preserve-env ./letest.sh Windows: + strategy: + matrix: + TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] runs-on: windows-latest env: TEST_LOCAL: 1 @@ -74,9 +95,15 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest shell: cmd - run: cd ../acmetest && bash.exe -c ./letest.sh + run: | + cd ../acmetest \ + set ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ + && bash.exe -c ./letest.sh FreeBSD: + strategy: + matrix: + TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] runs-on: macos-latest env: TEST_LOCAL: 1 @@ -99,9 +126,14 @@ jobs: prepare: pkg install -y socat curl usesh: true run: | - cd ../acmetest && ./letest.sh + cd ../acmetest \ + && export ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ + && ./letest.sh Solaris: + strategy: + matrix: + TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] runs-on: macos-latest env: TEST_LOCAL: 1 @@ -123,5 +155,7 @@ jobs: "8080": "80" prepare: pkgutil -y -i socat curl run: | - cd ../acmetest && ./letest.sh + cd ../acmetest \ + && export ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ + && ./letest.sh From 1ff5d71e12ba999f8c2305fc2ec764c2abe73ee7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 13 Jun 2021 15:30:51 +0800 Subject: [PATCH 1385/2234] fix windows --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 11137388..e7c5e2d1 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -97,7 +97,7 @@ jobs: shell: cmd run: | cd ../acmetest \ - set ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ + && set ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ && bash.exe -c ./letest.sh FreeBSD: From 56246592c7d5143fbefa58669a826f4a6230de14 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 13 Jun 2021 15:45:33 +0800 Subject: [PATCH 1386/2234] set ca names in the env --- .github/workflows/LetsEncrypt.yml | 58 +++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index e7c5e2d1..b95334d7 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -18,10 +18,17 @@ jobs: Ubuntu: strategy: matrix: - TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" runs-on: ubuntu-latest env: TEST_LOCAL: 1 + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} steps: - uses: actions/checkout@v2 - name: Install tools @@ -34,16 +41,22 @@ jobs: - name: Run acmetest run: | cd ../acmetest \ - && export ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ && sudo --preserve-env ./letest.sh MacOS: strategy: matrix: - TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" runs-on: macos-latest env: TEST_LOCAL: 1 + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} steps: - uses: actions/checkout@v2 - name: Install tools @@ -56,15 +69,21 @@ jobs: - name: Run acmetest run: | cd ../acmetest \ - && export ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ && sudo --preserve-env ./letest.sh Windows: strategy: matrix: - TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" runs-on: windows-latest env: + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} TEST_LOCAL: 1 #The 80 port is used by Windows server, we have to use a custom port, tunnel will also use this port. Le_HTTPPort: 8888 @@ -95,18 +114,22 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest shell: cmd - run: | - cd ../acmetest \ - && set ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ - && bash.exe -c ./letest.sh + run: cd ../acmetest && bash.exe -c ./letest.sh FreeBSD: strategy: matrix: - TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" runs-on: macos-latest env: TEST_LOCAL: 1 + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} steps: - uses: actions/checkout@v2 - uses: vmactions/cf-tunnel@v0.0.2 @@ -120,23 +143,29 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0.1.4 with: - envs: 'TEST_LOCAL TestingDomain' + envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA' nat: | "8080": "80" prepare: pkg install -y socat curl usesh: true run: | cd ../acmetest \ - && export ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ && ./letest.sh Solaris: strategy: matrix: - TEST_ACME_Server: ["", "https://acme.zerossl.com/v2/DV90"] + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" runs-on: macos-latest env: TEST_LOCAL: 1 + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} steps: - uses: actions/checkout@v2 - uses: vmactions/cf-tunnel@v0.0.2 @@ -150,12 +179,11 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0.0.3 with: - envs: 'TEST_LOCAL TestingDomain' + envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA' nat: | "8080": "80" prepare: pkgutil -y -i socat curl run: | cd ../acmetest \ - && export ACME_DIRECTORY=${{ matrix.TEST_ACME_Server }} \ && ./letest.sh From 54f2640ef252b4c1d84d535540cc9d7ac3728775 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 13 Jun 2021 15:52:38 +0800 Subject: [PATCH 1387/2234] fix env --- .github/workflows/LetsEncrypt.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index b95334d7..84fe61ad 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -22,13 +22,18 @@ jobs: - TEST_ACME_Server: "" CA_ECDSA: "" CA: "" + CA_EMAIL: "" - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" runs-on: ubuntu-latest env: TEST_LOCAL: 1 ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} steps: - uses: actions/checkout@v2 - name: Install tools @@ -50,13 +55,18 @@ jobs: - TEST_ACME_Server: "" CA_ECDSA: "" CA: "" + CA_EMAIL: "" - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" runs-on: macos-latest env: TEST_LOCAL: 1 ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} steps: - uses: actions/checkout@v2 - name: Install tools @@ -78,12 +88,17 @@ jobs: - TEST_ACME_Server: "" CA_ECDSA: "" CA: "" + CA_EMAIL: "" - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" runs-on: windows-latest env: ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_LOCAL: 1 #The 80 port is used by Windows server, we have to use a custom port, tunnel will also use this port. Le_HTTPPort: 8888 @@ -123,13 +138,18 @@ jobs: - TEST_ACME_Server: "" CA_ECDSA: "" CA: "" + CA_EMAIL: "" - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" runs-on: macos-latest env: TEST_LOCAL: 1 ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} steps: - uses: actions/checkout@v2 - uses: vmactions/cf-tunnel@v0.0.2 @@ -143,7 +163,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0.1.4 with: - envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA' + envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' nat: | "8080": "80" prepare: pkg install -y socat curl @@ -159,13 +179,18 @@ jobs: - TEST_ACME_Server: "" CA_ECDSA: "" CA: "" + CA_EMAIL: "" - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" runs-on: macos-latest env: TEST_LOCAL: 1 ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} steps: - uses: actions/checkout@v2 - uses: vmactions/cf-tunnel@v0.0.2 @@ -179,7 +204,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0.0.3 with: - envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA' + envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' nat: | "8080": "80" prepare: pkgutil -y -i socat curl From 8ae08b29e4ea296c2bb10e214dccdd0bc5be66a4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 13 Jun 2021 21:37:26 +0800 Subject: [PATCH 1388/2234] fix for solaris --- README.md | 4 ++-- acme.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index edd6442f..4b705751 100644 --- a/README.md +++ b/README.md @@ -85,8 +85,8 @@ https://github.com/acmesh-official/acmetest # Supported CA -- Letsencrypt.org CA(default) -- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA) +- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA)(default) +- Letsencrypt.org CA - [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) - Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA diff --git a/acme.sh b/acme.sh index 0b2eb9e6..08de9ce7 100755 --- a/acme.sh +++ b/acme.sh @@ -3538,14 +3538,14 @@ _regAccount() { _err "Can not get EAB credentials from ZeroSSL." return 1 fi - _debug2 "$_eabresp" + _secure_debug2 _eabresp "$_eabresp" _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" _secure_debug2 _eab_id "$_eab_id" if [ -z "$_eab_id" ]; then _err "Can not resolve _eab_id" return 1 fi - _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" + _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" _secure_debug2 _eab_hmac_key "$_eab_hmac_key" if [ -z "$_eab_hmac_key" ]; then _err "Can not resolve _eab_hmac_key" From cc9ec806b28915f82cf9532901639604265b5531 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 14 Jun 2021 11:50:19 +0800 Subject: [PATCH 1389/2234] add all Linux --- .github/workflows/Linux.yml | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/Linux.yml diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml new file mode 100644 index 00000000..9ebc4779 --- /dev/null +++ b/.github/workflows/Linux.yml @@ -0,0 +1,38 @@ +name: Linux +on: + push: + branches: + - '*' + paths: + - '**.sh' + - '**.yml' + pull_request: + branches: + - dev + paths: + - '**.sh' + - '**.yml' + + +jobs: + Linux: + strategy: + matrix: + os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3-amd64", "clearlinux:latest"] + runs-on: ubuntu-latest + env: + TEST_LOCAL: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: | + cd .. \ + && git clone https://github.com/acmesh-official/acmetest.git \ + && cp -r acme.sh acmetest/ + - name: Run acmetest + run: | + cd ../acmetest \ + && ./rundocker.sh testplat {{ matrix.os }} + + + From da754e9a71c98bb17a2a0339c9bbee171f0cfd4a Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 14 Jun 2021 11:52:45 +0800 Subject: [PATCH 1390/2234] fix --- .github/workflows/Linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 9ebc4779..f5f74351 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -32,7 +32,7 @@ jobs: - name: Run acmetest run: | cd ../acmetest \ - && ./rundocker.sh testplat {{ matrix.os }} + && ./rundocker.sh testplat ${{ matrix.os }} From 3d7375be8b1aee9593ba16ccb47b55753f996b9d Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 14 Jun 2021 12:00:42 +0800 Subject: [PATCH 1391/2234] update status --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 4b705751..07dc5d59 100644 --- a/README.md +++ b/README.md @@ -62,24 +62,24 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD |4|[![Solaris](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Solaris |5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)| Ubuntu -|6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense -|7|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD -|8|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian -|9|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS -|10|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE -|11|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl) -|12|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux -|13|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora -|14|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux -|15|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux +|6|NA|pfsense +|7|NA|OpenBSD +|8|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian +|9|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS +|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE +|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl) +|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux +|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora +|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux +|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux |16|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) |17|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|18|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia +|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia |19|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) -|20|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux -|21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux +|20|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux +|21|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux -For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): +Check our [testing project](https://github.com/acmesh-official/acmetest): https://github.com/acmesh-official/acmetest From 6621ef6a0be7c267d992733d1238d08a7ef02e67 Mon Sep 17 00:00:00 2001 From: Peter Dave Hello Date: Sat, 5 Oct 2019 21:28:25 +0800 Subject: [PATCH 1392/2234] Remove invalid "Contribute" link in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 07dc5d59..c1c3a3c4 100644 --- a/README.md +++ b/README.md @@ -469,7 +469,7 @@ TODO: ### Code Contributors -This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. +This project exists thanks to all the people who contribute. ### Financial Contributors From 447bf77dfe99d12999ec6c75495088e1a75e769b Mon Sep 17 00:00:00 2001 From: Peter Dave Hello Date: Sat, 5 Oct 2019 20:49:51 +0800 Subject: [PATCH 1393/2234] Simplify apk command in Dockerfile With apk `--no-cache` parameter, there is no need to run `apk update` and manually clean up the cache, apk will update automatically without leaving local cache files to be cleaned up. --- Dockerfile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4618efaf..4d8f219f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,6 @@ FROM alpine:3.12 -RUN apk update -f \ - && apk --no-cache add -f \ +RUN apk --no-cache add -f \ openssl \ openssh-client \ coreutils \ @@ -12,8 +11,7 @@ RUN apk update -f \ tzdata \ oath-toolkit-oathtool \ tar \ - libidn \ - && rm -rf /var/cache/apk/* + libidn ENV LE_CONFIG_HOME /acme.sh From 6f732a9957bbc41c3be6a37e9778b18c78f09816 Mon Sep 17 00:00:00 2001 From: Peter Dave Hello Date: Sat, 5 Oct 2019 20:51:51 +0800 Subject: [PATCH 1394/2234] Use `COPY` instead of `ADD` in Dockerfile for folder Ref: https://docs.docker.com/develop/develop-images/#add-or-copy --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 4d8f219f..c42f4f39 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ ARG AUTO_UPGRADE=1 ENV AUTO_UPGRADE $AUTO_UPGRADE #Install -ADD ./ /install_acme.sh/ +COPY ./ /install_acme.sh/ RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/ From 017a10189c9a8d38c95b8d2631a1facf181a6549 Mon Sep 17 00:00:00 2001 From: Avi Miller Date: Fri, 18 Jun 2021 10:16:32 +1000 Subject: [PATCH 1395/2234] fix: switch to using functions instead of calling OpenSSL directly Also reduced the number of environment variables which simplifies the documentation and requirements. The variable names now match those used by the OCI CLI. Signed-off-by: Avi Miller --- dnsapi/dns_oci.sh | 120 ++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 62 deletions(-) diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index 2843a8ca..1c75b99f 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -3,15 +3,16 @@ # Acme.sh DNS API plugin for Oracle Cloud Infrastructure # Copyright (c) 2021, Oracle and/or its affiliates # -# Required environment variables: -# - OCI_TENANCY : OCID of tenancy that contains the target DNS zone -# - OCI_USER : OCID of user with permission to add/remove records from zones -# - OCI_FINGERPRINT: fingerprint of the public key for the user -# - OCI_PRIVATE_KEY: Path to private API signing key file in PEM format +# Required OCI CLI environment variables: +# - OCI_CLI_TENANCY : OCID of tenancy that contains the target DNS zone +# - OCI_CLI_USER : OCID of user with permission to add/remove records from zones +# - OCI_CLI_REGION : Should point to the tenancy home region # -# Optional environment variables: -# - OCI_KEY_PASSPHRASE: if the private key above s encrypted, the passphrase is required -# - OCI_REGION: Your home region will probably response the fastest +# One of the following two variables is required: +# - OCI_CLI_KEY_FILE: Path to private API signing key file in PEM format; or +# - OCI_CLI_KEY : The private API signing key in PEM format +# +# NOTE: using an encrypted private key that needs a passphrase is not supported. # dns_oci_add() { @@ -20,11 +21,6 @@ dns_oci_add() { if _oci_config; then - if ! _get_zone "$_fqdn"; then - _err "Error: DNS Zone not found for $_fqdn." - return 1 - fi - if [ "$_sub_domain" ] && [ "$_domain" ]; then _add_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"ttl\": 30,\"operation\":\"ADD\"}]}" response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_add_record_body") @@ -48,11 +44,6 @@ dns_oci_rm() { if _oci_config; then - if ! _get_zone "$_fqdn"; then - _err "Error: DNS Zone not found for $_fqdn." - return 1 - fi - if [ "$_sub_domain" ] && [ "$_domain" ]; then _remove_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"operation\":\"REMOVE\"}]}" response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_remove_record_body") @@ -73,59 +64,57 @@ dns_oci_rm() { #################### Private functions below ################################## _oci_config() { - OCI_TENANCY="${OCI_TENANCY:-$(_readaccountconf_mutable OCI_TENANCY)}" - OCI_USER="${OCI_USER:-$(_readaccountconf_mutable OCI_USER)}" - OCI_FINGERPRINT="${OCI_FINGERPRINT:-$(_readaccountconf_mutable OCI_FINGERPRINT)}" - OCI_PRIVATE_KEY="${OCI_PRIVATE_KEY:-$(_readaccountconf_mutable OCI_PRIVATE_KEY)}" - OCI_KEY_PASSPHRASE="${OCI_KEY_PASSPHRASE:-$(_readaccountconf_mutable OCI_KEY_PASSPHRASE)}" - OCI_REGION="${OCI_REGION:-$(_readaccountconf_mutable OCI_REGION)}" + OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readaccountconf_mutable OCI_CLI_TENANCY)}" + OCI_CLI_USER="${OCI_CLI_USER:-$(_readaccountconf_mutable OCI_CLI_USER)}" + OCI_CLI_KEY="${OCI_CLI_KEY:-$(_readaccountconf_mutable OCI_CLI_KEY)}" + OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readaccountconf_mutable OCI_CLI_REGION)}" _not_set="" _ret=0 - if [ -f "$OCI_PRIVATE_KEY" ]; then - OCI_PRIVATE_KEY="$(openssl enc -a -A <"$OCI_PRIVATE_KEY")" + if [ -z "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then + _err "Fatal: you must provide a value for either OCI_CLI_KEY_FILE or OCI_CLI_KEY." + return 1 fi - if [ -z "$OCI_TENANCY" ]; then - _not_set="OCI_TENANCY " + if [ "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then + if [ -f "$OCI_CLI_KEY_FILE" ]; then + OCI_CLI_KEY=$(_base64 <"$OCI_CLI_KEY_FILE") + else + _err "Fatal: unable to read $OCI_CLI_KEY_FILE." + return 1 + fi fi - if [ -z "$OCI_USER" ]; then - _not_set="${_not_set}OCI_USER " + if [ -z "$OCI_CLI_TENANCY" ]; then + _not_set="${_not_set}OCI_CLI_TENANCY " fi - if [ -z "$OCI_FINGERPRINT" ]; then - _not_set="${_not_set}OCI_FINGERPRINT " + if [ -z "$OCI_CLI_USER" ]; then + _not_set="${_not_set}OCI_CLI_USER " fi - if [ -z "$OCI_PRIVATE_KEY" ]; then - _not_set="${_not_set}OCI_PRIVATE_KEY" + if [ -z "$OCI_CLI_REGION" ]; then + _not_set="${_not_set}OCI_CLI_REGION " fi if [ "$_not_set" ]; then - _err "Fatal: environment variable(s): ${_not_set} not set." + _err "Fatal: required environment variable(s): ${_not_set} not set." _ret=1 else - _saveaccountconf_mutable OCI_TENANCY "$OCI_TENANCY" - _saveaccountconf_mutable OCI_USER "$OCI_USER" - _saveaccountconf_mutable OCI_FINGERPRINT "$OCI_FINGERPRINT" - _saveaccountconf_mutable OCI_PRIVATE_KEY "$OCI_PRIVATE_KEY" + _saveaccountconf_mutable OCI_CLI_TENANCY "$OCI_CLI_TENANCY" + _saveaccountconf_mutable OCI_CLI_USER "$OCI_CLI_USER" + _saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY" + _saveaccountconf_mutable OCI_CLI_REGION "$OCI_CLI_REGION" fi - if [ "$OCI_PRIVATE_KEY" ] && [ "$(printf "%s\n" "$OCI_PRIVATE_KEY" | wc -l)" -eq 1 ]; then - OCI_PRIVATE_KEY="$(echo "$OCI_PRIVATE_KEY" | openssl enc -d -a -A)" - _secure_debug3 OCI_PRIVATE_KEY "$OCI_PRIVATE_KEY" + if ! _contains "PRIVATE KEY" "$OCI_CLI_KEY"; then + OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64 multiline) fi - if [ "$OCI_KEY_PASSPHRASE" ]; then - _saveaccountconf_mutable OCI_KEY_PASSPHRASE "$OCI_KEY_PASSPHRASE" - fi - - if [ "$OCI_REGION" ]; then - _saveaccountconf_mutable OCI_REGION "$OCI_REGION" - else - OCI_REGION="us-ashburn-1" + if ! _get_zone "$_fqdn"; then + _err "Error: DNS Zone not found for $_fqdn." + _ret=1 fi return $_ret @@ -168,6 +157,19 @@ _get_zone() { } +#Usage: privatekey +#Output MD5 fingerprint +_fingerprint() { + pkey="$1" + if [ -z "$pkey" ]; then + _usage "Usage: _fingerprint privkey" + return 1 + fi + + printf "%s" "$pkey" | ${ACME_OPENSSL_BIN:-openssl} rsa -pubout -outform DER 2>/dev/null | ${ACME_OPENSSL_BIN:-openssl} md5 -c | cut -d = -f 2 | tr -d ' ' + +} + _signed_request() { _sig_method="$1" @@ -175,17 +177,13 @@ _signed_request() { _sig_body="$3" _return_field="$4" - _sig_host="dns.$OCI_REGION.oraclecloud.com" - _sig_keyId="$OCI_TENANCY/$OCI_USER/$OCI_FINGERPRINT" + _key_fingerprint=$(_fingerprint "$OCI_CLI_KEY") + _sig_host="dns.$OCI_CLI_REGION.oraclecloud.com" + _sig_keyId="$OCI_CLI_TENANCY/$OCI_CLI_USER/$_key_fingerprint" _sig_alg="rsa-sha256" _sig_version="1" _sig_now="$(LC_ALL=C \date -u "+%a, %d %h %Y %H:%M:%S GMT")" - if [ "$OCI_KEY_PASSPHRASE" ]; then - export OCI_KEY_PASSPHRASE="$OCI_KEY_PASSPHRASE" - _sig_passinArg="-passin env:OCI_KEY_PASSPHRASE" - fi - _request_method=$(printf %s "$_sig_method" | _lower_case) _curl_method=$(printf %s "$_sig_method" | _upper_case) @@ -198,7 +196,7 @@ _signed_request() { if [ "$_sig_body" ]; then _secure_debug3 _sig_body "$_sig_body" - _sig_body_sha256="x-content-sha256: $(printf %s "$_sig_body" | openssl dgst -binary -sha256 | openssl enc -e -base64)" + _sig_body_sha256="x-content-sha256: $(printf %s "$_sig_body" | _digest sha256)" _sig_body_type="content-type: application/json" _sig_body_length="content-length: ${#_sig_body}" _string_to_sign="$_string_to_sign\n$_sig_body_sha256\n$_sig_body_type\n$_sig_body_length" @@ -207,10 +205,8 @@ _signed_request() { _tmp_file=$(_mktemp) if [ -f "$_tmp_file" ]; then - printf '%s' "$OCI_PRIVATE_KEY" >"$_tmp_file" - # Double quoting the file and passphrase breaks openssl - # shellcheck disable=SC2086 - _signature=$(printf '%b' "$_string_to_sign" | openssl dgst -sha256 -sign $_tmp_file $_sig_passinArg | openssl enc -e -base64 | tr -d '\r\n') + printf '%s' "$OCI_CLI_KEY" >"$_tmp_file" + _signature=$(printf '%b' "$_string_to_sign" | _sign "$_tmp_file" sha256 | tr -d '\r\n') rm -f "$_tmp_file" fi From 74c054b2a5db14f2ef2f663944e60f2bf5090577 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 19 Jun 2021 11:52:11 +0800 Subject: [PATCH 1396/2234] fix https://github.com/acmesh-official/acme.sh/issues/3563 --- dnsapi/dns_nsd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nsd.sh b/dnsapi/dns_nsd.sh index 83cc4cac..0d29a485 100644 --- a/dnsapi/dns_nsd.sh +++ b/dnsapi/dns_nsd.sh @@ -51,7 +51,7 @@ dns_nsd_rm() { Nsd_ZoneFile="${Nsd_ZoneFile:-$(_readdomainconf Nsd_ZoneFile)}" Nsd_Command="${Nsd_Command:-$(_readdomainconf Nsd_Command)}" - sed -i "/$fulldomain. $ttlvalue IN TXT \"$txtvalue\"/d" "$Nsd_ZoneFile" + _sed_i "/$fulldomain. $ttlvalue IN TXT \"$txtvalue\"/d" "$Nsd_ZoneFile" _info "Removed TXT record for $fulldomain" _debug "Running $Nsd_Command" if eval "$Nsd_Command"; then From ed971df93aff3d5688d09049784e16aa0365761d Mon Sep 17 00:00:00 2001 From: Avi Miller Date: Sat, 19 Jun 2021 15:41:34 +1000 Subject: [PATCH 1397/2234] fix: add missing else/return 1 to if block Signed-off-by: Avi Miller --- dnsapi/dns_oci.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index 1c75b99f..1380f4d4 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -30,6 +30,8 @@ dns_oci_add() { _err "Error: failed to add TXT record for ${_sub_domain}.${_domain}." return 1 fi + else + return 1 fi else @@ -53,6 +55,8 @@ dns_oci_rm() { _err "Error: failed to remove TXT record for ${_sub_domain}.${_domain}." return 1 fi + else + return 1 fi else From 946c8b498a26a0d5e1cdb487f3a11d8c5f14d9dc Mon Sep 17 00:00:00 2001 From: Avi Miller Date: Sun, 20 Jun 2021 09:06:21 +1000 Subject: [PATCH 1398/2234] feat: enable automatic configuration from an OCI configuration file The individual parameters can still be overridden via the corresponding OCI_CLI environment variable. Signed-off-by: Avi Miller --- dnsapi/dns_oci.sh | 129 +++++++++++++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 35 deletions(-) diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index 1380f4d4..4d013578 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -3,7 +3,10 @@ # Acme.sh DNS API plugin for Oracle Cloud Infrastructure # Copyright (c) 2021, Oracle and/or its affiliates # -# Required OCI CLI environment variables: +# The plugin will automatically use the default profile from an OCI SDK and CLI +# configuration file, if it exists. +# +# Alternatively, set the following environment variables: # - OCI_CLI_TENANCY : OCID of tenancy that contains the target DNS zone # - OCI_CLI_USER : OCID of user with permission to add/remove records from zones # - OCI_CLI_REGION : Should point to the tenancy home region @@ -19,18 +22,15 @@ dns_oci_add() { _fqdn="$1" _rdata="$2" - if _oci_config; then + if _get_oci_zone; then - if [ "$_sub_domain" ] && [ "$_domain" ]; then - _add_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"ttl\": 30,\"operation\":\"ADD\"}]}" - response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_add_record_body") - if [ "$response" ]; then - _info "Success: added TXT record for ${_sub_domain}.${_domain}." - else - _err "Error: failed to add TXT record for ${_sub_domain}.${_domain}." - return 1 - fi + _add_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"ttl\": 30,\"operation\":\"ADD\"}]}" + response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_add_record_body") + if [ "$response" ]; then + _info "Success: added TXT record for ${_sub_domain}.${_domain}." else + _err "Error: failed to add TXT record for ${_sub_domain}.${_domain}." + _err "Check that the user has permission to add records to this zone." return 1 fi @@ -44,18 +44,15 @@ dns_oci_rm() { _fqdn="$1" _rdata="$2" - if _oci_config; then + if _get_oci_zone; then - if [ "$_sub_domain" ] && [ "$_domain" ]; then - _remove_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"operation\":\"REMOVE\"}]}" - response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_remove_record_body") - if [ "$response" ]; then - _info "Success: removed TXT record for ${_sub_domain}.${_domain}." - else - _err "Error: failed to remove TXT record for ${_sub_domain}.${_domain}." - return 1 - fi + _remove_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"operation\":\"REMOVE\"}]}" + response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_remove_record_body") + if [ "$response" ]; then + _info "Success: removed TXT record for ${_sub_domain}.${_domain}." else + _err "Error: failed to remove TXT record for ${_sub_domain}.${_domain}." + _err "Check that the user has permission to remove records from this zone." return 1 fi @@ -66,12 +63,41 @@ dns_oci_rm() { } #################### Private functions below ################################## +_get_oci_zone() { + + if ! _oci_config; then + return 1 + fi + + if ! _get_zone "$_fqdn"; then + _err "Error: DNS Zone not found for $_fqdn in $OCI_CLI_TENANCY" + return 1 + fi + + return 0 + +} + _oci_config() { - OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readaccountconf_mutable OCI_CLI_TENANCY)}" - OCI_CLI_USER="${OCI_CLI_USER:-$(_readaccountconf_mutable OCI_CLI_USER)}" - OCI_CLI_KEY="${OCI_CLI_KEY:-$(_readaccountconf_mutable OCI_CLI_KEY)}" - OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readaccountconf_mutable OCI_CLI_REGION)}" + OCI_CLI_CONFIG_FILE="${OCI_CLI_CONFIG_FILE:-$HOME/.oci/config}" + OCI_CLI_PROFILE="${OCI_CLI_PROFILE:-DEFAULT}" + + # Let's try and find the values automagically first + # But still let any environment variables take precendence + if [ -f "$OCI_CLI_CONFIG_FILE" ]; then + _info "Reading OCI configuration file: $(_green "$OCI_CLI_CONFIG_FILE")" + OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_read_oci_config tenancy)}" + OCI_CLI_USER="${OCI_CLI_USER:-$(_read_oci_config user)}" + OCI_CLI_KEY_FILE="${OCI_CLI_KEY_FILE:-$(_read_oci_config key_file)}" + OCI_CLI_REGION="${OCI_CLI_REGION:-$(_read_oci_config region)}" + else + OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readaccountconf_mutable OCI_CLI_TENANCY)}" + OCI_CLI_USER="${OCI_CLI_USER:-$(_readaccountconf_mutable OCI_CLI_USER)}" + OCI_CLI_KEY="${OCI_CLI_KEY:-$(_readaccountconf_mutable OCI_CLI_KEY)}" + OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readaccountconf_mutable OCI_CLI_REGION)}" + _save_config="true" + fi _not_set="" _ret=0 @@ -85,7 +111,7 @@ _oci_config() { if [ -f "$OCI_CLI_KEY_FILE" ]; then OCI_CLI_KEY=$(_base64 <"$OCI_CLI_KEY_FILE") else - _err "Fatal: unable to read $OCI_CLI_KEY_FILE." + _err "Fatal: unable to read key file: $OCI_CLI_KEY_FILE" return 1 fi fi @@ -106,21 +132,20 @@ _oci_config() { _err "Fatal: required environment variable(s): ${_not_set} not set." _ret=1 else - _saveaccountconf_mutable OCI_CLI_TENANCY "$OCI_CLI_TENANCY" - _saveaccountconf_mutable OCI_CLI_USER "$OCI_CLI_USER" - _saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY" - _saveaccountconf_mutable OCI_CLI_REGION "$OCI_CLI_REGION" + if [ "$_save_config" ]; then + _saveaccountconf_mutable OCI_CLI_TENANCY "$OCI_CLI_TENANCY" + _saveaccountconf_mutable OCI_CLI_USER "$OCI_CLI_USER" + _saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY" + _saveaccountconf_mutable OCI_CLI_REGION "$OCI_CLI_REGION" + else + _info "Success: OCI configuration retrieved from $OCI_CLI_CONFIG_FILE." + fi fi if ! _contains "PRIVATE KEY" "$OCI_CLI_KEY"; then OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64 multiline) fi - if ! _get_zone "$_fqdn"; then - _err "Error: DNS Zone not found for $_fqdn." - _ret=1 - fi - return $_ret } @@ -244,3 +269,37 @@ _signed_request() { return $_ret } + +# file key [section] +_read_oci_config() { + _key="$1" + + _start_n=$(grep -n '\['"$OCI_CLI_PROFILE"']' "$OCI_CLI_CONFIG_FILE" | cut -d : -f 1) + _debug2 _start_n "$_start_n" + if [ -z "$_start_n" ]; then + _err "Can not find section: $OCI_CLI_PROFILE" + return 1 + fi + + _start_nn=$(_math "$_start_n" + 1) + _debug2 "_start_nn" "$_start_nn" + + _left="$(sed -n "${_start_nn},99999p" "$OCI_CLI_CONFIG_FILE")" + _debug2 _left "$_left" + _end="$(echo "$_left" | grep -n "^\[" | _head_n 1)" + _debug2 "_end" "$_end" + if [ "$_end" ]; then + _end_n=$(echo "$_end" | cut -d : -f 1) + _debug "_end_n" "$_end_n" + _seg_n=$(echo "$_left" | sed -n "1,${_end_n}p") + else + _seg_n="$_left" + fi + + _debug2 "_seg_n" "$_seg_n" + _lineini="$(echo "$_seg_n" | grep "^ *$_key *= *")" + + _debug2 "_lineini" "$_lineini" + printf "%b" "$(eval "echo $_lineini | sed -e \"s/${_key}[[:space:]]*=[[:space:]]*//g\"")" + +} From 766602284045f00fbc019b9bfa8c140fc9279a5e Mon Sep 17 00:00:00 2001 From: Avi Miller Date: Sun, 20 Jun 2021 13:12:14 +1000 Subject: [PATCH 1399/2234] fix: revert _readini() function to be more generic Also switched [::space::] with a literal space for better cross-platform compatibility. Signed-off-by: Avi Miller --- dnsapi/dns_oci.sh | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index 4d013578..1666c5a7 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -83,14 +83,14 @@ _oci_config() { OCI_CLI_CONFIG_FILE="${OCI_CLI_CONFIG_FILE:-$HOME/.oci/config}" OCI_CLI_PROFILE="${OCI_CLI_PROFILE:-DEFAULT}" - # Let's try and find the values automagically first - # But still let any environment variables take precendence + # Read the configuration from either the default or specified config file + # Override the config file value with the environment variable value (if set) if [ -f "$OCI_CLI_CONFIG_FILE" ]; then - _info "Reading OCI configuration file: $(_green "$OCI_CLI_CONFIG_FILE")" - OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_read_oci_config tenancy)}" - OCI_CLI_USER="${OCI_CLI_USER:-$(_read_oci_config user)}" - OCI_CLI_KEY_FILE="${OCI_CLI_KEY_FILE:-$(_read_oci_config key_file)}" - OCI_CLI_REGION="${OCI_CLI_REGION:-$(_read_oci_config region)}" + _info "Reading OCI configuration file: $OCI_CLI_CONFIG_FILE" + OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readini tenancy "$OCI_CLI_CONFIG_FILE" "$OCI_CLI_PROFILE")}" + OCI_CLI_USER="${OCI_CLI_USER:-$(_readini user "$OCI_CLI_CONFIG_FILE" "$OCI_CLI_PROFILE")}" + OCI_CLI_KEY_FILE="${OCI_CLI_KEY_FILE:-$(_readini key_file "$OCI_CLI_CONFIG_FILE" "$OCI_CLI_PROFILE")}" + OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readini region "$OCI_CLI_CONFIG_FILE" "$OCI_CLI_PROFILE")}" else OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readaccountconf_mutable OCI_CLI_TENANCY)}" OCI_CLI_USER="${OCI_CLI_USER:-$(_readaccountconf_mutable OCI_CLI_USER)}" @@ -271,20 +271,22 @@ _signed_request() { } # file key [section] -_read_oci_config() { +_readini() { _key="$1" + _file="$2" + _section="${3:-DEFAULT}" - _start_n=$(grep -n '\['"$OCI_CLI_PROFILE"']' "$OCI_CLI_CONFIG_FILE" | cut -d : -f 1) + _start_n=$(grep -n '\['"$_section"']' "$_file" | cut -d : -f 1) _debug2 _start_n "$_start_n" if [ -z "$_start_n" ]; then - _err "Can not find section: $OCI_CLI_PROFILE" + _err "Can not find section: $_section" return 1 fi _start_nn=$(_math "$_start_n" + 1) _debug2 "_start_nn" "$_start_nn" - _left="$(sed -n "${_start_nn},99999p" "$OCI_CLI_CONFIG_FILE")" + _left="$(sed -n "${_start_nn},99999p" "$_file")" _debug2 _left "$_left" _end="$(echo "$_left" | grep -n "^\[" | _head_n 1)" _debug2 "_end" "$_end" @@ -300,6 +302,6 @@ _read_oci_config() { _lineini="$(echo "$_seg_n" | grep "^ *$_key *= *")" _debug2 "_lineini" "$_lineini" - printf "%b" "$(eval "echo $_lineini | sed -e \"s/${_key}[[:space:]]*=[[:space:]]*//g\"")" + printf "%b" "$(eval "echo $_lineini | sed -e \"s/^ *${_key} *= *//g\"")" } From 1c786633780d5a070a24b1417039eeeaad54d3a2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 20 Jun 2021 12:26:12 +0800 Subject: [PATCH 1400/2234] exclude test for dns api changes --- .github/workflows/LetsEncrypt.yml | 6 ++++++ .github/workflows/Linux.yml | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 84fe61ad..b579d6e9 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -6,12 +6,18 @@ on: paths: - '**.sh' - '**.yml' + - '!dnsapi/**' + - '!deploy/**' + - '!notify/**' pull_request: branches: - dev paths: - '**.sh' - '**.yml' + - '!dnsapi/**' + - '!deploy/**' + - '!notify/**' jobs: diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index f5f74351..3e1d3cf8 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -6,12 +6,18 @@ on: paths: - '**.sh' - '**.yml' + - '!dnsapi/**' + - '!deploy/**' + - '!notify/**' pull_request: branches: - dev paths: - '**.sh' - '**.yml' + - '!dnsapi/**' + - '!deploy/**' + - '!notify/**' jobs: From 1d089d4541ca2764113fb8c13b644e8d7fdd5c0a Mon Sep 17 00:00:00 2001 From: Avi Miller Date: Sun, 20 Jun 2021 14:38:24 +1000 Subject: [PATCH 1401/2234] fix: refactor the way the config is read from file and envvars The plugin will use the following order of precedence: environment value > file value > default value See the wiki for details on environment variable names. Signed-off-by: Avi Miller --- dnsapi/dns_oci.sh | 125 ++++++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 53 deletions(-) diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index 1666c5a7..c27023e2 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -80,76 +80,93 @@ _get_oci_zone() { _oci_config() { - OCI_CLI_CONFIG_FILE="${OCI_CLI_CONFIG_FILE:-$HOME/.oci/config}" - OCI_CLI_PROFILE="${OCI_CLI_PROFILE:-DEFAULT}" + _DEFAULT_OCI_CLI_CONFIG_FILE="$HOME/.oci/config" + OCI_CLI_CONFIG_FILE="${OCI_CLI_CONFIG_FILE:-$(_readaccountconf_mutable OCI_CLI_CONFIG_FILE)}" - # Read the configuration from either the default or specified config file - # Override the config file value with the environment variable value (if set) - if [ -f "$OCI_CLI_CONFIG_FILE" ]; then - _info "Reading OCI configuration file: $OCI_CLI_CONFIG_FILE" - OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readini tenancy "$OCI_CLI_CONFIG_FILE" "$OCI_CLI_PROFILE")}" - OCI_CLI_USER="${OCI_CLI_USER:-$(_readini user "$OCI_CLI_CONFIG_FILE" "$OCI_CLI_PROFILE")}" - OCI_CLI_KEY_FILE="${OCI_CLI_KEY_FILE:-$(_readini key_file "$OCI_CLI_CONFIG_FILE" "$OCI_CLI_PROFILE")}" - OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readini region "$OCI_CLI_CONFIG_FILE" "$OCI_CLI_PROFILE")}" + if [ -z "$OCI_CLI_CONFIG_FILE" ]; then + OCI_CLI_CONFIG_FILE="$_DEFAULT_OCI_CLI_CONFIG_FILE" + fi + + if [ "$_DEFAULT_OCI_CLI_CONFIG_FILE" != "$OCI_CLI_CONFIG_FILE" ]; then + _saveaccountconf_mutable OCI_CLI_CONFIG_FILE "$OCI_CLI_CONFIG_FILE" else - OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readaccountconf_mutable OCI_CLI_TENANCY)}" - OCI_CLI_USER="${OCI_CLI_USER:-$(_readaccountconf_mutable OCI_CLI_USER)}" - OCI_CLI_KEY="${OCI_CLI_KEY:-$(_readaccountconf_mutable OCI_CLI_KEY)}" - OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readaccountconf_mutable OCI_CLI_REGION)}" - _save_config="true" + _clearaccountconf_mutable OCI_CLI_CONFIG_FILE fi - _not_set="" - _ret=0 - - if [ -z "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then - _err "Fatal: you must provide a value for either OCI_CLI_KEY_FILE or OCI_CLI_KEY." - return 1 + _DEFAULT_OCI_CLI_PROFILE="DEFAULT" + OCI_CLI_PROFILE="${OCI_CLI_PROFILE:-$(_readaccountconf_mutable OCI_CLI_PROFILE)}" + if [ "$_DEFAULT_OCI_CLI_PROFILE" != "$OCI_CLI_PROFILE" ]; then + _saveaccountconf_mutable OCI_CLI_PROFILE "$OCI_CLI_PROFILE" + else + OCI_CLI_PROFILE="$_DEFAULT_OCI_CLI_PROFILE" + _clearaccountconf_mutable OCI_CLI_PROFILE fi - if [ "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then - if [ -f "$OCI_CLI_KEY_FILE" ]; then - OCI_CLI_KEY=$(_base64 <"$OCI_CLI_KEY_FILE") - else - _err "Fatal: unable to read key file: $OCI_CLI_KEY_FILE" - return 1 - fi + OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readaccountconf_mutable OCI_CLI_TENANCY)}" + if [ "$OCI_CLI_TENANCY" ]; then + _saveaccountconf_mutable OCI_CLI_TENANCY "$OCI_CLI_TENANCY" + elif [ -f "$OCI_CLI_CONFIG_FILE" ]; then + _debug "Reading OCI_CLI_TENANCY value from: $OCI_CLI_CONFIG_FILE" + OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readini "$OCI_CLI_CONFIG_FILE" tenancy "$OCI_CLI_PROFILE")}" fi if [ -z "$OCI_CLI_TENANCY" ]; then - _not_set="${_not_set}OCI_CLI_TENANCY " + _err "Error: unable to read OCI_CLI_TENANCY from config file or environment variable." + return 1 fi + OCI_CLI_USER="${OCI_CLI_USER:-$(_readaccountconf_mutable OCI_CLI_USER)}" + if [ "$OCI_CLI_USER" ]; then + _saveaccountconf_mutable OCI_CLI_USER "$OCI_CLI_USER" + elif [ -f "$OCI_CLI_CONFIG_FILE" ]; then + _debug "Reading OCI_CLI_USER value from: $OCI_CLI_CONFIG_FILE" + OCI_CLI_USER="${OCI_CLI_USER:-$(_readini "$OCI_CLI_CONFIG_FILE" user "$OCI_CLI_PROFILE")}" + fi if [ -z "$OCI_CLI_USER" ]; then - _not_set="${_not_set}OCI_CLI_USER " + _err "Error: unable to read OCI_CLI_USER from config file or environment variable." + return 1 fi + OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readaccountconf_mutable OCI_CLI_REGION)}" + if [ "$OCI_CLI_REGION" ]; then + _saveaccountconf_mutable OCI_CLI_REGION "$OCI_CLI_REGION" + elif [ -f "$OCI_CLI_CONFIG_FILE" ]; then + _debug "Reading OCI_CLI_REGION value from: $OCI_CLI_CONFIG_FILE" + OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readini "$OCI_CLI_CONFIG_FILE" region "$OCI_CLI_PROFILE")}" + fi if [ -z "$OCI_CLI_REGION" ]; then - _not_set="${_not_set}OCI_CLI_REGION " + _err "Error: unable to read OCI_CLI_REGION from config file or environment variable." + return 1 fi - if [ "$_not_set" ]; then - _err "Fatal: required environment variable(s): ${_not_set} not set." - _ret=1 - else - if [ "$_save_config" ]; then - _saveaccountconf_mutable OCI_CLI_TENANCY "$OCI_CLI_TENANCY" - _saveaccountconf_mutable OCI_CLI_USER "$OCI_CLI_USER" + OCI_CLI_KEY="${OCI_CLI_KEY:-$(_readaccountconf_mutable OCI_CLI_KEY)}" + if [ -z "$OCI_CLI_KEY" ]; then + _clearaccountconf_mutable OCI_CLI_KEY + OCI_CLI_KEY_FILE="${OCI_CLI_KEY_FILE:-$(_readini "$OCI_CLI_CONFIG_FILE" key_file "$OCI_CLI_PROFILE")}" + if [ "$OCI_CLI_KEY_FILE" ] && [ -f "$OCI_CLI_KEY_FILE" ]; then + _debug "Reading OCI_CLI_KEY value from: $OCI_CLI_KEY_FILE" + OCI_CLI_KEY=$(_base64 <"$OCI_CLI_KEY_FILE") _saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY" - _saveaccountconf_mutable OCI_CLI_REGION "$OCI_CLI_REGION" - else - _info "Success: OCI configuration retrieved from $OCI_CLI_CONFIG_FILE." fi + else + _saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY" fi - if ! _contains "PRIVATE KEY" "$OCI_CLI_KEY"; then + if [ -z "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then + _err "Error: unable to find key file path in OCI config file or OCI_CLI_KEY_FILE." + _err "Error: unable to load private API signing key from OCI_CLI_KEY." + return 1 + fi + + if [ "$(printf "%s\n" "$OCI_CLI_KEY" | wc -l)" -eq 1 ]; then OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64 multiline) fi - return $_ret + return 0 } + # _get_zone(): retrieves the Zone name and OCID # # _sub_domain=_acme-challenge.www @@ -189,6 +206,7 @@ _get_zone() { #Usage: privatekey #Output MD5 fingerprint _fingerprint() { + pkey="$1" if [ -z "$pkey" ]; then _usage "Usage: _fingerprint privkey" @@ -272,36 +290,37 @@ _signed_request() { # file key [section] _readini() { - _key="$1" - _file="$2" + _file="$1" + _key="$2" _section="${3:-DEFAULT}" _start_n=$(grep -n '\['"$_section"']' "$_file" | cut -d : -f 1) - _debug2 _start_n "$_start_n" + _debug3 _start_n "$_start_n" if [ -z "$_start_n" ]; then _err "Can not find section: $_section" return 1 fi _start_nn=$(_math "$_start_n" + 1) - _debug2 "_start_nn" "$_start_nn" + _debug3 "_start_nn" "$_start_nn" _left="$(sed -n "${_start_nn},99999p" "$_file")" - _debug2 _left "$_left" + _debug3 _left "$_left" _end="$(echo "$_left" | grep -n "^\[" | _head_n 1)" - _debug2 "_end" "$_end" + _debug3 "_end" "$_end" if [ "$_end" ]; then _end_n=$(echo "$_end" | cut -d : -f 1) - _debug "_end_n" "$_end_n" + _debug3 "_end_n" "$_end_n" _seg_n=$(echo "$_left" | sed -n "1,${_end_n}p") else _seg_n="$_left" fi - _debug2 "_seg_n" "$_seg_n" + _debug3 "_seg_n" "$_seg_n" _lineini="$(echo "$_seg_n" | grep "^ *$_key *= *")" + _inivalue="$(printf "%b" "$(eval "echo $_lineini | sed \"s/^ *${_key} *= *//g\"")")" + _debug2 _inivalue "$_inivalue" + echo "$_inivalue" - _debug2 "_lineini" "$_lineini" - printf "%b" "$(eval "echo $_lineini | sed -e \"s/^ *${_key} *= *//g\"")" } From 25d0fdf8ff25135a8d071a46eb394b7e7b64d73f Mon Sep 17 00:00:00 2001 From: Avi Miller Date: Sun, 20 Jun 2021 17:07:04 +1000 Subject: [PATCH 1402/2234] fix: fix a format issue reported by shellfmt Signed-off-by: Avi Miller --- dnsapi/dns_oci.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index c27023e2..eb006120 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -166,7 +166,6 @@ _oci_config() { } - # _get_zone(): retrieves the Zone name and OCID # # _sub_domain=_acme-challenge.www @@ -322,5 +321,4 @@ _readini() { _debug2 _inivalue "$_inivalue" echo "$_inivalue" - } From 79fac4466e9b9bca12b659ea062dec2905b42052 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 20 Jun 2021 16:57:58 +0800 Subject: [PATCH 1403/2234] minor --- .github/workflows/LetsEncrypt.yml | 11 +++-------- .github/workflows/Linux.yml | 12 ++++-------- .github/workflows/PebbleStrict.yml | 4 ++-- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index b579d6e9..5986290d 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -4,20 +4,15 @@ on: branches: - '*' paths: - - '**.sh' + - '*.sh' - '**.yml' - - '!dnsapi/**' - - '!deploy/**' - - '!notify/**' + pull_request: branches: - dev paths: - - '**.sh' + - '*.sh' - '**.yml' - - '!dnsapi/**' - - '!deploy/**' - - '!notify/**' jobs: diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 3e1d3cf8..6d4dcf7c 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -4,20 +4,16 @@ on: branches: - '*' paths: - - '**.sh' + - '*.sh' - '**.yml' - - '!dnsapi/**' - - '!deploy/**' - - '!notify/**' + pull_request: branches: - dev paths: - - '**.sh' + - '*.sh' - '**.yml' - - '!dnsapi/**' - - '!deploy/**' - - '!notify/**' + jobs: diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 976e5373..fee41feb 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -4,13 +4,13 @@ on: branches: - '*' paths: - - '**.sh' + - '*.sh' - '**.yml' pull_request: branches: - dev paths: - - '**.sh' + - '*.sh' - '**.yml' jobs: From 280e44304ae87fa603b21d34dca3a39db951fa1a Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 21 Jun 2021 20:11:15 +0800 Subject: [PATCH 1404/2234] fix for compatibility to sslcom --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 08de9ce7..df1d7567 100755 --- a/acme.sh +++ b/acme.sh @@ -1210,7 +1210,7 @@ _createcsr() { _debug2 csr "$csr" _debug2 csrconf "$csrconf" - printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment" >"$csrconf" + printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\n" >"$csrconf" if [ "$acmeValidationv1" ]; then domainlist="$(_idn "$domainlist")" From 53d6ab6c2377f8bf6c2b0b1afd8b6d308d647c90 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 21 Jun 2021 21:31:00 +0800 Subject: [PATCH 1405/2234] support SSL.com --- README.md | 1 + acme.sh | 33 ++++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index c1c3a3c4..88373193 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ https://github.com/acmesh-official/acmetest - [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA)(default) - 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) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) - Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA diff --git a/acme.sh b/acme.sh index df1d7567..e398870f 100755 --- a/acme.sh +++ b/acme.sh @@ -29,18 +29,24 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" _ZERO_EAB_ENDPOINT="http://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" + + DEFAULT_CA=$CA_ZEROSSL DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST CA_NAMES=" +ZeroSSL.com,zerossl LetsEncrypt.org,letsencrypt LetsEncrypt.org_test,letsencrypt_test,letsencrypttest BuyPass.com,buypass BuyPass.com_test,buypass_test,buypasstest -ZeroSSL.com,zerossl +SSL.com,sslcom " -CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" +CA_SERVERS="$CA_ZEROSSL,$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_SSLCOM_RSA" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" @@ -155,6 +161,8 @@ _REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert" _ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA" +_SSLCOM_WIKI="https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA" + _SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server" _PREFERRED_CHAIN_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain" @@ -2617,7 +2625,13 @@ _initpath() { _ACME_SERVER_HOST="$(echo "$ACME_DIRECTORY" | cut -d : -f 2 | tr -s / | cut -d / -f 2)" _debug2 "_ACME_SERVER_HOST" "$_ACME_SERVER_HOST" - CA_DIR="$CA_HOME/$_ACME_SERVER_HOST" + _ACME_SERVER_PATH="$(echo "$ACME_DIRECTORY" | cut -d : -f 2- | tr -s / | cut -d / -f 3-)" + _debug2 "_ACME_SERVER_PATH" "$_ACME_SERVER_PATH" + if [ -z "$_ACME_SERVER_PATH" ] || [ "$_ACME_SERVER_PATH" = "directory" ]; then + CA_DIR="$CA_HOME/$_ACME_SERVER_HOST" + else + CA_DIR="$CA_HOME/$_ACME_SERVER_HOST/$_ACME_SERVER_PATH" + fi _DEFAULT_CA_CONF="$CA_DIR/ca.conf" @@ -6638,9 +6652,10 @@ _checkSudo() { return 0 } -#server +#server #keylength _selectServer() { _server="$1" + _skeylength="$2" _server_lower="$(echo "$_server" | _lower_case)" _sindex=0 for snames in $CA_NAMES; do @@ -6651,6 +6666,9 @@ _selectServer() { if [ "$_server_lower" = "$sname" ]; then _debug2 "_selectServer match $sname" _serverdir="$(_getfield "$CA_SERVERS" $_sindex)" + if [ "$_serverdir" = "$CA_SSLCOM_RSA" ] && _isEccKey "$_skeylength"; then + _serverdir="$CA_SSLCOM_ECC" + fi _debug "Selected server: $_serverdir" ACME_DIRECTORY="$_serverdir" export ACME_DIRECTORY @@ -6882,7 +6900,6 @@ _process() { ;; --server) _server="$2" - _selectServer "$_server" shift ;; --debug) @@ -6981,7 +6998,6 @@ _process() { Le_DNSSleep="$_dnssleep" shift ;; - --keylength | -k) _keylength="$2" shift @@ -6990,7 +7006,6 @@ _process() { _accountkeylength="$2" shift ;; - --cert-file | --certpath) _cert_file="$2" shift @@ -7254,6 +7269,10 @@ _process() { shift 1 done + if [ "$_server" ]; then + _selectServer "$_server" "${_ecc-:$_keylength}" + fi + if [ "${_CMD}" != "install" ]; then if [ "$__INTERACTIVE" ] && ! _checkSudo; then if [ -z "$FORCE" ]; then From 30f11d0e16e79ff672f6ef54934d6625162da882 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 21 Jun 2021 21:41:56 +0800 Subject: [PATCH 1406/2234] typo --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index e398870f..a22b053e 100755 --- a/acme.sh +++ b/acme.sh @@ -7270,7 +7270,7 @@ _process() { done if [ "$_server" ]; then - _selectServer "$_server" "${_ecc-:$_keylength}" + _selectServer "$_server" "${_ecc:-$_keylength}" fi if [ "${_CMD}" != "install" ]; then From 707cf35f0a4eb89687a2b8fcfba5184cf1a5d2f8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 21 Jun 2021 22:29:14 +0800 Subject: [PATCH 1407/2234] fix format --- acme.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/acme.sh b/acme.sh index a22b053e..56bb3ddb 100755 --- a/acme.sh +++ b/acme.sh @@ -29,11 +29,9 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" _ZERO_EAB_ENDPOINT="http://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" - DEFAULT_CA=$CA_ZEROSSL DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST From 593e8e1f636b83772224559b979c9a71724e4104 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 21 Jun 2021 22:47:22 +0800 Subject: [PATCH 1408/2234] move ca key path --- acme.sh | 79 ++++++++++++++++++++++----------------------------------- 1 file changed, 31 insertions(+), 48 deletions(-) diff --git a/acme.sh b/acme.sh index 56bb3ddb..a4bca7ea 100755 --- a/acme.sh +++ b/acme.sh @@ -2625,19 +2625,44 @@ _initpath() { _ACME_SERVER_PATH="$(echo "$ACME_DIRECTORY" | cut -d : -f 2- | tr -s / | cut -d / -f 3-)" _debug2 "_ACME_SERVER_PATH" "$_ACME_SERVER_PATH" - if [ -z "$_ACME_SERVER_PATH" ] || [ "$_ACME_SERVER_PATH" = "directory" ]; then - CA_DIR="$CA_HOME/$_ACME_SERVER_HOST" - else - CA_DIR="$CA_HOME/$_ACME_SERVER_HOST/$_ACME_SERVER_PATH" - fi + CA_DIR="$CA_HOME/$_ACME_SERVER_HOST/$_ACME_SERVER_PATH" _DEFAULT_CA_CONF="$CA_DIR/ca.conf" - if [ -z "$CA_CONF" ]; then CA_CONF="$_DEFAULT_CA_CONF" fi _debug3 CA_CONF "$CA_CONF" + _OLD_CADIR="$CA_HOME/$_ACME_SERVER_HOST" + _OLD_ACCOUNT_KEY="$_OLD_CADIR/account.key" + _OLD_ACCOUNT_JSON="$_OLD_CADIR/account.json" + _OLD_CA_CONF="$_OLD_CADIR/ca.conf" + + + _DEFAULT_ACCOUNT_KEY_PATH="$CA_DIR/account.key" + _DEFAULT_ACCOUNT_JSON_PATH="$CA_DIR/account.json" + if [ -z "$ACCOUNT_KEY_PATH" ]; then + ACCOUNT_KEY_PATH="$_DEFAULT_ACCOUNT_KEY_PATH" + if [ -f "$_OLD_ACCOUNT_KEY" ] && ! [ -f "$ACCOUNT_KEY_PATH" ]; then + mkdir -p "$CA_DIR" + mv "$_OLD_ACCOUNT_KEY" "$ACCOUNT_KEY_PATH" + fi + fi + + if [ -z "$ACCOUNT_JSON_PATH" ]; then + ACCOUNT_JSON_PATH="$_DEFAULT_ACCOUNT_JSON_PATH" + if [ -f "$_OLD_ACCOUNT_JSON" ] && ! [ -f "$ACCOUNT_JSON_PATH" ]; then + mkdir -p "$CA_DIR" + mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH" + fi + fi + + if [ -f "$_OLD_CA_CONF" ] && ! [ -f "$CA_CONF" ]; then + mkdir -p "$CA_DIR" + mv "$_OLD_CA_CONF" "$CA_CONF" + fi + + if [ -f "$CA_CONF" ]; then . "$CA_CONF" fi @@ -2658,19 +2683,6 @@ _initpath() { HTTP_HEADER="$LE_CONFIG_HOME/http.header" fi - _OLD_ACCOUNT_KEY="$LE_WORKING_DIR/account.key" - _OLD_ACCOUNT_JSON="$LE_WORKING_DIR/account.json" - - _DEFAULT_ACCOUNT_KEY_PATH="$CA_DIR/account.key" - _DEFAULT_ACCOUNT_JSON_PATH="$CA_DIR/account.json" - if [ -z "$ACCOUNT_KEY_PATH" ]; then - ACCOUNT_KEY_PATH="$_DEFAULT_ACCOUNT_KEY_PATH" - fi - - if [ -z "$ACCOUNT_JSON_PATH" ]; then - ACCOUNT_JSON_PATH="$_DEFAULT_ACCOUNT_JSON_PATH" - fi - _DEFAULT_CERT_HOME="$LE_CONFIG_HOME" if [ -z "$CERT_HOME" ]; then CERT_HOME="$_DEFAULT_CERT_HOME" @@ -3501,15 +3513,6 @@ _regAccount() { _initAPI mkdir -p "$CA_DIR" - if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then - _info "mv $_OLD_ACCOUNT_KEY to $ACCOUNT_KEY_PATH" - mv "$_OLD_ACCOUNT_KEY" "$ACCOUNT_KEY_PATH" - fi - - if [ ! -f "$ACCOUNT_JSON_PATH" ] && [ -f "$_OLD_ACCOUNT_JSON" ]; then - _info "mv $_OLD_ACCOUNT_JSON to $ACCOUNT_JSON_PATH" - mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH" - fi if [ ! -f "$ACCOUNT_KEY_PATH" ]; then if ! _create_account_key "$_reg_length"; then @@ -3647,16 +3650,6 @@ _regAccount() { updateaccount() { _initpath - if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then - _info "mv $_OLD_ACCOUNT_KEY to $ACCOUNT_KEY_PATH" - mv "$_OLD_ACCOUNT_KEY" "$ACCOUNT_KEY_PATH" - fi - - if [ ! -f "$ACCOUNT_JSON_PATH" ] && [ -f "$_OLD_ACCOUNT_JSON" ]; then - _info "mv $_OLD_ACCOUNT_JSON to $ACCOUNT_JSON_PATH" - mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH" - fi - if [ ! -f "$ACCOUNT_KEY_PATH" ]; then _err "Account key is not found at: $ACCOUNT_KEY_PATH" return 1 @@ -3699,16 +3692,6 @@ updateaccount() { deactivateaccount() { _initpath - if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then - _info "mv $_OLD_ACCOUNT_KEY to $ACCOUNT_KEY_PATH" - mv "$_OLD_ACCOUNT_KEY" "$ACCOUNT_KEY_PATH" - fi - - if [ ! -f "$ACCOUNT_JSON_PATH" ] && [ -f "$_OLD_ACCOUNT_JSON" ]; then - _info "mv $_OLD_ACCOUNT_JSON to $ACCOUNT_JSON_PATH" - mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH" - fi - if [ ! -f "$ACCOUNT_KEY_PATH" ]; then _err "Account key is not found at: $ACCOUNT_KEY_PATH" return 1 From c0ae44a41bf0c093b599a405f6e18538a786c6ea Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 21 Jun 2021 22:59:14 +0800 Subject: [PATCH 1409/2234] fix format --- acme.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/acme.sh b/acme.sh index a4bca7ea..4682544d 100755 --- a/acme.sh +++ b/acme.sh @@ -2638,7 +2638,6 @@ _initpath() { _OLD_ACCOUNT_JSON="$_OLD_CADIR/account.json" _OLD_CA_CONF="$_OLD_CADIR/ca.conf" - _DEFAULT_ACCOUNT_KEY_PATH="$CA_DIR/account.key" _DEFAULT_ACCOUNT_JSON_PATH="$CA_DIR/account.json" if [ -z "$ACCOUNT_KEY_PATH" ]; then @@ -2662,7 +2661,6 @@ _initpath() { mv "$_OLD_CA_CONF" "$CA_CONF" fi - if [ -f "$CA_CONF" ]; then . "$CA_CONF" fi From 8dae8c52c031cb49ad33c106e288b14fe577707d Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Jun 2021 07:48:37 +0800 Subject: [PATCH 1410/2234] split in to multiple files, so that it can pass more. --- .github/workflows/FreeBSD.yml | 60 +++++++++ .github/workflows/LetsEncrypt.yml | 215 ------------------------------ .github/workflows/MacOS.yml | 52 ++++++++ .github/workflows/Solaris.yml | 58 ++++++++ .github/workflows/Ubuntu.yml | 52 ++++++++ .github/workflows/Windows.yml | 70 ++++++++++ 6 files changed, 292 insertions(+), 215 deletions(-) create mode 100644 .github/workflows/FreeBSD.yml delete mode 100644 .github/workflows/LetsEncrypt.yml create mode 100644 .github/workflows/MacOS.yml create mode 100644 .github/workflows/Solaris.yml create mode 100644 .github/workflows/Ubuntu.yml create mode 100644 .github/workflows/Windows.yml diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml new file mode 100644 index 00000000..dd80a0b9 --- /dev/null +++ b/.github/workflows/FreeBSD.yml @@ -0,0 +1,60 @@ +name: FreeBSD +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '**.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '**.yml' + + +jobs: + FreeBSD: + strategy: + matrix: + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" + runs-on: macos-latest + env: + TEST_LOCAL: 1 + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + steps: + - uses: actions/checkout@v2 + - uses: vmactions/cf-tunnel@v0.0.2 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/freebsd-vm@v0.1.4 + with: + envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' + nat: | + "8080": "80" + prepare: pkg install -y socat curl + usesh: true + run: | + cd ../acmetest \ + && ./letest.sh + + diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml deleted file mode 100644 index 5986290d..00000000 --- a/.github/workflows/LetsEncrypt.yml +++ /dev/null @@ -1,215 +0,0 @@ -name: LetsEncrypt -on: - push: - branches: - - '*' - paths: - - '*.sh' - - '**.yml' - - pull_request: - branches: - - dev - paths: - - '*.sh' - - '**.yml' - - -jobs: - Ubuntu: - strategy: - matrix: - include: - - TEST_ACME_Server: "" - CA_ECDSA: "" - CA: "" - CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" - CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - CA: "ZeroSSL RSA Domain Secure Site CA" - CA_EMAIL: "githubtest@acme.sh" - runs-on: ubuntu-latest - env: - TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} - CA_ECDSA: ${{ matrix.CA_ECDSA }} - CA: ${{ matrix.CA }} - CA_EMAIL: ${{ matrix.CA_EMAIL }} - steps: - - uses: actions/checkout@v2 - - name: Install tools - run: sudo apt-get install -y socat - - name: Clone acmetest - run: | - cd .. \ - && git clone https://github.com/acmesh-official/acmetest.git \ - && cp -r acme.sh acmetest/ - - name: Run acmetest - run: | - cd ../acmetest \ - && sudo --preserve-env ./letest.sh - - MacOS: - strategy: - matrix: - include: - - TEST_ACME_Server: "" - CA_ECDSA: "" - CA: "" - CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" - CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - CA: "ZeroSSL RSA Domain Secure Site CA" - CA_EMAIL: "githubtest@acme.sh" - runs-on: macos-latest - env: - TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} - CA_ECDSA: ${{ matrix.CA_ECDSA }} - CA: ${{ matrix.CA }} - CA_EMAIL: ${{ matrix.CA_EMAIL }} - steps: - - uses: actions/checkout@v2 - - name: Install tools - run: brew install socat - - name: Clone acmetest - run: | - cd .. \ - && git clone https://github.com/acmesh-official/acmetest.git \ - && cp -r acme.sh acmetest/ - - name: Run acmetest - run: | - cd ../acmetest \ - && sudo --preserve-env ./letest.sh - - Windows: - strategy: - matrix: - include: - - TEST_ACME_Server: "" - CA_ECDSA: "" - CA: "" - CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" - CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - CA: "ZeroSSL RSA Domain Secure Site CA" - CA_EMAIL: "githubtest@acme.sh" - runs-on: windows-latest - env: - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} - CA_ECDSA: ${{ matrix.CA_ECDSA }} - CA: ${{ matrix.CA }} - CA_EMAIL: ${{ matrix.CA_EMAIL }} - TEST_LOCAL: 1 - #The 80 port is used by Windows server, we have to use a custom port, tunnel will also use this port. - Le_HTTPPort: 8888 - steps: - - name: Set git to use LF - run: | - git config --global core.autocrlf false - - uses: actions/checkout@v2 - - name: Install cygwin base packages with chocolatey - run: | - choco config get cacheLocation - choco install --no-progress cygwin - shell: cmd - - name: Install cygwin additional packages - run: | - C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git - shell: cmd - - name: Set ENV - shell: cmd - run: | - echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV% - - name: Check ENV - shell: cmd - run: | - echo "PATH=%PATH%" - - name: Clone acmetest - shell: cmd - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - name: Run acmetest - shell: cmd - run: cd ../acmetest && bash.exe -c ./letest.sh - - FreeBSD: - strategy: - matrix: - include: - - TEST_ACME_Server: "" - CA_ECDSA: "" - CA: "" - CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" - CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - CA: "ZeroSSL RSA Domain Secure Site CA" - CA_EMAIL: "githubtest@acme.sh" - runs-on: macos-latest - env: - TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} - CA_ECDSA: ${{ matrix.CA_ECDSA }} - CA: ${{ matrix.CA }} - CA_EMAIL: ${{ matrix.CA_EMAIL }} - steps: - - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.2 - id: tunnel - with: - protocol: http - port: 8080 - - name: Set envs - run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.4 - with: - envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' - nat: | - "8080": "80" - prepare: pkg install -y socat curl - usesh: true - run: | - cd ../acmetest \ - && ./letest.sh - - Solaris: - strategy: - matrix: - include: - - TEST_ACME_Server: "" - CA_ECDSA: "" - CA: "" - CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" - CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - CA: "ZeroSSL RSA Domain Secure Site CA" - CA_EMAIL: "githubtest@acme.sh" - runs-on: macos-latest - env: - TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} - CA_ECDSA: ${{ matrix.CA_ECDSA }} - CA: ${{ matrix.CA }} - CA_EMAIL: ${{ matrix.CA_EMAIL }} - steps: - - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.2 - id: tunnel - with: - protocol: http - port: 8080 - - name: Set envs - run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.3 - with: - envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' - nat: | - "8080": "80" - prepare: pkgutil -y -i socat curl - run: | - cd ../acmetest \ - && ./letest.sh - diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml new file mode 100644 index 00000000..b03bec0c --- /dev/null +++ b/.github/workflows/MacOS.yml @@ -0,0 +1,52 @@ +name: MacOS +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '**.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '**.yml' + + +jobs: + MacOS: + strategy: + matrix: + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" + runs-on: macos-latest + env: + TEST_LOCAL: 1 + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: brew install socat + - name: Clone acmetest + run: | + cd .. \ + && git clone https://github.com/acmesh-official/acmetest.git \ + && cp -r acme.sh acmetest/ + - name: Run acmetest + run: | + cd ../acmetest \ + && sudo --preserve-env ./letest.sh + + diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml new file mode 100644 index 00000000..ad976f59 --- /dev/null +++ b/.github/workflows/Solaris.yml @@ -0,0 +1,58 @@ +name: Solaris +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '**.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '**.yml' + + +jobs: + Solaris: + strategy: + matrix: + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" + runs-on: macos-latest + env: + TEST_LOCAL: 1 + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + steps: + - uses: actions/checkout@v2 + - uses: vmactions/cf-tunnel@v0.0.2 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/solaris-vm@v0.0.3 + with: + envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' + nat: | + "8080": "80" + prepare: pkgutil -y -i socat curl + run: | + cd ../acmetest \ + && ./letest.sh + diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml new file mode 100644 index 00000000..1ec50189 --- /dev/null +++ b/.github/workflows/Ubuntu.yml @@ -0,0 +1,52 @@ +name: Ubuntu +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '**.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '**.yml' + + +jobs: + Ubuntu: + strategy: + matrix: + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" + runs-on: ubuntu-latest + env: + TEST_LOCAL: 1 + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat + - name: Clone acmetest + run: | + cd .. \ + && git clone https://github.com/acmesh-official/acmetest.git \ + && cp -r acme.sh acmetest/ + - name: Run acmetest + run: | + cd ../acmetest \ + && sudo --preserve-env ./letest.sh + + diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml new file mode 100644 index 00000000..0219eaa5 --- /dev/null +++ b/.github/workflows/Windows.yml @@ -0,0 +1,70 @@ +name: Windows +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '**.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '**.yml' + + +jobs: + Windows: + strategy: + matrix: + include: + - TEST_ACME_Server: "" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + CA: "ZeroSSL RSA Domain Secure Site CA" + CA_EMAIL: "githubtest@acme.sh" + runs-on: windows-latest + env: + ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_LOCAL: 1 + #The 80 port is used by Windows server, we have to use a custom port, tunnel will also use this port. + Le_HTTPPort: 8888 + steps: + - name: Set git to use LF + run: | + git config --global core.autocrlf false + - uses: actions/checkout@v2 + - name: Install cygwin base packages with chocolatey + run: | + choco config get cacheLocation + choco install --no-progress cygwin + shell: cmd + - name: Install cygwin additional packages + run: | + C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git + shell: cmd + - name: Set ENV + shell: cmd + run: | + echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV% + - name: Check ENV + shell: cmd + run: | + echo "PATH=%PATH%" + - name: Clone acmetest + shell: cmd + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + shell: cmd + run: cd ../acmetest && bash.exe -c ./letest.sh + + + From 20082ec9fb5dda855d6ebd2d309cbba3cb4c0ad4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Jun 2021 07:55:12 +0800 Subject: [PATCH 1411/2234] update status --- README.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 88373193..805b1c2c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # An ACME Shell script: acme.sh -![LetsEncrypt](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg) +[![FreeBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml) +[![MacOS](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml) +[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml) +[![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml) +[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml) ![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) ![DockerHub](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) @@ -57,11 +61,11 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) | NO | Status| Platform| |----|-------|---------| -|1|[![MacOS](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX -|2|[![Windows](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included) -|3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD -|4|[![Solaris](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Solaris -|5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)| Ubuntu +|1|[![MacOS](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml)|Mac OSX +|2|[![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml)|Windows (cygwin with curl, openssl and crontab included) +|3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml)FreeBSD +|4|[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)Solaris +|5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)| Ubuntu |6|NA|pfsense |7|NA|OpenBSD |8|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian @@ -73,11 +77,12 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux |15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux |16|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) -|17|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia -|19|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) -|20|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux -|21|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux +|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia +|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux +|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux +|20|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 +|21|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) + Check our [testing project](https://github.com/acmesh-official/acmetest): From 41f4baadb9c20924b5f7d66e15f563d7aa178bc6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Jun 2021 07:59:02 +0800 Subject: [PATCH 1412/2234] minor --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 805b1c2c..132a375a 100644 --- a/README.md +++ b/README.md @@ -63,8 +63,8 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |----|-------|---------| |1|[![MacOS](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml)|Mac OSX |2|[![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml)|Windows (cygwin with curl, openssl and crontab included) -|3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml)FreeBSD -|4|[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)Solaris +|3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml)|FreeBSD +|4|[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)|Solaris |5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)| Ubuntu |6|NA|pfsense |7|NA|OpenBSD @@ -76,12 +76,12 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora |14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux |15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux -|16|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) -|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia -|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux -|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux -|20|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|21|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) +|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia +|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux +|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux +|19|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 +|20|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) +|21|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) Check our [testing project](https://github.com/acmesh-official/acmetest): From c7285967d61d79fcd2d1ecf0f8418952a930ca11 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Jun 2021 20:39:00 +0800 Subject: [PATCH 1413/2234] fix for list short name --- README.md | 1 + acme.sh | 3 +++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 132a375a..c7f7e677 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml) [![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml) [![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml) + ![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) ![DockerHub](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) diff --git a/acme.sh b/acme.sh index 4682544d..681632fa 100755 --- a/acme.sh +++ b/acme.sh @@ -6665,6 +6665,9 @@ _getCAShortName() { if [ -z "$caurl" ]; then caurl="$DEFAULT_CA" fi + if [ "$CA_SSLCOM_ECC" = "$caurl" ]; then + caurl="$CA_SSLCOM_RSA" #just hack to get the short name + fi caurl_lower="$(echo $caurl | _lower_case)" _sindex=0 for surl in $(echo "$CA_SERVERS" | _lower_case | tr , ' '); do From 7c7d61f61e634649482eff75e216df1da9e8e298 Mon Sep 17 00:00:00 2001 From: Habetdin <15926758+Habetdin@users.noreply.github.com> Date: Wed, 23 Jun 2021 03:20:07 +0300 Subject: [PATCH 1414/2234] Fix special characters escaping To escape characters '_', '*', '`', '[' outside of an entity, prepend the characters '\' before them. --- notify/telegram.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/telegram.sh b/notify/telegram.sh index d16f3a98..454b4146 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -27,7 +27,7 @@ telegram_send() { fi _saveaccountconf_mutable TELEGRAM_BOT_CHATID "$TELEGRAM_BOT_CHATID" - _content="$(printf "%s" "$_content" | sed -e 's/*/\\\\*/')" + _content="$(printf "%s" "$_content" | sed -e 's/\([_*`\[]\)/\\\\\1/g')" _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" _data="{\"text\": \"$_content\", " _data="$_data\"chat_id\": \"$TELEGRAM_BOT_CHATID\", " From 014e01605859d18a75d55db33f1ce2e886e50bbc Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 24 Jun 2021 20:35:49 +0800 Subject: [PATCH 1415/2234] add retry for init api --- acme.sh | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 681632fa..efbbd042 100755 --- a/acme.sh +++ b/acme.sh @@ -2540,12 +2540,18 @@ _initAPI() { _api_server="${1:-$ACME_DIRECTORY}" _debug "_init api for server: $_api_server" - if [ -z "$ACME_NEW_ACCOUNT" ]; then + MAX_API_RETRY_TIMES=10 + _sleep_retry_sec=10 + _request_retry_times=0 + while [ -z "$ACME_NEW_ACCOUNT" ] && [ "${_request_retry_times}" -lt "$MAX_API_RETRY_TIMES" ]; do + _request_retry_times=$(_math "$_request_retry_times" + 1) response=$(_get "$_api_server") if [ "$?" != "0" ]; then _debug2 "response" "$response" - _err "Can not init api for: $_api_server." - return 1 + _info "Can not init api for: $_api_server." + _info "Sleep $_sleep_retry_sec and retry." + _sleep "$_sleep_retry_sec" + continue fi response=$(echo "$response" | _json_decode) _debug2 "response" "$response" @@ -2578,8 +2584,12 @@ _initAPI() { _debug "ACME_REVOKE_CERT" "$ACME_REVOKE_CERT" _debug "ACME_AGREEMENT" "$ACME_AGREEMENT" _debug "ACME_NEW_NONCE" "$ACME_NEW_NONCE" - - fi + if [ "$ACME_KEY_CHANGE" ] && [ "$ACME_NEW_AUTHZ" ] && [ "$ACME_NEW_ORDEW_ACCOUNT" ] && [ "$ACME_REVOR" ] && [ "$ACME_NEKE_CERT" ]; then + return 0 + fi + done + _err "Can not init api, for $_api_server" + return 1 } #[domain] [keylength or isEcc flag] From 9daeae1695b19f13741b435d04381ed9fa84c815 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 24 Jun 2021 20:45:15 +0800 Subject: [PATCH 1416/2234] remove unnecessary check --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index efbbd042..0f81419a 100755 --- a/acme.sh +++ b/acme.sh @@ -2584,7 +2584,7 @@ _initAPI() { _debug "ACME_REVOKE_CERT" "$ACME_REVOKE_CERT" _debug "ACME_AGREEMENT" "$ACME_AGREEMENT" _debug "ACME_NEW_NONCE" "$ACME_NEW_NONCE" - if [ "$ACME_KEY_CHANGE" ] && [ "$ACME_NEW_AUTHZ" ] && [ "$ACME_NEW_ORDEW_ACCOUNT" ] && [ "$ACME_REVOR" ] && [ "$ACME_NEKE_CERT" ]; then + if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then return 0 fi done From 078a8b40e9cbcb42af679caf44ae19b2536a58a3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 24 Jun 2021 22:03:00 +0800 Subject: [PATCH 1417/2234] add buypass test --- .github/workflows/Ubuntu.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 1ec50189..c8ceffc7 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -28,6 +28,10 @@ jobs: CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" CA_EMAIL: "githubtest@acme.sh" + - TEST_ACME_Server: "https://api.test4.buypass.no/acme/directory" + CA_ECDSA: "Buypass Class 2 Test4 CA 5" + CA: "Buypass Class 2 Test4 CA 5" + CA_EMAIL: "githubtest@acme.sh" runs-on: ubuntu-latest env: TEST_LOCAL: 1 From 1ae9c4837042e5a53a2f3413ea88a263e86347e3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 24 Jun 2021 22:05:43 +0800 Subject: [PATCH 1418/2234] fix error --- .github/workflows/Ubuntu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index c8ceffc7..4113738f 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -28,7 +28,7 @@ jobs: CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" CA_EMAIL: "githubtest@acme.sh" - - TEST_ACME_Server: "https://api.test4.buypass.no/acme/directory" + - TEST_ACME_Server: "https://api.test4.buypass.no/acme/directory" CA_ECDSA: "Buypass Class 2 Test4 CA 5" CA: "Buypass Class 2 Test4 CA 5" CA_EMAIL: "githubtest@acme.sh" From 29fe1c86dae489458f64a660f3fe60d3d5a29bad Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 24 Jun 2021 23:21:10 +0800 Subject: [PATCH 1419/2234] fix initapi --- acme.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acme.sh b/acme.sh index 0f81419a..0dd8b678 100755 --- a/acme.sh +++ b/acme.sh @@ -2587,6 +2587,8 @@ _initAPI() { if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then return 0 fi + _info "Sleep $_sleep_retry_sec and retry." + _sleep "$_sleep_retry_sec" done _err "Can not init api, for $_api_server" return 1 From 2c927277e25758233b6b33300877afecb0e8a4a2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 24 Jun 2021 23:23:46 +0800 Subject: [PATCH 1420/2234] fix error --- .github/workflows/Ubuntu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 4113738f..cddf14b5 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -28,7 +28,7 @@ jobs: CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" CA_EMAIL: "githubtest@acme.sh" - - TEST_ACME_Server: "https://api.test4.buypass.no/acme/directory" + - TEST_ACME_Server: "https://api.test4.buypass.no/acme/directory" CA_ECDSA: "Buypass Class 2 Test4 CA 5" CA: "Buypass Class 2 Test4 CA 5" CA_EMAIL: "githubtest@acme.sh" From c66e157a14cae435413f39ef15630ca5a67d8ffd Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 24 Jun 2021 23:30:16 +0800 Subject: [PATCH 1421/2234] fix path filter --- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/Linux.yml | 2 +- .github/workflows/MacOS.yml | 2 +- .github/workflows/PebbleStrict.yml | 2 +- .github/workflows/Solaris.yml | 2 +- .github/workflows/Ubuntu.yml | 2 +- .github/workflows/Windows.yml | 2 +- .github/workflows/dockerhub.yml | 5 +++++ .github/workflows/shellcheck.yml | 2 +- 9 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index dd80a0b9..8b6d4aa5 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -5,7 +5,7 @@ on: - '*' paths: - '*.sh' - - '**.yml' + - '.github/workflows/FreeBSD.yml' pull_request: branches: diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 6d4dcf7c..a3cf1c59 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -12,7 +12,7 @@ on: - dev paths: - '*.sh' - - '**.yml' + - '.github/workflows/Linux.yml' diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index b03bec0c..e12ef8e2 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -12,7 +12,7 @@ on: - dev paths: - '*.sh' - - '**.yml' + - '.github/workflows/MacOS.yml' jobs: diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index fee41feb..15795367 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -11,7 +11,7 @@ on: - dev paths: - '*.sh' - - '**.yml' + - '.github/workflows/PebbleStrict.yml' jobs: PebbleStrict: diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index ad976f59..3f2adb6a 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -12,7 +12,7 @@ on: - dev paths: - '*.sh' - - '**.yml' + - '.github/workflows/Solaris.yml' jobs: diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index cddf14b5..dc704c04 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -12,7 +12,7 @@ on: - dev paths: - '*.sh' - - '**.yml' + - '.github/workflows/Ubuntu.yml' jobs: diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 0219eaa5..ed73641f 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -12,7 +12,7 @@ on: - dev paths: - '*.sh' - - '**.yml' + - '.github/workflows/Windows.yml' jobs: diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 238fde3a..0c3aec0a 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -6,6 +6,11 @@ on: - '*' tags: - '*' + paths: + - '**.sh' + - "Dockerfile" + - '.github/workflows/dockerhub.yml' + jobs: CheckToken: diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index b22a2fd8..006b5873 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -11,7 +11,7 @@ on: - dev paths: - '**.sh' - - '**.yml' + - '.github/workflows/shellcheck.yml' jobs: ShellCheck: From 77f659c9b9cbb1685075d5fc5e9d7409c87a6eb7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 24 Jun 2021 23:57:21 +0800 Subject: [PATCH 1422/2234] add NO_ECC_384 --- .github/workflows/Ubuntu.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index dc704c04..88a9fd38 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -32,6 +32,7 @@ jobs: CA_ECDSA: "Buypass Class 2 Test4 CA 5" CA: "Buypass Class 2 Test4 CA 5" CA_EMAIL: "githubtest@acme.sh" + NO_ECC_384: "1" runs-on: ubuntu-latest env: TEST_LOCAL: 1 @@ -39,6 +40,7 @@ jobs: CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} + NO_ECC_384: ${{ matrix.NO_ECC_384 }} steps: - uses: actions/checkout@v2 - name: Install tools From e9bdf02cfc7f57263d6693a62e35568795f56c3e Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 00:01:46 +0800 Subject: [PATCH 1423/2234] fix filter --- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/Linux.yml | 2 +- .github/workflows/MacOS.yml | 2 +- .github/workflows/PebbleStrict.yml | 2 +- .github/workflows/Solaris.yml | 2 +- .github/workflows/Ubuntu.yml | 2 +- .github/workflows/Windows.yml | 2 +- .github/workflows/shellcheck.yml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 8b6d4aa5..407a9e6d 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -12,7 +12,7 @@ on: - dev paths: - '*.sh' - - '**.yml' + - '.github/workflows/FreeBSD.yml' jobs: diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index a3cf1c59..c4ec07c4 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -5,7 +5,7 @@ on: - '*' paths: - '*.sh' - - '**.yml' + - '.github/workflows/Linux.yml' pull_request: branches: diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index e12ef8e2..5ceeba7a 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -5,7 +5,7 @@ on: - '*' paths: - '*.sh' - - '**.yml' + - '.github/workflows/MacOS.yml' pull_request: branches: diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 15795367..ea8e723d 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -5,7 +5,7 @@ on: - '*' paths: - '*.sh' - - '**.yml' + - '.github/workflows/PebbleStrict.yml' pull_request: branches: - dev diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 3f2adb6a..c3c756bb 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -5,7 +5,7 @@ on: - '*' paths: - '*.sh' - - '**.yml' + - '.github/workflows/Solaris.yml' pull_request: branches: diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 88a9fd38..e6102b97 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -5,7 +5,7 @@ on: - '*' paths: - '*.sh' - - '**.yml' + - '.github/workflows/Ubuntu.yml' pull_request: branches: diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index ed73641f..91605a52 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -5,7 +5,7 @@ on: - '*' paths: - '*.sh' - - '**.yml' + - '.github/workflows/Windows.yml' pull_request: branches: diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 006b5873..940a187d 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -5,7 +5,7 @@ on: - '*' paths: - '**.sh' - - '**.yml' + - '.github/workflows/shellcheck.yml' pull_request: branches: - dev From bcce77508a222eb70615e040c8cd6cbaf069b944 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 00:04:13 +0800 Subject: [PATCH 1424/2234] remove buypass test --- .github/workflows/Ubuntu.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index e6102b97..d3d66e19 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -28,11 +28,7 @@ jobs: CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" CA_EMAIL: "githubtest@acme.sh" - - TEST_ACME_Server: "https://api.test4.buypass.no/acme/directory" - CA_ECDSA: "Buypass Class 2 Test4 CA 5" - CA: "Buypass Class 2 Test4 CA 5" - CA_EMAIL: "githubtest@acme.sh" - NO_ECC_384: "1" + runs-on: ubuntu-latest env: TEST_LOCAL: 1 From eae490b5b153f1e7b43528a88e3156d18eb4f389 Mon Sep 17 00:00:00 2001 From: Arnoud Vermeer Date: Fri, 25 Jun 2021 10:12:23 +0200 Subject: [PATCH 1425/2234] [dns_pdns] Fix: missing content type in PATCH requests #3454 --- dnsapi/dns_pdns.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 28b35492..6aa2e953 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -103,7 +103,7 @@ set_record() { _build_record_string "$oldchallenge" done - if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [$_record_string]}]}"; then + if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [$_record_string]}]}" "application/json"; then _err "Set txt record error." return 1 fi @@ -126,7 +126,7 @@ rm_record() { if _contains "$_existing_challenges" "$txtvalue"; then #Delete all challenges (PowerDNS API does not allow to delete content) - if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"DELETE\", \"name\": \"$full.\", \"type\": \"TXT\"}]}"; then + if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"DELETE\", \"name\": \"$full.\", \"type\": \"TXT\"}]}" "application/json"; then _err "Delete txt record error." return 1 fi @@ -140,7 +140,7 @@ rm_record() { fi done #Recreate the existing challenges - if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [$_record_string]}]}"; then + if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [$_record_string]}]}" "application/json"; then _err "Set txt record error." return 1 fi @@ -203,12 +203,13 @@ _pdns_rest() { method=$1 ep=$2 data=$3 + ct=$4 export _H1="X-API-Key: $PDNS_Token" if [ ! "$method" = "GET" ]; then _debug data "$data" - response="$(_post "$data" "$PDNS_Url$ep" "" "$method")" + response="$(_post "$data" "$PDNS_Url$ep" "" "$method" "$ct")" else response="$(_get "$PDNS_Url$ep")" fi From e225e173861a2679136bb5f24c4bd863b5b15c8e Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 20:56:17 +0800 Subject: [PATCH 1426/2234] remove unused file --- .github/auto-comment.yml | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 .github/auto-comment.yml diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml deleted file mode 100644 index 520b3ce3..00000000 --- a/.github/auto-comment.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Comment to a new issue. -issuesOpened: > - If this is a bug report, please upgrade to the latest code and try again: - - 如果有 bug, 请先更新到最新版试试: - - ``` - acme.sh --upgrade - ``` - - please also provide the log with `--debug 2`. - - 同时请提供调试输出 `--debug 2` - - see: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh - - Without `--debug 2` log, your issue will NEVER get replied. - - 没有调试输出, 你的 issue 不会得到任何解答. - - -pullRequestOpened: > - First, NEVER send a PR to `master` branch, it will NEVER be accepted. Please send to the `dev` branch instead. - - If this is a PR to support new DNS API or new notification API, please read this guide first: - https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide - - Please check the guide items one by one. - - Then add your usage here: - https://github.com/acmesh-official/acme.sh/wiki/dnsapi - - Or some other wiki pages: - - https://github.com/acmesh-official/acme.sh/wiki/deployhooks - - https://github.com/acmesh-official/acme.sh/wiki/notify - - - From 77d3815baa72457e4b0fa6c4fb3677543fc979d4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 21:18:03 +0800 Subject: [PATCH 1427/2234] use TEST_ACME_Server --- .github/workflows/Ubuntu.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index d3d66e19..df0faaf3 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -20,11 +20,11 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest env: TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} From a69aece23a147a52714f6dd6724281b3e19213a4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 21:28:20 +0800 Subject: [PATCH 1428/2234] Use TEST_ACME_Server --- .github/workflows/FreeBSD.yml | 6 +++--- .github/workflows/MacOS.yml | 6 +++--- .github/workflows/PebbleStrict.yml | 2 +- .github/workflows/Solaris.yml | 6 +++--- .github/workflows/Windows.yml | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 407a9e6d..45b08405 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -20,18 +20,18 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" runs-on: macos-latest env: TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index 5ceeba7a..11d8e5c3 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -20,18 +20,18 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" runs-on: macos-latest env: TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index ea8e723d..f7907d8b 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -19,7 +19,7 @@ jobs: env: TestingDomain: example.com TestingAltDomains: www.example.com - ACME_DIRECTORY: https://localhost:14000/dir + TEST_ACME_Server: https://localhost:14000/dir HTTPS_INSECURE: 1 Le_HTTPPort: 5002 TEST_LOCAL: 1 diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index c3c756bb..27e9ad09 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -20,18 +20,18 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" runs-on: macos-latest env: TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 91605a52..69ed64ea 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -20,17 +20,17 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" runs-on: windows-latest env: - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} From 536a5f7cffe3b20441687713fb1e14837adc5637 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 21:59:38 +0800 Subject: [PATCH 1429/2234] fix deactivate --- acme.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 0dd8b678..62fb80d0 100755 --- a/acme.sh +++ b/acme.sh @@ -5775,7 +5775,20 @@ remove() { _deactivate() { _d_domain="$1" _d_type="$2" - _initpath + _initpath "$_d_domain" "$_d_type" + + . "$DOMAIN_CONF" + _debug Le_API "$Le_API" + + if [ "$Le_API" ]; then + export ACME_DIRECTORY="$Le_API" + #reload ca configs + ACCOUNT_KEY_PATH="" + ACCOUNT_JSON_PATH="" + CA_CONF="" + _debug3 "initpath again." + _initpath "$Le_Domain" "$_d_type" + fi _identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then From 175200430144c1b3070ec08450d8641713cb67a5 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 22:16:16 +0800 Subject: [PATCH 1430/2234] fix deactivate --- acme.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/acme.sh b/acme.sh index 62fb80d0..bf6f2806 100755 --- a/acme.sh +++ b/acme.sh @@ -2535,6 +2535,16 @@ __initHome() { fi } +_clearAPI() { + ACME_NEW_ACCOUNT="" + ACME_KEY_CHANGE="" + ACME_NEW_AUTHZ="" + ACME_NEW_ORDER="" + ACME_REVOKE_CERT="" + ACME_NEW_NONCE="" + ACME_AGREEMENT="" +} + #server _initAPI() { _api_server="${1:-$ACME_DIRECTORY}" @@ -5032,6 +5042,9 @@ renew() { _debug Le_API "$Le_API" if [ "$Le_API" ]; then + if [ "$Le_API" != "$ACME_DIRECTORY" ]; then + _clearAPI + fi export ACME_DIRECTORY="$Le_API" #reload ca configs ACCOUNT_KEY_PATH="" @@ -5039,6 +5052,7 @@ renew() { CA_CONF="" _debug3 "initpath again." _initpath "$Le_Domain" "$_isEcc" + _initAPI fi if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then @@ -5781,6 +5795,9 @@ _deactivate() { _debug Le_API "$Le_API" if [ "$Le_API" ]; then + if [ "$Le_API" != "$ACME_DIRECTORY" ]; then + _clearAPI + fi export ACME_DIRECTORY="$Le_API" #reload ca configs ACCOUNT_KEY_PATH="" @@ -5788,6 +5805,7 @@ _deactivate() { CA_CONF="" _debug3 "initpath again." _initpath "$Le_Domain" "$_d_type" + _initAPI fi _identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}" From 13ab98440c9699e9c652a323dbd493a82f149703 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 22:23:17 +0800 Subject: [PATCH 1431/2234] fix initapi --- acme.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/acme.sh b/acme.sh index bf6f2806..8e3d5f54 100755 --- a/acme.sh +++ b/acme.sh @@ -2600,6 +2600,9 @@ _initAPI() { _info "Sleep $_sleep_retry_sec and retry." _sleep "$_sleep_retry_sec" done + if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then + return 0 + fi _err "Can not init api, for $_api_server" return 1 } From 719ba75fccb8a2cb8dfe6655901d370f21bb2820 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 22:29:40 +0800 Subject: [PATCH 1432/2234] fix test server --- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/MacOS.yml | 2 +- .github/workflows/Solaris.yml | 2 +- .github/workflows/Ubuntu.yml | 2 +- .github/workflows/Windows.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 45b08405..83364b3c 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "LetsEncrypt.org" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index 11d8e5c3..85ec7527 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "LetsEncrypt.org" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 27e9ad09..64dd741f 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "LetsEncrypt.org" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index df0faaf3..af74965a 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "LetsEncrypt.org" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 69ed64ea..8c8e2842 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "LetsEncrypt.org" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" From 13fd83e0baf69edd7d5778eec980e16032f65a38 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 22:44:23 +0800 Subject: [PATCH 1433/2234] fix revoke --- acme.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/acme.sh b/acme.sh index 8e3d5f54..3afb958c 100755 --- a/acme.sh +++ b/acme.sh @@ -5713,6 +5713,23 @@ revoke() { return 1 fi + . "$DOMAIN_CONF" + _debug Le_API "$Le_API" + + if [ "$Le_API" ]; then + if [ "$Le_API" != "$ACME_DIRECTORY" ]; then + _clearAPI + fi + export ACME_DIRECTORY="$Le_API" + #reload ca configs + ACCOUNT_KEY_PATH="" + ACCOUNT_JSON_PATH="" + CA_CONF="" + _debug3 "initpath again." + _initpath "$Le_Domain" "$_isEcc" + _initAPI + fi + cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _url_replace)" if [ -z "$cert" ]; then From fb73dceab09bb5aec542becd1a896ed5cbbccdd6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 22:46:55 +0800 Subject: [PATCH 1434/2234] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3afb958c..b309704c 100755 --- a/acme.sh +++ b/acme.sh @@ -5713,7 +5713,7 @@ revoke() { return 1 fi - . "$DOMAIN_CONF" + . "$DOMAIN_CONF" _debug Le_API "$Le_API" if [ "$Le_API" ]; then From ba7d85145aff76cf15c0b61f03340af0ff01cca7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 25 Jun 2021 23:01:47 +0800 Subject: [PATCH 1435/2234] fix env --- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/Solaris.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 83364b3c..6a82156d 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -48,7 +48,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0.1.4 with: - envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL' nat: | "8080": "80" prepare: pkg install -y socat curl diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 64dd741f..9d1c46ac 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -48,7 +48,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0.0.3 with: - envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL' nat: | "8080": "80" prepare: pkgutil -y -i socat curl From 772d9700748ee00de74f1242753eb93bbeae089c Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 25 Jun 2021 23:20:40 +0800 Subject: [PATCH 1436/2234] fix CI tests (#3574) fix CI tests --- .github/auto-comment.yml | 40 ---------------------- .github/workflows/FreeBSD.yml | 8 ++--- .github/workflows/MacOS.yml | 6 ++-- .github/workflows/PebbleStrict.yml | 2 +- .github/workflows/Solaris.yml | 8 ++--- .github/workflows/Ubuntu.yml | 6 ++-- .github/workflows/Windows.yml | 6 ++-- acme.sh | 53 +++++++++++++++++++++++++++++- 8 files changed, 70 insertions(+), 59 deletions(-) delete mode 100644 .github/auto-comment.yml diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml deleted file mode 100644 index 520b3ce3..00000000 --- a/.github/auto-comment.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Comment to a new issue. -issuesOpened: > - If this is a bug report, please upgrade to the latest code and try again: - - 如果有 bug, 请先更新到最新版试试: - - ``` - acme.sh --upgrade - ``` - - please also provide the log with `--debug 2`. - - 同时请提供调试输出 `--debug 2` - - see: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh - - Without `--debug 2` log, your issue will NEVER get replied. - - 没有调试输出, 你的 issue 不会得到任何解答. - - -pullRequestOpened: > - First, NEVER send a PR to `master` branch, it will NEVER be accepted. Please send to the `dev` branch instead. - - If this is a PR to support new DNS API or new notification API, please read this guide first: - https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide - - Please check the guide items one by one. - - Then add your usage here: - https://github.com/acmesh-official/acme.sh/wiki/dnsapi - - Or some other wiki pages: - - https://github.com/acmesh-official/acme.sh/wiki/deployhooks - - https://github.com/acmesh-official/acme.sh/wiki/notify - - - diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 407a9e6d..6a82156d 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -20,18 +20,18 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" runs-on: macos-latest env: TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} @@ -48,7 +48,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0.1.4 with: - envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL' nat: | "8080": "80" prepare: pkg install -y socat curl diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index 5ceeba7a..85ec7527 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -20,18 +20,18 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" runs-on: macos-latest env: TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index ea8e723d..f7907d8b 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -19,7 +19,7 @@ jobs: env: TestingDomain: example.com TestingAltDomains: www.example.com - ACME_DIRECTORY: https://localhost:14000/dir + TEST_ACME_Server: https://localhost:14000/dir HTTPS_INSECURE: 1 Le_HTTPPort: 5002 TEST_LOCAL: 1 diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index c3c756bb..9d1c46ac 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -20,18 +20,18 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" runs-on: macos-latest env: TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} @@ -48,7 +48,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0.0.3 with: - envs: 'TEST_LOCAL TestingDomain ACME_DIRECTORY CA_ECDSA CA CA_EMAIL' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL' nat: | "8080": "80" prepare: pkgutil -y -i socat curl diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index d3d66e19..af74965a 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -20,11 +20,11 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest env: TEST_LOCAL: 1 - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 91605a52..8c8e2842 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -20,17 +20,17 @@ jobs: strategy: matrix: include: - - TEST_ACME_Server: "" + - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - - TEST_ACME_Server: "https://acme.zerossl.com/v2/DV90" + - 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" runs-on: windows-latest env: - ACME_DIRECTORY: ${{ matrix.TEST_ACME_Server }} + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} diff --git a/acme.sh b/acme.sh index 0dd8b678..b309704c 100755 --- a/acme.sh +++ b/acme.sh @@ -2535,6 +2535,16 @@ __initHome() { fi } +_clearAPI() { + ACME_NEW_ACCOUNT="" + ACME_KEY_CHANGE="" + ACME_NEW_AUTHZ="" + ACME_NEW_ORDER="" + ACME_REVOKE_CERT="" + ACME_NEW_NONCE="" + ACME_AGREEMENT="" +} + #server _initAPI() { _api_server="${1:-$ACME_DIRECTORY}" @@ -2590,6 +2600,9 @@ _initAPI() { _info "Sleep $_sleep_retry_sec and retry." _sleep "$_sleep_retry_sec" done + if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then + return 0 + fi _err "Can not init api, for $_api_server" return 1 } @@ -5032,6 +5045,9 @@ renew() { _debug Le_API "$Le_API" if [ "$Le_API" ]; then + if [ "$Le_API" != "$ACME_DIRECTORY" ]; then + _clearAPI + fi export ACME_DIRECTORY="$Le_API" #reload ca configs ACCOUNT_KEY_PATH="" @@ -5039,6 +5055,7 @@ renew() { CA_CONF="" _debug3 "initpath again." _initpath "$Le_Domain" "$_isEcc" + _initAPI fi if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then @@ -5696,6 +5713,23 @@ revoke() { return 1 fi + . "$DOMAIN_CONF" + _debug Le_API "$Le_API" + + if [ "$Le_API" ]; then + if [ "$Le_API" != "$ACME_DIRECTORY" ]; then + _clearAPI + fi + export ACME_DIRECTORY="$Le_API" + #reload ca configs + ACCOUNT_KEY_PATH="" + ACCOUNT_JSON_PATH="" + CA_CONF="" + _debug3 "initpath again." + _initpath "$Le_Domain" "$_isEcc" + _initAPI + fi + cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _url_replace)" if [ -z "$cert" ]; then @@ -5775,7 +5809,24 @@ remove() { _deactivate() { _d_domain="$1" _d_type="$2" - _initpath + _initpath "$_d_domain" "$_d_type" + + . "$DOMAIN_CONF" + _debug Le_API "$Le_API" + + if [ "$Le_API" ]; then + if [ "$Le_API" != "$ACME_DIRECTORY" ]; then + _clearAPI + fi + export ACME_DIRECTORY="$Le_API" + #reload ca configs + ACCOUNT_KEY_PATH="" + ACCOUNT_JSON_PATH="" + CA_CONF="" + _debug3 "initpath again." + _initpath "$Le_Domain" "$_d_type" + _initAPI + fi _identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then From e0def66959cc435d8320b6ce33ef86807a0b3479 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 27 Jun 2021 11:29:51 +0800 Subject: [PATCH 1437/2234] fix for compatiblity --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index b309704c..6f41285b 100755 --- a/acme.sh +++ b/acme.sh @@ -3577,7 +3577,7 @@ _regAccount() { return 1 fi _secure_debug2 _eabresp "$_eabresp" - _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" + _eab_id="$(echo "$_eabresp" | tr ',}' '\n\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" _secure_debug2 _eab_id "$_eab_id" if [ -z "$_eab_id" ]; then _err "Can not resolve _eab_id" @@ -5857,7 +5857,7 @@ _deactivate() { _debug2 response "$response" _URL_NAME="url" - entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")" + entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n\n' | grep "\"status\": *\"valid\"")" if [ -z "$entries" ]; then _info "No valid entries found." if [ -z "$thumbprint" ]; then @@ -6621,7 +6621,7 @@ _getRepoHash() { _hash_path=$1 shift _hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/$_hash_path" - _get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4 + _get $_hash_url | tr -d "\r\n" | tr '{},' '\n\n\n' | grep '"sha":' | cut -d '"' -f 4 } _getUpgradeHash() { From 518e1df257511f1a0f0c8e285f78c4a6320b5511 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 28 Jun 2021 21:10:42 +0800 Subject: [PATCH 1438/2234] sync (#3580) sync --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index b309704c..6f41285b 100755 --- a/acme.sh +++ b/acme.sh @@ -3577,7 +3577,7 @@ _regAccount() { return 1 fi _secure_debug2 _eabresp "$_eabresp" - _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" + _eab_id="$(echo "$_eabresp" | tr ',}' '\n\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" _secure_debug2 _eab_id "$_eab_id" if [ -z "$_eab_id" ]; then _err "Can not resolve _eab_id" @@ -5857,7 +5857,7 @@ _deactivate() { _debug2 response "$response" _URL_NAME="url" - entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")" + entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n\n' | grep "\"status\": *\"valid\"")" if [ -z "$entries" ]; then _info "No valid entries found." if [ -z "$thumbprint" ]; then @@ -6621,7 +6621,7 @@ _getRepoHash() { _hash_path=$1 shift _hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/$_hash_path" - _get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4 + _get $_hash_url | tr -d "\r\n" | tr '{},' '\n\n\n' | grep '"sha":' | cut -d '"' -f 4 } _getUpgradeHash() { From 2d07185300d612ed468538e8486c64cde03b8f20 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 28 Jun 2021 21:16:32 +0800 Subject: [PATCH 1439/2234] use letsencrypt server to renew certs if no server was saved. --- acme.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/acme.sh b/acme.sh index 6f41285b..d62f7007 100755 --- a/acme.sh +++ b/acme.sh @@ -5043,6 +5043,11 @@ renew() { . "$DOMAIN_CONF" _debug Le_API "$Le_API" + if [ -z "$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 [ "$Le_API" ]; then if [ "$Le_API" != "$ACME_DIRECTORY" ]; then From d519873fa434705b94b38f8e7975b62a2a426fd9 Mon Sep 17 00:00:00 2001 From: xpac1985 Date: Thu, 1 Jul 2021 22:25:49 +0200 Subject: [PATCH 1440/2234] Fix Infoblox_View handling + some cleanup URL is now constructed after possible fallback value for Infoblox_View is being set Infoblox_View is URLencoded to deal with e.g. spaces Some cleanup, clearer log messages etc. --- dnsapi/dns_infoblox.sh | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_infoblox.sh b/dnsapi/dns_infoblox.sh index 4cbb2146..a4581585 100644 --- a/dnsapi/dns_infoblox.sh +++ b/dnsapi/dns_infoblox.sh @@ -9,7 +9,6 @@ dns_infoblox_add() { ## Nothing to see here, just some housekeeping fulldomain=$1 txtvalue=$2 - baseurlnObject="https://$Infoblox_Server/wapi/v2.2.2/record:txt?name=$fulldomain&text=$txtvalue&view=$Infoblox_View" _info "Using Infoblox API" _debug fulldomain "$fulldomain" @@ -19,32 +18,39 @@ dns_infoblox_add() { if [ -z "$Infoblox_Creds" ] || [ -z "$Infoblox_Server" ]; then Infoblox_Creds="" Infoblox_Server="" - _err "You didn't specify the credentials, server or infoblox view yet (Infoblox_Creds, Infoblox_Server and Infoblox_View)." - _err "Please set them via EXPORT ([username:password], [ip or hostname]) and try again." + _err "You didn't specify the Infoblox credentials or server (Infoblox_Creds; Infoblox_Server)." + _err "Please set them via EXPORT Infoblox_Creds=username:password or EXPORT Infoblox_server=ip/hostname and try again." return 1 fi if [ -z "$Infoblox_View" ]; then + _info "No Infoblox_View set, using fallback value 'default'" Infoblox_View="default" fi - + ## Save the credentials to the account file _saveaccountconf Infoblox_Creds "$Infoblox_Creds" _saveaccountconf Infoblox_Server "$Infoblox_Server" _saveaccountconf Infoblox_View "$Infoblox_View" + ## URLencode Infoblox View to deal with e.g. spaces + Infoblox_ViewEncoded=$(printf "%b" "$Infoblox_View" | _url_encode) + ## Base64 encode the credentials Infoblox_CredsEncoded=$(printf "%b" "$Infoblox_Creds" | _base64) ## Construct the HTTP Authorization header export _H1="Accept-Language:en-US" export _H2="Authorization: Basic $Infoblox_CredsEncoded" + + ## Construct the request URL + baseurlnObject="https://$Infoblox_Server/wapi/v2.2.2/record:txt?name=$fulldomain&text=$txtvalue&view=${Infoblox_ViewEncoded}" ## Add the challenge record to the Infoblox grid member result="$(_post "" "$baseurlnObject" "" "POST")" ## Let's see if we get something intelligible back from the unit - if [ "$(echo "$result" | _egrep_o "record:txt/.*:.*/$Infoblox_View")" ]; then + if [ "$(echo "$result" | _egrep_o "record:txt/.*:.*/${Infoblox_ViewEncoded}")" ]; then _info "Successfully created the txt record" return 0 else @@ -65,6 +71,9 @@ dns_infoblox_rm() { _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" + ## URLencode Infoblox View to deal with e.g. spaces + Infoblox_ViewEncoded=$(printf "%b" "$Infoblox_View" | _url_encode) + ## Base64 encode the credentials Infoblox_CredsEncoded="$(printf "%b" "$Infoblox_Creds" | _base64)" @@ -73,18 +82,18 @@ dns_infoblox_rm() { export _H2="Authorization: Basic $Infoblox_CredsEncoded" ## Does the record exist? Let's check. - baseurlnObject="https://$Infoblox_Server/wapi/v2.2.2/record:txt?name=$fulldomain&text=$txtvalue&view=$Infoblox_View&_return_type=xml-pretty" + baseurlnObject="https://$Infoblox_Server/wapi/v2.2.2/record:txt?name=$fulldomain&text=$txtvalue&view=${Infoblox_ViewEncoded}&_return_type=xml-pretty" result="$(_get "$baseurlnObject")" ## Let's see if we get something intelligible back from the grid - if [ "$(echo "$result" | _egrep_o "record:txt/.*:.*/$Infoblox_View")" ]; then + if [ "$(echo "$result" | _egrep_o "record:txt/.*:.*/${Infoblox_ViewEncoded}")" ]; then ## Extract the object reference - objRef="$(printf "%b" "$result" | _egrep_o "record:txt/.*:.*/$Infoblox_View")" + objRef="$(printf "%b" "$result" | _egrep_o "record:txt/.*:.*/${Infoblox_ViewEncoded}")" objRmUrl="https://$Infoblox_Server/wapi/v2.2.2/$objRef" ## Delete them! All the stale records! rmResult="$(_post "" "$objRmUrl" "" "DELETE")" ## Let's see if that worked - if [ "$(echo "$rmResult" | _egrep_o "record:txt/.*:.*/$Infoblox_View")" ]; then + if [ "$(echo "$rmResult" | _egrep_o "record:txt/.*:.*/${Infoblox_ViewEncoded}")" ]; then _info "Successfully deleted $objRef" return 0 else From 52243d0870c67251cdccae936ca9b291d2306516 Mon Sep 17 00:00:00 2001 From: xpac1985 Date: Thu, 1 Jul 2021 22:54:56 +0200 Subject: [PATCH 1441/2234] Clean up formatting (SHFMT) --- dnsapi/dns_infoblox.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_infoblox.sh b/dnsapi/dns_infoblox.sh index a4581585..827d92d1 100644 --- a/dnsapi/dns_infoblox.sh +++ b/dnsapi/dns_infoblox.sh @@ -27,7 +27,7 @@ dns_infoblox_add() { _info "No Infoblox_View set, using fallback value 'default'" Infoblox_View="default" fi - + ## Save the credentials to the account file _saveaccountconf Infoblox_Creds "$Infoblox_Creds" _saveaccountconf Infoblox_Server "$Infoblox_Server" @@ -45,7 +45,7 @@ dns_infoblox_add() { ## Construct the request URL baseurlnObject="https://$Infoblox_Server/wapi/v2.2.2/record:txt?name=$fulldomain&text=$txtvalue&view=${Infoblox_ViewEncoded}" - + ## Add the challenge record to the Infoblox grid member result="$(_post "" "$baseurlnObject" "" "POST")" From 224cd046739e73c8c873a2031ca7b340349bc496 Mon Sep 17 00:00:00 2001 From: xpac1985 Date: Thu, 1 Jul 2021 22:59:43 +0200 Subject: [PATCH 1442/2234] Shell formatting, again --- dnsapi/dns_infoblox.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_infoblox.sh b/dnsapi/dns_infoblox.sh index 827d92d1..6bfd36ee 100644 --- a/dnsapi/dns_infoblox.sh +++ b/dnsapi/dns_infoblox.sh @@ -42,10 +42,10 @@ dns_infoblox_add() { ## Construct the HTTP Authorization header export _H1="Accept-Language:en-US" export _H2="Authorization: Basic $Infoblox_CredsEncoded" - + ## Construct the request URL baseurlnObject="https://$Infoblox_Server/wapi/v2.2.2/record:txt?name=$fulldomain&text=$txtvalue&view=${Infoblox_ViewEncoded}" - + ## Add the challenge record to the Infoblox grid member result="$(_post "" "$baseurlnObject" "" "POST")" From a0c5d17539394cd1b457c9afa14577debe1c52ed Mon Sep 17 00:00:00 2001 From: jonwltn <86822083+jonwltn@users.noreply.github.com> Date: Fri, 2 Jul 2021 09:23:45 -0700 Subject: [PATCH 1443/2234] Fix the URL for checking DNSPod availability. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d62f7007..4b20b708 100755 --- a/acme.sh +++ b/acme.sh @@ -3925,7 +3925,7 @@ _ns_lookup_ali() { } _ns_is_available_dp() { - if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then + if _get "https://doh.pub" "" 1 >/dev/null 2>&1; then return 0 else return 1 From da58fcbfce9402aee9209497850349f21dc61fae Mon Sep 17 00:00:00 2001 From: Steven Zhu Date: Tue, 6 Jul 2021 20:51:51 -0400 Subject: [PATCH 1444/2234] Add sender name for SendGrid notify hook --- notify/sendgrid.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/notify/sendgrid.sh b/notify/sendgrid.sh index 0d5ea3b3..ea4dcc93 100644 --- a/notify/sendgrid.sh +++ b/notify/sendgrid.sh @@ -37,11 +37,19 @@ sendgrid_send() { fi _saveaccountconf_mutable SENDGRID_FROM "$SENDGRID_FROM" + SENDGRID_FROM_NAME="${SENDGRID_FROM_NAME:-$(_readaccountconf_mutable SENDGRID_FROM_NAME)}" + _saveaccountconf_mutable SENDGRID_FROM_NAME "$SENDGRID_FROM_NAME" + export _H1="Authorization: Bearer $SENDGRID_API_KEY" export _H2="Content-Type: application/json" _content="$(echo "$_content" | _json_encode)" - _data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}" + + if [ -z "$SENDGRID_FROM_NAME" ]; then + _data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}" + else + _data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\", \"name\": \"$SENDGRID_FROM_NAME\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}" + fi response="$(_post "$_data" "https://api.sendgrid.com/v3/mail/send")" if [ "$?" = "0" ] && [ -z "$response" ]; then From 849c3fd9c90027cd96966d99569ffdfdccc61a3d Mon Sep 17 00:00:00 2001 From: Steven Zhu Date: Tue, 6 Jul 2021 22:54:15 -0400 Subject: [PATCH 1445/2234] Fix space inconsistency --- notify/sendgrid.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/sendgrid.sh b/notify/sendgrid.sh index ea4dcc93..82d3f6c6 100644 --- a/notify/sendgrid.sh +++ b/notify/sendgrid.sh @@ -44,7 +44,7 @@ sendgrid_send() { export _H2="Content-Type: application/json" _content="$(echo "$_content" | _json_encode)" - + if [ -z "$SENDGRID_FROM_NAME" ]; then _data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}" else From ac9993394c51409c22bb300c02f631bd8915022a Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 11 Jul 2021 21:58:47 +0800 Subject: [PATCH 1446/2234] update --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c7f7e677..91a18985 100644 --- a/README.md +++ b/README.md @@ -20,18 +20,18 @@ - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. -- Support ACME v1 and ACME v2 -- Support ACME v2 wildcard certs +- Support ECDSA certs +- Support SAN and wildcard certs - Simple, powerful and very easy to use. You only need 3 minutes to learn it. - Bash, dash and sh compatible. -- Purely written in Shell with no dependencies on python or the official Let's Encrypt client. +- Purely written in Shell with no dependencies on python. - Just one script to issue, renew and install your certificates automatically. - DOES NOT require `root/sudoer` access. -- Docker friendly -- IPv6 support +- Docker ready +- IPv6 ready - Cron job notifications for renewal or error etc. -It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt. +It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates. Wiki: https://github.com/acmesh-official/acme.sh/wiki From 98ef51514f59da72fcb8f4f2c2be563252c77848 Mon Sep 17 00:00:00 2001 From: ciro Date: Sun, 11 Jul 2021 20:29:44 -0300 Subject: [PATCH 1447/2234] added pushbullet functionality --- notify/pushbullet.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 notify/pushbullet.sh diff --git a/notify/pushbullet.sh b/notify/pushbullet.sh new file mode 100644 index 00000000..44461d25 --- /dev/null +++ b/notify/pushbullet.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env sh + +#Support for pushbullet.com's api. Push notification, notification sync and message platform for multiple platforms +#PUSHBULLET_TOKEN="" Required, pushbullet application token +#PUSHBULLET_DEVICE="" Optional, Specific device, ignore to send to all devices + +PUSHBULLET_URI="https://api.pushbullet.com/v2/pushes" +pushbullet_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + PUSHBULLET_TOKEN="${PUSHBULLET_TOKEN:-$(_readaccountconf_mutable PUSHBULLET_TOKEN)}" + if [ -z "$PUSHBULLET_TOKEN" ]; then + PUSHBULLET_TOKEN="" + _err "You didn't specify a Pushbullet application token yet." + return 1 + fi + _saveaccountconf_mutable PUSHBULLET_TOKEN "$PUSHBULLET_TOKEN" + + PUSHBULLET_DEVICE="${PUSHBULLET_DEVICE:-$(_readaccountconf_mutable PUSHBULLET_DEVICE)}" + if [ -z "$PUSHBULLET_DEVICE" ]; then + _saveaccountconf_mutable PUSHBULLET_TOKEN "$PUSHBULLET_TOKEN" + fi + + export _H1="Content-Type: application/json" + export _H2="Access-Token: ${PUSHBULLET_TOKEN}" + _content="$(printf "*%s*\n" "$_content" | _json_encode)" + _subject="$(printf "*%s*\n" "$_subject" | _json_encode)" + _data="{\"type\": \"note\",\"title\": \"${_subject}\",\"body\": \"${_content}\",\"device_iden\": \"${PUSHBULLET_DEVICE}\"}" + response="$(_post "$_data" "$PUSHBULLET_URI")" + + if [ "$?" != "0" ] || _contains "$response" "\"error_code\""; then + _err "PUSHBULLET send error." + _err "$response" + return 1 + fi + + _info "PUSHBULLET send success." + return 0 +} From dcc50093bb96df781c82708bf53233711287c63a Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 12 Jul 2021 21:46:08 +0800 Subject: [PATCH 1448/2234] fix https://github.com/acmesh-official/acme.sh/issues/3600 --- acme.sh | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/acme.sh b/acme.sh index 4b20b708..c57cd2ad 100755 --- a/acme.sh +++ b/acme.sh @@ -4712,26 +4712,13 @@ $_authorizations_map" return 1 fi - _debug "sleep 2 secs to verify" - sleep 2 - _debug "checking" - - _send_signed_request "$uri" - - if [ "$?" != "0" ]; then - _err "$d:Verify error:$response" - _clearupwebbroot "$_currentRoot" "$removelevel" "$token" - _clearup - _on_issue_err "$_post_hook" "$vlist" - return 1 - fi _debug2 original "$response" response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"') - + _debug2 status "$status" if _contains "$status" "invalid"; then error="$(echo "$response" | _egrep_o '"error":\{[^\}]*')" _debug2 error "$error" @@ -4773,7 +4760,19 @@ $_authorizations_map" _on_issue_err "$_post_hook" "$vlist" return 1 fi + _debug "sleep 2 secs to verify again" + sleep 2 + _debug "checking" + _send_signed_request "$uri" + + if [ "$?" != "0" ]; then + _err "$d:Verify error:$response" + _clearupwebbroot "$_currentRoot" "$removelevel" "$token" + _clearup + _on_issue_err "$_post_hook" "$vlist" + return 1 + fi done done From ae3dda0f8fc3071495cd1e8dff0fe4a339febb1c Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 15 Jul 2021 22:21:32 +0800 Subject: [PATCH 1449/2234] add retry for get() and post() --- acme.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index c57cd2ad..4ddc7501 100755 --- a/acme.sh +++ b/acme.sh @@ -1768,7 +1768,7 @@ _inithttp() { if [ -z "$ACME_HTTP_NO_REDIRECTS" ]; then _ACME_CURL="$_ACME_CURL -L " fi - if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then + if [ "$DEBUG" ] && [ "$DEBUG" -ge 2 ]; then _CURL_DUMP="$(_mktemp)" _ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP " fi @@ -1808,6 +1808,8 @@ _inithttp() { } +_HTTP_MAX_RETRY=8 + # body url [needbase64] [POST|PUT|DELETE] [ContentType] _post() { body="$1" @@ -1815,6 +1817,33 @@ _post() { needbase64="$3" httpmethod="$4" _postContentType="$5" + _sleep_retry_sec=1 + _http_retry_times=0 + _hcode=0 + while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do + [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] + _lastHCode="$?" + _debug "Retrying post" + _post_impl "$body" "$_post_url" "$needbase64" "$httpmethod" "$_postContentType" "$_lastHCode"; + _hcode="$?" + _debug _hcode "$_hcode" + if [ "$_hcode" = "0" ]; then + break; + fi + _http_retry_times=$(_math $_http_retry_times + 1) + _sleep $_sleep_retry_sec + done + return $_hcode +} + +# body url [needbase64] [POST|PUT|DELETE] [ContentType] [displayError] +_post_impl() { + body="$1" + _post_url="$2" + needbase64="$3" + httpmethod="$4" + _postContentType="$5" + displayError="$6" if [ -z "$httpmethod" ]; then httpmethod="POST" @@ -1866,7 +1895,9 @@ _post() { fi _ret="$?" if [ "$_ret" != "0" ]; then - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" + if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then + _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" + fi if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _err "Here is the curl dump log:" _err "$(cat "$_CURL_DUMP")" @@ -1922,7 +1953,9 @@ _post() { _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." fi if [ "$_ret" != "0" ]; then - _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" + if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then + _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" + fi fi _sed_i "s/^ *//g" "$HTTP_HEADER" else @@ -1936,13 +1969,38 @@ _post() { # url getheader timeout _get() { + url="$1" + onlyheader="$2" + t="$3" + _sleep_retry_sec=1 + _http_retry_times=0 + _hcode=0 + while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do + [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] + _lastHCode="$?" + _debug "Retrying GET" + _get_impl "$url" "$onlyheader" "$t" "$_lastHCode"; + _hcode="$?" + _debug _hcode "$_hcode" + if [ "$_hcode" = "0" ]; then + break; + fi + _http_retry_times=$(_math $_http_retry_times + 1) + _sleep $_sleep_retry_sec + done + return $_hcode +} + +# url getheader timeout displayError +_get_impl() { _debug GET url="$1" onlyheader="$2" t="$3" + displayError="$4" _debug url "$url" _debug "timeout=$t" - + _debug "displayError" "$displayError" _inithttp if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then @@ -1961,7 +2019,9 @@ _get() { fi ret=$? if [ "$ret" != "0" ]; then - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" + if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then + _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" + fi if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _err "Here is the curl dump log:" _err "$(cat "$_CURL_DUMP")" @@ -1987,7 +2047,9 @@ _get() { _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." fi if [ "$ret" != "0" ]; then - _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret" + if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then + _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret" + fi fi else ret=$? From d70b759cb9c5b413cce92e65e841a54a65813962 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 15 Jul 2021 22:47:20 +0800 Subject: [PATCH 1450/2234] format --- acme.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 4ddc7501..47b0e4d2 100755 --- a/acme.sh +++ b/acme.sh @@ -1824,11 +1824,11 @@ _post() { [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] _lastHCode="$?" _debug "Retrying post" - _post_impl "$body" "$_post_url" "$needbase64" "$httpmethod" "$_postContentType" "$_lastHCode"; + _post_impl "$body" "$_post_url" "$needbase64" "$httpmethod" "$_postContentType" "$_lastHCode" _hcode="$?" _debug _hcode "$_hcode" if [ "$_hcode" = "0" ]; then - break; + break fi _http_retry_times=$(_math $_http_retry_times + 1) _sleep $_sleep_retry_sec @@ -1979,11 +1979,11 @@ _get() { [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] _lastHCode="$?" _debug "Retrying GET" - _get_impl "$url" "$onlyheader" "$t" "$_lastHCode"; + _get_impl "$url" "$onlyheader" "$t" "$_lastHCode" _hcode="$?" _debug _hcode "$_hcode" if [ "$_hcode" = "0" ]; then - break; + break fi _http_retry_times=$(_math $_http_retry_times + 1) _sleep $_sleep_retry_sec From c7ca9d7e36a2a240a5a25f60d3e7f9d9daefc3b2 Mon Sep 17 00:00:00 2001 From: ciro Date: Thu, 15 Jul 2021 22:55:35 -0300 Subject: [PATCH 1451/2234] fix shfmt issues --- notify/pushbullet.sh | 56 ++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/notify/pushbullet.sh b/notify/pushbullet.sh index 44461d25..0a638745 100644 --- a/notify/pushbullet.sh +++ b/notify/pushbullet.sh @@ -6,37 +6,37 @@ PUSHBULLET_URI="https://api.pushbullet.com/v2/pushes" pushbullet_send() { - _subject="$1" - _content="$2" - _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped - _debug "_statusCode" "$_statusCode" + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" - PUSHBULLET_TOKEN="${PUSHBULLET_TOKEN:-$(_readaccountconf_mutable PUSHBULLET_TOKEN)}" - if [ -z "$PUSHBULLET_TOKEN" ]; then - PUSHBULLET_TOKEN="" - _err "You didn't specify a Pushbullet application token yet." - return 1 - fi + PUSHBULLET_TOKEN="${PUSHBULLET_TOKEN:-$(_readaccountconf_mutable PUSHBULLET_TOKEN)}" + if [ -z "$PUSHBULLET_TOKEN" ]; then + PUSHBULLET_TOKEN="" + _err "You didn't specify a Pushbullet application token yet." + return 1 + fi + _saveaccountconf_mutable PUSHBULLET_TOKEN "$PUSHBULLET_TOKEN" + + PUSHBULLET_DEVICE="${PUSHBULLET_DEVICE:-$(_readaccountconf_mutable PUSHBULLET_DEVICE)}" + if [ -z "$PUSHBULLET_DEVICE" ]; then _saveaccountconf_mutable PUSHBULLET_TOKEN "$PUSHBULLET_TOKEN" + fi - PUSHBULLET_DEVICE="${PUSHBULLET_DEVICE:-$(_readaccountconf_mutable PUSHBULLET_DEVICE)}" - if [ -z "$PUSHBULLET_DEVICE" ]; then - _saveaccountconf_mutable PUSHBULLET_TOKEN "$PUSHBULLET_TOKEN" - fi + export _H1="Content-Type: application/json" + export _H2="Access-Token: ${PUSHBULLET_TOKEN}" + _content="$(printf "*%s*\n" "$_content" | _json_encode)" + _subject="$(printf "*%s*\n" "$_subject" | _json_encode)" + _data="{\"type\": \"note\",\"title\": \"${_subject}\",\"body\": \"${_content}\",\"device_iden\": \"${PUSHBULLET_DEVICE}\"}" + response="$(_post "$_data" "$PUSHBULLET_URI")" - export _H1="Content-Type: application/json" - export _H2="Access-Token: ${PUSHBULLET_TOKEN}" - _content="$(printf "*%s*\n" "$_content" | _json_encode)" - _subject="$(printf "*%s*\n" "$_subject" | _json_encode)" - _data="{\"type\": \"note\",\"title\": \"${_subject}\",\"body\": \"${_content}\",\"device_iden\": \"${PUSHBULLET_DEVICE}\"}" - response="$(_post "$_data" "$PUSHBULLET_URI")" + if [ "$?" != "0" ] || _contains "$response" "\"error_code\""; then + _err "PUSHBULLET send error." + _err "$response" + return 1 + fi - if [ "$?" != "0" ] || _contains "$response" "\"error_code\""; then - _err "PUSHBULLET send error." - _err "$response" - return 1 - fi - - _info "PUSHBULLET send success." - return 0 + _info "PUSHBULLET send success." + return 0 } From 4a8511f68009826f0b56302df3e9faff3a64106c Mon Sep 17 00:00:00 2001 From: ciro Date: Sat, 17 Jul 2021 13:50:45 -0300 Subject: [PATCH 1452/2234] fix wrong variable name --- notify/pushbullet.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/pushbullet.sh b/notify/pushbullet.sh index 0a638745..6f33b44f 100644 --- a/notify/pushbullet.sh +++ b/notify/pushbullet.sh @@ -21,7 +21,7 @@ pushbullet_send() { PUSHBULLET_DEVICE="${PUSHBULLET_DEVICE:-$(_readaccountconf_mutable PUSHBULLET_DEVICE)}" if [ -z "$PUSHBULLET_DEVICE" ]; then - _saveaccountconf_mutable PUSHBULLET_TOKEN "$PUSHBULLET_TOKEN" + _saveaccountconf_mutable PUSHBULLET_DEVICE "$PUSHBULLET_DEVICE" fi export _H1="Content-Type: application/json" From 103810ce2091a2d0e907062033f12b06ec615d62 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 20 Jul 2021 21:05:17 +0800 Subject: [PATCH 1453/2234] add info --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 47b0e4d2..d9e7136a 100755 --- a/acme.sh +++ b/acme.sh @@ -4812,9 +4812,9 @@ $_authorizations_map" fi if [ "$status" = "pending" ]; then - _info "Pending" + _info "Pending, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)" elif [ "$status" = "processing" ]; then - _info "Processing" + _info "Processing, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)" else _err "$d:Verify error:$response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" From 63165764dcc7084750cb537b8563671fbc655b74 Mon Sep 17 00:00:00 2001 From: Ivanovitch_k Date: Thu, 22 Jul 2021 00:09:44 +0200 Subject: [PATCH 1454/2234] dns_ovh: fix random add/remove txt records failures due to inconsistent curl api response json --- dnsapi/dns_ovh.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index f6f9689a..b2c646fa 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -261,7 +261,9 @@ _get_root() { return 1 fi - if ! _contains "$response" "This service does not exist" >/dev/null && ! _contains "$response" "NOT_GRANTED_CALL" >/dev/null; then + if ! _contains "$response" "This service does not exist" >/dev/null && \ + ! _contains "$response" "This call has not been granted" >/dev/null && \ + ! _contains "$response" "NOT_GRANTED_CALL" >/dev/null; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" return 0 From 08438608d1e727cbbcaa311057c107c22f21a171 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 24 Jul 2021 15:46:58 +0800 Subject: [PATCH 1455/2234] fix format --- dnsapi/dns_ovh.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index b2c646fa..e65babbd 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -261,9 +261,9 @@ _get_root() { return 1 fi - if ! _contains "$response" "This service does not exist" >/dev/null && \ - ! _contains "$response" "This call has not been granted" >/dev/null && \ - ! _contains "$response" "NOT_GRANTED_CALL" >/dev/null; then + if ! _contains "$response" "This service does not exist" >/dev/null && + ! _contains "$response" "This call has not been granted" >/dev/null && + ! _contains "$response" "NOT_GRANTED_CALL" >/dev/null; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" return 0 From 655e34b166d89cef80e3a14c48d1e52b3ea9fb43 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 24 Jul 2021 16:23:30 +0800 Subject: [PATCH 1456/2234] minor, clean links for renewal --- acme.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/acme.sh b/acme.sh index d9e7136a..8ded1465 100755 --- a/acme.sh +++ b/acme.sh @@ -4207,6 +4207,10 @@ issue() { if [ -z "$_ACME_IS_RENEW" ]; then _initpath "$_main_domain" "$_key_length" mkdir -p "$DOMAIN_PATH" + else + Le_OrderFinalize="" + Le_LinkOrder="" + Le_LinkCert="" fi if _hasfield "$_web_roots" "$W_DNS" && [ -z "$FORCE_DNS_MANUAL" ]; then From 5cc1d9521cb33619d244d13dd2e646ee41e0410a Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 28 Jul 2021 22:14:54 +0800 Subject: [PATCH 1457/2234] fix https://github.com/acmesh-official/acme.sh/issues/3624#issuecomment-887689325 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 8ded1465..b2398c5d 100755 --- a/acme.sh +++ b/acme.sh @@ -3441,7 +3441,7 @@ _on_before_issue() { _netprc="$(_ss "$_checkport" | grep "$_checkport")" netprc="$(echo "$_netprc" | grep "$_checkaddr")" if [ -z "$netprc" ]; then - netprc="$(echo "$_netprc" | grep "$LOCAL_ANY_ADDRESS")" + netprc="$(echo "$_netprc" | grep "$LOCAL_ANY_ADDRESS:$_checkport")" fi if [ "$netprc" ]; then _err "$netprc" From 89abad798003362a8ec4f0f1866f2190993deba1 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 1 Aug 2021 13:11:52 +0800 Subject: [PATCH 1458/2234] fix https://github.com/acmesh-official/acme.sh/issues/3635 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index b2398c5d..0028164a 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.0 +VER=3.0.1 PROJECT_NAME="acme.sh" @@ -4207,7 +4207,7 @@ issue() { if [ -z "$_ACME_IS_RENEW" ]; then _initpath "$_main_domain" "$_key_length" mkdir -p "$DOMAIN_PATH" - else + elif ! _hasfield "$_web_roots" "$W_DNS"; then Le_OrderFinalize="" Le_LinkOrder="" Le_LinkCert="" From 2b5e2d4760d7c3ec36f5af33dfa95d9077cd5966 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 1 Aug 2021 15:44:14 +0800 Subject: [PATCH 1459/2234] fix nginx mode --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 0028164a..c0986c72 100755 --- a/acme.sh +++ b/acme.sh @@ -3161,14 +3161,14 @@ _checkConf() { FOUND_REAL_NGINX_CONF="$2" return 0 fi - if cat "$2" | tr "\t" " " | grep "^ *include *.*;" >/dev/null; then + if cat "$2" | tr "\t" " " | grep "^ *include *;" >/dev/null; then _debug "Try include files" - for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do + for included in $(cat "$2" | tr "\t" " " | grep "^ *include *;" | sed "s/include //" | tr -d " ;"); do _debug "check included $included" if ! _startswith "$included" "/" && _exists dirname; then _relpath="$(dirname "$_c_file")" _debug "_relpath" "$_relpath" - included="$_relpath/included" + included="$_relpath/$included" fi if _checkConf "$1" "$included"; then return 0 From ec678bc6d2095334f449b25298cfd029ce4ace74 Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Tue, 3 Aug 2021 01:36:59 +0800 Subject: [PATCH 1460/2234] Correct a typo in 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 068c337c..14a4594d 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -32,7 +32,7 @@ dns_aws_add() { if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then AWS_ACCESS_KEY_ID="" AWS_SECRET_ACCESS_KEY="" - _err "You haven't specifed the aws route53 api key id and and api key secret yet." + _err "You haven't specified the aws route53 api key id and and api key secret yet." _err "Please create your key and try again. see $(__green $AWS_WIKI)" return 1 fi From 6b97dc67349671450833450fd26449fb48450bbc Mon Sep 17 00:00:00 2001 From: jonwltn <86822083+jonwltn@users.noreply.github.com> Date: Wed, 4 Aug 2021 10:44:48 -0700 Subject: [PATCH 1461/2234] Minor output formatting changes. --- acme.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index c0986c72..9bc962d8 100755 --- a/acme.sh +++ b/acme.sh @@ -4984,10 +4984,10 @@ $_authorizations_map" _info "$(__green "Cert success.")" cat "$CERT_PATH" - _info "Your cert is in $(__green " $CERT_PATH ")" + _info "Your cert is in: $(__green "$CERT_PATH")" if [ -f "$CERT_KEY_PATH" ]; then - _info "Your cert key is in $(__green " $CERT_KEY_PATH ")" + _info "Your cert key is in: $(__green "$CERT_KEY_PATH")" fi if [ ! "$USER_PATH" ] || [ ! "$_ACME_IN_CRON" ]; then @@ -4996,8 +4996,8 @@ $_authorizations_map" fi fi - [ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in $(__green " $CA_CERT_PATH ")" - [ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green " $CERT_FULLCHAIN_PATH ")" + [ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in: $(__green "$CA_CERT_PATH")" + [ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green "$CERT_FULLCHAIN_PATH")" Le_CertCreateTime=$(_time) _savedomainconf "Le_CertCreateTime" "$Le_CertCreateTime" @@ -5541,7 +5541,7 @@ _installcert() { mkdir -p "$_backup_path" if [ "$_real_cert" ]; then - _info "Installing cert to:$_real_cert" + _info "Installing cert to: $_real_cert" if [ -f "$_real_cert" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_cert" "$_backup_path/cert.bak" fi @@ -5549,7 +5549,7 @@ _installcert() { fi if [ "$_real_ca" ]; then - _info "Installing CA to:$_real_ca" + _info "Installing CA to: $_real_ca" if [ "$_real_ca" = "$_real_cert" ]; then echo "" >>"$_real_ca" cat "$CA_CERT_PATH" >>"$_real_ca" || return 1 @@ -5562,7 +5562,7 @@ _installcert() { fi if [ "$_real_key" ]; then - _info "Installing key to:$_real_key" + _info "Installing key to: $_real_key" if [ -f "$_real_key" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_key" "$_backup_path/key.bak" fi @@ -5575,7 +5575,7 @@ _installcert() { fi if [ "$_real_fullchain" ]; then - _info "Installing full chain to:$_real_fullchain" + _info "Installing full chain to: $_real_fullchain" if [ -f "$_real_fullchain" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_fullchain" "$_backup_path/fullchain.bak" fi From 06580bf0e457fafb63fdd2e7aa8fad36dfb86d35 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 5 Aug 2021 20:12:42 +0800 Subject: [PATCH 1462/2234] fix https://github.com/acmesh-official/acme.sh/issues/1914#issuecomment-893188476 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 9bc962d8..2459404a 100755 --- a/acme.sh +++ b/acme.sh @@ -3161,9 +3161,9 @@ _checkConf() { FOUND_REAL_NGINX_CONF="$2" return 0 fi - if cat "$2" | tr "\t" " " | grep "^ *include *;" >/dev/null; then + if cat "$2" | tr "\t" " " | grep "^ *include +.*;" >/dev/null; then _debug "Try include files" - for included in $(cat "$2" | tr "\t" " " | grep "^ *include *;" | sed "s/include //" | tr -d " ;"); do + for included in $(cat "$2" | tr "\t" " " | grep "^ *include +.*;" | sed "s/include //" | tr -d " ;"); do _debug "check included $included" if ! _startswith "$included" "/" && _exists dirname; then _relpath="$(dirname "$_c_file")" From 5a44e63caddd9fe7b6b039b80a2a78f0d0a39dd9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 6 Aug 2021 21:22:10 +0800 Subject: [PATCH 1463/2234] fix nginx mode https://github.com/acmesh-official/acme.sh/issues/3648#issuecomment-894045613 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 2459404a..b7284db7 100755 --- a/acme.sh +++ b/acme.sh @@ -3161,9 +3161,9 @@ _checkConf() { FOUND_REAL_NGINX_CONF="$2" return 0 fi - if cat "$2" | tr "\t" " " | grep "^ *include +.*;" >/dev/null; then + if cat "$2" | tr "\t" " " | grep "^ *include *.*;" >/dev/null; then _debug "Try include files" - for included in $(cat "$2" | tr "\t" " " | grep "^ *include +.*;" | sed "s/include //" | tr -d " ;"); do + for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do _debug "check included $included" if ! _startswith "$included" "/" && _exists dirname; then _relpath="$(dirname "$_c_file")" From ccfd907914dad2530b52a1708b52e4a4248561d0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 7 Aug 2021 21:06:05 +0800 Subject: [PATCH 1464/2234] fix https://github.com/acmesh-official/acme.sh/issues/3649 --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index b7284db7..27b769ae 100755 --- a/acme.sh +++ b/acme.sh @@ -20,6 +20,8 @@ _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" @@ -5108,7 +5110,7 @@ renew() { . "$DOMAIN_CONF" _debug Le_API "$Le_API" - if [ -z "$Le_API" ]; then + 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" From 72e3f33f287a2da93cbc7d716290996c83f9ffd7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 8 Aug 2021 08:49:15 +0800 Subject: [PATCH 1465/2234] fix docker test --- .github/workflows/DNS.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index b00ef263..13066fdd 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -61,22 +61,22 @@ jobs: run: | cd ../acmetest if [ "${{ secrets.TokenName1}}" ] ; then - echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> env.list + echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env fi if [ "${{ secrets.TokenName2}}" ] ; then - echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> env.list + echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env fi if [ "${{ secrets.TokenName3}}" ] ; then - echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> env.list + echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env fi if [ "${{ secrets.TokenName4}}" ] ; then - echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> env.list + echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env fi if [ "${{ secrets.TokenName5}}" ] ; then - echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list + echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env fi - echo "TEST_DNS_NO_WILDCARD" >> env.list - echo "TEST_DNS_SLEEP" >> env.list + echo "TEST_DNS_NO_WILDCARD" >> docker.env + echo "TEST_DNS_SLEEP" >> docker.env - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall From e164362069001387d93229106e706fab959a3699 Mon Sep 17 00:00:00 2001 From: Bernard Spil Date: Tue, 10 Aug 2021 12:36:29 +0200 Subject: [PATCH 1466/2234] Make domain names available to pre hook Export Le_Domains and Le_Alt so your pre-hook script can run additional checks. Allows running checks on the domain names before the first call to the ACME API. Thereby not counting against the rate-limit when an issue is going to be problematic. Supersedes: #3288 --- acme.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acme.sh b/acme.sh index 27b769ae..d08a0b06 100755 --- a/acme.sh +++ b/acme.sh @@ -3382,6 +3382,8 @@ _on_before_issue() { if [ "$_chk_pre_hook" ]; then _info "Run pre hook:'$_chk_pre_hook'" if ! ( + export Le_Domain="$_chk_main_domain" + export Le_Alt="$_chk_alt_domains" cd "$DOMAIN_PATH" && eval "$_chk_pre_hook" ); then _err "Error when run pre hook." From 6bdf689d0f14e27fe41a3064d98a57d9a61c7565 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 15 Aug 2021 08:52:55 +0800 Subject: [PATCH 1467/2234] fix https://github.com/acmesh-official/acme.sh/issues/3660 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 27b769ae..3567900e 100755 --- a/acme.sh +++ b/acme.sh @@ -5745,7 +5745,7 @@ uninstallcronjob() { _info "Removing cron job" cr="$($_CRONTAB -l | grep "$PROJECT_ENTRY --cron")" if [ "$cr" ]; then - if _exists uname && uname -a | grep solaris >/dev/null; then + if _exists uname && uname -a | grep SunOS >/dev/null; then $_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB -- else $_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB - From 83cb89e4f741b0d160cd9776e625d6d17e3b5af6 Mon Sep 17 00:00:00 2001 From: Aleksei Faians Date: Tue, 17 Aug 2021 08:58:04 +0300 Subject: [PATCH 1468/2234] treat variable contents as text, don't process switches --- dnsapi/dns_he.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index ef09fa0a..bf4a5030 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -85,7 +85,7 @@ dns_he_rm() { _debug "The txt record is not found, just skip" return 0 fi - _record_id="$(echo "$response" | tr -d "#" | sed "s/ Date: Wed, 18 Aug 2021 20:59:47 +0800 Subject: [PATCH 1469/2234] remove clearlinux --- .github/workflows/Linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index c4ec07c4..7e7eba87 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -20,7 +20,7 @@ jobs: Linux: strategy: matrix: - os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3-amd64", "clearlinux:latest"] + os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3-amd64"] runs-on: ubuntu-latest env: TEST_LOCAL: 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 1470/2234] 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 20d23fcb92bcc58360089b8e0f3208c8291602aa Mon Sep 17 00:00:00 2001 From: fradev Date: Wed, 25 Aug 2021 16:55:36 +0200 Subject: [PATCH 1471/2234] Update ssh.sh Added scp mode for copy the certs --- deploy/ssh.sh | 237 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 205 insertions(+), 32 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 18de4aa6..b4a8140e 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -23,6 +23,8 @@ # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value # export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy # export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value +# export DEPLOY_SSH_USE_SCP="" yes or no , default to no +# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -T -q " # ######## Public functions ##################### @@ -73,6 +75,25 @@ ssh_deploy() { Le_Deploy_ssh_cmd="ssh -T" fi + # USE_SCP is optional. If not provided then default to previously saved + # value (which may be undefined... equivalent to "no"). + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + Le_Deploy_ssh_use_scp="yes" + _savedomainconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" + elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then + Le_Deploy_ssh_use_scp="" + _cleardomainconf Le_Deploy_ssh_use_scp + fi + + # SCP_CMD is optional. If not provided then use scp + if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then + Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" + _savedomainconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" + elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then + Le_Deploy_ssh_scp_cmd="scp -T" + fi + + # BACKUP is optional. If not provided then default to previously saved value or yes. if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then Le_Deploy_ssh_backup="no" @@ -99,6 +120,26 @@ ssh_deploy() { _cleardomainconf Le_Deploy_ssh_multi_call fi + # USE_SCP is optional. If not provided then default to previously saved + # value (which may be undefined... equivalent to "no"). + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + Le_Deploy_ssh_use_scp="yes" + _savedomainconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" + Le_Deploy_ssh_multi_call="yes" + _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then + Le_Deploy_ssh_use_scp="" + _cleardomainconf Le_Deploy_ssh_use_scp + fi + + # SCP_CMD is optional. If not provided then use scp + if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then + Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" + _savedomainconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" + elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then + Le_Deploy_ssh_scp_cmd="scp -T -q " + fi + _deploy_ssh_servers=$Le_Deploy_ssh_server for Le_Deploy_ssh_server in $_deploy_ssh_servers; do _ssh_deploy @@ -110,8 +151,16 @@ _ssh_deploy() { _cmdstr="" _backupprefix="" _backupdir="" + _local_cert_file="" + _local_ca_file="" + _local_full_file="" _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + _info "Using scp as alternate method for copying files. Multicall Mode is implicit" + Le_Deploy_ssh_multi_call="yes" + _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + fi if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" else @@ -149,15 +198,30 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_keyfile $_backupdir >/dev/null;" - fi - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" - _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi + fi + + + # copy new key into file. + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + # scp the file + if ! _scp_remote_cmd "$_ckey" "$Le_Deploy_ssh_keyfile"; then + return $_err_code + fi + else + _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" + _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" fi - _cmdstr="" fi fi @@ -172,18 +236,40 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ "$Le_Deploy_ssh_certfile" = "$Le_Deploy_ssh_keyfile" ]; then # if filename is same as previous file then append. _pipe=">>" + _local_cert_file=$(_mktemp) + cat $_ckey > $_local_cert_file + cat $_ccert >> $_local_cert_file elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;" - fi - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" - _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi + fi + + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + if -n $_local_cert_file ; then + if ! _scp_remote_cmd "$_local_cert_file" "$Le_Deploy_ssh_certfile"; then + return $_err_code + fi + else + if ! _scp_remote_cmd "$_ccert" "$Le_Deploy_ssh_certfile"; then + return $_err_code + fi + fi + else + # copy new certificate into file. + _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" + _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" fi - _cmdstr="" fi fi @@ -199,18 +285,47 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then # if filename is same as previous file then append. _pipe=">>" + _local_ca_file=$(_mktemp) + if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ; then + cat $_ckey >> $_local_ca_file + fi + if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then + cat $_ccert >> $_local_ca_file + fi + + cat $_cca >> $_local_ca_file + elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_cafile $_backupdir >/dev/null;" - fi - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" - _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi + fi + + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + if -n $_local_ca_file ; then + if ! _scp_remote_cmd "$_local_ca_file" "$Le_Deploy_ssh_cafile"; then + return $_err_code + fi + else + if ! _scp_remote_cmd "$_cca" "$Le_Deploy_ssh_cafile"; then + return $_err_code + fi + fi + else + # copy new certificate into file. + _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" + _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" fi - _cmdstr="" fi fi @@ -227,20 +342,63 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then # if filename is same as previous file then append. _pipe=">>" + _local_full_file=$(_mktemp) + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ; then + cat $_ckey >> $_local_full_file + fi + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ]; then + cat $_ccert >> $_local_full_file + fi + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then + cat $_cca >> $_local_full_file + fi + cat $_cfullchain >> $_local_full_file + elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_fullchain $_backupdir >/dev/null;" - fi - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" - _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi + fi + + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + if -n $_local_full_file ; then + if ! _scp_remote_cmd "$_local_full_file" "$Le_Deploy_ssh_fullchain"; then + return $_err_code + fi + else + if ! _scp_remote_cmd "$_cfullchain" "$Le_Deploy_ssh_fullchain"; then + return $_err_code + fi + fi + else + # copy new certificate into file. + _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" + _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" fi - _cmdstr="" fi fi + # cleanup local files if any + + if [ -n "$_local_cert_file" ]; then + rm $_local_cert_file > /dev/null 1>&2 + fi + if [ -n "$_local_ca_file" ]; then + rm $_local_ca_file > /dev/null 1>&2 + fi + if [ -n "$_local_full_file" ]; then + rm $_local_full_file > /dev/null 1>&2 + fi + # REMOTE_CMD is optional. # If provided then this command will be executed on remote host. @@ -265,6 +423,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d return $_err_code fi fi + # cleanup in case all is ok return 0 } @@ -284,3 +443,17 @@ _ssh_remote_cmd() { return $_err_code } + +# cmd scp +_scp_remote_cmd() { + _secure_debug "Remote scp source $1 and destination $2 using : $Le_Deploy_ssh_scp_cmd" + _info "Submitting secure copy command : $Le_Deploy_ssh_scp_cmd" + $Le_Deploy_ssh_scp_cmd "$1" "$Le_Deploy_ssh_user"@"$Le_Deploy_ssh_server":"$2" + _err_code="$?" + + if [ "$_err_code" != "0" ]; then + _err "Error code $_err_code returned from scp" + fi + + return $_err_code +} From 613475ac264bf9cf48681bd11f72b4d2aa341e54 Mon Sep 17 00:00:00 2001 From: fradev Date: Mon, 30 Aug 2021 11:08:06 +0200 Subject: [PATCH 1472/2234] Update ssh.sh --- deploy/ssh.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index b4a8140e..3424055f 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -237,8 +237,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # if filename is same as previous file then append. _pipe=">>" _local_cert_file=$(_mktemp) - cat $_ckey > $_local_cert_file - cat $_ccert >> $_local_cert_file + cat "$_ckey" > "$_local_cert_file" + cat "$_ccert" >> "$_local_cert_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;" @@ -344,15 +344,15 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _pipe=">>" _local_full_file=$(_mktemp) if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ; then - cat $_ckey >> $_local_full_file + cat "$_ckey" >> "$_local_full_file" fi if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ]; then - cat $_ccert >> $_local_full_file + cat "$_ccert" >> "$_local_full_file" fi if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then - cat $_cca >> $_local_full_file + cat "$_cca" >> "$_local_full_file" fi - cat $_cfullchain >> $_local_full_file + cat "$_cfullchain" >> "$_local_full_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. @@ -390,13 +390,13 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # cleanup local files if any if [ -n "$_local_cert_file" ]; then - rm $_local_cert_file > /dev/null 1>&2 + rm "$_local_cert_file" > /dev/null 1>&2 fi if [ -n "$_local_ca_file" ]; then - rm $_local_ca_file > /dev/null 1>&2 + rm "$_local_ca_file" > /dev/null 1>&2 fi if [ -n "$_local_full_file" ]; then - rm $_local_full_file > /dev/null 1>&2 + rm "$_local_full_file" > /dev/null 1>&2 fi From 4cda54774aeaae0f58352cff18dc243a69bdb9e9 Mon Sep 17 00:00:00 2001 From: fradev Date: Mon, 30 Aug 2021 11:17:03 +0200 Subject: [PATCH 1473/2234] Update ssh.sh SC2086 and SC2215 --- deploy/ssh.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 3424055f..8b91a055 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -251,7 +251,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if -n $_local_cert_file ; then + if [ -n "$_local_cert_file" ]; then if ! _scp_remote_cmd "$_local_cert_file" "$Le_Deploy_ssh_certfile"; then return $_err_code fi @@ -287,13 +287,13 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _pipe=">>" _local_ca_file=$(_mktemp) if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ; then - cat $_ckey >> $_local_ca_file + cat "$_ckey" >> "$_local_ca_file" fi if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then - cat $_ccert >> $_local_ca_file + cat "$_ccert" >> "$_local_ca_file" fi - cat $_cca >> $_local_ca_file + cat "$_cca" >> "$_local_ca_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. @@ -307,7 +307,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if -n $_local_ca_file ; then + if [ -n "$_local_ca_file" ]; then if ! _scp_remote_cmd "$_local_ca_file" "$Le_Deploy_ssh_cafile"; then return $_err_code fi @@ -366,7 +366,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if -n $_local_full_file ; then + if [ -n "$_local_full_file" ] ; then if ! _scp_remote_cmd "$_local_full_file" "$Le_Deploy_ssh_fullchain"; then return $_err_code fi From 08d60fcbf26172a3277a8785b9e161b8d1aa6c23 Mon Sep 17 00:00:00 2001 From: fradev Date: Mon, 30 Aug 2021 11:32:07 +0200 Subject: [PATCH 1474/2234] Update ssh.sh shfmt formatting --- deploy/ssh.sh | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 8b91a055..6039eefb 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -93,7 +93,6 @@ ssh_deploy() { Le_Deploy_ssh_scp_cmd="scp -T" fi - # BACKUP is optional. If not provided then default to previously saved value or yes. if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then Le_Deploy_ssh_backup="no" @@ -206,12 +205,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # copy new key into file. if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then # scp the file if ! _scp_remote_cmd "$_ckey" "$Le_Deploy_ssh_keyfile"; then - return $_err_code + return $_err_code fi else _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" @@ -237,8 +235,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # if filename is same as previous file then append. _pipe=">>" _local_cert_file=$(_mktemp) - cat "$_ckey" > "$_local_cert_file" - cat "$_ccert" >> "$_local_cert_file" + cat "$_ckey" >"$_local_cert_file" + cat "$_ccert" >>"$_local_cert_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;" @@ -253,11 +251,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then if [ -n "$_local_cert_file" ]; then if ! _scp_remote_cmd "$_local_cert_file" "$Le_Deploy_ssh_certfile"; then - return $_err_code + return $_err_code fi else if ! _scp_remote_cmd "$_ccert" "$Le_Deploy_ssh_certfile"; then - return $_err_code + return $_err_code fi fi else @@ -286,14 +284,14 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # if filename is same as previous file then append. _pipe=">>" _local_ca_file=$(_mktemp) - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ; then - cat "$_ckey" >> "$_local_ca_file" + if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ]; then + cat "$_ckey" >>"$_local_ca_file" fi if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then - cat "$_ccert" >> "$_local_ca_file" + cat "$_ccert" >>"$_local_ca_file" fi - cat "$_cca" >> "$_local_ca_file" + cat "$_cca" >>"$_local_ca_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. @@ -309,11 +307,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then if [ -n "$_local_ca_file" ]; then if ! _scp_remote_cmd "$_local_ca_file" "$Le_Deploy_ssh_cafile"; then - return $_err_code + return $_err_code fi else if ! _scp_remote_cmd "$_cca" "$Le_Deploy_ssh_cafile"; then - return $_err_code + return $_err_code fi fi else @@ -343,16 +341,16 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # if filename is same as previous file then append. _pipe=">>" _local_full_file=$(_mktemp) - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ; then - cat "$_ckey" >> "$_local_full_file" + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ]; then + cat "$_ckey" >>"$_local_full_file" fi if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ]; then - cat "$_ccert" >> "$_local_full_file" + cat "$_ccert" >>"$_local_full_file" fi if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then - cat "$_cca" >> "$_local_full_file" + cat "$_cca" >>"$_local_full_file" fi - cat "$_cfullchain" >> "$_local_full_file" + cat "$_cfullchain" >>"$_local_full_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. @@ -366,13 +364,13 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if [ -n "$_local_full_file" ] ; then + if [ -n "$_local_full_file" ]; then if ! _scp_remote_cmd "$_local_full_file" "$Le_Deploy_ssh_fullchain"; then - return $_err_code + return $_err_code fi else if ! _scp_remote_cmd "$_cfullchain" "$Le_Deploy_ssh_fullchain"; then - return $_err_code + return $_err_code fi fi else @@ -390,16 +388,15 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # cleanup local files if any if [ -n "$_local_cert_file" ]; then - rm "$_local_cert_file" > /dev/null 1>&2 + rm "$_local_cert_file" >/dev/null 1>&2 fi if [ -n "$_local_ca_file" ]; then - rm "$_local_ca_file" > /dev/null 1>&2 + rm "$_local_ca_file" >/dev/null 1>&2 fi if [ -n "$_local_full_file" ]; then - rm "$_local_full_file" > /dev/null 1>&2 + rm "$_local_full_file" >/dev/null 1>&2 fi - # REMOTE_CMD is optional. # If provided then this command will be executed on remote host. if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then From f354e6de69f66c23b67cc29dd84baac06d2fe5d6 Mon Sep 17 00:00:00 2001 From: Michael Weber Date: Sat, 6 Feb 2021 08:25:49 +0000 Subject: [PATCH 1475/2234] lighttpd deploy hook * verbatim copy from haproxy.sh, s/haproxy/lighttpd * enable issuer --- deploy/lighttpd.sh | 275 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 deploy/lighttpd.sh diff --git a/deploy/lighttpd.sh b/deploy/lighttpd.sh new file mode 100644 index 00000000..c003f455 --- /dev/null +++ b/deploy/lighttpd.sh @@ -0,0 +1,275 @@ +#!/usr/bin/env sh + +# Script for acme.sh to deploy certificates to lighttpd +# +# The following variables can be exported: +# +# export DEPLOY_LIGHTTPD_PEM_NAME="${domain}.pem" +# +# Defines the name of the PEM file. +# Defaults to ".pem" +# +# export DEPLOY_LIGHTTPD_PEM_PATH="/etc/lighttpd" +# +# Defines location of PEM file for Lighttpd. +# Defaults to /etc/lighttpd +# +# export DEPLOY_LIGHTTPD_RELOAD="systemctl reload lighttpd" +# +# OPTIONAL: Reload command used post deploy +# This defaults to be a no-op (ie "true"). +# It is strongly recommended to set this something that makes sense +# for your distro. +# +# export DEPLOY_LIGHTTPD_ISSUER="yes" +# +# OPTIONAL: Places CA file as "${DEPLOY_LIGHTTPD_PEM}.issuer" +# Note: Required for OCSP stapling to work +# +# export DEPLOY_LIGHTTPD_BUNDLE="no" +# +# OPTIONAL: Deploy this certificate as part of a multi-cert bundle +# This adds a suffix to the certificate based on the certificate type +# eg RSA certificates will have .rsa as a suffix to the file name +# Lighttpd will load all certificates and provide one or the other +# depending on client capabilities +# Note: This functionality requires Lighttpd was compiled against +# a version of OpenSSL that supports this. +# + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +lighttpd_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + # Some defaults + DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT="/etc/lighttpd" + DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT="${_cdomain}.pem" + DEPLOY_LIGHTTPD_BUNDLE_DEFAULT="no" + DEPLOY_LIGHTTPD_ISSUER_DEFAULT="yes" + DEPLOY_LIGHTTPD_RELOAD_DEFAULT="true" + + if [ -f "${DOMAIN_CONF}" ]; then + # shellcheck disable=SC1090 + . "${DOMAIN_CONF}" + fi + + _debug _cdomain "${_cdomain}" + _debug _ckey "${_ckey}" + _debug _ccert "${_ccert}" + _debug _cca "${_cca}" + _debug _cfullchain "${_cfullchain}" + + # PEM_PATH is optional. If not provided then assume "${DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT}" + if [ -n "${DEPLOY_LIGHTTPD_PEM_PATH}" ]; then + Le_Deploy_lighttpd_pem_path="${DEPLOY_LIGHTTPD_PEM_PATH}" + _savedomainconf Le_Deploy_lighttpd_pem_path "${Le_Deploy_lighttpd_pem_path}" + elif [ -z "${Le_Deploy_lighttpd_pem_path}" ]; then + Le_Deploy_lighttpd_pem_path="${DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT}" + fi + + # Ensure PEM_PATH exists + if [ -d "${Le_Deploy_lighttpd_pem_path}" ]; then + _debug "PEM_PATH ${Le_Deploy_lighttpd_pem_path} exists" + else + _err "PEM_PATH ${Le_Deploy_lighttpd_pem_path} does not exist" + return 1 + fi + + # PEM_NAME is optional. If not provided then assume "${DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT}" + if [ -n "${DEPLOY_LIGHTTPD_PEM_NAME}" ]; then + Le_Deploy_lighttpd_pem_name="${DEPLOY_LIGHTTPD_PEM_NAME}" + _savedomainconf Le_Deploy_lighttpd_pem_name "${Le_Deploy_lighttpd_pem_name}" + elif [ -z "${Le_Deploy_lighttpd_pem_name}" ]; then + Le_Deploy_lighttpd_pem_name="${DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT}" + fi + + # BUNDLE is optional. If not provided then assume "${DEPLOY_LIGHTTPD_BUNDLE_DEFAULT}" + if [ -n "${DEPLOY_LIGHTTPD_BUNDLE}" ]; then + Le_Deploy_lighttpd_bundle="${DEPLOY_LIGHTTPD_BUNDLE}" + _savedomainconf Le_Deploy_lighttpd_bundle "${Le_Deploy_lighttpd_bundle}" + elif [ -z "${Le_Deploy_lighttpd_bundle}" ]; then + Le_Deploy_lighttpd_bundle="${DEPLOY_LIGHTTPD_BUNDLE_DEFAULT}" + fi + + # ISSUER is optional. If not provided then assume "${DEPLOY_LIGHTTPD_ISSUER_DEFAULT}" + if [ -n "${DEPLOY_LIGHTTPD_ISSUER}" ]; then + Le_Deploy_lighttpd_issuer="${DEPLOY_LIGHTTPD_ISSUER}" + _savedomainconf Le_Deploy_lighttpd_issuer "${Le_Deploy_lighttpd_issuer}" + elif [ -z "${Le_Deploy_lighttpd_issuer}" ]; then + Le_Deploy_lighttpd_issuer="${DEPLOY_LIGHTTPD_ISSUER_DEFAULT}" + fi + + # RELOAD is optional. If not provided then assume "${DEPLOY_LIGHTTPD_RELOAD_DEFAULT}" + if [ -n "${DEPLOY_LIGHTTPD_RELOAD}" ]; then + Le_Deploy_lighttpd_reload="${DEPLOY_LIGHTTPD_RELOAD}" + _savedomainconf Le_Deploy_lighttpd_reload "${Le_Deploy_lighttpd_reload}" + elif [ -z "${Le_Deploy_lighttpd_reload}" ]; then + Le_Deploy_lighttpd_reload="${DEPLOY_LIGHTTPD_RELOAD_DEFAULT}" + fi + + # Set the suffix depending if we are creating a bundle or not + if [ "${Le_Deploy_lighttpd_bundle}" = "yes" ]; then + _info "Bundle creation requested" + # Initialise $Le_Keylength if its not already set + if [ -z "${Le_Keylength}" ]; then + Le_Keylength="" + fi + if _isEccKey "${Le_Keylength}"; then + _info "ECC key type detected" + _suffix=".ecdsa" + else + _info "RSA key type detected" + _suffix=".rsa" + fi + else + _suffix="" + fi + _debug _suffix "${_suffix}" + + # Set variables for later + _pem="${Le_Deploy_lighttpd_pem_path}/${Le_Deploy_lighttpd_pem_name}${_suffix}" + _issuer="${_pem}.issuer" + _ocsp="${_pem}.ocsp" + _reload="${Le_Deploy_lighttpd_reload}" + + _info "Deploying PEM file" + # Create a temporary PEM file + _temppem="$(_mktemp)" + _debug _temppem "${_temppem}" + cat "${_ckey}" "${_ccert}" "${_cca}" >"${_temppem}" + _ret="$?" + + # Check that we could create the temporary file + if [ "${_ret}" != "0" ]; then + _err "Error code ${_ret} returned during PEM file creation" + [ -f "${_temppem}" ] && rm -f "${_temppem}" + return ${_ret} + fi + + # Move PEM file into place + _info "Moving new certificate into place" + _debug _pem "${_pem}" + cat "${_temppem}" >"${_pem}" + _ret=$? + + # Clean up temp file + [ -f "${_temppem}" ] && rm -f "${_temppem}" + + # Deal with any failure of moving PEM file into place + if [ "${_ret}" != "0" ]; then + _err "Error code ${_ret} returned while moving new certificate into place" + return ${_ret} + fi + + # Update .issuer file if requested + if [ "${Le_Deploy_lighttpd_issuer}" = "yes" ]; then + _info "Updating .issuer file" + _debug _issuer "${_issuer}" + cat "${_cca}" >"${_issuer}" + _ret="$?" + + if [ "${_ret}" != "0" ]; then + _err "Error code ${_ret} returned while copying issuer/CA certificate into place" + return ${_ret} + fi + else + [ -f "${_issuer}" ] && _err "Issuer file update not requested but .issuer file exists" + fi + + # Update .ocsp file if certificate was requested with --ocsp/--ocsp-must-staple option + if [ -z "${Le_OCSP_Staple}" ]; then + Le_OCSP_Staple="0" + fi + if [ "${Le_OCSP_Staple}" = "1" ]; then + _info "Updating OCSP stapling info" + _debug _ocsp "${_ocsp}" + _info "Extracting OCSP URL" + _ocsp_url=$(openssl x509 -noout -ocsp_uri -in "${_pem}") + _debug _ocsp_url "${_ocsp_url}" + + # Only process OCSP if URL was present + if [ "${_ocsp_url}" != "" ]; then + # Extract the hostname from the OCSP URL + _info "Extracting OCSP URL" + _ocsp_host=$(echo "${_ocsp_url}" | cut -d/ -f3) + _debug _ocsp_host "${_ocsp_host}" + + # Only process the certificate if we have a .issuer file + if [ -r "${_issuer}" ]; then + # Check if issuer cert is also a root CA cert + _subjectdn=$(openssl x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) + _debug _subjectdn "${_subjectdn}" + _issuerdn=$(openssl x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) + _debug _issuerdn "${_issuerdn}" + _info "Requesting OCSP response" + # If the issuer is a CA cert then our command line has "-CAfile" added + if [ "${_subjectdn}" = "${_issuerdn}" ]; then + _cafile_argument="-CAfile \"${_issuer}\"" + else + _cafile_argument="" + fi + _debug _cafile_argument "${_cafile_argument}" + # if OpenSSL/LibreSSL is v1.1 or above, the format for the -header option has changed + _openssl_version=$(openssl version | cut -d' ' -f2) + _debug _openssl_version "${_openssl_version}" + _openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1) + _openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2) + if [ "${_openssl_major}" -eq "1" ] && [ "${_openssl_minor}" -ge "1" ] || [ "${_openssl_major}" -ge "2" ]; then + _header_sep="=" + else + _header_sep=" " + fi + # Request the OCSP response from the issuer and store it + _openssl_ocsp_cmd="openssl ocsp \ + -issuer \"${_issuer}\" \ + -cert \"${_pem}\" \ + -url \"${_ocsp_url}\" \ + -header Host${_header_sep}\"${_ocsp_host}\" \ + -respout \"${_ocsp}\" \ + -verify_other \"${_issuer}\" \ + ${_cafile_argument} \ + | grep -q \"${_pem}: good\"" + _debug _openssl_ocsp_cmd "${_openssl_ocsp_cmd}" + eval "${_openssl_ocsp_cmd}" + _ret=$? + else + # Non fatal: No issuer file was present so no OCSP stapling file created + _err "OCSP stapling in use but no .issuer file was present" + fi + else + # Non fatal: No OCSP url was found int the certificate + _err "OCSP update requested but no OCSP URL was found in certificate" + fi + + # Non fatal: Check return code of openssl command + if [ "${_ret}" != "0" ]; then + _err "Updating OCSP stapling failed with return code ${_ret}" + fi + else + # An OCSP file was already present but certificate did not have OCSP extension + if [ -f "${_ocsp}" ]; then + _err "OCSP was not requested but .ocsp file exists." + # Could remove the file at this step, although Lighttpd just ignores it in this case + # rm -f "${_ocsp}" || _err "Problem removing stale .ocsp file" + fi + fi + + # Reload Lighttpd + _debug _reload "${_reload}" + eval "${_reload}" + _ret=$? + if [ "${_ret}" != "0" ]; then + _err "Error code ${_ret} during reload" + return ${_ret} + else + _info "Reload successful" + fi + + return 0 +} From c43c711f720c672e2662e3d0c37cbcca44407e7a Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Wed, 1 Sep 2021 16:36:11 -0400 Subject: [PATCH 1476/2234] use _getdeployconf instead of sourcing DOMAIN_CONF (requested by @Neilpang in #3394) github: closes #3394 --- deploy/haproxy.sh | 15 ++++++++++----- deploy/lighttpd.sh | 15 ++++++++++----- deploy/ssh.sh | 27 ++++++++++++++++++++++----- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 0a45ee07..4497c34b 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -54,11 +54,6 @@ haproxy_deploy() { DEPLOY_HAPROXY_ISSUER_DEFAULT="no" DEPLOY_HAPROXY_RELOAD_DEFAULT="true" - if [ -f "${DOMAIN_CONF}" ]; then - # shellcheck disable=SC1090 - . "${DOMAIN_CONF}" - fi - _debug _cdomain "${_cdomain}" _debug _ckey "${_ckey}" _debug _ccert "${_ccert}" @@ -66,6 +61,8 @@ haproxy_deploy() { _debug _cfullchain "${_cfullchain}" # PEM_PATH is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_PATH_DEFAULT}" + _getdeployconf DEPLOY_HAPROXY_PEM_PATH + _debug2 DEPLOY_HAPROXY_PEM_PATH "${DEPLOY_HAPROXY_PEM_PATH}" if [ -n "${DEPLOY_HAPROXY_PEM_PATH}" ]; then Le_Deploy_haproxy_pem_path="${DEPLOY_HAPROXY_PEM_PATH}" _savedomainconf Le_Deploy_haproxy_pem_path "${Le_Deploy_haproxy_pem_path}" @@ -82,6 +79,8 @@ haproxy_deploy() { fi # PEM_NAME is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}" + _getdeployconf DEPLOY_HAPROXY_PEM_NAME + _debug2 DEPLOY_HAPROXY_PEM_NAME "${DEPLOY_HAPROXY_PEM_NAME}" if [ -n "${DEPLOY_HAPROXY_PEM_NAME}" ]; then Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME}" _savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}" @@ -90,6 +89,8 @@ haproxy_deploy() { fi # BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" + _getdeployconf DEPLOY_HAPROXY_BUNDLE + _debug2 DEPLOY_HAPROXY_BUNDLE "${DEPLOY_HAPROXY_BUNDLE}" if [ -n "${DEPLOY_HAPROXY_BUNDLE}" ]; then Le_Deploy_haproxy_bundle="${DEPLOY_HAPROXY_BUNDLE}" _savedomainconf Le_Deploy_haproxy_bundle "${Le_Deploy_haproxy_bundle}" @@ -98,6 +99,8 @@ haproxy_deploy() { fi # ISSUER is optional. If not provided then assume "${DEPLOY_HAPROXY_ISSUER_DEFAULT}" + _getdeployconf DEPLOY_HAPROXY_ISSUER + _debug2 DEPLOY_HAPROXY_ISSUER "${DEPLOY_HAPROXY_ISSUER}" if [ -n "${DEPLOY_HAPROXY_ISSUER}" ]; then Le_Deploy_haproxy_issuer="${DEPLOY_HAPROXY_ISSUER}" _savedomainconf Le_Deploy_haproxy_issuer "${Le_Deploy_haproxy_issuer}" @@ -106,6 +109,8 @@ haproxy_deploy() { fi # RELOAD is optional. If not provided then assume "${DEPLOY_HAPROXY_RELOAD_DEFAULT}" + _getdeployconf DEPLOY_HAPROXY_RELOAD + _debug2 DEPLOY_HAPROXY_RELOAD "${DEPLOY_HAPROXY_RELOAD}" if [ -n "${DEPLOY_HAPROXY_RELOAD}" ]; then Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD}" _savedomainconf Le_Deploy_haproxy_reload "${Le_Deploy_haproxy_reload}" diff --git a/deploy/lighttpd.sh b/deploy/lighttpd.sh index c003f455..e28cd27a 100644 --- a/deploy/lighttpd.sh +++ b/deploy/lighttpd.sh @@ -54,11 +54,6 @@ lighttpd_deploy() { DEPLOY_LIGHTTPD_ISSUER_DEFAULT="yes" DEPLOY_LIGHTTPD_RELOAD_DEFAULT="true" - if [ -f "${DOMAIN_CONF}" ]; then - # shellcheck disable=SC1090 - . "${DOMAIN_CONF}" - fi - _debug _cdomain "${_cdomain}" _debug _ckey "${_ckey}" _debug _ccert "${_ccert}" @@ -66,6 +61,8 @@ lighttpd_deploy() { _debug _cfullchain "${_cfullchain}" # PEM_PATH is optional. If not provided then assume "${DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT}" + _getdeployconf DEPLOY_LIGHTTPD_PEM_PATH + _debug2 DEPLOY_LIGHTTPD_PEM_PATH "${DEPLOY_LIGHTTPD_PEM_PATH}" if [ -n "${DEPLOY_LIGHTTPD_PEM_PATH}" ]; then Le_Deploy_lighttpd_pem_path="${DEPLOY_LIGHTTPD_PEM_PATH}" _savedomainconf Le_Deploy_lighttpd_pem_path "${Le_Deploy_lighttpd_pem_path}" @@ -82,6 +79,8 @@ lighttpd_deploy() { fi # PEM_NAME is optional. If not provided then assume "${DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT}" + _getdeployconf DEPLOY_LIGHTTPD_PEM_NAME + _debug2 DEPLOY_LIGHTTPD_PEM_NAME "${DEPLOY_LIGHTTPD_PEM_NAME}" if [ -n "${DEPLOY_LIGHTTPD_PEM_NAME}" ]; then Le_Deploy_lighttpd_pem_name="${DEPLOY_LIGHTTPD_PEM_NAME}" _savedomainconf Le_Deploy_lighttpd_pem_name "${Le_Deploy_lighttpd_pem_name}" @@ -90,6 +89,8 @@ lighttpd_deploy() { fi # BUNDLE is optional. If not provided then assume "${DEPLOY_LIGHTTPD_BUNDLE_DEFAULT}" + _getdeployconf DEPLOY_LIGHTTPD_BUNDLE + _debug2 DEPLOY_LIGHTTPD_BUNDLE "${DEPLOY_LIGHTTPD_BUNDLE}" if [ -n "${DEPLOY_LIGHTTPD_BUNDLE}" ]; then Le_Deploy_lighttpd_bundle="${DEPLOY_LIGHTTPD_BUNDLE}" _savedomainconf Le_Deploy_lighttpd_bundle "${Le_Deploy_lighttpd_bundle}" @@ -98,6 +99,8 @@ lighttpd_deploy() { fi # ISSUER is optional. If not provided then assume "${DEPLOY_LIGHTTPD_ISSUER_DEFAULT}" + _getdeployconf DEPLOY_LIGHTTPD_ISSUER + _debug2 DEPLOY_LIGHTTPD_ISSUER "${DEPLOY_LIGHTTPD_ISSUER}" if [ -n "${DEPLOY_LIGHTTPD_ISSUER}" ]; then Le_Deploy_lighttpd_issuer="${DEPLOY_LIGHTTPD_ISSUER}" _savedomainconf Le_Deploy_lighttpd_issuer "${Le_Deploy_lighttpd_issuer}" @@ -106,6 +109,8 @@ lighttpd_deploy() { fi # RELOAD is optional. If not provided then assume "${DEPLOY_LIGHTTPD_RELOAD_DEFAULT}" + _getdeployconf DEPLOY_LIGHTTPD_RELOAD + _debug2 DEPLOY_LIGHTTPD_RELOAD "${DEPLOY_LIGHTTPD_RELOAD}" if [ -n "${DEPLOY_LIGHTTPD_RELOAD}" ]; then Le_Deploy_lighttpd_reload="${DEPLOY_LIGHTTPD_RELOAD}" _savedomainconf Le_Deploy_lighttpd_reload "${Le_Deploy_lighttpd_reload}" diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 18de4aa6..89962621 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -35,11 +35,6 @@ ssh_deploy() { _cfullchain="$5" _deploy_ssh_servers="" - if [ -f "$DOMAIN_CONF" ]; then - # shellcheck disable=SC1090 - . "$DOMAIN_CONF" - fi - _debug _cdomain "$_cdomain" _debug _ckey "$_ckey" _debug _ccert "$_ccert" @@ -47,6 +42,8 @@ ssh_deploy() { _debug _cfullchain "$_cfullchain" # USER is required to login by SSH to remote host. + _getdeployconf DEPLOY_SSH_USER + _debug2 DEPLOY_SSH_USER "$DEPLOY_SSH_USER" if [ -z "$DEPLOY_SSH_USER" ]; then if [ -z "$Le_Deploy_ssh_user" ]; then _err "DEPLOY_SSH_USER not defined." @@ -58,6 +55,8 @@ ssh_deploy() { fi # SERVER is optional. If not provided then use _cdomain + _getdeployconf DEPLOY_SSH_SERVER + _debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER" if [ -n "$DEPLOY_SSH_SERVER" ]; then Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER" _savedomainconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server" @@ -66,6 +65,8 @@ ssh_deploy() { fi # CMD is optional. If not provided then use ssh + _getdeployconf DEPLOY_SSH_CMD + _debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD" if [ -n "$DEPLOY_SSH_CMD" ]; then Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD" _savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd" @@ -74,6 +75,8 @@ ssh_deploy() { fi # BACKUP is optional. If not provided then default to previously saved value or yes. + _getdeployconf DEPLOY_SSH_BACKUP + _debug2 DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP" if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then Le_Deploy_ssh_backup="no" elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then @@ -82,6 +85,8 @@ ssh_deploy() { _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" # BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy + _getdeployconf DEPLOY_SSH_BACKUP_PATH + _debug2 DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH" if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH" elif [ -z "$Le_Deploy_ssh_backup_path" ]; then @@ -91,6 +96,8 @@ ssh_deploy() { # MULTI_CALL is optional. If not provided then default to previously saved # value (which may be undefined... equivalent to "no"). + _getdeployconf DEPLOY_SSH_MULTI_CALL + _debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL" if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then Le_Deploy_ssh_multi_call="yes" _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" @@ -141,6 +148,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # KEYFILE is optional. # If provided then private key will be copied to provided filename. + _getdeployconf DEPLOY_SSH_KEYFILE + _debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE" if [ -n "$DEPLOY_SSH_KEYFILE" ]; then Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE" _savedomainconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile" @@ -163,6 +172,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # CERTFILE is optional. # If provided then certificate will be copied or appended to provided filename. + _getdeployconf DEPLOY_SSH_CERTFILE + _debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE" if [ -n "$DEPLOY_SSH_CERTFILE" ]; then Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE" _savedomainconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile" @@ -189,6 +200,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # CAFILE is optional. # If provided then CA intermediate certificate will be copied or appended to provided filename. + _getdeployconf DEPLOY_SSH_CAFILE + _debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE" if [ -n "$DEPLOY_SSH_CAFILE" ]; then Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE" _savedomainconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile" @@ -216,6 +229,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # FULLCHAIN is optional. # If provided then fullchain certificate will be copied or appended to provided filename. + _getdeployconf DEPLOY_SSH_FULLCHAIN + _debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN" if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN" _savedomainconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain" @@ -244,6 +259,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # REMOTE_CMD is optional. # If provided then this command will be executed on remote host. + _getdeployconf DEPLOY_SSH_REMOTE_CMD + _debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD" if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD" _savedomainconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd" From 2447fccf1eed45ef654e1ef60a9ffa5df1db96f0 Mon Sep 17 00:00:00 2001 From: Nookery Date: Sat, 4 Sep 2021 16:59:50 +0800 Subject: [PATCH 1477/2234] name="snis" => name="snis[]" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kong 2.5.x,snis参数是一个数组 --- deploy/kong.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/kong.sh b/deploy/kong.sh index 1e1e310c..b8facedf 100755 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -45,7 +45,7 @@ kong_deploy() { #Generate data for request (Multipart/form-data with mixed content) if [ -z "$ssl_uuid" ]; then #set sni to domain - content="--$delim${nl}Content-Disposition: form-data; name=\"snis\"${nl}${nl}$_cdomain" + content="--$delim${nl}Content-Disposition: form-data; name=\"snis[]\"${nl}${nl}$_cdomain" fi #add key content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" From 1064c270d96050ed829e832392fef8cc54cc4b33 Mon Sep 17 00:00:00 2001 From: Philipp B <16269108+TheTyrius@users.noreply.github.com> Date: Mon, 6 Sep 2021 17:01:31 +0200 Subject: [PATCH 1478/2234] Fix variable name Wrong variable name was used in login() and logout(), preventing operation. --- dnsapi/dns_netcup.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index d519e4f7..776fa02d 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -119,16 +119,16 @@ login() { tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") sid=$(echo "$tmp" | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4) _debug "$tmp" - if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then - _err "$msg" + if [ "$(_getfield "$tmp" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$tmp" return 1 fi } logout() { tmp=$(_post "{\"action\": \"logout\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") _debug "$tmp" - if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then - _err "$msg" + if [ "$(_getfield "$tmp" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$tmp" return 1 fi } From d317b49940adc07fc33f0d2cf0f011e4f1da0e03 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Wed, 8 Sep 2021 22:48:43 -0400 Subject: [PATCH 1479/2234] use head instead of tail so that the sessionid cookie gets set correctly --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index d720c1c5..4d5549ab 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -150,7 +150,7 @@ _1984hosting_login() { _debug2 response "$response" if _contains "$response" '"loggedin": true'; then - One984HOSTING_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" + One984HOSTING_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" export One984HOSTING_COOKIE _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" return 0 From 1312ef7e504c8bbac7c95c1acb0fd29032d36b5e Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Fri, 10 Sep 2021 07:25:18 -0400 Subject: [PATCH 1480/2234] simplify One984HOSTING_COOKIE grep --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 33c9bb2a..a9eb9dd2 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -150,7 +150,7 @@ _1984hosting_login() { _debug2 response "$response" if _contains "$response" '"loggedin": true'; then - One984HOSTING_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" + One984HOSTING_COOKIE="$(grep -io 'sessionid=[^;]*;' "$HTTP_HEADER" | tr -d ';')" export One984HOSTING_COOKIE _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" return 0 From 92f13eb8bf329523e618b32e97283cb4bf392126 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Fri, 10 Sep 2021 08:02:13 -0400 Subject: [PATCH 1481/2234] get both the CSRF token and session ID cookies, as they are both needed for login now --- dnsapi/dns_1984hosting.sh | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index a9eb9dd2..62448754 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -135,7 +135,7 @@ dns_1984hosting_rm() { _1984hosting_login() { if ! _check_credentials; then return 1; fi - if _check_cookie; then + if _check_cookies; then _debug "Already logged in" return 0 fi @@ -150,9 +150,12 @@ _1984hosting_login() { _debug2 response "$response" if _contains "$response" '"loggedin": true'; then - One984HOSTING_COOKIE="$(grep -io 'sessionid=[^;]*;' "$HTTP_HEADER" | tr -d ';')" - export One984HOSTING_COOKIE - _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" + One984HOSTING_SESSIONID_COOKIE="$(grep -io 'sessionid=[^;]*;' "$HTTP_HEADER" | tr -d ';')" + One984HOSTING_CSRFTOKEN_COOKIE="$(grep -io 'csrftoken=[^;]*;' "$HTTP_HEADER" | tr -d ';')" + export One984HOSTING_SESSIONID_COOKIE + export One984HOSTING_CSRFTOKEN_COOKIE + _saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE" + _saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE" return 0 fi return 1 @@ -169,21 +172,24 @@ _check_credentials() { return 0 } -_check_cookie() { - One984HOSTING_COOKIE="${One984HOSTING_COOKIE:-$(_readaccountconf_mutable One984HOSTING_COOKIE)}" - if [ -z "$One984HOSTING_COOKIE" ]; then - _debug "No cached cookie found" +_check_cookies() { + One984HOSTING_SESSIONID_COOKIE="${One984HOSTING_SESSIONID_COOKIE:-$(_readaccountconf_mutable One984HOSTING_SESSIONID_COOKIE)}" + One984HOSTING_CSRFTOKEN_COOKIE="${One984HOSTING_CSRFTOKEN_COOKIE:-$(_readaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE)}" + if [ -z "$One984HOSTING_SESSIONID_COOKIE" ] || [ -z "$One984HOSTING_CSRFTOKEN_COOKIE" ]; then + _debug "No cached cookie(s) found" return 1 fi _authget "https://management.1984hosting.com/accounts/loginstatus/" if _contains "$response" '"ok": true'; then - _debug "Cached cookie still valid" + _debug "Cached cookies still valid" return 0 fi - _debug "Cached cookie no longer valid" - One984HOSTING_COOKIE="" - _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" + _debug "Cached cookies no longer valid" + One984HOSTING_SESSIONID_COOKIE="" + One984HOSTING_CSRFTOKEN_COOKIE="" + _saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE" + _saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE" return 1 } @@ -217,7 +223,8 @@ _get_root() { # add extra headers to request _authget() { - export _H1="Cookie: $One984HOSTING_COOKIE" + export _H1="Cookie: $One984HOSTING_SESSIONID_COOKIE" + export _H2="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE" _response=$(_get "$1" | _normalizeJson) _debug2 _response "$_response" } @@ -225,12 +232,14 @@ _authget() { # truncate huge HTML response # echo: Argument list too long _htmlget() { - export _H1="Cookie: $One984HOSTING_COOKIE" + export _H1="Cookie: $One984HOSTING_SESSIONID_COOKIE" + export _H2="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE" _response=$(_get "$1" | grep "$2" | _head_n 1) } # add extra headers to request _authpost() { - export _H1="Cookie: $One984HOSTING_COOKIE" + export _H1="Cookie: $One984HOSTING_SESSIONID_COOKIE" + export _H2="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE" _response=$(_post "$1" "$2") } From ced7110a78ba8faa6163bbe1f8a786f00ad5c6a9 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Fri, 10 Sep 2021 08:49:38 -0400 Subject: [PATCH 1482/2234] remove -o option from grep and use _egrep_o instead --- dnsapi/dns_1984hosting.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 62448754..f626e75a 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -150,8 +150,8 @@ _1984hosting_login() { _debug2 response "$response" if _contains "$response" '"loggedin": true'; then - One984HOSTING_SESSIONID_COOKIE="$(grep -io 'sessionid=[^;]*;' "$HTTP_HEADER" | tr -d ';')" - One984HOSTING_CSRFTOKEN_COOKIE="$(grep -io 'csrftoken=[^;]*;' "$HTTP_HEADER" | tr -d ';')" + One984HOSTING_SESSIONID_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" + One984HOSTING_CSRFTOKEN_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')" export One984HOSTING_SESSIONID_COOKIE export One984HOSTING_CSRFTOKEN_COOKIE _saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE" From ea18c47011279cbabbba4e857abea5a2a92e8a3a Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 12:35:20 -0400 Subject: [PATCH 1483/2234] move getting zone id code into its own function --- dnsapi/dns_1984hosting.sh | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index f626e75a..fceb7618 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -95,17 +95,7 @@ dns_1984hosting_rm() { _debug _domain "$_domain" _debug "Delete $fulldomain TXT record" - url="https://management.1984hosting.com/domains" - - _htmlget "$url" "$_domain" - _debug2 _response "$_response" - zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" - _debug2 zone_id "$zone_id" - if [ -z "$zone_id" ]; then - _err "Error getting zone_id for $1" - return 1 - fi - + _htmlget "$url/$zone_id" "$_sub_domain" _debug2 _response "$_response" entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" @@ -221,6 +211,22 @@ _get_root() { return 1 } +#domain.com +#returns zone id for domain.com +_get_zone_id() { + url="https://management.1984hosting.com/domains" + + _htmlget "$url" "$_domain" + _debug2 _response "$_response" + _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" + _debug2 _zone_id "$_zone_id" + if [ -z "$zone_id" ]; then + _err "Error getting _zone_id for $1" + return 1 + fi + return 0 +} + # add extra headers to request _authget() { export _H1="Cookie: $One984HOSTING_SESSIONID_COOKIE" From 8f3b7c179ec3e6333c67ce41a054f2c5bf2fd7fb Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 12:37:56 -0400 Subject: [PATCH 1484/2234] put cookies into a format that the 1984 Hosting website expects --- dnsapi/dns_1984hosting.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index fceb7618..d1d7b154 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -229,8 +229,7 @@ _get_zone_id() { # add extra headers to request _authget() { - export _H1="Cookie: $One984HOSTING_SESSIONID_COOKIE" - export _H2="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE" + export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" _response=$(_get "$1" | _normalizeJson) _debug2 _response "$_response" } @@ -238,14 +237,12 @@ _authget() { # truncate huge HTML response # echo: Argument list too long _htmlget() { - export _H1="Cookie: $One984HOSTING_SESSIONID_COOKIE" - export _H2="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE" + export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" _response=$(_get "$1" | grep "$2" | _head_n 1) } # add extra headers to request _authpost() { - export _H1="Cookie: $One984HOSTING_SESSIONID_COOKIE" - export _H2="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE" + export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" _response=$(_post "$1" "$2") } From c668c603cc1a4be51393dcb6fd1896df3a5afe1a Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 12:45:06 -0400 Subject: [PATCH 1485/2234] add Referer and X-CSRFToken HTTP headers --- dnsapi/dns_1984hosting.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index d1d7b154..dc33ca60 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -243,6 +243,10 @@ _htmlget() { # add extra headers to request _authpost() { + _get_zone_id "$@" + 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 _H3="X-CSRFToken: $csrf_header" _response=$(_post "$1" "$2") } From c5c2014081b8c0ae87bfe1d92572d86140f43bf9 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 12:48:27 -0400 Subject: [PATCH 1486/2234] add _get_zone_id to dns_1984hosting_rm to get the zone id --- dnsapi/dns_1984hosting.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index dc33ca60..395c0da1 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -96,7 +96,9 @@ dns_1984hosting_rm() { _debug "Delete $fulldomain TXT record" - _htmlget "$url/$zone_id" "$_sub_domain" + _get_zone_id + + _htmlget "$url/$_zone_id" "$_sub_domain" _debug2 _response "$_response" entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" _debug2 entry_id "$entry_id" From 46e62f1a9ab12b1b111e141deef2f62ab3451578 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 12:50:03 -0400 Subject: [PATCH 1487/2234] fix typo --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 395c0da1..4d1bd9af 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -222,7 +222,7 @@ _get_zone_id() { _debug2 _response "$_response" _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" _debug2 _zone_id "$_zone_id" - if [ -z "$zone_id" ]; then + if [ -z "$_zone_id" ]; then _err "Error getting _zone_id for $1" return 1 fi From 384bc62f257eebd58850ef0e32c068b8831f548e Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 12:54:42 -0400 Subject: [PATCH 1488/2234] make _get_zone_id usage consistent --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 4d1bd9af..fafd9e8d 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -96,7 +96,7 @@ dns_1984hosting_rm() { _debug "Delete $fulldomain TXT record" - _get_zone_id + _get_zone_id "$@" _htmlget "$url/$_zone_id" "$_sub_domain" _debug2 _response "$_response" From aa05a1e81ddd3a5cb71dff985881b081ba9cc4e0 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 13:00:03 -0400 Subject: [PATCH 1489/2234] make sure _url gets set where it is needed --- dnsapi/dns_1984hosting.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index fafd9e8d..d011f334 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -96,9 +96,10 @@ dns_1984hosting_rm() { _debug "Delete $fulldomain TXT record" + _url="https://management.1984hosting.com/domains" _get_zone_id "$@" - _htmlget "$url/$_zone_id" "$_sub_domain" + _htmlget "$_url/$_zone_id" "$_sub_domain" _debug2 _response "$_response" entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" _debug2 entry_id "$entry_id" @@ -216,9 +217,7 @@ _get_root() { #domain.com #returns zone id for domain.com _get_zone_id() { - url="https://management.1984hosting.com/domains" - - _htmlget "$url" "$_domain" + _htmlget "$_url" "$_domain" _debug2 _response "$_response" _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" _debug2 _zone_id "$_zone_id" From f101418658fd4980071cdc0e34c96e2346d44d3f Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 13:03:54 -0400 Subject: [PATCH 1490/2234] change _url -> url --- dnsapi/dns_1984hosting.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index d011f334..764aad9e 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -96,10 +96,10 @@ dns_1984hosting_rm() { _debug "Delete $fulldomain TXT record" - _url="https://management.1984hosting.com/domains" + url="https://management.1984hosting.com/domains" _get_zone_id "$@" - _htmlget "$_url/$_zone_id" "$_sub_domain" + _htmlget "$url/$_zone_id" "$_sub_domain" _debug2 _response "$_response" entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" _debug2 entry_id "$entry_id" @@ -217,7 +217,7 @@ _get_root() { #domain.com #returns zone id for domain.com _get_zone_id() { - _htmlget "$_url" "$_domain" + _htmlget "$url" "$_domain" _debug2 _response "$_response" _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" _debug2 _zone_id "$_zone_id" From a196958bd6f26d429db8845ef0e096d40d57773e Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 13:13:55 -0400 Subject: [PATCH 1491/2234] add check when getting zone id --- dnsapi/dns_1984hosting.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 764aad9e..734d64fb 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -97,7 +97,11 @@ dns_1984hosting_rm() { _debug "Delete $fulldomain TXT record" url="https://management.1984hosting.com/domains" - _get_zone_id "$@" + + if ! _get_zone_id "$_domain"; then + _err "invalid zone" "$_domain" + return 1 + fi _htmlget "$url/$_zone_id" "$_sub_domain" _debug2 _response "$_response" @@ -214,10 +218,12 @@ _get_root() { return 1 } -#domain.com +#usage: _get_zone_id domain.com #returns zone id for domain.com _get_zone_id() { - _htmlget "$url" "$_domain" + url="https://management.1984hosting.com/domains" + domain=$1 + _htmlget "$url" "$domain" _debug2 _response "$_response" _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" _debug2 _zone_id "$_zone_id" From b45a44e4057fbc39f8be727520f3ee17739cd530 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 13:33:55 -0400 Subject: [PATCH 1492/2234] fix formatting --- dnsapi/dns_1984hosting.sh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 734d64fb..c517dc3f 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -93,14 +93,12 @@ dns_1984hosting_rm() { fi _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "Delete $fulldomain TXT record" - - url="https://management.1984hosting.com/domains" - if ! _get_zone_id "$_domain"; then - _err "invalid zone" "$_domain" - return 1 + url="https://management.1984hosting.com/domains" + if ! _get_zone_id "$url" "$_domain"; then + _err "invalid zone" "$_domain" + return 1 fi _htmlget "$url/$_zone_id" "$_sub_domain" @@ -218,11 +216,11 @@ _get_root() { return 1 } -#usage: _get_zone_id domain.com +#usage: _get_zone_id url domain.com #returns zone id for domain.com _get_zone_id() { - url="https://management.1984hosting.com/domains" - domain=$1 + url=$1 + domain=$2 _htmlget "$url" "$domain" _debug2 _response "$_response" _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" From 622464ff5e8dad1adb89815250dd79515c7858f7 Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 13:49:31 -0400 Subject: [PATCH 1493/2234] fix error message for _get_zone_id --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index c517dc3f..572173b2 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -226,7 +226,7 @@ _get_zone_id() { _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" _debug2 _zone_id "$_zone_id" if [ -z "$_zone_id" ]; then - _err "Error getting _zone_id for $1" + _err "Error getting _zone_id for $2" return 1 fi return 0 From 8d7a48701361cf0952b7022fba28d259a0c3a30e Mon Sep 17 00:00:00 2001 From: Christophe B Billheimer Date: Sun, 12 Sep 2021 14:10:15 -0400 Subject: [PATCH 1494/2234] change $@ -> $_domain --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 572173b2..16cd22a7 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -248,7 +248,7 @@ _htmlget() { # add extra headers to request _authpost() { - _get_zone_id "$@" + _get_zone_id "$_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" From 2f3ec3a77f071e4e56e78a5b858b8572005c29ec Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Sun, 12 Sep 2021 16:25:21 -0400 Subject: [PATCH 1495/2234] filter out instances where email@domain.com exists --- dnsapi/dns_1984hosting.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 16cd22a7..cd7102f1 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -244,6 +244,9 @@ _authget() { _htmlget() { export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" _response=$(_get "$1" | grep "$2" | _head_n 1) + if _contains "$_response" "@$2"; then + _response=$(echo "$_response" | grep -v "[@]" | _head_n 1) + fi } # add extra headers to request From 148336929d2aa0143fdddd9a301ba09e7c028cbb Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Sun, 12 Sep 2021 16:27:40 -0400 Subject: [PATCH 1496/2234] fix formatting --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index cd7102f1..80587101 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -245,7 +245,7 @@ _htmlget() { export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" _response=$(_get "$1" | grep "$2" | _head_n 1) if _contains "$_response" "@$2"; then - _response=$(echo "$_response" | grep -v "[@]" | _head_n 1) + _response=$(echo "$_response" | grep -v "[@]" | _head_n 1) fi } From f3196396a2cfb836df25af196017fb9cb7394ea1 Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Sun, 12 Sep 2021 16:49:53 -0400 Subject: [PATCH 1497/2234] fix email filtering --- dnsapi/dns_1984hosting.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 80587101..c75e4217 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -223,7 +223,7 @@ _get_zone_id() { domain=$2 _htmlget "$url" "$domain" _debug2 _response "$_response" - _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" + _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+' | _head_n 1)" _debug2 _zone_id "$_zone_id" if [ -z "$_zone_id" ]; then _err "Error getting _zone_id for $2" @@ -243,7 +243,7 @@ _authget() { # echo: Argument list too long _htmlget() { export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" - _response=$(_get "$1" | grep "$2" | _head_n 1) + _response=$(_get "$1" | grep "$2") if _contains "$_response" "@$2"; then _response=$(echo "$_response" | grep -v "[@]" | _head_n 1) fi From 64e3cab6ab7ee2ea2b420d02da50e87ca8dfa79e Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Sun, 12 Sep 2021 16:57:32 -0400 Subject: [PATCH 1498/2234] add correct number of vars for _get_zone_id --- dnsapi/dns_1984hosting.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index c75e4217..0a562605 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -251,7 +251,8 @@ _htmlget() { # add extra headers to request _authpost() { - _get_zone_id "$_domain" + url="https://management.1984hosting.com/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" From b910726c4356383b69601ce3b52a101e0f55353d Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Sun, 12 Sep 2021 17:05:36 -0400 Subject: [PATCH 1499/2234] pick first entry if more than one TXT entry exists --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 0a562605..cb60651d 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -103,7 +103,7 @@ dns_1984hosting_rm() { _htmlget "$url/$_zone_id" "$_sub_domain" _debug2 _response "$_response" - entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" + entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//' | _head_n 1)" _debug2 entry_id "$entry_id" if [ -z "$entry_id" ]; then _err "Error getting TXT entry_id for $1" From 4e553f34ba6958931e0a29bb97a629319dd3f95a Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Sun, 12 Sep 2021 17:20:01 -0400 Subject: [PATCH 1500/2234] get TXT entry based on $txtvalue --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index cb60651d..5fa8b738 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -103,7 +103,7 @@ dns_1984hosting_rm() { _htmlget "$url/$_zone_id" "$_sub_domain" _debug2 _response "$_response" - entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//' | _head_n 1)" + entry_id="$(echo "$_response" | grep "$txtvalue" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" _debug2 entry_id "$entry_id" if [ -z "$entry_id" ]; then _err "Error getting TXT entry_id for $1" From 4d95e35c06e4d5268edfb46a0909d7342e91dc04 Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Sun, 12 Sep 2021 17:38:27 -0400 Subject: [PATCH 1501/2234] get response based on $txtvalue --- dnsapi/dns_1984hosting.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 5fa8b738..c36c7758 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -101,9 +101,9 @@ dns_1984hosting_rm() { return 1 fi - _htmlget "$url/$_zone_id" "$_sub_domain" + _htmlget "$url/$_zone_id" "$txtvalue" _debug2 _response "$_response" - entry_id="$(echo "$_response" | grep "$txtvalue" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" + entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" _debug2 entry_id "$entry_id" if [ -z "$entry_id" ]; then _err "Error getting TXT entry_id for $1" From 41a2d0e06c7f7af044cf6815c6733c36664f57c3 Mon Sep 17 00:00:00 2001 From: DerVerruckteFuchs Date: Mon, 13 Sep 2021 11:44:39 -0400 Subject: [PATCH 1502/2234] reduce ttl --- dnsapi/dns_1984hosting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index c36c7758..db0cbe15 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -46,7 +46,7 @@ dns_1984hosting_add() { postdata="entry=new" postdata="$postdata&type=TXT" - postdata="$postdata&ttl=3600" + postdata="$postdata&ttl=900" postdata="$postdata&zone=$_domain" postdata="$postdata&host=$_sub_domain" postdata="$postdata&rdata=%22$value%22" From 5a689ce897e86d0e493de908b54de87e4e583915 Mon Sep 17 00:00:00 2001 From: Stephen Pliaskin Date: Wed, 22 Sep 2021 23:17:50 +0300 Subject: [PATCH 1503/2234] Add Veesp DNS API --- dnsapi/dns_veesp.sh | 158 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 dnsapi/dns_veesp.sh diff --git a/dnsapi/dns_veesp.sh b/dnsapi/dns_veesp.sh new file mode 100644 index 00000000..b8a41d00 --- /dev/null +++ b/dnsapi/dns_veesp.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env sh + +# bug reports to stepan@plyask.in + +# +# export VEESP_User="username" +# export VEESP_Password="password" + +VEESP_Api="https://secure.veesp.com/api" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_veesp_add() { + fulldomain=$1 + txtvalue=$2 + + VEESP_Password="${VEESP_Password:-$(_readaccountconf_mutable VEESP_Password)}" + VEESP_User="${VEESP_User:-$(_readaccountconf_mutable VEESP_User)}" + VEESP_auth=$(printf "%s" "$VEESP_User:$VEESP_Password" | _base64) + + if [ -z "$VEESP_Password" ] || [ -z "$VEESP_User" ]; then + VEESP_Password="" + VEESP_User="" + _err "You don't specify veesp api key and email yet." + _err "Please create you key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable VEESP_Password "$VEESP_Password" + _saveaccountconf_mutable VEESP_User "$VEESP_User" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _info "Adding record" + if VEESP_rest POST "service/$_service_id/dns/$_domain_id/records" "{\"name\":\"$fulldomain\",\"ttl\":1,\"priority\":0,\"type\":\"TXT\",\"content\":\"$txtvalue\"}"; then + if _contains "$response" "\"success\":true"; then + _info "Added" + #todo: check if the record takes effect + return 0 + else + _err "Add txt record error." + return 1 + fi + fi +} + +# Usage: fulldomain txtvalue +# Used to remove the txt record after validation +dns_veesp_rm() { + fulldomain=$1 + txtvalue=$2 + + VEESP_Password="${VEESP_Password:-$(_readaccountconf_mutable VEESP_Password)}" + VEESP_User="${VEESP_User:-$(_readaccountconf_mutable VEESP_User)}" + VEESP_auth=$(printf "%s" "$VEESP_User:$VEESP_Password" | _base64) + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + VEESP_rest GET "service/$_service_id/dns/$_domain_id" + + count=$(printf "%s\n" "$response" | _egrep_o "\"type\":\"TXT\",\"content\":\".\"$txtvalue.\"\"" | wc -l | tr -d " ") + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(printf "%s\n" "$response" | _egrep_o "{\"id\":[^}]*\"type\":\"TXT\",\"content\":\".\"$txtvalue.\"\"" | cut -d\" -f4) + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! VEESP_rest DELETE "service/$_service_id/dns/$_domain_id/records/$record_id"; then + _err "Delete record error." + return 1 + fi + _contains "$response" "\"success\":true" + fi +} + +#################### 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 ! VEESP_rest GET "dns"; 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" "\"name\":\"$h\""; then + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"domain_id\":[^,]*,\"name\":\"$h\"" | cut -d : -f 2 | cut -d , -f 1 | cut -d '"' -f 2) + _debug _domain_id "$_domain_id" + _service_id=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$h\",\"service_id\":[^}]*" | cut -d : -f 3 | cut -d '"' -f 2) + _debug _service_id "$_service_id" + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +VEESP_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + export _H1="Accept: application/json" + export _H2="Authorization: Basic $VEESP_auth" + if [ "$m" != "GET" ]; then + _debug data "$data" + export _H3="Content-Type: application/json" + response="$(_post "$data" "$VEESP_Api/$ep" "" "$m")" + else + response="$(_get "$VEESP_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 8d3ad3a8c17adc419dd25de6cbcf920888ae58f7 Mon Sep 17 00:00:00 2001 From: Tom Cocca Date: Thu, 23 Sep 2021 08:10:17 -0400 Subject: [PATCH 1504/2234] Rackspace changed their API response, fixed the sed matching --- dnsapi/dns_rackspace.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_rackspace.sh b/dnsapi/dns_rackspace.sh index 03e1fa68..9c967182 100644 --- a/dnsapi/dns_rackspace.sh +++ b/dnsapi/dns_rackspace.sh @@ -7,6 +7,7 @@ RACKSPACE_Endpoint="https://dns.api.rackspacecloud.com/v1.0" +# 20210923 - RS changed the fields in the API response; fix sed # 20190213 - The name & id fields swapped in the API response; fix sed # 20190101 - Duplicating file for new pull request to dev branch # Original - tcocca:rackspace_dnsapi https://github.com/acmesh-official/acme.sh/pull/1297 @@ -79,8 +80,8 @@ _get_root_zone() { _debug2 response "$response" if _contains "$response" "\"name\":\"$h\"" >/dev/null; then # Response looks like: - # {"ttl":300,"accountId":12345,"id":1111111,"name":"example.com","emailAddress": ... - _domain_id=$(echo "$response" | sed -n "s/^.*\"id\":\([^,]*\),\"name\":\"$h\",.*/\1/p") + # {"id": "12345","accountId": "1111111","name": "example.com","ttl": 3600,"emailAddress": ... + _domain_id=$(echo "$response" | sed -n "s/^.*\"id\":\"\([^,]*\)\",\"accountId\":\"[0-9]*\",\"name\":\"$h\",.*/\1/p") _debug2 domain_id "$_domain_id" if [ -n "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) From b9aa4f4478416e33593d9cc6c958cf1eaf73a2d5 Mon Sep 17 00:00:00 2001 From: Tom Cocca Date: Thu, 23 Sep 2021 08:20:50 -0400 Subject: [PATCH 1505/2234] trigger a GH actions change --- dnsapi/dns_rackspace.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_rackspace.sh b/dnsapi/dns_rackspace.sh index 9c967182..62af3c67 100644 --- a/dnsapi/dns_rackspace.sh +++ b/dnsapi/dns_rackspace.sh @@ -80,7 +80,7 @@ _get_root_zone() { _debug2 response "$response" if _contains "$response" "\"name\":\"$h\"" >/dev/null; then # Response looks like: - # {"id": "12345","accountId": "1111111","name": "example.com","ttl": 3600,"emailAddress": ... + # {"id": "12345","accountId": "1111111","name": "example.com","ttl": 3600,"emailAddress": ... _domain_id=$(echo "$response" | sed -n "s/^.*\"id\":\"\([^,]*\)\",\"accountId\":\"[0-9]*\",\"name\":\"$h\",.*/\1/p") _debug2 domain_id "$_domain_id" if [ -n "$_domain_id" ]; then From 16d0416f2211809f9d38945d506f508ef58bc462 Mon Sep 17 00:00:00 2001 From: Tom Cocca Date: Thu, 23 Sep 2021 08:50:20 -0400 Subject: [PATCH 1506/2234] trigger GH Actions again --- dnsapi/dns_rackspace.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_rackspace.sh b/dnsapi/dns_rackspace.sh index 62af3c67..b50d9168 100644 --- a/dnsapi/dns_rackspace.sh +++ b/dnsapi/dns_rackspace.sh @@ -80,7 +80,7 @@ _get_root_zone() { _debug2 response "$response" if _contains "$response" "\"name\":\"$h\"" >/dev/null; then # Response looks like: - # {"id": "12345","accountId": "1111111","name": "example.com","ttl": 3600,"emailAddress": ... + # {"id":"12345","accountId":"1111111","name": "example.com","ttl":3600,"emailAddress": ... _domain_id=$(echo "$response" | sed -n "s/^.*\"id\":\"\([^,]*\)\",\"accountId\":\"[0-9]*\",\"name\":\"$h\",.*/\1/p") _debug2 domain_id "$_domain_id" if [ -n "$_domain_id" ]; then From 8419b42e83ff4278a441390b8963281c50279b40 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Thu, 30 Sep 2021 19:00:21 -0400 Subject: [PATCH 1507/2234] use ${ACME_OPENSSL_BIN:-openssl} instead of openssl (requested by @Neilpang in #3687) --- deploy/haproxy.sh | 10 +++++----- deploy/lighttpd.sh | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 4497c34b..c255059d 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -195,7 +195,7 @@ haproxy_deploy() { _info "Updating OCSP stapling info" _debug _ocsp "${_ocsp}" _info "Extracting OCSP URL" - _ocsp_url=$(openssl x509 -noout -ocsp_uri -in "${_pem}") + _ocsp_url=$(${ACME_OPENSSL_BIN:-openssl} x509 -noout -ocsp_uri -in "${_pem}") _debug _ocsp_url "${_ocsp_url}" # Only process OCSP if URL was present @@ -208,9 +208,9 @@ haproxy_deploy() { # Only process the certificate if we have a .issuer file if [ -r "${_issuer}" ]; then # Check if issuer cert is also a root CA cert - _subjectdn=$(openssl x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) + _subjectdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) _debug _subjectdn "${_subjectdn}" - _issuerdn=$(openssl x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) + _issuerdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) _debug _issuerdn "${_issuerdn}" _info "Requesting OCSP response" # If the issuer is a CA cert then our command line has "-CAfile" added @@ -221,7 +221,7 @@ haproxy_deploy() { fi _debug _cafile_argument "${_cafile_argument}" # if OpenSSL/LibreSSL is v1.1 or above, the format for the -header option has changed - _openssl_version=$(openssl version | cut -d' ' -f2) + _openssl_version=$(${ACME_OPENSSL_BIN:-openssl} version | cut -d' ' -f2) _debug _openssl_version "${_openssl_version}" _openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1) _openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2) @@ -231,7 +231,7 @@ haproxy_deploy() { _header_sep=" " fi # Request the OCSP response from the issuer and store it - _openssl_ocsp_cmd="openssl ocsp \ + _openssl_ocsp_cmd="${ACME_OPENSSL_BIN:-openssl} ocsp \ -issuer \"${_issuer}\" \ -cert \"${_pem}\" \ -url \"${_ocsp_url}\" \ diff --git a/deploy/lighttpd.sh b/deploy/lighttpd.sh index e28cd27a..71f64b96 100644 --- a/deploy/lighttpd.sh +++ b/deploy/lighttpd.sh @@ -195,7 +195,7 @@ lighttpd_deploy() { _info "Updating OCSP stapling info" _debug _ocsp "${_ocsp}" _info "Extracting OCSP URL" - _ocsp_url=$(openssl x509 -noout -ocsp_uri -in "${_pem}") + _ocsp_url=$(${ACME_OPENSSL_BIN:-openssl} x509 -noout -ocsp_uri -in "${_pem}") _debug _ocsp_url "${_ocsp_url}" # Only process OCSP if URL was present @@ -208,9 +208,9 @@ lighttpd_deploy() { # Only process the certificate if we have a .issuer file if [ -r "${_issuer}" ]; then # Check if issuer cert is also a root CA cert - _subjectdn=$(openssl x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) + _subjectdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) _debug _subjectdn "${_subjectdn}" - _issuerdn=$(openssl x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) + _issuerdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) _debug _issuerdn "${_issuerdn}" _info "Requesting OCSP response" # If the issuer is a CA cert then our command line has "-CAfile" added @@ -221,7 +221,7 @@ lighttpd_deploy() { fi _debug _cafile_argument "${_cafile_argument}" # if OpenSSL/LibreSSL is v1.1 or above, the format for the -header option has changed - _openssl_version=$(openssl version | cut -d' ' -f2) + _openssl_version=$(${ACME_OPENSSL_BIN:-openssl} version | cut -d' ' -f2) _debug _openssl_version "${_openssl_version}" _openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1) _openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2) @@ -231,7 +231,7 @@ lighttpd_deploy() { _header_sep=" " fi # Request the OCSP response from the issuer and store it - _openssl_ocsp_cmd="openssl ocsp \ + _openssl_ocsp_cmd="${ACME_OPENSSL_BIN:-openssl} ocsp \ -issuer \"${_issuer}\" \ -cert \"${_pem}\" \ -url \"${_ocsp_url}\" \ From 7f9b8d68ac793ed9b3a9cd525f0eafbff94ca4c6 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sat, 2 Oct 2021 19:30:07 +0200 Subject: [PATCH 1508/2234] Added dns-cpanel.sh as support for cPanel controlled DNS systems --- dnsapi/dns_cpanel.sh | 150 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100755 dnsapi/dns_cpanel.sh diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh new file mode 100755 index 00000000..4f25dc5c --- /dev/null +++ b/dnsapi/dns_cpanel.sh @@ -0,0 +1,150 @@ +#!/bin/bash +#Author: Bjarne Saltbaek +#Report Bugs here: https://github.com/acmesh-official/acme.sh +# +# +######## Public functions ##################### + +# Export CPANEL username,api token and hostname in the following variables +# +# cPanel_Username=username +# cPanel_Apitoken=apitoken +# cPanel_Hostname=hostname + +#Usage: dns_cpanel_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_cpanel_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Adding TXT record to cPanel based system" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + if ! _cpanel_login; then + _err "cPanel Login failed for user $cPanel_Username. Check $HTTP_HEADER file" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_domain "$fulldomain"; then + _err "No matching root domain for $fulldomain found" + return 1 + fi + # adding entry + _info "Adding the entry" + stripped_fulldomain=$(echo "$fulldomain" | sed "s/.$_domain//") + _debug "Adding $stripped_fulldomain to $_domain zone" + _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=add_zone_record&domain=$_domain&name=$stripped_fulldomain&type=TXT&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_cpanel_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Using cPanel based system" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + if ! _cpanel_login; then + _err "cPanel Login failed for user $cPanel_Username. Check $HTTP_HEADER file" + 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..." + _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=remove_zone_record&domain=$_domain&line=$_id" + # removing entry + + if _successful_update; then return 0; fi + _err "Couldn't delete entry!" + return 1 +} + +#################### Private functions below ################################## + +_checkcredentials() { + cPanel_Username="${cPanel_Username:-$(_readaccountconf_mutable cPanel_Username)}" + cPanel_Apitoken="${cPanel_Apitoken:-$(_readaccountconf_mutable cPanel_Apitoken)}" + + if [ -z "$cPanel_Username" ] || [ -z "$cPanel_Apitoken" ]; then + cPanel_Username="" + cPanel_Apitoken="" + _err "You haven't specified cPanel username and apitoken yet." + _err "Please add credentials and try again." + return 1 + fi + #save the credentials to the account conf file. + _saveaccountconf_mutable cPanel_Username "$cPanel_Username" + _saveaccountconf_mutable cPanel_Apitoken "$cPanel_Apitoken" + return 0 +} + +_cpanel_login() { + if ! _checkcredentials; then return 1; fi + + if ! _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=CustInfo&cpanel_jsonapi_func=displaycontactinfo"; then + _err "cPanel login failed for user $cPanel_Username." + return 1 + fi + return 0 +} + +_myget() { + #Adds auth header to request + export _H1="Authorization: cpanel $cPanel_Username:$cPanel_Apitoken" + _result=$(_get "$cPanel_Hostname/$1") +} + +_get_domain() { + _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' + _domains=$(echo "$_result" | jq '.cpanelresult.data[]| {zones}| .zones| keys' | sed -e 's/"//g' -e 's/,//g' -e 's/\[//g' -e 's/\]//g' -e '/^$/d' -e 's/[[:space:]]//g') + _debug "_result is: $_result" + _debug "_domains is: $_domains" + if [ -z "$_domains" ]; then + _err "Primary domain list not found!" + return 1 + fi + for _domain in $_domains; do + _debug "Checking if $fulldomain ends with $_domain" + if (_endswith "$fulldomain" "$_domain"); then + _debug "Root domain: $_domain" + return 0 + fi + done + return 1 +} + +_successful_update() { + if (echo "$_result" | grep -q 'newserial'); then return 0; fi + return 1 +} + +_findentry() { + _debug "In _findentry" + #returns id of dns entry, if it exists + _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain" + jqquery=".cpanelresult.data[] | select(.name == \"$fulldomain.\")| {Line} | .Line" + _id=$(echo "$_result" | jq "$jqquery") + _debug "_result is: $_result" + _debug "fulldomain. is $fulldomain." + _debug "_id is: $_id" + if [ -n "$_id" ]; then + _debug "Entry found with _id=$_id" + return 0 + fi + return 1 +} From d4e1899747395971b276108402ffbb08f75a90b5 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 3 Oct 2021 19:02:45 +0800 Subject: [PATCH 1509/2234] support "--set-default-chain", fix https://github.com/acmesh-official/acme.sh/issues/3717 --- acme.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/acme.sh b/acme.sh index 0c4928f5..84fa1767 100755 --- a/acme.sh +++ b/acme.sh @@ -6547,6 +6547,8 @@ Commands: --deactivate Deactivate the domain authz, professional use. --set-default-ca Used with '--server', Set the default CA to use. See: $_SERVER_WIKI + --set-default-chain Set the default preferred chain for a CA. + See: $_PREFERRED_CHAIN_WIKI Parameters: @@ -6833,6 +6835,18 @@ setdefaultca() { _info "Changed default CA to: $(__green "$ACME_DIRECTORY")" } +#preferred-chain +setdefaultchain() { + _initpath + _preferred_chain="$1" + if [ -z "$_preferred_chain" ]; then + _err "Please give a '--preferred-chain value' value." + return 1 + fi + mkdir -p "$CA_DIR" + _savecaconf "DEFAULT_PREFERRED_CHAIN" "$_preferred_chain" +} + _process() { _CMD="" _domain="" @@ -6984,6 +6998,9 @@ _process() { --set-default-ca) _CMD="setdefaultca" ;; + --set-default-chain) + _CMD="setdefaultchain" + ;; -d | --domain) _dvalue="$2" @@ -7514,6 +7531,9 @@ _process() { setdefaultca) setdefaultca ;; + setdefaultchain) + setdefaultchain "$_preferred_chain" + ;; *) if [ "$_CMD" ]; then _err "Invalid command: $_CMD" From 64908e00804fe2464d05ade1b622173885fbdf07 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 3 Oct 2021 19:28:30 +0800 Subject: [PATCH 1510/2234] fix Windows path --- .github/workflows/Windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 8c8e2842..36af6934 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -54,7 +54,7 @@ jobs: - name: Set ENV shell: cmd run: | - echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV% + echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin;%PATH% >> %GITHUB_ENV% - name: Check ENV shell: cmd run: | From d2d023cca7fbb8d8b5e9136349a80b8b94c23382 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 13:35:22 +0200 Subject: [PATCH 1511/2234] added saving of cPanel_Hostname --- dnsapi/dns_cpanel.sh | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 4f25dc5c..868a411a 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -1,6 +1,7 @@ -#!/bin/bash +#!/usr/bin/env sh +# #Author: Bjarne Saltbaek -#Report Bugs here: https://github.com/acmesh-official/acme.sh +#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732 # # ######## Public functions ##################### @@ -10,8 +11,11 @@ # cPanel_Username=username # cPanel_Apitoken=apitoken # cPanel_Hostname=hostname +# +# Note: the program 'jq' must be availble on your system -#Usage: dns_cpanel_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record dns_cpanel_add() { fulldomain=$1 txtvalue=$2 @@ -26,7 +30,7 @@ dns_cpanel_add() { fi _debug "First detect the root zone" - if ! _get_domain "$fulldomain"; then + if ! _get_root "$fulldomain"; then _err "No matching root domain for $fulldomain found" return 1 fi @@ -40,8 +44,8 @@ dns_cpanel_add() { return 1 } -#Usage: fulldomain txtvalue -#Remove the txt record after validation. +# Usage: fulldomain txtvalue +# Used to remove the txt record after validation dns_cpanel_rm() { fulldomain=$1 txtvalue=$2 @@ -55,7 +59,7 @@ dns_cpanel_rm() { return 1 fi - if ! _get_domain; then + if ! _get_root; then _err "No matching root domain for $fulldomain found" return 1 fi @@ -79,17 +83,20 @@ dns_cpanel_rm() { _checkcredentials() { cPanel_Username="${cPanel_Username:-$(_readaccountconf_mutable cPanel_Username)}" cPanel_Apitoken="${cPanel_Apitoken:-$(_readaccountconf_mutable cPanel_Apitoken)}" + cPanel_Hostname="${cPanel_Hostname:-$(_readaccountconf_mutable cPanel_Hostname)}" - if [ -z "$cPanel_Username" ] || [ -z "$cPanel_Apitoken" ]; then + if [ -z "$cPanel_Username" ] || [ -z "$cPanel_Apitoken" ] || [ -z "$cPanel_Hostname" ]; then cPanel_Username="" cPanel_Apitoken="" - _err "You haven't specified cPanel username and apitoken yet." + cPanel_Hostname="" + _err "You haven't specified cPanel username, apitoken and hostname yet." _err "Please add credentials and try again." return 1 fi #save the credentials to the account conf file. _saveaccountconf_mutable cPanel_Username "$cPanel_Username" _saveaccountconf_mutable cPanel_Apitoken "$cPanel_Apitoken" + _saveaccountconf_mutable cPanel_Hostname "$cPanel_Hostname" return 0 } @@ -109,7 +116,7 @@ _myget() { _result=$(_get "$cPanel_Hostname/$1") } -_get_domain() { +_get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' _domains=$(echo "$_result" | jq '.cpanelresult.data[]| {zones}| .zones| keys' | sed -e 's/"//g' -e 's/,//g' -e 's/\[//g' -e 's/\]//g' -e '/^$/d' -e 's/[[:space:]]//g') _debug "_result is: $_result" From 84fe6654ccc351324f5d9204d170161d0cab2dc9 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 3 Oct 2021 20:59:55 +0800 Subject: [PATCH 1512/2234] fix for https://github.com/acmesh-official/acme.sh/issues/3717 --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 84fa1767..a5ac9e47 100755 --- a/acme.sh +++ b/acme.sh @@ -4934,7 +4934,9 @@ $_authorizations_map" echo "$response" >"$CERT_PATH" _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" - + if [ -z "$_preferred_chain" ]; then + _preferred_chain=$(_readcaconf DEFAULT_PREFERRED_CHAIN) + fi if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then if [ "$DEBUG" ]; then _debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" From 6a7f993a9a9d9e41977292498423a0aeb1bc1079 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 15:56:26 +0200 Subject: [PATCH 1513/2234] Forced CI --- dnsapi/dns_cpanel.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 868a411a..c3857aca 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -3,7 +3,6 @@ #Author: Bjarne Saltbaek #Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732 # -# ######## Public functions ##################### # Export CPANEL username,api token and hostname in the following variables From 68debc474abafe860f0aa6cb448ef7dc38168f4d Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 16:20:08 +0200 Subject: [PATCH 1514/2234] First jq rework --- dnsapi/dns_cpanel.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index c3857aca..99baf13a 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -11,8 +11,6 @@ # cPanel_Apitoken=apitoken # cPanel_Hostname=hostname # -# Note: the program 'jq' must be availble on your system - # Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Used to add txt record dns_cpanel_add() { @@ -117,7 +115,7 @@ _myget() { _get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' - _domains=$(echo "$_result" | jq '.cpanelresult.data[]| {zones}| .zones| keys' | sed -e 's/"//g' -e 's/,//g' -e 's/\[//g' -e 's/\]//g' -e '/^$/d' -e 's/[[:space:]]//g') + _domains=$(echo "$_result" | cut -d ':' -f9 | sed -e 's/"//g' -e 's/{//g' ) _debug "_result is: $_result" _debug "_domains is: $_domains" if [ -z "$_domains" ]; then From bd00db4292a0d6342292f0e2dd776c1f248ab491 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 16:25:21 +0200 Subject: [PATCH 1515/2234] First jq rework - redo --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 99baf13a..86d42506 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -115,7 +115,7 @@ _myget() { _get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' - _domains=$(echo "$_result" | cut -d ':' -f9 | sed -e 's/"//g' -e 's/{//g' ) + _domains=$(echo "$_result" | cut -d ':' -f9 | sed 's/"//g' | sed 's/{//g' ) _debug "_result is: $_result" _debug "_domains is: $_domains" if [ -z "$_domains" ]; then From 20f604948f943feca26b595fbeb21795c79e1a01 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 3 Oct 2021 22:31:56 +0800 Subject: [PATCH 1516/2234] Update pushbullet.sh --- notify/pushbullet.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/notify/pushbullet.sh b/notify/pushbullet.sh index 6f33b44f..76606c86 100644 --- a/notify/pushbullet.sh +++ b/notify/pushbullet.sh @@ -20,7 +20,9 @@ pushbullet_send() { _saveaccountconf_mutable PUSHBULLET_TOKEN "$PUSHBULLET_TOKEN" PUSHBULLET_DEVICE="${PUSHBULLET_DEVICE:-$(_readaccountconf_mutable PUSHBULLET_DEVICE)}" - if [ -z "$PUSHBULLET_DEVICE" ]; then + if [ -z "$PUSHBULLET_DEVICE" ]; then + _clearaccountconf_mutable PUSHBULLET_DEVICE + else _saveaccountconf_mutable PUSHBULLET_DEVICE "$PUSHBULLET_DEVICE" fi From 608547c62c292f0e3327af51572715d2dd40fc45 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 16:32:03 +0200 Subject: [PATCH 1517/2234] First jq rework - 3. redo --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 86d42506..e61e55ec 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -115,7 +115,7 @@ _myget() { _get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' - _domains=$(echo "$_result" | cut -d ':' -f9 | sed 's/"//g' | sed 's/{//g' ) + _domains=$(echo "$_result" | cut -d ':' -f9 | sed 's/"//g' | sed 's/{//g') _debug "_result is: $_result" _debug "_domains is: $_domains" if [ -z "$_domains" ]; then From f2958818c8ae1bb0f915d8418247802af2ac970e Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 3 Oct 2021 22:33:41 +0800 Subject: [PATCH 1518/2234] Update pushbullet.sh --- notify/pushbullet.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/pushbullet.sh b/notify/pushbullet.sh index 76606c86..ca997c84 100644 --- a/notify/pushbullet.sh +++ b/notify/pushbullet.sh @@ -20,7 +20,7 @@ pushbullet_send() { _saveaccountconf_mutable PUSHBULLET_TOKEN "$PUSHBULLET_TOKEN" PUSHBULLET_DEVICE="${PUSHBULLET_DEVICE:-$(_readaccountconf_mutable PUSHBULLET_DEVICE)}" - if [ -z "$PUSHBULLET_DEVICE" ]; then + if [ -z "$PUSHBULLET_DEVICE" ]; then _clearaccountconf_mutable PUSHBULLET_DEVICE else _saveaccountconf_mutable PUSHBULLET_DEVICE "$PUSHBULLET_DEVICE" From 8339b88180dc5e6f99d6035aa0bbbd47a9c2d82f Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 16:34:12 +0200 Subject: [PATCH 1519/2234] First jq rework - docker fails in Github - not my fault... --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index e61e55ec..237ecc30 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -4,7 +4,7 @@ #Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732 # ######## Public functions ##################### - +# # Export CPANEL username,api token and hostname in the following variables # # cPanel_Username=username From be827be74218d54ca8ee38a8959321167864dbb0 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 16:48:23 +0200 Subject: [PATCH 1520/2234] First jq rework - 4. redo --- dnsapi/dns_cpanel.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 237ecc30..f0776371 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -20,6 +20,9 @@ dns_cpanel_add() { _info "Adding TXT record to cPanel based system" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" + _debug cPanel_Username "$cPanel_Username" + _debug cPanel_Apitoken "$cPanel_Apitoken" + _debug cPanel_Hostname "$cPanel_Hostname" if ! _cpanel_login; then _err "cPanel Login failed for user $cPanel_Username. Check $HTTP_HEADER file" From 6b3d6d5211a36f722a8c8b5107b721b026343647 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 16:51:02 +0200 Subject: [PATCH 1521/2234] First jq rework - 5. redo --- dnsapi/dns_cpanel.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index f0776371..99a24965 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -24,6 +24,7 @@ dns_cpanel_add() { _debug cPanel_Apitoken "$cPanel_Apitoken" _debug cPanel_Hostname "$cPanel_Hostname" + if ! _cpanel_login; then _err "cPanel Login failed for user $cPanel_Username. Check $HTTP_HEADER file" return 1 From 0fdac82b935117b8e689c61703eac0940247e494 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 16:55:44 +0200 Subject: [PATCH 1522/2234] First jq rework - 6. redo --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 99a24965..eb77179c 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -119,7 +119,7 @@ _myget() { _get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' - _domains=$(echo "$_result" | cut -d ':' -f9 | sed 's/"//g' | sed 's/{//g') + _domains=$(echo "$_result" | cut -d ':' -f10 | sed 's/"//g' | sed 's/{//g') _debug "_result is: $_result" _debug "_domains is: $_domains" if [ -z "$_domains" ]; then From fda6502f33acf2deee09f62c0d0e422bf3fdd5d3 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 17:00:53 +0200 Subject: [PATCH 1523/2234] First jq rework - 7. redo --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index eb77179c..c9f62b11 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -119,7 +119,7 @@ _myget() { _get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' - _domains=$(echo "$_result" | cut -d ':' -f10 | sed 's/"//g' | sed 's/{//g') + _domains=$(echo "$_result" | cut -d ':' -f11 | sed 's/"//g' | sed 's/{//g') _debug "_result is: $_result" _debug "_domains is: $_domains" if [ -z "$_domains" ]; then From c9b353a689fab793e95b7cf2c3da610c404fb6e9 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 17:02:24 +0200 Subject: [PATCH 1524/2234] First jq rework - 8. redo --- dnsapi/dns_cpanel.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index c9f62b11..68888842 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -24,7 +24,6 @@ dns_cpanel_add() { _debug cPanel_Apitoken "$cPanel_Apitoken" _debug cPanel_Hostname "$cPanel_Hostname" - if ! _cpanel_login; then _err "cPanel Login failed for user $cPanel_Username. Check $HTTP_HEADER file" return 1 From 9264737985c8d35b970a1a33df98e5d7001369b1 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 17:04:49 +0200 Subject: [PATCH 1525/2234] First jq rework - 8. redo --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 68888842..cfd26d60 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -118,7 +118,7 @@ _myget() { _get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' - _domains=$(echo "$_result" | cut -d ':' -f11 | sed 's/"//g' | sed 's/{//g') + _domains=$(echo "$_result" | cut -d ':' -f10 | sed 's/"//g' | sed 's/{//g') _debug "_result is: $_result" _debug "_domains is: $_domains" if [ -z "$_domains" ]; then From 3184c3c21b94c82a2404dd25cc76ce3e741293f6 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 17:10:38 +0200 Subject: [PATCH 1526/2234] First jq rework - 9. redo --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index cfd26d60..f0776371 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -118,7 +118,7 @@ _myget() { _get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' - _domains=$(echo "$_result" | cut -d ':' -f10 | sed 's/"//g' | sed 's/{//g') + _domains=$(echo "$_result" | cut -d ':' -f9 | sed 's/"//g' | sed 's/{//g') _debug "_result is: $_result" _debug "_domains is: $_domains" if [ -z "$_domains" ]; then From f3cfef4021d82271938be9eeea72bd196ac23d10 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 17:40:01 +0200 Subject: [PATCH 1527/2234] First jq rework - 10. redo --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index f0776371..c794f121 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -118,7 +118,7 @@ _myget() { _get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' - _domains=$(echo "$_result" | cut -d ':' -f9 | sed 's/"//g' | sed 's/{//g') + _domains=$(echo "$_result" | sed 's/.*\(zones.*\[\).*/\1/' | cut -d':' -f2 | sed 's/"//g' | sed 's/{//g') _debug "_result is: $_result" _debug "_domains is: $_domains" if [ -z "$_domains" ]; then From 7bb0ff986b3698a993aeca8094ff17b8ba634527 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 17:50:57 +0200 Subject: [PATCH 1528/2234] First jq rework - 11. redo --- dnsapi/dns_cpanel.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index c794f121..d06fcfc7 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -144,8 +144,8 @@ _findentry() { _debug "In _findentry" #returns id of dns entry, if it exists _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain" - jqquery=".cpanelresult.data[] | select(.name == \"$fulldomain.\")| {Line} | .Line" - _id=$(echo "$_result" | jq "$jqquery") + _jqquery=".cpanelresult.data[] | select(.name == \"$fulldomain.\")| {Line} | .Line" + _id="" _debug "_result is: $_result" _debug "fulldomain. is $fulldomain." _debug "_id is: $_id" From bfda8f0b8a90aac03fd30df05c0023c87d2b6509 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 17:53:59 +0200 Subject: [PATCH 1529/2234] First jq rework - 12. redo --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index d06fcfc7..60360ebc 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -144,7 +144,7 @@ _findentry() { _debug "In _findentry" #returns id of dns entry, if it exists _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain" - _jqquery=".cpanelresult.data[] | select(.name == \"$fulldomain.\")| {Line} | .Line" + #_jqquery=".cpanelresult.data[] | select(.name == \"$fulldomain.\")| {Line} | .Line" _id="" _debug "_result is: $_result" _debug "fulldomain. is $fulldomain." From 17b18751518847317098cd588a07cb438ae4ff21 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 18:08:21 +0200 Subject: [PATCH 1530/2234] Added proper id lookup --- dnsapi/dns_cpanel.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 60360ebc..6fb65798 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -144,8 +144,7 @@ _findentry() { _debug "In _findentry" #returns id of dns entry, if it exists _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain" - #_jqquery=".cpanelresult.data[] | select(.name == \"$fulldomain.\")| {Line} | .Line" - _id="" + _id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1 _debug "_result is: $_result" _debug "fulldomain. is $fulldomain." _debug "_id is: $_id" From 15deec6c53e0efcc3d2aae372a9357298208c888 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 18:11:28 +0200 Subject: [PATCH 1531/2234] Added proper id lookup with missing bracket --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 6fb65798..0c6ee223 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -144,7 +144,7 @@ _findentry() { _debug "In _findentry" #returns id of dns entry, if it exists _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain" - _id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1 + _id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1) _debug "_result is: $_result" _debug "fulldomain. is $fulldomain." _debug "_id is: $_id" From d5b4f02932972befe1a083406b21f04af0b1f8be Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 18:13:05 +0200 Subject: [PATCH 1532/2234] Added proper id lookup with whitespace removed --- dnsapi/dns_cpanel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 0c6ee223..c8f1d027 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -144,7 +144,7 @@ _findentry() { _debug "In _findentry" #returns id of dns entry, if it exists _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain" - _id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1) + _id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1) _debug "_result is: $_result" _debug "fulldomain. is $fulldomain." _debug "_id is: $_id" From 86daaf4bf21e4ee31fa3b9badaaa4a7b7ce338b2 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 18:37:51 +0200 Subject: [PATCH 1533/2234] Added remove entry debug --- dnsapi/dns_cpanel.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index c8f1d027..bdda12fa 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -72,6 +72,7 @@ dns_cpanel_rm() { _debug "Deleting record..." _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=remove_zone_record&domain=$_domain&line=$_id" # removing entry + _debug "_result is: $_result" if _successful_update; then return 0; fi _err "Couldn't delete entry!" From a95e83ab6ef4b626a504cdb8f2d7d278932bd9ef Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sun, 3 Oct 2021 18:45:21 +0200 Subject: [PATCH 1534/2234] Added txtvalue to dns lookup --- dnsapi/dns_cpanel.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index bdda12fa..98d0ef34 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -145,9 +145,10 @@ _findentry() { _debug "In _findentry" #returns id of dns entry, if it exists _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain" - _id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1) + _id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain.*$txtvalue\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1) _debug "_result is: $_result" _debug "fulldomain. is $fulldomain." + _debug "txtvalue is $txtvalue" _debug "_id is: $_id" if [ -n "$_id" ]; then _debug "Entry found with _id=$_id" From aa7bf9169f36457088799c2befbfd50a24ca14e8 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Wed, 6 Oct 2021 14:01:18 +0200 Subject: [PATCH 1535/2234] Fix Word4You dns plugin to work with current api the value for uniqueFormIdTTL is not available or needed anymore. values for 'aktivPaket' are not needed by the api. changed endpoint for deletion from `/deleteRecord` to `/dns/record/delete` --- dnsapi/dns_world4you.sh | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 9ab406f6..94b9bb64 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -36,7 +36,6 @@ dns_world4you_add() { export _H1="Cookie: W4YSESSID=$sessid" form=$(_get "$WORLD4YOU_API/$paketnr/dns") formiddp=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/') - formidttl=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/') form_token=$(echo "$form" | grep 'AddDnsRecordForm\[_token\]' | sed 's/^.*name="AddDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/') if [ -z "$formiddp" ]; then _err "Unable to parse form" @@ -45,9 +44,7 @@ dns_world4you_add() { _resethttp export ACME_HTTP_NO_REDIRECTS=1 - body="AddDnsRecordForm[name]=$RECORD&AddDnsRecordForm[dnsType][type]=TXT&\ -AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\ -AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_token" + body="AddDnsRecordForm[name]=$RECORD&AddDnsRecordForm[dnsType][type]=TXT&AddDnsRecordForm[value]=$value&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&AddDnsRecordForm[_token]=$form_token" _info "Adding record..." ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded') _resethttp @@ -101,7 +98,6 @@ dns_world4you_rm() { form=$(_get "$WORLD4YOU_API/$paketnr/dns") formiddp=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/') - formidttl=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/') form_token=$(echo "$form" | grep 'DeleteDnsRecordForm\[_token\]' | sed 's/^.*name="DeleteDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/') if [ -z "$formiddp" ]; then _err "Unable to parse form" @@ -113,11 +109,9 @@ dns_world4you_rm() { _resethttp export ACME_HTTP_NO_REDIRECTS=1 - body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[aktivPaket]=$paketnr&\ -DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[uniqueFormIdTTL]=$formidttl&\ -DeleteDnsRecordForm[_token]=$form_token" + body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[_token]=$form_token" _info "Removing record..." - ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/deleteRecord" '' POST 'application/x-www-form-urlencoded') + ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns/record/delete" '' POST 'application/x-www-form-urlencoded') _resethttp if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then From ea4266538ae27200d385528781a13e9986628378 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Thu, 7 Oct 2021 20:21:51 +0200 Subject: [PATCH 1536/2234] force a re-test --- dnsapi/dns_cpanel.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 98d0ef34..2ff88578 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -2,7 +2,6 @@ # #Author: Bjarne Saltbaek #Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732 -# ######## Public functions ##################### # # Export CPANEL username,api token and hostname in the following variables From e11d0d37ee3eaa0b863b8d406e2a3f85c1c52f23 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Thu, 7 Oct 2021 20:51:18 +0200 Subject: [PATCH 1537/2234] force a re-test. Le servere fails during test --- dnsapi/dns_cpanel.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 2ff88578..98d0ef34 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -2,6 +2,7 @@ # #Author: Bjarne Saltbaek #Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732 +# ######## Public functions ##################### # # Export CPANEL username,api token and hostname in the following variables From 40e8c5e2b0adbca56e8e055b46b3ebb985fc4a73 Mon Sep 17 00:00:00 2001 From: Phil Krylov Date: Fri, 8 Oct 2021 18:24:21 +0200 Subject: [PATCH 1538/2234] Don't use global variable as local in recursion context ```nginx include conf.d/*; include sites-enabled/*; ``` In this situation, after the first recursive `_checkConf` invocation 4 lines below, `$_c_file` does not contain what you expect anymore, and the second lookup checks for `conf.d/sites-enabled/*` which is obviously wrong. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index a5ac9e47..e32693b1 100755 --- a/acme.sh +++ b/acme.sh @@ -3168,7 +3168,7 @@ _checkConf() { for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do _debug "check included $included" if ! _startswith "$included" "/" && _exists dirname; then - _relpath="$(dirname "$_c_file")" + _relpath="$(dirname "$2")" _debug "_relpath" "$_relpath" included="$_relpath/$included" fi From 1d2af0f2912f3f8dfa1a2ccb09f496279979f4d8 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Fri, 8 Oct 2021 20:10:46 +0200 Subject: [PATCH 1539/2234] force a re-test. --- dnsapi/dns_cpanel.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 98d0ef34..f91725a4 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -3,6 +3,7 @@ #Author: Bjarne Saltbaek #Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732 # +# ######## Public functions ##################### # # Export CPANEL username,api token and hostname in the following variables From 38a067e203a1cff25899407845c0cc831b40d8d3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 12 Oct 2021 20:55:11 +0800 Subject: [PATCH 1540/2234] fix https://github.com/acmesh-official/acme.sh/issues/3752 --- acme.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index e32693b1..66291224 100755 --- a/acme.sh +++ b/acme.sh @@ -4222,12 +4222,6 @@ issue() { return 1 fi - _debug "Using ACME_DIRECTORY: $ACME_DIRECTORY" - - if ! _initAPI; then - return 1 - fi - if [ -f "$DOMAIN_CONF" ]; then Le_NextRenewTime=$(_readdomainconf Le_NextRenewTime) _debug Le_NextRenewTime "$Le_NextRenewTime" @@ -4247,6 +4241,11 @@ issue() { fi fi + _debug "Using ACME_DIRECTORY: $ACME_DIRECTORY" + if ! _initAPI; then + return 1 + fi + _savedomainconf "Le_Domain" "$_main_domain" _savedomainconf "Le_Alt" "$_alt_domains" _savedomainconf "Le_Webroot" "$_web_roots" @@ -5131,7 +5130,6 @@ renew() { CA_CONF="" _debug3 "initpath again." _initpath "$Le_Domain" "$_isEcc" - _initAPI fi if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then From 32ea224933e138915f505ee1a7b15e65f2c0085b Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 12 Oct 2021 21:31:06 +0800 Subject: [PATCH 1541/2234] update versions --- .github/workflows/FreeBSD.yml | 6 +++--- .github/workflows/Solaris.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 6a82156d..316da402 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -28,7 +28,7 @@ jobs: CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" CA_EMAIL: "githubtest@acme.sh" - runs-on: macos-latest + runs-on: macos-10.15 env: TEST_LOCAL: 1 TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} @@ -37,7 +37,7 @@ jobs: CA_EMAIL: ${{ matrix.CA_EMAIL }} steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.2 + - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: protocol: http @@ -46,7 +46,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.4 + - uses: vmactions/freebsd-vm@v0.1.5 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL' nat: | diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 9d1c46ac..723a1237 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -28,7 +28,7 @@ jobs: CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" CA_EMAIL: "githubtest@acme.sh" - runs-on: macos-latest + runs-on: macos-10.15 env: TEST_LOCAL: 1 TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} @@ -37,7 +37,7 @@ jobs: CA_EMAIL: ${{ matrix.CA_EMAIL }} steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.2 + - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: protocol: http From 1760169ef9119259105ba5b79a730bbddd91456c Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 12 Oct 2021 23:43:20 +0800 Subject: [PATCH 1542/2234] fix Windows test --- .github/workflows/Windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 36af6934..dd147e85 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -49,7 +49,7 @@ jobs: shell: cmd - name: Install cygwin additional packages run: | - C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git + C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git,xxd shell: cmd - name: Set ENV shell: cmd From 365d22d0768994b1457312803fc0913b72596c7f Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 13 Oct 2021 00:03:12 +0800 Subject: [PATCH 1543/2234] add TEST_PREFERRED_CHAIN --- .github/workflows/FreeBSD.yml | 5 ++++- .github/workflows/Linux.yml | 1 + .github/workflows/MacOS.yml | 3 +++ .github/workflows/Solaris.yml | 5 ++++- .github/workflows/Ubuntu.yml | 3 +++ .github/workflows/Windows.yml | 3 +++ 6 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 316da402..40da24cf 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -24,10 +24,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" + TEST_PREFERRED_CHAIN: Fake LE Root X2 - 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 @@ -35,6 +37,7 @@ jobs: CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - uses: vmactions/cf-tunnel@v0.0.3 @@ -48,7 +51,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0.1.5 with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | "8080": "80" prepare: pkg install -y socat curl diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 7e7eba87..ba81391d 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -24,6 +24,7 @@ jobs: runs-on: ubuntu-latest env: TEST_LOCAL: 1 + TEST_PREFERRED_CHAIN: Fake LE Root X2 steps: - uses: actions/checkout@v2 - name: Clone acmetest diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index 85ec7527..db87db23 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -24,10 +24,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" + TEST_PREFERRED_CHAIN: Fake LE Root X2 - 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 @@ -35,6 +37,7 @@ jobs: CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - name: Install tools diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 723a1237..56c53870 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -24,10 +24,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" + TEST_PREFERRED_CHAIN: Fake LE Root X2 - 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 @@ -35,6 +37,7 @@ jobs: CA_ECDSA: ${{ matrix.CA_ECDSA }} CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - uses: vmactions/cf-tunnel@v0.0.3 @@ -48,7 +51,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0.0.3 with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | "8080": "80" prepare: pkgutil -y -i socat curl diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index af74965a..e5fe2901 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -24,10 +24,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" + TEST_PREFERRED_CHAIN: Fake LE Root X2 - 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: ubuntu-latest env: @@ -37,6 +39,7 @@ jobs: CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} NO_ECC_384: ${{ matrix.NO_ECC_384 }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - name: Install tools diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index dd147e85..f2f687f2 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -24,10 +24,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" + TEST_PREFERRED_CHAIN: Fake LE Root X2 - 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 }} @@ -37,6 +39,7 @@ jobs: TEST_LOCAL: 1 #The 80 port is used by Windows server, we have to use a custom port, tunnel will also use this port. Le_HTTPPort: 8888 + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - name: Set git to use LF run: | From 0510da0853dd25c1741709e69ce726245c240c75 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 13 Oct 2021 00:28:14 +0800 Subject: [PATCH 1544/2234] fix test chain root name. --- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/Linux.yml | 2 +- .github/workflows/MacOS.yml | 2 +- .github/workflows/Solaris.yml | 2 +- .github/workflows/Ubuntu.yml | 2 +- .github/workflows/Windows.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 40da24cf..5d032769 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -24,7 +24,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: Fake LE Root X2 + 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" diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index ba81391d..cba708b3 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest env: TEST_LOCAL: 1 - TEST_PREFERRED_CHAIN: Fake LE Root X2 + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 steps: - uses: actions/checkout@v2 - name: Clone acmetest diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index db87db23..4b529f6a 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -24,7 +24,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: Fake LE Root X2 + 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" diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 56c53870..4df10099 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -24,7 +24,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: Fake LE Root X2 + 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" diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index e5fe2901..28b06541 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -24,7 +24,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: Fake LE Root X2 + 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" diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index f2f687f2..2d7eeeae 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -24,7 +24,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: Fake LE Root X2 + 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" From 21ef3b0ecf622d8209b2ac04c6c9e137f952b679 Mon Sep 17 00:00:00 2001 From: wacki4 Date: Sat, 16 Oct 2021 14:08:03 +0200 Subject: [PATCH 1545/2234] Update dns_opnsense.sh Update for opnsense regards to error in #3735 --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 069f6c32..63723f5a 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\"(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{.*}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" From 00b6c6a437d2d11bbbf29c228f308d51d206b3de Mon Sep 17 00:00:00 2001 From: wacki4 Date: Sat, 16 Oct 2021 16:57:12 +0200 Subject: [PATCH 1546/2234] Update dns_opnsense.sh Correction when having many zones. --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 63723f5a..26a422f8 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{.*}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"\":{[^}]*}}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" From 6e7ce1eec132cd0b5e7e975ecdd03fea68c87cbe Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Wed, 20 Oct 2021 14:28:55 +0200 Subject: [PATCH 1547/2234] dns_world4you: fix for freeBSD sed Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 94b9bb64..231c34b3 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -184,7 +184,7 @@ _get_paketnr() { fqdn="$1" form="$2" - domains=$(echo "$form" | grep '^ *[A-Za-z0-9_\.-]*\.[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/') + domains=$(echo "$form" | grep '^ *[A-Za-z0-9_\.-]*\.[A-Za-z0-9_-]*$' | sed 's/^ *\(.*\)$/\1/') domain='' for domain in $domains; do if _contains "$fqdn" "$domain\$"; then From 401fd37e35c4b9e56b2fea333772530149d96281 Mon Sep 17 00:00:00 2001 From: Reto Schuettel Date: Wed, 20 Oct 2021 18:18:02 +0200 Subject: [PATCH 1548/2234] dns_gcloud: allowrecord-sets list output to be separated by 'semicolon' gcloud dns record-sets list used to separate records by comma, with version 353.0.0 the tool uses semicolons instead. --- dnsapi/dns_gcloud.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index 03060a8c..d560996c 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -163,5 +163,8 @@ _dns_gcloud_get_rrdatas() { return 1 fi ttl=$(echo "$rrdatas" | cut -f1) - rrdatas=$(echo "$rrdatas" | cut -f2 | sed 's/","/"\n"/g') + # starting with version 353.0.0 gcloud seems to + # separate records with a semicolon instead of commas + # see also https://cloud.google.com/sdk/docs/release-notes#35300_2021-08-17 + rrdatas=$(echo "$rrdatas" | cut -f2 | sed 's/"[,;]"/"\n"/g') } From a31ed4a723bf01b7ee51db5402002dfbb893c0f4 Mon Sep 17 00:00:00 2001 From: Miguel Angelo Date: Tue, 23 Jun 2020 17:55:14 -0300 Subject: [PATCH 1549/2234] Notify user about a possible problem when using synology_dsm.sh with 2fa enabled user account --- deploy/synology_dsm.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 5a70c74e..177b3fbe 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -100,6 +100,7 @@ synology_dsm_deploy() { if [ -z "$token" ]; then _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." _err "Check your username and password." + _err "If two-factor authentication is enabled for the user, you have to choose another user." return 1 fi sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p') From dbdcbd4b9e64acd8b0626cb6ca9a886b4693ce84 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 2 Nov 2021 20:37:14 +0800 Subject: [PATCH 1550/2234] add set-default-chain --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index c42f4f39..fb842c83 100644 --- a/Dockerfile +++ b/Dockerfile @@ -55,6 +55,7 @@ RUN for verb in help \ deactivate-account \ set-notify \ set-default-ca \ + set-default-chain \ ; do \ printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \ ; done From 35d6da785bf6bc4fc8267bbc16057192bf9a6553 Mon Sep 17 00:00:00 2001 From: jearton Date: Thu, 4 Nov 2021 00:41:58 +0800 Subject: [PATCH 1551/2234] add support for feishu notification --- notify/feishu.sh | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 notify/feishu.sh diff --git a/notify/feishu.sh b/notify/feishu.sh new file mode 100644 index 00000000..80ae9c45 --- /dev/null +++ b/notify/feishu.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env sh + +#Support feishu webhooks api + +#required +#FEISHU_WEBHOOK="xxxx" + +#optional +#FEISHU_KEYWORD="yyyy" + +# subject content statusCode +feishu_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + FEISHU_WEBHOOK="${FEISHU_WEBHOOK:-$(_readaccountconf_mutable FEISHU_WEBHOOK)}" + if [ -z "$FEISHU_WEBHOOK" ]; then + FEISHU_WEBHOOK="" + _err "You didn't specify a feishu webhooks FEISHU_WEBHOOK yet." + _err "You can get yours from https://www.feishu.cn" + return 1 + fi + _saveaccountconf_mutable FEISHU_WEBHOOK "$FEISHU_WEBHOOK" + + FEISHU_KEYWORD="${FEISHU_KEYWORD:-$(_readaccountconf_mutable FEISHU_KEYWORD)}" + if [ "$FEISHU_KEYWORD" ]; then + _saveaccountconf_mutable FEISHU_KEYWORD "$FEISHU_KEYWORD" + fi + + _content=$(echo "$_content" | _json_encode) + _subject=$(echo "$_subject" | _json_encode) + _data="{\"msg_type\": \"text\", \"content\": {\"text\": \"[$FEISHU_KEYWORD]\n$_subject\n$_content\"}}" + + response="$(_post "$_data" "$FEISHU_WEBHOOK" "" "POST" "application/json")" + + if [ "$?" = "0" ] && _contains "$response" "StatusCode\":0"; then + _info "feishu webhooks event fired success." + return 0 + fi + + _err "feishu webhooks event fired error." + _err "$response" + return 1 +} \ No newline at end of file From e8756482aa5884c0c85915cfde7b38aba4d8a3ed Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 4 Nov 2021 09:42:30 +0800 Subject: [PATCH 1552/2234] Update feishu.sh --- notify/feishu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/feishu.sh b/notify/feishu.sh index 80ae9c45..18693c2d 100644 --- a/notify/feishu.sh +++ b/notify/feishu.sh @@ -45,4 +45,4 @@ feishu_send() { _err "feishu webhooks event fired error." _err "$response" return 1 -} \ No newline at end of file +} From 7d249b6d3bda3503c9a1c8c83fdead9731472f0f Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 6 Nov 2021 09:52:21 +0800 Subject: [PATCH 1553/2234] start 3.0.2 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 66291224..9d576143 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.1 +VER=3.0.2 PROJECT_NAME="acme.sh" From 6ae8d101325d2df817664e197fd72ae26347c25f Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Dec 2020 15:10:42 +0800 Subject: [PATCH 1554/2234] support ip cert: rfc https://tools.ietf.org/html/rfc8738 --- acme.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/acme.sh b/acme.sh index 9d576143..2ddad09e 100755 --- a/acme.sh +++ b/acme.sh @@ -59,6 +59,9 @@ VTYPE_HTTP="http-01" VTYPE_DNS="dns-01" VTYPE_ALPN="tls-alpn-01" +ID_TYPE_DNS="dns" +ID_TYPE_IP="ip" + LOCAL_ANY_ADDRESS="0.0.0.0" DEFAULT_RENEW=60 @@ -1222,19 +1225,26 @@ _createcsr() { if [ "$acmeValidationv1" ]; then domainlist="$(_idn "$domainlist")" - printf -- "\nsubjectAltName=DNS:$domainlist" >>"$csrconf" + _debug2 domainlist "$domainlist" + for dl in $(echo "$domainlist" | tr "," ' '); do + if [ "$alt" ]; then + alt="$alt,$(_getIdType "$dl" | _upper_case):$dl" + else + alt="$(_getIdType "$dl" | _upper_case):$dl" + fi + done + printf -- "\nsubjectAltName=$alt" >>"$csrconf" elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then #single domain _info "Single domain" "$domain" - printf -- "\nsubjectAltName=DNS:$(_idn "$domain")" >>"$csrconf" + printf -- "\nsubjectAltName=$(_getIdType "$domain" | _upper_case):$(_idn "$domain")" >>"$csrconf" else domainlist="$(_idn "$domainlist")" _debug2 domainlist "$domainlist" - if _contains "$domainlist" ","; then - alt="DNS:$(_idn "$domain"),DNS:$(echo "$domainlist" | sed "s/,,/,/g" | sed "s/,/,DNS:/g")" - else - alt="DNS:$(_idn "$domain"),DNS:$domainlist" - fi + alt="$(_getIdType "$domain" | _upper_case):$domain" + for dl in $(echo "$domainlist" | tr "," ' '); do + alt="$alt,$(_getIdType "$dl" | _upper_case):$dl" + done #multi _info "Multi domain" "$alt" printf -- "\nsubjectAltName=$alt" >>"$csrconf" @@ -4174,6 +4184,36 @@ _match_issuer() { _contains "$_rootissuer" "$_missuer" } +#ip +_isIPv4() { + for seg in $(echo "$1" | tr '.' ' '); do + if [ $seg -ge 0 ] 2>/dev/null && [ $seg -le 255 ] 2>/dev/null; then + continue + fi + return 1 + done + return 0 +} + +#ip6 +_isIPv6() { + _contains "$1" ":" +} + +#ip +_isIP() { + _isIPv4 "$1" || _isIPv6 "$1" +} + +#identifier +_getIdType() { + if _isIP "$1"; then + echo "$ID_TYPE_IP"; + else + echo "$ID_TYPE_DNS"; + fi +} + #webroot, domain domainlist keylength issue() { if [ -z "$2" ]; then @@ -4330,7 +4370,7 @@ issue() { dvsep=',' if [ -z "$vlist" ]; then #make new order request - _identifiers="{\"type\":\"dns\",\"value\":\"$(_idn "$_main_domain")\"}" + _identifiers="{\"type\":\"$(_getIdType "$_main_domain")\",\"value\":\"$(_idn "$_main_domain")\"}" _w_index=1 while true; do d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")" @@ -4339,7 +4379,7 @@ issue() { if [ -z "$d" ]; then break fi - _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn "$d")\"}" + _identifiers="$_identifiers,{\"type\":\"$(_getIdType "$d")\",\"value\":\"$(_idn "$d")\"}" done _debug2 _identifiers "$_identifiers" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then From 737a7a2db27e3d27f79036388e55168b3bdfceb1 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Dec 2020 22:04:11 +0800 Subject: [PATCH 1555/2234] add test for ipcert --- .github/workflows/PebbleStrict.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index f7907d8b..c1ea1cd2 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -35,5 +35,28 @@ jobs: run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh + + PebbleStrict_IPCert: + runs-on: ubuntu-latest + env: + TestingDomain: 10.30.50.1 + ACME_DIRECTORY: https://localhost:14000/dir + HTTPS_INSECURE: 1 + Le_HTTPPort: 5002 + Le_TLSPort: 5001 + TEST_LOCAL: 1 + TEST_CA: "Pebble Intermediate CA" + TEST_IPCERT: 1 + + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat + - name: Run Pebble + run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest run: cd ../acmetest && ./letest.sh \ No newline at end of file From fe77d43fa0362ad48d71c9dd2cb6416ed1a64896 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Dec 2020 22:57:58 +0800 Subject: [PATCH 1556/2234] fix _deactivate for ip cert --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 2ddad09e..360fb672 100755 --- a/acme.sh +++ b/acme.sh @@ -5978,7 +5978,7 @@ _deactivate() { thumbprint="$(__calc_account_thumbprint)" fi _debug "Trigger validation." - vtype="$VTYPE_DNS" + vtype="$(_getIdType "$_d_domain")" entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" if [ -z "$entry" ]; then From e6e07714966d6fa35b27c58c2a23cbf7a8777ae4 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Dec 2020 23:20:26 +0800 Subject: [PATCH 1557/2234] fix for ip cert alpn mode --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index 360fb672..85c3b6dd 100755 --- a/acme.sh +++ b/acme.sh @@ -1226,6 +1226,7 @@ _createcsr() { if [ "$acmeValidationv1" ]; then domainlist="$(_idn "$domainlist")" _debug2 domainlist "$domainlist" + alt="" for dl in $(echo "$domainlist" | tr "," ' '); do if [ "$alt" ]; then alt="$alt,$(_getIdType "$dl" | _upper_case):$dl" From e488220bfc7ebeef56a0406011fec17b9bd02e5d Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Dec 2020 20:13:05 +0800 Subject: [PATCH 1558/2234] fix for solaris --- acme.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 85c3b6dd..107bd998 100755 --- a/acme.sh +++ b/acme.sh @@ -429,13 +429,11 @@ _secure_debug3() { } _upper_case() { - # shellcheck disable=SC2018,SC2019 - tr 'a-z' 'A-Z' + tr '[:lower:]' '[:upper:]' } _lower_case() { - # shellcheck disable=SC2018,SC2019 - tr 'A-Z' 'a-z' + tr '[:upper:]' '[:lower:]' } _startswith() { From 3f58823430ccecb9491e481c7a70089fb5ceaa22 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 6 Nov 2021 11:26:06 +0800 Subject: [PATCH 1559/2234] fix ip cert --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 107bd998..a385aa07 100755 --- a/acme.sh +++ b/acme.sh @@ -5941,7 +5941,7 @@ _deactivate() { _initAPI fi - _identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}" + _identifiers="{\"type\":\"$(_getIdType "$_d_domain")\",\"value\":\"$_d_domain\"}" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then _err "Can not get domain new order." return 1 From b8bfb5a56cb99ce8581091c4e6e34bedff05f583 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 6 Nov 2021 11:28:11 +0800 Subject: [PATCH 1560/2234] fix format --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index a385aa07..96f90208 100755 --- a/acme.sh +++ b/acme.sh @@ -4207,9 +4207,9 @@ _isIP() { #identifier _getIdType() { if _isIP "$1"; then - echo "$ID_TYPE_IP"; + echo "$ID_TYPE_IP" else - echo "$ID_TYPE_DNS"; + echo "$ID_TYPE_DNS" fi } From f63409eed9430debea571055687e3c1e9cbb5c8b Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 6 Nov 2021 12:27:50 +0800 Subject: [PATCH 1561/2234] fix https://github.com/acmesh-official/acme.sh/issues/1559 --- acme.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 96f90208..2786bbc5 100755 --- a/acme.sh +++ b/acme.sh @@ -5713,8 +5713,16 @@ installcronjob() { if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY" else - _err "Can not install cronjob, $PROJECT_ENTRY not found." - return 1 + _debug "_SCRIPT_" "$_SCRIPT_" + _script="$(_readlink "$_SCRIPT_")" + _debug _script "$_script" + if [ -f "$_script" ]; then + _info "Using the current script from: $_script" + lesh="$_script" + else + _err "Can not install cronjob, $PROJECT_ENTRY not found." + return 1 + fi fi if [ "$_c_home" ]; then _c_entry="--config-home \"$_c_home\" " From ee2dab51f3a8ac4445565f9aad3e084fcafaf40f Mon Sep 17 00:00:00 2001 From: Scre13 Date: Mon, 8 Nov 2021 22:13:14 +0100 Subject: [PATCH 1562/2234] removed newline at the end of subject, added MIME-Version header --- notify/mail.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/notify/mail.sh b/notify/mail.sh index 2cbddb63..23730bef 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -62,7 +62,7 @@ mail_send() { fi contenttype="text/plain; charset=utf-8" - subject="=?UTF-8?B?$(echo "$_subject" | _base64)?=" + subject="=?UTF-8?B?$(printf "$_subject" "%b" | _base64)?=" result=$({ _mail_body | eval "$(_mail_cmnd)"; } 2>&1) # shellcheck disable=SC2181 @@ -131,6 +131,7 @@ _mail_body() { echo "To: $MAIL_TO" echo "Subject: $subject" echo "Content-Type: $contenttype" + echo "MIME-Version: 1.0" echo ;; esac From 95bbf1b19071c3182b5d350be571ef1ed21504c7 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 9 Nov 2021 09:30:36 +0800 Subject: [PATCH 1563/2234] Update mail.sh --- notify/mail.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/mail.sh b/notify/mail.sh index 23730bef..5a5b18e2 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -62,7 +62,7 @@ mail_send() { fi contenttype="text/plain; charset=utf-8" - subject="=?UTF-8?B?$(printf "$_subject" "%b" | _base64)?=" + subject="=?UTF-8?B?$(printf "%b" -- "$_subject" | _base64)?=" result=$({ _mail_body | eval "$(_mail_cmnd)"; } 2>&1) # shellcheck disable=SC2181 From 2b2845aa0729b832e5c3ade841c878b050cfdc20 Mon Sep 17 00:00:00 2001 From: Scre13 Date: Tue, 9 Nov 2021 04:28:30 +0100 Subject: [PATCH 1564/2234] removed -- at beginning of subject --- notify/mail.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/mail.sh b/notify/mail.sh index 5a5b18e2..584d650f 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -62,7 +62,7 @@ mail_send() { fi contenttype="text/plain; charset=utf-8" - subject="=?UTF-8?B?$(printf "%b" -- "$_subject" | _base64)?=" + subject="=?UTF-8?B?$(printf "%b" "$_subject" | _base64)?=" result=$({ _mail_body | eval "$(_mail_cmnd)"; } 2>&1) # shellcheck disable=SC2181 From eb6395a62cbeb92b08da23b681a95eab3b847bae Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 9 Nov 2021 11:48:58 +0800 Subject: [PATCH 1565/2234] Update mail.sh --- notify/mail.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/mail.sh b/notify/mail.sh index 584d650f..656dd371 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -62,7 +62,7 @@ mail_send() { fi contenttype="text/plain; charset=utf-8" - subject="=?UTF-8?B?$(printf "%b" "$_subject" | _base64)?=" + subject="=?UTF-8?B?$(printf -- "%b" "$_subject" | _base64)?=" result=$({ _mail_body | eval "$(_mail_cmnd)"; } 2>&1) # shellcheck disable=SC2181 From 3bcb91f6ae0c0b09203cf5a66b3aa66f76c7c527 Mon Sep 17 00:00:00 2001 From: F-Plass <60349140+F-Plass@users.noreply.github.com> Date: Thu, 11 Nov 2021 23:03:00 +0100 Subject: [PATCH 1566/2234] Update truenas.sh solved the problem of UI-Restart after 12.0-U3 --- deploy/truenas.sh | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 7d8f3238..6f1a31b0 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -35,19 +35,6 @@ truenas_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - if _exists "curl"; then - _debug "curl found, no Message to restartUI error" - else - if _exists "wget"; then - _err "Until Version of TrueNAS is older than TrueNAS-12.0-U2 there are problems with using wget" - _err "There is a bug when using the API Call restartUI with wget" - _err "The API call does not give any response, whit wget the api call restartUI would be called about 20 times" - _err "Please use curl!" - _err "Bug Report at https://jira.ixsystems.com/browse/NAS-109435" - return 1 - fi - fi - _getdeployconf DEPLOY_TRUENAS_APIKEY if [ -z "$DEPLOY_TRUENAS_APIKEY" ]; then @@ -182,9 +169,6 @@ truenas_deploy() { _info "Reload WebUI from TrueNAS" _restart_UI=$(_get "$_api_url/system/general/ui_restart") - _info "Until Version of TrueNAS is older than TrueNAS-12.0-U3 curl returns error 52" - _info "This is not a problem for tis scipt" - _info "See Bugreport: https://jira.ixsystems.com/browse/NAS-109435" _debug2 _restart_UI "$_restart_UI" if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ]; then From 18e4d270d991b772ecd24d4751304372810e7eb3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 13 Nov 2021 15:23:32 +0800 Subject: [PATCH 1567/2234] fix https://github.com/acmesh-official/acme.sh/issues/3806 --- acme.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 2786bbc5..d2e8b04d 100755 --- a/acme.sh +++ b/acme.sh @@ -429,17 +429,27 @@ _secure_debug3() { } _upper_case() { - tr '[:lower:]' '[:upper:]' + if _is_solaris; then + tr '[:lower:]' '[:upper:]' + else + # shellcheck disable=SC2018,SC2019 + tr 'a-z' 'A-Z' + fi } _lower_case() { - tr '[:upper:]' '[:lower:]' + if _is_solaris; then + tr '[:upper:]' '[:lower:]' + else + # shellcheck disable=SC2018,SC2019 + tr 'A-Z' 'a-z' + fi } _startswith() { _str="$1" _sub="$2" - echo "$_str" | grep "^$_sub" >/dev/null 2>&1 + echo "$_str" | grep -- "^$_sub" >/dev/null 2>&1 } _endswith() { From 4635dacf7ff0285f523b7a7b3fc9b54e8f40891a Mon Sep 17 00:00:00 2001 From: Nasser Alansari Date: Sat, 13 Nov 2021 12:56:10 +0300 Subject: [PATCH 1568/2234] Add SYNO_TOTP_SECRET for user with two-factor authentication --- deploy/synology_dsm.sh | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 177b3fbe..66e28f93 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -2,8 +2,7 @@ # Here is a script to deploy cert to Synology DSM # -# it requires the jq and curl are in the $PATH and the following -# environment variables must be set: +# It requires following environment variables: # # SYNO_Username - Synology Username to login (must be an administrator) # SYNO_Password - Synology Password to login @@ -16,6 +15,12 @@ # SYNO_Hostname - defaults to localhost # SYNO_Port - defaults to 5000 # SYNO_DID - device ID to skip OTP - defaults to empty +# SYNO_TOTP_SECRET - TOTP secret to generate OTP - defaults to empty +# +# Dependencies: +# ------------- +# - jq and curl +# - oathtool (When using 2 Factor Authentication and SYNO_TOTP_SECRET is set) # #returns 0 means success, otherwise error. @@ -36,6 +41,7 @@ synology_dsm_deploy() { _getdeployconf SYNO_Password _getdeployconf SYNO_Create _getdeployconf SYNO_DID + _getdeployconf SYNO_TOTP_SECRET if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then _err "SYNO_Username & SYNO_Password must be set" return 1 @@ -86,13 +92,18 @@ synology_dsm_deploy() { encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" + otp_code="" + if [ -n "$SYNO_TOTP_SECRET" ]; then + otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" + fi + if [ -n "$SYNO_DID" ]; then _H1="Cookie: did=$SYNO_DID" export _H1 _debug3 H1 "${_H1}" fi - response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') _debug3 response "$response" _debug token "$token" @@ -100,7 +111,7 @@ synology_dsm_deploy() { if [ -z "$token" ]; then _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." _err "Check your username and password." - _err "If two-factor authentication is enabled for the user, you have to choose another user." + _err "If two-factor authentication is enabled for the user, set SYNO_TOTP_SECRET." return 1 fi sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p') @@ -113,6 +124,7 @@ synology_dsm_deploy() { _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" _savedeployconf SYNO_DID "$SYNO_DID" + _savedeployconf SYNO_TOTP_SECRET "$SYNO_TOTP_SECRET" _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") From 5e5ba116010b0f2aef39b4adba864288646a5386 Mon Sep 17 00:00:00 2001 From: Hao Guan <10684225+hguandl@users.noreply.github.com> Date: Sun, 21 Nov 2021 02:39:46 +0800 Subject: [PATCH 1569/2234] Add iOS Bark notify hook. --- notify/bark.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 notify/bark.sh diff --git a/notify/bark.sh b/notify/bark.sh new file mode 100644 index 00000000..bbd5bf34 --- /dev/null +++ b/notify/bark.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env sh + +#Support iOS Bark Notification + +#BARK_API_URL="https://api.day.app/xxxx" +#BARK_SOUND="yyyy" +#BARK_GROUP="zzzz" + +# subject content statusCode +bark_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + BARK_API_URL="${BARK_API_URL:-$(_readaccountconf_mutable BARK_API_URL)}" + if [ -z "$BARK_API_URL" ]; then + BARK_API_URL="" + _err "You didn't specify a Bark API URL BARK_API_URL yet." + _err "You can download Bark from App Store and get yours." + return 1 + fi + _saveaccountconf_mutable BARK_API_URL "$BARK_API_URL" + + BARK_SOUND="${BARK_SOUND:-$(_readaccountconf_mutable BARK_SOUND)}" + _saveaccountconf_mutable BARK_SOUND "$BARK_SOUND" + + BARK_GROUP="${BARK_GROUP:-$(_readaccountconf_mutable BARK_GROUP)}" + if [ -z "$BARK_GROUP" ]; then + BARK_GROUP="ACME" + _info "The BARK_GROUP is not set, so use the default ACME as group name." + else + _saveaccountconf_mutable BARK_GROUP "$BARK_GROUP" + fi + + _content=$(echo "$_content" | _url_encode) + _subject=$(echo "$_subject" | _url_encode) + + response="$(_get "$BARK_API_URL/$_subject/$_content?sound=$BARK_SOUND&group=$BARK_GROUP")" + + if [ "$?" = "0" ] && _contains "$response" "success"; then + _info "Bark API fired success." + return 0 + fi + + _err "Bark API fired error." + _err "$response" + return 1 +} From ba442354719632a79bdbd409d3faf15ab77214fe Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 30 Nov 2021 13:10:39 +0800 Subject: [PATCH 1570/2234] Update DNS.yml --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 13066fdd..56781fff 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -170,7 +170,7 @@ jobs: ./letest.sh FreeBSD: - runs-on: macos-latest + runs-on: macos-10.15 needs: Windows env: TEST_DNS : ${{ secrets.TEST_DNS }} @@ -209,7 +209,7 @@ jobs: ./letest.sh Solaris: - runs-on: macos-latest + runs-on: macos-10.15 needs: FreeBSD env: TEST_DNS : ${{ secrets.TEST_DNS }} From ccd3d96942803905c5b650800314ecd510a1da0a Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 5 Dec 2021 16:15:39 +0800 Subject: [PATCH 1571/2234] upgrade Solaris --- .github/workflows/DNS.yml | 2 +- .github/workflows/Solaris.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 56781fff..2b15e14c 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -223,7 +223,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.3 + - uses: vmactions/solaris-vm@v0.0.4 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 4df10099..a5f5bc7d 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -40,7 +40,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.3 + - uses: vmactions/cf-tunnel@v0.0.4 id: tunnel with: protocol: http From f66d9e1a2272fb960f2923b1440bfb6c8d00151f Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 5 Dec 2021 18:23:19 +0800 Subject: [PATCH 1572/2234] fix for OpenBSD7 https://github.com/acmesh-official/acme.sh/issues/3833 --- acme.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d2e8b04d..96392f5b 100755 --- a/acme.sh +++ b/acme.sh @@ -4196,7 +4196,12 @@ _match_issuer() { #ip _isIPv4() { for seg in $(echo "$1" | tr '.' ' '); do - if [ $seg -ge 0 ] 2>/dev/null && [ $seg -le 255 ] 2>/dev/null; then + _debug2 seg "$seg" + if [ "$(echo "$seg" | tr -d [0-9])" ]; then + #not all number + return 1 + fi + if [ $seg -ge 0 ] && [ $seg -lt 256 ]; then continue fi return 1 From bdf8bf391c3f5f0cdbd7078984caf3b4a69790e4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 5 Dec 2021 21:05:18 +0800 Subject: [PATCH 1573/2234] pass TEST_DNS_NO_SUBDOMAIN --- .github/workflows/DNS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 2b15e14c..47bbc48f 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -49,6 +49,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 From 66da6f18e362bb6604c7f219778e9c29a75051a4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 6 Dec 2021 22:03:38 +0800 Subject: [PATCH 1574/2234] add TEST_DNS_NO_SUBDOMAIN --- .github/workflows/DNS.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 47bbc48f..fc3886f2 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -88,6 +88,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 @@ -125,6 +126,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 @@ -177,6 +179,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 @@ -187,7 +190,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0.1.4 with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl usesh: true run: | @@ -216,6 +219,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 @@ -226,7 +230,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0.0.4 with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat run: | pkg set-mediator -v -I default@1.1 openssl From 225707c877cad8d9ab7fd5c4f40d3750be727e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Mei=C3=9Fner?= Date: Sun, 12 Dec 2021 14:17:13 +0100 Subject: [PATCH 1575/2234] [dns_knot] Use key command instead of command line argument to transmit dns key data. --- dnsapi/dns_knot.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_knot.sh b/dnsapi/dns_knot.sh index 094a6981..729a89cb 100644 --- a/dnsapi/dns_knot.sh +++ b/dnsapi/dns_knot.sh @@ -19,8 +19,9 @@ dns_knot_add() { _info "Adding ${fulldomain}. 60 TXT \"${txtvalue}\"" - knsupdate -y "${KNOT_KEY}" < Date: Mon, 13 Dec 2021 20:04:23 +0800 Subject: [PATCH 1576/2234] fix tunnel version --- .github/workflows/Solaris.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index a5f5bc7d..f0f2f670 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -40,7 +40,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.4 + - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: protocol: http @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.3 + - uses: vmactions/solaris-vm@v0.0.4 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From 342bce216826eaebdda0aa48cde4271e65285e0d Mon Sep 17 00:00:00 2001 From: Joel Pearson Date: Mon, 13 Dec 2021 17:15:49 +1100 Subject: [PATCH 1577/2234] Allow optional "NEW" in CSR header and footer When generating a CSR in Windows it seems to create a CSR header that looks like "-----BEGIN NEW CERTIFICATE REQUEST-----", but the addition of "NEW" breaks the parsing of the CSR. Making "NEW " optional fixes the problem. Apparently certbot is tolerant of both forms, see: https://community.letsencrypt.org/t/error-parsing-certificate-request-resolved/40039/6 for more information. --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 96392f5b..87322a69 100755 --- a/acme.sh +++ b/acme.sh @@ -80,8 +80,8 @@ NGINX="nginx:" NGINX_START="#ACME_NGINX_START" NGINX_END="#ACME_NGINX_END" -BEGIN_CSR="-----BEGIN CERTIFICATE REQUEST-----" -END_CSR="-----END CERTIFICATE REQUEST-----" +BEGIN_CSR="-----BEGIN [NEW ]\{0,4\}CERTIFICATE REQUEST-----" +END_CSR="-----END [NEW ]\{0,4\}CERTIFICATE REQUEST-----" BEGIN_CERT="-----BEGIN CERTIFICATE-----" END_CERT="-----END CERTIFICATE-----" From 3105235a7a14b003e791780fb865ca7065457a45 Mon Sep 17 00:00:00 2001 From: Christian Burmeister Date: Tue, 21 Dec 2021 22:20:42 +0100 Subject: [PATCH 1578/2234] Update Dockerfile - alpine:3.12 -> alpine:3.15 The support for the base image alpine:3.12 will expire in 4 months (https://endoflife.date/alpine), so it would make sense to upgrade to the current version alpine:3.15. I was able to create the acme.sh image with the new alpine:3.15 version without errors and also create and deploy a certificate, but further testing would be useful. --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index fb842c83..4046c726 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.12 +FROM alpine:3.15 RUN apk --no-cache add -f \ openssl \ From 052b45a5101a42a592596a88ed989c6b36f813e2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 25 Dec 2021 09:57:58 +0800 Subject: [PATCH 1579/2234] upgrade solaris vm --- .github/workflows/DNS.yml | 2 +- .github/workflows/Solaris.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index fc3886f2..32d97614 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -228,7 +228,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.4 + - uses: vmactions/solaris-vm@v0.0.5 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index f0f2f670..77fdcc9a 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.4 + - uses: vmactions/solaris-vm@v0.0.5 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From 9769afb944e791f5f8625aa8b890dca129bf8d5b Mon Sep 17 00:00:00 2001 From: racitup Date: Fri, 10 Dec 2021 01:10:41 +0000 Subject: [PATCH 1580/2234] feat: Mythic Beasts DNS API script --- dnsapi/dns_mythic_beasts.sh | 230 ++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100755 dnsapi/dns_mythic_beasts.sh diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh new file mode 100755 index 00000000..2d1b6551 --- /dev/null +++ b/dnsapi/dns_mythic_beasts.sh @@ -0,0 +1,230 @@ +#!/usr/bin/env sh +# Mythic Beasts is a long-standing UK service provider using standards-based OAuth2 authentication +# To test: ./acme.sh --dns dns_mythic_beasts --test --debug 1 --output-insecure --issue --domain domain.com +# Cannot retest once cert is issued +# OAuth2 tokens only valid for 300 seconds so we do not store +# NOTE: This will remove all TXT records matching the fulldomain, not just the added ones (_acme-challenge.www.domain.com) + +# Test OAuth2 credentials +#MB_AK="aaaaaaaaaaaaaaaa" +#MB_AS="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + +# URLs +MB_API='https://api.mythic-beasts.com/dns/v2/zones' +MB_AUTH='https://auth.mythic-beasts.com/login' + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_mythic_beasts_add() { + fulldomain=$1 + txtvalue=$2 + + _info "MYTHIC BEASTS Adding record $fulldomain = $txtvalue" + if ! _initAuth; then + return 1 + fi + + if ! _get_root "$fulldomain"; then + return 1 + fi + + # method path body_data + if _mb_rest POST "$_domain/records/$_sub_domain/TXT" "$txtvalue"; then + + if _contains "$response" "1 records added"; then + _info "Added, verifying..." + # Max 120 seconds to publish + for i in $(seq 1 6); do + # Retry on error + if ! _mb_rest GET "$_domain/records/$_sub_domain/TXT?verify"; then + _sleep 20 + else + _info "Record published!" + return 0 + fi + done + + else + _err "\n$response" + fi + + fi + _err "Add txt record error." + return 1 +} + +#Usage: rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_mythic_beasts_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "MYTHIC BEASTS Removing record $fulldomain = $txtvalue" + if ! _initAuth; then + return 1 + fi + + if ! _get_root "$fulldomain"; then + return 1 + fi + + # method path body_data + if _mb_rest DELETE "$_domain/records/$_sub_domain/TXT" "$txtvalue"; then + _info "Record removed" + return 0 + fi + _err "Remove txt record error." + return 1 +} + +#################### Private functions below ################################## + +#Possible formats: +# _acme-challenge.www.example.com +# _acme-challenge.example.com +# _acme-challenge.example.co.uk +# _acme-challenge.www.example.co.uk +# _acme-challenge.sub1.sub2.www.example.co.uk +# sub1.sub2.example.co.uk +# example.com +# example.co.uk +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + p=1 + + _debug "Detect the root zone" + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + _err "Domain exhausted" + return 1 + fi + + # Use the status errors to find the domain, continue on 403 Access denied + # method path body_data + _mb_rest GET "$h/records" + ret="$?" + if [ "$ret" -eq 0 ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + return 0 + elif [ "$ret" -eq 1 ]; then + return 1 + fi + + p=$i + i=$(_math "$i" + 1) + + if [ "$i" -gt 50 ]; then + break + fi + done + _err "Domain too long" + return 1 +} + +_initAuth() { + MB_AK="${MB_AK:-$(_readaccountconf_mutable MB_AK)}" + MB_AS="${MB_AS:-$(_readaccountconf_mutable MB_AS)}" + + if [ -z "$MB_AK" ] || [ -z "$MB_AS" ]; then + MB_AK="" + MB_AS="" + _err "Please specify an OAuth2 Key & Secret" + return 1 + fi + + _saveaccountconf_mutable MB_AK "$MB_AK" + _saveaccountconf_mutable MB_AS "$MB_AS" + + if ! _oauth2; then + return 1 + fi + + _info "Checking authentication" + _secure_debug access_token "$MB_TK" + _sleep 1 + + # GET a list of zones + # method path body_data + if ! _mb_rest GET ""; then + _err "The token is invalid" + return 1 + fi + _info "Token OK" + return 0 +} + +_oauth2() { + # HTTP Basic Authentication + _H1="Authorization: Basic $(echo "$MB_AK:$MB_AS" | _base64)" + _H2="Accepts: application/json" + export _H1 _H2 + body="grant_type=client_credentials" + + _info "Getting OAuth2 token..." + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + response="$(_post "$body" "$MB_AUTH" "" "POST" "application/x-www-form-urlencoded")" + if _contains "$response" "\"token_type\":\"bearer\""; then + MB_TK="$(echo "$response" | _egrep_o "access_token\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')" + if [ -z "$MB_TK" ]; then + _err "Unable to get access_token" + _err "\n$response" + return 1 + fi + else + _err "OAuth2 token_type not Bearer" + _err "\n$response" + return 1 + fi + _debug2 response "$response" + return 0 +} + +# method path body_data +_mb_rest() { + # URL encoded body for single API operations + m="$1" + ep="$2" + data="$3" + + if [ -z "$ep" ]; then + _mb_url="$MB_API" + else + _mb_url="$MB_API/$ep" + fi + + _H1="Authorization: Bearer $MB_TK" + _H2="Accepts: application/json" + export _H1 _H2 + if [ "$data" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ] || [ "$m" = "DELETE" ]; then + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + response="$(_post "data=$data" "$_mb_url" "" "$m" "application/x-www-form-urlencoded")" + else + response="$(_get "$_mb_url")" + fi + + if [ "$?" != "0" ]; then + _err "Request error" + return 1 + fi + + header="$(cat "$HTTP_HEADER")" + status="$(echo "$header" | _egrep_o "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n")" + code="$(echo "$status" | _egrep_o "^[0-9]*")" + if [ "$code" -ge 400 ] || _contains "$response" "\"error\"" || _contains "$response" "invalid_client"; then + _err "error $status" + _err "\n$response" + _debug "\n$header" + return 2 + fi + + _debug2 response "$response" + return 0 +} From 962ce380cdc3ff74d956b5eb8a6d6a4103f19f4f Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 00:31:15 +0000 Subject: [PATCH 1581/2234] fix: floating token for github --- dnsapi/dns_mythic_beasts.sh | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 2d1b6551..3cff3b02 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -161,7 +161,20 @@ _initAuth() { return 0 } +# Github appears to use an outbound proxy for requests which means subsequent requests may not have the same +# source IP. The standard Mythic Beasts OAuth2 tokens are tied to an IP, meaning github test requests fail +# authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an +# IP just for the github tests. _oauth2() { + printenv + if [ -z "$TEST_DNS_SLEEP" ]; then + return _oauth2_std + else + return _oauth2_github + fi +} + +_oauth2_std() { # HTTP Basic Authentication _H1="Authorization: Basic $(echo "$MB_AK:$MB_AS" | _base64)" _H2="Accepts: application/json" @@ -187,6 +200,24 @@ _oauth2() { return 0 } +_oauth2_github() { + _H1="Accepts: application/json" + export _H1 + body="{\"login\":{\"handle\":$MB_AK,\"pass\":$MB_AS,\"floating\":1}}" + + _info "Getting Floating token..." + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + response="$(_post "$body" "$MB_AUTH" "" "POST" "application/json")" + MB_TK="$(echo "$response" | _egrep_o "\"token\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')" + if [ -z "$MB_TK" ]; then + _err "Unable to get access_token" + _err "\n$response" + return 1 + fi + _debug2 response "$response" + return 0 +} + # method path body_data _mb_rest() { # URL encoded body for single API operations From bf66df2a291aa503bbf47a670d50d00fb7d8c259 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 00:35:14 +0000 Subject: [PATCH 1582/2234] fix: correct return value --- dnsapi/dns_mythic_beasts.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 3cff3b02..9de5d34c 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -168,10 +168,11 @@ _initAuth() { _oauth2() { printenv if [ -z "$TEST_DNS_SLEEP" ]; then - return _oauth2_std + _oauth2_std else - return _oauth2_github + _oauth2_github fi + return $? } _oauth2_std() { From 9c4ac24a66bea1f2ef1c6ea40441fba84e663f07 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 00:50:33 +0000 Subject: [PATCH 1583/2234] fix: debugging --- dnsapi/dns_mythic_beasts.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 9de5d34c..96230bf1 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -166,7 +166,7 @@ _initAuth() { # authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an # IP just for the github tests. _oauth2() { - printenv + _info "$(printenv)" if [ -z "$TEST_DNS_SLEEP" ]; then _oauth2_std else @@ -211,7 +211,7 @@ _oauth2_github() { response="$(_post "$body" "$MB_AUTH" "" "POST" "application/json")" MB_TK="$(echo "$response" | _egrep_o "\"token\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')" if [ -z "$MB_TK" ]; then - _err "Unable to get access_token" + _err "Unable to get token" _err "\n$response" return 1 fi From 6351b5d0dc6a30e77ff3191f71f5f3bc66fc3cd3 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 00:58:37 +0000 Subject: [PATCH 1584/2234] fix: github switch --- dnsapi/dns_mythic_beasts.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 96230bf1..8956ec36 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -166,8 +166,8 @@ _initAuth() { # authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an # IP just for the github tests. _oauth2() { - _info "$(printenv)" - if [ -z "$TEST_DNS_SLEEP" ]; then + _info "DOMAIN: $TEST_DNS" + if [ "$TEST_DNS" != "dns_mythic_beasts" ]; then _oauth2_std else _oauth2_github From d940f17390785693a68bb414b0dd8318a6693460 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 01:09:02 +0000 Subject: [PATCH 1585/2234] fix: token request body quoting --- dnsapi/dns_mythic_beasts.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 8956ec36..77eed04f 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -166,7 +166,6 @@ _initAuth() { # authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an # IP just for the github tests. _oauth2() { - _info "DOMAIN: $TEST_DNS" if [ "$TEST_DNS" != "dns_mythic_beasts" ]; then _oauth2_std else @@ -204,7 +203,7 @@ _oauth2_std() { _oauth2_github() { _H1="Accepts: application/json" export _H1 - body="{\"login\":{\"handle\":$MB_AK,\"pass\":$MB_AS,\"floating\":1}}" + body="{\"login\":{\"handle\":\"$MB_AK\",\"pass\":\"$MB_AS\",\"floating\":1}}" _info "Getting Floating token..." # body url [needbase64] [POST|PUT|DELETE] [ContentType] From ce47ccecc4b290609728f50b89d270579664c7fe Mon Sep 17 00:00:00 2001 From: racitup Date: Tue, 28 Dec 2021 14:45:02 +0000 Subject: [PATCH 1586/2234] fix: Neilpang review --- dnsapi/dns_mythic_beasts.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 77eed04f..294ae84c 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -163,13 +163,13 @@ _initAuth() { # Github appears to use an outbound proxy for requests which means subsequent requests may not have the same # source IP. The standard Mythic Beasts OAuth2 tokens are tied to an IP, meaning github test requests fail -# authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an +# authentication. This is a work around using an undocumented MB API to obtain a token not tied to an # IP just for the github tests. _oauth2() { - if [ "$TEST_DNS" != "dns_mythic_beasts" ]; then - _oauth2_std - else + if [ "$GITHUB_ACTIONS" = "true" ]; then _oauth2_github + else + _oauth2_std fi return $? } From 424cc46db0c138037106a7a51ad504cfba0b646f Mon Sep 17 00:00:00 2001 From: Viktor G Date: Thu, 30 Dec 2021 18:06:17 +0300 Subject: [PATCH 1587/2234] DNS-ISPConfig ISPC_Api_Insecure argument check fix --- 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..765e0eb5 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}" ] || [ -n "${ISPC_Api_Insecure}" ]; then ISPC_User="" ISPC_Password="" ISPC_Api="" From 82e8792737ef88c527e75e51260fb25c53ccb5ec Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jan 2022 11:20:53 +0800 Subject: [PATCH 1588/2234] send notifications for renew command https://github.com/acmesh-official/acme.sh/issues/3869#issuecomment-1003546762 --- acme.sh | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/acme.sh b/acme.sh index 96392f5b..65ed2fd4 100755 --- a/acme.sh +++ b/acme.sh @@ -5254,13 +5254,13 @@ renewAll() { _error_level="$NOTIFY_LEVEL_RENEW" _notify_code=0 fi - if [ "$_ACME_IN_CRON" ]; then - if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then - if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then - _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 - fi + + if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 fi fi + _success_msg="${_success_msg} $d " elif [ "$rc" = "$RENEW_SKIP" ]; then @@ -5268,13 +5268,13 @@ renewAll() { _error_level="$NOTIFY_LEVEL_SKIP" _notify_code=$RENEW_SKIP fi - if [ "$_ACME_IN_CRON" ]; then - if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then - if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then - _send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" - fi + + if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" fi fi + _info "Skipped $d" _skipped_msg="${_skipped_msg} $d " @@ -5283,13 +5283,13 @@ renewAll() { _error_level="$NOTIFY_LEVEL_ERROR" _notify_code=1 fi - if [ "$_ACME_IN_CRON" ]; then - if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then - if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then - _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 - fi + + if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 fi fi + _error_msg="${_error_msg} $d " if [ "$_stopRenewOnError" ]; then @@ -5304,7 +5304,7 @@ renewAll() { done _debug _error_level "$_error_level" _debug _set_level "$_set_level" - if [ "$_ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then + if [ $_error_level -le $_set_level ]; then if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then _msg_subject="Renew" if [ "$_error_msg" ]; then From eeee30ca03ab5ea4e402a3043aa13d082199da7b Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jan 2022 11:46:12 +0800 Subject: [PATCH 1589/2234] fix https://github.com/acmesh-official/acme.sh/issues/3869 --- acme.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 65ed2fd4..9fc44610 100755 --- a/acme.sh +++ b/acme.sh @@ -5154,7 +5154,7 @@ renew() { _isEcc="$2" _initpath "$Le_Domain" "$_isEcc" - + _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} _info "$(__green "Renew: '$Le_Domain'")" if [ ! -f "$DOMAIN_CONF" ]; then _info "'$Le_Domain' is not an issued domain, skip." @@ -5189,6 +5189,11 @@ renew() { if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then _info "Skip, Next renewal time is: $(__green "$Le_NextRenewTimeStr")" _info "Add '$(__red '--force')' to force to renew." + if [ -z "$_ACME_IN_RENEWALL" ]; then + if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then + _send_notify "Renew $Le_Domain skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" + fi + fi return "$RENEW_SKIP" fi @@ -5215,6 +5220,17 @@ renew() { fi _ACME_IS_RENEW="" + if [ -z "$_ACME_IN_RENEWALL" ]; then + if [ "$res" = "0" ]; then + if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then + _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 + fi + else + if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then + _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 + fi + fi + fi return "$res" } @@ -5232,6 +5248,7 @@ renewAll() { _notify_code=$RENEW_SKIP _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} _debug "_set_level" "$_set_level" + export _ACME_IN_RENEWALL=1 for di in "${CERT_HOME}"/*.*/; do _debug di "$di" if ! [ -d "$di" ]; then From dd2a4205787eaa9efad352d3903f25480ea49c92 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jan 2022 12:38:59 +0800 Subject: [PATCH 1590/2234] add `--info` command to show the global configs or domain configs. https://github.com/acmesh-official/acme.sh/issues/2444 --- Dockerfile | 1 + acme.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/Dockerfile b/Dockerfile index 4046c726..0421da34 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,6 +40,7 @@ RUN for verb in help \ revoke \ remove \ list \ + info \ showcsr \ install-cronjob \ uninstall-cronjob \ diff --git a/acme.sh b/acme.sh index 9fc44610..fe4dc1bd 100755 --- a/acme.sh +++ b/acme.sh @@ -144,6 +144,8 @@ NOTIFY_MODE_CERT=1 NOTIFY_MODE_DEFAULT=$NOTIFY_MODE_BULK +_BASE64_ENCODED_CFGS="Le_PreHook Le_PostHook Le_RenewHook Le_Preferred_Chain Le_ReloadCmd" + _DEBUG_WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh" _PREPARE_LINK="https://github.com/acmesh-official/acme.sh/wiki/Install-preparations" @@ -6609,6 +6611,7 @@ Commands: --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. --list List all the certs. + --info Show the $PROJECT_NAME configs, or the configs for a domain with [-d domain] parameter. --to-pkcs12 Export the certificate and key to a pfx file. --to-pkcs8 Convert to pkcs8 format. --sign-csr Issue a cert from an existing csr. @@ -6926,6 +6929,28 @@ setdefaultchain() { _savecaconf "DEFAULT_PREFERRED_CHAIN" "$_preferred_chain" } +#domain ecc +info() { + _domain="$1" + _ecc="$2" + _initpath + if [ -z "$_domain" ]; then + _debug "Show global configs" + echo "LE_WORKING_DIR=$LE_WORKING_DIR" + echo "LE_CONFIG_HOME=$LE_CONFIG_HOME" + cat "$ACCOUNT_CONF_PATH" + else + _debug "Show domain configs" + ( + _initpath "$_domain" "$_ecc" + echo "DOMAIN_CONF=$DOMAIN_CONF" + for seg in $(cat $DOMAIN_CONF | cut -d = -f 1); do + echo "$seg=$(_readdomainconf "$seg")" + done + ) + fi +} + _process() { _CMD="" _domain="" @@ -7035,6 +7060,9 @@ _process() { --list) _CMD="list" ;; + --info) + _CMD="info" + ;; --install-cronjob | --installcronjob) _CMD="installcronjob" ;; @@ -7586,6 +7614,9 @@ _process() { list) list "$_listraw" "$_domain" ;; + info) + info "$_domain" "$_ecc" + ;; installcronjob) installcronjob "$_confighome" ;; uninstallcronjob) uninstallcronjob ;; cron) cron ;; From dbd5bef0380a366773d5758dca023a51c3982d33 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jan 2022 13:41:57 +0800 Subject: [PATCH 1591/2234] fix gentoo image --- .github/workflows/Linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index cba708b3..7b24eac9 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -20,7 +20,7 @@ jobs: Linux: strategy: matrix: - os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3-amd64"] + os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"] runs-on: ubuntu-latest env: TEST_LOCAL: 1 From cc5cfc7525491c31ad224783fea440d30fb15554 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Wed, 5 Jan 2022 15:03:32 +0100 Subject: [PATCH 1592/2234] Added Selfhost DNS API +ShellCheck +ACME v2 compatible Example: - Fist create 2 new TXT records on _acme-challenge.example.com - Now note the ID in (...) from the edit page behind "_acme-challenge.example.com" export SELFHOSTDNS_USERNAME=myname export SELFHOSTDNS_PASSWORD=mypass export SELFHOSTDNS_RID=id_of_txt_record export SELFHOSTDNS_RID2=id_of_second_txt_record acme.sh --issue -d example.com --dns dns_selfhost --- dnsapi/dns_selfhost.sh | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 dnsapi/dns_selfhost.sh diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh new file mode 100644 index 00000000..d7dfcca4 --- /dev/null +++ b/dnsapi/dns_selfhost.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env sh +# +# Author: Marvin Edeler +# Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 + +dns_selfhost_add() { + domain=$1 + txt=$2 + _info "Calling acme-dns on selfhost" + _debug fulldomain "$domain" + _debug txtvalue "$txt" + + SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl" + SELFHOSTDNS_USERNAME="${SELFHOSTDNS_USERNAME:-$(_readaccountconf_mutable SELFHOSTDNS_USERNAME)}" + SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" + SELFHOSTDNS_RID="${SELFHOSTDNS_RID:-$(_readaccountconf_mutable SELFHOSTDNS_RID)}" + SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readaccountconf_mutable SELFHOSTDNS_RID2)}" + SELFHOSTDNS_LAST_SLOT="$(_readaccountconf_mutable SELFHOSTDNS_LAST_SLOT)" + + if test -z "$SELFHOSTDNS_LAST_SLOT"; then + SELFHOSTDNS_LAST_SLOT=1 + fi + + _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" + _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" + _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" + _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" + + if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then + rid=$SELFHOSTDNS_RID + SELFHOSTDNS_LAST_SLOT=1 + else + rid=$SELFHOSTDNS_RID2 + SELFHOSTDNS_LAST_SLOT=2 + fi + + _saveaccountconf_mutable SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" + + _info "Trying to add $txt on selfhost for rid: $rid" + + data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt" + response="$(_get "$SELFHOSTDNS_UPDATE_URL$data")" + + if ! echo "$response" | grep "200 OK" >/dev/null; then + _err "Invalid response of acme-dns for selfhost" + return 1 + fi +} + +dns_acmedns_rm() { + domain=$1 + txt=$2 + _debug fulldomain "$domain" + _debug txtvalue "$txt" +} From eaae0547f2687cdd7c1c9f00a437a204425dce56 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 5 Dec 2021 16:15:39 +0800 Subject: [PATCH 1593/2234] upgrade Solaris --- .github/workflows/DNS.yml | 2 +- .github/workflows/Solaris.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 56781fff..2b15e14c 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -223,7 +223,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.3 + - uses: vmactions/solaris-vm@v0.0.4 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 4df10099..a5f5bc7d 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -40,7 +40,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.3 + - uses: vmactions/cf-tunnel@v0.0.4 id: tunnel with: protocol: http From 4f386663e75e319b832560234b86922d14fe4184 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 5 Dec 2021 18:23:19 +0800 Subject: [PATCH 1594/2234] fix for OpenBSD7 https://github.com/acmesh-official/acme.sh/issues/3833 --- acme.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d2e8b04d..96392f5b 100755 --- a/acme.sh +++ b/acme.sh @@ -4196,7 +4196,12 @@ _match_issuer() { #ip _isIPv4() { for seg in $(echo "$1" | tr '.' ' '); do - if [ $seg -ge 0 ] 2>/dev/null && [ $seg -le 255 ] 2>/dev/null; then + _debug2 seg "$seg" + if [ "$(echo "$seg" | tr -d [0-9])" ]; then + #not all number + return 1 + fi + if [ $seg -ge 0 ] && [ $seg -lt 256 ]; then continue fi return 1 From 69c02cae764665be83d291ab0224c3220e4b2082 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 5 Dec 2021 21:05:18 +0800 Subject: [PATCH 1595/2234] pass TEST_DNS_NO_SUBDOMAIN --- .github/workflows/DNS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 2b15e14c..47bbc48f 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -49,6 +49,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 From 267e582827fd7fd6c5020fe926a5ab3835bd56a4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 6 Dec 2021 22:03:38 +0800 Subject: [PATCH 1596/2234] add TEST_DNS_NO_SUBDOMAIN --- .github/workflows/DNS.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 47bbc48f..fc3886f2 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -88,6 +88,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 @@ -125,6 +126,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 @@ -177,6 +179,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 @@ -187,7 +190,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0.1.4 with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl usesh: true run: | @@ -216,6 +219,7 @@ jobs: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 @@ -226,7 +230,7 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0.0.4 with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat run: | pkg set-mediator -v -I default@1.1 openssl From beed123fb00fd8780e4090c5e7f4ef8ed818ce7f Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 13 Dec 2021 20:04:23 +0800 Subject: [PATCH 1597/2234] fix tunnel version --- .github/workflows/Solaris.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index a5f5bc7d..f0f2f670 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -40,7 +40,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.4 + - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: protocol: http @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.3 + - uses: vmactions/solaris-vm@v0.0.4 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From dac7a3d2721cfb9cc13f34ede6553aff580c656d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Mei=C3=9Fner?= Date: Sun, 12 Dec 2021 14:17:13 +0100 Subject: [PATCH 1598/2234] [dns_knot] Use key command instead of command line argument to transmit dns key data. --- dnsapi/dns_knot.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_knot.sh b/dnsapi/dns_knot.sh index 094a6981..729a89cb 100644 --- a/dnsapi/dns_knot.sh +++ b/dnsapi/dns_knot.sh @@ -19,8 +19,9 @@ dns_knot_add() { _info "Adding ${fulldomain}. 60 TXT \"${txtvalue}\"" - knsupdate -y "${KNOT_KEY}" < Date: Tue, 21 Dec 2021 22:20:42 +0100 Subject: [PATCH 1599/2234] Update Dockerfile - alpine:3.12 -> alpine:3.15 The support for the base image alpine:3.12 will expire in 4 months (https://endoflife.date/alpine), so it would make sense to upgrade to the current version alpine:3.15. I was able to create the acme.sh image with the new alpine:3.15 version without errors and also create and deploy a certificate, but further testing would be useful. --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index fb842c83..4046c726 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.12 +FROM alpine:3.15 RUN apk --no-cache add -f \ openssl \ From c6a0ec64cb993221643412c702a32a4085b41957 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 25 Dec 2021 09:57:58 +0800 Subject: [PATCH 1600/2234] upgrade solaris vm --- .github/workflows/DNS.yml | 2 +- .github/workflows/Solaris.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index fc3886f2..32d97614 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -228,7 +228,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.4 + - uses: vmactions/solaris-vm@v0.0.5 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index f0f2f670..77fdcc9a 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.4 + - uses: vmactions/solaris-vm@v0.0.5 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From f485f3fdb5327218978f83ec2d4ef957d9774f19 Mon Sep 17 00:00:00 2001 From: wacki4 Date: Sat, 16 Oct 2021 14:08:03 +0200 Subject: [PATCH 1601/2234] Update dns_opnsense.sh Update for opnsense regards to error in #3735 --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 069f6c32..63723f5a 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\"(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{.*}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" From aa9f5b8c4af784dedcaa6411959ef8bb8a7933bb Mon Sep 17 00:00:00 2001 From: wacki4 Date: Sat, 16 Oct 2021 16:57:12 +0200 Subject: [PATCH 1602/2234] Update dns_opnsense.sh Correction when having many zones. --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 63723f5a..26a422f8 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{.*}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"\":{[^}]*}}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" From 4dd709b543016f3e8d7ee5bf0eb20918a618a153 Mon Sep 17 00:00:00 2001 From: racitup Date: Fri, 10 Dec 2021 01:10:41 +0000 Subject: [PATCH 1603/2234] feat: Mythic Beasts DNS API script --- dnsapi/dns_mythic_beasts.sh | 230 ++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100755 dnsapi/dns_mythic_beasts.sh diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh new file mode 100755 index 00000000..2d1b6551 --- /dev/null +++ b/dnsapi/dns_mythic_beasts.sh @@ -0,0 +1,230 @@ +#!/usr/bin/env sh +# Mythic Beasts is a long-standing UK service provider using standards-based OAuth2 authentication +# To test: ./acme.sh --dns dns_mythic_beasts --test --debug 1 --output-insecure --issue --domain domain.com +# Cannot retest once cert is issued +# OAuth2 tokens only valid for 300 seconds so we do not store +# NOTE: This will remove all TXT records matching the fulldomain, not just the added ones (_acme-challenge.www.domain.com) + +# Test OAuth2 credentials +#MB_AK="aaaaaaaaaaaaaaaa" +#MB_AS="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + +# URLs +MB_API='https://api.mythic-beasts.com/dns/v2/zones' +MB_AUTH='https://auth.mythic-beasts.com/login' + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_mythic_beasts_add() { + fulldomain=$1 + txtvalue=$2 + + _info "MYTHIC BEASTS Adding record $fulldomain = $txtvalue" + if ! _initAuth; then + return 1 + fi + + if ! _get_root "$fulldomain"; then + return 1 + fi + + # method path body_data + if _mb_rest POST "$_domain/records/$_sub_domain/TXT" "$txtvalue"; then + + if _contains "$response" "1 records added"; then + _info "Added, verifying..." + # Max 120 seconds to publish + for i in $(seq 1 6); do + # Retry on error + if ! _mb_rest GET "$_domain/records/$_sub_domain/TXT?verify"; then + _sleep 20 + else + _info "Record published!" + return 0 + fi + done + + else + _err "\n$response" + fi + + fi + _err "Add txt record error." + return 1 +} + +#Usage: rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_mythic_beasts_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "MYTHIC BEASTS Removing record $fulldomain = $txtvalue" + if ! _initAuth; then + return 1 + fi + + if ! _get_root "$fulldomain"; then + return 1 + fi + + # method path body_data + if _mb_rest DELETE "$_domain/records/$_sub_domain/TXT" "$txtvalue"; then + _info "Record removed" + return 0 + fi + _err "Remove txt record error." + return 1 +} + +#################### Private functions below ################################## + +#Possible formats: +# _acme-challenge.www.example.com +# _acme-challenge.example.com +# _acme-challenge.example.co.uk +# _acme-challenge.www.example.co.uk +# _acme-challenge.sub1.sub2.www.example.co.uk +# sub1.sub2.example.co.uk +# example.com +# example.co.uk +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + p=1 + + _debug "Detect the root zone" + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + _err "Domain exhausted" + return 1 + fi + + # Use the status errors to find the domain, continue on 403 Access denied + # method path body_data + _mb_rest GET "$h/records" + ret="$?" + if [ "$ret" -eq 0 ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + return 0 + elif [ "$ret" -eq 1 ]; then + return 1 + fi + + p=$i + i=$(_math "$i" + 1) + + if [ "$i" -gt 50 ]; then + break + fi + done + _err "Domain too long" + return 1 +} + +_initAuth() { + MB_AK="${MB_AK:-$(_readaccountconf_mutable MB_AK)}" + MB_AS="${MB_AS:-$(_readaccountconf_mutable MB_AS)}" + + if [ -z "$MB_AK" ] || [ -z "$MB_AS" ]; then + MB_AK="" + MB_AS="" + _err "Please specify an OAuth2 Key & Secret" + return 1 + fi + + _saveaccountconf_mutable MB_AK "$MB_AK" + _saveaccountconf_mutable MB_AS "$MB_AS" + + if ! _oauth2; then + return 1 + fi + + _info "Checking authentication" + _secure_debug access_token "$MB_TK" + _sleep 1 + + # GET a list of zones + # method path body_data + if ! _mb_rest GET ""; then + _err "The token is invalid" + return 1 + fi + _info "Token OK" + return 0 +} + +_oauth2() { + # HTTP Basic Authentication + _H1="Authorization: Basic $(echo "$MB_AK:$MB_AS" | _base64)" + _H2="Accepts: application/json" + export _H1 _H2 + body="grant_type=client_credentials" + + _info "Getting OAuth2 token..." + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + response="$(_post "$body" "$MB_AUTH" "" "POST" "application/x-www-form-urlencoded")" + if _contains "$response" "\"token_type\":\"bearer\""; then + MB_TK="$(echo "$response" | _egrep_o "access_token\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')" + if [ -z "$MB_TK" ]; then + _err "Unable to get access_token" + _err "\n$response" + return 1 + fi + else + _err "OAuth2 token_type not Bearer" + _err "\n$response" + return 1 + fi + _debug2 response "$response" + return 0 +} + +# method path body_data +_mb_rest() { + # URL encoded body for single API operations + m="$1" + ep="$2" + data="$3" + + if [ -z "$ep" ]; then + _mb_url="$MB_API" + else + _mb_url="$MB_API/$ep" + fi + + _H1="Authorization: Bearer $MB_TK" + _H2="Accepts: application/json" + export _H1 _H2 + if [ "$data" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ] || [ "$m" = "DELETE" ]; then + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + response="$(_post "data=$data" "$_mb_url" "" "$m" "application/x-www-form-urlencoded")" + else + response="$(_get "$_mb_url")" + fi + + if [ "$?" != "0" ]; then + _err "Request error" + return 1 + fi + + header="$(cat "$HTTP_HEADER")" + status="$(echo "$header" | _egrep_o "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n")" + code="$(echo "$status" | _egrep_o "^[0-9]*")" + if [ "$code" -ge 400 ] || _contains "$response" "\"error\"" || _contains "$response" "invalid_client"; then + _err "error $status" + _err "\n$response" + _debug "\n$header" + return 2 + fi + + _debug2 response "$response" + return 0 +} From 6a2c9a0dc1cca74fb44f3804aa979acdc1c0e08d Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 00:31:15 +0000 Subject: [PATCH 1604/2234] fix: floating token for github --- dnsapi/dns_mythic_beasts.sh | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 2d1b6551..3cff3b02 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -161,7 +161,20 @@ _initAuth() { return 0 } +# Github appears to use an outbound proxy for requests which means subsequent requests may not have the same +# source IP. The standard Mythic Beasts OAuth2 tokens are tied to an IP, meaning github test requests fail +# authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an +# IP just for the github tests. _oauth2() { + printenv + if [ -z "$TEST_DNS_SLEEP" ]; then + return _oauth2_std + else + return _oauth2_github + fi +} + +_oauth2_std() { # HTTP Basic Authentication _H1="Authorization: Basic $(echo "$MB_AK:$MB_AS" | _base64)" _H2="Accepts: application/json" @@ -187,6 +200,24 @@ _oauth2() { return 0 } +_oauth2_github() { + _H1="Accepts: application/json" + export _H1 + body="{\"login\":{\"handle\":$MB_AK,\"pass\":$MB_AS,\"floating\":1}}" + + _info "Getting Floating token..." + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + response="$(_post "$body" "$MB_AUTH" "" "POST" "application/json")" + MB_TK="$(echo "$response" | _egrep_o "\"token\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')" + if [ -z "$MB_TK" ]; then + _err "Unable to get access_token" + _err "\n$response" + return 1 + fi + _debug2 response "$response" + return 0 +} + # method path body_data _mb_rest() { # URL encoded body for single API operations From 6251652c936259e7c43794413a795b527d86e867 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 00:35:14 +0000 Subject: [PATCH 1605/2234] fix: correct return value --- dnsapi/dns_mythic_beasts.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 3cff3b02..9de5d34c 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -168,10 +168,11 @@ _initAuth() { _oauth2() { printenv if [ -z "$TEST_DNS_SLEEP" ]; then - return _oauth2_std + _oauth2_std else - return _oauth2_github + _oauth2_github fi + return $? } _oauth2_std() { From 56d799f4492416f05efb5216b031af29718ddff9 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 00:50:33 +0000 Subject: [PATCH 1606/2234] fix: debugging --- dnsapi/dns_mythic_beasts.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 9de5d34c..96230bf1 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -166,7 +166,7 @@ _initAuth() { # authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an # IP just for the github tests. _oauth2() { - printenv + _info "$(printenv)" if [ -z "$TEST_DNS_SLEEP" ]; then _oauth2_std else @@ -211,7 +211,7 @@ _oauth2_github() { response="$(_post "$body" "$MB_AUTH" "" "POST" "application/json")" MB_TK="$(echo "$response" | _egrep_o "\"token\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')" if [ -z "$MB_TK" ]; then - _err "Unable to get access_token" + _err "Unable to get token" _err "\n$response" return 1 fi From f46ee935978bcd3bf0a1c8ab74403a28b831d3e7 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 00:58:37 +0000 Subject: [PATCH 1607/2234] fix: github switch --- dnsapi/dns_mythic_beasts.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 96230bf1..8956ec36 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -166,8 +166,8 @@ _initAuth() { # authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an # IP just for the github tests. _oauth2() { - _info "$(printenv)" - if [ -z "$TEST_DNS_SLEEP" ]; then + _info "DOMAIN: $TEST_DNS" + if [ "$TEST_DNS" != "dns_mythic_beasts" ]; then _oauth2_std else _oauth2_github From 95f13360601e27071ccdc2dff4c46b00bb988720 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Dec 2021 01:09:02 +0000 Subject: [PATCH 1608/2234] fix: token request body quoting --- dnsapi/dns_mythic_beasts.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 8956ec36..77eed04f 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -166,7 +166,6 @@ _initAuth() { # authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an # IP just for the github tests. _oauth2() { - _info "DOMAIN: $TEST_DNS" if [ "$TEST_DNS" != "dns_mythic_beasts" ]; then _oauth2_std else @@ -204,7 +203,7 @@ _oauth2_std() { _oauth2_github() { _H1="Accepts: application/json" export _H1 - body="{\"login\":{\"handle\":$MB_AK,\"pass\":$MB_AS,\"floating\":1}}" + body="{\"login\":{\"handle\":\"$MB_AK\",\"pass\":\"$MB_AS\",\"floating\":1}}" _info "Getting Floating token..." # body url [needbase64] [POST|PUT|DELETE] [ContentType] From 2b6aa2670343e7e6a975c3d0961770f86b4ebfc9 Mon Sep 17 00:00:00 2001 From: racitup Date: Tue, 28 Dec 2021 14:45:02 +0000 Subject: [PATCH 1609/2234] fix: Neilpang review --- dnsapi/dns_mythic_beasts.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 77eed04f..294ae84c 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -163,13 +163,13 @@ _initAuth() { # Github appears to use an outbound proxy for requests which means subsequent requests may not have the same # source IP. The standard Mythic Beasts OAuth2 tokens are tied to an IP, meaning github test requests fail -# authentication. This works arounds this by using an undocumented MB API to obtain a token not tied to an +# authentication. This is a work around using an undocumented MB API to obtain a token not tied to an # IP just for the github tests. _oauth2() { - if [ "$TEST_DNS" != "dns_mythic_beasts" ]; then - _oauth2_std - else + if [ "$GITHUB_ACTIONS" = "true" ]; then _oauth2_github + else + _oauth2_std fi return $? } From d32cedd7dc925cad381920334316f6b563042f96 Mon Sep 17 00:00:00 2001 From: Viktor G Date: Thu, 30 Dec 2021 18:06:17 +0300 Subject: [PATCH 1610/2234] DNS-ISPConfig ISPC_Api_Insecure argument check fix --- 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..765e0eb5 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}" ] || [ -n "${ISPC_Api_Insecure}" ]; then ISPC_User="" ISPC_Password="" ISPC_Api="" From 737eba57bd87be29de0f5b9ab52fcdd1bffaca4b Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jan 2022 11:20:53 +0800 Subject: [PATCH 1611/2234] send notifications for renew command https://github.com/acmesh-official/acme.sh/issues/3869#issuecomment-1003546762 --- acme.sh | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/acme.sh b/acme.sh index 96392f5b..65ed2fd4 100755 --- a/acme.sh +++ b/acme.sh @@ -5254,13 +5254,13 @@ renewAll() { _error_level="$NOTIFY_LEVEL_RENEW" _notify_code=0 fi - if [ "$_ACME_IN_CRON" ]; then - if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then - if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then - _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 - fi + + if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 fi fi + _success_msg="${_success_msg} $d " elif [ "$rc" = "$RENEW_SKIP" ]; then @@ -5268,13 +5268,13 @@ renewAll() { _error_level="$NOTIFY_LEVEL_SKIP" _notify_code=$RENEW_SKIP fi - if [ "$_ACME_IN_CRON" ]; then - if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then - if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then - _send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" - fi + + if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" fi fi + _info "Skipped $d" _skipped_msg="${_skipped_msg} $d " @@ -5283,13 +5283,13 @@ renewAll() { _error_level="$NOTIFY_LEVEL_ERROR" _notify_code=1 fi - if [ "$_ACME_IN_CRON" ]; then - if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then - if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then - _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 - fi + + if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then + if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then + _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 fi fi + _error_msg="${_error_msg} $d " if [ "$_stopRenewOnError" ]; then @@ -5304,7 +5304,7 @@ renewAll() { done _debug _error_level "$_error_level" _debug _set_level "$_set_level" - if [ "$_ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then + if [ $_error_level -le $_set_level ]; then if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then _msg_subject="Renew" if [ "$_error_msg" ]; then From 1566656af30524717545965cc9b91727c7f38c7d Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jan 2022 11:46:12 +0800 Subject: [PATCH 1612/2234] fix https://github.com/acmesh-official/acme.sh/issues/3869 --- acme.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 65ed2fd4..9fc44610 100755 --- a/acme.sh +++ b/acme.sh @@ -5154,7 +5154,7 @@ renew() { _isEcc="$2" _initpath "$Le_Domain" "$_isEcc" - + _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} _info "$(__green "Renew: '$Le_Domain'")" if [ ! -f "$DOMAIN_CONF" ]; then _info "'$Le_Domain' is not an issued domain, skip." @@ -5189,6 +5189,11 @@ renew() { if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then _info "Skip, Next renewal time is: $(__green "$Le_NextRenewTimeStr")" _info "Add '$(__red '--force')' to force to renew." + if [ -z "$_ACME_IN_RENEWALL" ]; then + if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then + _send_notify "Renew $Le_Domain skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" + fi + fi return "$RENEW_SKIP" fi @@ -5215,6 +5220,17 @@ renew() { fi _ACME_IS_RENEW="" + if [ -z "$_ACME_IN_RENEWALL" ]; then + if [ "$res" = "0" ]; then + if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then + _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 + fi + else + if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then + _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 + fi + fi + fi return "$res" } @@ -5232,6 +5248,7 @@ renewAll() { _notify_code=$RENEW_SKIP _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} _debug "_set_level" "$_set_level" + export _ACME_IN_RENEWALL=1 for di in "${CERT_HOME}"/*.*/; do _debug di "$di" if ! [ -d "$di" ]; then From c39e6c44231a9c077a77a131d39fefe8428ae932 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jan 2022 12:38:59 +0800 Subject: [PATCH 1613/2234] add `--info` command to show the global configs or domain configs. https://github.com/acmesh-official/acme.sh/issues/2444 --- Dockerfile | 1 + acme.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/Dockerfile b/Dockerfile index 4046c726..0421da34 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,6 +40,7 @@ RUN for verb in help \ revoke \ remove \ list \ + info \ showcsr \ install-cronjob \ uninstall-cronjob \ diff --git a/acme.sh b/acme.sh index 9fc44610..fe4dc1bd 100755 --- a/acme.sh +++ b/acme.sh @@ -144,6 +144,8 @@ NOTIFY_MODE_CERT=1 NOTIFY_MODE_DEFAULT=$NOTIFY_MODE_BULK +_BASE64_ENCODED_CFGS="Le_PreHook Le_PostHook Le_RenewHook Le_Preferred_Chain Le_ReloadCmd" + _DEBUG_WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh" _PREPARE_LINK="https://github.com/acmesh-official/acme.sh/wiki/Install-preparations" @@ -6609,6 +6611,7 @@ Commands: --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. --list List all the certs. + --info Show the $PROJECT_NAME configs, or the configs for a domain with [-d domain] parameter. --to-pkcs12 Export the certificate and key to a pfx file. --to-pkcs8 Convert to pkcs8 format. --sign-csr Issue a cert from an existing csr. @@ -6926,6 +6929,28 @@ setdefaultchain() { _savecaconf "DEFAULT_PREFERRED_CHAIN" "$_preferred_chain" } +#domain ecc +info() { + _domain="$1" + _ecc="$2" + _initpath + if [ -z "$_domain" ]; then + _debug "Show global configs" + echo "LE_WORKING_DIR=$LE_WORKING_DIR" + echo "LE_CONFIG_HOME=$LE_CONFIG_HOME" + cat "$ACCOUNT_CONF_PATH" + else + _debug "Show domain configs" + ( + _initpath "$_domain" "$_ecc" + echo "DOMAIN_CONF=$DOMAIN_CONF" + for seg in $(cat $DOMAIN_CONF | cut -d = -f 1); do + echo "$seg=$(_readdomainconf "$seg")" + done + ) + fi +} + _process() { _CMD="" _domain="" @@ -7035,6 +7060,9 @@ _process() { --list) _CMD="list" ;; + --info) + _CMD="info" + ;; --install-cronjob | --installcronjob) _CMD="installcronjob" ;; @@ -7586,6 +7614,9 @@ _process() { list) list "$_listraw" "$_domain" ;; + info) + info "$_domain" "$_ecc" + ;; installcronjob) installcronjob "$_confighome" ;; uninstallcronjob) uninstallcronjob ;; cron) cron ;; From 37cc611e3fdad187d33b3f618ca67fbb79babe8a Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 3 Jan 2022 13:41:57 +0800 Subject: [PATCH 1614/2234] fix gentoo image --- .github/workflows/Linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index cba708b3..7b24eac9 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -20,7 +20,7 @@ jobs: Linux: strategy: matrix: - os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3-amd64"] + os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"] runs-on: ubuntu-latest env: TEST_LOCAL: 1 From 0727f7054bc4df6112988d44f45d795099d41b63 Mon Sep 17 00:00:00 2001 From: Joel Pearson Date: Mon, 13 Dec 2021 17:15:49 +1100 Subject: [PATCH 1615/2234] Allow optional "NEW" in CSR header and footer When generating a CSR in Windows it seems to create a CSR header that looks like "-----BEGIN NEW CERTIFICATE REQUEST-----", but the addition of "NEW" breaks the parsing of the CSR. Making "NEW " optional fixes the problem. Apparently certbot is tolerant of both forms, see: https://community.letsencrypt.org/t/error-parsing-certificate-request-resolved/40039/6 for more information. --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index fe4dc1bd..b536d742 100755 --- a/acme.sh +++ b/acme.sh @@ -80,8 +80,8 @@ NGINX="nginx:" NGINX_START="#ACME_NGINX_START" NGINX_END="#ACME_NGINX_END" -BEGIN_CSR="-----BEGIN CERTIFICATE REQUEST-----" -END_CSR="-----END CERTIFICATE REQUEST-----" +BEGIN_CSR="-----BEGIN [NEW ]\{0,4\}CERTIFICATE REQUEST-----" +END_CSR="-----END [NEW ]\{0,4\}CERTIFICATE REQUEST-----" BEGIN_CERT="-----BEGIN CERTIFICATE-----" END_CERT="-----END CERTIFICATE-----" From 6aa1ec08020ca9edb9813cb4148d0f467524d46d Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Thu, 6 Jan 2022 16:20:43 +0100 Subject: [PATCH 1616/2234] deploy/fritzbox: allow hook to be used with multiple fritzboxes Previously the deploy hook config was stored in the account config. This seems odd and adds unnecessary limitations to the hook. Now we're using the correct _*deployconf() functions to read and write the deploy hook config. --- deploy/fritzbox.sh | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/deploy/fritzbox.sh b/deploy/fritzbox.sh index 2ca7ab7d..416a4121 100644 --- a/deploy/fritzbox.sh +++ b/deploy/fritzbox.sh @@ -36,43 +36,51 @@ fritzbox_deploy() { fi fi - _fritzbox_username="${DEPLOY_FRITZBOX_USERNAME}" - _fritzbox_password="${DEPLOY_FRITZBOX_PASSWORD}" - _fritzbox_url="${DEPLOY_FRITZBOX_URL}" + # Clear traces of incorrectly stored values + _clearaccountconf DEPLOY_FRITZBOX_USERNAME + _clearaccountconf DEPLOY_FRITZBOX_PASSWORD + _clearaccountconf DEPLOY_FRITZBOX_URL - _debug _fritzbox_url "$_fritzbox_url" - _debug _fritzbox_username "$_fritzbox_username" - _secure_debug _fritzbox_password "$_fritzbox_password" - if [ -z "$_fritzbox_username" ]; then + # Read config from saved values or env + _getdeployconf DEPLOY_FRITZBOX_USERNAME + _getdeployconf DEPLOY_FRITZBOX_PASSWORD + _getdeployconf DEPLOY_FRITZBOX_URL + + _debug DEPLOY_FRITZBOX_URL "$DEPLOY_FRITZBOX_URL" + _debug DEPLOY_FRITZBOX_USERNAME "$DEPLOY_FRITZBOX_USERNAME" + _secure_debug DEPLOY_FRITZBOX_PASSWORD "$DEPLOY_FRITZBOX_PASSWORD" + + if [ -z "$DEPLOY_FRITZBOX_USERNAME" ]; then _err "FRITZ!Box username is not found, please define DEPLOY_FRITZBOX_USERNAME." return 1 fi - if [ -z "$_fritzbox_password" ]; then + if [ -z "$DEPLOY_FRITZBOX_PASSWORD" ]; then _err "FRITZ!Box password is not found, please define DEPLOY_FRITZBOX_PASSWORD." return 1 fi - if [ -z "$_fritzbox_url" ]; then + if [ -z "$DEPLOY_FRITZBOX_URL" ]; then _err "FRITZ!Box url is not found, please define DEPLOY_FRITZBOX_URL." return 1 fi - _saveaccountconf DEPLOY_FRITZBOX_USERNAME "${_fritzbox_username}" - _saveaccountconf DEPLOY_FRITZBOX_PASSWORD "${_fritzbox_password}" - _saveaccountconf DEPLOY_FRITZBOX_URL "${_fritzbox_url}" + # Save current values + _savedeployconf DEPLOY_FRITZBOX_USERNAME "$DEPLOY_FRITZBOX_USERNAME" + _savedeployconf DEPLOY_FRITZBOX_PASSWORD "$DEPLOY_FRITZBOX_PASSWORD" + _savedeployconf DEPLOY_FRITZBOX_URL "$DEPLOY_FRITZBOX_URL" # Do not check for a valid SSL certificate, because initially the cert is not valid, so it could not install the LE generated certificate export HTTPS_INSECURE=1 _info "Log in to the FRITZ!Box" - _fritzbox_challenge="$(_get "${_fritzbox_url}/login_sid.lua" | sed -e 's/^.*//' -e 's/<\/Challenge>.*$//')" + _fritzbox_challenge="$(_get "${DEPLOY_FRITZBOX_URL}/login_sid.lua" | sed -e 's/^.*//' -e 's/<\/Challenge>.*$//')" if _exists iconv; then - _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | _digest md5 hex)" + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${DEPLOY_FRITZBOX_PASSWORD}" | iconv -f ASCII -t UTF16LE | _digest md5 hex)" elif _exists uconv; then - _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | uconv -f ASCII -t UTF16LE | _digest md5 hex)" + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${DEPLOY_FRITZBOX_PASSWORD}" | uconv -f ASCII -t UTF16LE | _digest md5 hex)" else - _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | _digest md5 hex)" + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${DEPLOY_FRITZBOX_PASSWORD}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | _digest md5 hex)" fi - _fritzbox_sid="$(_get "${_fritzbox_url}/login_sid.lua?sid=0000000000000000&username=${_fritzbox_username}&response=${_fritzbox_challenge}-${_fritzbox_hash}" | sed -e 's/^.*//' -e 's/<\/SID>.*$//')" + _fritzbox_sid="$(_get "${DEPLOY_FRITZBOX_URL}/login_sid.lua?sid=0000000000000000&username=${DEPLOY_FRITZBOX_USERNAME}&response=${_fritzbox_challenge}-${_fritzbox_hash}" | sed -e 's/^.*//' -e 's/<\/SID>.*$//')" if [ -z "${_fritzbox_sid}" ] || [ "${_fritzbox_sid}" = "0000000000000000" ]; then _err "Logging in to the FRITZ!Box failed. Please check username, password and URL." @@ -104,7 +112,7 @@ fritzbox_deploy() { _info "Upload certificate to the FRITZ!Box" export _H1="Content-type: multipart/form-data boundary=${_post_boundary}" - _post "$(cat "${_post_request}")" "${_fritzbox_url}/cgi-bin/firmwarecfg" | grep SSL + _post "$(cat "${_post_request}")" "${DEPLOY_FRITZBOX_URL}/cgi-bin/firmwarecfg" | grep SSL retval=$? if [ $retval = 0 ]; then From 8cdceb83b2422b17ba5c5e6242a46c6cd481c669 Mon Sep 17 00:00:00 2001 From: Jacob Vandborg <16362036+jvandborg@users.noreply.github.com> Date: Thu, 6 Jan 2022 19:21:05 +0100 Subject: [PATCH 1617/2234] Cannot wait for PR #3673 to be completed PR #3673 Fix simply.com API seems abandoned by maintainer and I need this fixed asap Changes implemented * Normalize JSON and fix not handling return code correctly * Add some information to comments * Fix trailing slash on URIs * Add 60 second sleep for zone to be written * Fix parsing record_data and record_type --- dnsapi/dns_simply.sh | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index e0e05017..2baa4581 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -1,15 +1,15 @@ #!/usr/bin/env sh -# +# API-integration for Simply.com (https://www.simply.com) + #SIMPLY_AccountName="accountname" -# #SIMPLY_ApiKey="apikey" # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" SIMPLY_Api_Default="https://api.simply.com/1" #This is used for determining success of REST call -SIMPLY_SUCCESS_CODE='"status": 200' +SIMPLY_SUCCESS_CODE='"status":200' ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -51,7 +51,7 @@ dns_simply_rm() { _simply_save_config - _debug "First detect the root zone" + _debug "Find the DNS zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -77,8 +77,8 @@ dns_simply_rm() { for record in $records; do _debug record "$record" - record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) - record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + record_data=$(echo "$record" | sed -n "s/.*\"data\":\"\([^\"]*\)\".*/\1/p") + record_type=$(echo "$record" | sed -n "s/.*\"type\":\"\([^\"]*\)\".*/\1/p") _debug2 record_data "$record_data" _debug2 record_type "$record_type" @@ -151,7 +151,7 @@ _simply_save_config() { _simply_get_all_records() { domain=$1 - if ! _simply_rest GET "my/products/$domain/dns/records"; then + if ! _simply_rest GET "my/products/$domain/dns/records/"; then return 1 fi @@ -169,7 +169,7 @@ _get_root() { return 1 fi - if ! _simply_rest GET "my/products/$h/dns"; then + if ! _simply_rest GET "my/products/$h/dns/"; then return 1 fi @@ -193,7 +193,7 @@ _simply_add_record() { data="{\"name\": \"$sub_domain\", \"type\":\"TXT\", \"data\": \"$txtval\", \"priority\":0, \"ttl\": 3600}" - if ! _simply_rest POST "my/products/$domain/dns/records" "$data"; then + if ! _simply_rest POST "my/products/$domain/dns/records/" "$data"; then _err "Adding record not successfull!" return 1 fi @@ -203,6 +203,9 @@ _simply_add_record() { _err "$response" return 1 fi + + _info "Waiting 60 seconds for DNS changes to be written" + _sleep 60 return 0 } @@ -214,7 +217,7 @@ _simply_delete_record() { _debug record_id "Delete record with id $record_id" - if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id"; then + if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id/"; then _err "Deleting record not successfull!" return 1 fi @@ -249,6 +252,8 @@ _simply_rest() { _err "error $ep" return 1 fi + + response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" From 459faf4dfb121154aa0e9a48bac3c07cd3657239 Mon Sep 17 00:00:00 2001 From: jvandborg <16362036+jvandborg@users.noreply.github.com> Date: Thu, 6 Jan 2022 22:03:39 +0100 Subject: [PATCH 1618/2234] Format to comply with style guide --- dnsapi/dns_simply.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 2baa4581..85819ab8 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -203,7 +203,7 @@ _simply_add_record() { _err "$response" return 1 fi - + _info "Waiting 60 seconds for DNS changes to be written" _sleep 60 @@ -252,7 +252,7 @@ _simply_rest() { _err "error $ep" return 1 fi - + response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" From e23c02575db58790a4e3c96734549afa4aefe40e Mon Sep 17 00:00:00 2001 From: Jacob Vandborg <16362036+jvandborg@users.noreply.github.com> Date: Fri, 7 Jan 2022 08:10:31 +0100 Subject: [PATCH 1619/2234] Removed DNS sleep Users should use command line parameter --dnssleep instead --- dnsapi/dns_simply.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 85819ab8..437e5e5c 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -204,9 +204,6 @@ _simply_add_record() { return 1 fi - _info "Waiting 60 seconds for DNS changes to be written" - _sleep 60 - return 0 } From d43b587d175f3631df72d1a1d833a775df6a1066 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 7 Jan 2022 22:06:18 +0800 Subject: [PATCH 1620/2234] fix https://github.com/acmesh-official/acme.sh/issues/3870 --- acme.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index b536d742..97d1e257 100755 --- a/acme.sh +++ b/acme.sh @@ -1272,9 +1272,17 @@ _createcsr() { _csr_cn="$(_idn "$domain")" _debug2 _csr_cn "$_csr_cn" if _contains "$(uname -a)" "MINGW"; then - ${ACME_OPENSSL_BIN:-openssl} req -new -sha256 -key "$csrkey" -subj "//CN=$_csr_cn" -config "$csrconf" -out "$csr" + if _isIP "$_csr_cn"; then + ${ACME_OPENSSL_BIN:-openssl} req -new -sha256 -key "$csrkey" -subj "//O=$PROJECT_NAME" -config "$csrconf" -out "$csr" + else + ${ACME_OPENSSL_BIN:-openssl} req -new -sha256 -key "$csrkey" -subj "//CN=$_csr_cn" -config "$csrconf" -out "$csr" + fi else - ${ACME_OPENSSL_BIN:-openssl} req -new -sha256 -key "$csrkey" -subj "/CN=$_csr_cn" -config "$csrconf" -out "$csr" + if _isIP "$_csr_cn"; then + ${ACME_OPENSSL_BIN:-openssl} req -new -sha256 -key "$csrkey" -subj "/O=$PROJECT_NAME" -config "$csrconf" -out "$csr" + else + ${ACME_OPENSSL_BIN:-openssl} req -new -sha256 -key "$csrkey" -subj "/CN=$_csr_cn" -config "$csrconf" -out "$csr" + fi fi } From b2f4cc2dc55459f4ca1e927670935b04afe2695e Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 7 Jan 2022 22:58:42 +0800 Subject: [PATCH 1621/2234] add Step-ca to CI https://github.com/acmesh-official/acme.sh/issues/3871 --- .github/workflows/Ubuntu.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 28b06541..0f6a4799 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -30,6 +30,11 @@ jobs: CA: "ZeroSSL RSA Domain Secure Site CA" CA_EMAIL: "githubtest@acme.sh" TEST_PREFERRED_CHAIN: "" + - TEST_ACME_Server: "https://localhost:9000/acme/acme/directory" + CA_ECDSA: "" + CA: "Smallstep Intermediate CA" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: "" runs-on: ubuntu-latest env: @@ -44,6 +49,18 @@ jobs: - uses: actions/checkout@v2 - name: Install tools run: sudo apt-get install -y socat + - name: Start StepCA + if: ${{ matrix.TEST_ACME_Server=='https://localhost:9000/acme/acme/directory' }} + run: | + docker run -d \ + -p 9000:9000 \ + -e "DOCKER_STEPCA_INIT_NAME=Smallstep" \ + -e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \ + --name stepca \ + smallstep/step-ca \ + && docker exec -it stepca step ca provisioner add acme --type ACME \ + && docker exec -it stepca kill -1 1 \ + && docker exec -it stepca cat /home/step/certs/root_ca.crt >>/etc/ssl/certs/ca-certificates.crt - name: Clone acmetest run: | cd .. \ From 735db1a12be7b88e4f1a1c7e622dddbc751dd432 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 7 Jan 2022 23:00:34 +0800 Subject: [PATCH 1622/2234] fix ci --- .github/workflows/Ubuntu.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 0f6a4799..33c20161 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -58,9 +58,9 @@ jobs: -e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \ --name stepca \ smallstep/step-ca \ - && docker exec -it stepca step ca provisioner add acme --type ACME \ - && docker exec -it stepca kill -1 1 \ - && docker exec -it stepca cat /home/step/certs/root_ca.crt >>/etc/ssl/certs/ca-certificates.crt + && docker exec stepca step ca provisioner add acme --type ACME \ + && docker exec stepca kill -1 1 \ + && docker exec stepca cat /home/step/certs/root_ca.crt >>/etc/ssl/certs/ca-certificates.crt - name: Clone acmetest run: | cd .. \ From 10f171b6e4cdd2211207f75f0e00d07fdc91a87e Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 7 Jan 2022 23:05:49 +0800 Subject: [PATCH 1623/2234] fix ci --- .github/workflows/Ubuntu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 33c20161..1123c1ac 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -52,13 +52,13 @@ jobs: - name: Start StepCA if: ${{ matrix.TEST_ACME_Server=='https://localhost:9000/acme/acme/directory' }} run: | - docker run -d \ + docker run --rm -d \ -p 9000:9000 \ -e "DOCKER_STEPCA_INIT_NAME=Smallstep" \ -e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \ --name stepca \ smallstep/step-ca \ - && docker exec stepca step ca provisioner add acme --type ACME \ + && sleep 5 && docker exec stepca step ca provisioner add acme --type ACME \ && docker exec stepca kill -1 1 \ && docker exec stepca cat /home/step/certs/root_ca.crt >>/etc/ssl/certs/ca-certificates.crt - name: Clone acmetest From 49deb4af24d539a407b9fae4675d17d0b16b96f9 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 7 Jan 2022 23:09:56 +0800 Subject: [PATCH 1624/2234] fix CI --- .github/workflows/Ubuntu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 1123c1ac..e967e3b4 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -60,7 +60,7 @@ jobs: smallstep/step-ca \ && sleep 5 && docker exec stepca step ca provisioner add acme --type ACME \ && docker exec stepca kill -1 1 \ - && docker exec stepca cat /home/step/certs/root_ca.crt >>/etc/ssl/certs/ca-certificates.crt + && docker exec stepca cat /home/step/certs/root_ca.crt | sudo cat - >>/etc/ssl/certs/ca-certificates.crt - name: Clone acmetest run: | cd .. \ From ec10a3eab4ba87fce47ce83eeff3a7831fb4ad31 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 7 Jan 2022 23:14:46 +0800 Subject: [PATCH 1625/2234] fix CI --- .github/workflows/Ubuntu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index e967e3b4..3ac7d6ab 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -60,7 +60,7 @@ jobs: smallstep/step-ca \ && sleep 5 && docker exec stepca step ca provisioner add acme --type ACME \ && docker exec stepca kill -1 1 \ - && docker exec stepca cat /home/step/certs/root_ca.crt | sudo cat - >>/etc/ssl/certs/ca-certificates.crt + && docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt" - name: Clone acmetest run: | cd .. \ From 8e9bbd1bb3e83d1af7687a16dd9b4b7a2c3f407f Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 7 Jan 2022 23:35:18 +0800 Subject: [PATCH 1626/2234] fix CI --- .github/workflows/Ubuntu.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 3ac7d6ab..1f8db98a 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -35,6 +35,7 @@ jobs: CA: "Smallstep Intermediate CA" CA_EMAIL: "" TEST_PREFERRED_CHAIN: "" + NO_REVOKE: 1 runs-on: ubuntu-latest env: @@ -45,6 +46,7 @@ jobs: CA_EMAIL: ${{ matrix.CA_EMAIL }} NO_ECC_384: ${{ matrix.NO_ECC_384 }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + NO_REVOKE: ${{ matrix.NO_REVOKE }} steps: - uses: actions/checkout@v2 - name: Install tools From 45971b80834c0bea59f3dc549f23e968ccd04fbc Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 7 Jan 2022 23:43:08 +0800 Subject: [PATCH 1627/2234] add ip cert test for stepCA --- .github/workflows/Ubuntu.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 1f8db98a..ebf69a3b 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -36,6 +36,14 @@ jobs: CA_EMAIL: "" TEST_PREFERRED_CHAIN: "" NO_REVOKE: 1 + - TEST_ACME_Server: "https://localhost:9000/acme/acme/directory" + CA_ECDSA: "" + CA: "Smallstep Intermediate CA" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: "" + NO_REVOKE: 1 + TEST_IPCERT: 1 + TestingDomain: "172.17.0.1" runs-on: ubuntu-latest env: @@ -47,6 +55,8 @@ jobs: NO_ECC_384: ${{ matrix.NO_ECC_384 }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} NO_REVOKE: ${{ matrix.NO_REVOKE }} + TEST_IPCERT: ${{ matrix.TEST_IPCERT }} + TestingDomain: ${{ matrix.TestingDomain }} steps: - uses: actions/checkout@v2 - name: Install tools From d42feae0af801ad1c1ec0236925c350b8372571b Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 7 Jan 2022 23:44:19 +0800 Subject: [PATCH 1628/2234] fix ecdsa name for stepca --- .github/workflows/Ubuntu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index ebf69a3b..4540580c 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -31,13 +31,13 @@ jobs: CA_EMAIL: "githubtest@acme.sh" TEST_PREFERRED_CHAIN: "" - TEST_ACME_Server: "https://localhost:9000/acme/acme/directory" - CA_ECDSA: "" + CA_ECDSA: "Smallstep Intermediate CA" CA: "Smallstep Intermediate CA" CA_EMAIL: "" TEST_PREFERRED_CHAIN: "" NO_REVOKE: 1 - TEST_ACME_Server: "https://localhost:9000/acme/acme/directory" - CA_ECDSA: "" + CA_ECDSA: "Smallstep Intermediate CA" CA: "Smallstep Intermediate CA" CA_EMAIL: "" TEST_PREFERRED_CHAIN: "" From 75ae57e1945c7f6883aa8b494a9b0f6a43a79f63 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jan 2022 19:19:51 +0800 Subject: [PATCH 1629/2234] report false --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 32d97614..46fd8283 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -37,7 +37,7 @@ jobs: - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" run: | echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" - if [ "${{github.actor}}" != "Neilpang" ]; then + if [ "${{github.repository_owner}}" != "acmesh-official" ]; then false fi From 86c3fa0df030d3b5ac7c1597b19b0b36d9616e1a Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jan 2022 19:51:04 +0800 Subject: [PATCH 1630/2234] remove retry for get and post --- acme.sh | 72 ++++----------------------------------------------------- 1 file changed, 5 insertions(+), 67 deletions(-) diff --git a/acme.sh b/acme.sh index b536d742..b0a4388b 100755 --- a/acme.sh +++ b/acme.sh @@ -1831,8 +1831,6 @@ _inithttp() { } -_HTTP_MAX_RETRY=8 - # body url [needbase64] [POST|PUT|DELETE] [ContentType] _post() { body="$1" @@ -1840,33 +1838,6 @@ _post() { needbase64="$3" httpmethod="$4" _postContentType="$5" - _sleep_retry_sec=1 - _http_retry_times=0 - _hcode=0 - while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do - [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] - _lastHCode="$?" - _debug "Retrying post" - _post_impl "$body" "$_post_url" "$needbase64" "$httpmethod" "$_postContentType" "$_lastHCode" - _hcode="$?" - _debug _hcode "$_hcode" - if [ "$_hcode" = "0" ]; then - break - fi - _http_retry_times=$(_math $_http_retry_times + 1) - _sleep $_sleep_retry_sec - done - return $_hcode -} - -# body url [needbase64] [POST|PUT|DELETE] [ContentType] [displayError] -_post_impl() { - body="$1" - _post_url="$2" - needbase64="$3" - httpmethod="$4" - _postContentType="$5" - displayError="$6" if [ -z "$httpmethod" ]; then httpmethod="POST" @@ -1918,9 +1889,7 @@ _post_impl() { fi _ret="$?" if [ "$_ret" != "0" ]; then - if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" - fi + _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _err "Here is the curl dump log:" _err "$(cat "$_CURL_DUMP")" @@ -1976,9 +1945,7 @@ _post_impl() { _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." fi if [ "$_ret" != "0" ]; then - if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then - _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" - fi + _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" fi _sed_i "s/^ *//g" "$HTTP_HEADER" else @@ -1992,38 +1959,13 @@ _post_impl() { # url getheader timeout _get() { - url="$1" - onlyheader="$2" - t="$3" - _sleep_retry_sec=1 - _http_retry_times=0 - _hcode=0 - while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do - [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] - _lastHCode="$?" - _debug "Retrying GET" - _get_impl "$url" "$onlyheader" "$t" "$_lastHCode" - _hcode="$?" - _debug _hcode "$_hcode" - if [ "$_hcode" = "0" ]; then - break - fi - _http_retry_times=$(_math $_http_retry_times + 1) - _sleep $_sleep_retry_sec - done - return $_hcode -} - -# url getheader timeout displayError -_get_impl() { _debug GET url="$1" onlyheader="$2" t="$3" - displayError="$4" _debug url "$url" _debug "timeout=$t" - _debug "displayError" "$displayError" + _inithttp if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then @@ -2042,9 +1984,7 @@ _get_impl() { fi ret=$? if [ "$ret" != "0" ]; then - if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" - fi + _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _err "Here is the curl dump log:" _err "$(cat "$_CURL_DUMP")" @@ -2070,9 +2010,7 @@ _get_impl() { _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." fi if [ "$ret" != "0" ]; then - if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then - _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret" - fi + _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret" fi else ret=$? From e67d26caeb94c54d4daee8b8ce691b77d4861ce3 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jan 2022 19:58:49 +0800 Subject: [PATCH 1631/2234] fix https://github.com/acmesh-official/acme.sh/issues/3845#issuecomment-999367478 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index b0a4388b..b25619bf 100755 --- a/acme.sh +++ b/acme.sh @@ -1252,7 +1252,7 @@ _createcsr() { else domainlist="$(_idn "$domainlist")" _debug2 domainlist "$domainlist" - alt="$(_getIdType "$domain" | _upper_case):$domain" + alt="$(_getIdType "$domain" | _upper_case):$(_idn "$domain")" for dl in $(echo "$domainlist" | tr "," ' '); do alt="$alt,$(_getIdType "$dl" | _upper_case):$dl" done From 4346139d65ee013578e5e0893f425d1bab9863d7 Mon Sep 17 00:00:00 2001 From: Bodenhaltung <12759677+Bodenhaltung@users.noreply.github.com> Date: Sun, 9 Jan 2022 03:32:22 +0100 Subject: [PATCH 1632/2234] Add dnsHome.de API (#3823) Add dnsHome.de API --- dnsapi/dns_dnshome.sh | 87 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 dnsapi/dns_dnshome.sh diff --git a/dnsapi/dns_dnshome.sh b/dnsapi/dns_dnshome.sh new file mode 100755 index 00000000..99608769 --- /dev/null +++ b/dnsapi/dns_dnshome.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env sh + +# dnsHome.de API for acme.sh +# +# This Script adds the necessary TXT record to a Subdomain +# +# Author dnsHome.de (https://github.com/dnsHome-de) +# +# Report Bugs to https://github.com/acmesh-official/acme.sh/issues/3819 +# +# export DNSHOME_Subdomain="" +# export DNSHOME_SubdomainPassword="" + +# Usage: add subdomain.ddnsdomain.tld "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record +dns_dnshome_add() { + txtvalue=$2 + + DNSHOME_Subdomain="${DNSHOME_Subdomain:-$(_readdomainconf DNSHOME_Subdomain)}" + DNSHOME_SubdomainPassword="${DNSHOME_SubdomainPassword:-$(_readdomainconf DNSHOME_SubdomainPassword)}" + + if [ -z "$DNSHOME_Subdomain" ] || [ -z "$DNSHOME_SubdomainPassword" ]; then + DNSHOME_Subdomain="" + DNSHOME_SubdomainPassword="" + _err "Please specify/export your dnsHome.de Subdomain and Password" + return 1 + fi + + #save the credentials to the account conf file. + _savedomainconf DNSHOME_Subdomain "$DNSHOME_Subdomain" + _savedomainconf DNSHOME_SubdomainPassword "$DNSHOME_SubdomainPassword" + + DNSHOME_Api="https://$DNSHOME_Subdomain:$DNSHOME_SubdomainPassword@www.dnshome.de/dyndns.php" + + _DNSHOME_rest POST "acme=add&txt=$txtvalue" + if ! echo "$response" | grep 'successfully' >/dev/null; then + _err "Error" + _err "$response" + return 1 + fi + + return 0 +} + +# Usage: txtvalue +# Used to remove the txt record after validation +dns_dnshome_rm() { + txtvalue=$2 + + DNSHOME_Subdomain="${DNSHOME_Subdomain:-$(_readdomainconf DNSHOME_Subdomain)}" + DNSHOME_SubdomainPassword="${DNSHOME_SubdomainPassword:-$(_readdomainconf DNSHOME_SubdomainPassword)}" + + DNSHOME_Api="https://$DNSHOME_Subdomain:$DNSHOME_SubdomainPassword@www.dnshome.de/dyndns.php" + + if [ -z "$DNSHOME_Subdomain" ] || [ -z "$DNSHOME_SubdomainPassword" ]; then + DNSHOME_Subdomain="" + DNSHOME_SubdomainPassword="" + _err "Please specify/export your dnsHome.de Subdomain and Password" + return 1 + fi + + _DNSHOME_rest POST "acme=rm&txt=$txtvalue" + if ! echo "$response" | grep 'successfully' >/dev/null; then + _err "Error" + _err "$response" + return 1 + fi + + return 0 +} + +#################### Private functions below ################################## +_DNSHOME_rest() { + method=$1 + data="$2" + _debug "$data" + + _debug data "$data" + response="$(_post "$data" "$DNSHOME_Api" "" "$method")" + + if [ "$?" != "0" ]; then + _err "error $data" + return 1 + fi + _debug2 response "$response" + return 0 +} From 61c853a3c15656f2be5259285f571e53cb400211 Mon Sep 17 00:00:00 2001 From: "Victor R. Santos" Date: Sun, 9 Jan 2022 02:39:28 +0000 Subject: [PATCH 1633/2234] Add Gotify notification (#3759) --- notify/gotify.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 notify/gotify.sh diff --git a/notify/gotify.sh b/notify/gotify.sh new file mode 100644 index 00000000..e370bc21 --- /dev/null +++ b/notify/gotify.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env sh + +#Support Gotify + +#GOTIFY_URL="https://gotify.example.com" +#GOTIFY_TOKEN="123456789ABCDEF" + +#optional +#GOTIFY_PRIORITY=0 + +# subject content statusCode +gotify_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + GOTIFY_URL="${GOTIFY_URL:-$(_readaccountconf_mutable GOTIFY_URL)}" + if [ -z "$GOTIFY_URL" ]; then + GOTIFY_URL="" + _err "You didn't specify the gotify server url GOTIFY_URL." + return 1 + fi + _saveaccountconf_mutable GOTIFY_URL "$GOTIFY_URL" + + GOTIFY_TOKEN="${GOTIFY_TOKEN:-$(_readaccountconf_mutable GOTIFY_TOKEN)}" + if [ -z "$GOTIFY_TOKEN" ]; then + GOTIFY_TOKEN="" + _err "You didn't specify the gotify token GOTIFY_TOKEN." + return 1 + fi + _saveaccountconf_mutable GOTIFY_TOKEN "$GOTIFY_TOKEN" + + GOTIFY_PRIORITY="${GOTIFY_PRIORITY:-$(_readaccountconf_mutable GOTIFY_PRIORITY)}" + if [ -z "$GOTIFY_PRIORITY" ]; then + GOTIFY_PRIORITY=0 + else + _saveaccountconf_mutable GOTIFY_PRIORITY "$GOTIFY_PRIORITY" + fi + + export _H1="X-Gotify-Key: ${GOTIFY_TOKEN}" + export _H2="Content-Type: application/json" + + _content=$(echo "$_content" | _json_encode) + _subject=$(echo "$_subject" | _json_encode) + + _data="{\"title\": \"${_subject}\", \"message\": \"${_content}\", \"priority\": ${GOTIFY_PRIORITY}}" + + response="$(_post "${_data}" "${GOTIFY_URL}/message" "" "POST" "application/json")" + + if [ "$?" != "0" ]; then + _err "Failed to send message" + _err "$response" + return 1 + fi + + _debug2 response "$response" + + return 0 +} From 7e7291ace9d36ed2674c0042a2aa288396869a61 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Sun, 9 Jan 2022 06:01:38 +0300 Subject: [PATCH 1634/2234] Support Vault KV v2 (#3502) --- deploy/vault.sh | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/deploy/vault.sh b/deploy/vault.sh index 70c80444..399abaee 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -56,12 +56,23 @@ vault_deploy() { export _H1="X-Vault-Token: $VAULT_TOKEN" if [ -n "$FABIO" ]; then - _post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" + if [ -n "$VAULT_KV_V2" ]; then + _post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" + else + _post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" + fi else - _post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" - _post "{\"value\": \"$_ckey\"}" "$URL/cert.key" - _post "{\"value\": \"$_cca\"}" "$URL/chain.pem" - _post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" + if [ -n "$VAULT_KV_V2" ]; then + _post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem" + _post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key" + _post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem" + _post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem" + else + _post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" + _post "{\"value\": \"$_ckey\"}" "$URL/cert.key" + _post "{\"value\": \"$_cca\"}" "$URL/chain.pem" + _post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" + fi fi } From 2ce145f359deaaaff9bea06312984c70a04ef87c Mon Sep 17 00:00:00 2001 From: Felix Matouschek Date: Sun, 9 Jan 2022 04:11:00 +0100 Subject: [PATCH 1635/2234] Refactoring amcedns api (second try) (#3231) --- dnsapi/dns_acmedns.sh | 63 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 12 deletions(-) mode change 100644 => 100755 dnsapi/dns_acmedns.sh diff --git a/dnsapi/dns_acmedns.sh b/dnsapi/dns_acmedns.sh old mode 100644 new mode 100755 index 9b3efa48..057f9742 --- a/dnsapi/dns_acmedns.sh +++ b/dnsapi/dns_acmedns.sh @@ -1,31 +1,70 @@ #!/usr/bin/env sh # #Author: Wolfgang Ebner -#Report Bugs here: https://github.com/webner/acme.sh +#Author: Sven Neubuaer +#Report Bugs here: https://github.com/dampfklon/acme.sh +# +# Usage: +# export ACMEDNS_BASE_URL="https://auth.acme-dns.io" +# +# You can optionally define an already existing account: +# +# export ACMEDNS_USERNAME="" +# export ACMEDNS_PASSWORD="" +# export ACMEDNS_SUBDOMAIN="" # ######## Public functions ##################### #Usage: dns_acmedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record dns_acmedns_add() { fulldomain=$1 txtvalue=$2 _info "Using acme-dns" - _debug fulldomain "$fulldomain" - _debug txtvalue "$txtvalue" + _debug "fulldomain $fulldomain" + _debug "txtvalue $txtvalue" - ACMEDNS_UPDATE_URL="${ACMEDNS_UPDATE_URL:-$(_readaccountconf_mutable ACMEDNS_UPDATE_URL)}" + #for compatiblity from account conf ACMEDNS_USERNAME="${ACMEDNS_USERNAME:-$(_readaccountconf_mutable ACMEDNS_USERNAME)}" + _clearaccountconf_mutable ACMEDNS_USERNAME ACMEDNS_PASSWORD="${ACMEDNS_PASSWORD:-$(_readaccountconf_mutable ACMEDNS_PASSWORD)}" + _clearaccountconf_mutable ACMEDNS_PASSWORD ACMEDNS_SUBDOMAIN="${ACMEDNS_SUBDOMAIN:-$(_readaccountconf_mutable ACMEDNS_SUBDOMAIN)}" + _clearaccountconf_mutable ACMEDNS_SUBDOMAIN - if [ "$ACMEDNS_UPDATE_URL" = "" ]; then - ACMEDNS_UPDATE_URL="https://auth.acme-dns.io/update" + ACMEDNS_BASE_URL="${ACMEDNS_BASE_URL:-$(_readdomainconf ACMEDNS_BASE_URL)}" + ACMEDNS_USERNAME="${ACMEDNS_USERNAME:-$(_readdomainconf ACMEDNS_USERNAME)}" + ACMEDNS_PASSWORD="${ACMEDNS_PASSWORD:-$(_readdomainconf ACMEDNS_PASSWORD)}" + ACMEDNS_SUBDOMAIN="${ACMEDNS_SUBDOMAIN:-$(_readdomainconf ACMEDNS_SUBDOMAIN)}" + + if [ "$ACMEDNS_BASE_URL" = "" ]; then + ACMEDNS_BASE_URL="https://auth.acme-dns.io" fi - _saveaccountconf_mutable ACMEDNS_UPDATE_URL "$ACMEDNS_UPDATE_URL" - _saveaccountconf_mutable ACMEDNS_USERNAME "$ACMEDNS_USERNAME" - _saveaccountconf_mutable ACMEDNS_PASSWORD "$ACMEDNS_PASSWORD" - _saveaccountconf_mutable ACMEDNS_SUBDOMAIN "$ACMEDNS_SUBDOMAIN" + ACMEDNS_UPDATE_URL="$ACMEDNS_BASE_URL/update" + ACMEDNS_REGISTER_URL="$ACMEDNS_BASE_URL/register" + + if [ -z "$ACMEDNS_USERNAME" ] || [ -z "$ACMEDNS_PASSWORD" ]; then + response="$(_post "" "$ACMEDNS_REGISTER_URL" "" "POST")" + _debug response "$response" + ACMEDNS_USERNAME=$(echo "$response" | sed -n 's/^{.*\"username\":[ ]*\"\([^\"]*\)\".*}/\1/p') + _debug "received username: $ACMEDNS_USERNAME" + ACMEDNS_PASSWORD=$(echo "$response" | sed -n 's/^{.*\"password\":[ ]*\"\([^\"]*\)\".*}/\1/p') + _debug "received password: $ACMEDNS_PASSWORD" + ACMEDNS_SUBDOMAIN=$(echo "$response" | sed -n 's/^{.*\"subdomain\":[ ]*\"\([^\"]*\)\".*}/\1/p') + _debug "received subdomain: $ACMEDNS_SUBDOMAIN" + ACMEDNS_FULLDOMAIN=$(echo "$response" | sed -n 's/^{.*\"fulldomain\":[ ]*\"\([^\"]*\)\".*}/\1/p') + _info "##########################################################" + _info "# Create $fulldomain CNAME $ACMEDNS_FULLDOMAIN DNS entry #" + _info "##########################################################" + _info "Press enter to continue... " + read -r _ + fi + + _savedomainconf ACMEDNS_BASE_URL "$ACMEDNS_BASE_URL" + _savedomainconf ACMEDNS_USERNAME "$ACMEDNS_USERNAME" + _savedomainconf ACMEDNS_PASSWORD "$ACMEDNS_PASSWORD" + _savedomainconf ACMEDNS_SUBDOMAIN "$ACMEDNS_SUBDOMAIN" export _H1="X-Api-User: $ACMEDNS_USERNAME" export _H2="X-Api-Key: $ACMEDNS_PASSWORD" @@ -48,8 +87,8 @@ dns_acmedns_rm() { fulldomain=$1 txtvalue=$2 _info "Using acme-dns" - _debug fulldomain "$fulldomain" - _debug txtvalue "$txtvalue" + _debug "fulldomain $fulldomain" + _debug "txtvalue $txtvalue" } #################### Private functions below ################################## From 62dad721fceba8782903726349ee22dfff2400e4 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Sun, 9 Jan 2022 11:04:15 +0100 Subject: [PATCH 1636/2234] Start ShellCheck and CI Test --- dnsapi/dns_selfhost.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index d7dfcca4..8c6e9a91 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -2,6 +2,7 @@ # # Author: Marvin Edeler # Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 +# Last Edit: 09.01.2022 dns_selfhost_add() { domain=$1 From bda454fe9cbb3ba2d73251416a703db28a7d4ff7 Mon Sep 17 00:00:00 2001 From: I Komang Suryadana Date: Tue, 11 Jan 2022 15:25:10 +0800 Subject: [PATCH 1637/2234] Remove cloud domain record with cloud master zone. (#3507) --- dnsapi/dns_cloudns.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/dnsapi/dns_cloudns.sh b/dnsapi/dns_cloudns.sh index 381d17ec..b03fd579 100755 --- a/dnsapi/dns_cloudns.sh +++ b/dnsapi/dns_cloudns.sh @@ -2,11 +2,14 @@ # Author: Boyan Peychev # Repository: https://github.com/ClouDNS/acme.sh/ +# Editor: I Komang Suryadana #CLOUDNS_AUTH_ID=XXXXX #CLOUDNS_SUB_AUTH_ID=XXXXX #CLOUDNS_AUTH_PASSWORD="YYYYYYYYY" CLOUDNS_API="https://api.cloudns.net" +DOMAIN_TYPE= +DOMAIN_MASTER= ######## Public functions ##################### @@ -61,6 +64,15 @@ dns_cloudns_rm() { host="$(echo "$1" | sed "s/\.$zone\$//")" record=$2 + _dns_cloudns_get_zone_info "$zone" + + _debug "Type" "$DOMAIN_TYPE" + _debug "Cloud Master" "$DOMAIN_MASTER" + if _contains "$DOMAIN_TYPE" "cloud"; then + zone=$DOMAIN_MASTER + fi + _debug "ZONE" "$zone" + _dns_cloudns_http_api_call "dns/records.json" "domain-name=$zone&host=$host&type=TXT" if ! _contains "$response" "\"id\":"; then return 1 @@ -134,6 +146,18 @@ _dns_cloudns_init_check() { return 0 } +_dns_cloudns_get_zone_info() { + zone=$1 + _dns_cloudns_http_api_call "dns/get-zone-info.json" "domain-name=$zone" + if ! _contains "$response" "\"status\":\"Failed\""; then + DOMAIN_TYPE=$(echo "$response" | _egrep_o '"type":"[^"]*"' | cut -d : -f 2 | tr -d '"') + if _contains "$DOMAIN_TYPE" "cloud"; then + DOMAIN_MASTER=$(echo "$response" | _egrep_o '"cloud-master":"[^"]*"' | cut -d : -f 2 | tr -d '"') + fi + fi + return 0 +} + _dns_cloudns_get_zone_name() { i=2 while true; do From e07795e8f0e8f5d9c1cd6e68cbb35d4d4d5fff06 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Jan 2022 16:56:02 +0800 Subject: [PATCH 1638/2234] fix https://github.com/acmesh-official/acme.sh/issues/3883 --- acme.sh | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index f013fae2..9ec0c851 100755 --- a/acme.sh +++ b/acme.sh @@ -1631,6 +1631,24 @@ _stat() { return 1 #error, 'stat' not found } +#keyfile +_isRSA() { + keyfile=$1 + if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} rsa -in "$keyfile" -noout -text | grep "^publicExponent:" >/dev/null 2>&1; then + return 0 + fi + return 1 +} + +#keyfile +_isEcc() { + keyfile=$1 + if grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" >/dev/null 2>&1; then + return 0 + fi + return 1 +} + #keyfile _calcjwk() { keyfile="$1" @@ -1644,7 +1662,7 @@ _calcjwk() { return 0 fi - if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then + if _isRSA "$keyfile"; then _debug "RSA key" pub_exp=$(${ACME_OPENSSL_BIN:-openssl} rsa -in "$keyfile" -noout -text | grep "^publicExponent:" | cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1) if [ "${#pub_exp}" = "5" ]; then @@ -1666,7 +1684,7 @@ _calcjwk() { JWK_HEADER='{"alg": "RS256", "jwk": '$jwk'}' JWK_HEADERPLACE_PART1='{"nonce": "' JWK_HEADERPLACE_PART2='", "alg": "RS256"' - elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then + elif _isEcc "$keyfile"; then _debug "EC key" crv="$(${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" | cut -d ":" -f 2 | tr -d " \r\n")" _debug3 crv "$crv" From 188274277a18deb386f160de53262f22f8f7d7c2 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Jan 2022 17:16:51 +0800 Subject: [PATCH 1639/2234] fix https://github.com/acmesh-official/acme.sh/issues/3883 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 9ec0c851..78684267 100755 --- a/acme.sh +++ b/acme.sh @@ -1053,9 +1053,9 @@ _sign() { _sign_openssl="${ACME_OPENSSL_BIN:-openssl} dgst -sign $keyfile " - if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || grep "BEGIN PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then + if _isRSA "$keyfile" >/dev/null 2>&1; then $_sign_openssl -$alg | _base64 - elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then + elif _isEcc "$keyfile" >/dev/null 2>&1; then if ! _signedECText="$($_sign_openssl -sha$__ECC_KEY_LEN | ${ACME_OPENSSL_BIN:-openssl} asn1parse -inform DER)"; then _err "Sign failed: $_sign_openssl" _err "Key file: $keyfile" From e49ece87937aa258f32fa277c9f1a6d46b7484ce Mon Sep 17 00:00:00 2001 From: Yuan Ming Date: Fri, 14 Jan 2022 22:10:26 +0800 Subject: [PATCH 1640/2234] dns_huaweicloud.sh minor bug fixes 1. Match zone name in response in case multiple items return. 2. Use string '"id"' (single quotation marks added) to check if zone/record exist in _get_zoneid() & _get_recordset_id(). Fix domain can't contain string "id". (Sensitive _debug Access Token Commented out, For CICD Run) --- dnsapi/dns_huaweicloud.sh | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index f7192725..caac3e1e 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -35,7 +35,7 @@ dns_huaweicloud_add() { _err "dns_api(dns_huaweicloud): Error getting token." return 1 fi - _debug "Access token is: ${token}" + # _debug "Access token is: ${token}" unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" @@ -86,7 +86,7 @@ dns_huaweicloud_rm() { _err "dns_api(dns_huaweicloud): Error getting token." return 1 fi - _debug "Access token is: ${token}" + # _debug "Access token is: ${token}" unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" @@ -129,14 +129,25 @@ _get_zoneid() { fi _debug "$h" response=$(_get "${dns_api}/v2/zones?name=${h}") - - if _contains "${response}" "id"; then - _debug "Get Zone ID Success." - _zoneid=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") - printf "%s" "${_zoneid}" - return 0 + # _debug2 "$response" + if _contains "${response}" '"id"'; then + zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") + zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") + _debug2 "Return Zone ID(s):${zoneidlist}" + _debug2 "Return Zone Name(s):${zonenamelist}" + zoneidnum=0 + echo "${zonenamelist}" | while read -r zonename; do + zoneidnum=$(_math "$zoneidnum" + 1) + _debug "Check Zone Name $zonename" + if [ "${zonename}" = "${h}." ]; then + _debug "Get Zone ID Success." + _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p") + _debug2 "ZoneID:${_zoneid}" + printf "%s" "${_zoneid}" + return 0 + fi + done fi - i=$(_math "$i" + 1) done return 1 @@ -149,7 +160,7 @@ _get_recordset_id() { export _H1="X-Auth-Token: ${_token}" response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}") - if _contains "${response}" "id"; then + if _contains "${response}" '"id"'; then _id="$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")" printf "%s" "${_id}" return 0 @@ -269,7 +280,7 @@ _get_token() { _post "${body}" "${iam_api}/v3/auth/tokens" >/dev/null _code=$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n") _token=$(grep "^X-Subject-Token" "$HTTP_HEADER" | cut -d " " -f 2-) - _debug2 "${_code}" + # _debug2 "${_code}" printf "%s" "${_token}" return 0 } From 9d2ee2127de6ebcd2382e4cf9270276412d3f26f Mon Sep 17 00:00:00 2001 From: Yuan Ming Date: Sat, 15 Jan 2022 19:23:30 +0800 Subject: [PATCH 1641/2234] dns_huaweicloud debug info adjust _secure_debug for sensitive token. --- dnsapi/dns_huaweicloud.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index caac3e1e..cc21396a 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -35,7 +35,7 @@ dns_huaweicloud_add() { _err "dns_api(dns_huaweicloud): Error getting token." return 1 fi - # _debug "Access token is: ${token}" + _secure_debug "Access token is:" "${token}" unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" @@ -43,7 +43,7 @@ dns_huaweicloud_add() { _err "dns_api(dns_huaweicloud): Error getting zone id." return 1 fi - _debug "Zone ID is: ${zoneid}" + _debug "Zone ID is:" "${zoneid}" _debug "Adding Record" _add_record "${token}" "${fulldomain}" "${txtvalue}" @@ -86,7 +86,7 @@ dns_huaweicloud_rm() { _err "dns_api(dns_huaweicloud): Error getting token." return 1 fi - # _debug "Access token is: ${token}" + _secure_debug "Access token is:" "${token}" unset zoneid zoneid="$(_get_zoneid "${token}" "${fulldomain}")" @@ -94,7 +94,7 @@ dns_huaweicloud_rm() { _err "dns_api(dns_huaweicloud): Error getting zone id." return 1 fi - _debug "Zone ID is: ${zoneid}" + _debug "Zone ID is:" "${zoneid}" # Remove all records # Therotically HuaweiCloud does not allow more than one record set @@ -129,20 +129,20 @@ _get_zoneid() { fi _debug "$h" response=$(_get "${dns_api}/v2/zones?name=${h}") - # _debug2 "$response" + _debug2 "$response" if _contains "${response}" '"id"'; then zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") - _debug2 "Return Zone ID(s):${zoneidlist}" - _debug2 "Return Zone Name(s):${zonenamelist}" + _debug2 "Return Zone ID(s):" "${zoneidlist}" + _debug2 "Return Zone Name(s):" "${zonenamelist}" zoneidnum=0 echo "${zonenamelist}" | while read -r zonename; do zoneidnum=$(_math "$zoneidnum" + 1) - _debug "Check Zone Name $zonename" + _debug "Check Zone Name" "${zonename}" if [ "${zonename}" = "${h}." ]; then _debug "Get Zone ID Success." _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p") - _debug2 "ZoneID:${_zoneid}" + _debug2 "ZoneID:" "${_zoneid}" printf "%s" "${_zoneid}" return 0 fi @@ -208,7 +208,7 @@ _add_record() { fi _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" - _debug "Record Set ID is: ${_record_id}" + _debug "Record Set ID is:" "${_record_id}" # Remove all records while [ "${_record_id}" != "0" ]; do @@ -280,7 +280,7 @@ _get_token() { _post "${body}" "${iam_api}/v3/auth/tokens" >/dev/null _code=$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n") _token=$(grep "^X-Subject-Token" "$HTTP_HEADER" | cut -d " " -f 2-) - # _debug2 "${_code}" + _secure_debug "${_code}" printf "%s" "${_token}" return 0 } From edee7ea284c0b4f5670d859442c945b8cebd5b98 Mon Sep 17 00:00:00 2001 From: Ross Shen Date: Sun, 16 Jan 2022 20:46:09 +0800 Subject: [PATCH 1642/2234] routeros deploy hook: store the env vars within the domainconf related to #2344 and #2413 --- deploy/routeros.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 2f349999..9965d65c 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -66,21 +66,31 @@ routeros_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" + _getdeployconf ROUTER_OS_HOST + if [ -z "$ROUTER_OS_HOST" ]; then _debug "Using _cdomain as ROUTER_OS_HOST, please set if not correct." ROUTER_OS_HOST="$_cdomain" fi + _getdeployconf ROUTER_OS_USERNAME + if [ -z "$ROUTER_OS_USERNAME" ]; then _err "Need to set the env variable ROUTER_OS_USERNAME" return 1 fi + _getdeployconf ROUTER_OS_ADDITIONAL_SERVICES + if [ -z "$ROUTER_OS_ADDITIONAL_SERVICES" ]; then _debug "Not enabling additional services" ROUTER_OS_ADDITIONAL_SERVICES="" fi + _savedeployconf ROUTER_OS_HOST "$ROUTER_OS_HOST" + _savedeployconf ROUTER_OS_USERNAME "$ROUTER_OS_USERNAME" + _savedeployconf ROUTER_OS_ADDITIONAL_SERVICES "$ROUTER_OS_ADDITIONAL_SERVICES" + _info "Trying to push key '$_ckey' to router" scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" _info "Trying to push cert '$_cfullchain' to router" From dca9def42c2d8fb86551d5d5c6e70124defebb29 Mon Sep 17 00:00:00 2001 From: Ross Shen Date: Wed, 19 Jan 2022 12:36:54 +0800 Subject: [PATCH 1643/2234] add remote deploy hook for openmediavault 5 based on #3757 --- Dockerfile | 3 +- deploy/openmediavault.sh | 85 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 deploy/openmediavault.sh diff --git a/Dockerfile b/Dockerfile index 0421da34..fa11ea8a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,8 @@ RUN apk --no-cache add -f \ tzdata \ oath-toolkit-oathtool \ tar \ - libidn + libidn \ + jq ENV LE_CONFIG_HOME /acme.sh diff --git a/deploy/openmediavault.sh b/deploy/openmediavault.sh new file mode 100644 index 00000000..26743326 --- /dev/null +++ b/deploy/openmediavault.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env sh + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +openmediavault_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + _getdeployconf DEPLOY_OMV_HOST + + if [ -z "$DEPLOY_OMV_HOST" ]; then + _debug "Using _cdomain as DEPLOY_OMV_HOST, please set if not correct." + DEPLOY_OMV_HOST="$_cdomain" + fi + + _getdeployconf DEPLOY_OMV_USER + + if [ -z "$DEPLOY_OMV_USER" ]; then + DEPLOY_OMV_USER="admin" + fi + + _savedeployconf DEPLOY_OMV_HOST "$DEPLOY_OMV_HOST" + _savedeployconf DEPLOY_OMV_USER "$DEPLOY_OMV_USER" + + _command="omv-rpc -u $DEPLOY_OMV_USER 'CertificateMgmt' 'getList' '{\"start\": 0, \"limit\": -1}' | jq -r '.data[] | select(.name==\"/CN='$_cdomain'\") | .uuid'" + # shellcheck disable=SC2086 + _uuid=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") + _debug _command "$_command" + + if [ -z "$_uuid" ]; then + _info "[OMV deploy-hook] Domain $_cdomain has no certificate in openmediavault, creating it!" + _command="omv-rpc -u $DEPLOY_OMV_USER 'CertificateMgmt' 'create' '{\"cn\": \"test.example.com\", \"size\": 4096, \"days\": 3650, \"c\": \"\", \"st\": \"\", \"l\": \"\", \"o\": \"\", \"ou\": \"\", \"email\": \"\"}' | jq -r '.uuid'" + # shellcheck disable=SC2086 + _uuid=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") + _debug _command "$_command" + + if [ -z "$_uuid" ]; then + _err "[OMB deploy-hook] An error occured while creating the certificate" + return 1 + fi + fi + + _info "[OMV deploy-hook] Domain $_cdomain has uuid: $_uuid" + _fullchain=$(jq <"$_cfullchain" -aRs .) + _key=$(jq <"$_ckey" -aRs .) + + _debug _fullchain "$_fullchain" + _debug _key "$_key" + + _info "[OMV deploy-hook] Updating key and certificate in openmediavault" + _command="omv-rpc -u $DEPLOY_OMV_USER 'CertificateMgmt' 'set' '{\"uuid\":\"$_uuid\", \"certificate\":$_fullchain, \"privatekey\":$_key, \"comment\":\"acme.sh deployed $(date)\"}'" + # shellcheck disable=SC2029 + _result=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") + _debug _result "$_result" + + _debug _command "$_command" + + _info "[OMV deploy-hook] Asking openmediavault to apply changes... (this could take some time, hang in there)" + _command="omv-rpc -u $DEPLOY_OMV_USER 'Config' 'applyChanges' '{\"modules\":[], \"force\": false}'" + # shellcheck disable=SC2029 + _result=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") + + _debug _command "$_command" + _debug _result "$_result" + + _info "[OMV deploy-hook] Asking nginx to reload" + _command="nginx -s reload" + # shellcheck disable=SC2029 + _result=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") + + _debug _command "$_command" + _debug _result "$_result" + + return 0 +} From df671a77f674f9c75cff975b214de95b8cefc8b7 Mon Sep 17 00:00:00 2001 From: Ross Shen Date: Sun, 16 Jan 2022 20:46:09 +0800 Subject: [PATCH 1644/2234] routeros deploy hook: store the env vars within the domainconf related to #2344 and #2413 --- deploy/routeros.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 2f349999..9965d65c 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -66,21 +66,31 @@ routeros_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" + _getdeployconf ROUTER_OS_HOST + if [ -z "$ROUTER_OS_HOST" ]; then _debug "Using _cdomain as ROUTER_OS_HOST, please set if not correct." ROUTER_OS_HOST="$_cdomain" fi + _getdeployconf ROUTER_OS_USERNAME + if [ -z "$ROUTER_OS_USERNAME" ]; then _err "Need to set the env variable ROUTER_OS_USERNAME" return 1 fi + _getdeployconf ROUTER_OS_ADDITIONAL_SERVICES + if [ -z "$ROUTER_OS_ADDITIONAL_SERVICES" ]; then _debug "Not enabling additional services" ROUTER_OS_ADDITIONAL_SERVICES="" fi + _savedeployconf ROUTER_OS_HOST "$ROUTER_OS_HOST" + _savedeployconf ROUTER_OS_USERNAME "$ROUTER_OS_USERNAME" + _savedeployconf ROUTER_OS_ADDITIONAL_SERVICES "$ROUTER_OS_ADDITIONAL_SERVICES" + _info "Trying to push key '$_ckey' to router" scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" _info "Trying to push cert '$_cfullchain' to router" From 6bbf927f57f8a7b1dcdd1f24220c09397368a541 Mon Sep 17 00:00:00 2001 From: Ross Shen Date: Wed, 19 Jan 2022 21:13:02 +0800 Subject: [PATCH 1645/2234] omv deploy hook: separate DEPLOY_OMV_WEBUI_ADMIN and DEPLOY_OMV_SSH_USER --- deploy/openmediavault.sh | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/deploy/openmediavault.sh b/deploy/openmediavault.sh index 26743326..eb04f5bc 100644 --- a/deploy/openmediavault.sh +++ b/deploy/openmediavault.sh @@ -23,25 +23,32 @@ openmediavault_deploy() { DEPLOY_OMV_HOST="$_cdomain" fi - _getdeployconf DEPLOY_OMV_USER + _getdeployconf DEPLOY_OMV_WEBUI_ADMIN - if [ -z "$DEPLOY_OMV_USER" ]; then - DEPLOY_OMV_USER="admin" + if [ -z "$DEPLOY_OMV_WEBUI_ADMIN" ]; then + DEPLOY_OMV_WEBUI_ADMIN="admin" + fi + + _getdeployconf DEPLOY_OMV_SSH_USER + + if [ -z "$DEPLOY_OMV_SSH_USER" ]; then + DEPLOY_OMV_SSH_USER="root" fi _savedeployconf DEPLOY_OMV_HOST "$DEPLOY_OMV_HOST" - _savedeployconf DEPLOY_OMV_USER "$DEPLOY_OMV_USER" + _savedeployconf DEPLOY_OMV_WEBUI_ADMIN "$DEPLOY_OMV_WEBUI_ADMIN" + _savedeployconf DEPLOY_OMV_SSH_USER "$DEPLOY_OMV_SSH_USER" - _command="omv-rpc -u $DEPLOY_OMV_USER 'CertificateMgmt' 'getList' '{\"start\": 0, \"limit\": -1}' | jq -r '.data[] | select(.name==\"/CN='$_cdomain'\") | .uuid'" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'getList' '{\"start\": 0, \"limit\": -1}' | jq -r '.data[] | select(.name==\"/CN='$_cdomain'\") | .uuid'" # shellcheck disable=SC2086 - _uuid=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") + _uuid=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") _debug _command "$_command" if [ -z "$_uuid" ]; then _info "[OMV deploy-hook] Domain $_cdomain has no certificate in openmediavault, creating it!" - _command="omv-rpc -u $DEPLOY_OMV_USER 'CertificateMgmt' 'create' '{\"cn\": \"test.example.com\", \"size\": 4096, \"days\": 3650, \"c\": \"\", \"st\": \"\", \"l\": \"\", \"o\": \"\", \"ou\": \"\", \"email\": \"\"}' | jq -r '.uuid'" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'create' '{\"cn\": \"test.example.com\", \"size\": 4096, \"days\": 3650, \"c\": \"\", \"st\": \"\", \"l\": \"\", \"o\": \"\", \"ou\": \"\", \"email\": \"\"}' | jq -r '.uuid'" # shellcheck disable=SC2086 - _uuid=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") + _uuid=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") _debug _command "$_command" if [ -z "$_uuid" ]; then @@ -58,17 +65,17 @@ openmediavault_deploy() { _debug _key "$_key" _info "[OMV deploy-hook] Updating key and certificate in openmediavault" - _command="omv-rpc -u $DEPLOY_OMV_USER 'CertificateMgmt' 'set' '{\"uuid\":\"$_uuid\", \"certificate\":$_fullchain, \"privatekey\":$_key, \"comment\":\"acme.sh deployed $(date)\"}'" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'set' '{\"uuid\":\"$_uuid\", \"certificate\":$_fullchain, \"privatekey\":$_key, \"comment\":\"acme.sh deployed $(date)\"}'" # shellcheck disable=SC2029 - _result=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") - _debug _result "$_result" + _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") _debug _command "$_command" + _debug _result "$_result" _info "[OMV deploy-hook] Asking openmediavault to apply changes... (this could take some time, hang in there)" - _command="omv-rpc -u $DEPLOY_OMV_USER 'Config' 'applyChanges' '{\"modules\":[], \"force\": false}'" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'Config' 'applyChanges' '{\"modules\":[], \"force\": false}'" # shellcheck disable=SC2029 - _result=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") + _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") _debug _command "$_command" _debug _result "$_result" @@ -76,7 +83,7 @@ openmediavault_deploy() { _info "[OMV deploy-hook] Asking nginx to reload" _command="nginx -s reload" # shellcheck disable=SC2029 - _result=$(ssh "root@$DEPLOY_OMV_HOST" "$_command") + _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") _debug _command "$_command" _debug _result "$_result" From a78a4e67168599a2e898271a57e99aba6cbc5792 Mon Sep 17 00:00:00 2001 From: Ross Shen Date: Wed, 19 Jan 2022 21:42:17 +0800 Subject: [PATCH 1646/2234] omv deploy hook: shellcheck disable=SC2029 --- deploy/openmediavault.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/openmediavault.sh b/deploy/openmediavault.sh index eb04f5bc..b0bb4cb2 100644 --- a/deploy/openmediavault.sh +++ b/deploy/openmediavault.sh @@ -40,14 +40,14 @@ openmediavault_deploy() { _savedeployconf DEPLOY_OMV_SSH_USER "$DEPLOY_OMV_SSH_USER" _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'getList' '{\"start\": 0, \"limit\": -1}' | jq -r '.data[] | select(.name==\"/CN='$_cdomain'\") | .uuid'" - # shellcheck disable=SC2086 + # shellcheck disable=SC2029 _uuid=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") _debug _command "$_command" if [ -z "$_uuid" ]; then _info "[OMV deploy-hook] Domain $_cdomain has no certificate in openmediavault, creating it!" _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'create' '{\"cn\": \"test.example.com\", \"size\": 4096, \"days\": 3650, \"c\": \"\", \"st\": \"\", \"l\": \"\", \"o\": \"\", \"ou\": \"\", \"email\": \"\"}' | jq -r '.uuid'" - # shellcheck disable=SC2086 + # shellcheck disable=SC2029 _uuid=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") _debug _command "$_command" From e1a0f5706d6b7b46062668b54f3823666010c61d Mon Sep 17 00:00:00 2001 From: Vitaly Kireev Date: Tue, 28 Dec 2021 22:29:42 +0300 Subject: [PATCH 1647/2234] DNS REGRU utf-list to idn (punycode) service/get_list returns domains in utf. But if utf, then error Error parsing certificate request: x509: SAN dNSName is malformed early using my patch by IDN_ITEM="$(echo "${ITEM}" | idn)" Now replacing by IDN_ITEM="$(_idn "${ITEM}")" --- dnsapi/dns_regru.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index 29f758ea..2a1ebaa5 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -92,9 +92,10 @@ _get_root() { domains_list=$(echo "${response}" | grep dname | sed -r "s/.*dname=\"([^\"]+)\".*/\\1/g") for ITEM in ${domains_list}; do + IDN_ITEM="$(_idn "${ITEM}")" case "${domain}" in - *${ITEM}*) - _domain=${ITEM} + *${IDN_ITEM}*) + _domain=${IDN_ITEM} _debug _domain "${_domain}" return 0 ;; From faedea212095c398729224d5c9ce72f2a4d55237 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 19 Jan 2022 22:22:53 +0800 Subject: [PATCH 1648/2234] Update dns_ddnss.sh --- dnsapi/dns_ddnss.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index ecc4f174..b9da33ff 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -12,7 +12,7 @@ # -- # -DDNSS_DNS_API="https://ip4.ddnss.de/upd.php" +DDNSS_DNS_API="https://ddnss.de/upd.php" ######## Public functions ##################### @@ -77,7 +77,7 @@ dns_ddnss_rm() { # Now remove the TXT record from DDNS DNS _info "Trying to remove TXT record" - if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=1&txt=."; then + if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=2"; then if [ "$response" = "Updated 1 hostname." ]; then _info "TXT record has been successfully removed from your DDNSS domain." return 0 From 9088c8741a865301af48be2a87deab7ebe288759 Mon Sep 17 00:00:00 2001 From: Yuan Ming Date: Thu, 20 Jan 2022 14:01:33 +0800 Subject: [PATCH 1649/2234] Fix dns_huaweicloud subshell return Replace pipe read with line count loop, fix useless return in subshell. --- dnsapi/dns_huaweicloud.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index cc21396a..ac3ede65 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -136,13 +136,16 @@ _get_zoneid() { _debug2 "Return Zone ID(s):" "${zoneidlist}" _debug2 "Return Zone Name(s):" "${zonenamelist}" zoneidnum=0 - echo "${zonenamelist}" | while read -r zonename; do + zoneidcount=$(echo "${zoneidlist}" | grep -c '^') + _debug "Retund Zone ID(s) Count:" "${zoneidcount}" + while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do zoneidnum=$(_math "$zoneidnum" + 1) + _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p") + zonename=$(echo "${zonenamelist}" | sed -n "${zoneidnum}p") _debug "Check Zone Name" "${zonename}" if [ "${zonename}" = "${h}." ]; then _debug "Get Zone ID Success." - _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p") - _debug2 "ZoneID:" "${_zoneid}" + _debug "ZoneID:" "${_zoneid}" printf "%s" "${_zoneid}" return 0 fi From 0292e20c862c49d8729a832961d72dcf5a38101b Mon Sep 17 00:00:00 2001 From: Ross Shen Date: Thu, 20 Jan 2022 17:27:11 +0800 Subject: [PATCH 1650/2234] omv deploy hook: support both local and remote deployment --- deploy/openmediavault.sh | 162 ++++++++++++++++++++++++++------------- 1 file changed, 109 insertions(+), 53 deletions(-) diff --git a/deploy/openmediavault.sh b/deploy/openmediavault.sh index b0bb4cb2..859eabe7 100644 --- a/deploy/openmediavault.sh +++ b/deploy/openmediavault.sh @@ -16,77 +16,133 @@ openmediavault_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _getdeployconf DEPLOY_OMV_HOST - - if [ -z "$DEPLOY_OMV_HOST" ]; then - _debug "Using _cdomain as DEPLOY_OMV_HOST, please set if not correct." - DEPLOY_OMV_HOST="$_cdomain" - fi - _getdeployconf DEPLOY_OMV_WEBUI_ADMIN if [ -z "$DEPLOY_OMV_WEBUI_ADMIN" ]; then DEPLOY_OMV_WEBUI_ADMIN="admin" fi + _savedeployconf DEPLOY_OMV_WEBUI_ADMIN "$DEPLOY_OMV_WEBUI_ADMIN" + + _getdeployconf DEPLOY_OMV_HOST _getdeployconf DEPLOY_OMV_SSH_USER - if [ -z "$DEPLOY_OMV_SSH_USER" ]; then - DEPLOY_OMV_SSH_USER="root" + if [ -n "$DEPLOY_OMV_HOST" ] && [ -n "$DEPLOY_OMV_SSH_USER" ]; then + _info "[OMV deploy-hook] Deploy certificate remotely through ssh." + _savedeployconf DEPLOY_OMV_HOST "$DEPLOY_OMV_HOST" + _savedeployconf DEPLOY_OMV_SSH_USER "$DEPLOY_OMV_SSH_USER" + else + _info "[OMV deploy-hook] Deploy certificate locally." fi - _savedeployconf DEPLOY_OMV_HOST "$DEPLOY_OMV_HOST" - _savedeployconf DEPLOY_OMV_WEBUI_ADMIN "$DEPLOY_OMV_WEBUI_ADMIN" - _savedeployconf DEPLOY_OMV_SSH_USER "$DEPLOY_OMV_SSH_USER" + if [ -n "$DEPLOY_OMV_HOST" ] && [ -n "$DEPLOY_OMV_SSH_USER" ]; then - _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'getList' '{\"start\": 0, \"limit\": -1}' | jq -r '.data[] | select(.name==\"/CN='$_cdomain'\") | .uuid'" - # shellcheck disable=SC2029 - _uuid=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") - _debug _command "$_command" - - if [ -z "$_uuid" ]; then - _info "[OMV deploy-hook] Domain $_cdomain has no certificate in openmediavault, creating it!" - _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'create' '{\"cn\": \"test.example.com\", \"size\": 4096, \"days\": 3650, \"c\": \"\", \"st\": \"\", \"l\": \"\", \"o\": \"\", \"ou\": \"\", \"email\": \"\"}' | jq -r '.uuid'" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'getList' '{\"start\": 0, \"limit\": -1}' | jq -r '.data[] | select(.name==\"/CN='$_cdomain'\") | .uuid'" # shellcheck disable=SC2029 _uuid=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") _debug _command "$_command" if [ -z "$_uuid" ]; then - _err "[OMB deploy-hook] An error occured while creating the certificate" - return 1 + _info "[OMV deploy-hook] Domain $_cdomain has no certificate in openmediavault, creating it!" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'create' '{\"cn\": \"test.example.com\", \"size\": 4096, \"days\": 3650, \"c\": \"\", \"st\": \"\", \"l\": \"\", \"o\": \"\", \"ou\": \"\", \"email\": \"\"}' | jq -r '.uuid'" + # shellcheck disable=SC2029 + _uuid=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") + _debug _command "$_command" + + if [ -z "$_uuid" ]; then + _err "[OMV deploy-hook] An error occured while creating the certificate" + return 1 + fi fi + + _info "[OMV deploy-hook] Domain $_cdomain has uuid: $_uuid" + _fullchain=$(jq <"$_cfullchain" -aRs .) + _key=$(jq <"$_ckey" -aRs .) + + _debug _fullchain "$_fullchain" + _debug _key "$_key" + + _info "[OMV deploy-hook] Updating key and certificate in openmediavault" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'set' '{\"uuid\":\"$_uuid\", \"certificate\":$_fullchain, \"privatekey\":$_key, \"comment\":\"acme.sh deployed $(date)\"}'" + # shellcheck disable=SC2029 + _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") + + _debug _command "$_command" + _debug _result "$_result" + + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'WebGui' 'setSettings' \$(omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'WebGui' 'getSettings' | jq -c '.sslcertificateref=\"$_uuid\"')" + # shellcheck disable=SC2029 + _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") + + _debug _command "$_command" + _debug _result "$_result" + + _info "[OMV deploy-hook] Asking openmediavault to apply changes... (this could take some time, hang in there)" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'Config' 'applyChanges' '{\"modules\":[], \"force\": false}'" + # shellcheck disable=SC2029 + _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") + + _debug _command "$_command" + _debug _result "$_result" + + _info "[OMV deploy-hook] Asking nginx to reload" + _command="nginx -s reload" + # shellcheck disable=SC2029 + _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") + + _debug _command "$_command" + _debug _result "$_result" + + else + + # shellcheck disable=SC2086 + _uuid=$(omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'getList' '{"start": 0, "limit": -1}' | jq -r '.data[] | select(.name=="/CN='$_cdomain'") | .uuid') + if [ -z "$_uuid" ]; then + _info "[OMV deploy-hook] Domain $_cdomain has no certificate in openmediavault, creating it!" + # shellcheck disable=SC2086 + _uuid=$(omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'create' '{"cn": "test.example.com", "size": 4096, "days": 3650, "c": "", "st": "", "l": "", "o": "", "ou": "", "email": ""}' | jq -r '.uuid') + + if [ -z "$_uuid" ]; then + _err "[OMB deploy-hook] An error occured while creating the certificate" + return 1 + fi + fi + + _info "[OMV deploy-hook] Domain $_cdomain has uuid: $_uuid" + _fullchain=$(jq <"$_cfullchain" -aRs .) + _key=$(jq <"$_ckey" -aRs .) + + _debug _fullchain "$_fullchain" + _debug _key "$_key" + + _info "[OMV deploy-hook] Updating key and certificate in openmediavault" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'set' '{\"uuid\":\"$_uuid\", \"certificate\":$_fullchain, \"privatekey\":$_key, \"comment\":\"acme.sh deployed $(date)\"}'" + _result=$(eval "$_command") + + _debug _command "$_command" + _debug _result "$_result" + + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'WebGui' 'setSettings' \$(omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'WebGui' 'getSettings' | jq -c '.sslcertificateref=\"$_uuid\"')" + _result=$(eval "$_command") + + _debug _command "$_command" + _debug _result "$_result" + + _info "[OMV deploy-hook] Asking openmediavault to apply changes... (this could take some time, hang in there)" + _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'Config' 'applyChanges' '{\"modules\":[], \"force\": false}'" + _result=$(eval "$_command") + + _debug _command "$_command" + _debug _result "$_result" + + _info "[OMV deploy-hook] Asking nginx to reload" + _command="nginx -s reload" + _result=$(eval "$_command") + + _debug _command "$_command" + _debug _result "$_result" + fi - _info "[OMV deploy-hook] Domain $_cdomain has uuid: $_uuid" - _fullchain=$(jq <"$_cfullchain" -aRs .) - _key=$(jq <"$_ckey" -aRs .) - - _debug _fullchain "$_fullchain" - _debug _key "$_key" - - _info "[OMV deploy-hook] Updating key and certificate in openmediavault" - _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'set' '{\"uuid\":\"$_uuid\", \"certificate\":$_fullchain, \"privatekey\":$_key, \"comment\":\"acme.sh deployed $(date)\"}'" - # shellcheck disable=SC2029 - _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") - - _debug _command "$_command" - _debug _result "$_result" - - _info "[OMV deploy-hook] Asking openmediavault to apply changes... (this could take some time, hang in there)" - _command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'Config' 'applyChanges' '{\"modules\":[], \"force\": false}'" - # shellcheck disable=SC2029 - _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") - - _debug _command "$_command" - _debug _result "$_result" - - _info "[OMV deploy-hook] Asking nginx to reload" - _command="nginx -s reload" - # shellcheck disable=SC2029 - _result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") - - _debug _command "$_command" - _debug _result "$_result" - return 0 } From 67c990e8cfd6503bc8bdeb19a71b53d34b32090e Mon Sep 17 00:00:00 2001 From: Ross Shen Date: Thu, 20 Jan 2022 17:46:47 +0800 Subject: [PATCH 1651/2234] omv deploy hook: add usage comments --- deploy/openmediavault.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/deploy/openmediavault.sh b/deploy/openmediavault.sh index 859eabe7..cfc2d332 100644 --- a/deploy/openmediavault.sh +++ b/deploy/openmediavault.sh @@ -1,5 +1,13 @@ #!/usr/bin/env sh +# This deploy hook is tested on OpenMediaVault 5.x. It supports both local and remote deployment. +# The way it works is that if a cert with the matching domain name is not found, it will firstly create a dummy cert to get its uuid, and then replace it with your cert. +# +# DEPLOY_OMV_WEBUI_ADMIN - This is OMV web gui admin account. Default value is admin. It's required as the user parameter (-u) for the omv-rpc command. +# DEPLOY_OMV_HOST and DEPLOY_OMV_SSH_USER are optional. They are used for remote deployment through ssh (support public key authentication only). Per design, OMV web gui admin doesn't have ssh permission, so another account is needed for ssh. +# +# returns 0 means success, otherwise error. + ######## Public functions ##################### #domain keyfile certfile cafile fullchain From 7250a300df82ef79b9fce9d1f8287aef6686fe2e Mon Sep 17 00:00:00 2001 From: michal Date: Tue, 14 Dec 2021 20:27:40 +0100 Subject: [PATCH 1652/2234] add managed identity support for azure dns --- dnsapi/dns_azure.sh | 192 +++++++++++++++++++++++++------------------- 1 file changed, 111 insertions(+), 81 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index ce8a3fa7..1c33c13a 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -9,57 +9,72 @@ WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Azure-DNS" # # Ref: https://docs.microsoft.com/en-us/rest/api/dns/recordsets/createorupdate # + dns_azure_add() { fulldomain=$1 txtvalue=$2 AZUREDNS_SUBSCRIPTIONID="${AZUREDNS_SUBSCRIPTIONID:-$(_readaccountconf_mutable AZUREDNS_SUBSCRIPTIONID)}" - AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" - AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" - AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" - if [ -z "$AZUREDNS_SUBSCRIPTIONID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure Subscription ID " + _err "You didn't specify the Azure Subscription ID" return 1 fi - - if [ -z "$AZUREDNS_TENANTID" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure Tenant ID " - return 1 - fi - - if [ -z "$AZUREDNS_APPID" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure App ID" - return 1 - fi - - if [ -z "$AZUREDNS_CLIENTSECRET" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure Client Secret" - return 1 - fi - #save account details to account conf file. + #save subscription id to account conf file. _saveaccountconf_mutable AZUREDNS_SUBSCRIPTIONID "$AZUREDNS_SUBSCRIPTIONID" - _saveaccountconf_mutable AZUREDNS_TENANTID "$AZUREDNS_TENANTID" - _saveaccountconf_mutable AZUREDNS_APPID "$AZUREDNS_APPID" - _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" - accesstoken=$(_azure_getaccess_token "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") + AZUREDNS_MANAGEDIDENTITY="${AZUREDNS_MANAGEDIDENTITY:-$(_readaccountconf_mutable AZUREDNS_MANAGEDIDENTITY)}" + if [ "$AZUREDNS_MANAGEDIDENTITY" = true ]; then + _info "Using Azure managed identity" + #save managed identity as preferred authentication method, clear service principal credentials from conf file. + _saveaccountconf_mutable AZUREDNS_MANAGEDIDENTITY "$AZUREDNS_MANAGEDIDENTITY" + _saveaccountconf_mutable AZUREDNS_TENANTID "" + _saveaccountconf_mutable AZUREDNS_APPID "" + _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "" + else + _info "You didn't ask to use Azure managed identity, checking service principal credentials" + AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" + AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" + AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" + + if [ -z "$AZUREDNS_TENANTID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure Tenant ID " + return 1 + fi + + if [ -z "$AZUREDNS_APPID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure App ID" + return 1 + fi + + if [ -z "$AZUREDNS_CLIENTSECRET" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure Client Secret" + return 1 + fi + + #save account details to account conf file, don't opt in for azure manages identity check. + _saveaccountconf_mutable AZUREDNS_MANAGEDIDENTITY "false" + _saveaccountconf_mutable AZUREDNS_TENANTID "$AZUREDNS_TENANTID" + _saveaccountconf_mutable AZUREDNS_APPID "$AZUREDNS_APPID" + _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" + fi + + accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then _err "invalid domain" @@ -116,10 +131,6 @@ dns_azure_rm() { txtvalue=$2 AZUREDNS_SUBSCRIPTIONID="${AZUREDNS_SUBSCRIPTIONID:-$(_readaccountconf_mutable AZUREDNS_SUBSCRIPTIONID)}" - AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" - AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" - AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" - if [ -z "$AZUREDNS_SUBSCRIPTIONID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" @@ -129,34 +140,44 @@ dns_azure_rm() { return 1 fi - if [ -z "$AZUREDNS_TENANTID" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure Tenant ID " - return 1 + AZUREDNS_MANAGEDIDENTITY="${AZUREDNS_MANAGEDIDENTITY:-$(_readaccountconf_mutable AZUREDNS_MANAGEDIDENTITY)}" + if [ "$AZUREDNS_MANAGEDIDENTITY" = true ]; then + _info "Using Azure managed identity" + else + _info "You didn't ask to use Azure managed identity, checking service principal credentials" + AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" + AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" + AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" + + if [ -z "$AZUREDNS_TENANTID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure Tenant ID " + return 1 + fi + + if [ -z "$AZUREDNS_APPID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure App ID" + return 1 + fi + + if [ -z "$AZUREDNS_CLIENTSECRET" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure Client Secret" + return 1 + fi fi - if [ -z "$AZUREDNS_APPID" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure App ID" - return 1 - fi - - if [ -z "$AZUREDNS_CLIENTSECRET" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure Client Secret" - return 1 - fi - - accesstoken=$(_azure_getaccess_token "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") + accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then _err "invalid domain" @@ -258,9 +279,10 @@ _azure_rest() { ## Ref: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service#request-an-access-token _azure_getaccess_token() { - tenantID=$1 - clientID=$2 - clientSecret=$3 + managedIdentity=$1 + tenantID=$2 + clientID=$3 + clientSecret=$4 accesstoken="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" expires_on="${AZUREDNS_TOKENVALIDTO:-$(_readaccountconf_mutable AZUREDNS_TOKENVALIDTO)}" @@ -278,17 +300,25 @@ _azure_getaccess_token() { fi _debug "getting new bearer token" - export _H1="accept: application/json" - export _H2="Content-Type: application/x-www-form-urlencoded" - - body="resource=$(printf "%s" 'https://management.core.windows.net/' | _url_encode)&client_id=$(printf "%s" "$clientID" | _url_encode)&client_secret=$(printf "%s" "$clientSecret" | _url_encode)&grant_type=client_credentials" - _secure_debug2 "data $body" - response="$(_post "$body" "https://login.microsoftonline.com/$tenantID/oauth2/token" "" "POST")" - _ret="$?" - _secure_debug2 "response $response" - response="$(echo "$response" | _normalizeJson)" - accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") - expires_on=$(echo "$response" | _egrep_o "\"expires_on\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if [ "$managedIdentity" = true ]; then + # https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http + export _H1="Metadata: true" + response="$(_get http://169.254.169.254/metadata/identity/oauth2/token\?api-version=2018-02-01\&resource=https://management.azure.com/)" + response="$(echo "$response" | _normalizeJson)" + accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + expires_on=$(echo "$response" | _egrep_o "\"expires_on\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + else + export _H1="accept: application/json" + export _H2="Content-Type: application/x-www-form-urlencoded" + body="resource=$(printf "%s" 'https://management.core.windows.net/' | _url_encode)&client_id=$(printf "%s" "$clientID" | _url_encode)&client_secret=$(printf "%s" "$clientSecret" | _url_encode)&grant_type=client_credentials" + _secure_debug2 "data $body" + response="$(_post "$body" "https://login.microsoftonline.com/$tenantID/oauth2/token" "" "POST")" + _ret="$?" + _secure_debug2 "response $response" + response="$(echo "$response" | _normalizeJson)" + accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + expires_on=$(echo "$response" | _egrep_o "\"expires_on\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + fi if [ -z "$accesstoken" ]; then _err "no acccess token received. Check your Azure settings see $WIKI" From 190ec0c14c4f7816a3227fa07ca99007d24c34fb Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 24 Jan 2022 16:47:47 +0100 Subject: [PATCH 1653/2234] Adapt dns_world4you to new world4you website behaviour --- dnsapi/dns_world4you.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 231c34b3..fd124754 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -24,7 +24,7 @@ dns_world4you_add() { fi export _H1="Cookie: W4YSESSID=$sessid" - form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") + form=$(_get "$WORLD4YOU_API/") _get_paketnr "$fqdn" "$form" paketnr="$PAKETNR" if [ -z "$paketnr" ]; then @@ -87,7 +87,7 @@ dns_world4you_rm() { fi export _H1="Cookie: W4YSESSID=$sessid" - form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht") + form=$(_get "$WORLD4YOU_API/") _get_paketnr "$fqdn" "$form" paketnr="$PAKETNR" if [ -z "$paketnr" ]; then @@ -184,7 +184,7 @@ _get_paketnr() { fqdn="$1" form="$2" - domains=$(echo "$form" | grep '^ *[A-Za-z0-9_\.-]*\.[A-Za-z0-9_-]*$' | sed 's/^ *\(.*\)$/\1/') + domains=$(echo "$form" | grep 'header-paket-domain' | sed 's/<[^>]*>//g' | sed 's/^.*>\([^>]*\)$/\1/') domain='' for domain in $domains; do if _contains "$fqdn" "$domain\$"; then From 90b65c6618dbb00f1718667979f8aa375df67fd0 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Jan 2022 18:00:44 +0800 Subject: [PATCH 1654/2234] fix https://github.com/acmesh-official/acme.sh/issues/3898 https://github.com/acmesh-official/acme.sh/issues/3898 --- acme.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 78684267..11286130 100755 --- a/acme.sh +++ b/acme.sh @@ -1253,7 +1253,8 @@ _createcsr() { domainlist="$(_idn "$domainlist")" _debug2 domainlist "$domainlist" alt="$(_getIdType "$domain" | _upper_case):$(_idn "$domain")" - for dl in $(echo "$domainlist" | tr "," ' '); do + for dl in $(echo "'$domainlist'" | sed "s/,/' '/g"); do + dl=$(echo "$dl" | tr -d "'") alt="$alt,$(_getIdType "$dl" | _upper_case):$dl" done #multi From a7f2d89e3fcb3afeb219a5ffd29cc24c3bd1ec75 Mon Sep 17 00:00:00 2001 From: Andreas Scherer Date: Tue, 1 Feb 2022 14:46:20 +0100 Subject: [PATCH 1655/2234] Added united-domains Reselling DNS API --- dnsapi/dns_udr.sh | 160 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 dnsapi/dns_udr.sh diff --git a/dnsapi/dns_udr.sh b/dnsapi/dns_udr.sh new file mode 100644 index 00000000..5215e193 --- /dev/null +++ b/dnsapi/dns_udr.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env sh + +# united-domains Reselling (https://www.ud-reselling.com/) DNS API +# Author: Andreas Scherer (https://github.com/andischerer) +# Created: 2021-02-01 +# +# Set the environment variables as below: +# +# export UDR_USER="your_username_goes_here" +# export UDR_PASS="some_password_goes_here" +# + +UDR_API="https://api.domainreselling.de/api/call.cgi" +UDR_TTL="300" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "some_long_string_of_characters_go_here_from_lets_encrypt" +dns_udr_add() { + fulldomain=$1 + txtvalue=$2 + export txtvalue + UDR_USER="${UDR_USER:-$(_readaccountconf_mutable UDR_USER)}" + UDR_PASS="${UDR_PASS:-$(_readaccountconf_mutable UDR_PASS)}" + if [ -z "$UDR_USER" ] || [ -z "$UDR_PASS" ]; then + UDR_USER="" + UDR_PASS="" + _err "You didn't specify an UD-Reselling username and password yet" + return 1 + fi + # save the username and password to the account conf file. + _saveaccountconf_mutable UDR_USER "$UDR_USER" + _saveaccountconf_mutable UDR_PASS "$UDR_PASS" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _dnszone "${_dnszone}" + + _debug "Getting txt records" + if ! _udr_rest "QueryDNSZoneRRList" "dnszone=${_dnszone}"; then + return 1 + fi + + rr="${fulldomain}. ${UDR_TTL} IN TXT ${txtvalue}" + _debug resource_record "${rr}" + if _contains "$response" "$rr" >/dev/null; then + _err "Error, it would appear that this record already exists. Please review existing TXT records for this domain." + return 1 + fi + + _info "Adding record" + if ! _udr_rest "UpdateDNSZone" "dnszone=${_dnszone}&addrr0=${rr}"; then + _err "Adding the record did not succeed, please verify/check." + return 1 + fi + + _info "Added, OK" + return 0 +} + +dns_udr_rm() { + fulldomain=$1 + txtvalue=$2 + export txtvalue + UDR_USER="${UDR_USER:-$(_readaccountconf_mutable UDR_USER)}" + UDR_PASS="${UDR_PASS:-$(_readaccountconf_mutable UDR_PASS)}" + if [ -z "$UDR_USER" ] || [ -z "$UDR_PASS" ]; then + UDR_USER="" + UDR_PASS="" + _err "You didn't specify an UD-Reselling username and password yet" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _dnszone "${_dnszone}" + + _debug "Getting txt records" + if ! _udr_rest "QueryDNSZoneRRList" "dnszone=${_dnszone}"; then + return 1 + fi + + rr="${fulldomain}. ${UDR_TTL} IN TXT ${txtvalue}" + _debug resource_record "${rr}" + if _contains "$response" "$rr" >/dev/null; then + if ! _udr_rest "UpdateDNSZone" "dnszone=${_dnszone}&delrr0=${rr}"; then + _err "Deleting the record did not succeed, please verify/check." + return 1 + fi + _info "Removed, OK" + return 0 + else + _info "Text record is not present, will not delete anything." + return 0 + fi +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + + if ! _udr_rest "QueryDNSZoneList" ""; 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}." >/dev/null; then + _dnszone=$(echo "$response" | _egrep_o "${h}") + if [ "$_dnszone" ]; then + return 0 + fi + return 1 + fi + i=$(_math "$i" + 1) + done + return 1 +} + +_udr_rest() { + if [ -n "$2" ]; then + data="command=$1&$2" + else + data="command=$1" + fi + + _debug data "${data}" + response="$(_post "${data}" "${UDR_API}?s_login=${UDR_USER}&s_pw=${UDR_PASS}" "" "POST")" + + _code=$(echo "$response" | _egrep_o "code = ([0-9]+)" | _head_n 1 | cut -d = -f 2 | xargs) + _description=$(echo "$response" | _egrep_o "description = .*" | _head_n 1 | cut -d = -f 2 | xargs) + + _debug response_code "$_code" + _debug response_description "$_description" + + if [ ! "$_code" = "200" ]; then + _err "DNS-API-Error: $_description" + return 1 + fi + + return 0 +} From 36752cb6a88d5beb347a7951d14ee64ec5f5d19a Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 4 Feb 2022 13:49:58 +0800 Subject: [PATCH 1656/2234] Update acme.sh fix zerossl endpoint --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 11286130..18456968 100755 --- a/acme.sh +++ b/acme.sh @@ -29,7 +29,7 @@ CA_BUYPASS="https://api.buypass.com/acme/directory" CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" -_ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email" +_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" From 0f762d98a43546c82aa8eb14fdcffbea1e5cd358 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 4 Feb 2022 13:52:23 +0800 Subject: [PATCH 1657/2234] Update Linux.yml use centos:7 --- .github/workflows/Linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 7b24eac9..63e3136c 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -20,7 +20,7 @@ jobs: Linux: strategy: matrix: - os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"] + os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:7", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"] runs-on: ubuntu-latest env: TEST_LOCAL: 1 From 9ec4b59afb13dd081b114d43eb44ccf6a3eabe3f Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 5 Feb 2022 21:28:07 +0800 Subject: [PATCH 1658/2234] start v3.0.3 start v3.0.3 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 18456968..f355372d 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.2 +VER=3.0.3 PROJECT_NAME="acme.sh" From 38a19fa574a5df27e2537dd3d4bcde49c92b3a7b Mon Sep 17 00:00:00 2001 From: peterlh Date: Sat, 5 Feb 2022 20:54:30 +0100 Subject: [PATCH 1659/2234] created dns_curanet.sh --- dnsapi/dns_curanet.sh | 142 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 dnsapi/dns_curanet.sh diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh new file mode 100644 index 00000000..0cdf9592 --- /dev/null +++ b/dnsapi/dns_curanet.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env sh + +#Script to use with curanet.dk, scannet.dk, wannafind.dk, dandomain.dk DNS management. +# +#Author: Peter L. Hansen + +CURANET_REST_URL="https://api.curanet.dk/dns/v1/Domains" +CURANET_AUTH_URL="https://apiauth.dk.team.blue/auth/realms/Curanet/protocol/openid-connect/token" +CURANET_ACCESS_TOKEN="" + +######## Public functions ##################### + +#Usage: dns_curanet_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_curanet_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using curanet" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + CURANET_AUTHCLIENTID="${CURANET_AUTHCLIENTID:-$(_readaccountconf_mutable CURANET_AUTHCLIENTID)}" + CURANET_AUTHSECRET="${CURANET_AUTHSECRET:-$(_readaccountconf_mutable CURANET_AUTHSECRET)}" + if [ -z "$CURANET_AUTHCLIENTID" ] || [ -z "$CURANET_AUTHSECRET" ]; then + CURANET_AUTHCLIENTID="" + CURANET_AUTHSECRET="" + _err "You don't specify curanet api client and secret." + _err "Please create your auth info and try again." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable CURANET_AUTHCLIENTID "$CURANET_AUTHCLIENTID" + _saveaccountconf_mutable CURANET_AUTHSECRET "$CURANET_AUTHSECRET" + + gettoken + + _get_root "$fulldomain" + + export _H1="Content-Type: application/json-patch+json" + export _H2="Accept: application/json" + export _H3="Authorization: Bearer $CURANET_ACCESS_TOKEN" + data="{\"name\": \"$fulldomain\",\"type\": \"TXT\",\"ttl\": 60,\"priority\": 0,\"data\": \"$txtvalue\"}" + response="$(_post "$data" "$CURANET_REST_URL/${_domain}/Records" "" "")" + + if _contains "$response" "$txtvalue"; then + _debug "TXT record added OK" + else + _err "Unable to add TXT record" + return 1 + fi + + return 0 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_curanet_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using curanet" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + CURANET_AUTHCLIENTID="${CURANET_AUTHCLIENTID:-$(_readaccountconf_mutable CURANET_AUTHCLIENTID)}" + CURANET_AUTHSECRET="${CURANET_AUTHSECRET:-$(_readaccountconf_mutable CURANET_AUTHSECRET)}" + + gettoken + + _get_root "$fulldomain" + + _debug "Getting current record list to identify TXT to delete" + + export _H1="Content-Type: application/json" + export _H2="Accept: application/json" + export _H3="Authorization: Bearer $CURANET_ACCESS_TOKEN" + + response="$(_get "$CURANET_REST_URL/${_domain}/Records" "" "")" + + if ! _contains "$response" "$txtvalue"; then + _err "Unable to delete record (does not contain $txtvalue )" + return 1 + fi + + recordid=$(echo "$response" | _egrep_o "{\"id\":[0-9]+,\"name\":\"$fulldomain\"" | _egrep_o "id\":[0-9]+" | cut -c 5-) + + re='^[0-9]+$' + if ! [[ $recordid =~ $re ]] ; then + err "Unable to delete record (did not find recordID to delete)" + return 1 + fi + + _debug "Deleting recordID $recordid" + + response="$(_post "" "$CURANET_REST_URL/${_domain}/Records/$recordid" "" "DELETE")" + + return 0; + +} + +#################### Private functions below ################################## + +gettoken() { + CURANET_ACCESS_TOKEN=$(curl -s $CURANET_AUTH_URL -d "grant_type=client_credentials&client_id=$CURANET_AUTHCLIENTID&client_secret=$CURANET_AUTHSECRET&scope=dns" | jq -r '.access_token') + +} + + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=sdjkglgdfewsdfg +_get_root() { + domain=$1 + i=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + export _H1="Content-Type: application/json" + export _H2="Accept: application/json" + export _H3="Authorization: Bearer $CURANET_ACCESS_TOKEN" + response="$(_get "$CURANET_REST_URL/$h/Records" "" "")" + + if [ ! "$(echo "$response" | _egrep_o "Entity not found")" ]; 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 +} + From a2bb6a4f1f2b0824a7a74725c977a17ce0e77b31 Mon Sep 17 00:00:00 2001 From: peterlh Date: Sat, 5 Feb 2022 21:07:04 +0100 Subject: [PATCH 1660/2234] changed gettoken to use _post changed gettoken to use _post instead of curl+jq --- dnsapi/dns_curanet.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 0cdf9592..3d2fdb14 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -100,7 +100,16 @@ dns_curanet_rm() { #################### Private functions below ################################## gettoken() { - CURANET_ACCESS_TOKEN=$(curl -s $CURANET_AUTH_URL -d "grant_type=client_credentials&client_id=$CURANET_AUTHCLIENTID&client_secret=$CURANET_AUTHSECRET&scope=dns" | jq -r '.access_token') + + response="$(_post "grant_type=client_credentials&client_id=$CURANET_AUTHCLIENTID&client_secret=$CURANET_AUTHSECRET&scope=dns" "$CURANET_AUTH_URL" "" "")" + + if ! _contains "$response" "access_token"; then + _err "Unable get access token" + return 1 + fi + + CURANET_ACCESS_TOKEN=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]+\"" | cut -c 17-) + CURANET_ACCESS_TOKEN=${CURANET_ACCESS_TOKEN::-1} } From 10a15e1188b51faa004823079070b3d84b5e3329 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 5 Feb 2022 21:12:36 +0100 Subject: [PATCH 1661/2234] nothing --- dnsapi/dns_curanet.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 3d2fdb14..e8804767 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -1,7 +1,6 @@ #!/usr/bin/env sh #Script to use with curanet.dk, scannet.dk, wannafind.dk, dandomain.dk DNS management. -# #Author: Peter L. Hansen CURANET_REST_URL="https://api.curanet.dk/dns/v1/Domains" From dc61c9e277f4d34d34e141e4fe56afdb0e44fab6 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 5 Feb 2022 22:21:18 +0100 Subject: [PATCH 1662/2234] description --- dnsapi/dns_curanet.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index e8804767..ab5462b1 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -1,6 +1,7 @@ #!/usr/bin/env sh #Script to use with curanet.dk, scannet.dk, wannafind.dk, dandomain.dk DNS management. +#Requires api credentials with scope: dns #Author: Peter L. Hansen CURANET_REST_URL="https://api.curanet.dk/dns/v1/Domains" From af193291faf5b9765feedaae12f237b0f16fa518 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 6 Feb 2022 16:16:59 +0800 Subject: [PATCH 1663/2234] Update acme.sh fix https://github.com/acmesh-official/acme.sh/issues/3127#issuecomment-1030742187 --- acme.sh | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index f355372d..55fa4467 100755 --- a/acme.sh +++ b/acme.sh @@ -1141,13 +1141,19 @@ _createkey() { _debug "Use length $length" - if ! touch "$f" >/dev/null 2>&1; then - _f_path="$(dirname "$f")" - _debug _f_path "$_f_path" - if ! mkdir -p "$_f_path"; then - _err "Can not create path: $_f_path" + if ! [ -e "$f" ]; then + if ! touch "$f" >/dev/null 2>&1; then + _f_path="$(dirname "$f")" + _debug _f_path "$_f_path" + if ! mkdir -p "$_f_path"; then + _err "Can not create path: $_f_path" + return 1 + fi + fi + if ! touch "$f" >/dev/null 2>&1; then return 1 fi + chmod 600 "$f" fi if _isEccKey "$length"; then @@ -1495,7 +1501,6 @@ _create_account_key() { else #generate account key if _createkey "$length" "$ACCOUNT_KEY_PATH"; then - chmod 600 "$ACCOUNT_KEY_PATH" _info "Create account key ok." return 0 else @@ -5611,8 +5616,9 @@ _installcert() { if [ -f "$_real_key" ]; then cat "$CERT_KEY_PATH" >"$_real_key" || return 1 else - cat "$CERT_KEY_PATH" >"$_real_key" || return 1 + touch "$_real_key" || return 1 chmod 600 "$_real_key" + cat "$CERT_KEY_PATH" >"$_real_key" || return 1 fi fi From 5ae3a020bd056bd5e595c0c0bd3cef57754c974a Mon Sep 17 00:00:00 2001 From: John Elliott Date: Fri, 4 Feb 2022 18:25:02 -0800 Subject: [PATCH 1664/2234] Add err log for missing oathtool in Synology Alerts the user that the oathtool is missing and the TOTP can't be generated. --- deploy/synology_dsm.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 66e28f93..3ef243ca 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -94,6 +94,11 @@ synology_dsm_deploy() { otp_code="" if [ -n "$SYNO_TOTP_SECRET" ]; then + if ! command -v oathtool &> /dev/null + then + _err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET" + exit 1 + fi otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" fi From 5ce8050e46202c1f2466a1714794a664358a983e Mon Sep 17 00:00:00 2001 From: John Elliott Date: Mon, 7 Feb 2022 11:55:55 -0800 Subject: [PATCH 1665/2234] Update missing oathtool check --- deploy/synology_dsm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 3ef243ca..29e7de65 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -94,12 +94,12 @@ synology_dsm_deploy() { otp_code="" if [ -n "$SYNO_TOTP_SECRET" ]; then - if ! command -v oathtool &> /dev/null - then + if _exists oathtool; then + otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" + else _err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET" exit 1 fi - otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" fi if [ -n "$SYNO_DID" ]; then From 3a99a77104861c7cb24c401f99e7f3ed23033856 Mon Sep 17 00:00:00 2001 From: John Elliott Date: Mon, 7 Feb 2022 21:55:12 -0800 Subject: [PATCH 1666/2234] Update return statement --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 29e7de65..f30f82c0 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -98,7 +98,7 @@ synology_dsm_deploy() { otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" else _err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET" - exit 1 + return 1 fi fi From f3a0a25380dcd2e741f8715cd499f152556bdddf Mon Sep 17 00:00:00 2001 From: Andreas Scherer Date: Tue, 8 Feb 2022 08:05:48 +0100 Subject: [PATCH 1667/2234] FIX dns_udr api: ttl, xargs, cleanup --- dnsapi/dns_udr.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_udr.sh b/dnsapi/dns_udr.sh index 5215e193..305fc2b3 100644 --- a/dnsapi/dns_udr.sh +++ b/dnsapi/dns_udr.sh @@ -11,7 +11,7 @@ # UDR_API="https://api.domainreselling.de/api/call.cgi" -UDR_TTL="300" +UDR_TTL="30" ######## Public functions ##################### @@ -19,7 +19,7 @@ UDR_TTL="300" dns_udr_add() { fulldomain=$1 txtvalue=$2 - export txtvalue + UDR_USER="${UDR_USER:-$(_readaccountconf_mutable UDR_USER)}" UDR_PASS="${UDR_PASS:-$(_readaccountconf_mutable UDR_PASS)}" if [ -z "$UDR_USER" ] || [ -z "$UDR_PASS" ]; then @@ -64,7 +64,7 @@ dns_udr_add() { dns_udr_rm() { fulldomain=$1 txtvalue=$2 - export txtvalue + UDR_USER="${UDR_USER:-$(_readaccountconf_mutable UDR_USER)}" UDR_PASS="${UDR_PASS:-$(_readaccountconf_mutable UDR_PASS)}" if [ -z "$UDR_USER" ] || [ -z "$UDR_PASS" ]; then @@ -145,8 +145,8 @@ _udr_rest() { _debug data "${data}" response="$(_post "${data}" "${UDR_API}?s_login=${UDR_USER}&s_pw=${UDR_PASS}" "" "POST")" - _code=$(echo "$response" | _egrep_o "code = ([0-9]+)" | _head_n 1 | cut -d = -f 2 | xargs) - _description=$(echo "$response" | _egrep_o "description = .*" | _head_n 1 | cut -d = -f 2 | xargs) + _code=$(echo "$response" | _egrep_o "code = ([0-9]+)" | _head_n 1 | cut -d = -f 2 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + _description=$(echo "$response" | _egrep_o "description = .*" | _head_n 1 | cut -d = -f 2 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') _debug response_code "$_code" _debug response_description "$_description" From fac4e151cc739cc9993ff9f5ea7a08e4b37f2e13 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 8 Feb 2022 13:19:22 +0100 Subject: [PATCH 1668/2234] description --- dnsapi/dns_curanet.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index ab5462b1..92147bc7 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -83,12 +83,6 @@ dns_curanet_rm() { recordid=$(echo "$response" | _egrep_o "{\"id\":[0-9]+,\"name\":\"$fulldomain\"" | _egrep_o "id\":[0-9]+" | cut -c 5-) - re='^[0-9]+$' - if ! [[ $recordid =~ $re ]] ; then - err "Unable to delete record (did not find recordID to delete)" - return 1 - fi - _debug "Deleting recordID $recordid" response="$(_post "" "$CURANET_REST_URL/${_domain}/Records/$recordid" "" "DELETE")" @@ -108,8 +102,7 @@ gettoken() { return 1 fi - CURANET_ACCESS_TOKEN=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]+\"" | cut -c 17-) - CURANET_ACCESS_TOKEN=${CURANET_ACCESS_TOKEN::-1} + CURANET_ACCESS_TOKEN=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]+" | cut -c 17-) } From f8532ba812298274f544a1702faec014704fea8c Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 8 Feb 2022 13:21:02 +0100 Subject: [PATCH 1669/2234] removed unused variable --- dnsapi/dns_curanet.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 92147bc7..98f2edd5 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -109,7 +109,6 @@ gettoken() { #_acme-challenge.www.domain.com #returns -# _sub_domain=_acme-challenge.www # _domain=domain.com # _domain_id=sdjkglgdfewsdfg _get_root() { @@ -131,7 +130,6 @@ _get_root() { response="$(_get "$CURANET_REST_URL/$h/Records" "" "")" if [ ! "$(echo "$response" | _egrep_o "Entity not found")" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h return 0 fi From a5f943e22751cf52d90e800a9b918d9bf4be9617 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 8 Feb 2022 13:24:31 +0100 Subject: [PATCH 1670/2234] removed unused variable --- dnsapi/dns_curanet.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 98f2edd5..3df0bf44 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -114,7 +114,6 @@ gettoken() { _get_root() { domain=$1 i=1 - p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -134,7 +133,6 @@ _get_root() { return 0 fi - p=$i i=$(_math "$i" + 1) done return 1 From af5c36e4ad3f36367f19a8eaa1af8702235a48b0 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 8 Feb 2022 13:32:15 +0100 Subject: [PATCH 1671/2234] shfmt' --- dnsapi/dns_curanet.sh | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 3df0bf44..7c5f2fca 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -35,7 +35,7 @@ dns_curanet_add() { gettoken _get_root "$fulldomain" - + export _H1="Content-Type: application/json-patch+json" export _H2="Accept: application/json" export _H3="Authorization: Bearer $CURANET_ACCESS_TOKEN" @@ -43,7 +43,7 @@ dns_curanet_add() { response="$(_post "$data" "$CURANET_REST_URL/${_domain}/Records" "" "")" if _contains "$response" "$txtvalue"; then - _debug "TXT record added OK" + _debug "TXT record added OK" else _err "Unable to add TXT record" return 1 @@ -60,14 +60,14 @@ dns_curanet_rm() { _info "Using curanet" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" - + CURANET_AUTHCLIENTID="${CURANET_AUTHCLIENTID:-$(_readaccountconf_mutable CURANET_AUTHCLIENTID)}" CURANET_AUTHSECRET="${CURANET_AUTHSECRET:-$(_readaccountconf_mutable CURANET_AUTHSECRET)}" gettoken _get_root "$fulldomain" - + _debug "Getting current record list to identify TXT to delete" export _H1="Content-Type: application/json" @@ -88,25 +88,19 @@ dns_curanet_rm() { response="$(_post "" "$CURANET_REST_URL/${_domain}/Records/$recordid" "" "DELETE")" return 0; - } #################### Private functions below ################################## gettoken() { - response="$(_post "grant_type=client_credentials&client_id=$CURANET_AUTHCLIENTID&client_secret=$CURANET_AUTHSECRET&scope=dns" "$CURANET_AUTH_URL" "" "")" - if ! _contains "$response" "access_token"; then _err "Unable get access token" return 1 fi - CURANET_ACCESS_TOKEN=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]+" | cut -c 17-) - } - #_acme-challenge.www.domain.com #returns # _domain=domain.com @@ -132,9 +126,8 @@ _get_root() { _domain=$h return 0 fi - + i=$(_math "$i" + 1) done return 1 -} - +} \ No newline at end of file From 9fb89d7fd2155f113c65c2a31d70efe631647bef Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 8 Feb 2022 13:33:43 +0100 Subject: [PATCH 1672/2234] shfmt --- dnsapi/dns_curanet.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 7c5f2fca..a4e9bd97 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -82,11 +82,8 @@ dns_curanet_rm() { fi recordid=$(echo "$response" | _egrep_o "{\"id\":[0-9]+,\"name\":\"$fulldomain\"" | _egrep_o "id\":[0-9]+" | cut -c 5-) - _debug "Deleting recordID $recordid" - response="$(_post "" "$CURANET_REST_URL/${_domain}/Records/$recordid" "" "DELETE")" - return 0; } From ee0fadf2470d3c0e2197c9d495e95634cec76336 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 8 Feb 2022 13:34:42 +0100 Subject: [PATCH 1673/2234] shfmt --- dnsapi/dns_curanet.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index a4e9bd97..9cf7171e 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -84,7 +84,7 @@ dns_curanet_rm() { recordid=$(echo "$response" | _egrep_o "{\"id\":[0-9]+,\"name\":\"$fulldomain\"" | _egrep_o "id\":[0-9]+" | cut -c 5-) _debug "Deleting recordID $recordid" response="$(_post "" "$CURANET_REST_URL/${_domain}/Records/$recordid" "" "DELETE")" - return 0; + return 0 } #################### Private functions below ################################## @@ -127,4 +127,4 @@ _get_root() { i=$(_math "$i" + 1) done return 1 -} \ No newline at end of file +} From 2c0cc87b4cfa6352d3dfebbf9aa86ab4a5ce0ac0 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 8 Feb 2022 13:49:04 +0100 Subject: [PATCH 1674/2234] final commit --- dnsapi/dns_curanet.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 9cf7171e..90560c3c 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -3,6 +3,7 @@ #Script to use with curanet.dk, scannet.dk, wannafind.dk, dandomain.dk DNS management. #Requires api credentials with scope: dns #Author: Peter L. Hansen +#Version 1.0 CURANET_REST_URL="https://api.curanet.dk/dns/v1/Domains" CURANET_AUTH_URL="https://apiauth.dk.team.blue/auth/realms/Curanet/protocol/openid-connect/token" From 888d91d14a693c80069ad128a0df10b5bb77cbf3 Mon Sep 17 00:00:00 2001 From: Andreas Scherer Date: Tue, 8 Feb 2022 15:57:19 +0100 Subject: [PATCH 1675/2234] FIX dns_udr api: loop variable --- dnsapi/dns_udr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_udr.sh b/dnsapi/dns_udr.sh index 305fc2b3..caada826 100644 --- a/dnsapi/dns_udr.sh +++ b/dnsapi/dns_udr.sh @@ -108,7 +108,7 @@ dns_udr_rm() { # _domain=domain.com _get_root() { domain=$1 - i=2 + i=1 if ! _udr_rest "QueryDNSZoneList" ""; then return 1 From 0c9a6da623460b77f025d988573b53ad4666a67f Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 8 Feb 2022 17:18:48 +0100 Subject: [PATCH 1676/2234] more specific delete of records --- dnsapi/dns_curanet.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 90560c3c..b7726b77 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -82,7 +82,7 @@ dns_curanet_rm() { return 1 fi - recordid=$(echo "$response" | _egrep_o "{\"id\":[0-9]+,\"name\":\"$fulldomain\"" | _egrep_o "id\":[0-9]+" | cut -c 5-) + recordid=$(echo "$response" | _egrep_o "{\"id\":[0-9]+,\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":60,\"priority\":0,\"data\":\"..$txtvalue" | _egrep_o "id\":[0-9]+" | cut -c 5-) _debug "Deleting recordID $recordid" response="$(_post "" "$CURANET_REST_URL/${_domain}/Records/$recordid" "" "DELETE")" return 0 From 2c2a43e1ecfc8482888d392cef793f4980a73adc Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 9 Feb 2022 18:08:55 +0800 Subject: [PATCH 1677/2234] Update dns_cf.sh if CF_Zone_ID is used, save it to domain conf instead. --- dnsapi/dns_cf.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 36799dcd..c2430086 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -25,9 +25,15 @@ dns_cf_add() { CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" if [ "$CF_Token" ]; then - _saveaccountconf_mutable CF_Token "$CF_Token" - _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" - _saveaccountconf_mutable CF_Zone_ID "$CF_Zone_ID" + if [ "$CF_Zone_ID" ]; then + _savedomainconf CF_Token "$CF_Token" + _savedomainconf CF_Account_ID "$CF_Account_ID" + _savedomainconf CF_Zone_ID "$CF_Zone_ID" + else + _saveaccountconf_mutable CF_Token "$CF_Token" + _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" + _saveaccountconf_mutable CF_Zone_ID "$CF_Zone_ID" + fi else if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then CF_Key="" From 205e95a246c43dd7a6994ed891ef034081c9be74 Mon Sep 17 00:00:00 2001 From: Mac_Zhou Date: Thu, 10 Feb 2022 11:29:09 +0800 Subject: [PATCH 1678/2234] Add environment variables ROUTER_OS_PORT --- deploy/routeros.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 9965d65c..456107c8 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -23,6 +23,7 @@ # ```sh # export ROUTER_OS_USERNAME=certuser # export ROUTER_OS_HOST=router.example.com +# export ROUTER_OS_PORT=22 # # acme.sh --deploy -d ftp.example.com --deploy-hook routeros # ``` @@ -80,6 +81,13 @@ routeros_deploy() { return 1 fi + _getdeployconf ROUTER_OS_PORT + + if [ -z "$ROUTER_OS_PORT" ]; then + _debug "Using default port 22 as ROUTER_OS_PORT, please set if not correct." + ROUTER_OS_PORT=22 + fi + _getdeployconf ROUTER_OS_ADDITIONAL_SERVICES if [ -z "$ROUTER_OS_ADDITIONAL_SERVICES" ]; then @@ -89,12 +97,13 @@ routeros_deploy() { _savedeployconf ROUTER_OS_HOST "$ROUTER_OS_HOST" _savedeployconf ROUTER_OS_USERNAME "$ROUTER_OS_USERNAME" + _savedeployconf ROUTER_OS_PORT "$ROUTER_OS_PORT" _savedeployconf ROUTER_OS_ADDITIONAL_SERVICES "$ROUTER_OS_ADDITIONAL_SERVICES" _info "Trying to push key '$_ckey' to router" - scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" + scp -P "$ROUTER_OS_PORT" "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" _info "Trying to push cert '$_cfullchain' to router" - scp "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" + scp -P "$ROUTER_OS_PORT" "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=ftp,read,write,password,sensitive \ source=\"## generated by routeros deploy script in acme.sh;\ \n/certificate remove [ find name=$_cdomain.cer_0 ];\ @@ -111,11 +120,11 @@ source=\"## generated by routeros deploy script in acme.sh;\ \n\" " # shellcheck disable=SC2029 - ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD" + ssh -p "$ROUTER_OS_PORT" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD" # shellcheck disable=SC2029 - ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\"" + ssh -p "$ROUTER_OS_PORT" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\"" # shellcheck disable=SC2029 - ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\"" + ssh -p "$ROUTER_OS_PORT" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\"" return 0 } From 01ace11293f4cf27f8e761114f48148bbcbad063 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 11 Feb 2022 21:11:04 +0800 Subject: [PATCH 1679/2234] Update dns_ispconfig.sh fix https://github.com/acmesh-official/acme.sh/issues/3895#issuecomment-1035409954 --- 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 765e0eb5..e68ddd49 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}" ] || [ -n "${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 aaae83efec5eed7182a0dca78c313cde27100de2 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 12 Feb 2022 20:18:08 +0100 Subject: [PATCH 1680/2234] check for return values --- dnsapi/dns_curanet.sh | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index b7726b77..d446c64a 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -33,9 +33,15 @@ dns_curanet_add() { _saveaccountconf_mutable CURANET_AUTHCLIENTID "$CURANET_AUTHCLIENTID" _saveaccountconf_mutable CURANET_AUTHSECRET "$CURANET_AUTHSECRET" - gettoken + if ! _get_token; then + _err "Unable to get token" + return 1 + fi - _get_root "$fulldomain" + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi export _H1="Content-Type: application/json-patch+json" export _H2="Accept: application/json" @@ -65,9 +71,15 @@ dns_curanet_rm() { CURANET_AUTHCLIENTID="${CURANET_AUTHCLIENTID:-$(_readaccountconf_mutable CURANET_AUTHCLIENTID)}" CURANET_AUTHSECRET="${CURANET_AUTHSECRET:-$(_readaccountconf_mutable CURANET_AUTHSECRET)}" - gettoken + if ! _get_token; then + _err "Unable to get token" + return 1 + fi - _get_root "$fulldomain" + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi _debug "Getting current record list to identify TXT to delete" @@ -90,13 +102,19 @@ dns_curanet_rm() { #################### Private functions below ################################## -gettoken() { +_get_token() { response="$(_post "grant_type=client_credentials&client_id=$CURANET_AUTHCLIENTID&client_secret=$CURANET_AUTHSECRET&scope=dns" "$CURANET_AUTH_URL" "" "")" if ! _contains "$response" "access_token"; then _err "Unable get access token" return 1 fi CURANET_ACCESS_TOKEN=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]+" | cut -c 17-) + + if [ -z "$CURANET_ACCESS_TOKEN" ]; then + _err "Unable to get token" + return 1 + fi + } #_acme-challenge.www.domain.com From a2901d61ea4be6ca3a390f82f84ecde5c7ab7549 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 12 Feb 2022 23:39:33 +0100 Subject: [PATCH 1681/2234] check for return values --- dnsapi/dns_curanet.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index d446c64a..c59c2350 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -115,6 +115,8 @@ _get_token() { return 1 fi + return 0; + } #_acme-challenge.www.domain.com From af08d67fadc0382abdd066d1b8c97b32c33aef0f Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 12 Feb 2022 23:41:26 +0100 Subject: [PATCH 1682/2234] rem. ; --- dnsapi/dns_curanet.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index c59c2350..ef6b0dc3 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -115,7 +115,7 @@ _get_token() { return 1 fi - return 0; + return 0 } From 9a677534a7dea0e8a9efdb996979bcfa0b0a12ff Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 13 Feb 2022 14:00:14 +0100 Subject: [PATCH 1683/2234] added more debug info when rm recordid is empty --- dnsapi/dns_curanet.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index ef6b0dc3..4b39f365 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -95,6 +95,14 @@ dns_curanet_rm() { fi recordid=$(echo "$response" | _egrep_o "{\"id\":[0-9]+,\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":60,\"priority\":0,\"data\":\"..$txtvalue" | _egrep_o "id\":[0-9]+" | cut -c 5-) + + if [ -z "$recordid" ]; then + _err "Unable to get recordid" + _debug "regex {\"id\":[0-9]+,\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":60,\"priority\":0,\"data\":\"..$txtvalue" + _debug "response $response" + return 1 + fi + _debug "Deleting recordID $recordid" response="$(_post "" "$CURANET_REST_URL/${_domain}/Records/$recordid" "" "DELETE")" return 0 From 2982e9943e522773dd7e84d5f7252c0d6051b0d8 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Thu, 17 Feb 2022 19:02:35 +0100 Subject: [PATCH 1684/2234] Add custom option to map multidomain RIDs --- dnsapi/dns_selfhost.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 8c6e9a91..1ebc6596 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -2,7 +2,7 @@ # # Author: Marvin Edeler # Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 -# Last Edit: 09.01.2022 +# Last Edit: 17.02.2022 dns_selfhost_add() { domain=$1 @@ -14,6 +14,7 @@ dns_selfhost_add() { SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl" SELFHOSTDNS_USERNAME="${SELFHOSTDNS_USERNAME:-$(_readaccountconf_mutable SELFHOSTDNS_USERNAME)}" SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" + SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readaccountconf_mutable SELFHOSTDNS_MAP)}" SELFHOSTDNS_RID="${SELFHOSTDNS_RID:-$(_readaccountconf_mutable SELFHOSTDNS_RID)}" SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readaccountconf_mutable SELFHOSTDNS_RID2)}" SELFHOSTDNS_LAST_SLOT="$(_readaccountconf_mutable SELFHOSTDNS_LAST_SLOT)" @@ -24,15 +25,19 @@ dns_selfhost_add() { _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" + _saveaccountconf_mutable SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then - rid=$SELFHOSTDNS_RID - SELFHOSTDNS_LAST_SLOT=1 - else - rid=$SELFHOSTDNS_RID2 - SELFHOSTDNS_LAST_SLOT=2 + rid=$(echo $SELFHOSTDNS_MAP | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") + if test -z "$rid"; then + if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then + rid=$SELFHOSTDNS_RID + SELFHOSTDNS_LAST_SLOT=1 + else + rid=$SELFHOSTDNS_RID2 + SELFHOSTDNS_LAST_SLOT=2 + fi fi _saveaccountconf_mutable SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" From 947085025882a0dda7ea7297e4320bef385e1ff1 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Thu, 17 Feb 2022 19:08:58 +0100 Subject: [PATCH 1685/2234] Fix shellcheck, use double quote --- dnsapi/dns_selfhost.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 1ebc6596..7ad92e20 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -29,7 +29,7 @@ dns_selfhost_add() { _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - rid=$(echo $SELFHOSTDNS_MAP | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") + rid=$(echo "$SELFHOSTDNS_MAP" | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") if test -z "$rid"; then if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then rid=$SELFHOSTDNS_RID From ac0dd90c37db0105fc07b16c41ffebfc245ee738 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Thu, 17 Feb 2022 19:30:56 +0100 Subject: [PATCH 1686/2234] Fix shfmt --- dnsapi/dns_selfhost.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 7ad92e20..d5ecd278 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -29,7 +29,8 @@ dns_selfhost_add() { _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - rid=$(echo "$SELFHOSTDNS_MAP" | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") + rid=$(echo "$SELFHOSTDNS_MAP" | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") + if test -z "$rid"; then if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then rid=$SELFHOSTDNS_RID From 8a2f673903f4386ab3f1e19f012222d713620fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Sat, 19 Feb 2022 13:42:32 +0100 Subject: [PATCH 1687/2234] deploy/routeros.sh: make ssh/scp configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to modify ssh/scp commands make them configurable via environment variables. Signed-off-by: Andreas Bießmann --- deploy/routeros.sh | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 456107c8..b25bd100 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -49,6 +49,16 @@ # One optional thing to do as well is to create a script that updates # all the required services and run that script in a single command. # +# To adopt parameters to `scp` and/or `ssh` set the optional +# `ROUTER_OS_SSH_CMD` and `ROUTER_OS_SCP_CMD` variables accordingly, +# see ssh(1) and scp(1) for parameters to those commands. +# +# Example: +# ```ssh +# export ROUTER_OS_SSH_CMD="ssh -i /acme.sh/.ssh/router.example.com -o UserKnownHostsFile=/acme.sh/.ssh/known_hosts" +# export ROUTER_OS_SCP_CMD="scp -i /acme.sh/.ssh/router.example.com -o UserKnownHostsFile=/acme.sh/.ssh/known_hosts" +# ```` +# # returns 0 means success, otherwise error. ######## Public functions ##################### @@ -88,6 +98,20 @@ routeros_deploy() { ROUTER_OS_PORT=22 fi + _getdeployconf ROUTER_OS_SSH_CMD + + if [ -z "$ROUTER_OS_SSH_CMD" ]; then + _debug "Use default ssh setup." + ROUTER_OS_SSH_CMD="ssh -p $ROUTER_OS_PORT" + fi + + _getdeployconf ROUTER_OS_SCP_CMD + + if [ -z "$ROUTER_OS_SCP_CMD" ]; then + _debug "USe default scp setup." + ROUTER_OS_SCP_CMD="scp -P $ROUTER_OS_PORT" + fi + _getdeployconf ROUTER_OS_ADDITIONAL_SERVICES if [ -z "$ROUTER_OS_ADDITIONAL_SERVICES" ]; then @@ -98,12 +122,14 @@ routeros_deploy() { _savedeployconf ROUTER_OS_HOST "$ROUTER_OS_HOST" _savedeployconf ROUTER_OS_USERNAME "$ROUTER_OS_USERNAME" _savedeployconf ROUTER_OS_PORT "$ROUTER_OS_PORT" + _savedeployconf ROUTER_OS_SSH_CMD "$ROUTER_OS_SSH_CMD" + _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" - scp -P "$ROUTER_OS_PORT" "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" + $ROUTER_OS_SCP_CMD "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key" _info "Trying to push cert '$_cfullchain' to router" - scp -P "$ROUTER_OS_PORT" "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer" + $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=admin policy=ftp,read,write,password,sensitive \ source=\"## generated by routeros deploy script in acme.sh;\ \n/certificate remove [ find name=$_cdomain.cer_0 ];\ @@ -120,11 +146,11 @@ source=\"## generated by routeros deploy script in acme.sh;\ \n\" " # shellcheck disable=SC2029 - ssh -p "$ROUTER_OS_PORT" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD" + $ROUTER_OS_SSH_CMD "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD" # shellcheck disable=SC2029 - ssh -p "$ROUTER_OS_PORT" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\"" + $ROUTER_OS_SSH_CMD "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\"" # shellcheck disable=SC2029 - ssh -p "$ROUTER_OS_PORT" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\"" + $ROUTER_OS_SSH_CMD "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\"" return 0 } From 92e4ecce3b94ead392e0e1283ba14ce8bbad4bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Sat, 19 Feb 2022 13:44:51 +0100 Subject: [PATCH 1688/2234] deploy/routeros.sh: remove all certificates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the script is applying the fullchain which includes three certificates, delete all of them before applying updated certificate. Signed-off-by: Andreas Bießmann --- deploy/routeros.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index b25bd100..3c74f592 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -134,6 +134,7 @@ routeros_deploy() { source=\"## generated by routeros deploy script in acme.sh;\ \n/certificate remove [ find name=$_cdomain.cer_0 ];\ \n/certificate remove [ find name=$_cdomain.cer_1 ];\ +\n/certificate remove [ find name=$_cdomain.cer_2 ];\ \ndelay 1;\ \n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\";\ \n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\";\ From c46ceb06b49ae32a3c51d88756941fa94642dbe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Sat, 19 Feb 2022 13:56:07 +0100 Subject: [PATCH 1689/2234] deploy/routeros.sh: change DEPLOY_SCRIPT_CMD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This set the owner of script to ssh user, have the comment line in script as real comment and removes policy since this is set from current user, at least for RouterOS 7.x. Signed-off-by: Andreas Bießmann --- deploy/routeros.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index 3c74f592..b2b18c5e 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -130,9 +130,9 @@ 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=admin policy=ftp,read,write,password,sensitive \ -source=\"## generated by routeros deploy script in acme.sh;\ -\n/certificate remove [ find name=$_cdomain.cer_0 ];\ + DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=$ROUTER_OS_USER \ +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 ];\ \n/certificate remove [ find name=$_cdomain.cer_2 ];\ \ndelay 1;\ From 8752d08ce95e7edd938f5de1262038805424bd78 Mon Sep 17 00:00:00 2001 From: richard-9000 <53876487+richard-9000@users.noreply.github.com> Date: Sat, 19 Feb 2022 10:52:24 -0800 Subject: [PATCH 1690/2234] dns_opnsense.sh - Fixed the domain parse regex Extended the regex to skip the new transferkey and hmac sections of opnsense bind. --- dnsapi/dns_opnsense.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 26a422f8..eb95902f 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,8 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"\":{[^}]*}}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) - + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"[^\"]*\":{[^}]*}},\"transferkeyalgo\":{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^}]*}},\"transferkey\":\"[^\"]*\"(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" _host=$(printf "%s" "$domain" | cut -d . -f 1-$p) From bcf63b5d270a4535347e64e7f25f24970e474e6f Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 14:17:34 +0100 Subject: [PATCH 1691/2234] Add ArtFiles.de DNS API plugin --- dnsapi/dns_artfiles.sh | 176 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 dnsapi/dns_artfiles.sh diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh new file mode 100644 index 00000000..c857060a --- /dev/null +++ b/dnsapi/dns_artfiles.sh @@ -0,0 +1,176 @@ +#!/usr/bin/env sh + +################################################################################ +# ACME.sh 3rd party DNS API plugin for ArtFiles.de +################################################################################ +# Author: Martin Arndt, https://troublezone.net/ +# Released: 2022-02-27 +# Issues: https://github.com/acmesh-official/acme.sh/issues/XXXX +################################################################################ +# Usage: +# 1. export AF_API_Username="api12345678" +# 2. export AF_API_Password="apiPassword" +# 3. acme.sh --issue -d example.com --dns dns_artfiles +################################################################################ + +########## API configuration ################################################### +AF_API_SUCCESS='status":"OK' +AF_URL_DCP='https://dcp.c.artfiles.de/api/' +AF_URL_DNS=${AF_URL_DCP}'dns/{*}_dns.html?domain=' +AF_URL_DOMAINS=${AF_URL_BASE}'domain/get_domains.html' + +########## Public functions #################################################### + +# Adds a new TXT record for given ACME challenge value & domain. +# Usage: dns_artfiles_add _acme-challenge.www.example.com "ACME challenge value" +dns_artfiles_add() { + domain="$1" + txtValue="$2" + _info 'Using ArtFiles.de DNS addition API' + _debug 'Domain' "$domain" + _debug 'txtValue' "$txtValue" + + AF_API_USERNAME="${AF_API_USERNAME:-$(_readaccountconf_mutable AF_API_USERNAME)}" + AF_API_PASSWORD="${AF_API_PASSWORD:-$(_readaccountconf_mutable AF_API_PASSWORD)}" + if [ -z "$AF_API_USERNAME" ] || [ -z "$AF_API_PASSWORD" ]; then + _err 'Missing ArtFiles.de username and/or password.' + _err 'Please ensure both are set via export command & try again.' + + return 1 + fi + + _saveaccountconf_mutable 'AF_API_USERNAME' "$AF_API_USERNAME" + _saveaccountconf_mutable 'AF_API_PASSWORD' "$AF_API_PASSWORD" + + _set_headers + _get_zone "$domain" + _dns 'GET' + if ! _contains "$response" 'TXT'; then + _err 'Retrieving TXT records failed.' + + return 1 + fi + + _clean_records + _dns 'SET' "$(printf -- '%s\n_acme-challenge "%s"' "$response" "$txtValue")" + if ! _contains "$response" "$AF_API_SUCCESS"; then + _err 'Adding ACME challenge value failed.' + + return 1 + fi +} + +# Removes the existing TXT record for given ACME challenge value & domain. +# Usage: dns_artfiles_rm _acme-challenge.www.example.com "ACME challenge value" +dns_artfiles_rm() { + domain="$1" + txtValue="$2" + _info 'Using ArtFiles.de DNS removal API' + _debug 'Domain' "$domain" + _debug 'txtValue' "$txtValue" + + _set_headers + _get_zone "$domain" + if ! _dns 'GET'; then + return 1 + fi + + if ! _contains "$response" "$txtValue"; then + _err 'Retrieved TXT records are missing given ACME challenge value.' + + return 1 + fi + + _clean_records + response="$(printf -- '%s' "$response" | sed '$d')" + _dns 'SET' "$response" + if ! _contains "$response" "$AF_API_SUCCESS"; then + _err 'Removing ACME challenge value failed.' + + return 1 + fi +} + +########## Private functions ################################################### + +# Cleans awful TXT records response of ArtFiles's API & pretty prints it. +# Usage: _clean_records +_clean_records() +{ + # Extract TXT part, strip trailing quote sign (ACME.sh API guidelines forbid + # usage of SED's GNU extensions, hence couldn't omit it via regex), strip '\' + # from '\"' & turn '\n' into real LF characters. + # Yup, awful API to use - but that's all we got to get this working, so... ;) + _debug2 'Raw ' "$response" + response="$(printf -- '%s' "$response" + \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g')" + _debug2 'Clean' "$response" +} + +# Executes an HTTP GET or POST request for getting or setting DNS records, +# containing given payload upon POST. +# Usage: _dns [GET | SET] [payload] +_dns() +{ + action="$1" + payload="$(printf -- '%s' "$2" | _url_encode)" + url="$(printf -- '%s%s' "$AF_URL_DNS" "$domain" + \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')" + + if [ "$action" = 'SET' ]; then + _debug2 'Payload' "$payload" + response="$(_post '' "$url&TXT=$payload" '' 'POST' 'application/x-www-form-urlencoded')" + else + response="$(_get "$url" '' 10)" + fi + + if ! _contains "$response" "$AF_API_SUCCESS"; then + _err "DNS API error: $response" + + return 1 + fi + + _debug 'Response' "$response" + + return 0 +} + +# Gets the root domain zone for given domain. +# Usage: _get_zone _acme-challenge.www.example.com +_get_zone() +{ + _info 'Getting domain zone...' + _debug2 'Initial FQDN' "$1" + fqdn="$1" + fqdn="${fqdn#*.}" # Strip "_acme-challenge" right away + _debug2 'Reduced FQDN' "$fqdn" + + domains="$(_get "$AF_URL_DOMAINS" '' 10)" + while true; do + if _contains "$domains" "$fqdn"; then + domain="$fqdn" + _info "Found root domain zone: $domain" + break + else + fqdn="${fqdn#*.}" + _debug2 'FQDN' "$fqdn" + fi + done + + if [ "$domain" = "$fqdn" ]; then + return 0 + fi + + _err "Couldn't find root domain zone." + + return 1 +} + +# Adds the HTTP Authorization & Content-Type headers to a follow-up request. +# Usage: _set_headers +_set_headers() +{ + encoded="$(printf -- '%s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)" + export _H1="Authorization: Basic $encoded" + export _H2='Content-Type: application/json' +} From 72d02f442e2e8528afb04a0e55c88185bb99a7e9 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 14:35:21 +0100 Subject: [PATCH 1692/2234] Fix formatting according to Shellcheck --- dnsapi/dns_artfiles.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index c857060a..4598854d 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -95,8 +95,7 @@ dns_artfiles_rm() { # Cleans awful TXT records response of ArtFiles's API & pretty prints it. # Usage: _clean_records -_clean_records() -{ +_clean_records() { # Extract TXT part, strip trailing quote sign (ACME.sh API guidelines forbid # usage of SED's GNU extensions, hence couldn't omit it via regex), strip '\' # from '\"' & turn '\n' into real LF characters. @@ -110,8 +109,7 @@ _clean_records() # Executes an HTTP GET or POST request for getting or setting DNS records, # containing given payload upon POST. # Usage: _dns [GET | SET] [payload] -_dns() -{ +_dns() { action="$1" payload="$(printf -- '%s' "$2" | _url_encode)" url="$(printf -- '%s%s' "$AF_URL_DNS" "$domain" @@ -137,8 +135,7 @@ _dns() # Gets the root domain zone for given domain. # Usage: _get_zone _acme-challenge.www.example.com -_get_zone() -{ +_get_zone() { _info 'Getting domain zone...' _debug2 'Initial FQDN' "$1" fqdn="$1" @@ -168,8 +165,7 @@ _get_zone() # Adds the HTTP Authorization & Content-Type headers to a follow-up request. # Usage: _set_headers -_set_headers() -{ +_set_headers() { encoded="$(printf -- '%s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)" export _H1="Authorization: Basic $encoded" export _H2='Content-Type: application/json' From 0bea2e2b94e49f59e05c7507bcec548c50a4abac Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 14:37:22 +0100 Subject: [PATCH 1693/2234] Fix formatting according to Shellcheck 2/2 --- dnsapi/dns_artfiles.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 4598854d..f83ce64a 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -101,8 +101,9 @@ _clean_records() { # from '\"' & turn '\n' into real LF characters. # Yup, awful API to use - but that's all we got to get this working, so... ;) _debug2 'Raw ' "$response" - response="$(printf -- '%s' "$response" - \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g')" + response="$( + printf -- '%s' "$response" + \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g')" _debug2 'Clean' "$response" } @@ -112,8 +113,9 @@ _clean_records() { _dns() { action="$1" payload="$(printf -- '%s' "$2" | _url_encode)" - url="$(printf -- '%s%s' "$AF_URL_DNS" "$domain" - \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')" + url="$( + printf -- '%s%s' "$AF_URL_DNS" "$domain" + \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')" if [ "$action" = 'SET' ]; then _debug2 'Payload' "$payload" From fb457968ecae380bc17914f22d134bcfba93d304 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 14:38:24 +0100 Subject: [PATCH 1694/2234] Fix formatting according to Shellcheck 3/3 --- dnsapi/dns_artfiles.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index f83ce64a..9c1a4338 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -103,7 +103,8 @@ _clean_records() { _debug2 'Raw ' "$response" response="$( printf -- '%s' "$response" - \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g')" + \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g' + )" _debug2 'Clean' "$response" } @@ -115,7 +116,8 @@ _dns() { payload="$(printf -- '%s' "$2" | _url_encode)" url="$( printf -- '%s%s' "$AF_URL_DNS" "$domain" - \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')" + \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/' + )" if [ "$action" = 'SET' ]; then _debug2 'Payload' "$payload" From ed56d52af309a4d90747169a321dbd3698a4b71a Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 15:12:05 +0100 Subject: [PATCH 1695/2234] Changed GitHub issues URL --- dnsapi/dns_artfiles.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 9c1a4338..8e0a6151 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -5,7 +5,7 @@ ################################################################################ # Author: Martin Arndt, https://troublezone.net/ # Released: 2022-02-27 -# Issues: https://github.com/acmesh-official/acme.sh/issues/XXXX +# Issues: https://github.com/Eagle3386/acme.sh/issues ################################################################################ # Usage: # 1. export AF_API_Username="api12345678" From b37bf06de87ab41d495e0a3156f538c5baf9c679 Mon Sep 17 00:00:00 2001 From: fradev Date: Tue, 1 Mar 2022 17:57:59 +0100 Subject: [PATCH 1696/2234] Update ssh.sh --- deploy/ssh.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 604d8642..7d9e82e8 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -24,7 +24,7 @@ # export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy # export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value # export DEPLOY_SSH_USE_SCP="" yes or no , default to no -# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -T -q " +# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -q " # ######## Public functions ##################### @@ -53,7 +53,7 @@ ssh_deploy() { fi else Le_Deploy_ssh_user="$DEPLOY_SSH_USER" - _savedomainconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user" + _savedeployconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user" fi # SERVER is optional. If not provided then use _cdomain @@ -61,7 +61,7 @@ ssh_deploy() { _debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER" if [ -n "$DEPLOY_SSH_SERVER" ]; then Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER" - _savedomainconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server" + _savedeployconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server" elif [ -z "$Le_Deploy_ssh_server" ]; then Le_Deploy_ssh_server="$_cdomain" fi @@ -71,7 +71,7 @@ ssh_deploy() { _debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD" if [ -n "$DEPLOY_SSH_CMD" ]; then Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD" - _savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd" + _savedeployconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd" elif [ -z "$Le_Deploy_ssh_cmd" ]; then Le_Deploy_ssh_cmd="ssh -T" fi @@ -80,7 +80,7 @@ ssh_deploy() { # value (which may be undefined... equivalent to "no"). if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then Le_Deploy_ssh_use_scp="yes" - _savedomainconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" + _savedeployconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then Le_Deploy_ssh_use_scp="" _cleardomainconf Le_Deploy_ssh_use_scp @@ -89,9 +89,9 @@ ssh_deploy() { # SCP_CMD is optional. If not provided then use scp if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" - _savedomainconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" + _savedeployconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then - Le_Deploy_ssh_scp_cmd="scp -T" + Le_Deploy_ssh_scp_cmd="scp -q" fi # BACKUP is optional. If not provided then default to previously saved value or yes. @@ -102,7 +102,7 @@ ssh_deploy() { elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then Le_Deploy_ssh_backup="yes" fi - _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" + _savedeployconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" # BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy _getdeployconf DEPLOY_SSH_BACKUP_PATH @@ -112,7 +112,7 @@ ssh_deploy() { elif [ -z "$Le_Deploy_ssh_backup_path" ]; then Le_Deploy_ssh_backup_path=".acme_ssh_deploy" fi - _savedomainconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path" + _savedeployconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path" # MULTI_CALL is optional. If not provided then default to previously saved # value (which may be undefined... equivalent to "no"). @@ -120,7 +120,7 @@ ssh_deploy() { _debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL" if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then Le_Deploy_ssh_multi_call="yes" - _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then Le_Deploy_ssh_multi_call="" _cleardomainconf Le_Deploy_ssh_multi_call @@ -130,9 +130,9 @@ ssh_deploy() { # value (which may be undefined... equivalent to "no"). if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then Le_Deploy_ssh_use_scp="yes" - _savedomainconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" + _savedeployconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" Le_Deploy_ssh_multi_call="yes" - _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then Le_Deploy_ssh_use_scp="" _cleardomainconf Le_Deploy_ssh_use_scp @@ -141,7 +141,7 @@ ssh_deploy() { # SCP_CMD is optional. If not provided then use scp if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" - _savedomainconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" + _savedeployconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then Le_Deploy_ssh_scp_cmd="scp -T -q " fi @@ -165,7 +165,7 @@ _ssh_deploy() { if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then _info "Using scp as alternate method for copying files. Multicall Mode is implicit" Le_Deploy_ssh_multi_call="yes" - _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" fi if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" @@ -200,7 +200,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE" if [ -n "$DEPLOY_SSH_KEYFILE" ]; then Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE" - _savedomainconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile" + _savedeployconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile" fi if [ -n "$Le_Deploy_ssh_keyfile" ]; then if [ "$Le_Deploy_ssh_backup" = "yes" ]; then @@ -238,7 +238,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE" if [ -n "$DEPLOY_SSH_CERTFILE" ]; then Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE" - _savedomainconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile" + _savedeployconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile" fi if [ -n "$Le_Deploy_ssh_certfile" ]; then _pipe=">" @@ -288,7 +288,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE" if [ -n "$DEPLOY_SSH_CAFILE" ]; then Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE" - _savedomainconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile" + _savedeployconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile" fi if [ -n "$Le_Deploy_ssh_cafile" ]; then _pipe=">" @@ -346,7 +346,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN" if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN" - _savedomainconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain" + _savedeployconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain" fi if [ -n "$Le_Deploy_ssh_fullchain" ]; then _pipe=">" @@ -418,7 +418,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD" if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD" - _savedomainconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd" + _savedeployconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd" fi if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then _cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;" From 0ed4fc6a12fabf4fa01de07e391ea2daa0284b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Th=C3=B6rnblad?= Date: Fri, 4 Mar 2022 13:38:05 +0100 Subject: [PATCH 1697/2234] Update dns_loopia.sh Loopia API is now less tolerant so we need another tag surrounding the --- dnsapi/dns_loopia.sh | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 7760b53e..e8f99185 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -206,24 +206,26 @@ _loopia_add_record() { %s - - - type - TXT - - - priority - 0 - - - ttl - 300 - - - rdata - %s - - + + + + type + TXT + + + priority + 0 + + + ttl + 300 + + + rdata + %s + + + ' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain" "$txtval") From 13f80acb2d92801867c415d55dff2fb8dfb42272 Mon Sep 17 00:00:00 2001 From: waldner Date: Sat, 5 Mar 2022 01:03:04 +0100 Subject: [PATCH 1698/2234] geoscaling DNS API --- dnsapi/dns_geoscaling.sh | 221 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100755 dnsapi/dns_geoscaling.sh diff --git a/dnsapi/dns_geoscaling.sh b/dnsapi/dns_geoscaling.sh new file mode 100755 index 00000000..6d61312d --- /dev/null +++ b/dnsapi/dns_geoscaling.sh @@ -0,0 +1,221 @@ +#!/usr/bin/env sh + +######################################################################## +# Geoscaling hook script for acme.sh +# +# Environment variables: +# +# - $GEOSCALING_Username (your Geoscaling username - this is usually NOT an amail address) +# - $GEOSCALING_Password (your Geoscaling password) + +#-- dns_geoscaling_add() - Add TXT record -------------------------------------- +# Usage: dns_geoscaling_add _acme-challenge.subdomain.domain.com "XyZ123..." + +dns_geoscaling_add() { + full_domain=$1 + txt_value=$2 + _info "Using 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 and $zone_name + find_zone "${full_domain}" || return 1 + _debug "Zone id '${zone_id}' will be used." + + # We're logged in here + + # we should add ${full_domain} minus the trailing ${zone_name} + + prefix=$(echo "${full_domain}" | sed "s|\\.${zone_name}\$||") + + body="id=${zone_id}&name=${prefix}&type=TXT&content=${txt_value}&ttl=300&prio=0" + + do_post "$body" "https://www.geoscaling.com/dns2/ajax/add_record.php" + exit_code="$?" + if [ "${exit_code}" -eq 0 ]; then + _info "TXT record added successfully." + else + _err "Couldn't add the TXT record." + fi + do_logout + return "${exit_code}" +} + +#-- dns_geoscaling_rm() - Remove TXT record ------------------------------------ +# Usage: dns_geoscaling_rm _acme-challenge.subdomain.domain.com "XyZ123..." + +dns_geoscaling_rm() { + full_domain=$1 + txt_value=$2 + _info "Cleaning up after DNS-01 Geoscaling DNS2 hook" + + # fills in the $zone_id + find_zone "${full_domain}" || return 1 + _debug "Zone id '${zone_id}' will be used." + + # Here we're logged in + # Find the record id to clean + + # get the domain + response=$(do_get "https://www.geoscaling.com/dns2/index.php?module=domain&id=${zone_id}") + _debug2 "response" "$response" + + table="$(echo "${response}" | tr -d '\n' | sed 's|.*
Basic Records
.*||')" + _debug2 table "${table}" + names=$(echo "${table}" | _egrep_o 'id="[0-9]+\.name">[^<]*' | sed 's|||; s|.*>||') + ids=$(echo "${table}" | _egrep_o 'id="[0-9]+\.name">[^<]*' | sed 's|\.name">.*||; s|id="||') + types=$(echo "${table}" | _egrep_o 'id="[0-9]+\.type">[^<]*' | sed 's|||; s|.*>||') + values=$(echo "${table}" | _egrep_o 'id="[0-9]+\.content">[^<]*' | sed 's|||; s|.*>||') + + _debug2 names "${names}" + _debug2 ids "${ids}" + _debug2 types "${types}" + _debug2 values "${values}" + + # look for line whose name is ${full_domain}, whose type is TXT, and whose value is ${txt_value} + line_num="$(echo "${values}" | grep -F -n -- "${txt_value}" | _head_n 1 | cut -d ':' -f 1)" + _debug2 line_num "${line_num}" + found_id= + if [ -n "$line_num" ]; then + type=$(echo "${types}" | sed -n "${line_num}p") + name=$(echo "${names}" | sed -n "${line_num}p") + id=$(echo "${ids}" | sed -n "${line_num}p") + + _debug2 type "$type" + _debug2 name "$name" + _debug2 id "$id" + _debug2 full_domain "$full_domain" + + if [ "${type}" = "TXT" ] && [ "${name}" = "${full_domain}" ]; then + found_id=${id} + fi + fi + + if [ "${found_id}" = "" ]; then + _err "Can not find record id." + return 0 + fi + + # Remove the record + body="id=${zone_id}&record_id=${found_id}" + response=$(do_post "$body" "https://www.geoscaling.com/dns2/ajax/delete_record.php") + exit_code="$?" + if [ "$exit_code" -eq 0 ]; then + _info "Record removed successfully." + else + _err "Could not clean (remove) up the record. Please go to Geoscaling administration interface and clean it by hand." + fi + do_logout + return "${exit_code}" +} + +########################## PRIVATE FUNCTIONS ########################### + +do_get() { + _url=$1 + export _H1="Cookie: $geoscaling_phpsessid_cookie" + _get "${_url}" +} + +do_post() { + _body=$1 + _url=$2 + export _H1="Cookie: $geoscaling_phpsessid_cookie" + _post "${_body}" "${_url}" +} + +do_login() { + + _info "Logging in..." + + username_encoded="$(printf "%s" "${GEOSCALING_Username}" | _url_encode)" + password_encoded="$(printf "%s" "${GEOSCALING_Password}" | _url_encode)" + body="username=${username_encoded}&password=${password_encoded}" + + response=$(_post "$body" "https://www.geoscaling.com/dns2/index.php?module=auth") + _debug2 response "${response}" + + #retcode=$(grep '^HTTP[^ ]*' "${HTTP_HEADER}" | _head_n 1 | _egrep_o '[0-9]+$') + retcode=$(grep '^HTTP[^ ]*' "${HTTP_HEADER}" | _head_n 1 | cut -d ' ' -f 2) + + if [ "$retcode" != "302" ]; then + _err "Geoscaling login failed for user ${GEOSCALING_Username}. Check ${HTTP_HEADER} file" + return 1 + fi + + geoscaling_phpsessid_cookie="$(grep -i '^set-cookie:' "${HTTP_HEADER}" | _egrep_o 'PHPSESSID=[^;]*;' | tr -d ';')" + return 0 + +} + +do_logout() { + _info "Logging out." + response="$(do_get "https://www.geoscaling.com/dns2/index.php?module=auth")" + _debug2 response "$response" + return 0 +} + +find_zone() { + domain="$1" + + # do login + do_login || return 1 + + # get zones + response="$(do_get "https://www.geoscaling.com/dns2/index.php?module=domains")" + + table="$(echo "${response}" | tr -d '\n' | sed 's|.*
Your domains
.*||')" + _debug2 table "${table}" + zone_names="$(echo "${table}" | _egrep_o '[^<]*' | sed 's|||;s|||')" + _debug2 _matches "${zone_names}" + # Zone names and zone IDs are in same order + zone_ids=$(echo "${table}" | _egrep_o '' | sed 's|.*id=||;s|. .*||') + + _debug2 "These are the zones on this Geoscaling account:" + _debug2 "zone_names" "${zone_names}" + _debug2 "And these are their respective IDs:" + _debug2 "zone_ids" "${zone_ids}" + if [ -z "${zone_names}" ] || [ -z "${zone_ids}" ]; then + _err "Can not get zone names or IDs." + return 1 + fi + # Walk through all possible zone names + strip_counter=1 + while true; do + attempted_zone=$(echo "${domain}" | cut -d . -f ${strip_counter}-) + + # All possible zone names have been tried + if [ -z "${attempted_zone}" ]; then + _err "No zone for domain '${domain}' found." + return 1 + fi + + _debug "Looking for zone '${attempted_zone}'" + + line_num="$(echo "${zone_names}" | grep -n "^${attempted_zone}\$" | _head_n 1 | cut -d : -f 1)" + _debug2 line_num "${line_num}" + if [ "$line_num" ]; then + zone_id=$(echo "${zone_ids}" | sed -n "${line_num}p") + zone_name=$(echo "${zone_names}" | sed -n "${line_num}p") + if [ -z "${zone_id}" ]; then + _err "Can not find zone id." + return 1 + fi + _debug "Found relevant zone '${attempted_zone}' with id '${zone_id}' - will be used for domain '${domain}'." + return 0 + fi + + _debug "Zone '${attempted_zone}' doesn't exist, let's try a less specific zone." + strip_counter=$(_math "${strip_counter}" + 1) + done +} +# vim: et:ts=2:sw=2: From b75e90f8c92e34676f571e295c4f304c6379e455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Th=C3=B6rnblad?= Date: Mon, 7 Mar 2022 10:28:09 +0100 Subject: [PATCH 1700/2234] Double quote variables (shellcheck suggestions) --- dnsapi/dns_loopia.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index e8f99185..73327335 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -133,7 +133,7 @@ _loopia_get_records() { %s - ' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain") + ' "$LOOPIA_User" "$LOOPIA_Password" "$domain" "$sub_domain") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" if ! _contains "$response" ""; then @@ -162,7 +162,7 @@ _get_root() { %s - ' $LOOPIA_User $LOOPIA_Password) + ' "$LOOPIA_User" "$LOOPIA_Password") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" while true; do @@ -228,7 +228,7 @@ _loopia_add_record() { - ' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain" "$txtval") + ' "$LOOPIA_User" "$LOOPIA_Password" "$domain" "$sub_domain" "$txtval") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" @@ -257,7 +257,7 @@ _sub_domain_exists() { %s - ' $LOOPIA_User $LOOPIA_Password "$domain") + ' "$LOOPIA_User" "$LOOPIA_Password" "$domain") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" @@ -292,7 +292,7 @@ _loopia_add_sub_domain() { %s - ' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain") + ' "$LOOPIA_User" "$LOOPIA_Password" "$domain" "$sub_domain") response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" From ea3c37d754801b289fa6a5abcbeadea1c773b147 Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Wed, 9 Mar 2022 01:36:06 +0100 Subject: [PATCH 1701/2234] Corrected use of Plesk API calls to fetch all domain for all Plesk editions This implementation of the Plesk API will add support for Plesk web admin edition and will now discover all domains managed by the specific plesk instance. The existing implementation of the Plesk API uses the customer API. This brings two problems: 1. The current API call only fetches the domains of resellers/customers and not the domains that are managed by administrative users. compare: https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-customer-accounts/retrieving-the-list-of-customer%E2%80%99s-domains.75309/ https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-plesk-server/getting-server-information/response-packet-structure-and-samples/list-of-domains.75294/ 2. The customer API is only available in the pro/admin editions. The most common license on VPS/Dedicated Servers is the web host edition. See: https://www.plesk.com/editions/ The correct way to get all domains in all Plesk editions is to use the Sites (Domains) API: https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-sites-domains/getting-information-about-sites.66583/ --- dnsapi/dns_pleskxml.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index f5986827..0f7dc241 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -41,7 +41,7 @@ pleskxml_init_checks_done=0 NEWLINE='\ ' -pleskxml_tplt_get_domains="" +pleskxml_tplt_get_domains="" # Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh # Also used to test credentials and URI. # No params. @@ -375,7 +375,7 @@ _pleskxml_get_root_domain() { # Output will be one line per known domain, containing 2 tages and a single tag # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. - output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" + output="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" _debug 'Domains managed by Plesk server are (ignore the hacked output):' _debug "$output" From a6b58bc88d390a21baf3cf457f3d3daba314222b Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Wed, 9 Mar 2022 01:36:06 +0100 Subject: [PATCH 1702/2234] Corrected use of Plesk API calls to fetch all domain for all Plesk editions This implementation of the Plesk API will add support for Plesk web admin edition and will now discover all domains ( of customers & administrative users) managed by the specific plesk instance. The previous implementation of the Plesk API uses the customer API. This brings two problems: 1. The current API call only fetches the domains of resellers/customers and not the domains that are managed by administrative users. compare: https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-customer-accounts/retrieving-the-list-of-customer%E2%80%99s-domains.75309/ https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-plesk-server/getting-server-information/response-packet-structure-and-samples/list-of-domains.75294/ 2. The customer API is only available in the web pro/host editions. The most common license on VPS/Dedicated Servers is nowadays the web admin edition. See: https://www.plesk.com/editions/ The correct way to get all domains in all Plesk editions is to use the Sites (Domains) API: https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-sites-domains/getting-information-about-sites.66583/ This way is working for all plesk editions the same way. --- dnsapi/dns_pleskxml.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index f5986827..0f7dc241 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -41,7 +41,7 @@ pleskxml_init_checks_done=0 NEWLINE='\ ' -pleskxml_tplt_get_domains="" +pleskxml_tplt_get_domains="" # Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh # Also used to test credentials and URI. # No params. @@ -375,7 +375,7 @@ _pleskxml_get_root_domain() { # Output will be one line per known domain, containing 2 tages and a single tag # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. - output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" + output="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" _debug 'Domains managed by Plesk server are (ignore the hacked output):' _debug "$output" 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 1703/2234] 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 1704/2234] 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 1705/2234] =?UTF-8?q?fix(notify)=EF=BC=9Aremove=20nofity,m?= =?UTF-8?q?ove=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 1706/2234] 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 1707/2234] 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 1708/2234] 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 1709/2234] 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 1710/2234] 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 1711/2234] 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 1712/2234] 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 1713/2234] 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 1714/2234] 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 1715/2234] 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 1716/2234] 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 1717/2234] 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 d6c68f1a843f28cb2a451890d07bee63d53b9e72 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Mon, 28 Mar 2022 13:03:02 +0200 Subject: [PATCH 1718/2234] Rename delete function, add info --- dnsapi/dns_selfhost.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index d5ecd278..d51608c9 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -54,9 +54,10 @@ dns_selfhost_add() { fi } -dns_acmedns_rm() { +dns_selfhost_rm() { domain=$1 txt=$2 _debug fulldomain "$domain" _debug txtvalue "$txt" + _info "Creating and removing of records is not supported by selfhost API, will not delete anything." } From fb5091a388c6cb4280cd095ab74056697be21a54 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 30 Mar 2022 22:47:12 +0800 Subject: [PATCH 1719/2234] 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 1720/2234] 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 1721/2234] 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 1722/2234] 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 1723/2234] 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 1724/2234] 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 1725/2234] 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 1727/2234] 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 1728/2234] 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 1729/2234] 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 1730/2234] 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 1731/2234] 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 1732/2234] 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 1733/2234] 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 1734/2234] 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 1735/2234] 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 1736/2234] 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 1737/2234] 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 1738/2234] 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 1739/2234] 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 1740/2234] 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 1741/2234] 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 1742/2234] 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 1743/2234] 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 1744/2234] 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 1745/2234] 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 1746/2234] 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 1747/2234] 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 1748/2234] 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 1749/2234] 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 1750/2234] 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 1751/2234] 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 1752/2234] 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 1753/2234] 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 96d45cc34162347b236a3cbb252aec3f4246bbe2 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Fri, 29 Apr 2022 22:23:39 +0200 Subject: [PATCH 1754/2234] Added variable checks --- dnsapi/dns_selfhost.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index d51608c9..601fca52 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -19,6 +19,11 @@ dns_selfhost_add() { SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readaccountconf_mutable SELFHOSTDNS_RID2)}" SELFHOSTDNS_LAST_SLOT="$(_readaccountconf_mutable SELFHOSTDNS_LAST_SLOT)" + if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then + _err "SELFHOSTDNS_USERNAME and SELFHOSTDNS_PASSWORD must be set" + return 1 + fi + if test -z "$SELFHOSTDNS_LAST_SLOT"; then SELFHOSTDNS_LAST_SLOT=1 fi @@ -41,6 +46,11 @@ dns_selfhost_add() { fi fi + if test -z "$rid"; then + _err "SELFHOSTDNS_RID and SELFHOSTDNS_RID2, or SELFHOSTDNS_MAP must be set" + return 1 + fi + _saveaccountconf_mutable SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" _info "Trying to add $txt on selfhost for rid: $rid" From 610c3cf6811f4f152b5959ee451eae1f6e3fb929 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Fri, 29 Apr 2022 22:26:36 +0200 Subject: [PATCH 1755/2234] Save domain dependent values in domain.conf after successfull use --- dnsapi/dns_selfhost.sh | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 601fca52..47e2f24c 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -12,12 +12,15 @@ dns_selfhost_add() { _debug txtvalue "$txt" SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl" + + # Get values, but don't save until we successfully validated SELFHOSTDNS_USERNAME="${SELFHOSTDNS_USERNAME:-$(_readaccountconf_mutable SELFHOSTDNS_USERNAME)}" SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" - SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readaccountconf_mutable SELFHOSTDNS_MAP)}" - SELFHOSTDNS_RID="${SELFHOSTDNS_RID:-$(_readaccountconf_mutable SELFHOSTDNS_RID)}" - SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readaccountconf_mutable SELFHOSTDNS_RID2)}" - SELFHOSTDNS_LAST_SLOT="$(_readaccountconf_mutable SELFHOSTDNS_LAST_SLOT)" + # These values are domain dependent, so read them from there + _getdeployconf SELFHOSTDNS_MAP + _getdeployconf SELFHOSTDNS_RID + _getdeployconf SELFHOSTDNS_RID2 + _getdeployconf SELFHOSTDNS_LAST_SLOT if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then _err "SELFHOSTDNS_USERNAME and SELFHOSTDNS_PASSWORD must be set" @@ -28,12 +31,6 @@ dns_selfhost_add() { SELFHOSTDNS_LAST_SLOT=1 fi - _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" - _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" - _saveaccountconf_mutable SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" - _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" - _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - rid=$(echo "$SELFHOSTDNS_MAP" | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") if test -z "$rid"; then @@ -51,8 +48,6 @@ dns_selfhost_add() { return 1 fi - _saveaccountconf_mutable SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" - _info "Trying to add $txt on selfhost for rid: $rid" data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt" @@ -62,6 +57,15 @@ dns_selfhost_add() { _err "Invalid response of acme-dns for selfhost" return 1 fi + + # Now that we know the values are good, save them + _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" + _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" + # These values are domain dependent, so store them there + _savedeployconf SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" + _savedeployconf SELFHOSTDNS_RID "$SELFHOSTDNS_RID" + _savedeployconf SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" + _savedeployconf SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" } dns_selfhost_rm() { From 1cbd5485e7d80fd184d3048972cc79e71ac1fffa Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Fri, 29 Apr 2022 22:53:36 +0200 Subject: [PATCH 1756/2234] Pseudo commit tp trigger Github Actions --- dnsapi/dns_selfhost.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 47e2f24c..33159c48 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -75,3 +75,4 @@ dns_selfhost_rm() { _debug txtvalue "$txt" _info "Creating and removing of records is not supported by selfhost API, will not delete anything." } + From 227eac10f1549f71e57e63721219cb8ba38e3062 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Fri, 29 Apr 2022 23:05:46 +0200 Subject: [PATCH 1757/2234] Fix shfmt --- dnsapi/dns_selfhost.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 33159c48..47e2f24c 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -75,4 +75,3 @@ dns_selfhost_rm() { _debug txtvalue "$txt" _info "Creating and removing of records is not supported by selfhost API, will not delete anything." } - From 24ce7c19914917b4c78c4e49a442f0f40cf258fd Mon Sep 17 00:00:00 2001 From: nicolaspn Date: Mon, 2 May 2022 15:46:49 +0200 Subject: [PATCH 1758/2234] 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 6aebaf6f47b0825cd8d6cc247214607ae7de25aa Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 5 Dec 2021 16:15:39 +0800 Subject: [PATCH 1759/2234] upgrade Solaris --- .github/workflows/Solaris.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index f8a3826c..567a22f9 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -40,7 +40,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.3 + - uses: vmactions/cf-tunnel@v0.0.4 id: tunnel with: protocol: http From 18de21f723605f4c8bc718dd1d126add2a47a205 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 13 Dec 2021 20:04:23 +0800 Subject: [PATCH 1760/2234] fix tunnel version --- .github/workflows/Solaris.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 567a22f9..f8a3826c 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -40,7 +40,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v2 - - uses: vmactions/cf-tunnel@v0.0.4 + - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: protocol: http From 3d312e2140652ad826617a4cdaa23626a0a9129c Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Wed, 5 Jan 2022 15:03:32 +0100 Subject: [PATCH 1761/2234] Added Selfhost DNS API +ShellCheck +ACME v2 compatible Example: - Fist create 2 new TXT records on _acme-challenge.example.com - Now note the ID in (...) from the edit page behind "_acme-challenge.example.com" export SELFHOSTDNS_USERNAME=myname export SELFHOSTDNS_PASSWORD=mypass export SELFHOSTDNS_RID=id_of_txt_record export SELFHOSTDNS_RID2=id_of_second_txt_record acme.sh --issue -d example.com --dns dns_selfhost --- dnsapi/dns_selfhost.sh | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 dnsapi/dns_selfhost.sh diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh new file mode 100644 index 00000000..d7dfcca4 --- /dev/null +++ b/dnsapi/dns_selfhost.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env sh +# +# Author: Marvin Edeler +# Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 + +dns_selfhost_add() { + domain=$1 + txt=$2 + _info "Calling acme-dns on selfhost" + _debug fulldomain "$domain" + _debug txtvalue "$txt" + + SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl" + SELFHOSTDNS_USERNAME="${SELFHOSTDNS_USERNAME:-$(_readaccountconf_mutable SELFHOSTDNS_USERNAME)}" + SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" + SELFHOSTDNS_RID="${SELFHOSTDNS_RID:-$(_readaccountconf_mutable SELFHOSTDNS_RID)}" + SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readaccountconf_mutable SELFHOSTDNS_RID2)}" + SELFHOSTDNS_LAST_SLOT="$(_readaccountconf_mutable SELFHOSTDNS_LAST_SLOT)" + + if test -z "$SELFHOSTDNS_LAST_SLOT"; then + SELFHOSTDNS_LAST_SLOT=1 + fi + + _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" + _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" + _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" + _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" + + if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then + rid=$SELFHOSTDNS_RID + SELFHOSTDNS_LAST_SLOT=1 + else + rid=$SELFHOSTDNS_RID2 + SELFHOSTDNS_LAST_SLOT=2 + fi + + _saveaccountconf_mutable SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" + + _info "Trying to add $txt on selfhost for rid: $rid" + + data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt" + response="$(_get "$SELFHOSTDNS_UPDATE_URL$data")" + + if ! echo "$response" | grep "200 OK" >/dev/null; then + _err "Invalid response of acme-dns for selfhost" + return 1 + fi +} + +dns_acmedns_rm() { + domain=$1 + txt=$2 + _debug fulldomain "$domain" + _debug txtvalue "$txt" +} From e717c9dba248f141c37b614a6c53b2d699ff3591 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Sun, 9 Jan 2022 11:04:15 +0100 Subject: [PATCH 1762/2234] Start ShellCheck and CI Test --- dnsapi/dns_selfhost.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index d7dfcca4..8c6e9a91 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -2,6 +2,7 @@ # # Author: Marvin Edeler # Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 +# Last Edit: 09.01.2022 dns_selfhost_add() { domain=$1 From 77d606df34590e0b36233d759f7f595ab42d16c5 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Thu, 17 Feb 2022 19:02:35 +0100 Subject: [PATCH 1763/2234] Add custom option to map multidomain RIDs --- dnsapi/dns_selfhost.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 8c6e9a91..1ebc6596 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -2,7 +2,7 @@ # # Author: Marvin Edeler # Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 -# Last Edit: 09.01.2022 +# Last Edit: 17.02.2022 dns_selfhost_add() { domain=$1 @@ -14,6 +14,7 @@ dns_selfhost_add() { SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl" SELFHOSTDNS_USERNAME="${SELFHOSTDNS_USERNAME:-$(_readaccountconf_mutable SELFHOSTDNS_USERNAME)}" SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" + SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readaccountconf_mutable SELFHOSTDNS_MAP)}" SELFHOSTDNS_RID="${SELFHOSTDNS_RID:-$(_readaccountconf_mutable SELFHOSTDNS_RID)}" SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readaccountconf_mutable SELFHOSTDNS_RID2)}" SELFHOSTDNS_LAST_SLOT="$(_readaccountconf_mutable SELFHOSTDNS_LAST_SLOT)" @@ -24,15 +25,19 @@ dns_selfhost_add() { _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" + _saveaccountconf_mutable SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then - rid=$SELFHOSTDNS_RID - SELFHOSTDNS_LAST_SLOT=1 - else - rid=$SELFHOSTDNS_RID2 - SELFHOSTDNS_LAST_SLOT=2 + rid=$(echo $SELFHOSTDNS_MAP | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") + if test -z "$rid"; then + if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then + rid=$SELFHOSTDNS_RID + SELFHOSTDNS_LAST_SLOT=1 + else + rid=$SELFHOSTDNS_RID2 + SELFHOSTDNS_LAST_SLOT=2 + fi fi _saveaccountconf_mutable SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" From c23c40df8a5c27fbe130afc007913ba3b312583c Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Thu, 17 Feb 2022 19:08:58 +0100 Subject: [PATCH 1764/2234] Fix shellcheck, use double quote --- dnsapi/dns_selfhost.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 1ebc6596..7ad92e20 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -29,7 +29,7 @@ dns_selfhost_add() { _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - rid=$(echo $SELFHOSTDNS_MAP | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") + rid=$(echo "$SELFHOSTDNS_MAP" | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") if test -z "$rid"; then if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then rid=$SELFHOSTDNS_RID From ef8cb11707e2c1351563ebddd10e22f1e4ce5935 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Thu, 17 Feb 2022 19:30:56 +0100 Subject: [PATCH 1765/2234] Fix shfmt --- dnsapi/dns_selfhost.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 7ad92e20..d5ecd278 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -29,7 +29,8 @@ dns_selfhost_add() { _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - rid=$(echo "$SELFHOSTDNS_MAP" | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") + rid=$(echo "$SELFHOSTDNS_MAP" | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") + if test -z "$rid"; then if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then rid=$SELFHOSTDNS_RID From 1054325b2dcd61ecdf55b2aad213f9878d38c530 Mon Sep 17 00:00:00 2001 From: Marvo2011 Date: Mon, 28 Mar 2022 13:03:02 +0200 Subject: [PATCH 1766/2234] Rename delete function, add info --- dnsapi/dns_selfhost.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index d5ecd278..d51608c9 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -54,9 +54,10 @@ dns_selfhost_add() { fi } -dns_acmedns_rm() { +dns_selfhost_rm() { domain=$1 txt=$2 _debug fulldomain "$domain" _debug txtvalue "$txt" + _info "Creating and removing of records is not supported by selfhost API, will not delete anything." } From 9bf37fde027dba6f03e7942a6398e50256d206e7 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Fri, 29 Apr 2022 22:23:39 +0200 Subject: [PATCH 1767/2234] Added variable checks --- dnsapi/dns_selfhost.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index d51608c9..601fca52 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -19,6 +19,11 @@ dns_selfhost_add() { SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readaccountconf_mutable SELFHOSTDNS_RID2)}" SELFHOSTDNS_LAST_SLOT="$(_readaccountconf_mutable SELFHOSTDNS_LAST_SLOT)" + if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then + _err "SELFHOSTDNS_USERNAME and SELFHOSTDNS_PASSWORD must be set" + return 1 + fi + if test -z "$SELFHOSTDNS_LAST_SLOT"; then SELFHOSTDNS_LAST_SLOT=1 fi @@ -41,6 +46,11 @@ dns_selfhost_add() { fi fi + if test -z "$rid"; then + _err "SELFHOSTDNS_RID and SELFHOSTDNS_RID2, or SELFHOSTDNS_MAP must be set" + return 1 + fi + _saveaccountconf_mutable SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" _info "Trying to add $txt on selfhost for rid: $rid" From b07e479840817af8adde56265c81e0267dc7f477 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Fri, 29 Apr 2022 22:26:36 +0200 Subject: [PATCH 1768/2234] Save domain dependent values in domain.conf after successfull use --- dnsapi/dns_selfhost.sh | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 601fca52..47e2f24c 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -12,12 +12,15 @@ dns_selfhost_add() { _debug txtvalue "$txt" SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl" + + # Get values, but don't save until we successfully validated SELFHOSTDNS_USERNAME="${SELFHOSTDNS_USERNAME:-$(_readaccountconf_mutable SELFHOSTDNS_USERNAME)}" SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" - SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readaccountconf_mutable SELFHOSTDNS_MAP)}" - SELFHOSTDNS_RID="${SELFHOSTDNS_RID:-$(_readaccountconf_mutable SELFHOSTDNS_RID)}" - SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readaccountconf_mutable SELFHOSTDNS_RID2)}" - SELFHOSTDNS_LAST_SLOT="$(_readaccountconf_mutable SELFHOSTDNS_LAST_SLOT)" + # These values are domain dependent, so read them from there + _getdeployconf SELFHOSTDNS_MAP + _getdeployconf SELFHOSTDNS_RID + _getdeployconf SELFHOSTDNS_RID2 + _getdeployconf SELFHOSTDNS_LAST_SLOT if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then _err "SELFHOSTDNS_USERNAME and SELFHOSTDNS_PASSWORD must be set" @@ -28,12 +31,6 @@ dns_selfhost_add() { SELFHOSTDNS_LAST_SLOT=1 fi - _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" - _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" - _saveaccountconf_mutable SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" - _saveaccountconf_mutable SELFHOSTDNS_RID "$SELFHOSTDNS_RID" - _saveaccountconf_mutable SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - rid=$(echo "$SELFHOSTDNS_MAP" | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") if test -z "$rid"; then @@ -51,8 +48,6 @@ dns_selfhost_add() { return 1 fi - _saveaccountconf_mutable SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" - _info "Trying to add $txt on selfhost for rid: $rid" data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt" @@ -62,6 +57,15 @@ dns_selfhost_add() { _err "Invalid response of acme-dns for selfhost" return 1 fi + + # Now that we know the values are good, save them + _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" + _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" + # These values are domain dependent, so store them there + _savedeployconf SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" + _savedeployconf SELFHOSTDNS_RID "$SELFHOSTDNS_RID" + _savedeployconf SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" + _savedeployconf SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" } dns_selfhost_rm() { From 199d846acba357f11908dfc4219668dca5e9a459 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Fri, 29 Apr 2022 22:53:36 +0200 Subject: [PATCH 1769/2234] Pseudo commit tp trigger Github Actions --- dnsapi/dns_selfhost.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 47e2f24c..33159c48 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -75,3 +75,4 @@ dns_selfhost_rm() { _debug txtvalue "$txt" _info "Creating and removing of records is not supported by selfhost API, will not delete anything." } + From fe3523f47a0f05173ac2b1ac1620cbc3c671e9da Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Fri, 29 Apr 2022 23:05:46 +0200 Subject: [PATCH 1770/2234] Fix shfmt --- dnsapi/dns_selfhost.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 33159c48..47e2f24c 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -75,4 +75,3 @@ dns_selfhost_rm() { _debug txtvalue "$txt" _info "Creating and removing of records is not supported by selfhost API, will not delete anything." } - From 64847afc3ff8cfe214aca7db7f793d96bee95e5e Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 3 May 2022 21:19:29 +0800 Subject: [PATCH 1771/2234] 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 1772/2234] 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 1773/2234] 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 1774/2234] 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 2cf72bad30766960149c7111495cf1e1af6e6883 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Tue, 10 May 2022 07:09:31 +0200 Subject: [PATCH 1775/2234] domain lookup for DNS_MAP changed. --- dnsapi/dns_selfhost.sh | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 47e2f24c..7fa685fa 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -4,11 +4,13 @@ # Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 # Last Edit: 17.02.2022 +DNS_CHALLENGE_PREFIX_ESCAPED="_acme-challenge\." + dns_selfhost_add() { - domain=$1 + fulldomain=$1 txt=$2 _info "Calling acme-dns on selfhost" - _debug fulldomain "$domain" + _debug fulldomain "$fulldomain" _debug txtvalue "$txt" SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl" @@ -31,7 +33,16 @@ dns_selfhost_add() { SELFHOSTDNS_LAST_SLOT=1 fi - rid=$(echo "$SELFHOSTDNS_MAP" | grep -Eoi "$domain:(\d+)" | tr -d "$domain:") + # cut DNS_CHALLENGE_PREFIX_ESCAPED from fulldomain if present at the beginning of the string + lookupdomain=$(echo "$fulldomain" | sed "s/^$DNS_CHALLENGE_PREFIX_ESCAPED//") + _debug lookupdomain "$lookupdomain" + + # get the RID for lookupdomain or fulldomain from SELFHOSTDNS_MAP + # only match full domains (at the beginning of the string or with a leading whitespace), + # e.g. don't match mytest.example.com or sub.test.example.com for test.example.com + # replace the whole string with the RID (matching group 3) for assignment + # if the domain is defined multiple times only the last occurance will be matched + rid=$(echo "$SELFHOSTDNS_MAP" | sed -n "s/\(^\|^.*\s\)\($lookupdomain:\|$fulldomain:\)\([0-9][0-9]*\)\(.*\)/\3/Ip") if test -z "$rid"; then if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then @@ -69,9 +80,9 @@ dns_selfhost_add() { } dns_selfhost_rm() { - domain=$1 + fulldomain=$1 txt=$2 - _debug fulldomain "$domain" + _debug fulldomain "$fulldomain" _debug txtvalue "$txt" _info "Creating and removing of records is not supported by selfhost API, will not delete anything." } From 619bae745b36e885072c7bbf29fb0e08f4577bf3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 9 May 2022 20:08:38 +0800 Subject: [PATCH 1776/2234] 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 1777/2234] 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 1778/2234] 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 1779/2234] 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 1780/2234] 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 1781/2234] Update callmebotWhatsApp.sh Added CallMeBot API for WhatsApp Notifications. --- notify/callmebotWhatsApp.sh | 65 ++++++++++++++----------------------- 1 file changed, 25 insertions(+), 40 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" + _saveaccountconf_mutable CallMeBot_Phone_No "$CallMeBot_Phone_No" - SLACK_CHANNEL="${SLACK_CHANNEL:-$(_readaccountconf_mutable SLACK_CHANNEL)}" - if [ -n "$SLACK_CHANNEL" ]; then - _saveaccountconf_mutable SLACK_CHANNEL "$SLACK_CHANNEL" + CallMeBot_apikey="${CallMeBot_apikey:-$(_readaccountconf_mutable CallMeBot_apikey)}" + 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")" - 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 + 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 1782/2234] 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 1783/2234] 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 1784/2234] 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 1785/2234] 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 1786/2234] 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 1787/2234] 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 1788/2234] 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 1789/2234] 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 1790/2234] 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 1791/2234] 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 1792/2234] 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 9fb5bb620d2ffa51eabb0354dfccc29ea9d88315 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:13:24 +0800 Subject: [PATCH 1793/2234] refact ssh hook to use deploy config --- acme.sh | 20 +++ deploy/ssh.sh | 434 +++++++++++++++++++++++--------------------------- 2 files changed, 220 insertions(+), 234 deletions(-) diff --git a/acme.sh b/acme.sh index 260733a2..37c625d2 100755 --- a/acme.sh +++ b/acme.sh @@ -2332,6 +2332,26 @@ _readdomainconf() { _read_conf "$DOMAIN_CONF" "$1" } +#_migratedomainconf oldkey newkey base64encode +_migratedomainconf() { + _old_key="$1" + _new_key="$2" + _b64encode="$3" + _value=$(_readdomainconf "$_old_key") + if [ -z "$_value" ]; then + return 1 # oldkey is not found + fi + _savedomainconf "$_new_key" "$_value" "$_b64encode" + _cleardomainconf "$_old_key" + _debug "Domain config $_old_key has been migrated to $_new_key" +} + +#_migratedeployconf oldkey newkey base64encode +_migratedeployconf() { + _migratedomainconf "$1" "SAVED_$2" "$3" || + _migratedomainconf "SAVED_$1" "SAVED_$2" "$3" # try only when oldkey itself is not found +} + #key value base64encode _savedeployconf() { _savedomainconf "SAVED_$1" "$2" "$3" diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 7d9e82e8..73d71597 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -23,8 +23,8 @@ # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value # export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy # export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value -# export DEPLOY_SSH_USE_SCP="" yes or no , default to no -# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -q " +# export DEPLOY_SSH_USE_SCP="" yes or no, default to no +# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -q" # ######## Public functions ##################### @@ -44,110 +44,134 @@ ssh_deploy() { _debug _cfullchain "$_cfullchain" # USER is required to login by SSH to remote host. + _migratedeployconf Le_Deploy_ssh_user DEPLOY_SSH_USER _getdeployconf DEPLOY_SSH_USER _debug2 DEPLOY_SSH_USER "$DEPLOY_SSH_USER" if [ -z "$DEPLOY_SSH_USER" ]; then - if [ -z "$Le_Deploy_ssh_user" ]; then - _err "DEPLOY_SSH_USER not defined." - return 1 - fi - else - Le_Deploy_ssh_user="$DEPLOY_SSH_USER" - _savedeployconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user" + _err "DEPLOY_SSH_USER not defined." + return 1 fi + _savedeployconf DEPLOY_SSH_USER "$DEPLOY_SSH_USER" # SERVER is optional. If not provided then use _cdomain + _migratedeployconf Le_Deploy_ssh_server DEPLOY_SSH_SERVER _getdeployconf DEPLOY_SSH_SERVER _debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER" - if [ -n "$DEPLOY_SSH_SERVER" ]; then - Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER" - _savedeployconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server" - elif [ -z "$Le_Deploy_ssh_server" ]; then - Le_Deploy_ssh_server="$_cdomain" + if [ -z "$DEPLOY_SSH_SERVER" ]; then + DEPLOY_SSH_SERVER="$_cdomain" fi + _savedeployconf DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER" # CMD is optional. If not provided then use ssh + _migratedeployconf Le_Deploy_ssh_cmd DEPLOY_SSH_CMD _getdeployconf DEPLOY_SSH_CMD _debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD" - if [ -n "$DEPLOY_SSH_CMD" ]; then - Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD" - _savedeployconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd" - elif [ -z "$Le_Deploy_ssh_cmd" ]; then - Le_Deploy_ssh_cmd="ssh -T" - fi - - # USE_SCP is optional. If not provided then default to previously saved - # value (which may be undefined... equivalent to "no"). - if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then - Le_Deploy_ssh_use_scp="yes" - _savedeployconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" - elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then - Le_Deploy_ssh_use_scp="" - _cleardomainconf Le_Deploy_ssh_use_scp - fi - - # SCP_CMD is optional. If not provided then use scp - if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then - Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" - _savedeployconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" - elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then - Le_Deploy_ssh_scp_cmd="scp -q" + if [ -z "$DEPLOY_SSH_CMD" ]; then + DEPLOY_SSH_CMD="ssh -T" fi + _savedeployconf DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD" # BACKUP is optional. If not provided then default to previously saved value or yes. + _migratedeployconf Le_Deploy_ssh_backup DEPLOY_SSH_BACKUP _getdeployconf DEPLOY_SSH_BACKUP _debug2 DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP" - if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then - Le_Deploy_ssh_backup="no" - elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then - Le_Deploy_ssh_backup="yes" + if [ -z "$DEPLOY_SSH_BACKUP" ]; then + DEPLOY_SSH_BACKUP="yes" fi - _savedeployconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" + _savedeployconf DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP" # BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy + _migratedeployconf Le_Deploy_ssh_backup_path DEPLOY_SSH_BACKUP_PATH _getdeployconf DEPLOY_SSH_BACKUP_PATH _debug2 DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH" - if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then - Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH" - elif [ -z "$Le_Deploy_ssh_backup_path" ]; then - Le_Deploy_ssh_backup_path=".acme_ssh_deploy" + if [ -z "$DEPLOY_SSH_BACKUP_PATH" ]; then + DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" fi - _savedeployconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path" + _savedeployconf DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH" # MULTI_CALL is optional. If not provided then default to previously saved # value (which may be undefined... equivalent to "no"). + _migratedeployconf Le_Deploy_ssh_multi_call DEPLOY_SSH_MULTI_CALL _getdeployconf DEPLOY_SSH_MULTI_CALL _debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL" - if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then - Le_Deploy_ssh_multi_call="yes" - _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" - elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then - Le_Deploy_ssh_multi_call="" - _cleardomainconf Le_Deploy_ssh_multi_call + if [ -z "$DEPLOY_SSH_MULTI_CALL" ]; then + DEPLOY_SSH_MULTI_CALL="no" + fi + _savedeployconf DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL" + + # KEYFILE is optional. + # If provided then private key will be copied to provided filename. + _migratedeployconf Le_Deploy_ssh_keyfile DEPLOY_SSH_KEYFILE + _getdeployconf DEPLOY_SSH_KEYFILE + _debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE" + if [ -n "$DEPLOY_SSH_KEYFILE" ]; then + _savedeployconf DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE" + fi + + # CERTFILE is optional. + # If provided then certificate will be copied or appended to provided filename. + _migratedeployconf Le_Deploy_ssh_certfile DEPLOY_SSH_CERTFILE + _getdeployconf DEPLOY_SSH_CERTFILE + _debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE" + if [ -n "$DEPLOY_SSH_CERTFILE" ]; then + _savedeployconf DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE" + fi + + # CAFILE is optional. + # If provided then CA intermediate certificate will be copied or appended to provided filename. + _migratedeployconf Le_Deploy_ssh_cafile DEPLOY_SSH_CAFILE + _getdeployconf DEPLOY_SSH_CAFILE + _debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE" + if [ -n "$DEPLOY_SSH_CAFILE" ]; then + _savedeployconf DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE" + fi + + # FULLCHAIN is optional. + # If provided then fullchain certificate will be copied or appended to provided filename. + _migratedeployconf Le_Deploy_ssh_fullchain DEPLOY_SSH_FULLCHAIN + _getdeployconf DEPLOY_SSH_FULLCHAIN + _debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN" + if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then + _savedeployconf DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN" + fi + + # REMOTE_CMD is optional. + # If provided then this command will be executed on remote host. + _migratedeployconf Le_Deploy_ssh_remote_cmd DEPLOY_SSH_REMOTE_CMD + _getdeployconf DEPLOY_SSH_REMOTE_CMD + _debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD" + if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then + _savedeployconf DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD" fi # USE_SCP is optional. If not provided then default to previously saved # value (which may be undefined... equivalent to "no"). - if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then - Le_Deploy_ssh_use_scp="yes" - _savedeployconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" - Le_Deploy_ssh_multi_call="yes" - _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" - elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then - Le_Deploy_ssh_use_scp="" - _cleardomainconf Le_Deploy_ssh_use_scp + _getdeployconf DEPLOY_SSH_USE_SCP + _debug2 DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP" + if [ -z "$DEPLOY_SSH_USE_SCP" ]; then + DEPLOY_SSH_USE_SCP="no" fi + _savedeployconf DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP" # SCP_CMD is optional. If not provided then use scp - if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then - Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" - _savedeployconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" - elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then - Le_Deploy_ssh_scp_cmd="scp -T -q " + _getdeployconf DEPLOY_SSH_SCP_CMD + _debug2 DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD" + if [ -z "$DEPLOY_SSH_SCP_CMD" ]; then + DEPLOY_SSH_SCP_CMD="scp -q" + fi + _savedeployconf DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD" + + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + DEPLOY_SSH_MULTI_CALL="yes" + _info "Using scp as alternate method for copying files. Multicall Mode is implicit" + elif [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then + _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" + else + _info "Required commands batched and sent in single call to remote host" fi - _deploy_ssh_servers=$Le_Deploy_ssh_server - for Le_Deploy_ssh_server in $_deploy_ssh_servers; do + _deploy_ssh_servers=$DEPLOY_SSH_SERVER + for DEPLOY_SSH_SERVER in $_deploy_ssh_servers; do _ssh_deploy done } @@ -161,20 +185,10 @@ _ssh_deploy() { _local_ca_file="" _local_full_file="" - _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - _info "Using scp as alternate method for copying files. Multicall Mode is implicit" - Le_Deploy_ssh_multi_call="yes" - _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" - fi - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" - else - _info "Required commands batched and sent in single call to remote host" - fi + _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$DEPLOY_SSH_SERVER" - if [ "$Le_Deploy_ssh_backup" = "yes" ]; then - _backupprefix="$Le_Deploy_ssh_backup_path/$_cdomain-backup" + if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then + _backupprefix="$DEPLOY_SSH_BACKUP_PATH/$_cdomain-backup" _backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')" # run cleanup on the backup directory, erase all older # than 180 days (15552000 seconds). @@ -186,7 +200,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _cmdstr="mkdir -p $_backupdir; $_cmdstr" _info "Backup of old certificate files will be placed in remote directory $_backupdir" _info "Backup directories erased after 180 days." - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -194,19 +208,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # KEYFILE is optional. - # If provided then private key will be copied to provided filename. - _getdeployconf DEPLOY_SSH_KEYFILE - _debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE" if [ -n "$DEPLOY_SSH_KEYFILE" ]; then - Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE" - _savedeployconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile" - fi - if [ -n "$Le_Deploy_ssh_keyfile" ]; then - if [ "$Le_Deploy_ssh_backup" = "yes" ]; then + if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then # backup file we are about to overwrite. - _cmdstr="$_cmdstr cp $Le_Deploy_ssh_keyfile $_backupdir >/dev/null;" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _cmdstr="$_cmdstr cp $DEPLOY_SSH_KEYFILE $_backupdir >/dev/null;" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -215,15 +221,16 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi # copy new key into file. - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then # scp the file - if ! _scp_remote_cmd "$_ckey" "$Le_Deploy_ssh_keyfile"; then + if ! _scp_remote_cmd "$_ckey" "$DEPLOY_SSH_KEYFILE"; then return $_err_code fi else - _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" - _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + # ssh echo to the file + _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $DEPLOY_SSH_KEYFILE;" + _info "will copy private key to remote file $DEPLOY_SSH_KEYFILE" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -232,48 +239,38 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # CERTFILE is optional. - # If provided then certificate will be copied or appended to provided filename. - _getdeployconf DEPLOY_SSH_CERTFILE - _debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE" if [ -n "$DEPLOY_SSH_CERTFILE" ]; then - Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE" - _savedeployconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile" - fi - if [ -n "$Le_Deploy_ssh_certfile" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_certfile" = "$Le_Deploy_ssh_keyfile" ]; then + if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then # if filename is same as previous file then append. _pipe=">>" + elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then + # backup file we are about to overwrite. + _cmdstr="$_cmdstr cp $DEPLOY_SSH_CERTFILE $_backupdir >/dev/null;" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi + fi + + # copy new certificate into file. + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + # scp the file _local_cert_file=$(_mktemp) - cat "$_ckey" >"$_local_cert_file" - cat "$_ccert" >>"$_local_cert_file" - elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then - # backup file we are about to overwrite. - _cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code - fi - _cmdstr="" + if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then + cat "$_ckey" >> "$_local_cert_file" fi - fi - - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if [ -n "$_local_cert_file" ]; then - if ! _scp_remote_cmd "$_local_cert_file" "$Le_Deploy_ssh_certfile"; then - return $_err_code - fi - else - if ! _scp_remote_cmd "$_ccert" "$Le_Deploy_ssh_certfile"; then - return $_err_code - fi + cat "$_ccert" >> "$_local_cert_file" + if ! _scp_remote_cmd "$_local_cert_file" "$DEPLOY_SSH_CERTFILE"; then + return $_err_code fi else - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" - _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + # ssh echo to the file + _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $DEPLOY_SSH_CERTFILE;" + _info "will copy certificate to remote file $DEPLOY_SSH_CERTFILE" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -282,56 +279,42 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # CAFILE is optional. - # If provided then CA intermediate certificate will be copied or appended to provided filename. - _getdeployconf DEPLOY_SSH_CAFILE - _debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE" if [ -n "$DEPLOY_SSH_CAFILE" ]; then - Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE" - _savedeployconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile" - fi - if [ -n "$Le_Deploy_ssh_cafile" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] || - [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then + if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ] || + [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then # if filename is same as previous file then append. _pipe=">>" + elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then + # backup file we are about to overwrite. + _cmdstr="$_cmdstr cp $DEPLOY_SSH_CAFILE $_backupdir >/dev/null;" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi + fi + + # copy new certificate into file. + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + # scp the file _local_ca_file=$(_mktemp) - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ]; then - cat "$_ckey" >>"$_local_ca_file" + if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ]; then + cat "$_ckey" >> "$_local_ca_file" fi - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then - cat "$_ccert" >>"$_local_ca_file" + if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then + cat "$_ccert" >> "$_local_ca_file" fi - cat "$_cca" >>"$_local_ca_file" - - elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then - # backup file we are about to overwrite. - _cmdstr="$_cmdstr cp $Le_Deploy_ssh_cafile $_backupdir >/dev/null;" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code - fi - _cmdstr="" - fi - fi - - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if [ -n "$_local_ca_file" ]; then - if ! _scp_remote_cmd "$_local_ca_file" "$Le_Deploy_ssh_cafile"; then - return $_err_code - fi - else - if ! _scp_remote_cmd "$_cca" "$Le_Deploy_ssh_cafile"; then - return $_err_code - fi + if ! _scp_remote_cmd "$_local_ca_file" "$DEPLOY_SSH_CAFILE"; then + return $_err_code fi else - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" - _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + # ssh echo to the file + _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $DEPLOY_SSH_CAFILE;" + _info "will copy CA file to remote file $DEPLOY_SSH_CAFILE" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -340,37 +323,17 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # FULLCHAIN is optional. - # If provided then fullchain certificate will be copied or appended to provided filename. - _getdeployconf DEPLOY_SSH_FULLCHAIN - _debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN" if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then - Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN" - _savedeployconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain" - fi - if [ -n "$Le_Deploy_ssh_fullchain" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] || - [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] || - [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then + if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ] || + [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ] || + [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then # if filename is same as previous file then append. _pipe=">>" - _local_full_file=$(_mktemp) - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ]; then - cat "$_ckey" >>"$_local_full_file" - fi - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ]; then - cat "$_ccert" >>"$_local_full_file" - fi - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then - cat "$_cca" >>"$_local_full_file" - fi - cat "$_cfullchain" >>"$_local_full_file" - - elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then + elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then # backup file we are about to overwrite. - _cmdstr="$_cmdstr cp $Le_Deploy_ssh_fullchain $_backupdir >/dev/null;" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _cmdstr="$_cmdstr cp $DEPLOY_SSH_FULLCHAIN $_backupdir >/dev/null;" + if [ "$DEPLOY_SSH_FULLCHAIN" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -378,21 +341,28 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if [ -n "$_local_full_file" ]; then - if ! _scp_remote_cmd "$_local_full_file" "$Le_Deploy_ssh_fullchain"; then - return $_err_code - fi - else - if ! _scp_remote_cmd "$_cfullchain" "$Le_Deploy_ssh_fullchain"; then - return $_err_code - fi + # copy new certificate into file. + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + # scp the file + _local_full_file=$(_mktemp) + if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ]; then + cat "$_ckey" >> "$_local_full_file" + fi + if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ]; then + cat "$_ccert" >> "$_local_full_file" + fi + if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then + cat "$_cca" >> "$_local_full_file" + fi + cat "$_cfullchain" >> "$_local_full_file" + if ! _scp_remote_cmd "$_local_full_file" "$DEPLOY_SSH_FULLCHAIN"; then + return $_err_code fi else - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" - _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + # ssh echo to the file + _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $DEPLOY_SSH_FULLCHAIN;" + _info "will copy fullchain to remote file $DEPLOY_SSH_FULLCHAIN" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -400,30 +370,22 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi fi + # cleanup local files if any - - if [ -n "$_local_cert_file" ]; then - rm "$_local_cert_file" >/dev/null 1>&2 + if [ -f "$_local_cert_file" ]; then + rm -f "$_local_cert_file" fi - if [ -n "$_local_ca_file" ]; then - rm "$_local_ca_file" >/dev/null 1>&2 + if [ -f "$_local_ca_file" ]; then + rm -f "$_local_ca_file" fi - if [ -n "$_local_full_file" ]; then - rm "$_local_full_file" >/dev/null 1>&2 + if [ -f "$_local_full_file" ]; then + rm -f "$_local_full_file" fi - # REMOTE_CMD is optional. - # If provided then this command will be executed on remote host. - _getdeployconf DEPLOY_SSH_REMOTE_CMD - _debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD" if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then - Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD" - _savedeployconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd" - fi - if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then - _cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;" - _info "Will execute remote command $Le_Deploy_ssh_remote_cmd" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _cmdstr="$_cmdstr $DEPLOY_SSH_REMOTE_CMD;" + _info "Will execute remote command $DEPLOY_SSH_REMOTE_CMD" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -445,10 +407,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _ssh_remote_cmd() { _cmd="$1" _secure_debug "Remote commands to execute: $_cmd" - _info "Submitting sequence of commands to remote server by ssh" + _info "Submitting sequence of commands to remote server by $DEPLOY_SSH_CMD" + # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 - $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'" + $DEPLOY_SSH_CMD "$DEPLOY_SSH_USER@$DEPLOY_SSH_SERVER" sh -c "'$_cmd'" _err_code="$?" if [ "$_err_code" != "0" ]; then @@ -460,9 +423,12 @@ _ssh_remote_cmd() { # cmd scp _scp_remote_cmd() { - _secure_debug "Remote scp source $1 and destination $2 using : $Le_Deploy_ssh_scp_cmd" - _info "Submitting secure copy command : $Le_Deploy_ssh_scp_cmd" - $Le_Deploy_ssh_scp_cmd "$1" "$Le_Deploy_ssh_user"@"$Le_Deploy_ssh_server":"$2" + _src=$1 + _dest=$2 + _secure_debug "Remote copy source $_src to destination $_dest using: $DEPLOY_SSH_SCP_CMD" + _info "Submitting secure copy command: $DEPLOY_SSH_SCP_CMD" + + $DEPLOY_SSH_SCP_CMD "$_src" "$DEPLOY_SSH_USER"@"$DEPLOY_SSH_SERVER":"$_dest" _err_code="$?" if [ "$_err_code" != "0" ]; then From c8929ca0cb13abb2213cd5da7abd9bd1b140af9a Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:29:19 +0800 Subject: [PATCH 1794/2234] support specifying port for each host --- deploy/ssh.sh | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 73d71597..2de0d325 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -14,7 +14,7 @@ # The following examples are for QNAP NAS running QTS 4.2 # export DEPLOY_SSH_CMD="" # defaults to "ssh -T" # export DEPLOY_SSH_USER="admin" # required -# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name +# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name, support multiple servers with optional port (eg. "host1 host2:8022") # export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem" @@ -185,7 +185,12 @@ _ssh_deploy() { _local_ca_file="" _local_full_file="" - _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$DEPLOY_SSH_SERVER" + case $DEPLOY_SSH_SERVER in + (*:*) _host=${DEPLOY_SSH_SERVER%:*} _port=${DEPLOY_SSH_SERVER##*:};; + (*) _host=$DEPLOY_SSH_SERVER _port=;; + esac + + _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$_host:$_port" if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then _backupprefix="$DEPLOY_SSH_BACKUP_PATH/$_cdomain-backup" @@ -406,12 +411,18 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d #cmd _ssh_remote_cmd() { _cmd="$1" + + _ssh_cmd="$DEPLOY_SSH_CMD" + if [ -n "$_port" ]; then + _ssh_cmd="$_ssh_cmd -p $_port" + fi + _secure_debug "Remote commands to execute: $_cmd" - _info "Submitting sequence of commands to remote server by $DEPLOY_SSH_CMD" + _info "Submitting sequence of commands to remote server by $_ssh_cmd" # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 - $DEPLOY_SSH_CMD "$DEPLOY_SSH_USER@$DEPLOY_SSH_SERVER" sh -c "'$_cmd'" + $_ssh_cmd "$DEPLOY_SSH_USER@$_host" sh -c "'$_cmd'" _err_code="$?" if [ "$_err_code" != "0" ]; then @@ -425,10 +436,16 @@ _ssh_remote_cmd() { _scp_remote_cmd() { _src=$1 _dest=$2 - _secure_debug "Remote copy source $_src to destination $_dest using: $DEPLOY_SSH_SCP_CMD" - _info "Submitting secure copy command: $DEPLOY_SSH_SCP_CMD" - $DEPLOY_SSH_SCP_CMD "$_src" "$DEPLOY_SSH_USER"@"$DEPLOY_SSH_SERVER":"$_dest" + _scp_cmd="$DEPLOY_SSH_SCP_CMD" + if [ -n "$_port" ]; then + _scp_cmd="$_scp_cmd -P $_port" + fi + + _secure_debug "Remote copy source $_src to destination $_dest" + _info "Submitting secure copy by $_scp_cmd" + + $_scp_cmd "$_src" "$DEPLOY_SSH_USER"@"$_host":"$_dest" _err_code="$?" if [ "$_err_code" != "0" ]; then From f90cbb636a101625b118fbdb57b64f7d4d0bdabb Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:41:59 +0800 Subject: [PATCH 1795/2234] fix format --- acme.sh | 2 +- deploy/ssh.sh | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/acme.sh b/acme.sh index 37c625d2..4366501b 100755 --- a/acme.sh +++ b/acme.sh @@ -2349,7 +2349,7 @@ _migratedomainconf() { #_migratedeployconf oldkey newkey base64encode _migratedeployconf() { _migratedomainconf "$1" "SAVED_$2" "$3" || - _migratedomainconf "SAVED_$1" "SAVED_$2" "$3" # try only when oldkey itself is not found + _migratedomainconf "SAVED_$1" "SAVED_$2" "$3" # try only when oldkey itself is not found } #key value base64encode diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 2de0d325..d40bba43 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -186,8 +186,8 @@ _ssh_deploy() { _local_full_file="" case $DEPLOY_SSH_SERVER in - (*:*) _host=${DEPLOY_SSH_SERVER%:*} _port=${DEPLOY_SSH_SERVER##*:};; - (*) _host=$DEPLOY_SSH_SERVER _port=;; + *:*) _host=${DEPLOY_SSH_SERVER%:*} _port=${DEPLOY_SSH_SERVER##*:};; + *) _host=$DEPLOY_SSH_SERVER _port=;; esac _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$_host:$_port" @@ -265,9 +265,9 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # scp the file _local_cert_file=$(_mktemp) if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then - cat "$_ckey" >> "$_local_cert_file" + cat "$_ckey" >>"$_local_cert_file" fi - cat "$_ccert" >> "$_local_cert_file" + cat "$_ccert" >>"$_local_cert_file" if ! _scp_remote_cmd "$_local_cert_file" "$DEPLOY_SSH_CERTFILE"; then return $_err_code fi @@ -306,10 +306,10 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # scp the file _local_ca_file=$(_mktemp) if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ]; then - cat "$_ckey" >> "$_local_ca_file" + cat "$_ckey" >>"$_local_ca_file" fi if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then - cat "$_ccert" >> "$_local_ca_file" + cat "$_ccert" >>"$_local_ca_file" fi cat "$_cca" >>"$_local_ca_file" if ! _scp_remote_cmd "$_local_ca_file" "$DEPLOY_SSH_CAFILE"; then @@ -351,15 +351,15 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # scp the file _local_full_file=$(_mktemp) if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ]; then - cat "$_ckey" >> "$_local_full_file" + cat "$_ckey" >>"$_local_full_file" fi if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ]; then - cat "$_ccert" >> "$_local_full_file" + cat "$_ccert" >>"$_local_full_file" fi if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then - cat "$_cca" >> "$_local_full_file" + cat "$_cca" >>"$_local_full_file" fi - cat "$_cfullchain" >> "$_local_full_file" + cat "$_cfullchain" >>"$_local_full_file" if ! _scp_remote_cmd "$_local_full_file" "$DEPLOY_SSH_FULLCHAIN"; then return $_err_code fi From 74f28021e701c53665774c4861d68863775bb206 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:49:40 +0800 Subject: [PATCH 1796/2234] fix format again --- deploy/ssh.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index d40bba43..074af84f 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -186,8 +186,14 @@ _ssh_deploy() { _local_full_file="" case $DEPLOY_SSH_SERVER in - *:*) _host=${DEPLOY_SSH_SERVER%:*} _port=${DEPLOY_SSH_SERVER##*:};; - *) _host=$DEPLOY_SSH_SERVER _port=;; + *:*) + _host=${DEPLOY_SSH_SERVER%:*} + _port=${DEPLOY_SSH_SERVER##*:} + ;; + *) + _host=$DEPLOY_SSH_SERVER + _port= + ;; esac _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$_host:$_port" From 3ce7d410c8ee18d4ed1049ccdc500a6624613df7 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:59:02 +0800 Subject: [PATCH 1797/2234] improve doc comments --- deploy/ssh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 074af84f..1aed7d3e 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -14,7 +14,7 @@ # The following examples are for QNAP NAS running QTS 4.2 # export DEPLOY_SSH_CMD="" # defaults to "ssh -T" # export DEPLOY_SSH_USER="admin" # required -# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name, support multiple servers with optional port (eg. "host1 host2:8022") +# export DEPLOY_SSH_SERVER="host1 host2:8022 192.168.0.1:9022" # defaults to domain name, support multiple servers with optional port # export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem" From 5ba2068fc22c0ec816e4f1ed09ba507c27f9455b Mon Sep 17 00:00:00 2001 From: Sebastiaan Hoogeveen Date: Mon, 16 May 2022 14:27:24 +0200 Subject: [PATCH 1798/2234] 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 d4cf03c9fd0c5dbfaf2292c0f5552382ee4640a0 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Wed, 18 May 2022 11:48:48 +0200 Subject: [PATCH 1799/2234] changes due to inkompabilities of some distros --- dnsapi/dns_selfhost.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 7fa685fa..b4284f51 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -42,7 +42,7 @@ dns_selfhost_add() { # e.g. don't match mytest.example.com or sub.test.example.com for test.example.com # replace the whole string with the RID (matching group 3) for assignment # if the domain is defined multiple times only the last occurance will be matched - rid=$(echo "$SELFHOSTDNS_MAP" | sed -n "s/\(^\|^.*\s\)\($lookupdomain:\|$fulldomain:\)\([0-9][0-9]*\)\(.*\)/\3/Ip") + rid=$(echo "$SELFHOSTDNS_MAP" | sed -E "s/(^|^.*[[:space:]])($lookupdomain:|$fulldomain:)([0-9][0-9]*)(.*)/\3/") if test -z "$rid"; then if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then From 4047adcc35eb66abbddff5a2ea8efa0b27ceb95b Mon Sep 17 00:00:00 2001 From: Sebastiaan Hoogeveen Date: Wed, 18 May 2022 16:12:37 +0200 Subject: [PATCH 1800/2234] 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 1801/2234] 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 1802/2234] 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 d2a9d731edbc5d6dcfc434560ba605bef9039ed2 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 24 May 2022 22:25:44 +0800 Subject: [PATCH 1803/2234] Update ssh.sh --- deploy/ssh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 1aed7d3e..c66e2e19 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -170,7 +170,7 @@ ssh_deploy() { _info "Required commands batched and sent in single call to remote host" fi - _deploy_ssh_servers=$DEPLOY_SSH_SERVER + _deploy_ssh_servers="$DEPLOY_SSH_SERVER" for DEPLOY_SSH_SERVER in $_deploy_ssh_servers; do _ssh_deploy done From 606e59a5d0a6b3fc1963aeae2b23898cb2715a8f Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 29 May 2022 14:56:30 +0800 Subject: [PATCH 1804/2234] 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 1805/2234] 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 1806/2234] 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 1807/2234] 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 1808/2234] 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 1809/2234] 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 1810/2234] 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 1811/2234] 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 1812/2234] 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 1813/2234] 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 1814/2234] 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 1815/2234] 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 c8d0d475e4f79f48877048fc6dfb45e1b28c5404 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 11 Jun 2022 13:49:31 -0400 Subject: [PATCH 1816/2234] deploy api script to upload certs to proxmox using proxmox api --- deploy/proxmoxve.sh | 123 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 deploy/proxmoxve.sh diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh new file mode 100644 index 00000000..8a5893b7 --- /dev/null +++ b/deploy/proxmoxve.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env bash + +# Deploy certificates to a proxmox virtual environment node using the API. +# +# Environment variables that can be set are: +# `DEPLOY_PROXMOXVE_SERVER`: The hostname of the proxmox ve node. Defaults to +# _cdomain. +# `DEPLOY_PROXMOXVE_SERVER_PORT`: The port number the management interface is on. +# Defaults to 8006. +# `DEPLOY_PROXMOXVE_NODE_NAME`: The name of the node we'll be connecting to. +# Defaults to the host portion of the server +# domain name. +# `DEPLOY_PROXMOXVE_USER`: The user we'll connect as. Defaults to root. +# `DEPLOY_PROXMOXVE_USER_REALM`: The authentication realm the user authenticates +# with. Defaults to pam. +# `DEPLOY_PROXMOXVE_API_TOKEN_NAME`: The name of the API token created for the +# user account. Defaults to acme. +# `DEPLOY_PROXMOXVE_API_TOKEN_KEY`: The API token. Required. + +proxmoxve_deploy(){ + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + # "Sane" defaults. + _target_hostname="$_cdomain" + if [ ! -z "$DEPLOY_PROXMOXVE_SERVER" ];then + _target_hostname="$DEPLOY_PROXMOXVE_SERVER" + fi + + _target_port="8006" + if [ ! -z "$DEPLOY_PROXMOXVE_SERVER_PORT" ];then + _target_port="$DEPLOY_PROXMOXVE_SERVER_PORT" + fi + + if [ ! -z "$DEPLOY_PROXMOXVE_NODE_NAME" ];then + _node_name="$DEPLOY_PROXMOXVE_NODE_NAME" + else + _node_name=$(echo "$_target_hostname"|cut -d. -f1) + fi + + # Complete URL. + _target_url="https://${_target_hostname}:${_target_port}/api2/json/nodes/${_node_name}/certificates/custom" + + # More "sane" defaults. + _proxmoxve_user="root" + if [ ! -z "$_proxmoxve_user" ];then + _proxmoxve_user="$DEPLOY_PROXMOXVE_USER" + fi + + _proxmoxve_user_realm="pam" + if [ ! -z "$DEPLOY_PROXMOXVE_USER_REALM" ];then + _proxmoxve_user_realm="$DEPLOY_PROXMOXVE_USER_REALM" + fi + + _proxmoxve_api_token_name="acme" + if [ ! -z "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" ];then + _proxmoxve_api_token_name="$DEPLOY_PROXMOXVE_API_TOKEN_NAME" + fi + + # This is required. + _proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY" + if [ -z "$_proxmoxve_api_token_key" ];then + _err "API key not provided." + return 1 + fi + + # PVE API Token header value. Used in "Authorization: PVEAPIToken". + _proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}" + + # Generate the data file curl will pass as the data. + _proxmoxve_temp_data="/tmp/proxmoxve_api/$_cdomain" + _proxmoxve_temp_data_file="$_proxmoxve_temp_data/body.json" + # We delete this directory at the end of the script to avoid any conflicts. + if [ ! -d "$_proxmoxve_temp_data" ];then + mkdir -p "$_proxmoxve_temp_data" + # Set to 700 since this file will contain the private key contents. + chmod 700 "$_proxmoxve_temp_data" + fi + # Ugly. I hate putting heredocs inside functions because heredocs don't account + # for whitespace correctly but it _does_ work and is several times cleaner + # than anything else I had here. + # + # This creates a temporary data file that curl will use as the data being + # posted to the webserver. + cat << HEREDOC > "$_proxmoxve_temp_data_file" +{ + "certificates": "$(cat $_cfullchain|tr '\n' ':'|sed 's/:/\\n/g')", + "key": "$(cat $_ckey|tr '\n' ':'|sed 's/:/\\n/g')", + "node":"$_node_name", + "restart":"1", + "force":"1" +} +HEREDOC + + # Push certificates to server. + # + # --insecure is to ignore certificate errors. + # --fail is to fail the script if the http return code is not 200. + if curl -X "POST" --header "Content-Type: application/json" \ + --header "Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" \ + --data "@${_proxmoxve_temp_data_file}" \ + --insecure --fail \ + "${_target_url}" + then + _info "Successfully updated certificate for $_cdomain." + rm -r "$_proxmoxve_temp_data" + return 0 + else + _err "Unable to update certificate for $_cdomain." + rm -r "$_proxmoxve_temp_data" + return 1 + fi + +} From 6652138d3e2965ddadfbfd9d385e98973f7a4cc0 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Tue, 14 Jun 2022 22:33:38 -0400 Subject: [PATCH 1817/2234] fixed per shellcheck's preference for `-n` instead of `! -z` --- deploy/proxmoxve.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 8a5893b7..c783d248 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -32,16 +32,16 @@ proxmoxve_deploy(){ # "Sane" defaults. _target_hostname="$_cdomain" - if [ ! -z "$DEPLOY_PROXMOXVE_SERVER" ];then + if [ -n "$DEPLOY_PROXMOXVE_SERVER" ];then _target_hostname="$DEPLOY_PROXMOXVE_SERVER" fi _target_port="8006" - if [ ! -z "$DEPLOY_PROXMOXVE_SERVER_PORT" ];then + if [ -n "$DEPLOY_PROXMOXVE_SERVER_PORT" ];then _target_port="$DEPLOY_PROXMOXVE_SERVER_PORT" fi - if [ ! -z "$DEPLOY_PROXMOXVE_NODE_NAME" ];then + if [ -n "$DEPLOY_PROXMOXVE_NODE_NAME" ];then _node_name="$DEPLOY_PROXMOXVE_NODE_NAME" else _node_name=$(echo "$_target_hostname"|cut -d. -f1) @@ -52,17 +52,17 @@ proxmoxve_deploy(){ # More "sane" defaults. _proxmoxve_user="root" - if [ ! -z "$_proxmoxve_user" ];then + if [ -n "$_proxmoxve_user" ];then _proxmoxve_user="$DEPLOY_PROXMOXVE_USER" fi _proxmoxve_user_realm="pam" - if [ ! -z "$DEPLOY_PROXMOXVE_USER_REALM" ];then + if [ -n "$DEPLOY_PROXMOXVE_USER_REALM" ];then _proxmoxve_user_realm="$DEPLOY_PROXMOXVE_USER_REALM" fi _proxmoxve_api_token_name="acme" - if [ ! -z "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" ];then + if [ -n "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" ];then _proxmoxve_api_token_name="$DEPLOY_PROXMOXVE_API_TOKEN_NAME" fi From 4351110082cd3cfc6a11891f4296bf5c32468da5 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Tue, 14 Jun 2022 22:38:06 -0400 Subject: [PATCH 1818/2234] properly quoted variable names --- deploy/proxmoxve.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index c783d248..664a04cd 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -93,8 +93,8 @@ proxmoxve_deploy(){ # posted to the webserver. cat << HEREDOC > "$_proxmoxve_temp_data_file" { - "certificates": "$(cat $_cfullchain|tr '\n' ':'|sed 's/:/\\n/g')", - "key": "$(cat $_ckey|tr '\n' ':'|sed 's/:/\\n/g')", + "certificates": "$(cat "$_cfullchain"|tr '\n' ':'|sed 's/:/\\n/g')", + "key": "$(cat "$_ckey"|tr '\n' ':'|sed 's/:/\\n/g')", "node":"$_node_name", "restart":"1", "force":"1" From 6d640982885c849172656ddcb68d01c98dbacea5 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Tue, 14 Jun 2022 23:46:09 -0400 Subject: [PATCH 1819/2234] shell check war warning against unnecessary use of cat --- deploy/proxmoxve.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 664a04cd..459c909a 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -93,8 +93,8 @@ proxmoxve_deploy(){ # posted to the webserver. cat << HEREDOC > "$_proxmoxve_temp_data_file" { - "certificates": "$(cat "$_cfullchain"|tr '\n' ':'|sed 's/:/\\n/g')", - "key": "$(cat "$_ckey"|tr '\n' ':'|sed 's/:/\\n/g')", + "certificates": "$(tr '\n' ':' < "$_cfullchain" | sed 's/:/\\n/g')", + "key": "$(tr '\n' ':' < "$_ckey" |sed 's/:/\\n/g')", "node":"$_node_name", "restart":"1", "force":"1" From 7be758697133b15cd4f8410df8e114252eeb4198 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Jun 2022 15:01:38 +0800 Subject: [PATCH 1820/2234] Update proxmoxve.sh --- deploy/proxmoxve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 459c909a..30f8b0b6 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # Deploy certificates to a proxmox virtual environment node using the API. # From 13c71829485aac03e1d0da98784ea50e983e73cd Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sat, 18 Jun 2022 17:32:56 +0200 Subject: [PATCH 1821/2234] Fix usage docs in file's header comment --- dnsapi/dns_artfiles.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 8e0a6151..2f8e158f 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -8,8 +8,8 @@ # Issues: https://github.com/Eagle3386/acme.sh/issues ################################################################################ # Usage: -# 1. export AF_API_Username="api12345678" -# 2. export AF_API_Password="apiPassword" +# 1. export AF_API_USERNAME="api12345678" +# 2. export AF_API_PASSWORD="apiPassword" # 3. acme.sh --issue -d example.com --dns dns_artfiles ################################################################################ From 5f3cb9019b6fa182837fe1f9c97f8e2106e86d9b Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 12:18:33 -0400 Subject: [PATCH 1822/2234] fixed to use _post function instead of curl --- deploy/proxmoxve.sh | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 459c909a..a7f11d20 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -85,13 +85,13 @@ proxmoxve_deploy(){ # Set to 700 since this file will contain the private key contents. chmod 700 "$_proxmoxve_temp_data" fi - # Ugly. I hate putting heredocs inside functions because heredocs don't account - # for whitespace correctly but it _does_ work and is several times cleaner - # than anything else I had here. + # Ugly. I hate putting heredocs inside functions because heredocs don't + # account for whitespace correctly but it _does_ work and is several times + # cleaner than anything else I had here. # - # This creates a temporary data file that curl will use as the data being - # posted to the webserver. - cat << HEREDOC > "$_proxmoxve_temp_data_file" + # This dumps the json payload to a variable that should be passable to the + # _psot function. + _json_payload=$(cat << HEREDOC { "certificates": "$(tr '\n' ':' < "$_cfullchain" | sed 's/:/\\n/g')", "key": "$(tr '\n' ':' < "$_ckey" |sed 's/:/\\n/g')", @@ -100,24 +100,10 @@ proxmoxve_deploy(){ "force":"1" } HEREDOC - +) # Push certificates to server. - # - # --insecure is to ignore certificate errors. - # --fail is to fail the script if the http return code is not 200. - if curl -X "POST" --header "Content-Type: application/json" \ - --header "Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" \ - --data "@${_proxmoxve_temp_data_file}" \ - --insecure --fail \ - "${_target_url}" - then - _info "Successfully updated certificate for $_cdomain." - rm -r "$_proxmoxve_temp_data" - return 0 - else - _err "Unable to update certificate for $_cdomain." - rm -r "$_proxmoxve_temp_data" - return 1 - fi + export _HTTPS_INSECURE=1 + export ="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" + _post "$_json_payload" "$_target_url" } From daffc4e6a4818da714ee73f4ed25a824b931f466 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 12:21:14 -0400 Subject: [PATCH 1823/2234] typo, using _H1 to provide header keys. --- deploy/proxmoxve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index a7f11d20..fafa3cb4 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -103,7 +103,7 @@ HEREDOC ) # Push certificates to server. export _HTTPS_INSECURE=1 - export ="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" + export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" _post "$_json_payload" "$_target_url" } From ca41ea2d5c792178d1f434ccfb0723825d139244 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 15:40:05 -0400 Subject: [PATCH 1824/2234] added _getdeployconf to set all of the environment variables --- deploy/proxmoxve.sh | 50 ++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index fafa3cb4..7cc0b850 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -31,50 +31,72 @@ proxmoxve_deploy(){ _debug _cfullchain "$_cfullchain" # "Sane" defaults. - _target_hostname="$_cdomain" - if [ -n "$DEPLOY_PROXMOXVE_SERVER" ];then + _getdeployconf DEPLOY_PROXMOXVE_SERVER + if [ -z "$DEPLOY_PROXMOXVE_SERVER" ]; then _target_hostname="$DEPLOY_PROXMOXVE_SERVER" + else + _target_hostname="$_cdomain" fi + _debug2 DEPLOY_PROXMOXVE_SERVER "$_target_hostname" - _target_port="8006" - if [ -n "$DEPLOY_PROXMOXVE_SERVER_PORT" ];then + _getdeployconf DEPLOY_PROXMOXVE_SERVER_PORT + if [ -z "$DEPLOY_PROXMOXVE_SERVER_PORT" ]; then + _target_port="8006" + else _target_port="$DEPLOY_PROXMOXVE_SERVER_PORT" fi + _debug2 DEPLOY_PROXMOXVE_SERVER_PORT "$_target_port" - if [ -n "$DEPLOY_PROXMOXVE_NODE_NAME" ];then - _node_name="$DEPLOY_PROXMOXVE_NODE_NAME" - else + _getdeployconf DEPLOY_PROXMOXVE_NODE_NAME + if [ -z "$DEPLOY_PROXMOXVE_NODE_NAME" ]; then _node_name=$(echo "$_target_hostname"|cut -d. -f1) + else + _node_name="$DEPLOY_PROXMOXVE_NODE_NAME" fi + _debug2 DEPLOY_PROXMOXVE_NODE_NAME "$_node_name" # Complete URL. _target_url="https://${_target_hostname}:${_target_port}/api2/json/nodes/${_node_name}/certificates/custom" + _debug TARGET_URL "$_target_url" # More "sane" defaults. - _proxmoxve_user="root" - if [ -n "$_proxmoxve_user" ];then + _getdeployconf DEPLOY_PROXMOXVE_USER + if [ -z "$DEPLOY_PROXMOXVE_USER" ]; then + _proxmoxve_user="root" + else _proxmoxve_user="$DEPLOY_PROXMOXVE_USER" fi + _debug2 DEPLOY_PROXMOXVE_NODE_NAME "$_proxmoxve_user" - _proxmoxve_user_realm="pam" - if [ -n "$DEPLOY_PROXMOXVE_USER_REALM" ];then + _getdeployconf DEPLOY_PROXMOXVE_USER_REALM + if [ -z "$DEPLOY_PROXMOXVE_USER_REALM" ]; then + _proxmoxve_user_realm="pam" + else _proxmoxve_user_realm="$DEPLOY_PROXMOXVE_USER_REALM" fi + _debug2 DEPLOY_PROXMOXVE_USER_REALM "$_proxmoxve_user_realm" - _proxmoxve_api_token_name="acme" - if [ -n "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" ];then + _getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME + if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" ]; then + _proxmoxve_api_token_name="acme" + else _proxmoxve_api_token_name="$DEPLOY_PROXMOXVE_API_TOKEN_NAME" fi + _debug2 DEPLOY_PROXMOXVE_API_TOKEN_NAME "$_proxmoxve_api_token_name" # This is required. - _proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY" + _getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY if [ -z "$_proxmoxve_api_token_key" ];then _err "API key not provided." return 1 + else + _proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY" fi + _debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY _proxmoxve_api_token_key # PVE API Token header value. Used in "Authorization: PVEAPIToken". _proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}" + _debug2 "Auth Header" _proxmoxve_header_api_token # Generate the data file curl will pass as the data. _proxmoxve_temp_data="/tmp/proxmoxve_api/$_cdomain" From 35cf98fff2e69c8afabce3f8444e1c94ed0f9da5 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 15:41:38 -0400 Subject: [PATCH 1825/2234] sensititive things debugged at a higher level --- deploy/proxmoxve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 7cc0b850..2c99ab9f 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -25,7 +25,7 @@ proxmoxve_deploy(){ _cfullchain="$5" _debug _cdomain "$_cdomain" - _debug _ckey "$_ckey" + _debug2 _ckey "$_ckey" _debug _ccert "$_ccert" _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" From 3cc283cbee2b3ac0997ee0b5a0c1793b0647efd8 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 15:44:25 -0400 Subject: [PATCH 1826/2234] not generating files any more --- deploy/proxmoxve.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 2c99ab9f..80be4a3c 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -98,15 +98,6 @@ proxmoxve_deploy(){ _proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}" _debug2 "Auth Header" _proxmoxve_header_api_token - # Generate the data file curl will pass as the data. - _proxmoxve_temp_data="/tmp/proxmoxve_api/$_cdomain" - _proxmoxve_temp_data_file="$_proxmoxve_temp_data/body.json" - # We delete this directory at the end of the script to avoid any conflicts. - if [ ! -d "$_proxmoxve_temp_data" ];then - mkdir -p "$_proxmoxve_temp_data" - # Set to 700 since this file will contain the private key contents. - chmod 700 "$_proxmoxve_temp_data" - fi # Ugly. I hate putting heredocs inside functions because heredocs don't # account for whitespace correctly but it _does_ work and is several times # cleaner than anything else I had here. From 37031721dd23db54900e7d9f0a20f00f7903b667 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 15:52:18 -0400 Subject: [PATCH 1827/2234] typo --- deploy/proxmoxve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 80be4a3c..b15f06df 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -86,7 +86,7 @@ proxmoxve_deploy(){ # This is required. _getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY - if [ -z "$_proxmoxve_api_token_key" ];then + if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" ];then _err "API key not provided." return 1 else From 76fe5d8831dbf0a8169f607430a3dd061971840d Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 16:39:32 -0400 Subject: [PATCH 1828/2234] those where flipped by mistake --- deploy/proxmoxve.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index b15f06df..2366b34d 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -33,9 +33,9 @@ proxmoxve_deploy(){ # "Sane" defaults. _getdeployconf DEPLOY_PROXMOXVE_SERVER if [ -z "$DEPLOY_PROXMOXVE_SERVER" ]; then - _target_hostname="$DEPLOY_PROXMOXVE_SERVER" - else _target_hostname="$_cdomain" + else + _target_hostname="$DEPLOY_PROXMOXVE_SERVER" fi _debug2 DEPLOY_PROXMOXVE_SERVER "$_target_hostname" From 7900c493af1d035a79c54c8ad429350d7acc8041 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 16:43:25 -0400 Subject: [PATCH 1829/2234] debugging for the payload --- deploy/proxmoxve.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 2366b34d..3b6a5a4e 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -114,6 +114,8 @@ proxmoxve_deploy(){ } HEREDOC ) + _debug2 Payload "$_json_payload" + # Push certificates to server. export _HTTPS_INSECURE=1 export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" From a5d5113be34bace02dc9370bed102187aa52e7fe Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 16:55:12 -0400 Subject: [PATCH 1830/2234] seems like the escaped new lines aren't remaining escaped new lines with the new version of curl --- deploy/proxmoxve.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 3b6a5a4e..9b01b7c0 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -107,7 +107,7 @@ proxmoxve_deploy(){ _json_payload=$(cat << HEREDOC { "certificates": "$(tr '\n' ':' < "$_cfullchain" | sed 's/:/\\n/g')", - "key": "$(tr '\n' ':' < "$_ckey" |sed 's/:/\\n/g')", + "key": "$(tr '\n' ':' < "$_ckey" |sed 's/:/\\\n/g')", "node":"$_node_name", "restart":"1", "force":"1" @@ -115,7 +115,7 @@ proxmoxve_deploy(){ HEREDOC ) _debug2 Payload "$_json_payload" - + # Push certificates to server. export _HTTPS_INSECURE=1 export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" From 4e625c18dc233a77517bb4be830acc0924972ce0 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 16:56:46 -0400 Subject: [PATCH 1831/2234] Revert "seems like the escaped new lines aren't remaining escaped new lines with the new version of curl" This reverts commit a5d5113be34bace02dc9370bed102187aa52e7fe. --- deploy/proxmoxve.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 9b01b7c0..3b6a5a4e 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -107,7 +107,7 @@ proxmoxve_deploy(){ _json_payload=$(cat << HEREDOC { "certificates": "$(tr '\n' ':' < "$_cfullchain" | sed 's/:/\\n/g')", - "key": "$(tr '\n' ':' < "$_ckey" |sed 's/:/\\\n/g')", + "key": "$(tr '\n' ':' < "$_ckey" |sed 's/:/\\n/g')", "node":"$_node_name", "restart":"1", "force":"1" @@ -115,7 +115,7 @@ proxmoxve_deploy(){ HEREDOC ) _debug2 Payload "$_json_payload" - + # Push certificates to server. export _HTTPS_INSECURE=1 export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" From 149310e1ecdec3343757296cab9ebf6975693d5d Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 16:58:15 -0400 Subject: [PATCH 1832/2234] '+' are being converted to ' ' at some point --- deploy/proxmoxve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 3b6a5a4e..a7123bf1 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -106,7 +106,7 @@ proxmoxve_deploy(){ # _psot function. _json_payload=$(cat << HEREDOC { - "certificates": "$(tr '\n' ':' < "$_cfullchain" | sed 's/:/\\n/g')", + "certificates": "$(tr '\n' ':' < "$_cfullchain" | sed 's/:/\\n/g' -e 's/+/\+/g')", "key": "$(tr '\n' ':' < "$_ckey" |sed 's/:/\\n/g')", "node":"$_node_name", "restart":"1", From c0da80158005bb40f793f639c12a2d604dbddb7e Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sat, 18 Jun 2022 17:00:36 -0400 Subject: [PATCH 1833/2234] Revert "'+' are being converted to ' ' at some point" This reverts commit 149310e1ecdec3343757296cab9ebf6975693d5d. --- deploy/proxmoxve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index a7123bf1..3b6a5a4e 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -106,7 +106,7 @@ proxmoxve_deploy(){ # _psot function. _json_payload=$(cat << HEREDOC { - "certificates": "$(tr '\n' ':' < "$_cfullchain" | sed 's/:/\\n/g' -e 's/+/\+/g')", + "certificates": "$(tr '\n' ':' < "$_cfullchain" | sed 's/:/\\n/g')", "key": "$(tr '\n' ':' < "$_ckey" |sed 's/:/\\n/g')", "node":"$_node_name", "restart":"1", From b876128635542d12e7214619994bf1c1947c7fc5 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sun, 19 Jun 2022 01:46:10 -0400 Subject: [PATCH 1834/2234] forced content-type to json --- deploy/proxmoxve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 3b6a5a4e..f003d2b6 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -119,6 +119,6 @@ HEREDOC # Push certificates to server. export _HTTPS_INSECURE=1 export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" - _post "$_json_payload" "$_target_url" + _post "$_json_payload" "$_target_url" "" POST "application/json" } From b3b4811b2c4b9fa875d4744da6152422f55d1c20 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Sun, 19 Jun 2022 22:01:56 -0400 Subject: [PATCH 1835/2234] added savedeployconf to preserve environment variables usedi in initial deployments --- deploy/proxmoxve.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 5f44a147..40012c75 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -36,6 +36,7 @@ proxmoxve_deploy(){ _target_hostname="$_cdomain" else _target_hostname="$DEPLOY_PROXMOXVE_SERVER" + _savedeployconf DEPLOY_PROXMOXVE_SERVER "$DEPLOY_PROXMOXVE_SERVER" fi _debug2 DEPLOY_PROXMOXVE_SERVER "$_target_hostname" @@ -44,6 +45,7 @@ proxmoxve_deploy(){ _target_port="8006" else _target_port="$DEPLOY_PROXMOXVE_SERVER_PORT" + _savedeployconf DEPLOY_PROXMOXVE_SERVER_PORT "$DEPLOY_PROXMOXVE_SERVER_PORT" fi _debug2 DEPLOY_PROXMOXVE_SERVER_PORT "$_target_port" @@ -52,6 +54,7 @@ proxmoxve_deploy(){ _node_name=$(echo "$_target_hostname"|cut -d. -f1) else _node_name="$DEPLOY_PROXMOXVE_NODE_NAME" + _savedeployconf DEPLOY_PROXMOXVE_NODE_NAME "$DEPLOY_PROXMOXVE_NODE_NAME" fi _debug2 DEPLOY_PROXMOXVE_NODE_NAME "$_node_name" @@ -65,14 +68,16 @@ proxmoxve_deploy(){ _proxmoxve_user="root" else _proxmoxve_user="$DEPLOY_PROXMOXVE_USER" + _savedeployconf DEPLOY_PROXMOXVE_USER "$DEPLOY_PROXMOXVE_USER" fi - _debug2 DEPLOY_PROXMOXVE_NODE_NAME "$_proxmoxve_user" + _debug2 DEPLOY_PROXMOXVE_USER "$_proxmoxve_user" _getdeployconf DEPLOY_PROXMOXVE_USER_REALM if [ -z "$DEPLOY_PROXMOXVE_USER_REALM" ]; then _proxmoxve_user_realm="pam" else _proxmoxve_user_realm="$DEPLOY_PROXMOXVE_USER_REALM" + _savedeployconf DEPLOY_PROXMOXVE_USER_REALM "$DEPLOY_PROXMOXVE_USER_REALMz" fi _debug2 DEPLOY_PROXMOXVE_USER_REALM "$_proxmoxve_user_realm" @@ -81,6 +86,7 @@ proxmoxve_deploy(){ _proxmoxve_api_token_name="acme" else _proxmoxve_api_token_name="$DEPLOY_PROXMOXVE_API_TOKEN_NAME" + _savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" fi _debug2 DEPLOY_PROXMOXVE_API_TOKEN_NAME "$_proxmoxve_api_token_name" @@ -91,6 +97,7 @@ proxmoxve_deploy(){ return 1 else _proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY" + _savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" fi _debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY _proxmoxve_api_token_key From 6ccf617d62f1d73dc9fa2afbea8ca080be294194 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 21 Jun 2022 10:12:06 +0800 Subject: [PATCH 1836/2234] 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" From 095697900b94e05f3ba8176c53632d6d3a7769e0 Mon Sep 17 00:00:00 2001 From: Marcel Hellkamp Date: Wed, 22 Jun 2022 17:54:49 +0200 Subject: [PATCH 1837/2234] fix: Challenge not skipped for pre-validated wildcard domain orders Some CAs auto-validate orders based on account-level rules and do not require a challenge at all. Sectigo introduced a non-standard challenges named 'sectigo-dns-01', presumably to work around this issue in certbot. This also works for non-wildcard domains in acme.sh, but wildcard domains are rejected because acme.sh hard-codes 'dns-01' as the only allowed challenge for wildcard domains, which is not offered by Sectigo. This change simply moves the '"status":"valid"' check up a bit and ignores challenge type mismatches or missing tokens if no challenge is needed anyway. --- acme.sh | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/acme.sh b/acme.sh index 260733a2..3210efd6 100755 --- a/acme.sh +++ b/acme.sh @@ -4600,28 +4600,26 @@ $_authorizations_map" thumbprint="$(__calc_account_thumbprint)" fi + keyauthorization="" + + if echo "$response" | grep '"status":"valid"' >/dev/null 2>&1; then + _debug "$d is already valid." + keyauthorization="$STATE_VERIFIED" + _debug keyauthorization "$keyauthorization" + fi + entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" - keyauthorization="" - if [ -z "$entry" ]; then - if ! _startswith "$d" '*.'; then - _debug "Not a wildcard domain, lets check whether the validation is already valid." - if echo "$response" | grep '"status":"valid"' >/dev/null 2>&1; then - _debug "$d is already valid." - keyauthorization="$STATE_VERIFIED" - _debug keyauthorization "$keyauthorization" - fi - fi - if [ -z "$keyauthorization" ]; then - _err "Error, can not get domain token entry $d for $vtype" - _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" - if [ "$_supported_vtypes" ]; then - _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" - fi - _clearup - _on_issue_err "$_post_hook" - return 1 + + if [ -z "$keyauthorization" -a -z "$entry" ]; then + _err "Error, can not get domain token entry $d for $vtype" + _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" + if [ "$_supported_vtypes" ]; then + _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" fi + _clearup + _on_issue_err "$_post_hook" + return 1 fi if [ -z "$keyauthorization" ]; then @@ -4647,12 +4645,6 @@ $_authorizations_map" fi keyauthorization="$token.$thumbprint" _debug keyauthorization "$keyauthorization" - - if printf "%s" "$response" | grep '"status":"valid"' >/dev/null 2>&1; then - _debug "$d is already verified." - keyauthorization="$STATE_VERIFIED" - _debug keyauthorization "$keyauthorization" - fi fi dvlist="$d$sep$keyauthorization$sep$uri$sep$vtype$sep$_currentRoot" From 688a2341273df7c6efda960fcc854c3697805786 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Wed, 22 Jun 2022 18:56:25 +0200 Subject: [PATCH 1838/2234] Added new 'dns' provider script for https://dns.services --- dnsapi/dns_dnsservices.sh | 239 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100755 dnsapi/dns_dnsservices.sh diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh new file mode 100755 index 00000000..d5654793 --- /dev/null +++ b/dnsapi/dns_dnsservices.sh @@ -0,0 +1,239 @@ +#!/usr/bin/env sh + +#This file name is "dns_dnsservices.sh" +#Script for Danish DNS registra and DNS hosting provider https://dns.services +# +#Author: Bjarke Bruun +#Report Bugs here: https://github.com/bbruun/acme.sh + +# Global variable to connect to the DNS Services API +DNSServices_API=https://dns.services/api + +######## Public functions ##################### + +#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_dnsservices_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Using dns.services to create ACME DNS challenge" + _debug2 add_fulldomain "$fulldomain" + _debug2 add_txtvalue "$txtvalue" + + # Read username/password from environment or .acme.sh/accounts.conf + DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" + DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" + if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then + DnsServices_Username="" + DnsServices_Password="" + _err "You didn't specify dns.services api username and password yet." + _err "Set environment variables DnsServices_Username and DnsServices_Password" + return 1 + fi + + # Setup GET/POST/DELETE headers + _setup_headers + + #save the credentials to the account conf file. + _saveaccountconf_mutable DnsServices_Username "$DnsServices_Username" + _saveaccountconf_mutable DnsServices_Password "$DnsServices_Password" + + if ! _contains "$DnsServices_Username" "@"; then + _err "It seems that the username variable DnsServices_Username has not been set/left blank" + _err "or is not a valid email. Please correct and try again." + return 1 + fi + + if ! _get_root "${fulldomain}"; then + _err "Invalid domain ${fulldomain}" + return 1 + fi + + if ! createRecord "$fulldomain" "${txtvalue}"; then + _err "Error creating TXT record in domain $fulldomain in $rootZoneName" + return 1 + fi + + _debug2 challenge-created "Created $fulldomain" + return 0 +} + +#Usage: fulldomain txtvalue +#Description: Remove the txt record after validation. +dns_dnsservices_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Using dns.services to delete challenge $fulldomain TXT $txtvalue" + _debug rm_fulldomain "$fulldomain" + _debug rm_txtvalue "$txtvalue" + + # Read username/password from environment or .acme.sh/accounts.conf + DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" + DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" + if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then + DnsServices_Username="" + DnsServices_Password="" + _err "You didn't specify dns.services api username and password yet." + _err "Set environment variables DnsServices_Username and DnsServices_Password" + return 1 + fi + + # Setup GET/POST/DELETE headers + _setup_headers + + if ! _get_root "${fulldomain}"; then + _err "Invalid domain ${fulldomain}" + return 1 + fi + + _debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain" + + if ! deleteRecord "${fulldomain}" "${txtvalue}"; then + _err "Error removing record: $fulldomain TXT ${txtvalue}" + return 1 + fi + + return 0 +} + +#################### Private functions below ################################## + +_setup_headers() { + # Set up API Headers for _get() and _post() + # The _add or _rm must have been called before to work + + if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then + _err "Could not setup BASIC authentication headers, they are missing" + return 1 + fi + + DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)" + export _H1="Authorization: Basic $DnsServiceCredentials" + export _H2="Content-Type: application/json" + + # Just return if headers are set + return 0 +} + +_get_root() { + domain=$1 + _debug2 _get_root "Get the root domain of ${domain} for DNS API" + + # Setup _get() and _post() headers + #_setup_headers + + result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns") + _debug2 _get_root "Got the following root domain(s) $result" + _debug2 _get_root "- JSON: $result" + + if [ "$(echo "$result" | grep -c '"name"')" -gt "1" ]; then + checkMultiZones="true" + _debug2 _get_root "- multiple zones found" + else + checkMultiZones="false" + + fi + + # Find/isolate the root zone to work with in createRecord() and deleteRecord() + rootZone="" + if [ "$checkMultiZones" == "true" ]; then + rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do + if [[ "$zone" =~ "$domain" ]]; then + _debug2 _get_root "- trying to figure out if $zone is in $domain" + echo "$zone" + break + fi + done) + else + rootZone=$(echo "$result" | grep -o '"name":"[^"]*' | cut -d'"' -f4) + _debug2 _get_root "- only found 1 domain in API: $rootZone" + fi + + if [ -z "$rootZone" ]; then + _err "Could not find root domain for $domain - is it correctly typed?" + return 1 + fi + + # Setup variables used by other functions to communicate with DNS Services API + zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") + rootZoneName="$rootZone" + subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")" + subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")" + rootZoneDomainID=$(echo "$zoneInfo" | tr ',' '\n' | grep domain_id | cut -d'"' -f4) + rootZoneServiceID=$(echo "$zoneInfo" | tr ',' '\n' | grep service_id | cut -d'"' -f4) + + _debug2 _get_root "Root zone name : $rootZoneName" + _debug2 _get_root "Root zone domain ID : $rootZoneDomainID" + _debug2 _get_root "Root zone service ID: $rootZoneServiceID" + _debug2 _get_root "Sub domain : $subDomainName" + + _debug _get_root "Found valid root domain $rootZone for $subDomainNameClean" + return 0 + +} + +createRecord() { + fulldomain=$1 + txtvalue="$2" + + # Get root domain information - needed for DNS Services API communication + if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then + _get_root $fulldomain + fi + + _debug2 createRecord "CNAME TXT value is: $txtvalue" + + # Prepare data to send to API + data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}" + + _debug2 createRecord "data to API: $data" + result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST") + _debug2 createRecord "result from API: $result" + + if [ "$(echo "$result" | grep '"success":true')" == "" ]; then + _err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName" + _err "$result" + return 1 + fi + + _info "Record \"$fulldomain TXT $txtvalue\" has been created" + return 0 + +} + +deleteRecord() { + fulldomain=$1 + txtvalue=$2 + + if [[ ! "$fulldomain" =~ "_acme-challenge" ]]; then + _err "The script tried to delete the record $fulldomain which is not the above created ACME challenge" + return 1 + fi + + _debug2 deleteRecord "Deleting $fulldomain TXT $txtvalue record" + + if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then + _get_root $fulldomain + fi + + result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" + recordInfo="$(echo "$result" | tr '}' '\n' | grep "\"name\":\"${fulldomain}" | grep "\"content\":\"" | grep "${txtvalue}")" + _debug2 deleteRecord "recordInfo=$recordInfo" + recordID="$(echo "$recordInfo" | tr ',' '\n' | egrep "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" + + if [ -z "$recordID" ]; then + _info "Record $fulldomain TXT $txtvalue not found or already deleted" + return 0 + else + _debug2 deleteRecord "Found recordID=$recordID" + fi + + _debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" + result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")" + _debug2 deleteRecord "API Delete result \"$result\"" + + # Return OK regardless + return 0 + +} From 799f509ba9f90e6a6d5b84eaf1d7c6d9730cdbd6 Mon Sep 17 00:00:00 2001 From: William Sellitti Date: Wed, 22 Jun 2022 23:19:12 -0400 Subject: [PATCH 1839/2234] typo --- deploy/proxmoxve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 40012c75..c156b3a3 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -77,7 +77,7 @@ proxmoxve_deploy(){ _proxmoxve_user_realm="pam" else _proxmoxve_user_realm="$DEPLOY_PROXMOXVE_USER_REALM" - _savedeployconf DEPLOY_PROXMOXVE_USER_REALM "$DEPLOY_PROXMOXVE_USER_REALMz" + _savedeployconf DEPLOY_PROXMOXVE_USER_REALM "$DEPLOY_PROXMOXVE_USER_REALM" fi _debug2 DEPLOY_PROXMOXVE_USER_REALM "$_proxmoxve_user_realm" From d6eebf82bea04335c9cc98b9e98b8080f59aa33e Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 23 Jun 2022 07:57:05 +0200 Subject: [PATCH 1840/2234] Removed a few empty lines --- dnsapi/dns_dnsservices.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index d5654793..1869bf65 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -170,7 +170,6 @@ _get_root() { _debug _get_root "Found valid root domain $rootZone for $subDomainNameClean" return 0 - } createRecord() { @@ -199,7 +198,6 @@ createRecord() { _info "Record \"$fulldomain TXT $txtvalue\" has been created" return 0 - } deleteRecord() { @@ -235,5 +233,4 @@ deleteRecord() { # Return OK regardless return 0 - } From dc882e6279783efd8b6f3afa99093feff27fb56d Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 23 Jun 2022 08:06:28 +0200 Subject: [PATCH 1841/2234] Removed empty space --- dnsapi/dns_dnsservices.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 1869bf65..f49d8328 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -11,7 +11,7 @@ DNSServices_API=https://dns.services/api ######## Public functions ##################### -#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dnsservices_add() { fulldomain=$1 txtvalue=$2 From 668894fc4d1b2e7b8af4db57a6e5c454f05bfda5 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 23 Jun 2022 14:08:24 +0800 Subject: [PATCH 1842/2234] Update proxmoxve.sh --- deploy/proxmoxve.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index c156b3a3..91f02e10 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -51,7 +51,7 @@ proxmoxve_deploy(){ _getdeployconf DEPLOY_PROXMOXVE_NODE_NAME if [ -z "$DEPLOY_PROXMOXVE_NODE_NAME" ]; then - _node_name=$(echo "$_target_hostname"|cut -d. -f1) + _node_name=$(echo "$_target_hostname" | cut -d. -f1) else _node_name="$DEPLOY_PROXMOXVE_NODE_NAME" _savedeployconf DEPLOY_PROXMOXVE_NODE_NAME "$DEPLOY_PROXMOXVE_NODE_NAME" @@ -92,7 +92,7 @@ proxmoxve_deploy(){ # This is required. _getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY - if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" ];then + if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" ]; then _err "API key not provided." return 1 else @@ -111,7 +111,8 @@ proxmoxve_deploy(){ # # This dumps the json payload to a variable that should be passable to the # _psot function. - _json_payload=$(cat << HEREDOC + _json_payload=$( + cat << HEREDOC { "certificates": "$(tr '\n' ':' < "$_cfullchain" | sed 's/:/\\n/g')", "key": "$(tr '\n' ':' < "$_ckey" |sed 's/:/\\n/g')", @@ -120,9 +121,9 @@ proxmoxve_deploy(){ "force":"1" } HEREDOC -) + ) _debug2 Payload "$_json_payload" - + # Push certificates to server. export _HTTPS_INSECURE=1 export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" From a386826808ae7e7dd2191c8f73ca716cf108067d Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 23 Jun 2022 14:11:36 +0800 Subject: [PATCH 1843/2234] Update proxmoxve.sh --- deploy/proxmoxve.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 91f02e10..742c977d 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -17,7 +17,7 @@ # user account. Defaults to acme. # `DEPLOY_PROXMOXVE_API_TOKEN_KEY`: The API token. Required. -proxmoxve_deploy(){ +proxmoxve_deploy() { _cdomain="$1" _ckey="$2" _ccert="$3" @@ -112,10 +112,10 @@ proxmoxve_deploy(){ # This dumps the json payload to a variable that should be passable to the # _psot function. _json_payload=$( - cat << HEREDOC + cat < Date: Thu, 23 Jun 2022 14:12:53 +0800 Subject: [PATCH 1844/2234] Update proxmoxve.sh --- deploy/proxmoxve.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 742c977d..216a8fc7 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -115,7 +115,7 @@ proxmoxve_deploy() { cat < Date: Thu, 23 Jun 2022 08:31:40 +0200 Subject: [PATCH 1845/2234] Code formatting (shfmt) --- dnsapi/dns_dnsservices.sh | 330 +++++++++++++++++++------------------- 1 file changed, 165 insertions(+), 165 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index f49d8328..a131a165 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh #This file name is "dns_dnsservices.sh" -#Script for Danish DNS registra and DNS hosting provider https://dns.services +#Script for Danish DNS registra and DNS hosting provider https://dns.services # #Author: Bjarke Bruun #Report Bugs here: https://github.com/bbruun/acme.sh @@ -13,224 +13,224 @@ DNSServices_API=https://dns.services/api #Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dnsservices_add() { - fulldomain=$1 - txtvalue=$2 + fulldomain=$1 + txtvalue=$2 - _info "Using dns.services to create ACME DNS challenge" - _debug2 add_fulldomain "$fulldomain" - _debug2 add_txtvalue "$txtvalue" + _info "Using dns.services to create ACME DNS challenge" + _debug2 add_fulldomain "$fulldomain" + _debug2 add_txtvalue "$txtvalue" - # Read username/password from environment or .acme.sh/accounts.conf - DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" - DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" - if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then - DnsServices_Username="" - DnsServices_Password="" - _err "You didn't specify dns.services api username and password yet." - _err "Set environment variables DnsServices_Username and DnsServices_Password" - return 1 - fi + # Read username/password from environment or .acme.sh/accounts.conf + DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" + DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" + if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then + DnsServices_Username="" + DnsServices_Password="" + _err "You didn't specify dns.services api username and password yet." + _err "Set environment variables DnsServices_Username and DnsServices_Password" + return 1 + fi - # Setup GET/POST/DELETE headers - _setup_headers + # Setup GET/POST/DELETE headers + _setup_headers - #save the credentials to the account conf file. - _saveaccountconf_mutable DnsServices_Username "$DnsServices_Username" - _saveaccountconf_mutable DnsServices_Password "$DnsServices_Password" + #save the credentials to the account conf file. + _saveaccountconf_mutable DnsServices_Username "$DnsServices_Username" + _saveaccountconf_mutable DnsServices_Password "$DnsServices_Password" - if ! _contains "$DnsServices_Username" "@"; then - _err "It seems that the username variable DnsServices_Username has not been set/left blank" - _err "or is not a valid email. Please correct and try again." - return 1 - fi + if ! _contains "$DnsServices_Username" "@"; then + _err "It seems that the username variable DnsServices_Username has not been set/left blank" + _err "or is not a valid email. Please correct and try again." + return 1 + fi - if ! _get_root "${fulldomain}"; then - _err "Invalid domain ${fulldomain}" - return 1 - fi + if ! _get_root "${fulldomain}"; then + _err "Invalid domain ${fulldomain}" + return 1 + fi - if ! createRecord "$fulldomain" "${txtvalue}"; then - _err "Error creating TXT record in domain $fulldomain in $rootZoneName" - return 1 - fi + if ! createRecord "$fulldomain" "${txtvalue}"; then + _err "Error creating TXT record in domain $fulldomain in $rootZoneName" + return 1 + fi - _debug2 challenge-created "Created $fulldomain" - return 0 + _debug2 challenge-created "Created $fulldomain" + return 0 } #Usage: fulldomain txtvalue #Description: Remove the txt record after validation. dns_dnsservices_rm() { - fulldomain=$1 - txtvalue=$2 + fulldomain=$1 + txtvalue=$2 - _info "Using dns.services to delete challenge $fulldomain TXT $txtvalue" - _debug rm_fulldomain "$fulldomain" - _debug rm_txtvalue "$txtvalue" + _info "Using dns.services to delete challenge $fulldomain TXT $txtvalue" + _debug rm_fulldomain "$fulldomain" + _debug rm_txtvalue "$txtvalue" - # Read username/password from environment or .acme.sh/accounts.conf - DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" - DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" - if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then - DnsServices_Username="" - DnsServices_Password="" - _err "You didn't specify dns.services api username and password yet." - _err "Set environment variables DnsServices_Username and DnsServices_Password" - return 1 - fi + # Read username/password from environment or .acme.sh/accounts.conf + DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" + DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" + if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then + DnsServices_Username="" + DnsServices_Password="" + _err "You didn't specify dns.services api username and password yet." + _err "Set environment variables DnsServices_Username and DnsServices_Password" + return 1 + fi - # Setup GET/POST/DELETE headers - _setup_headers - - if ! _get_root "${fulldomain}"; then - _err "Invalid domain ${fulldomain}" - return 1 - fi + # Setup GET/POST/DELETE headers + _setup_headers - _debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain" - - if ! deleteRecord "${fulldomain}" "${txtvalue}"; then - _err "Error removing record: $fulldomain TXT ${txtvalue}" - return 1 - fi + if ! _get_root "${fulldomain}"; then + _err "Invalid domain ${fulldomain}" + return 1 + fi - return 0 + _debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain" + + if ! deleteRecord "${fulldomain}" "${txtvalue}"; then + _err "Error removing record: $fulldomain TXT ${txtvalue}" + return 1 + fi + + return 0 } #################### Private functions below ################################## _setup_headers() { - # Set up API Headers for _get() and _post() - # The _add or _rm must have been called before to work + # Set up API Headers for _get() and _post() + # The _add or _rm must have been called before to work - if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then - _err "Could not setup BASIC authentication headers, they are missing" - return 1 - fi + if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then + _err "Could not setup BASIC authentication headers, they are missing" + return 1 + fi - DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)" - export _H1="Authorization: Basic $DnsServiceCredentials" - export _H2="Content-Type: application/json" + DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)" + export _H1="Authorization: Basic $DnsServiceCredentials" + export _H2="Content-Type: application/json" - # Just return if headers are set - return 0 + # Just return if headers are set + return 0 } _get_root() { - domain=$1 - _debug2 _get_root "Get the root domain of ${domain} for DNS API" + domain=$1 + _debug2 _get_root "Get the root domain of ${domain} for DNS API" - # Setup _get() and _post() headers - #_setup_headers + # Setup _get() and _post() headers + #_setup_headers - result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns") - _debug2 _get_root "Got the following root domain(s) $result" - _debug2 _get_root "- JSON: $result" + result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns") + _debug2 _get_root "Got the following root domain(s) $result" + _debug2 _get_root "- JSON: $result" - if [ "$(echo "$result" | grep -c '"name"')" -gt "1" ]; then - checkMultiZones="true" - _debug2 _get_root "- multiple zones found" - else - checkMultiZones="false" + if [ "$(echo "$result" | grep -c '"name"')" -gt "1" ]; then + checkMultiZones="true" + _debug2 _get_root "- multiple zones found" + else + checkMultiZones="false" - fi + fi - # Find/isolate the root zone to work with in createRecord() and deleteRecord() - rootZone="" - if [ "$checkMultiZones" == "true" ]; then - rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do - if [[ "$zone" =~ "$domain" ]]; then - _debug2 _get_root "- trying to figure out if $zone is in $domain" - echo "$zone" - break - fi - done) - else - rootZone=$(echo "$result" | grep -o '"name":"[^"]*' | cut -d'"' -f4) - _debug2 _get_root "- only found 1 domain in API: $rootZone" - fi + # Find/isolate the root zone to work with in createRecord() and deleteRecord() + rootZone="" + if [ "$checkMultiZones" == "true" ]; then + rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do + if [[ "$zone" =~ "$domain" ]]; then + _debug2 _get_root "- trying to figure out if $zone is in $domain" + echo "$zone" + break + fi + done) + else + rootZone=$(echo "$result" | grep -o '"name":"[^"]*' | cut -d'"' -f4) + _debug2 _get_root "- only found 1 domain in API: $rootZone" + fi - if [ -z "$rootZone" ]; then - _err "Could not find root domain for $domain - is it correctly typed?" - return 1 - fi + if [ -z "$rootZone" ]; then + _err "Could not find root domain for $domain - is it correctly typed?" + return 1 + fi - # Setup variables used by other functions to communicate with DNS Services API - zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") - rootZoneName="$rootZone" - subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")" - subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")" - rootZoneDomainID=$(echo "$zoneInfo" | tr ',' '\n' | grep domain_id | cut -d'"' -f4) - rootZoneServiceID=$(echo "$zoneInfo" | tr ',' '\n' | grep service_id | cut -d'"' -f4) + # Setup variables used by other functions to communicate with DNS Services API + zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") + rootZoneName="$rootZone" + subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")" + subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")" + rootZoneDomainID=$(echo "$zoneInfo" | tr ',' '\n' | grep domain_id | cut -d'"' -f4) + rootZoneServiceID=$(echo "$zoneInfo" | tr ',' '\n' | grep service_id | cut -d'"' -f4) - _debug2 _get_root "Root zone name : $rootZoneName" - _debug2 _get_root "Root zone domain ID : $rootZoneDomainID" - _debug2 _get_root "Root zone service ID: $rootZoneServiceID" - _debug2 _get_root "Sub domain : $subDomainName" + _debug2 _get_root "Root zone name : $rootZoneName" + _debug2 _get_root "Root zone domain ID : $rootZoneDomainID" + _debug2 _get_root "Root zone service ID: $rootZoneServiceID" + _debug2 _get_root "Sub domain : $subDomainName" - _debug _get_root "Found valid root domain $rootZone for $subDomainNameClean" - return 0 + _debug _get_root "Found valid root domain $rootZone for $subDomainNameClean" + return 0 } createRecord() { - fulldomain=$1 - txtvalue="$2" - - # Get root domain information - needed for DNS Services API communication - if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then - _get_root $fulldomain - fi + fulldomain=$1 + txtvalue="$2" - _debug2 createRecord "CNAME TXT value is: $txtvalue" + # Get root domain information - needed for DNS Services API communication + if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then + _get_root $fulldomain + fi - # Prepare data to send to API - data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}" + _debug2 createRecord "CNAME TXT value is: $txtvalue" - _debug2 createRecord "data to API: $data" - result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST") - _debug2 createRecord "result from API: $result" + # Prepare data to send to API + data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}" - if [ "$(echo "$result" | grep '"success":true')" == "" ]; then - _err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName" - _err "$result" - return 1 - fi + _debug2 createRecord "data to API: $data" + result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST") + _debug2 createRecord "result from API: $result" - _info "Record \"$fulldomain TXT $txtvalue\" has been created" - return 0 + if [ "$(echo "$result" | grep '"success":true')" == "" ]; then + _err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName" + _err "$result" + return 1 + fi + + _info "Record \"$fulldomain TXT $txtvalue\" has been created" + return 0 } deleteRecord() { - fulldomain=$1 - txtvalue=$2 + fulldomain=$1 + txtvalue=$2 - if [[ ! "$fulldomain" =~ "_acme-challenge" ]]; then - _err "The script tried to delete the record $fulldomain which is not the above created ACME challenge" - return 1 - fi + if [[ ! "$fulldomain" =~ "_acme-challenge" ]]; then + _err "The script tried to delete the record $fulldomain which is not the above created ACME challenge" + return 1 + fi - _debug2 deleteRecord "Deleting $fulldomain TXT $txtvalue record" + _debug2 deleteRecord "Deleting $fulldomain TXT $txtvalue record" - if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then - _get_root $fulldomain - fi + if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then + _get_root $fulldomain + fi - result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" - recordInfo="$(echo "$result" | tr '}' '\n' | grep "\"name\":\"${fulldomain}" | grep "\"content\":\"" | grep "${txtvalue}")" - _debug2 deleteRecord "recordInfo=$recordInfo" - recordID="$(echo "$recordInfo" | tr ',' '\n' | egrep "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" + result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" + recordInfo="$(echo "$result" | tr '}' '\n' | grep "\"name\":\"${fulldomain}" | grep "\"content\":\"" | grep "${txtvalue}")" + _debug2 deleteRecord "recordInfo=$recordInfo" + recordID="$(echo "$recordInfo" | tr ',' '\n' | egrep "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" - if [ -z "$recordID" ]; then - _info "Record $fulldomain TXT $txtvalue not found or already deleted" - return 0 - else - _debug2 deleteRecord "Found recordID=$recordID" - fi + if [ -z "$recordID" ]; then + _info "Record $fulldomain TXT $txtvalue not found or already deleted" + return 0 + else + _debug2 deleteRecord "Found recordID=$recordID" + fi - _debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" - result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")" - _debug2 deleteRecord "API Delete result \"$result\"" + _debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" + result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")" + _debug2 deleteRecord "API Delete result \"$result\"" - # Return OK regardless - return 0 + # Return OK regardless + return 0 } From 2f97c789ddc9f6d1689bd8726608e70ad0594af5 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 23 Jun 2022 09:14:17 +0200 Subject: [PATCH 1846/2234] Code formatting (shellcheck/shfmt) --- dnsapi/dns_dnsservices.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index a131a165..bf56c16b 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -137,9 +137,9 @@ _get_root() { # Find/isolate the root zone to work with in createRecord() and deleteRecord() rootZone="" - if [ "$checkMultiZones" == "true" ]; then + if [ "$checkMultiZones" = "true" ]; then rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do - if [[ "$zone" =~ "$domain" ]]; then + if [ "$(echo "$domain" | grep "$zone")" != "" ]; then _debug2 _get_root "- trying to figure out if $zone is in $domain" echo "$zone" break @@ -178,7 +178,7 @@ createRecord() { # Get root domain information - needed for DNS Services API communication if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then - _get_root $fulldomain + _get_root "$fulldomain" fi _debug2 createRecord "CNAME TXT value is: $txtvalue" @@ -190,7 +190,7 @@ createRecord() { result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST") _debug2 createRecord "result from API: $result" - if [ "$(echo "$result" | grep '"success":true')" == "" ]; then + if [ "$(echo "$result" | grep '"success":true')" = "" ]; then _err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName" _err "$result" return 1 @@ -204,7 +204,7 @@ deleteRecord() { fulldomain=$1 txtvalue=$2 - if [[ ! "$fulldomain" =~ "_acme-challenge" ]]; then + if [ "$(echo "$fulldomain" | grep "_acme-challenge")" = "" ]; then _err "The script tried to delete the record $fulldomain which is not the above created ACME challenge" return 1 fi @@ -212,13 +212,13 @@ deleteRecord() { _debug2 deleteRecord "Deleting $fulldomain TXT $txtvalue record" if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then - _get_root $fulldomain + _get_root "$fulldomain" fi result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" recordInfo="$(echo "$result" | tr '}' '\n' | grep "\"name\":\"${fulldomain}" | grep "\"content\":\"" | grep "${txtvalue}")" _debug2 deleteRecord "recordInfo=$recordInfo" - recordID="$(echo "$recordInfo" | tr ',' '\n' | egrep "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" + recordID="$(echo "$recordInfo" | tr ',' '\n' | grep -E "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" if [ -z "$recordID" ]; then _info "Record $fulldomain TXT $txtvalue not found or already deleted" From 56a686d3e06c13d867bd7cce2b5e5babbf4c28ab Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 23 Jun 2022 09:21:20 +0200 Subject: [PATCH 1847/2234] Code formatting (shfmt) --- dnsapi/dns_dnsservices.sh | 322 +++++++++++++++++++------------------- 1 file changed, 161 insertions(+), 161 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index bf56c16b..a7a646c2 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -13,224 +13,224 @@ DNSServices_API=https://dns.services/api #Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dnsservices_add() { - fulldomain=$1 - txtvalue=$2 + fulldomain=$1 + txtvalue=$2 - _info "Using dns.services to create ACME DNS challenge" - _debug2 add_fulldomain "$fulldomain" - _debug2 add_txtvalue "$txtvalue" + _info "Using dns.services to create ACME DNS challenge" + _debug2 add_fulldomain "$fulldomain" + _debug2 add_txtvalue "$txtvalue" - # Read username/password from environment or .acme.sh/accounts.conf - DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" - DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" - if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then - DnsServices_Username="" - DnsServices_Password="" - _err "You didn't specify dns.services api username and password yet." - _err "Set environment variables DnsServices_Username and DnsServices_Password" - return 1 - fi + # Read username/password from environment or .acme.sh/accounts.conf + DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" + DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" + if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then + DnsServices_Username="" + DnsServices_Password="" + _err "You didn't specify dns.services api username and password yet." + _err "Set environment variables DnsServices_Username and DnsServices_Password" + return 1 + fi - # Setup GET/POST/DELETE headers - _setup_headers + # Setup GET/POST/DELETE headers + _setup_headers - #save the credentials to the account conf file. - _saveaccountconf_mutable DnsServices_Username "$DnsServices_Username" - _saveaccountconf_mutable DnsServices_Password "$DnsServices_Password" + #save the credentials to the account conf file. + _saveaccountconf_mutable DnsServices_Username "$DnsServices_Username" + _saveaccountconf_mutable DnsServices_Password "$DnsServices_Password" - if ! _contains "$DnsServices_Username" "@"; then - _err "It seems that the username variable DnsServices_Username has not been set/left blank" - _err "or is not a valid email. Please correct and try again." - return 1 - fi + if ! _contains "$DnsServices_Username" "@"; then + _err "It seems that the username variable DnsServices_Username has not been set/left blank" + _err "or is not a valid email. Please correct and try again." + return 1 + fi - if ! _get_root "${fulldomain}"; then - _err "Invalid domain ${fulldomain}" - return 1 - fi + if ! _get_root "${fulldomain}"; then + _err "Invalid domain ${fulldomain}" + return 1 + fi - if ! createRecord "$fulldomain" "${txtvalue}"; then - _err "Error creating TXT record in domain $fulldomain in $rootZoneName" - return 1 - fi + if ! createRecord "$fulldomain" "${txtvalue}"; then + _err "Error creating TXT record in domain $fulldomain in $rootZoneName" + return 1 + fi - _debug2 challenge-created "Created $fulldomain" - return 0 + _debug2 challenge-created "Created $fulldomain" + return 0 } #Usage: fulldomain txtvalue #Description: Remove the txt record after validation. dns_dnsservices_rm() { - fulldomain=$1 - txtvalue=$2 + fulldomain=$1 + txtvalue=$2 - _info "Using dns.services to delete challenge $fulldomain TXT $txtvalue" - _debug rm_fulldomain "$fulldomain" - _debug rm_txtvalue "$txtvalue" + _info "Using dns.services to delete challenge $fulldomain TXT $txtvalue" + _debug rm_fulldomain "$fulldomain" + _debug rm_txtvalue "$txtvalue" - # Read username/password from environment or .acme.sh/accounts.conf - DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" - DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" - if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then - DnsServices_Username="" - DnsServices_Password="" - _err "You didn't specify dns.services api username and password yet." - _err "Set environment variables DnsServices_Username and DnsServices_Password" - return 1 - fi + # Read username/password from environment or .acme.sh/accounts.conf + DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" + DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" + if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then + DnsServices_Username="" + DnsServices_Password="" + _err "You didn't specify dns.services api username and password yet." + _err "Set environment variables DnsServices_Username and DnsServices_Password" + return 1 + fi - # Setup GET/POST/DELETE headers - _setup_headers + # Setup GET/POST/DELETE headers + _setup_headers - if ! _get_root "${fulldomain}"; then - _err "Invalid domain ${fulldomain}" - return 1 - fi + if ! _get_root "${fulldomain}"; then + _err "Invalid domain ${fulldomain}" + return 1 + fi - _debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain" + _debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain" - if ! deleteRecord "${fulldomain}" "${txtvalue}"; then - _err "Error removing record: $fulldomain TXT ${txtvalue}" - return 1 - fi + if ! deleteRecord "${fulldomain}" "${txtvalue}"; then + _err "Error removing record: $fulldomain TXT ${txtvalue}" + return 1 + fi - return 0 + return 0 } #################### Private functions below ################################## _setup_headers() { - # Set up API Headers for _get() and _post() - # The _add or _rm must have been called before to work + # Set up API Headers for _get() and _post() + # The _add or _rm must have been called before to work - if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then - _err "Could not setup BASIC authentication headers, they are missing" - return 1 - fi + if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then + _err "Could not setup BASIC authentication headers, they are missing" + return 1 + fi - DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)" - export _H1="Authorization: Basic $DnsServiceCredentials" - export _H2="Content-Type: application/json" + DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)" + export _H1="Authorization: Basic $DnsServiceCredentials" + export _H2="Content-Type: application/json" - # Just return if headers are set - return 0 + # Just return if headers are set + return 0 } _get_root() { - domain=$1 - _debug2 _get_root "Get the root domain of ${domain} for DNS API" + domain=$1 + _debug2 _get_root "Get the root domain of ${domain} for DNS API" - # Setup _get() and _post() headers - #_setup_headers + # Setup _get() and _post() headers + #_setup_headers - result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns") - _debug2 _get_root "Got the following root domain(s) $result" - _debug2 _get_root "- JSON: $result" + result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns") + _debug2 _get_root "Got the following root domain(s) $result" + _debug2 _get_root "- JSON: $result" - if [ "$(echo "$result" | grep -c '"name"')" -gt "1" ]; then - checkMultiZones="true" - _debug2 _get_root "- multiple zones found" - else - checkMultiZones="false" + if [ "$(echo "$result" | grep -c '"name"')" -gt "1" ]; then + checkMultiZones="true" + _debug2 _get_root "- multiple zones found" + else + checkMultiZones="false" - fi + fi - # Find/isolate the root zone to work with in createRecord() and deleteRecord() - rootZone="" - if [ "$checkMultiZones" = "true" ]; then - rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do - if [ "$(echo "$domain" | grep "$zone")" != "" ]; then - _debug2 _get_root "- trying to figure out if $zone is in $domain" - echo "$zone" - break - fi - done) - else - rootZone=$(echo "$result" | grep -o '"name":"[^"]*' | cut -d'"' -f4) - _debug2 _get_root "- only found 1 domain in API: $rootZone" - fi + # Find/isolate the root zone to work with in createRecord() and deleteRecord() + rootZone="" + if [ "$checkMultiZones" = "true" ]; then + rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do + if [ "$(echo "$domain" | grep "$zone")" != "" ]; then + _debug2 _get_root "- trying to figure out if $zone is in $domain" + echo "$zone" + break + fi + done) + else + rootZone=$(echo "$result" | grep -o '"name":"[^"]*' | cut -d'"' -f4) + _debug2 _get_root "- only found 1 domain in API: $rootZone" + fi - if [ -z "$rootZone" ]; then - _err "Could not find root domain for $domain - is it correctly typed?" - return 1 - fi + if [ -z "$rootZone" ]; then + _err "Could not find root domain for $domain - is it correctly typed?" + return 1 + fi - # Setup variables used by other functions to communicate with DNS Services API - zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") - rootZoneName="$rootZone" - subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")" - subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")" - rootZoneDomainID=$(echo "$zoneInfo" | tr ',' '\n' | grep domain_id | cut -d'"' -f4) - rootZoneServiceID=$(echo "$zoneInfo" | tr ',' '\n' | grep service_id | cut -d'"' -f4) + # Setup variables used by other functions to communicate with DNS Services API + zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") + rootZoneName="$rootZone" + subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")" + subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")" + rootZoneDomainID=$(echo "$zoneInfo" | tr ',' '\n' | grep domain_id | cut -d'"' -f4) + rootZoneServiceID=$(echo "$zoneInfo" | tr ',' '\n' | grep service_id | cut -d'"' -f4) - _debug2 _get_root "Root zone name : $rootZoneName" - _debug2 _get_root "Root zone domain ID : $rootZoneDomainID" - _debug2 _get_root "Root zone service ID: $rootZoneServiceID" - _debug2 _get_root "Sub domain : $subDomainName" + _debug2 _get_root "Root zone name : $rootZoneName" + _debug2 _get_root "Root zone domain ID : $rootZoneDomainID" + _debug2 _get_root "Root zone service ID: $rootZoneServiceID" + _debug2 _get_root "Sub domain : $subDomainName" - _debug _get_root "Found valid root domain $rootZone for $subDomainNameClean" - return 0 + _debug _get_root "Found valid root domain $rootZone for $subDomainNameClean" + return 0 } createRecord() { - fulldomain=$1 - txtvalue="$2" + fulldomain=$1 + txtvalue="$2" - # Get root domain information - needed for DNS Services API communication - if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then - _get_root "$fulldomain" - fi + # Get root domain information - needed for DNS Services API communication + if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then + _get_root "$fulldomain" + fi - _debug2 createRecord "CNAME TXT value is: $txtvalue" + _debug2 createRecord "CNAME TXT value is: $txtvalue" - # Prepare data to send to API - data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}" + # Prepare data to send to API + data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}" - _debug2 createRecord "data to API: $data" - result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST") - _debug2 createRecord "result from API: $result" + _debug2 createRecord "data to API: $data" + result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST") + _debug2 createRecord "result from API: $result" - if [ "$(echo "$result" | grep '"success":true')" = "" ]; then - _err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName" - _err "$result" - return 1 - fi + if [ "$(echo "$result" | grep '"success":true')" = "" ]; then + _err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName" + _err "$result" + return 1 + fi - _info "Record \"$fulldomain TXT $txtvalue\" has been created" - return 0 + _info "Record \"$fulldomain TXT $txtvalue\" has been created" + return 0 } deleteRecord() { - fulldomain=$1 - txtvalue=$2 + fulldomain=$1 + txtvalue=$2 - if [ "$(echo "$fulldomain" | grep "_acme-challenge")" = "" ]; then - _err "The script tried to delete the record $fulldomain which is not the above created ACME challenge" - return 1 - fi + if [ "$(echo "$fulldomain" | grep "_acme-challenge")" = "" ]; then + _err "The script tried to delete the record $fulldomain which is not the above created ACME challenge" + return 1 + fi - _debug2 deleteRecord "Deleting $fulldomain TXT $txtvalue record" + _debug2 deleteRecord "Deleting $fulldomain TXT $txtvalue record" - if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then - _get_root "$fulldomain" - fi + if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then + _get_root "$fulldomain" + fi - result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" - recordInfo="$(echo "$result" | tr '}' '\n' | grep "\"name\":\"${fulldomain}" | grep "\"content\":\"" | grep "${txtvalue}")" - _debug2 deleteRecord "recordInfo=$recordInfo" - recordID="$(echo "$recordInfo" | tr ',' '\n' | grep -E "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" + result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" + recordInfo="$(echo "$result" | tr '}' '\n' | grep "\"name\":\"${fulldomain}" | grep "\"content\":\"" | grep "${txtvalue}")" + _debug2 deleteRecord "recordInfo=$recordInfo" + recordID="$(echo "$recordInfo" | tr ',' '\n' | grep -E "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" - if [ -z "$recordID" ]; then - _info "Record $fulldomain TXT $txtvalue not found or already deleted" - return 0 - else - _debug2 deleteRecord "Found recordID=$recordID" - fi + if [ -z "$recordID" ]; then + _info "Record $fulldomain TXT $txtvalue not found or already deleted" + return 0 + else + _debug2 deleteRecord "Found recordID=$recordID" + fi - _debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" - result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")" - _debug2 deleteRecord "API Delete result \"$result\"" + _debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" + result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")" + _debug2 deleteRecord "API Delete result \"$result\"" - # Return OK regardless - return 0 + # Return OK regardless + return 0 } From 3bd4d32b8d4446d59002db1d8f376736f66fb57d Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 23 Jun 2022 11:48:39 +0200 Subject: [PATCH 1848/2234] Updated bug report URL --- dnsapi/dns_dnsservices.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index a7a646c2..9525007a 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -4,7 +4,7 @@ #Script for Danish DNS registra and DNS hosting provider https://dns.services # #Author: Bjarke Bruun -#Report Bugs here: https://github.com/bbruun/acme.sh +#Report Bugs here: https://github.com/Neilpang/acme.sh/issues # Global variable to connect to the DNS Services API DNSServices_API=https://dns.services/api From 543c4423a2283b906dfb790733050e353d9e7f3b Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Fri, 24 Jun 2022 07:42:00 +0200 Subject: [PATCH 1849/2234] Added bug report link to dns_dnsservices.sh --- dnsapi/dns_dnsservices.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 9525007a..6abf8ceb 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -4,7 +4,7 @@ #Script for Danish DNS registra and DNS hosting provider https://dns.services # #Author: Bjarke Bruun -#Report Bugs here: https://github.com/Neilpang/acme.sh/issues +#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152 # Global variable to connect to the DNS Services API DNSServices_API=https://dns.services/api From b3529dc7482e6a8d2bdbb0e77374d960b58974a1 Mon Sep 17 00:00:00 2001 From: seidler2547 Date: Mon, 27 Jun 2022 19:42:16 +0000 Subject: [PATCH 1850/2234] remove dns_do as it does not work anymore The API that it uses was shut down in May 2022 --- dnsapi/dns_do.sh | 148 ----------------------------------------------- 1 file changed, 148 deletions(-) delete mode 100755 dnsapi/dns_do.sh diff --git a/dnsapi/dns_do.sh b/dnsapi/dns_do.sh deleted file mode 100755 index 3850890c..00000000 --- a/dnsapi/dns_do.sh +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env sh - -# DNS API for Domain-Offensive / Resellerinterface / Domainrobot - -# Report bugs at https://github.com/seidler2547/acme.sh/issues - -# set these environment variables to match your customer ID and password: -# DO_PID="KD-1234567" -# DO_PW="cdfkjl3n2" - -DO_URL="https://soap.resellerinterface.de/" - -######## Public functions ##################### - -#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_do_add() { - fulldomain=$1 - txtvalue=$2 - if _dns_do_authenticate; then - _info "Adding TXT record to ${_domain} as ${fulldomain}" - _dns_do_soap createRR origin "${_domain}" name "${fulldomain}" type TXT data "${txtvalue}" ttl 300 - if _contains "${response}" '>success<'; then - return 0 - fi - _err "Could not create resource record, check logs" - fi - return 1 -} - -#fulldomain -dns_do_rm() { - fulldomain=$1 - if _dns_do_authenticate; then - if _dns_do_list_rrs; then - _dns_do_had_error=0 - for _rrid in ${_rr_list}; do - _info "Deleting resource record $_rrid for $_domain" - _dns_do_soap deleteRR origin "${_domain}" rrid "${_rrid}" - if ! _contains "${response}" '>success<'; then - _dns_do_had_error=1 - _err "Could not delete resource record for ${_domain}, id ${_rrid}" - fi - done - return $_dns_do_had_error - fi - fi - return 1 -} - -#################### Private functions below ################################## -_dns_do_authenticate() { - _info "Authenticating as ${DO_PID}" - _dns_do_soap authPartner partner "${DO_PID}" password "${DO_PW}" - if _contains "${response}" '>success<'; then - _get_root "$fulldomain" - _debug "_domain $_domain" - return 0 - else - _err "Authentication failed, are DO_PID and DO_PW set correctly?" - fi - return 1 -} - -_dns_do_list_rrs() { - _dns_do_soap getRRList origin "${_domain}" - if ! _contains "${response}" 'SOAP-ENC:Array'; then - _err "getRRList origin ${_domain} failed" - return 1 - fi - _rr_list="$(echo "${response}" | - tr -d "\n\r\t" | - sed -e 's//\n/g' | - grep ">$(_regexcape "$fulldomain")" | - sed -e 's/<\/item>/\n/g' | - grep '>id[0-9]{1,16}<' | - tr -d '><')" - [ "${_rr_list}" ] -} - -_dns_do_soap() { - func="$1" - shift - # put the parameters to xml - body="" - while [ "$1" ]; do - _k="$1" - shift - _v="$1" - shift - body="$body<$_k>$_v" - done - body="$body" - _debug2 "SOAP request ${body}" - - # build SOAP XML - _xml=' - - '"$body"' -' - - # set SOAP headers - export _H1="SOAPAction: ${DO_URL}#${func}" - - if ! response="$(_post "${_xml}" "${DO_URL}")"; then - _err "Error <$1>" - return 1 - fi - _debug2 "SOAP response $response" - - # retrieve cookie header - _H2="$(_egrep_o 'Cookie: [^;]+' <"$HTTP_HEADER" | _head_n 1)" - export _H2 - - return 0 -} - -_get_root() { - domain=$1 - i=1 - - _dns_do_soap getDomainList - _all_domains="$(echo "${response}" | - tr -d "\n\r\t " | - _egrep_o 'domain]+>[^<]+' | - sed -e 's/^domain<\/key>]*>//g')" - - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if [ -z "$h" ]; then - return 1 - fi - - if _contains "${_all_domains}" "^$(_regexcape "$h")\$"; then - _domain="$h" - return 0 - fi - - i=$(_math $i + 1) - done - _debug "$domain not found" - - return 1 -} - -_regexcape() { - echo "$1" | sed -e 's/\([]\.$*^[]\)/\\\1/g' -} From 7746042adc3879abf3fe14c69c60b83173f7b94a Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 30 Jun 2022 23:07:18 +0800 Subject: [PATCH 1851/2234] fix https://github.com/acmesh-official/acme.sh/issues/4160 fix https://github.com/acmesh-official/acme.sh/issues/4160 --- acme.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index bc667359..86e4ccf1 100755 --- a/acme.sh +++ b/acme.sh @@ -435,8 +435,10 @@ _secure_debug3() { fi } +__USE_TR_RAW="$([ "$(echo "abc" | tr a-z A-Z 2>/dev/null)" = "ABC" ] && echo 1 || echo 0)" + _upper_case() { - if _is_solaris; then + if [ "$__USE_TR_RAW" = "0" ]; then tr '[:lower:]' '[:upper:]' else # shellcheck disable=SC2018,SC2019 @@ -445,7 +447,7 @@ _upper_case() { } _lower_case() { - if _is_solaris; then + if [ "$__USE_TR_RAW" = "0" ]; then tr '[:upper:]' '[:lower:]' else # shellcheck disable=SC2018,SC2019 From 789ebb899001faaf1e3d8e545c295fb4aea34226 Mon Sep 17 00:00:00 2001 From: nil <1993plus@gmail.com> Date: Fri, 1 Jul 2022 09:12:06 +0000 Subject: [PATCH 1852/2234] Fix dns_huaweicloud provider 1. Fix huaweicloud api use iam account get token fail. 2. Default use ap-southeast-1 project name, don't need query project id. --- dnsapi/dns_huaweicloud.sh | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index ac3ede65..916ce5a3 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -2,7 +2,8 @@ # HUAWEICLOUD_Username # HUAWEICLOUD_Password -# HUAWEICLOUD_ProjectID +# HUAWEICLOUD_DomainName + iam_api="https://iam.myhuaweicloud.com" dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work @@ -14,6 +15,8 @@ dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work # # Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/zh-cn_topic_0132421999.html # +# About "DomainName" parameters see: https://support.huaweicloud.com/api-iam/iam_01_0006.html +# dns_huaweicloud_add() { fulldomain=$1 @@ -21,16 +24,16 @@ dns_huaweicloud_add() { HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" - HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" # Check information - if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then _err "Not enough information provided to dns_huaweicloud!" return 1 fi unset token # Clear token - token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")" if [ -z "${token}" ]; then # Check token _err "dns_api(dns_huaweicloud): Error getting token." return 1 @@ -56,7 +59,7 @@ dns_huaweicloud_add() { # Do saving work if all succeeded _saveaccountconf_mutable HUAWEICLOUD_Username "${HUAWEICLOUD_Username}" _saveaccountconf_mutable HUAWEICLOUD_Password "${HUAWEICLOUD_Password}" - _saveaccountconf_mutable HUAWEICLOUD_ProjectID "${HUAWEICLOUD_ProjectID}" + _saveaccountconf_mutable HUAWEICLOUD_DomainName "${HUAWEICLOUD_DomainName}" return 0 } @@ -72,16 +75,16 @@ dns_huaweicloud_rm() { HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" - HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" # Check information - if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then _err "Not enough information provided to dns_huaweicloud!" return 1 fi unset token # Clear token - token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")" if [ -z "${token}" ]; then # Check token _err "dns_api(dns_huaweicloud): Error getting token." return 1 @@ -253,7 +256,7 @@ _rm_record() { _get_token() { _username=$1 _password=$2 - _project=$3 + _domain_name=$3 _debug "Getting Token" body="{ @@ -267,14 +270,14 @@ _get_token() { \"name\": \"${_username}\", \"password\": \"${_password}\", \"domain\": { - \"name\": \"${_username}\" + \"name\": \"${_domain_name}\" } } } }, \"scope\": { \"project\": { - \"id\": \"${_project}\" + \"name\": \"ap-southeast-1\" } } } @@ -287,3 +290,4 @@ _get_token() { printf "%s" "${_token}" return 0 } + From a46e51e8db9a25ef146fcf2e699142152d25cae1 Mon Sep 17 00:00:00 2001 From: nil <1993plus@gmail.com> Date: Sat, 2 Jul 2022 01:22:46 +0000 Subject: [PATCH 1853/2234] Update format code. --- dnsapi/dns_huaweicloud.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 916ce5a3..ceda9258 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -4,7 +4,6 @@ # HUAWEICLOUD_Password # HUAWEICLOUD_DomainName - iam_api="https://iam.myhuaweicloud.com" dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work @@ -290,4 +289,3 @@ _get_token() { printf "%s" "${_token}" return 0 } - From be7840c82779122cdf6a72256a1100fe33d00a82 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Wed, 27 Nov 2019 12:06:02 +1100 Subject: [PATCH 1854/2234] Exit with separate failure if in DNS manual mode In our environment we use DNS manual mode and take the TXT record output of acme.sh and process it with Ansible to install the records (then we call renew later when the records have been pushed to the DNS servers by a whole bunch of other bits). One problem is that after getting/showing the TXT records, acme.sh always returns 1. This makes it difficult to tell if there is actually an error condition. Since we have set the manual-mode flag, not installing the DNS records is an expected correct result. This returns a separate error code for this situation (3), which can be distinguished in automation. --- acme.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 86e4ccf1..e3439749 100755 --- a/acme.sh +++ b/acme.sh @@ -4764,7 +4764,13 @@ $_authorizations_map" _err "Please add the TXT records to the domains, and re-run with --renew." _on_issue_err "$_post_hook" _clearup - return 1 + if [ -n "$FORCE_DNS_MANUAL" ]; then + # If asked to be in manual DNS mode, flag this exit with a separate + # error so it can be distinguished from other failures. + return 3 + else + return 1 + fi fi fi From a364ab4ea7fffd2512a6650b9ab83829d2e62a40 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Wed, 6 Jul 2022 12:10:19 +0200 Subject: [PATCH 1855/2234] Added '.' to 'DNS Services' as that is the correct provider name --- dnsapi/dns_dnsservices.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 6abf8ceb..feb4e73f 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -6,7 +6,7 @@ #Author: Bjarke Bruun #Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152 -# Global variable to connect to the DNS Services API +# Global variable to connect to the DNS.Services API DNSServices_API=https://dns.services/api ######## Public functions ##################### @@ -155,7 +155,7 @@ _get_root() { return 1 fi - # Setup variables used by other functions to communicate with DNS Services API + # Setup variables used by other functions to communicate with DNS.Services API zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") rootZoneName="$rootZone" subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")" @@ -176,7 +176,7 @@ createRecord() { fulldomain=$1 txtvalue="$2" - # Get root domain information - needed for DNS Services API communication + # Get root domain information - needed for DNS.Services API communication if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then _get_root "$fulldomain" fi From 444b111a62ec8e7f48cd93aaefdc78816d7ff32e Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 7 Jul 2022 09:40:18 +0200 Subject: [PATCH 1856/2234] Fixed acmetest for domain acmetestXyzRandomName.github-test. that was explicitly disallowed as it is not _acme-challenge --- dnsapi/dns_dnsservices.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index feb4e73f..89ed0210 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -204,7 +204,8 @@ deleteRecord() { fulldomain=$1 txtvalue=$2 - if [ "$(echo "$fulldomain" | grep "_acme-challenge")" = "" ]; then + # Fix for acmetest to limit acme.sh to only work on _acme-challenge and acmeTestXYzRandomName in GitHub actions + if [ "$(echo "$fulldomain" | grep "_acme-challenge\|acmetestXyzRandomName.github-test")" = "" ]; then _err "The script tried to delete the record $fulldomain which is not the above created ACME challenge" return 1 fi From eba788e8c9879ca5c9383df9ea4c438415490cdb Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 7 Jul 2022 10:59:25 +0200 Subject: [PATCH 1857/2234] Removed check for _acme-challenge and acmetestXyzRandomName.github-test sub-domain --- dnsapi/dns_dnsservices.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 89ed0210..788c9680 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -204,12 +204,6 @@ deleteRecord() { fulldomain=$1 txtvalue=$2 - # Fix for acmetest to limit acme.sh to only work on _acme-challenge and acmeTestXYzRandomName in GitHub actions - if [ "$(echo "$fulldomain" | grep "_acme-challenge\|acmetestXyzRandomName.github-test")" = "" ]; then - _err "The script tried to delete the record $fulldomain which is not the above created ACME challenge" - return 1 - fi - _debug2 deleteRecord "Deleting $fulldomain TXT $txtvalue record" if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then From 9c757bbe6ed08c244497860a16d9cbfd8c2bd409 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 7 Jul 2022 20:01:43 +0800 Subject: [PATCH 1858/2234] Update acme.sh --- acme.sh | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index e3439749..3d65612f 100755 --- a/acme.sh +++ b/acme.sh @@ -91,6 +91,7 @@ END_CERT="-----END CERTIFICATE-----" CONTENT_TYPE_JSON="application/jose+json" RENEW_SKIP=2 +CODE_DNS_MANUAL=3 B64CONF_START="__ACME_BASE64__START_" B64CONF_END="__ACME_BASE64__END_" @@ -4764,13 +4765,9 @@ $_authorizations_map" _err "Please add the TXT records to the domains, and re-run with --renew." _on_issue_err "$_post_hook" _clearup - if [ -n "$FORCE_DNS_MANUAL" ]; then - # If asked to be in manual DNS mode, flag this exit with a separate - # error so it can be distinguished from other failures. - return 3 - else - return 1 - fi + # If asked to be in manual DNS mode, flag this exit with a separate + # error so it can be distinguished from other failures. + return $CODE_DNS_MANUAL fi fi From 0afabc60aefa1d4e3dd7dc58a87458869d143526 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 7 Jul 2022 15:00:12 +0200 Subject: [PATCH 1859/2234] Changed 'grep -E' to '_egrep_o' --- dnsapi/dns_dnsservices.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 788c9680..2190d3c6 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -213,7 +213,7 @@ deleteRecord() { result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" recordInfo="$(echo "$result" | tr '}' '\n' | grep "\"name\":\"${fulldomain}" | grep "\"content\":\"" | grep "${txtvalue}")" _debug2 deleteRecord "recordInfo=$recordInfo" - recordID="$(echo "$recordInfo" | tr ',' '\n' | grep -E "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" + recordID="$(echo "$recordInfo" | tr ',' '\n' | _egrep_o() "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" if [ -z "$recordID" ]; then _info "Record $fulldomain TXT $txtvalue not found or already deleted" From 1b3e1a7abea9ca7b7f8e077d114aad83416f8304 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 7 Jul 2022 15:05:12 +0200 Subject: [PATCH 1860/2234] Changed 'grep -E' to '_egrep_o' 'removed ()' --- dnsapi/dns_dnsservices.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 2190d3c6..6acb13da 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -213,7 +213,7 @@ deleteRecord() { result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" recordInfo="$(echo "$result" | tr '}' '\n' | grep "\"name\":\"${fulldomain}" | grep "\"content\":\"" | grep "${txtvalue}")" _debug2 deleteRecord "recordInfo=$recordInfo" - recordID="$(echo "$recordInfo" | tr ',' '\n' | _egrep_o() "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" + recordID="$(echo "$recordInfo" | tr ',' '\n' | _egrep_o "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" if [ -z "$recordID" ]; then _info "Record $fulldomain TXT $txtvalue not found or already deleted" From 87b110bb86f61ffb5dd1b5816dca6777766636d1 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 7 Jul 2022 22:27:18 +0800 Subject: [PATCH 1861/2234] add OpenBSD CI test: https://vmactions.org --- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/OpenBSD.yml | 63 +++++++++++++++++++++++++++++++++++ .github/workflows/Solaris.yml | 2 +- README.md | 3 +- 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/OpenBSD.yml diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 22f8b9af..4d310f05 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -30,7 +30,7 @@ jobs: # CA: "ZeroSSL RSA Domain Secure Site CA" # CA_EMAIL: "githubtest@acme.sh" # TEST_PREFERRED_CHAIN: "" - runs-on: macos-10.15 + runs-on: macos-12 env: TEST_LOCAL: 1 TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml new file mode 100644 index 00000000..2b974a81 --- /dev/null +++ b/.github/workflows/OpenBSD.yml @@ -0,0 +1,63 @@ +name: OpenBSD +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '.github/workflows/OpenBSD.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '.github/workflows/OpenBSD.yml' + + +jobs: + OpenBSD: + strategy: + matrix: + include: + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + 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: "" + runs-on: macos-12 + env: + TEST_LOCAL: 1 + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + steps: + - uses: actions/checkout@v2 + - uses: vmactions/cf-tunnel@v0.0.3 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/openbsd-vm@v0.0.1 + with: + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + nat: | + "8080": "80" + prepare: pkg_add socat curl + usesh: true + run: | + cd ../acmetest \ + && ./letest.sh + + diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index f8a3826c..6ba0e414 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -30,7 +30,7 @@ jobs: # CA: "ZeroSSL RSA Domain Secure Site CA" # CA_EMAIL: "githubtest@acme.sh" # TEST_PREFERRED_CHAIN: "" - runs-on: macos-10.15 + runs-on: macos-12 env: TEST_LOCAL: 1 TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} diff --git a/README.md b/README.md index 4a12d46a..2f580a57 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # An ACME Shell script: acme.sh [![FreeBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml) +[![OpenBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml) [![MacOS](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml) [![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml) [![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml) @@ -68,7 +69,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |4|[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)|Solaris |5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)| Ubuntu |6|NA|pfsense -|7|NA|OpenBSD +|7|[![OpenBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml)|OpenBSD |8|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian |9|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS |10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE From 59dc513ac32f97cd4e148ae5c4d8504bdf5bac7c Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 7 Jul 2022 22:30:35 +0800 Subject: [PATCH 1862/2234] add OpenBSD test --- .github/workflows/DNS.yml | 47 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 46fd8283..2706c72f 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -173,7 +173,7 @@ jobs: ./letest.sh FreeBSD: - runs-on: macos-10.15 + runs-on: macos-12 needs: Windows env: TEST_DNS : ${{ secrets.TEST_DNS }} @@ -213,7 +213,7 @@ jobs: ./letest.sh Solaris: - runs-on: macos-10.15 + runs-on: macos-12 needs: FreeBSD env: TEST_DNS : ${{ secrets.TEST_DNS }} @@ -252,3 +252,46 @@ jobs: fi cd ../acmetest ./letest.sh + + + OpenBSD: + runs-on: macos-12 + needs: Solaris + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/openbsd-vm@v0.0.1 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: pkg_add socat curl + usesh: true + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + + \ No newline at end of file From 2cbf1259a8f6e4987e44bb4f14fe20bb2c3f13c4 Mon Sep 17 00:00:00 2001 From: Jordan ERNST Date: Thu, 7 Jul 2022 17:20:23 +0200 Subject: [PATCH 1863/2234] Fix for ECC certificates --- deploy/mailcow.sh | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index 3492cea4..51c71892 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -44,24 +44,14 @@ mailcow_deploy() { return 1 fi - # ECC or RSA - 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" + _real_key="$_ssl_path/key.pem" if ! cat "$_ckey" >"$_real_key"; then _err "Error: write key file to: $_real_key" return 1 fi - _real_fullchain="$_ssl_path/${_cert_name_prefix}cert.pem" + _real_fullchain="$_ssl_path/cert.pem" if ! cat "$_cfullchain" >"$_real_fullchain"; then _err "Error: write cert file to: $_real_fullchain" return 1 From c8d17bc3633c2923504065d12aaf232322239fc1 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Thu, 7 Jul 2022 20:30:48 +0200 Subject: [PATCH 1864/2234] Re-commit (removed non-needed #'tag) --- dnsapi/dns_dnsservices.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 6acb13da..3e004ec4 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -2,7 +2,7 @@ #This file name is "dns_dnsservices.sh" #Script for Danish DNS registra and DNS hosting provider https://dns.services -# + #Author: Bjarke Bruun #Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152 From 5ff095786116aea232954ae07872953b4a6147c4 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Fri, 8 Jul 2022 07:49:20 +0200 Subject: [PATCH 1865/2234] Added empty new line to trigger workflow --- dnsapi/dns_dnsservices.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 3e004ec4..300d0e51 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -229,3 +229,4 @@ deleteRecord() { # Return OK regardless return 0 } + From 41801a60ad2c59ac22bef807b84d845cc1d7d3b7 Mon Sep 17 00:00:00 2001 From: Ry3nlNaToR <49639150+Ry3nlNaToR@users.noreply.github.com> Date: Sat, 9 Jul 2022 14:30:18 +0100 Subject: [PATCH 1866/2234] Also restart postfix --- deploy/mailcow.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/mailcow.sh b/deploy/mailcow.sh index 3492cea4..aa29ae9d 100644 --- a/deploy/mailcow.sh +++ b/deploy/mailcow.sh @@ -67,7 +67,7 @@ mailcow_deploy() { return 1 fi - DEFAULT_MAILCOW_RELOAD="docker restart \$(docker ps --quiet --filter name=nginx-mailcow --filter name=dovecot-mailcow)" + DEFAULT_MAILCOW_RELOAD="docker restart \$(docker ps --quiet --filter name=nginx-mailcow --filter name=dovecot-mailcow --filter name=postfix-mailcow)" _reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}" _info "Run reload: $_reload" From 093cfcdf42a2f25f38c7933042d289011f7ca50d Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 10 Jul 2022 18:01:49 +0800 Subject: [PATCH 1867/2234] Add NetBSD Test by: https://github.com/vmactions/netbsd-vm --- .github/workflows/DNS.yml | 42 +++++++++++++++++++++++ .github/workflows/NetBSD.yml | 65 ++++++++++++++++++++++++++++++++++++ README.md | 30 +++++++++-------- 3 files changed, 123 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/NetBSD.yml diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 2706c72f..5f6cdac9 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -293,5 +293,47 @@ jobs: fi cd ../acmetest ./letest.sh + + NetBSD: + runs-on: macos-12 + needs: OpenBSD + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/netbsd-vm@v0.0.1 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: | + export PKG_PATH="http://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/" + pkg_add curl socat + usesh: true + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh \ No newline at end of file diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml new file mode 100644 index 00000000..d5a98586 --- /dev/null +++ b/.github/workflows/NetBSD.yml @@ -0,0 +1,65 @@ +name: NetBSD +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '.github/workflows/NetBSD.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '.github/workflows/NetBSD.yml' + + +jobs: + NetBSD: + strategy: + matrix: + include: + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + 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: "" + runs-on: macos-12 + env: + TEST_LOCAL: 1 + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + steps: + - uses: actions/checkout@v2 + - uses: vmactions/cf-tunnel@v0.0.3 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/netbsd-vm@v0.0.1 + with: + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + nat: | + "8080": "80" + prepare: | + export PKG_PATH="http://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/" + pkg_add curl socat + usesh: true + run: | + cd ../acmetest \ + && ./letest.sh + + diff --git a/README.md b/README.md index 2f580a57..836664cd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![FreeBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml) [![OpenBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml) +[![NetBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml) [![MacOS](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml) [![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml) [![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml) @@ -70,20 +71,21 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)| Ubuntu |6|NA|pfsense |7|[![OpenBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml)|OpenBSD -|8|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian -|9|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS -|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE -|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl) -|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux -|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora -|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux -|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux -|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia -|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux -|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux -|19|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|20|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) -|21|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) +|8|[![NetBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml)|NetBSD +|9|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian +|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS +|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE +|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl) +|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux +|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora +|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux +|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux +|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia +|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux +|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux +|10|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 +|21|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) +|22|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) Check our [testing project](https://github.com/acmesh-official/acmetest): From ba3e088b238382c76922fcf4a312819292bc75cb Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Thu, 7 Jul 2022 17:32:22 +0200 Subject: [PATCH 1868/2234] Improved error handling Improved error handling when result contains data-structure which might contain another status-flag that is related to the status of the related object and not the api call Revert "Improved error handling" This reverts commit fa6df1cfab134d38baad19fc1caa0842f00416d5. Revert "Revert "Improved error handling"" This reverts commit 5a4b78392f063863ee9f56686f5c429e9376af1b. --- dnsapi/dns_pleskxml.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 0f7dc241..e0b1724b 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -251,9 +251,12 @@ _call_api() { # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. + # Remove structure from result string, since it might contain values that are related to the status of the domain and not to the API request - statuslines_count_total="$(echo "$pleskxml_prettyprint_result" | grep -c '^ *[^<]* *$')" - statuslines_count_okay="$(echo "$pleskxml_prettyprint_result" | grep -c '^ *ok *$')" + statuslines_count_total="$(echo "$pleskxml_prettyprint_result" | sed '//,/<\/data>/d' | grep -c '^ *[^<]* *$')" + statuslines_count_okay="$(echo "$pleskxml_prettyprint_result" | sed '//,/<\/data>/d' | grep -c '^ *ok *$')" + _debug "statuslines_count_total=$statuslines_count_total." + _debug "statuslines_count_okay=$statuslines_count_okay." if [ -z "$statuslines_count_total" ]; then From b41d40da4010bc99bae3966dcc84df4b7b9abbd9 Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Sat, 9 Jul 2022 21:23:50 +0200 Subject: [PATCH 1869/2234] Extended debug logging in dns_pleskxml_rm() --- dnsapi/dns_pleskxml.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index e0b1724b..bcd72d9a 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -152,13 +152,23 @@ dns_pleskxml_rm() { _debug "Got list of DNS TXT records for root domain '$root_domain_name':" _debug "$reclist" - recid="$( + recline="$( _value "$reclist" | grep "${fulldomain}." | - grep "${txtvalue}" | + grep "${txtvalue}" + )" + + _debug "Got line for ${fulldomain}. and ${txtvalue}:" + _debug "$recline" + + recid="$( + _value "$recline" | sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' )" + _debug "Got id from line:" + _debug $recid + if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" _err "Cannot delete TXT record. Exiting." From 55a55e9f74a7c0842ed12d9e76d89b2c3232cdce Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Sat, 9 Jul 2022 21:28:19 +0200 Subject: [PATCH 1870/2234] Fixed debug log to prevent globbing and word splitting. --- dnsapi/dns_pleskxml.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index bcd72d9a..56902e20 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -157,7 +157,7 @@ dns_pleskxml_rm() { grep "${fulldomain}." | grep "${txtvalue}" )" - + _debug "Got line for ${fulldomain}. and ${txtvalue}:" _debug "$recline" @@ -167,7 +167,7 @@ dns_pleskxml_rm() { )" _debug "Got id from line:" - _debug $recid + _debug "$recid" if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" From bc7e02b47a7b04c367e08962a84a63170701f890 Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Sun, 10 Jul 2022 17:11:27 +0200 Subject: [PATCH 1871/2234] Fixed removal of TXT record when subdomain is case-sensitive and improved debug logging Plesk SPI return domain names always lower-case. Therefore the search for domain names in the API response must be case-insensitve. Set debug logging to the values that are reallys used for the spi calls. added comment --- dnsapi/dns_pleskxml.sh | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 56902e20..a8f7f7be 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -145,32 +145,25 @@ dns_pleskxml_rm() { )" if [ -z "$reclist" ]; then - _err "No TXT records found for root domain ${root_domain_name} (Plesk domain ID ${root_domain_id}). Exiting." + _err "No TXT records found for root domain $fulldomain (Plesk domain ID ${root_domain_id}). Exiting." return 1 fi - _debug "Got list of DNS TXT records for root domain '$root_domain_name':" + _debug "Got list of DNS TXT records for root Plesk domain ID ${root_domain_id} of root domain $fulldomain:" _debug "$reclist" - recline="$( - _value "$reclist" | - grep "${fulldomain}." | - grep "${txtvalue}" - )" - - _debug "Got line for ${fulldomain}. and ${txtvalue}:" - _debug "$recline" - + # Extracting the id of the TXT record for the full domain (NOT case-sensitive) and corresponding value recid="$( - _value "$recline" | + _value "$reclist" | + grep -i "${fulldomain}." | + grep "${txtvalue}" | sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' )" - _debug "Got id from line:" - _debug "$recid" + _debug "Got id from line: $recid" if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then - _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" + _err "DNS records for root domain '${fulldomain}.' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" _err "Cannot delete TXT record. Exiting." return 1 fi From ca0981645fd0d855679e19565f59a40096c61fcf Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Sun, 10 Jul 2022 17:34:30 +0200 Subject: [PATCH 1872/2234] Fixed shfmt error --- dnsapi/dns_pleskxml.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index a8f7f7be..799c374c 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -160,7 +160,7 @@ dns_pleskxml_rm() { sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' )" - _debug "Got id from line: $recid" + _debug "Got id from line: $recid" if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then _err "DNS records for root domain '${fulldomain}.' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" From 4d8b661d51489d3f9f3ea139cd5844ed1f250ddb Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 10 Jul 2022 17:38:26 +0200 Subject: [PATCH 1873/2234] dns_world4you: Fix cookie parsing issue Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index bcf256ff..a8d312ad 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -160,24 +160,25 @@ _login() { username="$WORLD4YOU_USERNAME" password="$WORLD4YOU_PASSWORD" csrf_token=$(_get "$WORLD4YOU_API/login" | grep '_csrf_token' | sed 's/^.*]*value=\"\([^"]*\)\".*$/\1/') - sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/') + _parse_sessid export _H1="Cookie: W4YSESSID=$sessid" export _H2="X-Requested-With: XMLHttpRequest" body="_username=$username&_password=$password&_csrf_token=$csrf_token" ret=$(_post "$body" "$WORLD4YOU_API/login" '' POST 'application/x-www-form-urlencoded') unset _H2 + _debug ret "$ret" if _contains "$ret" "\"success\":true"; then _info "Successfully logged in" - sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/') + _parse_sessid else _err "Unable to log in: $(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')" return 1 fi } -# Usage _get_paketnr +# Usage: _get_paketnr _get_paketnr() { fqdn="$1" form="$2" @@ -200,3 +201,8 @@ _get_paketnr() { PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _tail_n 1 | sed "s|.*$WORLD4YOU_API/\\([0-9]*\\)/.*|\\1|") return 0 } + +# Usage: _parse_sessid +_parse_sessid() { + sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | _tail_n 1 | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/') +} From 68c2478e0e205a5eb4de1ad62ed30d5d4c1421a2 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 10 Jul 2022 18:55:36 +0200 Subject: [PATCH 1874/2234] dns_world4you: Handle already logged in sessions Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index a8d312ad..5cb77402 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -49,7 +49,7 @@ dns_world4you_add() { ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded') _resethttp - if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then + if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then res=$(_get "$WORLD4YOU_API/$paketnr/dns") if _contains "$res" "successfully"; then return 0 @@ -66,7 +66,7 @@ dns_world4you_add() { return 1 fi else - _err "$(_head_n 3 <"$HTTP_HEADER")" + _err "$(_head_n 1 <"$HTTP_HEADER")" _err "View $HTTP_HEADER for debugging" return 1 fi @@ -113,7 +113,7 @@ dns_world4you_rm() { ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns/record/delete" '' POST 'application/x-www-form-urlencoded') _resethttp - if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then + if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then res=$(_get "$WORLD4YOU_API/$paketnr/dns") if _contains "$res" "successfully"; then return 0 @@ -130,7 +130,7 @@ dns_world4you_rm() { return 1 fi else - _err "$(_head_n 3 <"$HTTP_HEADER")" + _err "$(_head_n 1 <"$HTTP_HEADER")" _err "View $HTTP_HEADER for debugging" return 1 fi @@ -155,11 +155,22 @@ _login() { _saveaccountconf_mutable WORLD4YOU_USERNAME "$WORLD4YOU_USERNAME" _saveaccountconf_mutable WORLD4YOU_PASSWORD "$WORLD4YOU_PASSWORD" + _resethttp + export ACME_HTTP_NO_REDIRECTS=1 + page=$(_get "$WORLD4YOU_API/login") + _resethttp + + if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then + _info "Already logged in" + _parse_sessid + return 0 + fi + _info "Logging in..." username="$WORLD4YOU_USERNAME" password="$WORLD4YOU_PASSWORD" - csrf_token=$(_get "$WORLD4YOU_API/login" | grep '_csrf_token' | sed 's/^.*]*value=\"\([^"]*\)\".*$/\1/') + csrf_token=$(echo "$page" | grep '_csrf_token' | sed 's/^.*]*value=\"\([^"]*\)\".*$/\1/') _parse_sessid export _H1="Cookie: W4YSESSID=$sessid" From a8f71f79feff9ee3fd4b07352a36b3274f0cf3cb Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 10 Jul 2022 19:25:31 +0200 Subject: [PATCH 1875/2234] dns_world4you: Update error handling Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 5cb77402..e3fff426 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -66,8 +66,8 @@ dns_world4you_add() { return 1 fi else - _err "$(_head_n 1 <"$HTTP_HEADER")" - _err "View $HTTP_HEADER for debugging" + msg=$(echo "$ret" | grep '"form-error-message"' | sed 's/^.*

\([^<]*\)<\/div>.*$/\1/') + _err "Unable to add record: my.world4you.com: $msg" return 1 fi } @@ -130,8 +130,8 @@ dns_world4you_rm() { return 1 fi else - _err "$(_head_n 1 <"$HTTP_HEADER")" - _err "View $HTTP_HEADER for debugging" + msg=$(echo "$ret" | grep "form-error-message" | sed 's/^.*
\([^<]*\)<\/div>.*$/\1/') + _err "Unable to remove record: my.world4you.com: $msg" return 1 fi } @@ -184,7 +184,8 @@ _login() { _info "Successfully logged in" _parse_sessid else - _err "Unable to log in: $(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')" + msg=$(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/') + _err "Unable to log in: my.world4you.com: $msg" return 1 fi } From ed15ff0515eb2c3a708e211b8ff412966f771648 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 10 Jul 2022 20:30:41 +0200 Subject: [PATCH 1876/2234] dns_world4you: Fix upper case fqdn issues Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index e3fff426..0e14b9e8 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -12,7 +12,7 @@ RECORD='' # Usage: dns_world4you_add dns_world4you_add() { - fqdn="$1" + fqdn=$(echo "$1" | tr '[:upper:]' '[:lower:]') value="$2" _info "Using world4you to add record" _debug fulldomain "$fqdn" @@ -74,7 +74,7 @@ dns_world4you_add() { # Usage: dns_world4you_rm dns_world4you_rm() { - fqdn="$1" + fqdn=$(echo "$1" | tr '[:upper:]' '[:lower:]') value="$2" _info "Using world4you to remove record" _debug fulldomain "$fqdn" From 29f12ddaf4920cebc5444d8c31996a433e4868e3 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 10 Jul 2022 22:22:12 +0200 Subject: [PATCH 1877/2234] dns_world4you: Improve error message handling Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 0e14b9e8..67e6d118 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -54,7 +54,7 @@ dns_world4you_add() { if _contains "$res" "successfully"; then return 0 else - msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "]*>[^<]" | sed 's/<[^>]*>\|^\s*//g') + msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "]*>[^<]" | sed 's/<[^>]*>//g' | sed 's/^\s*//g') if [ "$msg" = '' ]; then _err "Unable to add record: Unknown error" echo "$ret" >'error-01.html' @@ -118,7 +118,7 @@ dns_world4you_rm() { if _contains "$res" "successfully"; then return 0 else - msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "]*>[^<]" | sed 's/<[^>]*>\|^\s*//g') + msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "]*>[^<]" | sed 's/<[^>]*>//g' | sed 's/^\s*//g') if [ "$msg" = '' ]; then _err "Unable to remove record: Unknown error" echo "$ret" >'error-01.html' From 80d30bdd30f192cdd9b003d903e20b1f874c72e6 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Mon, 11 Jul 2022 14:08:37 +0200 Subject: [PATCH 1878/2234] Removed empty new line to trigger workflow --- dnsapi/dns_dnsservices.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 300d0e51..3e004ec4 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -229,4 +229,3 @@ deleteRecord() { # Return OK regardless return 0 } - From c1ba4f1b55faad5e2991592cf538681b478f11ad Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Mon, 11 Jul 2022 16:43:34 +0200 Subject: [PATCH 1879/2234] Added forced _log to debug deletion of records in GH Actions --- dnsapi/dns_dnsservices.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 3e004ec4..78588ada 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -64,7 +64,7 @@ dns_dnsservices_rm() { fulldomain=$1 txtvalue=$2 - _info "Using dns.services to delete challenge $fulldomain TXT $txtvalue" + _info "Using dns.services to remove DNS record $fulldomain TXT $txtvalue" _debug rm_fulldomain "$fulldomain" _debug rm_txtvalue "$txtvalue" @@ -204,7 +204,7 @@ deleteRecord() { fulldomain=$1 txtvalue=$2 - _debug2 deleteRecord "Deleting $fulldomain TXT $txtvalue record" + _log deleteRecord "Deleting $fulldomain TXT $txtvalue record" if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then _get_root "$fulldomain" From df199c5788972aec58e40a1e9e05e844bfe15f7c Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Mon, 11 Jul 2022 18:11:55 +0200 Subject: [PATCH 1880/2234] Updated API call for OpenBSD sed and tr as newlines does not work there --- dnsapi/dns_dnsservices.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 78588ada..d591ce3b 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -156,12 +156,13 @@ _get_root() { fi # Setup variables used by other functions to communicate with DNS.Services API - zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") + #zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") + zoneInfo=$(echo -e "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g') rootZoneName="$rootZone" subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")" subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")" - rootZoneDomainID=$(echo "$zoneInfo" | tr ',' '\n' | grep domain_id | cut -d'"' -f4) - rootZoneServiceID=$(echo "$zoneInfo" | tr ',' '\n' | grep service_id | cut -d'"' -f4) + rootZoneDomainID=$(echo -e "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g') + rootZoneServiceID=$(echo -e "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"service_id":")([^"]*)"(.*)$,\2,g') _debug2 _get_root "Root zone name : $rootZoneName" _debug2 _get_root "Root zone domain ID : $rootZoneDomainID" @@ -190,7 +191,7 @@ createRecord() { result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST") _debug2 createRecord "result from API: $result" - if [ "$(echo "$result" | grep '"success":true')" = "" ]; then + if [ "$(echo "$result" | _egrep_o "\"success\":true")" = "" ]; then _err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName" _err "$result" return 1 @@ -211,7 +212,7 @@ deleteRecord() { fi result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" - recordInfo="$(echo "$result" | tr '}' '\n' | grep "\"name\":\"${fulldomain}" | grep "\"content\":\"" | grep "${txtvalue}")" + recordInfo="$(echo "$result" | tr '}' '\n' | _egrep_o "\"name\":\"${fulldomain}" | _egrep_o "\"content\":\"" | grep "${txtvalue}")" _debug2 deleteRecord "recordInfo=$recordInfo" recordID="$(echo "$recordInfo" | tr ',' '\n' | _egrep_o "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" From ae71a5abf629b937e23e06410a41ac45a009a575 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Mon, 11 Jul 2022 18:16:03 +0200 Subject: [PATCH 1881/2234] Added debug for API result --- dnsapi/dns_dnsservices.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index d591ce3b..f87509c2 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -157,13 +157,14 @@ _get_root() { # Setup variables used by other functions to communicate with DNS.Services API #zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") - zoneInfo=$(echo -e "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g') + zoneInfo=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g' | grep "\"$rootZone\"") rootZoneName="$rootZone" subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")" subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")" - rootZoneDomainID=$(echo -e "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g') - rootZoneServiceID=$(echo -e "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"service_id":")([^"]*)"(.*)$,\2,g') + rootZoneDomainID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g') + rootZoneServiceID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"service_id":")([^"]*)"(.*)$,\2,g') + _debug2 _zoneInfo "Zone info from API : $zoneInfo" _debug2 _get_root "Root zone name : $rootZoneName" _debug2 _get_root "Root zone domain ID : $rootZoneDomainID" _debug2 _get_root "Root zone service ID: $rootZoneServiceID" From b1b336804d624287cf885c61a16f925ca4569255 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Tue, 12 Jul 2022 16:26:45 +0200 Subject: [PATCH 1882/2234] Fixed a missed 'grep -o' to _egrep_o() --- dnsapi/dns_dnsservices.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index f87509c2..82e9b5c5 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -146,7 +146,7 @@ _get_root() { fi done) else - rootZone=$(echo "$result" | grep -o '"name":"[^"]*' | cut -d'"' -f4) + rootZone=$(echo "$result" | _egrep_o '"name":"[^"]*' | cut -d'"' -f4) _debug2 _get_root "- only found 1 domain in API: $rootZone" fi From e4387e4aad97f1296ef49681433afb2ac95a75e8 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Tue, 12 Jul 2022 22:04:28 +0200 Subject: [PATCH 1883/2234] Updated delete function --- dnsapi/dns_dnsservices.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 82e9b5c5..f2a7608e 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -213,9 +213,10 @@ deleteRecord() { fi result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" - recordInfo="$(echo "$result" | tr '}' '\n' | _egrep_o "\"name\":\"${fulldomain}" | _egrep_o "\"content\":\"" | grep "${txtvalue}")" - _debug2 deleteRecord "recordInfo=$recordInfo" - recordID="$(echo "$recordInfo" | tr ',' '\n' | _egrep_o "\"id\":\"[0-9]+\"" | cut -d'"' -f4)" + recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")" + recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')" + recordDomainID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g')" + recordName="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g')" if [ -z "$recordID" ]; then _info "Record $fulldomain TXT $txtvalue not found or already deleted" @@ -225,8 +226,10 @@ deleteRecord() { fi _debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" + _log "curl DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")" _debug2 deleteRecord "API Delete result \"$result\"" + _log "curl API Delete result \"$result\"" # Return OK regardless return 0 From 5f44c195e99d1e415d2f490412347dbf2e52dc15 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Tue, 12 Jul 2022 22:10:20 +0200 Subject: [PATCH 1884/2234] Removed unused variable --- dnsapi/dns_dnsservices.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index f2a7608e..9d913d39 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -215,8 +215,8 @@ deleteRecord() { result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")" recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')" - recordDomainID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g')" - recordName="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g')" + #recordDomainID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g')" + #recordName="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g')" if [ -z "$recordID" ]; then _info "Record $fulldomain TXT $txtvalue not found or already deleted" From e5aeff50dc52febc6b44e22e258950732a2049e1 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Tue, 12 Jul 2022 22:20:24 +0200 Subject: [PATCH 1885/2234] Removed spaces (shfmt) --- dnsapi/dns_dnsservices.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 9d913d39..71ed705d 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -213,10 +213,8 @@ deleteRecord() { fi result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" - recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")" - recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')" - #recordDomainID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g')" - #recordName="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g')" + recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")" + recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')" if [ -z "$recordID" ]; then _info "Record $fulldomain TXT $txtvalue not found or already deleted" From bcc967933926d71507a06eca2497fd7223a717d4 Mon Sep 17 00:00:00 2001 From: Bjarke Bruun Date: Tue, 12 Jul 2022 22:21:38 +0200 Subject: [PATCH 1886/2234] Removed spaces (shfmt) (missed one) --- dnsapi/dns_dnsservices.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 71ed705d..9f2220fe 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -213,7 +213,7 @@ deleteRecord() { fi result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" - recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")" + recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")" recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')" if [ -z "$recordID" ]; then From e2eb685d76311761b5516830b81093892ab73375 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 13 Jul 2022 21:06:57 +0800 Subject: [PATCH 1887/2234] upgrade FreeBSD 13.1 --- .github/workflows/DNS.yml | 2 +- .github/workflows/FreeBSD.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 5f6cdac9..720cfaab 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -188,7 +188,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.4 + - uses: vmactions/freebsd-vm@v0.1.7 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 4d310f05..6f8797db 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.5 + - uses: vmactions/freebsd-vm@v0.1.7 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From 3a29e0345852733b5690d8e40f9110330d009b41 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Thu, 14 Jul 2022 11:25:59 +0200 Subject: [PATCH 1888/2234] dns_world4you: Use _lower_case instead of tr Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index 67e6d118..a0a83c37 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -12,7 +12,7 @@ RECORD='' # Usage: dns_world4you_add dns_world4you_add() { - fqdn=$(echo "$1" | tr '[:upper:]' '[:lower:]') + fqdn=$(echo "$1" | _lower_case) value="$2" _info "Using world4you to add record" _debug fulldomain "$fqdn" @@ -74,7 +74,7 @@ dns_world4you_add() { # Usage: dns_world4you_rm dns_world4you_rm() { - fqdn=$(echo "$1" | tr '[:upper:]' '[:lower:]') + fqdn=$(echo "$1" | _lower_case) value="$2" _info "Using world4you to remove record" _debug fulldomain "$fqdn" From 19790e9011bba37365e80adebfd27ae12d2322e5 Mon Sep 17 00:00:00 2001 From: Maxime-J Date: Thu, 14 Jul 2022 10:54:37 +0000 Subject: [PATCH 1889/2234] dns_ovh: save OVH_CK in all cases --- dnsapi/dns_ovh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index b382e52f..2252f03a 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -118,6 +118,7 @@ _initAuth() { #return and wait for retry. return 1 fi + _saveaccountconf OVH_CK "$OVH_CK" _info "Checking authentication" @@ -235,7 +236,6 @@ _ovh_authentication() { _secure_debug consumerKey "$consumerKey" OVH_CK="$consumerKey" - _saveaccountconf OVH_CK "$OVH_CK" _info "Please open this link to do authentication: $(__green "$validationUrl")" From bd73823828f7d8009b7e0f0ec233b97c62c2754c Mon Sep 17 00:00:00 2001 From: spider Date: Fri, 15 Jul 2022 13:31:19 +0600 Subject: [PATCH 1890/2234] reg.ru list unicode domains NOT in IDN code --- dnsapi/dns_regru.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index 2a1ebaa5..8ff380f0 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -92,10 +92,10 @@ _get_root() { domains_list=$(echo "${response}" | grep dname | sed -r "s/.*dname=\"([^\"]+)\".*/\\1/g") for ITEM in ${domains_list}; do - IDN_ITEM="$(_idn "${ITEM}")" + IDN_ITEM=${ITEM} case "${domain}" in *${IDN_ITEM}*) - _domain=${IDN_ITEM} + _domain="$(_idn "${ITEM}")" _debug _domain "${_domain}" return 0 ;; From 927c003d22dbc9e14250e6e1f993df028aed91d8 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Fri, 15 Jul 2022 14:17:32 +0200 Subject: [PATCH 1891/2234] More robust and shortend egrep --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index eb95902f..38a8f8de 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"[^\"]*\":{[^}]*}},\"transferkeyalgo\":{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^}]*}},\"transferkey\":\"[^\"]*\"(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"\":{[^}]*}}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" _host=$(printf "%s" "$domain" | cut -d . -f 1-$p) From 0e73128f40f3f898b060c1a159213d0be3dc7e15 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Fri, 15 Jul 2022 16:42:20 +0200 Subject: [PATCH 1892/2234] Finaly found a regex wich works for sed and egrep -o and use searchDomain api for easier to parse response --- dnsapi/dns_opnsense.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 38a8f8de..937f4aa5 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -137,7 +137,7 @@ _get_root() { domain=$1 i=2 p=1 - if _opns_rest "GET" "/domain/get"; then + if _opns_rest "GET" "/domain/searchDomain"; then _domain_response="$response" else return 1 @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"\":{[^}]*}}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"master\",[^.]*,\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" _host=$(printf "%s" "$domain" | cut -d . -f 1-$p) From 0b8ae6821303742ebd9ed4423f9c7b64836c9513 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Fri, 15 Jul 2022 16:50:38 +0200 Subject: [PATCH 1893/2234] Fix: cut for domain uuid with searchDOmain response --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 937f4aa5..96d4b788 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"master\",[^.]*,\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"master\",[^.]*,\"domainname\":\"${h}\"" | cut -d ':' -f 2 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" _host=$(printf "%s" "$domain" | cut -d . -f 1-$p) From c485011ed1d714540163013f14418dce937dbac1 Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sat, 16 Jul 2022 14:16:03 +0200 Subject: [PATCH 1894/2234] Multidomain patch suggestion from Sandeep Mittal --- dnsapi/dns_cpanel.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index f91725a4..0c9def67 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -120,7 +120,7 @@ _myget() { _get_root() { _myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones' - _domains=$(echo "$_result" | sed 's/.*\(zones.*\[\).*/\1/' | cut -d':' -f2 | sed 's/"//g' | sed 's/{//g') + _domains=$(echo "$_result" | _egrep_o '"[a-z0-9\.\-]*":\["; cPanel first' | cut -d':' -f1 | sed 's/"//g' | sed 's/{//g') _debug "_result is: $_result" _debug "_domains is: $_domains" if [ -z "$_domains" ]; then @@ -146,7 +146,7 @@ _findentry() { _debug "In _findentry" #returns id of dns entry, if it exists _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain" - _id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain.*$txtvalue\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1) + _id=$(echo "$_result" | sed -e "s/},{/},\n{/g" | grep "$fulldomain" | grep "$txtvalue" | _egrep_o 'line":[0-9]+' | cut -d ':' -f 2) _debug "_result is: $_result" _debug "fulldomain. is $fulldomain." _debug "txtvalue is $txtvalue" From 2fb9c923f4c3ffad2806f4ef6a941466b417f83e Mon Sep 17 00:00:00 2001 From: Bjarne Saltbaek Date: Sat, 16 Jul 2022 14:35:49 +0200 Subject: [PATCH 1895/2234] push for re-test --- dnsapi/dns_cpanel.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index 0c9def67..053b3ff3 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -13,6 +13,7 @@ # cPanel_Hostname=hostname # # Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" + # Used to add txt record dns_cpanel_add() { fulldomain=$1 From c0097497be609609743f861a49005ae9c2666b3f Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 17 Jul 2022 11:48:58 +0800 Subject: [PATCH 1896/2234] Upgrade FreeBSD version https://github.com/vmactions/freebsd-vm --- .github/workflows/FreeBSD.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 6f8797db..027b7caf 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.7 + - uses: vmactions/freebsd-vm@v0.1.8 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From ddabc38e3f8be529dc5e4b466c380f0ceb63d018 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 17 Jul 2022 11:49:58 +0800 Subject: [PATCH 1897/2234] upgrade OpenBSD https://github.com/vmactions/openbsd-vm --- .github/workflows/OpenBSD.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 2b974a81..0d3465de 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0.0.1 + - uses: vmactions/openbsd-vm@v0.0.4 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From 3e628f267805caf8c5b3271fe53abb8bd3a73055 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 17 Jul 2022 11:53:23 +0800 Subject: [PATCH 1898/2234] Upgrade NetBSD https://github.com/vmactions/netbsd-vm --- .github/workflows/DNS.yml | 6 +++--- .github/workflows/NetBSD.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 720cfaab..b9389438 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -188,7 +188,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.7 + - uses: vmactions/freebsd-vm@v0.1.8 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl @@ -270,7 +270,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0.0.1 + - uses: vmactions/openbsd-vm@v0.0.4 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg_add socat curl @@ -310,7 +310,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v0.0.1 + - uses: vmactions/netbsd-vm@v0.0.2 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index d5a98586..609d1131 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v0.0.1 + - uses: vmactions/netbsd-vm@v0.0.2 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From 0717f8591c89a32dd6c474b4cfe28aac7d493e86 Mon Sep 17 00:00:00 2001 From: Aleksandr Kunin Date: Sun, 17 Jul 2022 21:15:47 +0700 Subject: [PATCH 1899/2234] Update to Vultr Api v2 - change endpoints - change Api-Key header to Authorization: Bearer --- dnsapi/dns_vultr.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh index 84857966..bd925fdb 100644 --- a/dnsapi/dns_vultr.sh +++ b/dnsapi/dns_vultr.sh @@ -3,10 +3,10 @@ # #VULTR_API_KEY=000011112222333344445555666677778888 -VULTR_Api="https://api.vultr.com/v1" +VULTR_Api="https://api.vultr.com/v2" ######## Public functions ##################### - +# #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_vultr_add() { fulldomain=$1 @@ -31,14 +31,14 @@ dns_vultr_add() { _debug _domain "$_domain" _debug 'Getting txt records' - _vultr_rest GET "dns/records?domain=$_domain" + _vultr_rest GET "domains/$_domain/records" if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then _err 'Error' return 1 fi - if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then + if ! _vultr_rest POST "domains/$_domain/records" "{\"name\":\"$_sub_domain\",\"data\":\"$txtvalue\",\"type\":\"TXT\"}"; then _err "$response" return 1 fi @@ -71,14 +71,14 @@ dns_vultr_rm() { _debug _domain "$_domain" _debug 'Getting txt records' - _vultr_rest GET "dns/records?domain=$_domain" + _vultr_rest GET "domains/$_domain/records" if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then _err 'Error' return 1 fi - _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)" + _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'id' | cut -d : -f 2)" _debug _record_id "$_record_id" if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." @@ -87,7 +87,7 @@ dns_vultr_rm() { return 0 fi - if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then + if ! _vultr_rest DELETE "domains/$_domain/records/$_record_id"; then _err "$response" return 1 fi @@ -112,11 +112,11 @@ _get_root() { return 1 fi - if ! _vultr_rest GET "dns/list"; then + if ! _vultr_rest GET "domains"; then return 1 fi - if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then + if printf "%s\n" "$response" | grep '^\{.*\}' >/dev/null; then if _contains "$response" "\"domain\":\"$_domain\""; then _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" return 0 @@ -141,8 +141,8 @@ _vultr_rest() { api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"') - export _H1="Api-Key: $api_key_trimmed" - export _H2='Content-Type: application/x-www-form-urlencoded' + export _H1="Authorization: Bearer $api_key_trimmed" + export _H2='Content-Type: application/json' if [ "$m" != "GET" ]; then _debug data "$data" From bc920949cba1eb73cbb2f5fd38e2d489096e054d Mon Sep 17 00:00:00 2001 From: Grigory Starinkin Date: Mon, 18 Jul 2022 10:50:50 +0100 Subject: [PATCH 1900/2234] Add Slack App notification hook Slack Incoming webhooks is a legacy custom integration - an outdated way for teams to integrate with Slack. These integrations lack newer features and they will be deprecated and possibly removed in the future. Slack team do not recommend their use. Instead, it's suggested to use Slack apps. --- notify/slack_app.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100755 notify/slack_app.sh diff --git a/notify/slack_app.sh b/notify/slack_app.sh new file mode 100755 index 00000000..5b012a41 --- /dev/null +++ b/notify/slack_app.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env sh + +#Support Slack APP notifications + +#SLACK_APP_CHANNEL="" +#SLACK_APP_TOKEN="" + +slack_app_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + SLACK_APP_CHANNEL="${SLACK_APP_CHANNEL:-$(_readaccountconf_mutable SLACK_APP_CHANNEL)}" + if [ -n "$SLACK_APP_CHANNEL" ]; then + _saveaccountconf_mutable SLACK_APP_CHANNEL "$SLACK_APP_CHANNEL" + fi + + SLACK_APP_TOKEN="${SLACK_APP_TOKEN:-$(_readaccountconf_mutable SLACK_APP_TOKEN)}" + if [ -n "$SLACK_APP_TOKEN" ]; then + _saveaccountconf_mutable SLACK_APP_TOKEN "$SLACK_APP_TOKEN" + fi + + _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" + _data="{\"text\": \"$_content\", " + if [ -n "$SLACK_APP_CHANNEL" ]; then + _data="$_data\"channel\": \"$SLACK_APP_CHANNEL\", " + fi + _data="$_data\"mrkdwn\": \"true\"}" + + export _H1="Authorization: Bearer $SLACK_APP_TOKEN" + + SLACK_APP_API_URL="https://slack.com/api/chat.postMessage" + if _post "$_data" "$SLACK_APP_API_URL" "" "POST" "application/json; charset=utf-8"; then + SLACK_APP_RESULT_OK=$(echo "$response" | _egrep_o 'ok" *: *true') + if [ "$?" = "0" ] && [ "$SLACK_APP_RESULT_OK" ]; then + _info "slack send success." + return 0 + fi + fi + _err "slack send error." + _err "$response" + return 1 +} From d8a4e47a130fd87953bf9c495d3fcc1897848a89 Mon Sep 17 00:00:00 2001 From: Grigory Starinkin Date: Mon, 18 Jul 2022 17:20:25 +0100 Subject: [PATCH 1901/2234] disable "$response is referenced but not assigned" warning the variable is assigned by the `_post` call --- notify/slack_app.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/notify/slack_app.sh b/notify/slack_app.sh index 5b012a41..84d4733a 100755 --- a/notify/slack_app.sh +++ b/notify/slack_app.sh @@ -32,6 +32,7 @@ slack_app_send() { SLACK_APP_API_URL="https://slack.com/api/chat.postMessage" if _post "$_data" "$SLACK_APP_API_URL" "" "POST" "application/json; charset=utf-8"; then + # shellcheck disable=SC2154 SLACK_APP_RESULT_OK=$(echo "$response" | _egrep_o 'ok" *: *true') if [ "$?" = "0" ] && [ "$SLACK_APP_RESULT_OK" ]; then _info "slack send success." From 328dbd57d426c64ebead7318a22827e958c053bc Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 24 Jul 2022 16:20:44 +0800 Subject: [PATCH 1902/2234] fix for solaris --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3d65612f..ef37f163 100755 --- a/acme.sh +++ b/acme.sh @@ -1196,7 +1196,7 @@ _createkey() { _is_idn() { _is_idn_d="$1" _debug2 _is_idn_d "$_is_idn_d" - _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '0-9' | tr -d 'a-z' | tr -d 'A-Z' | tr -d '*.,-_') + _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d [0-9] | tr -d [a-z] | tr -d [A-Z] | tr -d '*.,-_') _debug2 _idn_temp "$_idn_temp" [ "$_idn_temp" ] } From a3784854a7903c05949d15185235c7680c12bd1b Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 26 Jul 2022 13:20:00 +0800 Subject: [PATCH 1903/2234] fix https://github.com/acmesh-official/acme.sh/issues/3975 --- dnsapi/dns_ispconfig.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 6f0e920f..560f073e 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -32,6 +32,10 @@ dns_ispconfig_rm() { #################### Private functions below ################################## _ISPC_credentials() { + ISPC_User="${ISPC_User:-$(_readaccountconf_mutable ISPC_User)}" + ISPC_Password="${ISPC_Password:-$(_readaccountconf_mutable ISPC_Password)}" + ISPC_Api="${ISPC_Api:-$(_readaccountconf_mutable ISPC_Api)}" + ISPC_Api_Insecure="${ISPC_Api_Insecure:-$(_readaccountconf_mutable ISPC_Api_Insecure)}" if [ -z "${ISPC_User}" ] || [ -z "${ISPC_Password}" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then ISPC_User="" ISPC_Password="" @@ -40,10 +44,10 @@ _ISPC_credentials() { _err "You haven't specified the ISPConfig Login data, URL and whether you want check the ISPC SSL cert. Please try again." return 1 else - _saveaccountconf ISPC_User "${ISPC_User}" - _saveaccountconf ISPC_Password "${ISPC_Password}" - _saveaccountconf ISPC_Api "${ISPC_Api}" - _saveaccountconf ISPC_Api_Insecure "${ISPC_Api_Insecure}" + _saveaccountconf_mutable ISPC_User "${ISPC_User}" + _saveaccountconf_mutable ISPC_Password "${ISPC_Password}" + _saveaccountconf_mutable ISPC_Api "${ISPC_Api}" + _saveaccountconf_mutable ISPC_Api_Insecure "${ISPC_Api_Insecure}" # Set whether curl should use secure or insecure mode export HTTPS_INSECURE="${ISPC_Api_Insecure}" fi From 7843c0c1b0870d199f06278e635277e2fe00ab00 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 27 Jul 2022 21:19:36 +0800 Subject: [PATCH 1904/2234] Upgrade VM versions from https://github.com/vmactions --- .github/workflows/DNS.yml | 6 +++--- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/NetBSD.yml | 2 +- .github/workflows/OpenBSD.yml | 2 +- .github/workflows/Solaris.yml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index b9389438..52753a79 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -188,7 +188,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.8 + - uses: vmactions/freebsd-vm@v0.2.0 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl @@ -270,7 +270,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0.0.4 + - uses: vmactions/openbsd-vm@v0.0.6 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg_add socat curl @@ -310,7 +310,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v0.0.2 + - uses: vmactions/netbsd-vm@v0.0.4 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 027b7caf..52f13fbb 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.1.8 + - uses: vmactions/freebsd-vm@v0.2.0 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 609d1131..83ae1cf3 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v0.0.2 + - uses: vmactions/netbsd-vm@v0.0.4 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 0d3465de..69acf66d 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0.0.4 + - uses: vmactions/openbsd-vm@v0.0.6 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 6ba0e414..a4b179b7 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.5 + - uses: vmactions/solaris-vm@v0.0.6 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From 64fda951861bb43cc3976ce6573182e967fb1532 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 27 Jul 2022 22:09:22 +0800 Subject: [PATCH 1905/2234] Upgrade solaris by https://github.com/vmactions/solaris-vm --- .github/workflows/Solaris.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index a4b179b7..e2336ed6 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -49,9 +49,10 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.6 + - uses: vmactions/solaris-vm@v0.0.7 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + copyback: "false" nat: | "8080": "80" prepare: pkgutil -y -i socat curl From 1ea8cfbfb04609871fb3dc3b3037f734f9b7114d Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 27 Jul 2022 22:15:38 +0800 Subject: [PATCH 1906/2234] Add DragonFlyBSD test by https://github.com/vmactions/dragonflybsd-vm --- .github/workflows/DNS.yml | 42 ++++++++++++++++++- .github/workflows/DragonFlyBSD.yml | 65 ++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/DragonFlyBSD.yml diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 52753a79..a3564d27 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -336,4 +336,44 @@ jobs: cd ../acmetest ./letest.sh - \ No newline at end of file + DragonFlyBSD: + runs-on: macos-12 + needs: NetBSD + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/dragonflybsd-vm@v0.0.3 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: | + pkg install -y curl socat + usesh: true + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml new file mode 100644 index 00000000..4836a08b --- /dev/null +++ b/.github/workflows/DragonFlyBSD.yml @@ -0,0 +1,65 @@ +name: DragonFlyBSD +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '.github/workflows/DragonFlyBSD.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '.github/workflows/DragonFlyBSD.yml' + + +jobs: + DragonFlyBSD: + strategy: + matrix: + include: + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + 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: "" + runs-on: macos-12 + env: + TEST_LOCAL: 1 + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + steps: + - uses: actions/checkout@v2 + - uses: vmactions/cf-tunnel@v0.0.3 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/dragonflybsd-vm@v0.0.3 + with: + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + copyback: "false" + nat: | + "8080": "80" + prepare: | + pkg install -y curl socat + usesh: true + run: | + cd ../acmetest \ + && ./letest.sh + + From 1a140a55155ce60342956444e67df12d334f3153 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 27 Jul 2022 22:17:35 +0800 Subject: [PATCH 1907/2234] upgrade OpenBSD by https://github.com/vmactions/openbsd-vm --- .github/workflows/DNS.yml | 2 +- .github/workflows/OpenBSD.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index a3564d27..e039653f 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -270,7 +270,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0.0.6 + - uses: vmactions/openbsd-vm@v0.0.7 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg_add socat curl diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 69acf66d..9c8a807c 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0.0.6 + - uses: vmactions/openbsd-vm@v0.0.7 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | From 2d144a8b435297bf3f99717978682e6ceaf7079a Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 27 Jul 2022 22:22:34 +0800 Subject: [PATCH 1908/2234] Add DragonFlyBSD test by https://github.com/vmactions/dragonflybsd-vm --- README.md | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 836664cd..27e933ca 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ [![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml) [![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml) [![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml) +[![DragonFlyBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml) + ![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) @@ -72,20 +74,21 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |6|NA|pfsense |7|[![OpenBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml)|OpenBSD |8|[![NetBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml)|NetBSD -|9|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian -|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS -|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE -|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl) -|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux -|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora -|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux -|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux -|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia -|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux -|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux -|10|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|21|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) -|22|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) +|9|[![DragonFlyBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml)|DragonFlyBSD +|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian +|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS +|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE +|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl) +|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux +|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora +|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux +|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux +|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia +|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux +|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux +|11|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 +|22|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) +|23|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) Check our [testing project](https://github.com/acmesh-official/acmetest): From 0de3bf0ac76f49c30d4584e78495a141f5c9a4b8 Mon Sep 17 00:00:00 2001 From: msys0843 <110224197+msys0843@users.noreply.github.com> Date: Fri, 29 Jul 2022 18:09:57 +0900 Subject: [PATCH 1909/2234] Update dns_mydnsjp.sh To fit current mydns.jp web site. --- dnsapi/dns_mydnsjp.sh | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/dnsapi/dns_mydnsjp.sh b/dnsapi/dns_mydnsjp.sh index aab2aabf..13866f70 100755 --- a/dnsapi/dns_mydnsjp.sh +++ b/dnsapi/dns_mydnsjp.sh @@ -150,7 +150,7 @@ _get_root() { _mydnsjp_retrieve_domain() { _debug "Login to MyDNS.JP" - response="$(_post "masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/?MENU=100")" + response="$(_post "MENU=100&masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/members/")" cookie="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)" # If cookies is not empty then logon successful @@ -159,22 +159,8 @@ _mydnsjp_retrieve_domain() { return 1 fi - _debug "Retrieve DOMAIN INFO page" - - export _H1="Cookie:${cookie}" - - response="$(_get "$MYDNSJP_API/?MENU=300")" - - if [ "$?" != "0" ]; then - _err "Fail to retrieve DOMAIN INFO." - return 1 - fi - _root_domain=$(echo "$response" | grep "DNSINFO\[domainname\]" | sed 's/^.*value="\([^"]*\)".*/\1/') - # Logout - response="$(_get "$MYDNSJP_API/?MENU=090")" - _debug _root_domain "$_root_domain" if [ -z "$_root_domain" ]; then From bd78120bd5946763248da60167adc99f6bb2c2b1 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 30 Jul 2022 08:53:44 +0800 Subject: [PATCH 1910/2234] Use major version of https://github.com/vmactions/freebsd-vm --- .github/workflows/DNS.yml | 10 +++++----- .github/workflows/DragonFlyBSD.yml | 2 +- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/NetBSD.yml | 2 +- .github/workflows/OpenBSD.yml | 2 +- .github/workflows/Solaris.yml | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index e039653f..538a1cfc 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -188,7 +188,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.2.0 + - uses: vmactions/freebsd-vm@v0 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl @@ -228,7 +228,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.5 + - uses: vmactions/solaris-vm@v0 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkgutil -y -i socat @@ -270,7 +270,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0.0.7 + - uses: vmactions/openbsd-vm@v0 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg_add socat curl @@ -310,7 +310,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v0.0.4 + - uses: vmactions/netbsd-vm@v0 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | @@ -352,7 +352,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/dragonflybsd-vm@v0.0.3 + - uses: vmactions/dragonflybsd-vm@v0 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index 4836a08b..76af8b30 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/dragonflybsd-vm@v0.0.3 + - uses: vmactions/dragonflybsd-vm@v0 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' copyback: "false" diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 52f13fbb..676b67c7 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.2.0 + - uses: vmactions/freebsd-vm@v0 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 83ae1cf3..616dfc39 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v0.0.4 + - uses: vmactions/netbsd-vm@v0 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 9c8a807c..4f17780f 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0.0.7 + - uses: vmactions/openbsd-vm@v0 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index e2336ed6..53386752 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -49,7 +49,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0.0.7 + - uses: vmactions/solaris-vm@v0 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' copyback: "false" From 8a1f038a80bbb9fbd762f73682c7cc329732d1ba Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 30 Jul 2022 21:45:58 +0800 Subject: [PATCH 1911/2234] add issue.yml --- .github/workflows/issue.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/issue.yml diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml new file mode 100644 index 00000000..7e44e5ae --- /dev/null +++ b/.github/workflows/issue.yml @@ -0,0 +1,18 @@ +name: "Update issues" +on: + issues: + types: [opened] + +jobs: + comment: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'Please provode the log with `--debug 2` if this is a bug report.' + }) \ No newline at end of file From f91aeea91cdcf4d2c3524e0ddb1c870befd2b8fa Mon Sep 17 00:00:00 2001 From: Bill Gertz Date: Tue, 2 Aug 2022 19:01:16 +0200 Subject: [PATCH 1912/2234] Update dns_miab.sh Added an explicit no error (0) return on the internal _retrieve_miab_env() function. This was causing errors when acme.sh was not run with a debug level. --- dnsapi/dns_miab.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 7e697704..dad69bde 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -163,6 +163,7 @@ _retrieve_miab_env() { _saveaccountconf_mutable MIAB_Username "$MIAB_Username" _saveaccountconf_mutable MIAB_Password "$MIAB_Password" _saveaccountconf_mutable MIAB_Server "$MIAB_Server" + return 0 } #Useage: _miab_rest "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" "custom/_acme-challenge.www.domain.com/txt "POST" From 51d4d1451a10ae5dd4f859e4f8f7fdb33ed8cd17 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 3 Aug 2022 20:55:25 +0800 Subject: [PATCH 1913/2234] use ${{ secrets.DEBUG }} https://github.com/acmesh-official/acme.sh/issues/4215 --- .github/workflows/DNS.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 538a1cfc..ca6631dd 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -53,7 +53,7 @@ jobs: TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 - DEBUG: 1 + DEBUG: ${{ secrets.DEBUG }} steps: - uses: actions/checkout@v2 - name: Clone acmetest @@ -92,7 +92,7 @@ jobs: TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 - DEBUG: 1 + DEBUG: ${{ secrets.DEBUG }} steps: - uses: actions/checkout@v2 - name: Install tools @@ -130,7 +130,7 @@ jobs: TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 - DEBUG: 1 + DEBUG: ${{ secrets.DEBUG }} steps: - name: Set git to use LF run: | @@ -183,7 +183,7 @@ jobs: TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 - DEBUG: 1 + DEBUG: ${{ secrets.DEBUG }} steps: - uses: actions/checkout@v2 - name: Clone acmetest @@ -223,7 +223,7 @@ jobs: TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 - DEBUG: 1 + DEBUG: ${{ secrets.DEBUG }} steps: - uses: actions/checkout@v2 - name: Clone acmetest @@ -265,7 +265,7 @@ jobs: TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 - DEBUG: 1 + DEBUG: ${{ secrets.DEBUG }} steps: - uses: actions/checkout@v2 - name: Clone acmetest @@ -305,7 +305,7 @@ jobs: TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 - DEBUG: 1 + DEBUG: ${{ secrets.DEBUG }} steps: - uses: actions/checkout@v2 - name: Clone acmetest @@ -347,7 +347,7 @@ jobs: TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi TEST_LOCAL: 1 - DEBUG: 1 + DEBUG: ${{ secrets.DEBUG }} steps: - uses: actions/checkout@v2 - name: Clone acmetest From d0c2fb97616c6e395185b5bd2b711bf9604cfff7 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 3 Aug 2022 23:07:02 +0800 Subject: [PATCH 1914/2234] fix https://github.com/acmesh-official/acme.sh/issues/3833#issuecomment-1203652970 --- .github/workflows/DNS.yml | 6 +++++- .github/workflows/FreeBSD.yml | 1 + .github/workflows/NetBSD.yml | 1 + .github/workflows/OpenBSD.yml | 1 + acme.sh | 18 ++++-------------- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index ca6631dd..ac1937af 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -193,6 +193,7 @@ jobs: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl usesh: true + copyback: false run: | if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} @@ -231,6 +232,7 @@ jobs: - uses: vmactions/solaris-vm@v0 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + copyback: false prepare: pkgutil -y -i socat run: | pkg set-mediator -v -I default@1.1 openssl @@ -275,6 +277,7 @@ jobs: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg_add socat curl usesh: true + copyback: false run: | if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} @@ -314,9 +317,9 @@ jobs: with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | - export PKG_PATH="http://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/" pkg_add curl socat usesh: true + copyback: false run: | if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} @@ -358,6 +361,7 @@ jobs: prepare: | pkg install -y curl socat usesh: true + copyback: false run: | if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 676b67c7..74b69745 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -56,6 +56,7 @@ jobs: "8080": "80" prepare: pkg install -y socat curl usesh: true + copyback: false run: | cd ../acmetest \ && ./letest.sh diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 616dfc39..84bf96b8 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -58,6 +58,7 @@ jobs: export PKG_PATH="http://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/" pkg_add curl socat usesh: true + copyback: false run: | cd ../acmetest \ && ./letest.sh diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 4f17780f..6aba1b2a 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -56,6 +56,7 @@ jobs: "8080": "80" prepare: pkg_add socat curl usesh: true + copyback: false run: | cd ../acmetest \ && ./letest.sh diff --git a/acme.sh b/acme.sh index ef37f163..9ac8caf9 100755 --- a/acme.sh +++ b/acme.sh @@ -436,24 +436,14 @@ _secure_debug3() { fi } -__USE_TR_RAW="$([ "$(echo "abc" | tr a-z A-Z 2>/dev/null)" = "ABC" ] && echo 1 || echo 0)" - _upper_case() { - if [ "$__USE_TR_RAW" = "0" ]; then - tr '[:lower:]' '[:upper:]' - else - # shellcheck disable=SC2018,SC2019 - tr 'a-z' 'A-Z' - fi + # shellcheck disable=SC2018,SC2019 + tr '[a-z]' '[A-Z]' } _lower_case() { - if [ "$__USE_TR_RAW" = "0" ]; then - tr '[:upper:]' '[:lower:]' - else - # shellcheck disable=SC2018,SC2019 - tr 'A-Z' 'a-z' - fi + # shellcheck disable=SC2018,SC2019 + tr '[A-Z]' '[a-z]' } _startswith() { From aaee0414c83fac0fc5e319e95fd35557790537b5 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 4 Aug 2022 09:44:35 +0200 Subject: [PATCH 1915/2234] Fix and Upgrade Switching from formula.php to SOAP Now session-based login Only record entries with corresponding values will now be deleted --- dnsapi/dns_kas.sh | 202 +++++++++++++++++++++++++++------------------- 1 file changed, 117 insertions(+), 85 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 2cb0b439..755161e4 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -14,39 +14,43 @@ # Git repo: https://github.com/phlegx/acme.sh # TODO: Better Error handling ######################################################################## -KAS_Api="https://kasapi.kasserver.com/dokumentation/formular.php" +KAS_Api="https://kasapi.kasserver.com/soap/KasApi.php" +KAS_Auth="https://kasapi.kasserver.com/soap/KasAuth.php" ######## Public functions ##################### dns_kas_add() { _fulldomain=$1 _txtvalue=$2 - _info "Using DNS-01 All-inkl/Kasserver hook" - _info "Adding $_fulldomain DNS TXT entry on All-inkl/Kasserver" - _info "Check and Save Props" + + _info "### -> Using DNS-01 All-inkl/Kasserver hook" + _info "### -> Adding $_fulldomain DNS TXT entry on All-inkl/Kasserver" + _info "### -> Retriving Credential Token" + _get_credential_token + + _info "### -> Check and Save Props" _check_and_save - _info "Checking Zone and Record_Name" + + _info "### -> Checking Zone and Record_Name" _get_zone_and_record_name "$_fulldomain" - _info "Getting Record ID" + + _info "### -> Checking for existing Record entries" _get_record_id - _info "Creating TXT DNS record" - params="?kas_login=$KAS_Login" - params="$params&kas_auth_type=$KAS_Authtype" - params="$params&kas_auth_data=$KAS_Authdata" - params="$params&var1=record_name" - params="$params&wert1=$_record_name" - params="$params&var2=record_type" - params="$params&wert2=TXT" - params="$params&var3=record_data" - params="$params&wert3=$_txtvalue" - params="$params&var4=record_aux" - params="$params&wert4=0" - params="$params&kas_action=add_dns_settings" - params="$params&var5=zone_host" - params="$params&wert5=$_zone" - _debug2 "Wait for 10 seconds by default before calling KAS API." - _sleep 10 - response="$(_get "$KAS_Api$params")" - _debug2 "response" "$response" + # If there is a record_id, delete the entry + if [ -n "$_record_id" ]; then + _info "Existing records found. Now deleting old entries" + for i in $_record_id; do + _delete_RecordByID "$i" + done + else + _info "No record found." + fi + + _info "### -> Creating TXT DNS record" + action="add_dns_settings" + kasReqParam="{\"record_name\":\"$_record_name\",\"record_type\":\"TXT\",\"record_data\":\"$_txtvalue\",\"record_aux\":\"0\",\"zone_host\":\"$_zone\"}" + response="$(_callAPI "$action" "$kasReqParam")" + + _debug2 "Response" "$response" if ! _contains "$response" "TRUE"; then _err "An unkown error occurred, please check manually." @@ -58,45 +62,46 @@ dns_kas_add() { dns_kas_rm() { _fulldomain=$1 _txtvalue=$2 - _info "Using DNS-01 All-inkl/Kasserver hook" - _info "Cleaning up after All-inkl/Kasserver hook" - _info "Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver" - _info "Check and Save Props" + _info "### -> Using DNS-01 All-inkl/Kasserver hook" + _info "### -> Cleaning up after All-inkl/Kasserver hook" + _info "### -> Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver" + _info "### -> Retriving Credential Token" + _get_credential_token + + _info "### -> Check and Save Props" _check_and_save - _info "Checking Zone and Record_Name" + + _info "### -> Checking Zone and Record_Name" _get_zone_and_record_name "$_fulldomain" - _info "Getting Record ID" + + _info "### -> Getting Record ID" _get_record_id + _info "### -> Removing entries with ID: $_record_id" # If there is a record_id, delete the entry if [ -n "$_record_id" ]; then - params="?kas_login=$KAS_Login" - params="$params&kas_auth_type=$KAS_Authtype" - params="$params&kas_auth_data=$KAS_Authdata" - params="$params&kas_action=delete_dns_settings" - for i in $_record_id; do - params2="$params&var1=record_id" - params2="$params2&wert1=$i" - _debug2 "Wait for 10 seconds by default before calling KAS API." - _sleep 10 - response="$(_get "$KAS_Api$params2")" - _debug2 "response" "$response" - if ! _contains "$response" "TRUE"; then - _err "Either the txt record is not found or another error occurred, please check manually." - return 1 - fi + _delete_RecordByID "$i" done else # Cannot delete or unkown error - _err "No record_id found that can be deleted. Please check manually." - return 1 + _info "No record_id found that can be deleted. Please check manually." fi return 0 } ########################## PRIVATE FUNCTIONS ########################### - +# Delete Record ID +_delete_RecordByID() { + recId=$1 + action="delete_dns_settings" + kasReqParam="{\"record_id\":\"$recId\"}" + response="$(_callAPI "$action" "$kasReqParam")" + _debug2 "Response" "$response" + if ! _contains "$response" "TRUE"; then + _info "Either the txt record is not found or another error occurred, please check manually." + fi +} # Checks for the ENV variables and saves them _check_and_save() { KAS_Login="${KAS_Login:-$(_readaccountconf_mutable KAS_Login)}" @@ -119,50 +124,77 @@ _check_and_save() { # Gets back the base domain/zone and record name. # See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide _get_zone_and_record_name() { - params="?kas_login=$KAS_Login" - params="?kas_login=$KAS_Login" - params="$params&kas_auth_type=$KAS_Authtype" - params="$params&kas_auth_data=$KAS_Authdata" - params="$params&kas_action=get_domains" - - _debug2 "Wait for 10 seconds by default before calling KAS API." - _sleep 10 - response="$(_get "$KAS_Api$params")" - _debug2 "response" "$response" - _zonen="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | sed "s/domain_name>=>//g")" - _domain="$1" - _temp_domain="$(echo "$1" | sed 's/\.$//')" - _rootzone="$_domain" - for i in $_zonen; do - l1=${#_rootzone} + action="get_domains" + kasReqParam="[]" + response="$(_callAPI "$action" "$kasReqParam")" + _debug2 "Response" "$response" + zonen="$(echo "$response" | sed 's//\n/g' | sed -r 's/(.*domain_name<\/key>)(.*)(<\/value.*)/\2/' | sed '/^' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | sed "s/record_id>=>//g")" - _debug2 _record_id "$_record_id" + _debug2 "Response" "$response" + _record_id="$(echo "$response" | sed 's//\n/g' | sed -n -e "/^.*$_record_name.*/Ip" | sed -n -e "/^.*$_txtvalue.*/Ip" | sed -r 's/(.*record_id<\/key>)([0-9]+)(<\/value.*)/\2/')" + _debug "Record Id: " "$_record_id" return 0 } + +# Retrieve credential token +_get_credential_token() { + data="" + data="$data{\"kas_login\":\"$KAS_Login\",\"kas_auth_type\":\"$KAS_Authtype\",\"kas_auth_data\":\"$KAS_Authdata\",\"session_lifetime\":600,\"session_update_lifetime\":\"Y\",\"session_2fa\":123456}" + data="$data" + + _debug "Be frindly and wait 10 seconds by default before calling KAS API." + _sleep 10 + + contentType="text/xml" + export _H1="SOAPAction: ns1:KasAuth" + response="$(_post "$data" "$KAS_Auth" "" "POST" "$contentType")" + _debug2 "Response" "$response" + + _credential_token="$(echo "$response" | tr '\n' ' ' | sed 's/.*return xsi:type="xsd:string">\(.*\)<\/return>/\1/' | sed 's/<\/ns1:KasAuthResponse\(.*\)Envelope>.*//')" + _debug "Credential Token: " "$_credential_token" + return 0 +} + +_callAPI() { + kasaction=$1 + kasReqParams=$2 + baseParam="{\"kas_login\":\"$KAS_Login\",\"kas_auth_type\":\"session\",\"kas_auth_data\":\"$_credential_token\",\"kas_action\":\"$kasaction\",\"KasRequestParams\":$kasReqParams" + baseParamClosing="}" + data="" + data="$data$baseParam$baseParamClosing" + data="$data" + _debug2 "Request" "$data" + + _debug "Be frindly and wait 10 seconds by default before calling KAS API." + _sleep 10 + + contentType="text/xml" + export _H1="SOAPAction: ns1:KasApi" + response="$(_post "$data" "$KAS_Api" "" "POST" "$contentType")" + _debug2 "Response" "$response" + echo "$response" +} From 9a5c2b88dc72e29f9283ca7ccbbaab4a614011fd Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 6 Aug 2022 23:40:12 +0800 Subject: [PATCH 1916/2234] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 27e933ca..30e6e554 100644 --- a/README.md +++ b/README.md @@ -509,6 +509,12 @@ Support this project with your organization. Your logo will show up here with a + +#### Sponsors + +[![quantumca-acmesh-logo](https://user-images.githubusercontent.com/8305679/183255712-634ee1db-bb61-4c03-bca0-bacce99e078c.svg)](https://www.quantumca.com.cn/?__utm_source=acmesh-donation) + + # 19. License & Others License is GPLv3 From edebe65d95d89f09cdf92599351ef1ecaed3d9d6 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 7 Aug 2022 10:54:38 +0800 Subject: [PATCH 1917/2234] add pr_dns.yml --- .github/dns_api_pr.md | 0 .github/workflows/pr_dns.yml | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 .github/dns_api_pr.md create mode 100644 .github/workflows/pr_dns.yml diff --git a/.github/dns_api_pr.md b/.github/dns_api_pr.md new file mode 100644 index 00000000..e69de29b diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml new file mode 100644 index 00000000..0e3f2c8b --- /dev/null +++ b/.github/workflows/pr_dns.yml @@ -0,0 +1,27 @@ +name: Check dns api + +on: + pull_request_target: + types: + - opened + branches: + - 'dev' + paths: + - 'dnsapi/*.sh' + + +jobs: + welcome: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `**Welcome** + Please make sure you're read our [dns api guide](.github/dns_api_pr.md) and we look forward to reviewing your Pull request shortly ✨` + }) + From 916743f44b27dc9f3327e084946fb9c22b757372 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 7 Aug 2022 11:07:04 +0800 Subject: [PATCH 1918/2234] fix pr_dns.yml --- .github/dns_api_pr.md | 0 .github/workflows/pr_dns.yml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 .github/dns_api_pr.md diff --git a/.github/dns_api_pr.md b/.github/dns_api_pr.md deleted file mode 100644 index e69de29b..00000000 diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml index 0e3f2c8b..89232186 100644 --- a/.github/workflows/pr_dns.yml +++ b/.github/workflows/pr_dns.yml @@ -22,6 +22,6 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: `**Welcome** - Please make sure you're read our [dns api guide](.github/dns_api_pr.md) and we look forward to reviewing your Pull request shortly ✨` + Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and we look forward to reviewing your Pull request shortly ✨` }) From 2bb29a105c7ff175abd431452ae914a0bfe9a482 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 7 Aug 2022 12:17:43 +0800 Subject: [PATCH 1919/2234] fix pr_dns.yml --- .github/workflows/pr_dns.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml index 89232186..0964250a 100644 --- a/.github/workflows/pr_dns.yml +++ b/.github/workflows/pr_dns.yml @@ -22,6 +22,7 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: `**Welcome** - Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and we look forward to reviewing your Pull request shortly ✨` + Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test(../wiki/DNS-API-Test). + We look forward to reviewing your Pull request shortly ✨` }) From 044a9bb6d38e628c85f5a9e1f8234dcb86439557 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 8 Aug 2022 13:19:38 +0800 Subject: [PATCH 1920/2234] fix https://github.com/acmesh-official/acme.sh/issues/4231 --- dnsapi/dns_ovh.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 2252f03a..708ea0af 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -118,7 +118,7 @@ _initAuth() { #return and wait for retry. return 1 fi - _saveaccountconf OVH_CK "$OVH_CK" + _saveaccountconf_mutable OVH_CK "$OVH_CK" _info "Checking authentication" @@ -236,7 +236,7 @@ _ovh_authentication() { _secure_debug consumerKey "$consumerKey" OVH_CK="$consumerKey" - + _saveaccountconf_mutable OVH_CK "$OVH_CK" _info "Please open this link to do authentication: $(__green "$validationUrl")" _info "Here is a guide for you: $(__green "$wiki")" From 204e5f4418e494e5afe04b500516e3526246b50f Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 8 Aug 2022 18:22:07 +0800 Subject: [PATCH 1921/2234] fix https://github.com/acmesh-official/acme.sh/issues/4232 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 9ac8caf9..e8228e30 100755 --- a/acme.sh +++ b/acme.sh @@ -1186,7 +1186,7 @@ _createkey() { _is_idn() { _is_idn_d="$1" _debug2 _is_idn_d "$_is_idn_d" - _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d [0-9] | tr -d [a-z] | tr -d [A-Z] | tr -d '*.,-_') + _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '[0-9]' | tr -d '[a-z]' | tr -d '[A-Z]' | tr -d '*.,-_') _debug2 _idn_temp "$_idn_temp" [ "$_idn_temp" ] } @@ -4195,7 +4195,7 @@ _match_issuer() { _isIPv4() { for seg in $(echo "$1" | tr '.' ' '); do _debug2 seg "$seg" - if [ "$(echo "$seg" | tr -d [0-9])" ]; then + if [ "$(echo "$seg" | tr -d '[0-9]')" ]; then #not all number return 1 fi From 86dd4ea4800c8e53012adee79f81d4b3e4cd5b36 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 8 Aug 2022 21:11:16 +0800 Subject: [PATCH 1922/2234] fix https://github.com/acmesh-official/acme.sh/issues/4231 --- dnsapi/dns_ovh.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 708ea0af..5e35011b 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -92,7 +92,7 @@ _initAuth() { if [ "$OVH_AK" != "$(_readaccountconf OVH_AK)" ]; then _info "It seems that your ovh key is changed, let's clear consumer key first." - _clearaccountconf OVH_CK + _clearaccountconf_mutable OVH_CK fi _saveaccountconf_mutable OVH_AK "$OVH_AK" _saveaccountconf_mutable OVH_AS "$OVH_AS" @@ -125,7 +125,7 @@ _initAuth() { if ! _ovh_rest GET "domain" || _contains "$response" "INVALID_CREDENTIAL" || _contains "$response" "NOT_CREDENTIAL"; then _err "The consumer key is invalid: $OVH_CK" _err "Please retry to create a new one." - _clearaccountconf OVH_CK + _clearaccountconf_mutable OVH_CK return 1 fi _info "Consumer key is ok." From 2f70b8682ef257eb23a194d1d2cffe9798a20643 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 10 Aug 2022 21:44:22 +0800 Subject: [PATCH 1923/2234] add logs --- .github/workflows/DNS.yml | 60 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index ac1937af..51602baf 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -81,6 +81,13 @@ jobs: - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: Docker-logs + path: logs + + MacOS: runs-on: macos-latest needs: Docker @@ -119,6 +126,14 @@ jobs: cd ../acmetest ./letest.sh + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: MacOS-logs + path: logs + + + Windows: runs-on: windows-latest needs: MacOS @@ -172,6 +187,12 @@ jobs: cd ../acmetest ./letest.sh + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: Windows-logs + path: logs + FreeBSD: runs-on: macos-12 needs: Windows @@ -213,6 +234,13 @@ jobs: cd ../acmetest ./letest.sh + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: FreeBSD-logs + path: logs + + Solaris: runs-on: macos-12 needs: FreeBSD @@ -255,6 +283,12 @@ jobs: cd ../acmetest ./letest.sh + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: Solaris-logs + path: logs + OpenBSD: runs-on: macos-12 @@ -297,6 +331,13 @@ jobs: cd ../acmetest ./letest.sh + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: OpenBSD-logs + path: logs + + NetBSD: runs-on: macos-12 needs: OpenBSD @@ -338,7 +379,14 @@ jobs: fi cd ../acmetest ./letest.sh - + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: NetBSD-logs + path: logs + + DragonFlyBSD: runs-on: macos-12 needs: NetBSD @@ -381,3 +429,13 @@ jobs: cd ../acmetest ./letest.sh + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: DragonFlyBSD-logs + path: logs + + + + + From 8ba9c4ab97e98237c4ef48c799c20e240ead3b6f Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 10 Aug 2022 22:00:46 +0800 Subject: [PATCH 1924/2234] support https_proxy for https://github.com/acmesh-official/acme.sh/pull/1838 --- .github/workflows/DNS.yml | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 51602baf..8457b30a 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -54,6 +54,8 @@ jobs: CASE: le_test_dnsapi TEST_LOCAL: 1 DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} steps: - uses: actions/checkout@v2 - name: Clone acmetest @@ -77,7 +79,8 @@ jobs: echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env fi echo "TEST_DNS_NO_WILDCARD" >> docker.env - echo "TEST_DNS_SLEEP" >> docker.env + echo "http_proxy" >> docker.env + echo "https_proxy" >> docker.env - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall @@ -100,6 +103,8 @@ jobs: CASE: le_test_dnsapi TEST_LOCAL: 1 DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} steps: - uses: actions/checkout@v2 - name: Install tools @@ -146,6 +151,8 @@ jobs: CASE: le_test_dnsapi TEST_LOCAL: 1 DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} steps: - name: Set git to use LF run: | @@ -205,13 +212,15 @@ jobs: CASE: le_test_dnsapi TEST_LOCAL: 1 DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} steps: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0 with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl usesh: true copyback: false @@ -253,13 +262,15 @@ jobs: CASE: le_test_dnsapi TEST_LOCAL: 1 DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} steps: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0 with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' copyback: false prepare: pkgutil -y -i socat run: | @@ -302,13 +313,15 @@ jobs: CASE: le_test_dnsapi TEST_LOCAL: 1 DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} steps: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/openbsd-vm@v0 with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg_add socat curl usesh: true copyback: false @@ -350,13 +363,15 @@ jobs: CASE: le_test_dnsapi TEST_LOCAL: 1 DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} steps: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/netbsd-vm@v0 with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | pkg_add curl socat usesh: true @@ -399,13 +414,15 @@ jobs: CASE: le_test_dnsapi TEST_LOCAL: 1 DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} steps: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/dragonflybsd-vm@v0 with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | pkg install -y curl socat usesh: true From ab8df825635047fdc4eee3ccc190b6bcee56567c Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 11 Aug 2022 22:15:38 +0800 Subject: [PATCH 1925/2234] fix log name --- .github/workflows/DNS.yml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 8457b30a..135cea5d 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -135,7 +135,8 @@ jobs: if: failure() with: name: MacOS-logs - path: logs + path: | + *.log @@ -198,7 +199,8 @@ jobs: if: failure() with: name: Windows-logs - path: logs + path: | + *.log FreeBSD: runs-on: macos-12 @@ -247,7 +249,8 @@ jobs: if: failure() with: name: FreeBSD-logs - path: logs + path: | + *.log Solaris: @@ -298,7 +301,8 @@ jobs: if: failure() with: name: Solaris-logs - path: logs + path: | + *.log OpenBSD: @@ -348,7 +352,8 @@ jobs: if: failure() with: name: OpenBSD-logs - path: logs + path: | + *.log NetBSD: @@ -399,7 +404,8 @@ jobs: if: failure() with: name: NetBSD-logs - path: logs + path: | + *.log DragonFlyBSD: @@ -450,7 +456,8 @@ jobs: if: failure() with: name: DragonFlyBSD-logs - path: logs + path: | + *.log From 8d211c352468999b9cc343f3e16051045e6fa5b1 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Aug 2022 09:01:57 +0800 Subject: [PATCH 1926/2234] fix log name --- .github/workflows/DNS.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 135cea5d..3075dbcd 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -88,7 +88,9 @@ jobs: if: failure() with: name: Docker-logs - path: logs + path: | + *.log + logs MacOS: From ea07b495ac2b187bfdb06e9754e1e90133de0a99 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Aug 2022 09:09:08 +0800 Subject: [PATCH 1927/2234] change message --- .github/workflows/issue.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 7e44e5ae..059bd30f 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -14,5 +14,11 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: 'Please provode the log with `--debug 2` if this is a bug report.' + body: ' + Please upgrade to the latest code and try again first. Maybe it's already fixed. + + `acme.sh --upgrade` + + If it's still not working, please provode the log with `--debug 2`, otherwise, nobody can help you.' + }) \ No newline at end of file From 683aa727d5602696f3f4287aceefe01cca9e80fa Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Aug 2022 09:14:06 +0800 Subject: [PATCH 1928/2234] fix log path --- .github/workflows/DNS.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 3075dbcd..79f17a7c 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -89,8 +89,8 @@ jobs: with: name: Docker-logs path: | - *.log - logs + ../acmetest/*.log + ../acmetest/logs MacOS: @@ -138,7 +138,7 @@ jobs: with: name: MacOS-logs path: | - *.log + ../acmetest/*.log @@ -202,7 +202,7 @@ jobs: with: name: Windows-logs path: | - *.log + ../acmetest/*.log FreeBSD: runs-on: macos-12 @@ -252,7 +252,7 @@ jobs: with: name: FreeBSD-logs path: | - *.log + ../acmetest/*.log Solaris: @@ -304,7 +304,7 @@ jobs: with: name: Solaris-logs path: | - *.log + ../acmetest/*.log OpenBSD: @@ -355,7 +355,7 @@ jobs: with: name: OpenBSD-logs path: | - *.log + ../acmetest/*.log NetBSD: @@ -407,7 +407,7 @@ jobs: with: name: NetBSD-logs path: | - *.log + ../acmetest/*.log DragonFlyBSD: @@ -459,7 +459,7 @@ jobs: with: name: DragonFlyBSD-logs path: | - *.log + ../acmetest/*.log From cc36421fe5b867a69bcc0717c1916e0c95fa47f7 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Aug 2022 09:31:36 +0800 Subject: [PATCH 1929/2234] fix typo --- .github/workflows/pr_dns.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml index 0964250a..50de26b4 100644 --- a/.github/workflows/pr_dns.yml +++ b/.github/workflows/pr_dns.yml @@ -22,7 +22,7 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: `**Welcome** - Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test(../wiki/DNS-API-Test). + Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). We look forward to reviewing your Pull request shortly ✨` }) From 7e9612035374154784709c0bf11fbd496f9c8a69 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Aug 2022 09:33:43 +0800 Subject: [PATCH 1930/2234] fix message --- .github/workflows/pr_dns.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml index 50de26b4..6c60738e 100644 --- a/.github/workflows/pr_dns.yml +++ b/.github/workflows/pr_dns.yml @@ -23,6 +23,10 @@ jobs: repo: context.repo.repo, body: `**Welcome** Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). - We look forward to reviewing your Pull request shortly ✨` + + Then reply on this message, otherwise, your code will not be reviewed or merged. + + We look forward to reviewing your Pull request shortly ✨ + ` }) From 5684b7c329ca4be798e63c3180bb3f87ede76823 Mon Sep 17 00:00:00 2001 From: Awalon Date: Sat, 13 Aug 2022 05:02:12 +0200 Subject: [PATCH 1931/2234] dns_gd (GoDaddy): Delete TXT record instead of just setting them to an empty value. Replaced "#todo: check if the record takes effect" by some error handling and validation. --- dnsapi/dns_gd.sh | 50 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh index 7f8efca9..e8ce4578 100755 --- a/dnsapi/dns_gd.sh +++ b/dnsapi/dns_gd.sh @@ -51,7 +51,8 @@ dns_gd_add() { _add_data="{\"data\":\"$txtvalue\"}" for t in $(echo "$response" | tr '{' "\n" | grep "\"name\":\"$_sub_domain\"" | tr ',' "\n" | grep '"data"' | cut -d : -f 2); do _debug2 t "$t" - if [ "$t" ]; then + # ignore empty (previously removed) records, to prevent useless _acme-challenge TXT entries + if [ "$t" ] && [ "$t" != '""' ]; then _add_data="$_add_data,{\"data\":$t}" fi done @@ -59,13 +60,25 @@ dns_gd_add() { _info "Adding record" if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then - _info "Added, sleeping 10 seconds" - _sleep 10 - #todo: check if the record takes effect - return 0 + _debug "Checking updated records of '${fulldomain}'" + + if ! _gd_rest GET "domains/$_domain/records/TXT/$_sub_domain"; then + _err "Validating TXT record for '${fulldomain}' with rest error [$?]." "$response" + return 1 + fi + + if ! _contains "$response" "$txtvalue"; then + _err "TXT record '${txtvalue}' for '${fulldomain}', value wasn't set!" + return 1 + fi + else + _err "Add txt record error, value '${txtvalue}' for '${fulldomain}' was not set." + return 1 fi - _err "Add txt record error." - return 1 + + _sleep 10 + _info "Added TXT record '${txtvalue}' for '${fulldomain}'." + return 0 } #fulldomain @@ -107,11 +120,20 @@ dns_gd_rm() { fi done if [ -z "$_add_data" ]; then - _add_data="{\"data\":\"\"}" + # delete empty record + _debug "Delete last record for '${fulldomain}'" + if ! _gd_rest DELETE "domains/$_domain/records/TXT/$_sub_domain"; then + _err "Cannot delete empty TXT record for '$fulldomain'" + return 1 + fi + else + # remove specific TXT value, keeping other entries + _debug2 _add_data "$_add_data" + if ! _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then + _err "Cannot update TXT record for '$fulldomain'" + return 1 + fi fi - _debug2 _add_data "$_add_data" - - _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]" } #################### Private functions below ################################## @@ -156,15 +178,15 @@ _gd_rest() { export _H1="Authorization: sso-key $GD_Key:$GD_Secret" export _H2="Content-Type: application/json" - if [ "$data" ]; then - _debug data "$data" + if [ "$data" ] || [ "$m" = "DELETE" ]; then + _debug "data ($m): " "$data" response="$(_post "$data" "$GD_Api/$ep" "" "$m")" else response="$(_get "$GD_Api/$ep")" fi if [ "$?" != "0" ]; then - _err "error $ep" + _err "error on rest call ($m): $ep" return 1 fi _debug2 response "$response" From 15ae5a513562a498fe3f8b42fa8711230813585b Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Aug 2022 11:14:22 +0800 Subject: [PATCH 1932/2234] fix format --- .github/workflows/pr_dns.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml index 6c60738e..c62f2f29 100644 --- a/.github/workflows/pr_dns.yml +++ b/.github/workflows/pr_dns.yml @@ -22,11 +22,7 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: `**Welcome** - Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). - - Then reply on this message, otherwise, your code will not be reviewed or merged. - - We look forward to reviewing your Pull request shortly ✨ + Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). Then reply on this message, otherwise, your code will not be reviewed or merged. We look forward to reviewing your Pull request shortly ✨ ` }) From 79e044ac317f8c27c32c3b0dac4ab844daf87c36 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Aug 2022 11:16:40 +0800 Subject: [PATCH 1933/2234] fix format --- .github/workflows/pr_dns.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml index c62f2f29..5faa9105 100644 --- a/.github/workflows/pr_dns.yml +++ b/.github/workflows/pr_dns.yml @@ -22,7 +22,9 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: `**Welcome** - Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). Then reply on this message, otherwise, your code will not be reviewed or merged. We look forward to reviewing your Pull request shortly ✨ + Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). + Then reply on this message, otherwise, your code will not be reviewed or merged. + We look forward to reviewing your Pull request shortly ✨ ` }) From 2d4aa7ff8b07876c5a1cc70e2dd81f74220a52e1 Mon Sep 17 00:00:00 2001 From: Awalon Date: Sat, 13 Aug 2022 05:34:05 +0200 Subject: [PATCH 1934/2234] Added example and URL for API key --- dnsapi/dns_gd.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh index e8ce4578..44c3d279 100755 --- a/dnsapi/dns_gd.sh +++ b/dnsapi/dns_gd.sh @@ -1,10 +1,12 @@ #!/usr/bin/env sh #Godaddy domain api +# Get API key and secret from https://developer.godaddy.com/ # -#GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" +# GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" +# GD_Secret="asdfsdfsfsdfsdfdfsdf" # -#GD_Secret="asdfsdfsfsdfsdfdfsdf" +# Ex.: acme.sh --issue --staging --dns dns_gd -d "*.s.example.com" -d "s.example.com" GD_Api="https://api.godaddy.com/v1" From 74168c3e056c78cf2389d6d2ad155759f40b4d7b Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 14 Aug 2022 15:25:48 +0800 Subject: [PATCH 1935/2234] fix ip test for pebble --- .github/workflows/PebbleStrict.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index c1ea1cd2..d51b3841 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -41,7 +41,7 @@ jobs: PebbleStrict_IPCert: runs-on: ubuntu-latest env: - TestingDomain: 10.30.50.1 + TestingDomain: 1.23.45.67 ACME_DIRECTORY: https://localhost:14000/dir HTTPS_INSECURE: 1 Le_HTTPPort: 5002 @@ -55,7 +55,10 @@ jobs: - name: Install tools run: sudo apt-get install -y socat - name: Run Pebble - run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d + run: | + docker run --rm -itd --name=pebble \ + -e PEBBLE_VA_ALWAYS_VALID=1 \ + -p 14000:14000 -p 15000:15000 letsencrypt/pebble:latest pebble -config /test/config/pebble-config.json -strict - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest From 4f8d1c5c9db17df3298f6ef1631eab4c5b4e7f42 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 14 Aug 2022 15:29:28 +0800 Subject: [PATCH 1936/2234] fix ip test --- .github/workflows/PebbleStrict.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index d51b3841..77512955 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-latest env: TestingDomain: 1.23.45.67 - ACME_DIRECTORY: https://localhost:14000/dir + TEST_ACME_Server: https://localhost:14000/dir HTTPS_INSECURE: 1 Le_HTTPPort: 5002 Le_TLSPort: 5001 From 5dba8b493d205d5799e8136ab05965597ddad34d Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 14 Aug 2022 16:25:28 +0800 Subject: [PATCH 1937/2234] fix log pattern --- .github/workflows/DNS.yml | 934 +++++++++++++++++++------------------- 1 file changed, 467 insertions(+), 467 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 79f17a7c..d44f5cdc 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -1,467 +1,467 @@ -name: DNS -on: - push: - paths: - - 'dnsapi/*.sh' - - '.github/workflows/DNS.yml' - pull_request: - branches: - - 'dev' - paths: - - 'dnsapi/*.sh' - - '.github/workflows/DNS.yml' - - -jobs: - CheckToken: - runs-on: ubuntu-latest - outputs: - hasToken: ${{ steps.step_one.outputs.hasToken }} - steps: - - name: Set the value - id: step_one - run: | - if [ "${{secrets.TokenName1}}" ] ; then - echo "::set-output name=hasToken::true" - else - echo "::set-output name=hasToken::false" - fi - - name: Check the value - run: echo ${{ steps.step_one.outputs.hasToken }} - - Fail: - runs-on: ubuntu-latest - needs: CheckToken - if: "contains(needs.CheckToken.outputs.hasToken, 'false')" - steps: - - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" - run: | - echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" - if [ "${{github.repository_owner}}" != "acmesh-official" ]; then - false - fi - - Docker: - runs-on: ubuntu-latest - needs: CheckToken - if: "contains(needs.CheckToken.outputs.hasToken, 'true')" - env: - TEST_DNS : ${{ secrets.TEST_DNS }} - TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} - TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} - TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} - CASE: le_test_dnsapi - TEST_LOCAL: 1 - DEBUG: ${{ secrets.DEBUG }} - http_proxy: ${{ secrets.http_proxy }} - https_proxy: ${{ secrets.https_proxy }} - steps: - - uses: actions/checkout@v2 - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - name: Set env file - run: | - cd ../acmetest - if [ "${{ secrets.TokenName1}}" ] ; then - echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env - fi - if [ "${{ secrets.TokenName2}}" ] ; then - echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env - fi - if [ "${{ secrets.TokenName3}}" ] ; then - echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env - fi - if [ "${{ secrets.TokenName4}}" ] ; then - echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env - fi - if [ "${{ secrets.TokenName5}}" ] ; then - echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env - fi - echo "TEST_DNS_NO_WILDCARD" >> docker.env - echo "http_proxy" >> docker.env - echo "https_proxy" >> docker.env - - name: Run acmetest - run: cd ../acmetest && ./rundocker.sh testall - - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: Docker-logs - path: | - ../acmetest/*.log - ../acmetest/logs - - - MacOS: - runs-on: macos-latest - needs: Docker - env: - TEST_DNS : ${{ secrets.TEST_DNS }} - TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} - TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} - TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} - CASE: le_test_dnsapi - TEST_LOCAL: 1 - DEBUG: ${{ secrets.DEBUG }} - http_proxy: ${{ secrets.http_proxy }} - https_proxy: ${{ secrets.https_proxy }} - steps: - - uses: actions/checkout@v2 - - name: Install tools - run: brew install socat - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - name: Run acmetest - run: | - if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} - fi - if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} - fi - if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} - fi - if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} - fi - if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} - fi - cd ../acmetest - ./letest.sh - - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: MacOS-logs - path: | - ../acmetest/*.log - - - - Windows: - runs-on: windows-latest - needs: MacOS - env: - TEST_DNS : ${{ secrets.TEST_DNS }} - TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} - TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} - TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} - CASE: le_test_dnsapi - TEST_LOCAL: 1 - DEBUG: ${{ secrets.DEBUG }} - http_proxy: ${{ secrets.http_proxy }} - https_proxy: ${{ secrets.https_proxy }} - steps: - - name: Set git to use LF - run: | - git config --global core.autocrlf false - - uses: actions/checkout@v2 - - name: Install cygwin base packages with chocolatey - run: | - choco config get cacheLocation - choco install --no-progress cygwin - shell: cmd - - name: Install cygwin additional packages - run: | - C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git - shell: cmd - - name: Set ENV - shell: cmd - run: | - echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV% - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - name: Run acmetest - shell: bash - run: | - if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} - fi - if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} - fi - if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} - fi - if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} - fi - if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} - fi - cd ../acmetest - ./letest.sh - - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: Windows-logs - path: | - ../acmetest/*.log - - FreeBSD: - runs-on: macos-12 - needs: Windows - env: - TEST_DNS : ${{ secrets.TEST_DNS }} - TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} - TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} - TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} - CASE: le_test_dnsapi - TEST_LOCAL: 1 - DEBUG: ${{ secrets.DEBUG }} - http_proxy: ${{ secrets.http_proxy }} - https_proxy: ${{ secrets.https_proxy }} - steps: - - uses: actions/checkout@v2 - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0 - with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' - prepare: pkg install -y socat curl - usesh: true - copyback: false - run: | - if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} - fi - if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} - fi - if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} - fi - if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} - fi - if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} - fi - cd ../acmetest - ./letest.sh - - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: FreeBSD-logs - path: | - ../acmetest/*.log - - - Solaris: - runs-on: macos-12 - needs: FreeBSD - env: - TEST_DNS : ${{ secrets.TEST_DNS }} - TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} - TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} - TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} - CASE: le_test_dnsapi - TEST_LOCAL: 1 - DEBUG: ${{ secrets.DEBUG }} - http_proxy: ${{ secrets.http_proxy }} - https_proxy: ${{ secrets.https_proxy }} - steps: - - uses: actions/checkout@v2 - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0 - with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' - copyback: false - prepare: pkgutil -y -i socat - run: | - pkg set-mediator -v -I default@1.1 openssl - export PATH=/usr/gnu/bin:$PATH - if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} - fi - if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} - fi - if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} - fi - if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} - fi - if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} - fi - cd ../acmetest - ./letest.sh - - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: Solaris-logs - path: | - ../acmetest/*.log - - - OpenBSD: - runs-on: macos-12 - needs: Solaris - env: - TEST_DNS : ${{ secrets.TEST_DNS }} - TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} - TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} - TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} - CASE: le_test_dnsapi - TEST_LOCAL: 1 - DEBUG: ${{ secrets.DEBUG }} - http_proxy: ${{ secrets.http_proxy }} - https_proxy: ${{ secrets.https_proxy }} - steps: - - uses: actions/checkout@v2 - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0 - with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' - prepare: pkg_add socat curl - usesh: true - copyback: false - run: | - if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} - fi - if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} - fi - if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} - fi - if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} - fi - if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} - fi - cd ../acmetest - ./letest.sh - - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: OpenBSD-logs - path: | - ../acmetest/*.log - - - NetBSD: - runs-on: macos-12 - needs: OpenBSD - env: - TEST_DNS : ${{ secrets.TEST_DNS }} - TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} - TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} - TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} - CASE: le_test_dnsapi - TEST_LOCAL: 1 - DEBUG: ${{ secrets.DEBUG }} - http_proxy: ${{ secrets.http_proxy }} - https_proxy: ${{ secrets.https_proxy }} - steps: - - uses: actions/checkout@v2 - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v0 - with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' - prepare: | - pkg_add curl socat - usesh: true - copyback: false - run: | - if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} - fi - if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} - fi - if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} - fi - if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} - fi - if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} - fi - cd ../acmetest - ./letest.sh - - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: NetBSD-logs - path: | - ../acmetest/*.log - - - DragonFlyBSD: - runs-on: macos-12 - needs: NetBSD - env: - TEST_DNS : ${{ secrets.TEST_DNS }} - TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} - TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} - TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} - CASE: le_test_dnsapi - TEST_LOCAL: 1 - DEBUG: ${{ secrets.DEBUG }} - http_proxy: ${{ secrets.http_proxy }} - https_proxy: ${{ secrets.https_proxy }} - steps: - - uses: actions/checkout@v2 - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/dragonflybsd-vm@v0 - with: - envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' - prepare: | - pkg install -y curl socat - usesh: true - copyback: false - run: | - if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} - fi - if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} - fi - if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} - fi - if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} - fi - if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} - fi - cd ../acmetest - ./letest.sh - - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: DragonFlyBSD-logs - path: | - ../acmetest/*.log - - - - - +name: DNS +on: + push: + paths: + - 'dnsapi/*.sh' + - '.github/workflows/DNS.yml' + pull_request: + branches: + - 'dev' + paths: + - 'dnsapi/*.sh' + - '.github/workflows/DNS.yml' + + +jobs: + CheckToken: + runs-on: ubuntu-latest + outputs: + hasToken: ${{ steps.step_one.outputs.hasToken }} + steps: + - name: Set the value + id: step_one + run: | + if [ "${{secrets.TokenName1}}" ] ; then + echo "::set-output name=hasToken::true" + else + echo "::set-output name=hasToken::false" + fi + - name: Check the value + run: echo ${{ steps.step_one.outputs.hasToken }} + + Fail: + runs-on: ubuntu-latest + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'false')" + steps: + - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" + run: | + echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" + if [ "${{github.repository_owner}}" != "acmesh-official" ]; then + false + fi + + Docker: + runs-on: ubuntu-latest + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'true')" + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Set env file + run: | + cd ../acmetest + if [ "${{ secrets.TokenName1}}" ] ; then + echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env + fi + if [ "${{ secrets.TokenName2}}" ] ; then + echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env + fi + if [ "${{ secrets.TokenName3}}" ] ; then + echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env + fi + if [ "${{ secrets.TokenName4}}" ] ; then + echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env + fi + if [ "${{ secrets.TokenName5}}" ] ; then + echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env + fi + echo "TEST_DNS_NO_WILDCARD" >> docker.env + echo "http_proxy" >> docker.env + echo "https_proxy" >> docker.env + - name: Run acmetest + run: cd ../acmetest && ./rundocker.sh testall + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: Docker-logs + path: | + ../acmetest/**.log + ../acmetest/logs + + + MacOS: + runs-on: macos-latest + needs: Docker + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: brew install socat + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: MacOS-logs + path: | + ../acmetest/**.log + + + + Windows: + runs-on: windows-latest + needs: MacOS + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} + steps: + - name: Set git to use LF + run: | + git config --global core.autocrlf false + - uses: actions/checkout@v2 + - name: Install cygwin base packages with chocolatey + run: | + choco config get cacheLocation + choco install --no-progress cygwin + shell: cmd + - name: Install cygwin additional packages + run: | + C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git + shell: cmd + - name: Set ENV + shell: cmd + run: | + echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV% + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + shell: bash + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: Windows-logs + path: | + ../acmetest/**.log + + FreeBSD: + runs-on: macos-12 + needs: Windows + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/freebsd-vm@v0 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: pkg install -y socat curl + usesh: true + copyback: false + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: FreeBSD-logs + path: | + ../acmetest/**.log + + + Solaris: + runs-on: macos-12 + needs: FreeBSD + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/solaris-vm@v0 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + copyback: false + prepare: pkgutil -y -i socat + run: | + pkg set-mediator -v -I default@1.1 openssl + export PATH=/usr/gnu/bin:$PATH + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: Solaris-logs + path: | + ../acmetest/**.log + + + OpenBSD: + runs-on: macos-12 + needs: Solaris + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/openbsd-vm@v0 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: pkg_add socat curl + usesh: true + copyback: false + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: OpenBSD-logs + path: | + ../acmetest/**.log + + + NetBSD: + runs-on: macos-12 + needs: OpenBSD + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/netbsd-vm@v0 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: | + pkg_add curl socat + usesh: true + copyback: false + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: NetBSD-logs + path: | + ../acmetest/**.log + + + DragonFlyBSD: + runs-on: macos-12 + needs: NetBSD + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/dragonflybsd-vm@v0 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: | + pkg install -y curl socat + usesh: true + copyback: false + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: DragonFlyBSD-logs + path: | + ../acmetest/**.log + + + + + From 20f097faa41073bec2d78d1da9221cae3343d3db Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 14 Aug 2022 16:33:48 +0800 Subject: [PATCH 1938/2234] typo --- .github/workflows/issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 059bd30f..20d3d5fd 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -19,6 +19,6 @@ jobs: `acme.sh --upgrade` - If it's still not working, please provode the log with `--debug 2`, otherwise, nobody can help you.' + If it's still not working, please provide the log with `--debug 2`, otherwise, nobody can help you.' }) \ No newline at end of file From 2454ac8ef105778943352a4c472c1ed71b20013b Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 14 Aug 2022 17:44:16 +0800 Subject: [PATCH 1939/2234] don't upload log --- .github/workflows/DNS.yml | 56 +++++---------------------------------- 1 file changed, 6 insertions(+), 50 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index d44f5cdc..04a8bd6d 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -84,13 +84,7 @@ jobs: - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: Docker-logs - path: | - ../acmetest/**.log - ../acmetest/logs + MacOS: @@ -133,12 +127,6 @@ jobs: cd ../acmetest ./letest.sh - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: MacOS-logs - path: | - ../acmetest/**.log @@ -197,12 +185,7 @@ jobs: cd ../acmetest ./letest.sh - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: Windows-logs - path: | - ../acmetest/**.log + FreeBSD: runs-on: macos-12 @@ -247,12 +230,7 @@ jobs: cd ../acmetest ./letest.sh - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: FreeBSD-logs - path: | - ../acmetest/**.log + Solaris: @@ -299,12 +277,7 @@ jobs: cd ../acmetest ./letest.sh - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: Solaris-logs - path: | - ../acmetest/**.log + OpenBSD: @@ -350,12 +323,7 @@ jobs: cd ../acmetest ./letest.sh - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: OpenBSD-logs - path: | - ../acmetest/**.log + NetBSD: @@ -402,12 +370,7 @@ jobs: cd ../acmetest ./letest.sh - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: NetBSD-logs - path: | - ../acmetest/**.log + DragonFlyBSD: @@ -454,13 +417,6 @@ jobs: cd ../acmetest ./letest.sh - - uses: actions/upload-artifact@v1 - if: failure() - with: - name: DragonFlyBSD-logs - path: | - ../acmetest/**.log - From 671eecf2033705e2235ec0342a6cac2b28d3e4fa Mon Sep 17 00:00:00 2001 From: stephen Date: Mon, 15 Aug 2022 18:10:18 +0800 Subject: [PATCH 1940/2234] www.dns.la official acme script www.dns.la official acme script --- dnsapi/dns_la.sh | 161 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 dnsapi/dns_la.sh diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh new file mode 100644 index 00000000..10ee7ea6 --- /dev/null +++ b/dnsapi/dns_la.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env sh +# dns.la Domain api +# +#LA_Id="test123" +# +#LA_Key="d1j2fdo4dee3948" +DNSLA_API="https://www.dns.la/api/" +######## Public functions ##################### +#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_la_add() { + fulldomain=$1 + txtvalue=$2 + + LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" + LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" + if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then + LA_Id="" + LA_Key="" + _err "You don't specify dnsla api id and key yet." + _err "Please create your key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable LA_Id "$LA_Id" + _saveaccountconf_mutable LA_Key "$LA_Key" + + _debug "detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + add_record "$_domain" "$_sub_domain" "$txtvalue" + +} + +#fulldomain txtvalue +dns_la_rm() { + fulldomain=$1 + txtvalue=$2 + _fullkey=$(printf "%s" ${fulldomain:16} | tr '.' '_' ) + + LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" + LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" + _debug fullkey $_fullkey + RM_recordid="$(_readaccountconf $_fullkey)" + _debug rm_recordid "$RM_recordid" + _debug "detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + if ! _rest GET "record.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then + _err "get record lis error." + return 1 + fi + + if ! _contains "$response" "$RM_recordid"; then + _info "no need to remove record." + return 0 + fi + + if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then + _err "record remove error." + return 1 + fi + + _clearaccountconf $_fullkey + + _contains "$response" "\"code\":300" +} + +#add the txt record. +#usage: root sub txtvalue +add_record() { + root=$1 + sub=$2 + txtvalue=$3 + fulldomain="$sub.$root" + + _info "adding txt record" + + if ! _rest GET "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then + return 1 + fi + + if _contains "$response" "\"code\":300"; then + _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) + _fullkey=$(printf "%s" ${fulldomain:16} | tr '.' '_' ) + _debug fullkey $_fullkey + _saveaccountconf $_fullkey "$_record_id" + _debug _record_id "$_record_id" + fi + _contains "$response" "\"code\":300" +} + +#################### 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 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _rest GET "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then + return 1 + fi + + if _contains "$response" "\"code\":300"; then + _domain_id=$(printf "%s" "$response" | grep '"domainid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) + _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" + data="$3" + _debug "$ep" + url="$DNSLA_API$ep" + + _debug url "$url" + + if [ "$m" = "GET" ]; then + response="$(_get "$url" | tr -d ' ' | tr "}" ",")" + else + _debug2 data "$data" + response="$(_post "$data" "$url" | tr -d ' ' | tr "}" ",")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 33da8a7f6210eb298da7bf5bc6b6b8195bb661a5 Mon Sep 17 00:00:00 2001 From: stephen Date: Tue, 16 Aug 2022 09:51:59 +0800 Subject: [PATCH 1941/2234] dns.la official acme script, error fixed fixed shcheck error --- dnsapi/dns_la.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh index 10ee7ea6..0468220a 100644 --- a/dnsapi/dns_la.sh +++ b/dnsapi/dns_la.sh @@ -39,12 +39,12 @@ dns_la_add() { dns_la_rm() { fulldomain=$1 txtvalue=$2 - _fullkey=$(printf "%s" ${fulldomain:16} | tr '.' '_' ) + _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" - _debug fullkey $_fullkey - RM_recordid="$(_readaccountconf $_fullkey)" + _debug fullkey "$_fullkey" + RM_recordid="$(_readaccountconf "$_fullkey")" _debug rm_recordid "$RM_recordid" _debug "detect the root zone" if ! _get_root "$fulldomain"; then @@ -67,7 +67,7 @@ dns_la_rm() { return 1 fi - _clearaccountconf $_fullkey + _clearaccountconf "$_fullkey" _contains "$response" "\"code\":300" } @@ -88,9 +88,9 @@ add_record() { if _contains "$response" "\"code\":300"; then _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) - _fullkey=$(printf "%s" ${fulldomain:16} | tr '.' '_' ) - _debug fullkey $_fullkey - _saveaccountconf $_fullkey "$_record_id" + _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) + _debug fullkey "$_fullkey" + _saveaccountconf "$_fullkey" "$_record_id" _debug _record_id "$_record_id" fi _contains "$response" "\"code\":300" From a6e87e7e086648f32f7d0d2c325c2a996851203e Mon Sep 17 00:00:00 2001 From: stephen Date: Tue, 16 Aug 2022 15:11:55 +0800 Subject: [PATCH 1942/2234] Delete dns_la.sh --- dnsapi/dns_la.sh | 161 ----------------------------------------------- 1 file changed, 161 deletions(-) delete mode 100644 dnsapi/dns_la.sh diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh deleted file mode 100644 index 0468220a..00000000 --- a/dnsapi/dns_la.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env sh -# dns.la Domain api -# -#LA_Id="test123" -# -#LA_Key="d1j2fdo4dee3948" -DNSLA_API="https://www.dns.la/api/" -######## Public functions ##################### -#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_la_add() { - fulldomain=$1 - txtvalue=$2 - - LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" - LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" - if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then - LA_Id="" - LA_Key="" - _err "You don't specify dnsla api id and key yet." - _err "Please create your key and try again." - return 1 - fi - - #save the api key and email to the account conf file. - _saveaccountconf_mutable LA_Id "$LA_Id" - _saveaccountconf_mutable LA_Key "$LA_Key" - - _debug "detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - - add_record "$_domain" "$_sub_domain" "$txtvalue" - -} - -#fulldomain txtvalue -dns_la_rm() { - fulldomain=$1 - txtvalue=$2 - _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) - - LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" - LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" - _debug fullkey "$_fullkey" - RM_recordid="$(_readaccountconf "$_fullkey")" - _debug rm_recordid "$RM_recordid" - _debug "detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - - if ! _rest GET "record.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then - _err "get record lis error." - return 1 - fi - - if ! _contains "$response" "$RM_recordid"; then - _info "no need to remove record." - return 0 - fi - - if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then - _err "record remove error." - return 1 - fi - - _clearaccountconf "$_fullkey" - - _contains "$response" "\"code\":300" -} - -#add the txt record. -#usage: root sub txtvalue -add_record() { - root=$1 - sub=$2 - txtvalue=$3 - fulldomain="$sub.$root" - - _info "adding txt record" - - if ! _rest GET "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then - return 1 - fi - - if _contains "$response" "\"code\":300"; then - _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) - _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) - _debug fullkey "$_fullkey" - _saveaccountconf "$_fullkey" "$_record_id" - _debug _record_id "$_record_id" - fi - _contains "$response" "\"code\":300" -} - -#################### 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 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if [ -z "$h" ]; then - #not valid - return 1 - fi - - if ! _rest GET "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then - return 1 - fi - - if _contains "$response" "\"code\":300"; then - _domain_id=$(printf "%s" "$response" | grep '"domainid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) - _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" - data="$3" - _debug "$ep" - url="$DNSLA_API$ep" - - _debug url "$url" - - if [ "$m" = "GET" ]; then - response="$(_get "$url" | tr -d ' ' | tr "}" ",")" - else - _debug2 data "$data" - response="$(_post "$data" "$url" | tr -d ' ' | tr "}" ",")" - fi - - if [ "$?" != "0" ]; then - _err "error $ep" - return 1 - fi - _debug2 response "$response" - return 0 -} From 67a2a4f249a51fe0425c2d2bb3fb37807040ea14 Mon Sep 17 00:00:00 2001 From: stephen Date: Tue, 16 Aug 2022 15:14:27 +0800 Subject: [PATCH 1943/2234] dns.la dns acme script dns.la dns acme script --- dnsapi/dns_la.sh | 161 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 dnsapi/dns_la.sh diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh new file mode 100644 index 00000000..0468220a --- /dev/null +++ b/dnsapi/dns_la.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env sh +# dns.la Domain api +# +#LA_Id="test123" +# +#LA_Key="d1j2fdo4dee3948" +DNSLA_API="https://www.dns.la/api/" +######## Public functions ##################### +#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_la_add() { + fulldomain=$1 + txtvalue=$2 + + LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" + LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" + if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then + LA_Id="" + LA_Key="" + _err "You don't specify dnsla api id and key yet." + _err "Please create your key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable LA_Id "$LA_Id" + _saveaccountconf_mutable LA_Key "$LA_Key" + + _debug "detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + add_record "$_domain" "$_sub_domain" "$txtvalue" + +} + +#fulldomain txtvalue +dns_la_rm() { + fulldomain=$1 + txtvalue=$2 + _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) + + LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" + LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" + _debug fullkey "$_fullkey" + RM_recordid="$(_readaccountconf "$_fullkey")" + _debug rm_recordid "$RM_recordid" + _debug "detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + if ! _rest GET "record.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then + _err "get record lis error." + return 1 + fi + + if ! _contains "$response" "$RM_recordid"; then + _info "no need to remove record." + return 0 + fi + + if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then + _err "record remove error." + return 1 + fi + + _clearaccountconf "$_fullkey" + + _contains "$response" "\"code\":300" +} + +#add the txt record. +#usage: root sub txtvalue +add_record() { + root=$1 + sub=$2 + txtvalue=$3 + fulldomain="$sub.$root" + + _info "adding txt record" + + if ! _rest GET "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then + return 1 + fi + + if _contains "$response" "\"code\":300"; then + _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) + _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) + _debug fullkey "$_fullkey" + _saveaccountconf "$_fullkey" "$_record_id" + _debug _record_id "$_record_id" + fi + _contains "$response" "\"code\":300" +} + +#################### 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 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _rest GET "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then + return 1 + fi + + if _contains "$response" "\"code\":300"; then + _domain_id=$(printf "%s" "$response" | grep '"domainid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) + _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" + data="$3" + _debug "$ep" + url="$DNSLA_API$ep" + + _debug url "$url" + + if [ "$m" = "GET" ]; then + response="$(_get "$url" | tr -d ' ' | tr "}" ",")" + else + _debug2 data "$data" + response="$(_post "$data" "$url" | tr -d ' ' | tr "}" ",")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From d4ed50a91516206f7245652a9cb6de2c7db898c4 Mon Sep 17 00:00:00 2001 From: stephen Date: Tue, 16 Aug 2022 15:29:35 +0800 Subject: [PATCH 1945/2234] Delete dns_la.sh --- dnsapi/dns_la.sh | 161 ----------------------------------------------- 1 file changed, 161 deletions(-) delete mode 100644 dnsapi/dns_la.sh diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh deleted file mode 100644 index 0468220a..00000000 --- a/dnsapi/dns_la.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env sh -# dns.la Domain api -# -#LA_Id="test123" -# -#LA_Key="d1j2fdo4dee3948" -DNSLA_API="https://www.dns.la/api/" -######## Public functions ##################### -#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_la_add() { - fulldomain=$1 - txtvalue=$2 - - LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" - LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" - if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then - LA_Id="" - LA_Key="" - _err "You don't specify dnsla api id and key yet." - _err "Please create your key and try again." - return 1 - fi - - #save the api key and email to the account conf file. - _saveaccountconf_mutable LA_Id "$LA_Id" - _saveaccountconf_mutable LA_Key "$LA_Key" - - _debug "detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - - add_record "$_domain" "$_sub_domain" "$txtvalue" - -} - -#fulldomain txtvalue -dns_la_rm() { - fulldomain=$1 - txtvalue=$2 - _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) - - LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" - LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" - _debug fullkey "$_fullkey" - RM_recordid="$(_readaccountconf "$_fullkey")" - _debug rm_recordid "$RM_recordid" - _debug "detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - - if ! _rest GET "record.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then - _err "get record lis error." - return 1 - fi - - if ! _contains "$response" "$RM_recordid"; then - _info "no need to remove record." - return 0 - fi - - if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then - _err "record remove error." - return 1 - fi - - _clearaccountconf "$_fullkey" - - _contains "$response" "\"code\":300" -} - -#add the txt record. -#usage: root sub txtvalue -add_record() { - root=$1 - sub=$2 - txtvalue=$3 - fulldomain="$sub.$root" - - _info "adding txt record" - - if ! _rest GET "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then - return 1 - fi - - if _contains "$response" "\"code\":300"; then - _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) - _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) - _debug fullkey "$_fullkey" - _saveaccountconf "$_fullkey" "$_record_id" - _debug _record_id "$_record_id" - fi - _contains "$response" "\"code\":300" -} - -#################### 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 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if [ -z "$h" ]; then - #not valid - return 1 - fi - - if ! _rest GET "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then - return 1 - fi - - if _contains "$response" "\"code\":300"; then - _domain_id=$(printf "%s" "$response" | grep '"domainid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) - _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" - data="$3" - _debug "$ep" - url="$DNSLA_API$ep" - - _debug url "$url" - - if [ "$m" = "GET" ]; then - response="$(_get "$url" | tr -d ' ' | tr "}" ",")" - else - _debug2 data "$data" - response="$(_post "$data" "$url" | tr -d ' ' | tr "}" ",")" - fi - - if [ "$?" != "0" ]; then - _err "error $ep" - return 1 - fi - _debug2 response "$response" - return 0 -} From dd980d9dca5aca25c3335cfc6e3fdca004d6ae84 Mon Sep 17 00:00:00 2001 From: stephen Date: Tue, 16 Aug 2022 15:30:10 +0800 Subject: [PATCH 1946/2234] dns.la official acme script dns.la official acme script --- dnsapi/dns_la.sh | 161 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 dnsapi/dns_la.sh diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh new file mode 100644 index 00000000..0468220a --- /dev/null +++ b/dnsapi/dns_la.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env sh +# dns.la Domain api +# +#LA_Id="test123" +# +#LA_Key="d1j2fdo4dee3948" +DNSLA_API="https://www.dns.la/api/" +######## Public functions ##################### +#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_la_add() { + fulldomain=$1 + txtvalue=$2 + + LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" + LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" + if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then + LA_Id="" + LA_Key="" + _err "You don't specify dnsla api id and key yet." + _err "Please create your key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable LA_Id "$LA_Id" + _saveaccountconf_mutable LA_Key "$LA_Key" + + _debug "detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + add_record "$_domain" "$_sub_domain" "$txtvalue" + +} + +#fulldomain txtvalue +dns_la_rm() { + fulldomain=$1 + txtvalue=$2 + _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) + + LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" + LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" + _debug fullkey "$_fullkey" + RM_recordid="$(_readaccountconf "$_fullkey")" + _debug rm_recordid "$RM_recordid" + _debug "detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + if ! _rest GET "record.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then + _err "get record lis error." + return 1 + fi + + if ! _contains "$response" "$RM_recordid"; then + _info "no need to remove record." + return 0 + fi + + if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then + _err "record remove error." + return 1 + fi + + _clearaccountconf "$_fullkey" + + _contains "$response" "\"code\":300" +} + +#add the txt record. +#usage: root sub txtvalue +add_record() { + root=$1 + sub=$2 + txtvalue=$3 + fulldomain="$sub.$root" + + _info "adding txt record" + + if ! _rest GET "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then + return 1 + fi + + if _contains "$response" "\"code\":300"; then + _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) + _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) + _debug fullkey "$_fullkey" + _saveaccountconf "$_fullkey" "$_record_id" + _debug _record_id "$_record_id" + fi + _contains "$response" "\"code\":300" +} + +#################### 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 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _rest GET "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then + return 1 + fi + + if _contains "$response" "\"code\":300"; then + _domain_id=$(printf "%s" "$response" | grep '"domainid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) + _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" + data="$3" + _debug "$ep" + url="$DNSLA_API$ep" + + _debug url "$url" + + if [ "$m" = "GET" ]; then + response="$(_get "$url" | tr -d ' ' | tr "}" ",")" + else + _debug2 data "$data" + response="$(_post "$data" "$url" | tr -d ' ' | tr "}" ",")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 23c3e9482fadeea75b2147e8542339b390df97b5 Mon Sep 17 00:00:00 2001 From: stephen Date: Tue, 16 Aug 2022 15:35:22 +0800 Subject: [PATCH 1947/2234] Delete dns_la.sh --- dnsapi/dns_la.sh | 161 ----------------------------------------------- 1 file changed, 161 deletions(-) delete mode 100644 dnsapi/dns_la.sh diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh deleted file mode 100644 index 0468220a..00000000 --- a/dnsapi/dns_la.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env sh -# dns.la Domain api -# -#LA_Id="test123" -# -#LA_Key="d1j2fdo4dee3948" -DNSLA_API="https://www.dns.la/api/" -######## Public functions ##################### -#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_la_add() { - fulldomain=$1 - txtvalue=$2 - - LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" - LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" - if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then - LA_Id="" - LA_Key="" - _err "You don't specify dnsla api id and key yet." - _err "Please create your key and try again." - return 1 - fi - - #save the api key and email to the account conf file. - _saveaccountconf_mutable LA_Id "$LA_Id" - _saveaccountconf_mutable LA_Key "$LA_Key" - - _debug "detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - - add_record "$_domain" "$_sub_domain" "$txtvalue" - -} - -#fulldomain txtvalue -dns_la_rm() { - fulldomain=$1 - txtvalue=$2 - _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) - - LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" - LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" - _debug fullkey "$_fullkey" - RM_recordid="$(_readaccountconf "$_fullkey")" - _debug rm_recordid "$RM_recordid" - _debug "detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - - if ! _rest GET "record.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then - _err "get record lis error." - return 1 - fi - - if ! _contains "$response" "$RM_recordid"; then - _info "no need to remove record." - return 0 - fi - - if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then - _err "record remove error." - return 1 - fi - - _clearaccountconf "$_fullkey" - - _contains "$response" "\"code\":300" -} - -#add the txt record. -#usage: root sub txtvalue -add_record() { - root=$1 - sub=$2 - txtvalue=$3 - fulldomain="$sub.$root" - - _info "adding txt record" - - if ! _rest GET "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then - return 1 - fi - - if _contains "$response" "\"code\":300"; then - _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) - _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_' ) - _debug fullkey "$_fullkey" - _saveaccountconf "$_fullkey" "$_record_id" - _debug _record_id "$_record_id" - fi - _contains "$response" "\"code\":300" -} - -#################### 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 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if [ -z "$h" ]; then - #not valid - return 1 - fi - - if ! _rest GET "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then - return 1 - fi - - if _contains "$response" "\"code\":300"; then - _domain_id=$(printf "%s" "$response" | grep '"domainid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n' ) - _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" - data="$3" - _debug "$ep" - url="$DNSLA_API$ep" - - _debug url "$url" - - if [ "$m" = "GET" ]; then - response="$(_get "$url" | tr -d ' ' | tr "}" ",")" - else - _debug2 data "$data" - response="$(_post "$data" "$url" | tr -d ' ' | tr "}" ",")" - fi - - if [ "$?" != "0" ]; then - _err "error $ep" - return 1 - fi - _debug2 response "$response" - return 0 -} From 5899d7034fd906a1194beb2205a9fc338ff6b200 Mon Sep 17 00:00:00 2001 From: stephen Date: Tue, 16 Aug 2022 15:35:46 +0800 Subject: [PATCH 1948/2234] dns.la official acme script dns.la official acme script --- dnsapi/dns_la.sh | 161 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 dnsapi/dns_la.sh diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh new file mode 100644 index 00000000..4d60c243 --- /dev/null +++ b/dnsapi/dns_la.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env sh +# dns.la Domain api +# +#LA_Id="test123" +# +#LA_Key="d1j2fdo4dee3948" +DNSLA_API="https://www.dns.la/api/" +######## Public functions ##################### +#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_la_add() { + fulldomain=$1 + txtvalue=$2 + + LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" + LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" + if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then + LA_Id="" + LA_Key="" + _err "You don't specify dnsla api id and key yet." + _err "Please create your key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable LA_Id "$LA_Id" + _saveaccountconf_mutable LA_Key "$LA_Key" + + _debug "detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + add_record "$_domain" "$_sub_domain" "$txtvalue" + +} + +#fulldomain txtvalue +dns_la_rm() { + fulldomain=$1 + txtvalue=$2 + _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_') + + LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" + LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" + _debug fullkey "$_fullkey" + RM_recordid="$(_readaccountconf "$_fullkey")" + _debug rm_recordid "$RM_recordid" + _debug "detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + if ! _rest GET "record.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then + _err "get record lis error." + return 1 + fi + + if ! _contains "$response" "$RM_recordid"; then + _info "no need to remove record." + return 0 + fi + + if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then + _err "record remove error." + return 1 + fi + + _clearaccountconf "$_fullkey" + + _contains "$response" "\"code\":300" +} + +#add the txt record. +#usage: root sub txtvalue +add_record() { + root=$1 + sub=$2 + txtvalue=$3 + fulldomain="$sub.$root" + + _info "adding txt record" + + if ! _rest GET "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then + return 1 + fi + + if _contains "$response" "\"code\":300"; then + _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') + _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_') + _debug fullkey "$_fullkey" + _saveaccountconf "$_fullkey" "$_record_id" + _debug _record_id "$_record_id" + fi + _contains "$response" "\"code\":300" +} + +#################### 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 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _rest GET "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then + return 1 + fi + + if _contains "$response" "\"code\":300"; then + _domain_id=$(printf "%s" "$response" | grep '"domainid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') + _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" + data="$3" + _debug "$ep" + url="$DNSLA_API$ep" + + _debug url "$url" + + if [ "$m" = "GET" ]; then + response="$(_get "$url" | tr -d ' ' | tr "}" ",")" + else + _debug2 data "$data" + response="$(_post "$data" "$url" | tr -d ' ' | tr "}" ",")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From e1eb0018720eaf111180da9d036b7a92cf213682 Mon Sep 17 00:00:00 2001 From: stephen Date: Wed, 17 Aug 2022 17:23:12 +0800 Subject: [PATCH 1949/2234] dns.la official acme script dns.la official acme script --- dnsapi/dns_la.sh | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh index 4d60c243..b8b484a5 100644 --- a/dnsapi/dns_la.sh +++ b/dnsapi/dns_la.sh @@ -4,7 +4,7 @@ #LA_Id="test123" # #LA_Key="d1j2fdo4dee3948" -DNSLA_API="https://www.dns.la/api/" +DNSLA_API="https://api.dns.la/api/" ######## Public functions ##################### #Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_la_add() { @@ -39,36 +39,34 @@ dns_la_add() { dns_la_rm() { fulldomain=$1 txtvalue=$2 - _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_') LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" - _debug fullkey "$_fullkey" - RM_recordid="$(_readaccountconf "$_fullkey")" - _debug rm_recordid "$RM_recordid" - _debug "detect the root zone" + + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 fi - if ! _rest GET "record.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then - _err "get record lis error." + if ! _rest GET "record.ashx?cmd=listn&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue"; then + _err "get record list error." return 1 fi - if ! _contains "$response" "$RM_recordid"; then + if ! _contains "$response" "recordid"; then _info "no need to remove record." return 0 fi - if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$RM_recordid"; then + _record_id=$(printf "%s" "$response" | grep '"recordid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') + + _debug delete_rid "$_record_id" + if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$_record_id"; then _err "record remove error." return 1 fi - _clearaccountconf "$_fullkey" - _contains "$response" "\"code\":300" } @@ -81,16 +79,12 @@ add_record() { fulldomain="$sub.$root" _info "adding txt record" - if ! _rest GET "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then return 1 fi if _contains "$response" "\"code\":300"; then _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') - _fullkey=$(printf "%s" "$fulldomain" | awk '{ string=substr($0, 17); print string; }' | tr '.' '_') - _debug fullkey "$_fullkey" - _saveaccountconf "$_fullkey" "$_record_id" _debug _record_id "$_record_id" fi _contains "$response" "\"code\":300" From 233c724b2dc4e2080f9e2b3ca285ff4853d5b0fa Mon Sep 17 00:00:00 2001 From: stephen Date: Wed, 17 Aug 2022 18:18:42 +0800 Subject: [PATCH 1950/2234] dns.la official acme script dns.la official acme script --- dnsapi/dns_la.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh index b8b484a5..921da473 100644 --- a/dnsapi/dns_la.sh +++ b/dnsapi/dns_la.sh @@ -83,11 +83,10 @@ add_record() { return 1 fi - if _contains "$response" "\"code\":300"; then - _record_id=$(printf "%s" "$response" | grep '"resultid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') - _debug _record_id "$_record_id" + if _contains "$response" "resultid" || _contains "$response" "\"code\":532"; then + return 0 fi - _contains "$response" "\"code\":300" + return 1 } #################### Private functions below ################################## From d5b649a1a4b821a6379cfc99ff5d1cd75d65afca Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 17 Aug 2022 23:49:30 +0800 Subject: [PATCH 1951/2234] add tests for wget --- .github/workflows/FreeBSD.yml | 11 +++++++++-- .github/workflows/OpenBSD.yml | 11 +++++++++-- .github/workflows/Solaris.yml | 11 +++++++++-- .github/workflows/Ubuntu.yml | 9 ++++++++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 74b69745..414523d9 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -25,6 +25,12 @@ jobs: CA: "" CA_EMAIL: "" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" @@ -38,6 +44,7 @@ jobs: CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - uses: actions/checkout@v2 - uses: vmactions/cf-tunnel@v0.0.3 @@ -51,10 +58,10 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0 with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' nat: | "8080": "80" - prepare: pkg install -y socat curl + prepare: pkg install -y socat curl wget usesh: true copyback: false run: | diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 6aba1b2a..41844a89 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -25,6 +25,12 @@ jobs: CA: "" CA_EMAIL: "" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" @@ -38,6 +44,7 @@ jobs: CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - uses: actions/checkout@v2 - uses: vmactions/cf-tunnel@v0.0.3 @@ -51,10 +58,10 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/openbsd-vm@v0 with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' nat: | "8080": "80" - prepare: pkg_add socat curl + prepare: pkg_add socat curl wget usesh: true copyback: false run: | diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 53386752..188352b1 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -25,6 +25,12 @@ jobs: CA: "" CA_EMAIL: "" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" @@ -38,6 +44,7 @@ jobs: CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - uses: actions/checkout@v2 - uses: vmactions/cf-tunnel@v0.0.3 @@ -51,11 +58,11 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0 with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' copyback: "false" nat: | "8080": "80" - prepare: pkgutil -y -i socat curl + prepare: pkgutil -y -i socat curl wget run: | cd ../acmetest \ && ./letest.sh diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 4540580c..5f9fb74c 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -25,6 +25,12 @@ jobs: CA: "" CA_EMAIL: "" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + ACME_USE_WGET: 1 - TEST_ACME_Server: "ZeroSSL.com" CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA: "ZeroSSL RSA Domain Secure Site CA" @@ -57,10 +63,11 @@ jobs: NO_REVOKE: ${{ matrix.NO_REVOKE }} TEST_IPCERT: ${{ matrix.TEST_IPCERT }} TestingDomain: ${{ matrix.TestingDomain }} + ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - uses: actions/checkout@v2 - name: Install tools - run: sudo apt-get install -y socat + run: sudo apt-get install -y socat wget - name: Start StepCA if: ${{ matrix.TEST_ACME_Server=='https://localhost:9000/acme/acme/directory' }} run: | From 7122a960fa1c4e33ca22d0afd98063df0a89757e Mon Sep 17 00:00:00 2001 From: Dennis Koot Date: Tue, 26 Jul 2022 11:33:50 +0200 Subject: [PATCH 1952/2234] make ip-whitelisting configurable for DNS TransIP and download keyfile if it is an url --- dnsapi/dns_transip.sh | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 23debe0d..64a256ec 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -1,7 +1,6 @@ #!/usr/bin/env sh TRANSIP_Api_Url="https://api.transip.nl/v6" TRANSIP_Token_Read_Only="false" -TRANSIP_Token_Global_Key="false" TRANSIP_Token_Expiration="30 minutes" # You can't reuse a label token, so we leave this empty normally TRANSIP_Token_Label="" @@ -96,7 +95,11 @@ _transip_get_token() { nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex | cut -c 1-32) _debug nonce "$nonce" - data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key}\"}" + # make IP whitelisting configurable + TRANSIP_Token_Global_Key="${TRANSIP_Token_Global_Key:-$(_readaccountconf_mutable TRANSIP_Token_Global_Key)}" + _saveaccountconf_mutable TRANSIP_Token_Global_Key "$TRANSIP_Token_Global_Key" + + data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key:-false}\"}" _debug data "$data" #_signature=$(printf "%s" "$data" | openssl dgst -sha512 -sign "$TRANSIP_Key_File" | _base64) @@ -139,6 +142,18 @@ _transip_setup() { _saveaccountconf_mutable TRANSIP_Username "$TRANSIP_Username" _saveaccountconf_mutable TRANSIP_Key_File "$TRANSIP_Key_File" + # download key file if it's an URL + if _startswith "$TRANSIP_Key_File" "http"; then + _debug "download transip key file" + TRANSIP_Key_URL=$TRANSIP_Key_File + TRANSIP_Key_File="$(_mktemp)" + chmod 600 "$TRANSIP_Key_File" + if ! _get "$TRANSIP_Key_URL" >"$TRANSIP_Key_File"; then + _err "Error getting key file from : $TRANSIP_Key_URL" + return 1 + fi + fi + if [ -f "$TRANSIP_Key_File" ]; then if ! grep "BEGIN PRIVATE KEY" "$TRANSIP_Key_File" >/dev/null 2>&1; then _err "Key file doesn't seem to be a valid key: ${TRANSIP_Key_File}" @@ -156,6 +171,12 @@ _transip_setup() { fi fi + if [ -n "${TRANSIP_Key_URL}" ]; then + _debug "delete transip key file" + rm "${TRANSIP_Key_File}" + TRANSIP_Key_File=$TRANSIP_Key_URL + fi + _get_root "$fulldomain" || return 1 return 0 From 0e8fef73bb67b02ca28a2a05088f8aca4cd0a24d Mon Sep 17 00:00:00 2001 From: Hobby-Student <6012744+Hobby-Student@users.noreply.github.com> Date: Wed, 17 Aug 2022 19:43:30 +0200 Subject: [PATCH 1953/2234] error handling, minor changes to params, ... --- dnsapi/dns_kas.sh | 202 +++++++++++++++++++++++++++++++--------------- 1 file changed, 137 insertions(+), 65 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 755161e4..b42722b4 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -5,55 +5,81 @@ # Environment variables: # # - $KAS_Login (Kasserver API login name) -# - $KAS_Authtype (Kasserver API auth type. Default: sha1) +# - $KAS_Authtype (Kasserver API auth type. Default: plain) # - $KAS_Authdata (Kasserver API auth data.) # -# Author: Martin Kammerlander, Phlegx Systems OG -# Updated by: Marc-Oliver Lange -# Credits: Inspired by dns_he.sh. Thanks a lot man! -# Git repo: https://github.com/phlegx/acme.sh -# TODO: Better Error handling +# Author: squared GmbH +# Credits: +# Inspired by dns_he.sh. Thanks a lot man! +# Previous version by Martin Kammerlander, Phlegx Systems OG +# Previous update by Marc-Oliver Lange +# KASAPI SOAP guideline by https://github.com/o1oo11oo/kasapi.sh ######################################################################## -KAS_Api="https://kasapi.kasserver.com/soap/KasApi.php" -KAS_Auth="https://kasapi.kasserver.com/soap/KasAuth.php" +KAS_Api_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasApi.wsdl")" +KAS_Api="$(echo "$KAS_Api_GET" | tr -d ' ' | grep -i "//g")" +_info "[KAS] -> API URL $KAS_Api" + +KAS_Auth_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasAuth.wsdl")" +KAS_Auth="$(echo "$KAS_Auth_GET" | tr -d ' ' | grep -i "//g")" +_info "[KAS] -> AUTH URL $KAS_Auth" + +KAS_default_ratelimit=5 # TODO - Every response delivers a ratelimit (seconds) where KASAPI is blocking a request. + ######## Public functions ##################### dns_kas_add() { _fulldomain=$1 _txtvalue=$2 - _info "### -> Using DNS-01 All-inkl/Kasserver hook" - _info "### -> Adding $_fulldomain DNS TXT entry on All-inkl/Kasserver" - _info "### -> Retriving Credential Token" + _info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook" + _info "[KAS] -> Adding $_fulldomain DNS TXT entry on All-inkl/Kasserver" + _info "[KAS] -> Retriving Credential Token" _get_credential_token - _info "### -> Check and Save Props" + _info "[KAS] -> Check and Save Props" _check_and_save - _info "### -> Checking Zone and Record_Name" + _info "[KAS] -> Checking Zone and Record_Name" _get_zone_and_record_name "$_fulldomain" - _info "### -> Checking for existing Record entries" + _info "[KAS] -> Checking for existing Record entries" _get_record_id # If there is a record_id, delete the entry if [ -n "$_record_id" ]; then - _info "Existing records found. Now deleting old entries" + _info "[KAS] -> Existing records found. Now deleting old entries" for i in $_record_id; do _delete_RecordByID "$i" done else - _info "No record found." + _info "[KAS] -> No record found." fi - _info "### -> Creating TXT DNS record" + _info "[KAS] -> Creating TXT DNS record" action="add_dns_settings" - kasReqParam="{\"record_name\":\"$_record_name\",\"record_type\":\"TXT\",\"record_data\":\"$_txtvalue\",\"record_aux\":\"0\",\"zone_host\":\"$_zone\"}" + kasReqParam="\"record_name\":\"$_record_name\"" + kasReqParam="$kasReqParam,\"record_type\":\"TXT\"" + kasReqParam="$kasReqParam,\"record_data\":\"$_txtvalue\"" + kasReqParam="$kasReqParam,\"record_aux\":\"0\"" + kasReqParam="$kasReqParam,\"zone_host\":\"$_zone\"" response="$(_callAPI "$action" "$kasReqParam")" + _debug2 "[KAS] -> Response" "$response" - _debug2 "Response" "$response" - - if ! _contains "$response" "TRUE"; then - _err "An unkown error occurred, please check manually." + if [ -z "$response" ]; then + _info "[KAS] -> Response was empty, please check manually." + return 1 + elif _contains "$response" ""; then + faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")" + case "${faultstring}" in + "record_already_exists") + _info "[KAS] -> The record already exists, which must not be a problem. Please check manually." + ;; + *) + _err "[KAS] -> An error =>$faultstring<= occurred, please check manually." + return 1 + ;; + esac + elif ! _contains "$response" "ReturnStringTRUE"; then + _err "[KAS] -> An unknown error occurred, please check manually." return 1 fi return 0 @@ -63,29 +89,29 @@ dns_kas_rm() { _fulldomain=$1 _txtvalue=$2 - _info "### -> Using DNS-01 All-inkl/Kasserver hook" - _info "### -> Cleaning up after All-inkl/Kasserver hook" - _info "### -> Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver" - _info "### -> Retriving Credential Token" + _info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook" + _info "[KAS] -> Cleaning up after All-inkl/Kasserver hook" + _info "[KAS] -> Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver" + _info "[KAS] -> Retriving Credential Token" _get_credential_token - _info "### -> Check and Save Props" + _info "[KAS] -> Check and Save Props" _check_and_save - _info "### -> Checking Zone and Record_Name" + _info "[KAS] -> Checking Zone and Record_Name" _get_zone_and_record_name "$_fulldomain" - _info "### -> Getting Record ID" + _info "[KAS] -> Getting Record ID" _get_record_id - _info "### -> Removing entries with ID: $_record_id" + _info "[KAS] -> Removing entries with ID: $_record_id" # If there is a record_id, delete the entry if [ -n "$_record_id" ]; then for i in $_record_id; do _delete_RecordByID "$i" done else # Cannot delete or unkown error - _info "No record_id found that can be deleted. Please check manually." + _info "[KAS] -> No record_id found that can be deleted. Please check manually." fi return 0 } @@ -95,11 +121,27 @@ dns_kas_rm() { _delete_RecordByID() { recId=$1 action="delete_dns_settings" - kasReqParam="{\"record_id\":\"$recId\"}" + kasReqParam="\"record_id\":\"$recId\"" response="$(_callAPI "$action" "$kasReqParam")" - _debug2 "Response" "$response" - if ! _contains "$response" "TRUE"; then - _info "Either the txt record is not found or another error occurred, please check manually." + _debug2 "[KAS] -> Response" "$response" + + if [ -z "$response" ]; then + _info "[KAS] -> Response was empty, please check manually." + return 1 + elif _contains "$response" ""; then + faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")" + case "${faultstring}" in + "record_id_not_found") + _info "[KAS] -> The record was not found, which perhaps is not a problem. Please check manually." + ;; + *) + _err "[KAS] -> An error =>$faultstring<= occurred, please check manually." + return 1 + ;; + esac + elif ! _contains "$response" "ReturnStringTRUE"; then + _err "[KAS] -> An unknown error occurred, please check manually." + return 1 fi } # Checks for the ENV variables and saves them @@ -112,7 +154,7 @@ _check_and_save() { KAS_Login= KAS_Authtype= KAS_Authdata= - _err "No auth details provided. Please set user credentials using the \$KAS_Login, \$KAS_Authtype, and \$KAS_Authdata environment variables." + _err "[KAS] -> No auth details provided. Please set user credentials using the \$KAS_Login, \$KAS_Authtype, and \$KAS_Authdata environment variables." return 1 fi _saveaccountconf_mutable KAS_Login "$KAS_Login" @@ -125,9 +167,18 @@ _check_and_save() { # See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide _get_zone_and_record_name() { action="get_domains" - kasReqParam="[]" - response="$(_callAPI "$action" "$kasReqParam")" - _debug2 "Response" "$response" + response="$(_callAPI "$action")" + _debug2 "[KAS] -> Response" "$response" + + if [ -z "$response" ]; then + _info "[KAS] -> Response was empty, please check manually." + return 1 + elif _contains "$response" ""; then + faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")" + _err "[KAS] -> Either no domains were found or another error =>$faultstring<= occurred, please check manually." + return 1 + fi + zonen="$(echo "$response" | sed 's//\n/g' | sed -r 's/(.*domain_name<\/key>)(.*)(<\/value.*)/\2/' | sed '/^ Zone:" "$_zone" + _debug "[KAS] -> Domain:" "$domain" + _debug "[KAS] -> Record_Name:" "$_record_name" return 0 } # Retrieve the DNS record ID _get_record_id() { action="get_dns_settings" - kasReqParam="{\"zone_host\":\"$_zone\",\"nameserver\":\"ns5.kasserver.com\"}" + kasReqParam="\"zone_host\":\"$_zone\"" response="$(_callAPI "$action" "$kasReqParam")" + _debug2 "[KAS] -> Response" "$response" - _debug2 "Response" "$response" - _record_id="$(echo "$response" | sed 's//\n/g' | sed -n -e "/^.*$_record_name.*/Ip" | sed -n -e "/^.*$_txtvalue.*/Ip" | sed -r 's/(.*record_id<\/key>)([0-9]+)(<\/value.*)/\2/')" - _debug "Record Id: " "$_record_id" + if [ -z "$response" ]; then + _info "[KAS] -> Response was empty, please check manually." + return 1 + elif _contains "$response" ""; then + faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")" + _err "[KAS] -> Either no domains were found or another error =>$faultstring<= occurred, please check manually." + return 1 + fi + + _record_id="$(echo "$response" | tr -d '\n\r' | sed "s//\n/g" | grep -i "$_record_name" | grep -i ">TXT<" | sed "s/record_id<\/key>/=>/g" | sed "s/<\/value><\/item>/\n/g" | grep "=>" | sed "s/=>//g")" + _debug "[KAS] -> Record Id: " "$_record_id" return 0 } # Retrieve credential token _get_credential_token() { - data="" - data="$data{\"kas_login\":\"$KAS_Login\",\"kas_auth_type\":\"$KAS_Authtype\",\"kas_auth_data\":\"$KAS_Authdata\",\"session_lifetime\":600,\"session_update_lifetime\":\"Y\",\"session_2fa\":123456}" - data="$data" + baseParamAuth="\"kas_login\":\"$KAS_Login\"" + baseParamAuth="$baseParamAuth,\"kas_auth_type\":\"$KAS_Authtype\"" + baseParamAuth="$baseParamAuth,\"kas_auth_data\":\"$KAS_Authdata\"" + baseParamAuth="$baseParamAuth,\"session_lifetime\":600" + baseParamAuth="$baseParamAuth,\"session_update_lifetime\":\"Y\"" - _debug "Be frindly and wait 10 seconds by default before calling KAS API." - _sleep 10 + data='{' + data="$data$baseParamAuth}" + + _debug "[KAS] -> Be friendly and wait $KAS_default_ratelimit seconds by default before calling KAS API." + _sleep $KAS_default_ratelimit contentType="text/xml" - export _H1="SOAPAction: ns1:KasAuth" + export _H1="SOAPAction: urn:xmethodsKasApiAuthentication#KasAuth" response="$(_post "$data" "$KAS_Auth" "" "POST" "$contentType")" - _debug2 "Response" "$response" + _debug2 "[KAS] -> Response" "$response" _credential_token="$(echo "$response" | tr '\n' ' ' | sed 's/.*return xsi:type="xsd:string">\(.*\)<\/return>/\1/' | sed 's/<\/ns1:KasAuthResponse\(.*\)Envelope>.*//')" - _debug "Credential Token: " "$_credential_token" + _debug "[KAS] -> Credential Token: " "$_credential_token" return 0 } _callAPI() { kasaction=$1 kasReqParams=$2 - baseParam="{\"kas_login\":\"$KAS_Login\",\"kas_auth_type\":\"session\",\"kas_auth_data\":\"$_credential_token\",\"kas_action\":\"$kasaction\",\"KasRequestParams\":$kasReqParams" - baseParamClosing="}" - data="" - data="$data$baseParam$baseParamClosing" - data="$data" - _debug2 "Request" "$data" - _debug "Be frindly and wait 10 seconds by default before calling KAS API." - _sleep 10 + baseParamAuth="\"kas_login\":\"$KAS_Login\"" + baseParamAuth="$baseParamAuth,\"kas_auth_type\":\"session\"" + baseParamAuth="$baseParamAuth,\"kas_auth_data\":\"$_credential_token\"" + + data='{' + data="$data$baseParamAuth,\"kas_action\":\"$kasaction\"" + if [ -n "$kasReqParams" ]; then + data="$data,\"KasRequestParams\":{$kasReqParams}" + fi + data="$data}" + + _debug2 "[KAS] -> Request" "$data" + + _debug "[KAS] -> Be friendly and wait $KAS_default_ratelimit seconds by default before calling KAS API." + _sleep $KAS_default_ratelimit contentType="text/xml" - export _H1="SOAPAction: ns1:KasApi" + export _H1="SOAPAction: urn:xmethodsKasApi#KasApi" response="$(_post "$data" "$KAS_Api" "" "POST" "$contentType")" - _debug2 "Response" "$response" + _debug2 "[KAS] -> Response" "$response" echo "$response" -} +} \ No newline at end of file From da6a335b8733daba8d6d5d499037733f0b47e035 Mon Sep 17 00:00:00 2001 From: Hobby-Student <6012744+Hobby-Student@users.noreply.github.com> Date: Wed, 17 Aug 2022 19:50:47 +0200 Subject: [PATCH 1954/2234] new line EOF --- dnsapi/dns_kas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index b42722b4..5e725e9a 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -269,4 +269,4 @@ _callAPI() { response="$(_post "$data" "$KAS_Api" "" "POST" "$contentType")" _debug2 "[KAS] -> Response" "$response" echo "$response" -} \ No newline at end of file +} From b42532afe9f664e5907618ff6754e798c089bb24 Mon Sep 17 00:00:00 2001 From: Hobby-Student <6012744+Hobby-Student@users.noreply.github.com> Date: Wed, 17 Aug 2022 19:58:34 +0200 Subject: [PATCH 1955/2234] forgot enabling github actions. forced commit --- dnsapi/dns_kas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 5e725e9a..6bb0823e 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -31,7 +31,7 @@ dns_kas_add() { _txtvalue=$2 _info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook" - _info "[KAS] -> Adding $_fulldomain DNS TXT entry on All-inkl/Kasserver" + _info "[KAS] -> Adding $_fulldomain DNS TXT entry on all-inkl.com/Kasserver" _info "[KAS] -> Retriving Credential Token" _get_credential_token From b44ba0d21a8bfbc60708c8afa7477af9e0ef19cc Mon Sep 17 00:00:00 2001 From: Danny Tix Date: Tue, 16 Aug 2022 23:08:04 -0800 Subject: [PATCH 1956/2234] Add wildcard deployment to cpanel_uapi --- deploy/cpanel_uapi.sh | 187 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 168 insertions(+), 19 deletions(-) diff --git a/deploy/cpanel_uapi.sh b/deploy/cpanel_uapi.sh index 44844f79..eea96248 100644 --- a/deploy/cpanel_uapi.sh +++ b/deploy/cpanel_uapi.sh @@ -3,18 +3,29 @@ # Uses command line uapi. --user option is needed only if run as root. # Returns 0 when success. # +# Configure DEPLOY_CPANEL_AUTO_<...> options to enable or restrict automatic +# detection of deployment targets through UAPI (if not set, defaults below are used.) +# - ENABLED : 'true' for multi-site / wildcard capability; otherwise single-site mode. +# - NOMATCH : 'true' to allow deployment to sites that do not match the certificate. +# - INCLUDE : Comma-separated list - sites must match this field. +# - EXCLUDE : Comma-separated list - sites must NOT match this field. +# INCLUDE/EXCLUDE both support non-lexical, glob-style matches using '*' +# # Please note that I am no longer using Github. If you want to report an issue # or contact me, visit https://forum.webseodesigners.com/web-design-seo-and-hosting-f16/ # # Written by Santeri Kannisto # Public domain, 2017-2018 - -#export DEPLOY_CPANEL_USER=myusername +# +# export DEPLOY_CPANEL_USER=myusername +# export DEPLOY_CPANEL_AUTO_ENABLED='true' +# export DEPLOY_CPANEL_AUTO_NOMATCH='false' +# export DEPLOY_CPANEL_AUTO_INCLUDE='*' +# export DEPLOY_CPANEL_AUTO_EXCLUDE='' ######## Public functions ##################### #domain keyfile certfile cafile fullchain - cpanel_uapi_deploy() { _cdomain="$1" _ckey="$2" @@ -22,6 +33,9 @@ cpanel_uapi_deploy() { _cca="$4" _cfullchain="$5" + # re-declare vars inherited from acme.sh but not passed to make ShellCheck happy + : "${Le_Alt:=""}" + _debug _cdomain "$_cdomain" _debug _ckey "$_ckey" _debug _ccert "$_ccert" @@ -32,31 +46,166 @@ cpanel_uapi_deploy() { _err "The command uapi is not found." return 1 fi + + # declare useful constants + uapi_error_response='status: 0' + # read cert and key files and urlencode both _cert=$(_url_encode <"$_ccert") _key=$(_url_encode <"$_ckey") - _debug _cert "$_cert" - _debug _key "$_key" + _debug2 _cert "$_cert" + _debug2 _key "$_key" if [ "$(id -u)" = 0 ]; then - if [ -z "$DEPLOY_CPANEL_USER" ]; then + _getdeployconf DEPLOY_CPANEL_USER + # fallback to _readdomainconf for old installs + if [ -z "${DEPLOY_CPANEL_USER:=$(_readdomainconf DEPLOY_CPANEL_USER)}" ]; then _err "It seems that you are root, please define the target user name: export DEPLOY_CPANEL_USER=username" return 1 fi - _savedomainconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER" - _response=$(uapi --user="$DEPLOY_CPANEL_USER" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key") - else - _response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key") - fi - error_response="status: 0" - if test "${_response#*$error_response}" != "$_response"; then - _err "Error in deploying certificate:" - _err "$_response" - return 1 + _debug DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER" + _savedeployconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER" + + _uapi_user="$DEPLOY_CPANEL_USER" fi - _debug response "$_response" - _info "Certificate successfully deployed" - return 0 + # Load all AUTO envars and set defaults - see above for usage + __cpanel_initautoparam ENABLED 'true' + __cpanel_initautoparam NOMATCH 'false' + __cpanel_initautoparam INCLUDE '*' + __cpanel_initautoparam EXCLUDE '' + + # Auto mode + if [ "$DEPLOY_CPANEL_AUTO_ENABLED" = "true" ]; then + # call API for site config + _response=$(uapi DomainInfo list_domains) + # exit if error in response + if [ -z "$_response" ] || [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then + _err "Error in deploying certificate - cannot retrieve sitelist:" + _err "\n$_response" + return 1 + fi + + # parse response to create site list + sitelist=$(__cpanel_parse_response "$_response") + _debug "UAPI sites found: $sitelist" + + # filter sitelist using configured domains + # skip if NOMATCH is "true" + if [ "$DEPLOY_CPANEL_AUTO_NOMATCH" = "true" ]; then + _debug "DEPLOY_CPANEL_AUTO_NOMATCH is true" + _info "UAPI nomatch mode is enabled - Will not validate sites are valid for the certificate" + else + _debug "DEPLOY_CPANEL_AUTO_NOMATCH is false" + d="$(echo "${Le_Alt}," | sed -e "s/^$_cdomain,//" -e "s/,$_cdomain,/,/")" + d="$(echo "$_cdomain,$d" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\[\^\.\]\*/g')" + sitelist="$(echo "$sitelist" | grep -ix "$d")" + _debug2 "Matched UAPI sites: $sitelist" + fi + + # filter sites that do not match $DEPLOY_CPANEL_AUTO_INCLUDE + _info "Applying sitelist filter DEPLOY_CPANEL_AUTO_INCLUDE: $DEPLOY_CPANEL_AUTO_INCLUDE" + sitelist="$(echo "$sitelist" | grep -ix "$(echo "$DEPLOY_CPANEL_AUTO_INCLUDE" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\.\*/g')")" + _debug2 "Remaining sites: $sitelist" + + # filter sites that match $DEPLOY_CPANEL_AUTO_EXCLUDE + _info "Applying sitelist filter DEPLOY_CPANEL_AUTO_EXCLUDE: $DEPLOY_CPANEL_AUTO_EXCLUDE" + sitelist="$(echo "$sitelist" | grep -vix "$(echo "$DEPLOY_CPANEL_AUTO_EXCLUDE" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\.\*/g')")" + _debug2 "Remaining sites: $sitelist" + + # counter for success / failure check + successes=0 + if [ -n "$sitelist" ]; then + sitetotal="$(echo "$sitelist" | wc -l)" + _debug "$sitetotal sites to deploy" + else + sitetotal=0 + _debug "No sites to deploy" + fi + + # for each site: call uapi to publish cert and log result. Only return failure if all fail + for site in $sitelist; do + # call uapi to publish cert, check response for errors and log them. + if [ -n "$_uapi_user" ]; then + _response=$(uapi --user="$_uapi_user" SSL install_ssl domain="$site" cert="$_cert" key="$_key") + else + _response=$(uapi SSL install_ssl domain="$site" cert="$_cert" key="$_key") + fi + if [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then + _err "Error in deploying certificate to $site:" + _err "$_response" + else + successes=$((successes + 1)) + _debug "$_response" + _info "Succcessfully deployed to $site" + fi + done + + # Raise error if all updates fail + if [ "$sitetotal" -gt 0 ] && [ "$successes" -eq 0 ]; then + _err "Could not deploy to any of $sitetotal sites via UAPI" + _debug "successes: $successes, sitetotal: $sitetotal" + return 1 + fi + + _info "Successfully deployed certificate to $successes of $sitetotal sites via UAPI" + return 0 + else + # "classic" mode - will only try to deploy to the primary domain; will not check UAPI first + if [ -n "$_uapi_user" ]; then + _response=$(uapi --user="$_uapi_user" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key") + else + _response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key") + fi + + if [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then + _err "Error in deploying certificate:" + _err "$_response" + return 1 + fi + + _debug response "$_response" + _info "Certificate successfully deployed" + return 0 + fi +} + +######## Private functions ##################### + +# Internal utility to process YML from UAPI - only looks at main_domain and sub_domains +#[response] +__cpanel_parse_response() { + if [ $# -gt 0 ]; then resp="$*"; else resp="$(cat)"; fi + + echo "$resp" | + sed -En \ + -e 's/\r$//' \ + -e 's/^( *)([_.[:alnum:]]+) *: *(.*)/\1,\2,\3/p' \ + -e 's/^( *)- (.*)/\1,-,\2/p' | + awk -F, '{ + level = length($1)/2; + section[level] = $2; + for (i in section) {if (i > level) {delete section[i]}} + if (length($3) > 0) { + prefix=""; + for (i=0; i < level; i++) + { prefix = (prefix)(section[i])("/") } + printf("%s%s=%s\n", prefix, $2, $3); + } + }' | + sed -En -e 's/^result\/data\/(main_domain|sub_domains\/-)=(.*)$/\2/p' +} + +# Load parameter by prefix+name - fallback to default if not set, and save to config +#pname pdefault +__cpanel_initautoparam() { + pname="$1" + pdefault="$2" + pkey="DEPLOY_CPANEL_AUTO_$pname" + + _getdeployconf "$pkey" + [ -n "$(eval echo "\"\$$pkey\"")" ] || eval "$pkey=\"$pdefault\"" + _debug2 "$pkey" "$(eval echo "\"\$$pkey\"")" + _savedeployconf "$pkey" "$(eval echo "\"\$$pkey\"")" } From 5fbaeda217592501446892b94efd97df6833632d Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 18 Aug 2022 19:48:09 +0800 Subject: [PATCH 1957/2234] Update dns_la.sh --- dnsapi/dns_la.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh index 921da473..6d495e0a 100644 --- a/dnsapi/dns_la.sh +++ b/dnsapi/dns_la.sh @@ -97,7 +97,7 @@ add_record() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From 70351677a144ef374d6ca424d5b7df13c8af0b69 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 18 Aug 2022 20:30:11 +0800 Subject: [PATCH 1958/2234] add concurrency --- .github/workflows/DNS.yml | 3 +++ .github/workflows/DragonFlyBSD.yml | 6 ++++++ .github/workflows/FreeBSD.yml | 5 +++++ .github/workflows/Linux.yml | 6 ++++++ .github/workflows/MacOS.yml | 5 +++++ .github/workflows/NetBSD.yml | 6 ++++++ .github/workflows/OpenBSD.yml | 5 +++++ .github/workflows/PebbleStrict.yml | 7 +++++++ .github/workflows/Solaris.yml | 5 +++++ .github/workflows/Ubuntu.yml | 5 +++++ .github/workflows/Windows.yml | 5 +++++ .github/workflows/dockerhub.yml | 6 +++++- .github/workflows/shellcheck.yml | 5 +++++ 13 files changed, 68 insertions(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 04a8bd6d..8f487ff4 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -11,6 +11,9 @@ on: - 'dnsapi/*.sh' - '.github/workflows/DNS.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true jobs: CheckToken: diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index 76af8b30..ae953473 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -14,6 +14,12 @@ on: - '*.sh' - '.github/workflows/DragonFlyBSD.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + + jobs: DragonFlyBSD: diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 414523d9..151f462c 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -14,6 +14,11 @@ on: - '*.sh' - '.github/workflows/FreeBSD.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + jobs: FreeBSD: diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index c665652a..e532e1cb 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -15,6 +15,12 @@ on: - '.github/workflows/Linux.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + + jobs: Linux: diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index 8d52b3f6..34966144 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -14,6 +14,11 @@ on: - '*.sh' - '.github/workflows/MacOS.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + jobs: MacOS: diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 84bf96b8..53bb94d7 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -14,6 +14,12 @@ on: - '*.sh' - '.github/workflows/NetBSD.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + + jobs: NetBSD: diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 41844a89..698f86a3 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -14,6 +14,11 @@ on: - '*.sh' - '.github/workflows/OpenBSD.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + jobs: OpenBSD: diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 77512955..afd3a68f 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -13,6 +13,13 @@ on: - '*.sh' - '.github/workflows/PebbleStrict.yml' + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + + jobs: PebbleStrict: runs-on: ubuntu-latest diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 188352b1..12333ceb 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -15,6 +15,11 @@ on: - '.github/workflows/Solaris.yml' + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + jobs: Solaris: strategy: diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 5f9fb74c..478adca9 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -14,6 +14,11 @@ on: - '*.sh' - '.github/workflows/Ubuntu.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + jobs: Ubuntu: diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 55d32519..b5a0a6ba 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -15,6 +15,11 @@ on: - '.github/workflows/Windows.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + jobs: Windows: strategy: diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 0c3aec0a..bbda7550 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -11,7 +11,11 @@ on: - "Dockerfile" - '.github/workflows/dockerhub.yml' - +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + jobs: CheckToken: runs-on: ubuntu-latest diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 940a187d..3c24d2b4 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -13,6 +13,11 @@ on: - '**.sh' - '.github/workflows/shellcheck.yml' +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + jobs: ShellCheck: runs-on: ubuntu-latest From 039e4c662d5e9577707b0fba8f3208774258bfec Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 18 Aug 2022 21:10:38 +0800 Subject: [PATCH 1959/2234] rename the csr/key file if the cert is revoked. --- acme.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/acme.sh b/acme.sh index e8228e30..8a851fd4 100755 --- a/acme.sh +++ b/acme.sh @@ -6038,6 +6038,8 @@ revoke() { if [ -z "$response" ]; then _info "Revoke success." rm -f "$CERT_PATH" + cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked" + cat "$CSR_PATH" >"$CSR_PATH.revoked" return 0 else _err "Revoke error by domain key." @@ -6054,6 +6056,8 @@ revoke() { if [ -z "$response" ]; then _info "Revoke success." rm -f "$CERT_PATH" + cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked" + cat "$CSR_PATH" >"$CSR_PATH.revoked" return 0 else _err "Revoke error." From 2a05f24cb6df57c4faa1c992f0136ace5b493b6e Mon Sep 17 00:00:00 2001 From: stephen Date: Fri, 19 Aug 2022 11:12:16 +0800 Subject: [PATCH 1960/2234] Add dns.la api support Add dns.la api support --- dnsapi/dns_la.sh | 111 ++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh index 6d495e0a..674df410 100644 --- a/dnsapi/dns_la.sh +++ b/dnsapi/dns_la.sh @@ -1,11 +1,12 @@ #!/usr/bin/env sh -# dns.la Domain api -# + #LA_Id="test123" -# #LA_Key="d1j2fdo4dee3948" -DNSLA_API="https://api.dns.la/api/" + +LA_Api="https://api.dns.la/api" + ######## Public functions ##################### + #Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_la_add() { fulldomain=$1 @@ -13,11 +14,11 @@ dns_la_add() { LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" + if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then LA_Id="" LA_Key="" - _err "You don't specify dnsla api id and key yet." - _err "Please create your key and try again." + _err "You didn't specify a dnsla api id and key yet." return 1 fi @@ -25,13 +26,30 @@ dns_la_add() { _saveaccountconf_mutable LA_Id "$LA_Id" _saveaccountconf_mutable LA_Key "$LA_Key" - _debug "detect the root zone" + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" - add_record "$_domain" "$_sub_domain" "$txtvalue" + _info "Adding record" + if _la_rest "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then + if _contains "$response" '"resultid":'; then + _info "Added, OK" + return 0 + elif _contains "$response" '"code":532'; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 } @@ -48,45 +66,33 @@ dns_la_rm() { _err "invalid domain" return 1 fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" - if ! _rest GET "record.ashx?cmd=listn&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue"; then - _err "get record list error." + _debug "Getting txt records" + if ! _la_rest "record.ashx?cmd=listn&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue"; then + _err "Error" return 1 fi - if ! _contains "$response" "recordid"; then - _info "no need to remove record." + if ! _contains "$response" '"recordid":'; then + _info "Don't need to remove." return 0 fi - _record_id=$(printf "%s" "$response" | grep '"recordid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') - - _debug delete_rid "$_record_id" - if ! _rest GET "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$_record_id"; then - _err "record remove error." + record_id=$(printf "%s" "$response" | grep '"recordid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." return 1 fi - - _contains "$response" "\"code\":300" -} - -#add the txt record. -#usage: root sub txtvalue -add_record() { - root=$1 - sub=$2 - txtvalue=$3 - fulldomain="$sub.$root" - - _info "adding txt record" - if ! _rest GET "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then + if ! _la_rest "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$record_id"; then + _err "Delete record error." return 1 fi + _contains "$response" '"code":300' - if _contains "$response" "resultid" || _contains "$response" "\"code\":532"; then - return 0 - fi - return 1 } #################### Private functions below ################################## @@ -99,6 +105,7 @@ _get_root() { domain=$1 i=1 p=1 + while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) if [ -z "$h" ]; then @@ -106,18 +113,15 @@ _get_root() { return 1 fi - if ! _rest GET "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then + if ! _la_rest "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then return 1 fi - if _contains "$response" "\"code\":300"; then - _domain_id=$(printf "%s" "$response" | grep '"domainid"' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') - _debug _domain_id "$_domain_id" + if _contains "$response" '"domainid":'; then + _domain_id=$(printf "%s" "$response" | grep '"domainid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') 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 @@ -128,27 +132,16 @@ _get_root() { return 1 } -#Usage: method URI data -_rest() { - m="$1" - ep="$2" - data="$3" - _debug "$ep" - url="$DNSLA_API$ep" +#Usage: URI +_la_rest() { + url="$LA_Api/$1" + _debug "$url" - _debug url "$url" - - if [ "$m" = "GET" ]; then - response="$(_get "$url" | tr -d ' ' | tr "}" ",")" - else - _debug2 data "$data" - response="$(_post "$data" "$url" | tr -d ' ' | tr "}" ",")" - fi - - if [ "$?" != "0" ]; then - _err "error $ep" + if ! response="$(_get "$url" | tr -d ' ' | tr "}" ",")"; then + _err "Error: $url" return 1 fi + _debug2 response "$response" return 0 } From 71690604259b365d3028c4f31e6d9ee82f4d3034 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 20 Aug 2022 10:54:04 +0800 Subject: [PATCH 1961/2234] fix https://github.com/acmesh-official/acme.sh/issues/4248#issuecomment-1217378906 --- acme.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 8a851fd4..428c016f 100755 --- a/acme.sh +++ b/acme.sh @@ -5200,11 +5200,25 @@ $_authorizations_map" _info "The domain is set to be valid to: $_valid_to" _info "It can not be renewed automatically" _info "See: $_VALIDITY_WIKI" + else + _now=$(_time) + _debug2 "_now" "$_now" + _lifetime=$(_math $Le_NextRenewTime - $_now) + _debug2 "_lifetime" "$_lifetime" + if [ $_lifetime -gt 86400 ]; then + #if lifetime is logner than one day, it will renew one day before + Le_NextRenewTime=$(_math $Le_NextRenewTime - 86400) + Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime") + else + #if lifetime is less than 24 hours, it will renew one hour before + Le_NextRenewTime=$(_math $Le_NextRenewTime - 3600) + Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime") + fi fi else Le_NextRenewTime=$(_math "$Le_CertCreateTime" + "$Le_RenewalDays" \* 24 \* 60 \* 60) - Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime") Le_NextRenewTime=$(_math "$Le_NextRenewTime" - 86400) + Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime") fi _savedomainconf "Le_NextRenewTimeStr" "$Le_NextRenewTimeStr" _savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime" From 8155ba522486cdcafb2e98ec294cfbad6431f1ae Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 20 Aug 2022 10:59:50 +0800 Subject: [PATCH 1962/2234] fix issue.yml --- .github/workflows/issue.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 20d3d5fd..ab1b43e9 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -14,11 +14,6 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: ' - Please upgrade to the latest code and try again first. Maybe it's already fixed. - - `acme.sh --upgrade` - - If it's still not working, please provide the log with `--debug 2`, otherwise, nobody can help you.' + body: 'Please upgrade to the latest code and try again first. Maybe it's already fixed. ```acme.sh --upgrade``` If it's still not working, please provide the log with `--debug 2`, otherwise, nobody can help you.' }) \ No newline at end of file From 3dcacc1f8d01059ba310d22c129a91cfdd179479 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 20 Aug 2022 12:32:41 +0800 Subject: [PATCH 1963/2234] add pr_notify.yml --- .github/workflows/pr_notify.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/pr_notify.yml diff --git a/.github/workflows/pr_notify.yml b/.github/workflows/pr_notify.yml new file mode 100644 index 00000000..4844e297 --- /dev/null +++ b/.github/workflows/pr_notify.yml @@ -0,0 +1,30 @@ +name: Check dns api + +on: + pull_request_target: + types: + - opened + branches: + - 'dev' + paths: + - 'notify/*.sh' + + +jobs: + welcome: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `**Welcome** + Please make sure you're read our [Code-of-conduct](../wiki/Code-of-conduct) and add the usage here: [notify](../wiki/notify). + Then reply on this message, otherwise, your code will not be reviewed or merged. + We look forward to reviewing your Pull request shortly ✨ + ` + }) + From dcf9c467c386e49c606aa98069f63efd8bc32309 Mon Sep 17 00:00:00 2001 From: Monius Date: Sat, 20 Aug 2022 19:37:51 +0800 Subject: [PATCH 1964/2234] fix issue, when profile not end with newline --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index e8228e30..aecef894 100755 --- a/acme.sh +++ b/acme.sh @@ -6371,7 +6371,7 @@ _installalias() { if [ "$_profile" ]; then _debug "Found profile: $_profile" _info "Installing alias to '$_profile'" - _setopt "$_profile" ". \"$_envfile\"" + _setopt "$_profile" "\n. \"$_envfile\"" _info "OK, Close and reopen your terminal to start using $PROJECT_NAME" else _info "No profile is found, you will need to go into $LE_WORKING_DIR to use $PROJECT_NAME" From f2634b44cdd4bc38cfd9838ca6cb2e975bd4c25a Mon Sep 17 00:00:00 2001 From: Monius Date: Sun, 21 Aug 2022 12:26:37 +0800 Subject: [PATCH 1965/2234] add EOF, if $__conf not end with one --- acme.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index aecef894..ec4f90b7 100755 --- a/acme.sh +++ b/acme.sh @@ -2239,7 +2239,11 @@ _setopt() { if [ ! -f "$__conf" ]; then touch "$__conf" fi - + if [ -n "$(tail -c 1 <"$__conf")" ]; then + _debug3 No New Line + echo >>"$__conf" + fi + if grep -n "^$__opt$__sep" "$__conf" >/dev/null; then _debug3 OK if _contains "$__val" "&"; then @@ -6371,7 +6375,7 @@ _installalias() { if [ "$_profile" ]; then _debug "Found profile: $_profile" _info "Installing alias to '$_profile'" - _setopt "$_profile" "\n. \"$_envfile\"" + _setopt "$_profile" ". \"$_envfile\"" _info "OK, Close and reopen your terminal to start using $PROJECT_NAME" else _info "No profile is found, you will need to go into $LE_WORKING_DIR to use $PROJECT_NAME" From 6502a71083de93cef288992b00f8d38f4d35c9a4 Mon Sep 17 00:00:00 2001 From: Monius Date: Mon, 22 Aug 2022 05:26:12 +0800 Subject: [PATCH 1966/2234] fix, but remove debug info --- acme.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/acme.sh b/acme.sh index ec4f90b7..882aaf03 100755 --- a/acme.sh +++ b/acme.sh @@ -2240,7 +2240,6 @@ _setopt() { touch "$__conf" fi if [ -n "$(tail -c 1 <"$__conf")" ]; then - _debug3 No New Line echo >>"$__conf" fi From 734c9a1aa5d697c9ae63a73326d2138ab4f60e65 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 21 Aug 2022 14:29:16 +0200 Subject: [PATCH 1967/2234] Dns Challenge prefix removed. SELFHOSTDNS_MAP entries must be fullpath incl. prefix --- dnsapi/dns_selfhost.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index b4284f51..628afe8d 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -4,8 +4,6 @@ # Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 # Last Edit: 17.02.2022 -DNS_CHALLENGE_PREFIX_ESCAPED="_acme-challenge\." - dns_selfhost_add() { fulldomain=$1 txt=$2 @@ -33,16 +31,12 @@ dns_selfhost_add() { SELFHOSTDNS_LAST_SLOT=1 fi - # cut DNS_CHALLENGE_PREFIX_ESCAPED from fulldomain if present at the beginning of the string - lookupdomain=$(echo "$fulldomain" | sed "s/^$DNS_CHALLENGE_PREFIX_ESCAPED//") - _debug lookupdomain "$lookupdomain" - - # get the RID for lookupdomain or fulldomain from SELFHOSTDNS_MAP + # get the RID for fulldomain from SELFHOSTDNS_MAP # only match full domains (at the beginning of the string or with a leading whitespace), # e.g. don't match mytest.example.com or sub.test.example.com for test.example.com # replace the whole string with the RID (matching group 3) for assignment # if the domain is defined multiple times only the last occurance will be matched - rid=$(echo "$SELFHOSTDNS_MAP" | sed -E "s/(^|^.*[[:space:]])($lookupdomain:|$fulldomain:)([0-9][0-9]*)(.*)/\3/") + rid=$(echo "$SELFHOSTDNS_MAP" | sed -E "s/(^|^.*[[:space:]])($fulldomain:)([0-9][0-9]*)(.*)/\3/") if test -z "$rid"; then if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then From b9256a1ba727022ad02a0ef771df43303ee7ed85 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 21 Aug 2022 23:23:47 +0200 Subject: [PATCH 1968/2234] changed from *deployconf to *domainconf --- dnsapi/dns_selfhost.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 628afe8d..4171cb3c 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -17,10 +17,10 @@ dns_selfhost_add() { SELFHOSTDNS_USERNAME="${SELFHOSTDNS_USERNAME:-$(_readaccountconf_mutable SELFHOSTDNS_USERNAME)}" SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" # These values are domain dependent, so read them from there - _getdeployconf SELFHOSTDNS_MAP - _getdeployconf SELFHOSTDNS_RID - _getdeployconf SELFHOSTDNS_RID2 - _getdeployconf SELFHOSTDNS_LAST_SLOT + SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readdomainconf SELFHOSTDNS_MAP)}" + SELFHOSTDNS_RID="${SELFHOSTDNS_RID:-$(_readdomainconf SELFHOSTDNS_RID)}" + SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readdomainconf SELFHOSTDNS_RID2)}" + SELFHOSTDNS_LAST_SLOT="${SELFHOSTDNS_LAST_SLOT:-$(_readdomainconf SELFHOSTDNS_LAST_SLOT)}" if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then _err "SELFHOSTDNS_USERNAME and SELFHOSTDNS_PASSWORD must be set" @@ -67,10 +67,10 @@ dns_selfhost_add() { _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" # These values are domain dependent, so store them there - _savedeployconf SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" - _savedeployconf SELFHOSTDNS_RID "$SELFHOSTDNS_RID" - _savedeployconf SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - _savedeployconf SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" + _savedomainconf SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" + _savedomainconf SELFHOSTDNS_RID "$SELFHOSTDNS_RID" + _savedomainconf SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" + _savedomainconf SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" } dns_selfhost_rm() { From 35ec3adadc82836918d9854fe671300c382e209c Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 22 Aug 2022 00:53:32 +0200 Subject: [PATCH 1969/2234] only use SELFHOSTDNS_MAP for configuration of RIDs. detect wildcard domain for use of additional RID --- dnsapi/dns_selfhost.sh | 45 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 4171cb3c..c63f81d7 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -10,6 +10,7 @@ dns_selfhost_add() { _info "Calling acme-dns on selfhost" _debug fulldomain "$fulldomain" _debug txtvalue "$txt" + _debug domain "$d" SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl" @@ -18,39 +19,36 @@ dns_selfhost_add() { SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" # These values are domain dependent, so read them from there SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readdomainconf SELFHOSTDNS_MAP)}" - SELFHOSTDNS_RID="${SELFHOSTDNS_RID:-$(_readdomainconf SELFHOSTDNS_RID)}" - SELFHOSTDNS_RID2="${SELFHOSTDNS_RID2:-$(_readdomainconf SELFHOSTDNS_RID2)}" - SELFHOSTDNS_LAST_SLOT="${SELFHOSTDNS_LAST_SLOT:-$(_readdomainconf SELFHOSTDNS_LAST_SLOT)}" if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then _err "SELFHOSTDNS_USERNAME and SELFHOSTDNS_PASSWORD must be set" return 1 fi - if test -z "$SELFHOSTDNS_LAST_SLOT"; then - SELFHOSTDNS_LAST_SLOT=1 - fi - - # get the RID for fulldomain from SELFHOSTDNS_MAP + # get the domain entry from SELFHOSTDNS_MAP # only match full domains (at the beginning of the string or with a leading whitespace), # e.g. don't match mytest.example.com or sub.test.example.com for test.example.com - # replace the whole string with the RID (matching group 3) for assignment # if the domain is defined multiple times only the last occurance will be matched - rid=$(echo "$SELFHOSTDNS_MAP" | sed -E "s/(^|^.*[[:space:]])($fulldomain:)([0-9][0-9]*)(.*)/\3/") - - if test -z "$rid"; then - if [ $SELFHOSTDNS_LAST_SLOT = "2" ]; then - rid=$SELFHOSTDNS_RID - SELFHOSTDNS_LAST_SLOT=1 - else - rid=$SELFHOSTDNS_RID2 - SELFHOSTDNS_LAST_SLOT=2 - fi + mapEntry=$(echo "$SELFHOSTDNS_MAP" | sed -n -E "s/(^|^.*[[:space:]])($fulldomain)(:[[:digit:]]+)([:]?[[:digit:]]*)(.*)/\2\3\4/p") + _debug mapEntry $mapEntry + if test -z "$mapEntry"; then + _err "SELFHOSTDNS_MAP must contain the fulldomain incl. prefix and at least one RID" + return 1 fi - if test -z "$rid"; then - _err "SELFHOSTDNS_RID and SELFHOSTDNS_RID2, or SELFHOSTDNS_MAP must be set" - return 1 + # get the RIDs from the map entry + rid1=$(echo "$mapEntry" | cut -d: -f2) + _debug rid1 $rid1 + rid2=$(echo "$mapEntry" | cut -d: -f3) + _debug rid2 $rid2 + + rid=$rid1 + # check for wildcard domain and use rid2 if set + if _startswith "$d" '*.'; then + _debug2 "wildcard domain" + if ! test -z "$rid2"; then + rid=$rid2 + fi fi _info "Trying to add $txt on selfhost for rid: $rid" @@ -68,9 +66,6 @@ dns_selfhost_add() { _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" # These values are domain dependent, so store them there _savedomainconf SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" - _savedomainconf SELFHOSTDNS_RID "$SELFHOSTDNS_RID" - _savedomainconf SELFHOSTDNS_RID2 "$SELFHOSTDNS_RID2" - _savedomainconf SELFHOSTDNS_LAST_SLOT "$SELFHOSTDNS_LAST_SLOT" } dns_selfhost_rm() { From 281951a86bed68de20ae1cec96bfbe24ef64e181 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 22 Aug 2022 06:51:17 +0200 Subject: [PATCH 1970/2234] ShellCheck fixed --- dnsapi/dns_selfhost.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index c63f81d7..f8c8d314 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -30,7 +30,7 @@ dns_selfhost_add() { # e.g. don't match mytest.example.com or sub.test.example.com for test.example.com # if the domain is defined multiple times only the last occurance will be matched mapEntry=$(echo "$SELFHOSTDNS_MAP" | sed -n -E "s/(^|^.*[[:space:]])($fulldomain)(:[[:digit:]]+)([:]?[[:digit:]]*)(.*)/\2\3\4/p") - _debug mapEntry $mapEntry + _debug mapEntry "$mapEntry" if test -z "$mapEntry"; then _err "SELFHOSTDNS_MAP must contain the fulldomain incl. prefix and at least one RID" return 1 @@ -38,16 +38,16 @@ dns_selfhost_add() { # get the RIDs from the map entry rid1=$(echo "$mapEntry" | cut -d: -f2) - _debug rid1 $rid1 + _debug rid1 "$rid1" rid2=$(echo "$mapEntry" | cut -d: -f3) - _debug rid2 $rid2 + _debug rid2 "$rid2" rid=$rid1 # check for wildcard domain and use rid2 if set if _startswith "$d" '*.'; then _debug2 "wildcard domain" if ! test -z "$rid2"; then - rid=$rid2 + rid="$rid2" fi fi From 5a604bfdeec85bf0e578d73f57e7c6bb4ae91409 Mon Sep 17 00:00:00 2001 From: Monius Date: Mon, 22 Aug 2022 15:16:30 +0800 Subject: [PATCH 1971/2234] shfmt check? --- acme.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 882aaf03..11814b6e 100755 --- a/acme.sh +++ b/acme.sh @@ -2239,10 +2239,11 @@ _setopt() { if [ ! -f "$__conf" ]; then touch "$__conf" fi + if [ -n "$(tail -c 1 <"$__conf")" ]; then echo >>"$__conf" fi - + if grep -n "^$__opt$__sep" "$__conf" >/dev/null; then _debug3 OK if _contains "$__val" "&"; then From fc336e3733ba62250cf7c7c649b5dbf827e84322 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Tue, 23 Aug 2022 00:04:41 +0200 Subject: [PATCH 1972/2234] fixed RID usage for wildcard domains --- dnsapi/dns_selfhost.sh | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index f8c8d314..d2d3cf60 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -10,7 +10,6 @@ dns_selfhost_add() { _info "Calling acme-dns on selfhost" _debug fulldomain "$fulldomain" _debug txtvalue "$txt" - _debug domain "$d" SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl" @@ -19,6 +18,10 @@ dns_selfhost_add() { SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" # These values are domain dependent, so read them from there SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readdomainconf SELFHOSTDNS_MAP)}" + # Selfhost api can't dynamically add TXT record, + # so we have to store the last used RID of the domain to support a second RID for wildcard domains + # (format: ';fulldomainA:lastRid;;fulldomainB:lastRid;...') + SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(_readdomainconf SELFHOSTDNS_MAP_LAST_USED_INTERNAL) if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then _err "SELFHOSTDNS_USERNAME and SELFHOSTDNS_PASSWORD must be set" @@ -30,7 +33,7 @@ dns_selfhost_add() { # e.g. don't match mytest.example.com or sub.test.example.com for test.example.com # if the domain is defined multiple times only the last occurance will be matched mapEntry=$(echo "$SELFHOSTDNS_MAP" | sed -n -E "s/(^|^.*[[:space:]])($fulldomain)(:[[:digit:]]+)([:]?[[:digit:]]*)(.*)/\2\3\4/p") - _debug mapEntry "$mapEntry" + _debug2 mapEntry "$mapEntry" if test -z "$mapEntry"; then _err "SELFHOSTDNS_MAP must contain the fulldomain incl. prefix and at least one RID" return 1 @@ -38,19 +41,27 @@ dns_selfhost_add() { # get the RIDs from the map entry rid1=$(echo "$mapEntry" | cut -d: -f2) - _debug rid1 "$rid1" rid2=$(echo "$mapEntry" | cut -d: -f3) - _debug rid2 "$rid2" - rid=$rid1 - # check for wildcard domain and use rid2 if set - if _startswith "$d" '*.'; then - _debug2 "wildcard domain" - if ! test -z "$rid2"; then - rid="$rid2" - fi + # read last used rid domain + lastUsedRidForDomainEntry=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/.*(;$fulldomain:[[:digit:]]+;).*/\1/p") + _debug2 lastUsedRidForDomainEntry "$lastUsedRidForDomainEntry" + lastUsedRidForDomain=$(echo "$lastUsedRidForDomainEntry" | tr -d ";" | cut -d: -f2) + + rid="$rid1" + if [ "$lastUsedRidForDomain" = "$rid" ] && ! test -z "$rid2"; then + rid="$rid2" fi + if ! test -z "$lastUsedRidForDomainEntry"; then + # replace last used rid entry for domain + SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/$lastUsedRidForDomainEntry/;$fulldomain:$rid;/p") + else + # add last used rid entry for domain + SELFHOSTDNS_MAP_LAST_USED_INTERNAL="$SELFHOSTDNS_MAP_LAST_USED_INTERNAL"";$fulldomain:$rid;" + fi + + _info "Trying to add $txt on selfhost for rid: $rid" data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt" @@ -66,6 +77,7 @@ dns_selfhost_add() { _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" # These values are domain dependent, so store them there _savedomainconf SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP" + _savedomainconf SELFHOSTDNS_MAP_LAST_USED_INTERNAL "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" } dns_selfhost_rm() { From c94f9f21afcbc5f3e7f05545c95c6c278236df83 Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Tue, 23 Aug 2022 00:28:52 +0200 Subject: [PATCH 1973/2234] fixed shfmt --- dnsapi/dns_selfhost.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index d2d3cf60..ea301788 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -18,7 +18,7 @@ dns_selfhost_add() { SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}" # These values are domain dependent, so read them from there SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readdomainconf SELFHOSTDNS_MAP)}" - # Selfhost api can't dynamically add TXT record, + # Selfhost api can't dynamically add TXT record, # so we have to store the last used RID of the domain to support a second RID for wildcard domains # (format: ';fulldomainA:lastRid;;fulldomainB:lastRid;...') SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(_readdomainconf SELFHOSTDNS_MAP_LAST_USED_INTERNAL) @@ -56,12 +56,11 @@ dns_selfhost_add() { if ! test -z "$lastUsedRidForDomainEntry"; then # replace last used rid entry for domain SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/$lastUsedRidForDomainEntry/;$fulldomain:$rid;/p") - else + else # add last used rid entry for domain SELFHOSTDNS_MAP_LAST_USED_INTERNAL="$SELFHOSTDNS_MAP_LAST_USED_INTERNAL"";$fulldomain:$rid;" fi - _info "Trying to add $txt on selfhost for rid: $rid" data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt" From b95f836256ca2c7b57d74c1a4a9b524fc92255bc Mon Sep 17 00:00:00 2001 From: Monius Date: Tue, 23 Aug 2022 06:30:09 +0800 Subject: [PATCH 1974/2234] final try --- acme.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/acme.sh b/acme.sh index 11814b6e..bb6863c7 100755 --- a/acme.sh +++ b/acme.sh @@ -2239,7 +2239,6 @@ _setopt() { if [ ! -f "$__conf" ]; then touch "$__conf" fi - if [ -n "$(tail -c 1 <"$__conf")" ]; then echo >>"$__conf" fi From 2304f005e3ec70a56153adf8efba489b9d361c79 Mon Sep 17 00:00:00 2001 From: Hobby-Student <6012744+Hobby-Student@users.noreply.github.com> Date: Tue, 23 Aug 2022 12:41:42 +0200 Subject: [PATCH 1975/2234] better error handling --- dnsapi/dns_kas.sh | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 6bb0823e..43990824 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -8,12 +8,12 @@ # - $KAS_Authtype (Kasserver API auth type. Default: plain) # - $KAS_Authdata (Kasserver API auth data.) # -# Author: squared GmbH +# Last update: squared GmbH # Credits: -# Inspired by dns_he.sh. Thanks a lot man! -# Previous version by Martin Kammerlander, Phlegx Systems OG -# Previous update by Marc-Oliver Lange -# KASAPI SOAP guideline by https://github.com/o1oo11oo/kasapi.sh +# - dns_he.sh. Thanks a lot man! +# - Martin Kammerlander, Phlegx Systems OG +# - Marc-Oliver Lange +# - https://github.com/o1oo11oo/kasapi.sh ######################################################################## KAS_Api_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasApi.wsdl")" KAS_Api="$(echo "$KAS_Api_GET" | tr -d ' ' | grep -i "//g")" @@ -31,13 +31,13 @@ dns_kas_add() { _txtvalue=$2 _info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook" + _info "[KAS] -> Check and Save Props" + _check_and_save + _info "[KAS] -> Adding $_fulldomain DNS TXT entry on all-inkl.com/Kasserver" _info "[KAS] -> Retriving Credential Token" _get_credential_token - _info "[KAS] -> Check and Save Props" - _check_and_save - _info "[KAS] -> Checking Zone and Record_Name" _get_zone_and_record_name "$_fulldomain" @@ -90,14 +90,14 @@ dns_kas_rm() { _txtvalue=$2 _info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook" + _info "[KAS] -> Check and Save Props" + _check_and_save + _info "[KAS] -> Cleaning up after All-inkl/Kasserver hook" _info "[KAS] -> Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver" _info "[KAS] -> Retriving Credential Token" _get_credential_token - _info "[KAS] -> Check and Save Props" - _check_and_save - _info "[KAS] -> Checking Zone and Record_Name" _get_zone_and_record_name "$_fulldomain" @@ -239,6 +239,15 @@ _get_credential_token() { response="$(_post "$data" "$KAS_Auth" "" "POST" "$contentType")" _debug2 "[KAS] -> Response" "$response" + if [ -z "$response" ]; then + _info "[KAS] -> Response was empty, please check manually." + return 1 + elif _contains "$response" ""; then + faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")" + _err "[KAS] -> Could not retrieve login token or antoher error =>$faultstring<= occurred, please check manually." + return 1 + fi + _credential_token="$(echo "$response" | tr '\n' ' ' | sed 's/.*return xsi:type="xsd:string">\(.*\)<\/return>/\1/' | sed 's/<\/ns1:KasAuthResponse\(.*\)Envelope>.*//')" _debug "[KAS] -> Credential Token: " "$_credential_token" return 0 From f9c2874c3544b23e99b417fd90cb19e179b83180 Mon Sep 17 00:00:00 2001 From: Hobby-Student <6012744+Hobby-Student@users.noreply.github.com> Date: Tue, 23 Aug 2022 13:30:04 +0200 Subject: [PATCH 1976/2234] removed unnecessary white space in empty line --- dnsapi/dns_kas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 43990824..053abd21 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -33,7 +33,7 @@ dns_kas_add() { _info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook" _info "[KAS] -> Check and Save Props" _check_and_save - + _info "[KAS] -> Adding $_fulldomain DNS TXT entry on all-inkl.com/Kasserver" _info "[KAS] -> Retriving Credential Token" _get_credential_token From b888792940367d8860b7d780c7c31a2d72028052 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 23 Aug 2022 22:15:50 +0800 Subject: [PATCH 1977/2234] fix concurrency --- .github/workflows/DNS.yml | 2 +- .github/workflows/DragonFlyBSD.yml | 2 +- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/Linux.yml | 2 +- .github/workflows/MacOS.yml | 2 +- .github/workflows/NetBSD.yml | 2 +- .github/workflows/OpenBSD.yml | 2 +- .github/workflows/PebbleStrict.yml | 2 +- .github/workflows/Solaris.yml | 2 +- .github/workflows/Ubuntu.yml | 2 +- .github/workflows/Windows.yml | 2 +- .github/workflows/dockerhub.yml | 2 +- .github/workflows/shellcheck.yml | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 8f487ff4..057972f6 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -12,7 +12,7 @@ on: - '.github/workflows/DNS.yml' concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index ae953473..8581db47 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -15,7 +15,7 @@ on: - '.github/workflows/DragonFlyBSD.yml' concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 151f462c..795ddc75 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -15,7 +15,7 @@ on: - '.github/workflows/FreeBSD.yml' concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index e532e1cb..238b3016 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -16,7 +16,7 @@ on: concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index 34966144..69fb09f7 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -15,7 +15,7 @@ on: - '.github/workflows/MacOS.yml' concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 53bb94d7..10952778 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -15,7 +15,7 @@ on: - '.github/workflows/NetBSD.yml' concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 698f86a3..9c21daa1 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -15,7 +15,7 @@ on: - '.github/workflows/OpenBSD.yml' concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index afd3a68f..7417b8b0 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -15,7 +15,7 @@ on: concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 12333ceb..3a86d3dc 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -17,7 +17,7 @@ on: concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 478adca9..664ba92c 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -15,7 +15,7 @@ on: - '.github/workflows/Ubuntu.yml' concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index b5a0a6ba..3b7bf2eb 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -16,7 +16,7 @@ on: concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index bbda7550..4d9f34b3 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -12,7 +12,7 @@ on: - '.github/workflows/dockerhub.yml' concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 3c24d2b4..d628ea93 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -14,7 +14,7 @@ on: - '.github/workflows/shellcheck.yml' concurrency: - group: ${{ github.workflow }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true From 238ecfc53956e71a00603c7c1204ba75aecce425 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 23 Aug 2022 22:19:10 +0800 Subject: [PATCH 1978/2234] fix issue message --- .github/workflows/issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index ab1b43e9..e92b0411 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -14,6 +14,6 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: 'Please upgrade to the latest code and try again first. Maybe it's already fixed. ```acme.sh --upgrade``` If it's still not working, please provide the log with `--debug 2`, otherwise, nobody can help you.' + body: "Please upgrade to the latest code and try again first. Maybe it's already fixed. ```acme.sh --upgrade``` If it's still not working, please provide the log with `--debug 2`, otherwise, nobody can help you." }) \ No newline at end of file From ec53b27dfe7bcc030c4e4e6613a7bb902eac018f Mon Sep 17 00:00:00 2001 From: Viktor Sokhan Date: Wed, 24 Aug 2022 13:48:10 +0700 Subject: [PATCH 1979/2234] Add dns_yc.sh --- dnsapi/dns_yc.sh | 259 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 dnsapi/dns_yc.sh diff --git a/dnsapi/dns_yc.sh b/dnsapi/dns_yc.sh new file mode 100644 index 00000000..74a605b5 --- /dev/null +++ b/dnsapi/dns_yc.sh @@ -0,0 +1,259 @@ +#!/usr/bin/env sh + +#YC_Zone_ID="" # DNS Zone ID +#YC_Folder_ID="" # YC Folder ID +#YC_SA_ID="" # Service Account ID +#YC_SA_Key_ID="" # Service Account IAM Key ID +#YC_SA_Key_File_Path="/path/to/private.key" # Path to private.key use instead of PEM +#YC_SA_Key_File_PEM="" # Content of private.key use instead of Path +YC_Api="https://dns.api.cloud.yandex.net/dns/v1" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_yc_add() { + fulldomain="$(echo "$1". | _lower_case)" # Add dot at end of domain name + txtvalue=$2 + + if ["$YC_SA_Key_File_PEM"]; then + YC_SA_Key_File="<(echo '$YC_SA_Key_File_PEM')" + else + YC_SA_Key_File=$YC_SA_Key_File_Path + fi + + YC_Zone_ID="${YC_Zone_ID:-$(_readaccountconf_mutable YC_Zone_ID)}" + YC_Folder_ID="${YC_Folder_ID:-$(_readaccountconf_mutable YC_Folder_ID)}" + YC_SA_ID="${YC_SA_ID:-$(_readaccountconf_mutable YC_SA_ID)}" + YC_SA_Key_ID="${YC_SA_Key_ID:-$(_readaccountconf_mutable YC_SA_Key_ID)}" + YC_SA_Key_File="${YC_SA_Key_File:-$(_readaccountconf_mutable YC_SA_Key_File)}" + + if [ "$YC_SA_ID" ] && [ "$YC_SA_Key_ID" ] && [ "$YC_SA_Key_File" ]; then + if [ -f "$YC_SA_Key_File" ]; then + if _isRSA "$YC_SA_Key_File" >/dev/null 2>&1; then + if [ "$YC_Zone_ID" ]; then + _savedomainconf YC_Zone_ID "$YC_Zone_ID" + _savedomainconf YC_SA_ID "$YC_SA_ID" + _savedomainconf YC_SA_Key_ID "$YC_SA_Key_ID" + _savedomainconf YC_SA_Key_File "$YC_SA_Key_File" + elif [ "$YC_Folder_ID" ]; then + _savedomainconf YC_Folder_ID "$YC_Folder_ID" + _saveaccountconf_mutable YC_SA_ID "$YC_SA_ID" + _saveaccountconf_mutable YC_SA_Key_ID "$YC_SA_Key_ID" + _saveaccountconf_mutable YC_SA_Key_File "$YC_SA_Key_File" + _clearaccountconf_mutable YC_Zone_ID + _clearaccountconf YC_Zone_ID + else + _err "You didn't specify a Yandex Cloud Zone ID or Folder ID yet." + return 1 + fi + else + _err "YC_SA_Key_File not a RSA file(_isRSA function return false)." + return 1 + fi + else + _err "YC_SA_Key_File not found in path $YC_SA_Key_File." + return 1 + fi + else + _clearaccountconf YC_Zone_ID + _clearaccountconf YC_Folder_ID + _clearaccountconf YC_SA_ID + _clearaccountconf YC_SA_Key_ID + _clearaccountconf YC_SA_Key_File + _err "You didn't specify a YC_SA_ID or YC_SA_Key_ID or YC_SA_Key_File." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + if ! _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$_sub_domain"; then + _err "Error: $response" + return 1 + fi + + _info "Adding record" + if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"merges\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then + if _contains "$response" "\"done\": true"; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_yc_rm() { + fulldomain="$(echo "$1". | _lower_case)" # Add dot at end of domain name + txtvalue=$2 + + YC_Zone_ID="${YC_Zone_ID:-$(_readaccountconf_mutable YC_Zone_ID)}" + YC_Folder_ID="${YC_Folder_ID:-$(_readaccountconf_mutable YC_Folder_ID)}" + YC_SA_ID="${YC_SA_ID:-$(_readaccountconf_mutable YC_SA_ID)}" + YC_SA_Key_ID="${YC_SA_Key_ID:-$(_readaccountconf_mutable YC_SA_Key_ID)}" + YC_SA_Key_File="${YC_SA_Key_File:-$(_readaccountconf_mutable YC_SA_Key_File)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + if _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$_sub_domain"; then + exists_txtvalue=$(echo "$response" | _normalizeJson | _egrep_o "\"data\".*\][^,]*" | _egrep_o "[^:]*$") + _debug exists_txtvalue "$exists_txtvalue" + else + _err "Error: $response" + return 1 + fi + + if _yc_rest POST "zones/$_domain_id:updateRecordSets" "{\"deletions\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":$exists_txtvalue}]}"; then + if _contains "$response" "\"done\": true"; then + _info "Delete, OK" + return 0 + else + _err "Delete record error." + return 1 + fi + fi + _err "Delete record error." + return 1 +} + +#################### 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=1 + p=1 + + # Use Zone ID directly if provided + if [ "$YC_Zone_ID" ]; then + if ! _yc_rest GET "zones/$YC_Zone_ID"; then + return 1 + else + if echo "$response" | tr -d " " | grep \"id\":\"$YC_Zone_ID\" >/dev/null; then + _domain=$(echo "$response" | _egrep_o "\"zone\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") + if [ "$_domain" ]; then + _cutlength=$((${#domain} - ${#_domain})) + _sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cutlength") + _domain_id=$YC_Zone_ID + return 0 + else + return 1 + fi + else + return 1 + fi + fi + 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 [ "$YC_Folder_ID" ]; then + if ! _yc_rest GET "zones?folderId=$YC_Folder_ID"; then + return 1 + fi + else + echo "You didn't specify a Yandex Cloud Folder ID." + return 1 + fi + if _contains "$response" "\"zone\": \"$h\""; then + _domain_id=$(echo "$response" | _normalizeJson | _egrep_o "[^{]*\"zone\":\"$h\"[^}]*" | _egrep_o "\"id\"[^,]*" | _egrep_o "[^:]*$" | tr -d '"') + _debug _domain_id "$_domain_id" + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_yc_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + if [ ! "$YC_Token" ]; then + _debug "Login" + _yc_login + else + _debug "Token already exists. Skip Login." + fi + + token_trimmed=$(echo "$YC_Token" | tr -d '"') + + export _H1="Content-Type: application/json" + export _H2="Authorization: Bearer $token_trimmed" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$YC_Api/$ep" "" "$m")" + else + response="$(_get "$YC_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} + +_yc_login() { + header=$(echo "{\"typ\":\"JWT\",\"alg\":\"PS256\",\"kid\":\"$YC_SA_Key_ID\"}" | _normalizeJson | _base64 | _url_replace) + _debug header "$header" + + _current_timestamp=$(_time) + _expire_timestamp=$(_math $_current_timestamp + 1200) # 20 minutes + payload=$(echo "{\"iss\":\"$YC_SA_ID\",\"aud\":\"https://iam.api.cloud.yandex.net/iam/v1/tokens\",\"iat\":$_current_timestamp,\"exp\":$_expire_timestamp}" | _normalizeJson | _base64 | _url_replace) + _debug payload "$payload" + + #signature=$(printf "%s.%s" "$header" "$payload" | ${ACME_OPENSSL_BIN:-openssl} dgst -sign "$YC_SA_Key_File -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _base64 | _url_replace ) + _signature=$(printf "%s.%s" "$header" "$payload" | _sign "$YC_SA_Key_File" "sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _url_replace) + _debug2 _signature "$_signature" + + _jwt=$(printf "{\"jwt\": \"%s.%s.%s\"}" "$header" "$payload" "$_signature") + _debug2 _jwt "$_jwt" + + export _H1="Content-Type: application/json" + _iam_response="$(_post "$_jwt" "https://iam.api.cloud.yandex.net/iam/v1/tokens" "" "POST")" + _debug3 _iam_response "$(echo "$_iam_response" | _normalizeJson)" + + YC_Token="$(echo "$_iam_response" | _normalizeJson | _egrep_o "\"iamToken\"[^,]*" | _egrep_o "[^:]*$" | tr -d '"')" + _debug3 YC_Token + + return 0 +} From 43503a20e571b354877a9246bc13c3514275cf20 Mon Sep 17 00:00:00 2001 From: Viktor Sokhan Date: Wed, 24 Aug 2022 14:12:57 +0700 Subject: [PATCH 1980/2234] Fix --- dnsapi/dns_yc.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_yc.sh b/dnsapi/dns_yc.sh index 74a605b5..9f9c3e5e 100644 --- a/dnsapi/dns_yc.sh +++ b/dnsapi/dns_yc.sh @@ -5,7 +5,7 @@ #YC_SA_ID="" # Service Account ID #YC_SA_Key_ID="" # Service Account IAM Key ID #YC_SA_Key_File_Path="/path/to/private.key" # Path to private.key use instead of PEM -#YC_SA_Key_File_PEM="" # Content of private.key use instead of Path +#YC_SA_Key_File_PEM_b64="" # Base64 content of private.key use instead of Path YC_Api="https://dns.api.cloud.yandex.net/dns/v1" ######## Public functions ##################### @@ -15,8 +15,8 @@ dns_yc_add() { fulldomain="$(echo "$1". | _lower_case)" # Add dot at end of domain name txtvalue=$2 - if ["$YC_SA_Key_File_PEM"]; then - YC_SA_Key_File="<(echo '$YC_SA_Key_File_PEM')" + if ["$YC_SA_Key_File_PEM_b64"]; then + YC_SA_Key_File="<(echo '$YC_SA_Key_File_PEM_b64' | _dbase64 )" else YC_SA_Key_File=$YC_SA_Key_File_Path fi From 90623142e16f1423ac1be1cd8bb1cbdc95ce03b1 Mon Sep 17 00:00:00 2001 From: Viktor Sokhan Date: Wed, 24 Aug 2022 16:40:27 +0700 Subject: [PATCH 1981/2234] Fix --- dnsapi/dns_yc.sh | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_yc.sh b/dnsapi/dns_yc.sh index 9f9c3e5e..bce9aa63 100644 --- a/dnsapi/dns_yc.sh +++ b/dnsapi/dns_yc.sh @@ -4,8 +4,8 @@ #YC_Folder_ID="" # YC Folder ID #YC_SA_ID="" # Service Account ID #YC_SA_Key_ID="" # Service Account IAM Key ID -#YC_SA_Key_File_Path="/path/to/private.key" # Path to private.key use instead of PEM -#YC_SA_Key_File_PEM_b64="" # Base64 content of private.key use instead of Path +#YC_SA_Key_File_Path="/path/to/private.key" # Path to private.key use instead of YC_SA_Key_File_PEM_b64 +#YC_SA_Key_File_PEM_b64="" # Base64 content of private.key use instead of YC_SA_Key_File_Path YC_Api="https://dns.api.cloud.yandex.net/dns/v1" ######## Public functions ##################### @@ -15,18 +15,23 @@ dns_yc_add() { fulldomain="$(echo "$1". | _lower_case)" # Add dot at end of domain name txtvalue=$2 - if ["$YC_SA_Key_File_PEM_b64"]; then - YC_SA_Key_File="<(echo '$YC_SA_Key_File_PEM_b64' | _dbase64 )" + YC_SA_Key_File_PEM_b64="${YC_SA_Key_File_PEM_b64:-$(_readaccountconf_mutable YC_SA_Key_File_PEM_b64)}" + YC_SA_Key_File_Path="${YC_SA_Key_File_Path:-$(_readaccountconf_mutable YC_SA_Key_File_Path)}" + + if [ "$YC_SA_Key_File_PEM_b64" ]; then + echo "$YC_SA_Key_File_PEM_b64" | _dbase64 > private.key + YC_SA_Key_File="private.key" + _savedomainconf YC_SA_Key_File_PEM_b64 "$YC_SA_Key_File_PEM_b64" else - YC_SA_Key_File=$YC_SA_Key_File_Path + YC_SA_Key_File="$YC_SA_Key_File_Path" + _savedomainconf YC_SA_Key_File_Path "$YC_SA_Key_File_Path" fi YC_Zone_ID="${YC_Zone_ID:-$(_readaccountconf_mutable YC_Zone_ID)}" YC_Folder_ID="${YC_Folder_ID:-$(_readaccountconf_mutable YC_Folder_ID)}" YC_SA_ID="${YC_SA_ID:-$(_readaccountconf_mutable YC_SA_ID)}" YC_SA_Key_ID="${YC_SA_Key_ID:-$(_readaccountconf_mutable YC_SA_Key_ID)}" - YC_SA_Key_File="${YC_SA_Key_File:-$(_readaccountconf_mutable YC_SA_Key_File)}" - + if [ "$YC_SA_ID" ] && [ "$YC_SA_Key_ID" ] && [ "$YC_SA_Key_File" ]; then if [ -f "$YC_SA_Key_File" ]; then if _isRSA "$YC_SA_Key_File" >/dev/null 2>&1; then @@ -34,12 +39,10 @@ dns_yc_add() { _savedomainconf YC_Zone_ID "$YC_Zone_ID" _savedomainconf YC_SA_ID "$YC_SA_ID" _savedomainconf YC_SA_Key_ID "$YC_SA_Key_ID" - _savedomainconf YC_SA_Key_File "$YC_SA_Key_File" elif [ "$YC_Folder_ID" ]; then _savedomainconf YC_Folder_ID "$YC_Folder_ID" _saveaccountconf_mutable YC_SA_ID "$YC_SA_ID" _saveaccountconf_mutable YC_SA_Key_ID "$YC_SA_Key_ID" - _saveaccountconf_mutable YC_SA_Key_File "$YC_SA_Key_File" _clearaccountconf_mutable YC_Zone_ID _clearaccountconf YC_Zone_ID else @@ -59,7 +62,8 @@ dns_yc_add() { _clearaccountconf YC_Folder_ID _clearaccountconf YC_SA_ID _clearaccountconf YC_SA_Key_ID - _clearaccountconf YC_SA_Key_File + _clearaccountconf YC_SA_Key_File_PEM_b64 + _clearaccountconf YC_SA_Key_File_Path _err "You didn't specify a YC_SA_ID or YC_SA_Key_ID or YC_SA_Key_File." return 1 fi @@ -103,7 +107,6 @@ dns_yc_rm() { YC_Folder_ID="${YC_Folder_ID:-$(_readaccountconf_mutable YC_Folder_ID)}" YC_SA_ID="${YC_SA_ID:-$(_readaccountconf_mutable YC_SA_ID)}" YC_SA_Key_ID="${YC_SA_Key_ID:-$(_readaccountconf_mutable YC_SA_Key_ID)}" - YC_SA_Key_File="${YC_SA_Key_File:-$(_readaccountconf_mutable YC_SA_Key_File)}" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -244,6 +247,8 @@ _yc_login() { #signature=$(printf "%s.%s" "$header" "$payload" | ${ACME_OPENSSL_BIN:-openssl} dgst -sign "$YC_SA_Key_File -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _base64 | _url_replace ) _signature=$(printf "%s.%s" "$header" "$payload" | _sign "$YC_SA_Key_File" "sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _url_replace) _debug2 _signature "$_signature" + + rm -rf "$YC_SA_Key_File" _jwt=$(printf "{\"jwt\": \"%s.%s.%s\"}" "$header" "$payload" "$_signature") _debug2 _jwt "$_jwt" From 53117b2f4cead0b78b58242c21b44ff44bd062b9 Mon Sep 17 00:00:00 2001 From: Klaus Frank Date: Wed, 17 Aug 2022 16:48:02 +0200 Subject: [PATCH 1982/2234] Fix missing HTTP_HEADER for _get with wget Save http header to file for _get with wget. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 428c016f..31a2cb03 100755 --- a/acme.sh +++ b/acme.sh @@ -2054,7 +2054,7 @@ _get() { if [ "$onlyheader" ]; then $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1 | sed 's/^[ ]*//g' else - $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -O - "$url" + $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O - "$url" 2>"$HTTP_HEADER" fi ret=$? if [ "$ret" = "8" ]; then From 713b7338ea1a77c1ca33c46b6212b13914cf48dd Mon Sep 17 00:00:00 2001 From: Klaus Frank Date: Wed, 17 Aug 2022 20:01:02 +0200 Subject: [PATCH 1983/2234] demultiplex wget debug output --- acme.sh | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 31a2cb03..0130f004 100755 --- a/acme.sh +++ b/acme.sh @@ -1999,7 +1999,13 @@ _post() { if [ "$_ret" != "0" ]; then _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" fi - _sed_i "s/^ *//g" "$HTTP_HEADER" + if echo $_WGET | grep -q " -d " 2> /dev/null; then + # Demultiplex wget debug output + cat "$HTTP_HEADER" >&2 + _sed_i '/^[^[:space:]][^[:space:]]/d; /^[[:space:]]*$/d' "$HTTP_HEADER" + fi + # remove leading whitespaces from header to match curl format + _sed_i 's/^[[:space:]][[:space:]]//g' "$HTTP_HEADER" else _ret="$?" _err "Neither curl nor wget is found, can not do $httpmethod." @@ -2052,9 +2058,21 @@ _get() { fi _debug "_WGET" "$_WGET" if [ "$onlyheader" ]; then - $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1 | sed 's/^[ ]*//g' + _wget_out = "$($_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1)" + if echo $_WGET | grep -q " -d " 2> /dev/null; then + # Demultiplex wget debug output + echo "$_wget_out" >&2 + echo "$_wget_out" | sed '/^[^[:space:]][^[:space:]]/d; /^[[:space:]]*$/d; s/^[[:space:]][[:space:]]//g' - + fi else $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O - "$url" 2>"$HTTP_HEADER" + if echo $_WGET | grep -q " -d " 2> /dev/null; then + # Demultiplex wget debug output + cat "$HTTP_HEADER" >&2 + _sed_i '/^[^[:space:]][^[:space:]]/d; /^[[:space:]]*$/d' "$HTTP_HEADER" + fi + # remove leading whitespaces from header to match curl format + _sed_i 's/^[[:space:]][[:space:]]//g' "$HTTP_HEADER" fi ret=$? if [ "$ret" = "8" ]; then From 864315f6d19b12ec514698094c3dc987c0128d26 Mon Sep 17 00:00:00 2001 From: Klaus Frank Date: Sun, 21 Aug 2022 01:55:47 +0200 Subject: [PATCH 1984/2234] Use literal space Replace [[:space:]] with " " --- acme.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 0130f004..c9146d87 100755 --- a/acme.sh +++ b/acme.sh @@ -2002,10 +2002,10 @@ _post() { if echo $_WGET | grep -q " -d " 2> /dev/null; then # Demultiplex wget debug output cat "$HTTP_HEADER" >&2 - _sed_i '/^[^[:space:]][^[:space:]]/d; /^[[:space:]]*$/d' "$HTTP_HEADER" + _sed_i '/^[^ ][^ ]/d; /^ *$/d' "$HTTP_HEADER" fi # remove leading whitespaces from header to match curl format - _sed_i 's/^[[:space:]][[:space:]]//g' "$HTTP_HEADER" + _sed_i 's/^ //g' "$HTTP_HEADER" else _ret="$?" _err "Neither curl nor wget is found, can not do $httpmethod." @@ -2062,17 +2062,17 @@ _get() { if echo $_WGET | grep -q " -d " 2> /dev/null; then # Demultiplex wget debug output echo "$_wget_out" >&2 - echo "$_wget_out" | sed '/^[^[:space:]][^[:space:]]/d; /^[[:space:]]*$/d; s/^[[:space:]][[:space:]]//g' - + echo "$_wget_out" | sed '/^[^ ][^ ]/d; /^ *$/d; s/^ //g' - fi else $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O - "$url" 2>"$HTTP_HEADER" if echo $_WGET | grep -q " -d " 2> /dev/null; then # Demultiplex wget debug output cat "$HTTP_HEADER" >&2 - _sed_i '/^[^[:space:]][^[:space:]]/d; /^[[:space:]]*$/d' "$HTTP_HEADER" + _sed_i '/^[^ ][^ ]/d; /^ *$/d' "$HTTP_HEADER" fi # remove leading whitespaces from header to match curl format - _sed_i 's/^[[:space:]][[:space:]]//g' "$HTTP_HEADER" + _sed_i 's/^ //g' "$HTTP_HEADER" fi ret=$? if [ "$ret" = "8" ]; then From 4e5d4b969538094f2d3306a23c84c773e2717f08 Mon Sep 17 00:00:00 2001 From: Viktor Sokhan Date: Thu, 25 Aug 2022 13:43:06 +0700 Subject: [PATCH 1985/2234] Fix shellcheck and shfmt --- dnsapi/dns_yc.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_yc.sh b/dnsapi/dns_yc.sh index bce9aa63..ec3bbc87 100644 --- a/dnsapi/dns_yc.sh +++ b/dnsapi/dns_yc.sh @@ -19,7 +19,7 @@ dns_yc_add() { YC_SA_Key_File_Path="${YC_SA_Key_File_Path:-$(_readaccountconf_mutable YC_SA_Key_File_Path)}" if [ "$YC_SA_Key_File_PEM_b64" ]; then - echo "$YC_SA_Key_File_PEM_b64" | _dbase64 > private.key + echo "$YC_SA_Key_File_PEM_b64" | _dbase64 >private.key YC_SA_Key_File="private.key" _savedomainconf YC_SA_Key_File_PEM_b64 "$YC_SA_Key_File_PEM_b64" else @@ -155,7 +155,7 @@ _get_root() { if ! _yc_rest GET "zones/$YC_Zone_ID"; then return 1 else - if echo "$response" | tr -d " " | grep \"id\":\"$YC_Zone_ID\" >/dev/null; then + if echo "$response" | tr -d " " | _egrep_o "\"id\":\"$YC_Zone_ID\"" >/dev/null; then _domain=$(echo "$response" | _egrep_o "\"zone\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") if [ "$_domain" ]; then _cutlength=$((${#domain} - ${#_domain})) @@ -238,16 +238,16 @@ _yc_rest() { _yc_login() { header=$(echo "{\"typ\":\"JWT\",\"alg\":\"PS256\",\"kid\":\"$YC_SA_Key_ID\"}" | _normalizeJson | _base64 | _url_replace) _debug header "$header" - + _current_timestamp=$(_time) - _expire_timestamp=$(_math $_current_timestamp + 1200) # 20 minutes + _expire_timestamp=$(_math "$_current_timestamp" + 1200) # 20 minutes payload=$(echo "{\"iss\":\"$YC_SA_ID\",\"aud\":\"https://iam.api.cloud.yandex.net/iam/v1/tokens\",\"iat\":$_current_timestamp,\"exp\":$_expire_timestamp}" | _normalizeJson | _base64 | _url_replace) _debug payload "$payload" #signature=$(printf "%s.%s" "$header" "$payload" | ${ACME_OPENSSL_BIN:-openssl} dgst -sign "$YC_SA_Key_File -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _base64 | _url_replace ) _signature=$(printf "%s.%s" "$header" "$payload" | _sign "$YC_SA_Key_File" "sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _url_replace) _debug2 _signature "$_signature" - + rm -rf "$YC_SA_Key_File" _jwt=$(printf "{\"jwt\": \"%s.%s.%s\"}" "$header" "$payload" "$_signature") From 3dde83d8a0b911bf7740fa86db2997aa66cd9522 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 26 Aug 2022 19:47:45 +0800 Subject: [PATCH 1986/2234] fix https://github.com/acmesh-official/acme.sh/issues/4268 --- dnsapi/dns_namesilo.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index 0b87b7f7..f961d0bd 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -110,7 +110,7 @@ _get_root() { return 1 fi - if _contains "$response" "$host"; then + if _contains "$response" ">$host"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$host" return 0 From f9320fff8ff71c9bc7a4d228bb8943ed9a1ae7eb Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sat, 27 Aug 2022 01:17:53 +0200 Subject: [PATCH 1987/2234] Changed lastUsedRidForDomainEntry seperator to space --- dnsapi/dns_selfhost.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index ea301788..4c94576b 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -20,7 +20,7 @@ dns_selfhost_add() { SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readdomainconf SELFHOSTDNS_MAP)}" # Selfhost api can't dynamically add TXT record, # so we have to store the last used RID of the domain to support a second RID for wildcard domains - # (format: ';fulldomainA:lastRid;;fulldomainB:lastRid;...') + # (format: 'fulldomainA:lastRid fulldomainB:lastRid ...') SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(_readdomainconf SELFHOSTDNS_MAP_LAST_USED_INTERNAL) if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then @@ -44,21 +44,26 @@ dns_selfhost_add() { rid2=$(echo "$mapEntry" | cut -d: -f3) # read last used rid domain - lastUsedRidForDomainEntry=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/.*(;$fulldomain:[[:digit:]]+;).*/\1/p") + lastUsedRidForDomainEntry=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/(^|^.*[[:space:]])($fulldomain:[[:digit:]]+)(.*)/\2/p") _debug2 lastUsedRidForDomainEntry "$lastUsedRidForDomainEntry" - lastUsedRidForDomain=$(echo "$lastUsedRidForDomainEntry" | tr -d ";" | cut -d: -f2) + lastUsedRidForDomain=$(echo "$lastUsedRidForDomainEntry" | cut -d: -f2) rid="$rid1" if [ "$lastUsedRidForDomain" = "$rid" ] && ! test -z "$rid2"; then rid="$rid2" fi + newLastUsedRidForDomainEntry="$fulldomain:$rid" if ! test -z "$lastUsedRidForDomainEntry"; then # replace last used rid entry for domain - SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/$lastUsedRidForDomainEntry/;$fulldomain:$rid;/p") + SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/$lastUsedRidForDomainEntry/$newLastUsedRidForDomainEntry/p") else # add last used rid entry for domain - SELFHOSTDNS_MAP_LAST_USED_INTERNAL="$SELFHOSTDNS_MAP_LAST_USED_INTERNAL"";$fulldomain:$rid;" + if test -z "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL"; then + SELFHOSTDNS_MAP_LAST_USED_INTERNAL="$newLastUsedRidForDomainEntry" + else + SELFHOSTDNS_MAP_LAST_USED_INTERNAL="$SELFHOSTDNS_MAP_LAST_USED_INTERNAL $newLastUsedRidForDomainEntry" + fi fi _info "Trying to add $txt on selfhost for rid: $rid" From 7a1f94bc20d2eb80ca05a78fb798d5ff0e2022cf Mon Sep 17 00:00:00 2001 From: AlvinSchiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 28 Aug 2022 20:44:17 +0200 Subject: [PATCH 1988/2234] set newLastUsedRidForDomainEntry after request was successfull --- dnsapi/dns_selfhost.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index 4c94576b..a6ef1f94 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -53,6 +53,17 @@ dns_selfhost_add() { rid="$rid2" fi + _info "Trying to add $txt on selfhost for rid: $rid" + + data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt" + response="$(_get "$SELFHOSTDNS_UPDATE_URL$data")" + + if ! echo "$response" | grep "200 OK" >/dev/null; then + _err "Invalid response of acme-dns for selfhost" + return 1 + fi + + # write last used rid domain newLastUsedRidForDomainEntry="$fulldomain:$rid" if ! test -z "$lastUsedRidForDomainEntry"; then # replace last used rid entry for domain @@ -66,16 +77,6 @@ dns_selfhost_add() { fi fi - _info "Trying to add $txt on selfhost for rid: $rid" - - data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt" - response="$(_get "$SELFHOSTDNS_UPDATE_URL$data")" - - if ! echo "$response" | grep "200 OK" >/dev/null; then - _err "Invalid response of acme-dns for selfhost" - return 1 - fi - # Now that we know the values are good, save them _saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME" _saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD" From dd707242efa70e0440edc2a9214d6113b95b9751 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 3 Sep 2022 21:11:16 +0800 Subject: [PATCH 1989/2234] the envs are moved to acmetest --- .github/workflows/DNS.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 057972f6..5aedfe8a 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -81,9 +81,7 @@ jobs: if [ "${{ secrets.TokenName5}}" ] ; then echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env fi - echo "TEST_DNS_NO_WILDCARD" >> docker.env - echo "http_proxy" >> docker.env - echo "https_proxy" >> docker.env + - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall From 5d6d0c6176c1be41c8729478bc7fe5e3fc787823 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 5 Sep 2022 13:19:34 +0200 Subject: [PATCH 1990/2234] World4You: fix paketnr parsing Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index a0a83c37..dfda4efd 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -195,7 +195,7 @@ _get_paketnr() { fqdn="$1" form="$2" - domains=$(echo "$form" | grep 'header-paket-domain' | sed 's/<[^>]*>//g' | sed 's/^.*>\([^>]*\)$/\1/') + domains=$(echo "$form" | grep '