From 861df496707b2837d1972f76ce5c8c1fdf2d19d7 Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 9 Mar 2018 16:29:47 +0100 Subject: [PATCH 0001/1299] 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 0002/1299] 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 cbf0ceacd57fe16f27fa6150ffd2b180d796f3b3 Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Fri, 16 Mar 2018 14:51:16 +0100 Subject: [PATCH 0003/1299] 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 0004/1299] 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 0005/1299] 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 0006/1299] 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 0007/1299] 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 68f66ca101ba04bf3abc3fb97f1f0162d6a2506c Mon Sep 17 00:00:00 2001 From: Martin Kammerlander Date: Thu, 2 Aug 2018 16:20:48 +0200 Subject: [PATCH 0008/1299] 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 16db9a7337ffbcfa5c8610a13fdedd66a5f4b956 Mon Sep 17 00:00:00 2001 From: Stephane Moser Date: Fri, 29 Mar 2019 14:12:34 +0000 Subject: [PATCH 0009/1299] 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 0010/1299] 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 0011/1299] 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 0012/1299] 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 aeed2871223b39eecf59917e19e1155e634588f2 Mon Sep 17 00:00:00 2001 From: Stephane Moser Date: Tue, 2 Apr 2019 10:27:22 +0100 Subject: [PATCH 0013/1299] 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 1ef7fd36590068fd83631318c13b79bf384e0046 Mon Sep 17 00:00:00 2001 From: Dominic Jonas Date: Wed, 5 Jun 2019 11:38:41 +0200 Subject: [PATCH 0014/1299] 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 ae66c6f0b484ce5c451ff8c195f382115b3d15a0 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Thu, 11 Jul 2019 15:46:17 -0400 Subject: [PATCH 0015/1299] 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 0016/1299] 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 0b2b8b960b07232edd92fed0124a35cbfd969a87 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Fri, 16 Aug 2019 22:56:22 -0400 Subject: [PATCH 0017/1299] 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 0018/1299] 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 0019/1299] 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 0020/1299] 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 0021/1299] 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 0022/1299] 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 0023/1299] 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 4bf1f579f51d7343c1b643f7bb357ba9e48d0cd6 Mon Sep 17 00:00:00 2001 From: Jesai Langenbach Date: Thu, 12 Sep 2019 16:28:57 +0200 Subject: [PATCH 0024/1299] 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 0025/1299] 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 0026/1299] 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 0027/1299] 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 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 0028/1299] 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 0029/1299] 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 0030/1299] 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 0031/1299] 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 0032/1299] 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 0033/1299] 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 0034/1299] 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 0035/1299] 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 0036/1299] 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 0037/1299] 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 0038/1299] 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 0039/1299] 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 0040/1299] 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 0041/1299] 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 0042/1299] 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 0043/1299] 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 0044/1299] 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 0045/1299] 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 0046/1299] 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 0047/1299] 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 0048/1299] 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 0049/1299] 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 0050/1299] 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 0051/1299] 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 0052/1299] 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 0053/1299] 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 0054/1299] 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 0055/1299] 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 0056/1299] 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 0057/1299] 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 0058/1299] 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 0059/1299] 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 0060/1299] 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 0061/1299] 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 0062/1299] 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 0063/1299] 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 0064/1299] 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 0065/1299] 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 0066/1299] 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 0067/1299] 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 0068/1299] 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 0069/1299] 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 0070/1299] 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 0071/1299] 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 0072/1299] 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 0073/1299] 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 0074/1299] 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 0075/1299] 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 0076/1299] 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 0077/1299] 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 0078/1299] 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 0079/1299] 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 0080/1299] 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 0081/1299] 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 0082/1299] [[: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 0083/1299] 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 0084/1299] 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 0085/1299] 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 0086/1299] 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 0087/1299] 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 0088/1299] 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 0089/1299] 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 0090/1299] 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 0091/1299] 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 0092/1299] 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 0093/1299] 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 0094/1299] 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 0095/1299] 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 0096/1299] 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 0097/1299] 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 0098/1299] 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 0099/1299] 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 0100/1299] 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 0101/1299] 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 0102/1299] 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 0103/1299] 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 0104/1299] 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 0105/1299] 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 0106/1299] 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 0107/1299] 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 0108/1299] 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 0109/1299] 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 0110/1299] 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 0111/1299] 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 0112/1299] 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 0113/1299] 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 0114/1299] 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 0115/1299] 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 0116/1299] 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 0117/1299] 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 0118/1299] 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 0119/1299] 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 0120/1299] 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 0121/1299] 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 0122/1299] 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 0123/1299] 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 0124/1299] 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 0125/1299] 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 0126/1299] 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 0127/1299] 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 0128/1299] 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 0129/1299] 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 0130/1299] 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 0131/1299] 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 0132/1299] 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 0133/1299] 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 0134/1299] 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 0135/1299] 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 0136/1299] 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 0137/1299] 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 0138/1299] 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 0139/1299] 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 0140/1299] #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 0141/1299] #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 0142/1299] 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 0143/1299] 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 0144/1299] 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 0145/1299] 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 0146/1299] 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 0147/1299] 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 0148/1299] 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 0149/1299] 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 0150/1299] 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 0151/1299] 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 0152/1299] 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 0153/1299] 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 0154/1299] 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 0155/1299] 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 0156/1299] 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 0157/1299] 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 0158/1299] 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 0159/1299] 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 0160/1299] 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 0161/1299] 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 0162/1299] 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 0163/1299] 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 0164/1299] 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 0165/1299] 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 0166/1299] 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 0167/1299] 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 0168/1299] 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 0169/1299] 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 0170/1299] 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 0171/1299] 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 0172/1299] 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 0173/1299] 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 0174/1299] 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 0175/1299] 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 0176/1299] 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 0177/1299] 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 0178/1299] 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 0179/1299] 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 0180/1299] 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 0181/1299] 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 0182/1299] 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 0183/1299] 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 0184/1299] 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 0185/1299] 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 0186/1299] 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 0187/1299] 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 0188/1299] 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 0189/1299] 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 0190/1299] 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 0191/1299] 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 0192/1299] 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 0193/1299] 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 0194/1299] 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 0195/1299] 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 0196/1299] 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 0197/1299] 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 0198/1299] 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 0199/1299] 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 0200/1299] 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 0201/1299] 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 0202/1299] 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 0203/1299] 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 0204/1299] 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 0205/1299] 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 0206/1299] 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 0207/1299] 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 0208/1299] 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 0209/1299] 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 0210/1299] 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 0211/1299] 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 0212/1299] 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 0213/1299] 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 0214/1299] 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 0215/1299] 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 0216/1299] 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 0217/1299] 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 0218/1299] 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 0219/1299] 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 0220/1299] 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 0221/1299] 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 0222/1299] 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 0223/1299] 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 0224/1299] 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 0225/1299] 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 0226/1299] 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 0227/1299] 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 0228/1299] 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 0229/1299] 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 0230/1299] 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 0231/1299] 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 0232/1299] 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 0233/1299] 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 0234/1299] 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 0235/1299] 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 0236/1299] 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 0237/1299] 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 0238/1299] 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 0239/1299] 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 0240/1299] 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 0241/1299] 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 0242/1299] 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 0243/1299] 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 0244/1299] 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 0245/1299] 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 0246/1299] 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 0247/1299] 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 0248/1299] 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 0249/1299] 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 0250/1299] 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 0251/1299] 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 0252/1299] 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 0253/1299] 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 0254/1299] 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 0255/1299] 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 0256/1299] 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 0257/1299] 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 0258/1299] 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 0259/1299] 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 0260/1299] 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 0261/1299] 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 0262/1299] 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 0263/1299] 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 0264/1299] 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 0265/1299] 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 0266/1299] 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 0267/1299] 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 0268/1299] 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 0269/1299] 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 0270/1299] 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 0271/1299] 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 0272/1299] 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 0273/1299] 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 0274/1299] 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 0275/1299] 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 0276/1299] 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 0277/1299] 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 0278/1299] 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 0279/1299] 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 0280/1299] 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 0281/1299] 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 0282/1299] 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 0283/1299] 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 0284/1299] 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 0285/1299] 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 0286/1299] 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 0287/1299] - 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 0288/1299] 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 0289/1299] 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 0290/1299] 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 0291/1299] 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 0292/1299] 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 0293/1299] 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 0294/1299] 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 0295/1299] 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 0296/1299] 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 0297/1299] 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 0298/1299] 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 0299/1299] 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 0300/1299] 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 0301/1299] 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 0302/1299] 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 0303/1299] 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 0304/1299] 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 0305/1299] 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 0306/1299] 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 0307/1299] 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 0308/1299] 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 0309/1299] 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 0310/1299] 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 0311/1299] 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 0312/1299] 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 0313/1299] 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 0314/1299] 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 0315/1299] 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 0316/1299] 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 0317/1299] 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 0318/1299] 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 0319/1299] 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 0320/1299] 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 0321/1299] 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 0322/1299] 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 0323/1299] 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 0324/1299] 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 0325/1299] 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 0326/1299] 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 0327/1299] 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 0328/1299] 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 0329/1299] 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 0330/1299] 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 0331/1299] 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 0332/1299] 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 0333/1299] 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 0334/1299] 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 0335/1299] 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 0336/1299] 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 0337/1299] 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 0338/1299] 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 0339/1299] 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 0340/1299] 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 0341/1299] 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 0342/1299] 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 0343/1299] 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 0344/1299] 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 0345/1299] 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 0346/1299] 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 0347/1299] 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 0348/1299] 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 0349/1299] 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 0350/1299] 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 0351/1299] 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 0352/1299] 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 0353/1299] 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 0354/1299] 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 0355/1299] 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 0356/1299] 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 0357/1299] 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 0358/1299] 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 0359/1299] 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 0360/1299] 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 0361/1299] 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 0362/1299] 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 0363/1299] 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 0364/1299] 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 0365/1299] 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 0366/1299] 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 0367/1299] 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 0368/1299] 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 0369/1299] 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 0370/1299] 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 0371/1299] 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 0372/1299] 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 0373/1299] 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 0374/1299] 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 0375/1299] 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 0376/1299] 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 0377/1299] 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 0378/1299] 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 0379/1299] 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 0380/1299] 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 0381/1299] 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 0382/1299] 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 0383/1299] 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 0384/1299] 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 0385/1299] 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 0386/1299] 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 0387/1299] 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 0388/1299] 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 0389/1299] 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 0390/1299] 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 0391/1299] 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 0392/1299] 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 0393/1299] 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 0394/1299] 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 0395/1299] 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 0396/1299] 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 0397/1299] 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 0398/1299] 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 0399/1299] 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 0400/1299] 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 0401/1299] 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 0402/1299] 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 0403/1299] 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 0404/1299] 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 0405/1299] 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 0406/1299] 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 0407/1299] 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 0408/1299] 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 0409/1299] 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 0410/1299] 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 0411/1299] 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 0412/1299] 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 0413/1299] 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 0414/1299] 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 0415/1299] 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 0416/1299] 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 0417/1299] 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 0418/1299] 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 0419/1299] 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 0420/1299] 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 0421/1299] 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 0422/1299] 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 0423/1299] 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 0424/1299] 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 0425/1299] 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 0426/1299] 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 0427/1299] 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 0428/1299] 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 0429/1299] 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 0430/1299] 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 0431/1299] 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 0432/1299] 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 0433/1299] 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 0434/1299] 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 0435/1299] 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 0436/1299] 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 0437/1299] 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 0438/1299] 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 0439/1299] 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 0440/1299] 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 0441/1299] 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 0442/1299] 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 0443/1299] 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 0444/1299] 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 0445/1299] 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 0446/1299] 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 0447/1299] 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 0448/1299] 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 0449/1299] 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 0450/1299] 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 0451/1299] 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 0452/1299] 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 0453/1299] 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 0454/1299] 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 0455/1299] 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 0456/1299] 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 0457/1299] 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 0458/1299] 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 0459/1299] 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 0460/1299] 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 0461/1299] 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 0462/1299] 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 0463/1299] 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 0464/1299] 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 0465/1299] 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 0466/1299] 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 0467/1299] 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 0468/1299] 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 0469/1299] 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 0470/1299] 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 0471/1299] 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 0472/1299] 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 0473/1299] 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 0474/1299] 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 0475/1299] 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 0476/1299] 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 0477/1299] 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 0478/1299] 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 0479/1299] 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 0480/1299] 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 0481/1299] 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 0482/1299] 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 0483/1299] 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 0484/1299] 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 0485/1299] 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 0486/1299] 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 0487/1299] 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 0488/1299] 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 0489/1299] 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 0490/1299] 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 0491/1299] 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 0492/1299] 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 0493/1299] 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 0494/1299] 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 0495/1299] 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 0496/1299] 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 0497/1299] 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 0498/1299] 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 0499/1299] 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 0500/1299] 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 0501/1299] 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 0502/1299] 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 0503/1299] 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 0504/1299] 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 0505/1299] 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 0506/1299] 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 0507/1299] 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 0508/1299] 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 0509/1299] 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 0510/1299] 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 0511/1299] 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 0512/1299] 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 0513/1299] --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 0514/1299] 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 0515/1299] 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 0516/1299] 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 0517/1299] 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 0518/1299] 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 0519/1299] 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 0520/1299] 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 0521/1299] 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 0522/1299] 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 0523/1299] 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 0524/1299] 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 0525/1299] 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 0526/1299] 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 0527/1299] 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 0528/1299] 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 0529/1299] 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 0530/1299] 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 0531/1299] 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 0532/1299] 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 0533/1299] 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 0534/1299] 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 0535/1299] 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 0536/1299] 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 0537/1299] 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 0538/1299] 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 0539/1299] 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 0540/1299] 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 0541/1299] 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 0542/1299] 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 0543/1299] 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 0544/1299] 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 0545/1299] 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 0546/1299] 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 0547/1299] 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 0548/1299] 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 0549/1299] 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 0550/1299] 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 0551/1299] 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 0552/1299] 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 0553/1299] 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 784b914e0741099feb1ccd22d2f09a91f09a0ded Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 9 Oct 2020 22:33:21 +0800 Subject: [PATCH 0554/1299] 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 05141b4f527d8aaacf75b9762e82affa1acac07c Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Mon, 21 Sep 2020 14:17:23 +0200 Subject: [PATCH 0555/1299] 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 0556/1299] 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 0557/1299] 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 0558/1299] 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 ea3e6dae93e76dfe79272c6cb9dd0c6b9acbb297 Mon Sep 17 00:00:00 2001 From: Ed Lynes Date: Wed, 14 Oct 2020 14:49:09 -0400 Subject: [PATCH 0559/1299] 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 0560/1299] 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 0561/1299] 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 0562/1299] 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 0563/1299] 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 0564/1299] 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 0565/1299] 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 0566/1299] 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 0567/1299] 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 0568/1299] 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 0569/1299] 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 0570/1299] 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 0571/1299] 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 0572/1299] 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 0573/1299] 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 0574/1299] 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 0575/1299] 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 0576/1299] 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 0577/1299] 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 0578/1299] 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 0579/1299] 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 0580/1299] 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 0581/1299] 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 0582/1299] 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 0583/1299] 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 0584/1299] 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 0585/1299] 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 0586/1299] 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 0587/1299] 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 0588/1299] 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 0589/1299] 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 0590/1299] 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 0591/1299] 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 0592/1299] 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 0593/1299] 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 0594/1299] 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 0595/1299] 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 0596/1299] 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 0597/1299] 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 0598/1299] 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 0599/1299] 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 0600/1299] 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 0601/1299] 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 0602/1299] 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 0603/1299] 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 0604/1299] 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 0605/1299] 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 0606/1299] 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 0607/1299] 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 0608/1299] 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 0609/1299] 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 0610/1299] 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 0611/1299] 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 0612/1299] 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 0613/1299] 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 0614/1299] 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 0615/1299] 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 0616/1299] 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 0617/1299] 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 0618/1299] 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 0619/1299] 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 0620/1299] 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 0621/1299] 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 0622/1299] 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 0623/1299] 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 0624/1299] 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 0625/1299] 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 0626/1299] 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 0627/1299] 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 0628/1299] 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 0629/1299] 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 0630/1299] 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 0631/1299] 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 0632/1299] 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 0633/1299] 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 0634/1299] 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 0635/1299] 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 0636/1299] 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 0637/1299] 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 0638/1299] 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 0639/1299] 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 0640/1299] 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 0641/1299] 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 0642/1299] 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 0643/1299] 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 0644/1299] 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 0645/1299] 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 0646/1299] 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 0647/1299] 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 0648/1299] 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 0649/1299] 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 0650/1299] 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 0651/1299] 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 0652/1299] 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 0653/1299] 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 0654/1299] 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 0655/1299] 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 0656/1299] 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 0657/1299] 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 0658/1299] 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 0659/1299] 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 0660/1299] 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 0661/1299] 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 0662/1299] 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 0663/1299] 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 0664/1299] 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 0665/1299] 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 0666/1299] 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 0667/1299] 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 0668/1299] 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 0669/1299] 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 0670/1299] 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 0671/1299] 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 0672/1299] 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 0673/1299] 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 0674/1299] 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 0675/1299] 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 0676/1299] 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 0677/1299] 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 0678/1299] 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 0679/1299] 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 0680/1299] 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 0681/1299] 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 0682/1299] 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 0683/1299] 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 0684/1299] 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 0685/1299] 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 0686/1299] 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 0687/1299] 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 0688/1299] 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 0689/1299] 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 0690/1299] 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 0691/1299] 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 0692/1299] 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 0693/1299] 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 0694/1299] 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 0695/1299] 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 0696/1299] 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 0697/1299] 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 0698/1299] 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 0699/1299] 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 0700/1299] 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 0701/1299] 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 0702/1299] 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 0703/1299] 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 0704/1299] 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 0705/1299] 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 0706/1299] 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 0707/1299] 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 0708/1299] 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 0709/1299] 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 0710/1299] 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 0711/1299] 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 0712/1299] 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 0713/1299] 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 0714/1299] 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 0715/1299] 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 0716/1299] 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 0717/1299] 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 0718/1299] 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 0719/1299] 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 0720/1299] 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 0721/1299] 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 0722/1299] 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 0723/1299] 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 0724/1299] 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 0725/1299] 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 0726/1299] 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 0727/1299] 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 0728/1299] 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 0729/1299] 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 0730/1299] 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 0731/1299] 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 0732/1299] 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 0733/1299] 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 0734/1299] 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 0735/1299] 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 0736/1299] 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 0737/1299] 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 0738/1299] 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 0739/1299] 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 0740/1299] 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 0741/1299] _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 0742/1299] 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 0743/1299] 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 0744/1299] 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 0745/1299] 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 0746/1299] 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 0747/1299] 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 0748/1299] 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 0749/1299] 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 0750/1299] 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 0751/1299] 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 0752/1299] 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 0753/1299] 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 0754/1299] 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 0755/1299] 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 0756/1299] 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 0757/1299] 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 0758/1299] 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 0759/1299] 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 0760/1299] 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 0761/1299] "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 0762/1299] 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 0763/1299] 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 0764/1299] 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 0765/1299] 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 0766/1299] 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 0767/1299] 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 0768/1299] 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 0769/1299] 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 0770/1299] 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 0771/1299] 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 0772/1299] 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 0773/1299] 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 0774/1299] 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 0775/1299] 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 0776/1299] 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 0777/1299] 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 0778/1299] 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 fa3cee9d5871558b8616fd1fcf33a52abd4d45cf Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 18:38:40 +0100 Subject: [PATCH 0779/1299] Update dns_websupport.sh From aa479948f9917e220b8a6c39968845caf3efaf78 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Thu, 4 Feb 2021 19:03:35 +0100 Subject: [PATCH 0780/1299] Final try, leaving _hmac as before 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 0781/1299] 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 0782/1299] 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 0783/1299] 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 0784/1299] 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 0785/1299] 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 0786/1299] 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 0787/1299] 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 0788/1299] 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 0789/1299] 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 0790/1299] 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 0791/1299] 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 0792/1299] 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 0793/1299] 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 0794/1299] 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 0795/1299] 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 0796/1299] 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 0797/1299] 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 0798/1299] 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 0799/1299] 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 0800/1299] 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 0801/1299] 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 0802/1299] 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 0803/1299] 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 0804/1299] 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 0805/1299] 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 0806/1299] 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 0807/1299] 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 0808/1299] 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 0809/1299] 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 0810/1299] 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 0811/1299] 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 0812/1299] 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 0813/1299] 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 0814/1299] 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 0815/1299] 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 0816/1299] 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 0817/1299] 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 0818/1299] 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 0819/1299] 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 0820/1299] 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 0821/1299] 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 0822/1299] 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 0823/1299] 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 0824/1299] 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 0825/1299] 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 0826/1299] 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 0827/1299] 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 0828/1299] 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 0829/1299] 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 0830/1299] 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 0831/1299] 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 0832/1299] 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 0833/1299] 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 0834/1299] 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 0835/1299] 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 0836/1299] 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 0837/1299] 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 0838/1299] 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 0839/1299] 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 0840/1299] 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 0841/1299] 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 0842/1299] 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 5cc0fa7c98566eebc6bd035b4f41e63681d8f14e Mon Sep 17 00:00:00 2001 From: wout Date: Sun, 14 Mar 2021 15:50:16 +0100 Subject: [PATCH 0843/1299] Retrigger checks From cc7e1a72c1385031cf98c1e4f2f7188725576476 Mon Sep 17 00:00:00 2001 From: wout Date: Sun, 14 Mar 2021 15:54:28 +0100 Subject: [PATCH 0844/1299] Retrigger checks From 2386d2e299561378b11eb6a72dac05e7449e2222 Mon Sep 17 00:00:00 2001 From: Alexander Kulumbeg Date: Sat, 20 Mar 2021 15:26:32 +0100 Subject: [PATCH 0845/1299] 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 0846/1299] 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 0847/1299] 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 0848/1299] 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 0849/1299] 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 0850/1299] 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 0851/1299] 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 0852/1299] 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 0853/1299] 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 0854/1299] 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 0855/1299] 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 0856/1299] 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 0857/1299] 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 0858/1299] 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 0859/1299] 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 0860/1299] 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 0861/1299] 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 0862/1299] 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 0863/1299] 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 0864/1299] 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 0865/1299] 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 0866/1299] 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 0867/1299] 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 0868/1299] 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 0869/1299] 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 0870/1299] 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 0871/1299] 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 0872/1299] 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 0873/1299] 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 0874/1299] 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 0875/1299] 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 0876/1299] 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 0877/1299] 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 0878/1299] 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 0879/1299] 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 0880/1299] 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 0881/1299] 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 0882/1299] 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 0883/1299] 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 0884/1299] 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 0885/1299] 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 0886/1299] 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 0887/1299] 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 0888/1299] 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 0889/1299] 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 0890/1299] 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 0891/1299] 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 0892/1299] 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 0893/1299] 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 0894/1299] 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 0895/1299] 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 0896/1299] 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 0897/1299] 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 0898/1299] 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 0899/1299] 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 0900/1299] 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 0901/1299] 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 0902/1299] 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 0903/1299] 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 0904/1299] 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 0905/1299] 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 0906/1299] 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 0907/1299] 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 0908/1299] 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 0909/1299] 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 0910/1299] 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 0911/1299] 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 0912/1299] 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 0913/1299] 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 0914/1299] 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 0915/1299] 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 0916/1299] 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 0917/1299] 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 0918/1299] 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 0919/1299] 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 0920/1299] 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 0921/1299] 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 0922/1299] 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 0923/1299] 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 0924/1299] 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 0925/1299] 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 0926/1299] 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 0927/1299] 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 0928/1299] 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 0929/1299] 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 0930/1299] 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 0931/1299] 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 0932/1299] 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 0933/1299] 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 0934/1299] 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 0935/1299] 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 0936/1299] 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 0937/1299] 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 0938/1299] 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 0939/1299] 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 0940/1299] 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 0941/1299] 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 0942/1299] 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 0943/1299] 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 0944/1299] 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 0945/1299] 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 0946/1299] 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 0947/1299] 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 0948/1299] 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 0949/1299] 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 0950/1299] 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 0951/1299] 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 0952/1299] 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 0953/1299] 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 0954/1299] 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 0955/1299] 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 0956/1299] 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 0957/1299] 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 0958/1299] 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 0959/1299] 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 0960/1299] 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 0961/1299] 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 0962/1299] 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 0963/1299] 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 0964/1299] 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 0965/1299] 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 0966/1299] 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 0967/1299] 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 0968/1299] 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 0969/1299] 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 0970/1299] 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 0971/1299] 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 0972/1299] 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 0973/1299] 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 0974/1299] 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 0975/1299] 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 0976/1299] 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 0977/1299] 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 0978/1299] 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 0979/1299] 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 0980/1299] 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 0981/1299] 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 0982/1299] 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 0983/1299] 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 0984/1299] 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 0985/1299] 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 0986/1299] 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 0987/1299] 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 0988/1299] 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 0989/1299] 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 0990/1299] 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 0991/1299] 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 0992/1299] 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 0993/1299] [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 0994/1299] 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 0995/1299] 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 0996/1299] 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 0997/1299] 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 0998/1299] 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 0999/1299] 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 1000/1299] 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 1001/1299] 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 1002/1299] 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 1003/1299] 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 1004/1299] 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 1005/1299] 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 1006/1299] 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 1007/1299] 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 1008/1299] 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 1009/1299] 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 1010/1299] 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 1011/1299] 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 1012/1299] 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 1013/1299] 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 1014/1299] 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 1015/1299] 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 1016/1299] 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 1017/1299] 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 1018/1299] 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 1019/1299] 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 1020/1299] 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 1021/1299] 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 1022/1299] 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 1023/1299] 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 1024/1299] 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 1025/1299] 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 1026/1299] 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 1027/1299] 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 1028/1299] 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 1029/1299] 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 1030/1299] 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 1031/1299] 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 1032/1299] 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 1033/1299] 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 1034/1299] 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 1035/1299] 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 1036/1299] 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 1037/1299] 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 1038/1299] 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 f354e6de69f66c23b67cc29dd84baac06d2fe5d6 Mon Sep 17 00:00:00 2001 From: Michael Weber Date: Sat, 6 Feb 2021 08:25:49 +0000 Subject: [PATCH 1039/1299] 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 1040/1299] 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 1041/1299] 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 1042/1299] 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 1043/1299] 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 1044/1299] 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 1045/1299] 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 1046/1299] 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 1047/1299] 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 1048/1299] 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 1049/1299] 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 1050/1299] 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 1051/1299] 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 1052/1299] 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 1053/1299] 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 1054/1299] 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 1055/1299] 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 1056/1299] 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 1057/1299] 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 1058/1299] 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 1059/1299] 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 1060/1299] 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 1061/1299] 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 1062/1299] 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 1063/1299] 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 1064/1299] 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 1065/1299] 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 1066/1299] 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 1067/1299] 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 1068/1299] 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 1069/1299] 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 1070/1299] 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 1071/1299] 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 1072/1299] 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 1073/1299] 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 1074/1299] 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 1075/1299] 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 1076/1299] 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 1077/1299] 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 1078/1299] 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 1079/1299] 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 1080/1299] 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 1081/1299] 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 1082/1299] 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 1083/1299] 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 1084/1299] 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 1085/1299] 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 1086/1299] 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 1087/1299] 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 1088/1299] 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 1089/1299] 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 1090/1299] 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 1091/1299] 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 1092/1299] 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 1093/1299] 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 1094/1299] 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 1095/1299] 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 1096/1299] 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 1097/1299] 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 1098/1299] 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 1099/1299] 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 1100/1299] 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 1101/1299] 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 1102/1299] 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 1103/1299] 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 1104/1299] 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 1105/1299] 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 1106/1299] 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 1107/1299] 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 1108/1299] 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 6e7ce1eec132cd0b5e7e975ecdd03fea68c87cbe Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Wed, 20 Oct 2021 14:28:55 +0200 Subject: [PATCH 1109/1299] 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 1110/1299] 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 1111/1299] 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 1112/1299] 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 1113/1299] 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 1114/1299] 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 1115/1299] 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 1116/1299] 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 1117/1299] 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 1118/1299] 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 1119/1299] 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 1120/1299] 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 1121/1299] 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 1122/1299] 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 1123/1299] 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 1124/1299] 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 1125/1299] 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 1126/1299] 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 1127/1299] 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 1128/1299] 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 1129/1299] 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 1130/1299] 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 1131/1299] 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 1132/1299] 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 eaae0547f2687cdd7c1c9f00a437a204425dce56 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 5 Dec 2021 16:15:39 +0800 Subject: [PATCH 1133/1299] 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 1134/1299] 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 1135/1299] 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 1136/1299] 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 1137/1299] 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 1138/1299] [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 1139/1299] 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 1140/1299] 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 1141/1299] 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 1142/1299] 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 1143/1299] 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 1144/1299] 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 1145/1299] 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 1146/1299] 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 1147/1299] 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 1148/1299] 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 1149/1299] 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 1150/1299] 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 1151/1299] 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 1152/1299] 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 1153/1299] 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 1154/1299] 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 1155/1299] 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 1156/1299] 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 1157/1299] 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 1158/1299] 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 1159/1299] 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 1160/1299] 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 1161/1299] 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 1162/1299] 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 1163/1299] 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 1164/1299] 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 1165/1299] 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 1166/1299] 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 1167/1299] 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 1168/1299] 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 1169/1299] 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 1170/1299] 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 1171/1299] 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 1172/1299] 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 1173/1299] 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 1174/1299] 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 1175/1299] 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 bda454fe9cbb3ba2d73251416a703db28a7d4ff7 Mon Sep 17 00:00:00 2001 From: I Komang Suryadana Date: Tue, 11 Jan 2022 15:25:10 +0800 Subject: [PATCH 1176/1299] 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 1177/1299] 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 1178/1299] 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 1179/1299] 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 1180/1299] 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 1181/1299] 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 1182/1299] 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 1183/1299] 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 1184/1299] 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 1185/1299] 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 1186/1299] 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 1187/1299] 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 1188/1299] 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 1189/1299] 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 1190/1299] 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 1191/1299] 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 1192/1299] 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 1193/1299] 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 1194/1299] 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 1195/1299] 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 1196/1299] 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 1197/1299] 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 1198/1299] 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 1199/1299] 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 1200/1299] 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 1201/1299] 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 1202/1299] 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 1203/1299] 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 1204/1299] 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 1205/1299] 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 1206/1299] 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 1207/1299] 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 1208/1299] 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 1209/1299] 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 1210/1299] 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 1211/1299] 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 1212/1299] 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 1213/1299] 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 1214/1299] 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 1215/1299] 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 1216/1299] 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 1217/1299] 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 1218/1299] 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 1219/1299] 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 1220/1299] 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 1221/1299] 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 1222/1299] 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 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 1223/1299] 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 1224/1299] 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 1225/1299] 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 1226/1299] 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 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 1227/1299] 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 1228/1299] 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 e82f3439c300b9771f9975ca968fe4e50f4e20e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Th=C3=B6rnblad?= Date: Mon, 7 Mar 2022 10:13:45 +0100 Subject: [PATCH 1229/1299] Trigger CI 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 1230/1299] 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 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 1231/1299] 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 1232/1299] 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 1233/1299] =?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 1234/1299] 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 1235/1299] 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 1236/1299] 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 1237/1299] 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 1238/1299] 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 1239/1299] 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 1240/1299] 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 1241/1299] 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 1242/1299] 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 1243/1299] 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 1244/1299] 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 1245/1299] Update acme.sh fix https://github.com/acmesh-official/acme.sh/issues/4001 --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 55fa4467..b4cf3e63 100755 --- a/acme.sh +++ b/acme.sh @@ -1845,7 +1845,9 @@ _inithttp() { _ACME_WGET="$_ACME_WGET --max-redirect 0 " fi if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then - _ACME_WGET="$_ACME_WGET -d " + if [ "$_ACME_WGET" ] && _contains "$($_ACME_WGET --help 2>&1)" "--debug"; then + _ACME_WGET="$_ACME_WGET -d " + fi fi if [ "$CA_PATH" ]; then _ACME_WGET="$_ACME_WGET --ca-directory=$CA_PATH " From fb5091a388c6cb4280cd095ab74056697be21a54 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 30 Mar 2022 22:47:12 +0800 Subject: [PATCH 1246/1299] 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 1247/1299] 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 1248/1299] 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 1249/1299] 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 1250/1299] 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 1251/1299] 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 1252/1299] 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 922553032b1ea1f274868b7181d5e5b897a02bff Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 1 Apr 2022 15:13:52 +0800 Subject: [PATCH 1253/1299] typo From 0f607413d08a3e067a4852b27faf096d846854bf Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 3 Apr 2022 20:05:30 +0800 Subject: [PATCH 1254/1299] 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 1255/1299] 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 1256/1299] 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 1257/1299] 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 1258/1299] 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 1259/1299] 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 1260/1299] 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 1261/1299] 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 1262/1299] 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 1263/1299] 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 1264/1299] 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 1265/1299] 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 1266/1299] 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 1267/1299] 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 1268/1299] 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 1269/1299] 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 1270/1299] 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 1271/1299] 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 1272/1299] 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 1273/1299] 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 1274/1299] 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 1275/1299] 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 1276/1299] 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 1277/1299] 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 1278/1299] 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 1279/1299] 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 1280/1299] dns_world4you: fix _parse_paket_nr Signed-off-by: Lorenz Stechauner --- dnsapi/dns_world4you.sh | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index fd124754..bcf256ff 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -54,15 +54,14 @@ dns_world4you_add() { if _contains "$res" "successfully"; then return 0 else - msg=$(echo "$res" | tr '\n' '\t' | sed 's/.*

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

[^\t]*\t *\([^\t]*\)\t.*/\1/') - if _contains "$msg" '^<\!DOCTYPE html>'; then - msg='Unknown error' - fi - _err "Unable to remove record: $msg" - if _contains "$msg" '^<\!DOCTYPE html>'; then + msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "]*>[^<]" | sed 's/<[^>]*>\|^\s*//g') + if [ "$msg" = '' ]; then + _err "Unable to remove record: Unknown error" echo "$ret" >'error-01.html' echo "$res" >'error-02.html' _err "View error-01.html and error-02.html for debugging" + else + _err "Unable to remove record: my.world4you.com: $msg" fi return 1 fi @@ -199,6 +197,6 @@ _get_paketnr() { TLD="$domain" _debug domain "$domain" RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))") - PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _head_n 1 | sed 's/^.* \([0-9]*\) .*$/\1/') + PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _tail_n 1 | sed "s|.*$WORLD4YOU_API/\\([0-9]*\\)/.*|\\1|") return 0 } From 24ce7c19914917b4c78c4e49a442f0f40cf258fd Mon Sep 17 00:00:00 2001 From: nicolaspn Date: Mon, 2 May 2022 15:46:49 +0200 Subject: [PATCH 1281/1299] Add call dns OVH API for refresh domain after delete TXT record --- dnsapi/dns_ovh.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index e65babbd..b382e52f 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -198,6 +198,8 @@ dns_ovh_rm() { if ! _ovh_rest DELETE "domain/zone/$_domain/record/$rid"; then return 1 fi + _ovh_rest POST "domain/zone/$_domain/refresh" + _debug "Refresh:$response" return 0 fi done From 64847afc3ff8cfe214aca7db7f793d96bee95e5e Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 3 May 2022 21:19:29 +0800 Subject: [PATCH 1282/1299] 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 1283/1299] 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 1284/1299] 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 1285/1299] fix https://github.com/acmesh-official/acme.sh/issues/4069 --- acme.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/acme.sh b/acme.sh index eb9ba7ef..b958a02b 100755 --- a/acme.sh +++ b/acme.sh @@ -2691,6 +2691,13 @@ _initAPI() { return 1 } +_clearCA() { + export ACME_DIRECTORY= + export CA_CONF= + export ACCOUNT_KEY_PATH= + export ACCOUNT_JSON_PATH= +} + #[domain] [keylength or isEcc flag] _initpath() { domain="$1" @@ -5357,6 +5364,7 @@ renew() { #renewAll [stopRenewOnError] renewAll() { _initpath + _clearCA _stopRenewOnError="$1" _debug "_stopRenewOnError" "$_stopRenewOnError" _ret="0" From 619bae745b36e885072c7bbf29fb0e08f4577bf3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 9 May 2022 20:08:38 +0800 Subject: [PATCH 1286/1299] 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 1287/1299] 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 1288/1299] 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 1289/1299] 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 1290/1299] 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 1291/1299] 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 1292/1299] 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 1293/1299] 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 1294/1299] 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 1295/1299] 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 1296/1299] 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 1297/1299] 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 1298/1299] 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 1299/1299] 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