From 748cb28017398ca125f507342a2c8cf5d7480a85 Mon Sep 17 00:00:00 2001 From: Ian Epperson Date: Wed, 13 May 2020 10:39:11 -0700 Subject: [PATCH 001/569] 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 b19cb0805cfe72aec1cea8b1f4fc9e5921cf0d4e Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Tue, 17 Nov 2020 13:19:55 +0100 Subject: [PATCH 002/569] 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 003/569] 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 004/569] 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 6cf0eb9e1d5b8f831c44b93adfcb8b9d5fe1d405 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 14:52:32 +0100 Subject: [PATCH 005/569] 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 006/569] 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 6ef66399f8accca401e0c55d24cb74624617bea6 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 15:37:26 +0100 Subject: [PATCH 007/569] 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 008/569] 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 009/569] 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 010/569] 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 1e2d2abbdf668a2d307a07363d5e6e265d2dbee2 Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Wed, 18 Nov 2020 18:01:02 +0100 Subject: [PATCH 011/569] 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 65c06da275c49b1675d46af91d8e0e0e366cf29e Mon Sep 17 00:00:00 2001 From: jakelamotta Date: Tue, 17 Nov 2020 13:19:55 +0100 Subject: [PATCH 012/569] 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 013/569] 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 014/569] 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 015/569] 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 016/569] 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 017/569] 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 018/569] 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 019/569] 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 020/569] 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 021/569] 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 2bc627970ed38fbccd7316e7e4a868eb33cff94c Mon Sep 17 00:00:00 2001 From: Christian Burmeister Date: Tue, 1 Dec 2020 20:30:56 +0100 Subject: [PATCH 022/569] 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 023/569] 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 024/569] 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 025/569] 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 026/569] 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 027/569] 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 028/569] 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 029/569] 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 030/569] 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 031/569] 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 032/569] 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 033/569] 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 034/569] 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 035/569] 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 036/569] 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 037/569] 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 038/569] 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 039/569] 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 040/569] 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 041/569] 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 042/569] 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 043/569] 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 044/569] 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 045/569] 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 046/569] 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 047/569] 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 048/569] 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 049/569] 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 050/569] 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 051/569] 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 052/569] 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 053/569] 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 054/569] 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 055/569] 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 056/569] 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 057/569] _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 058/569] 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 059/569] 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 060/569] 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 061/569] 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 062/569] 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 063/569] 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 064/569] 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 065/569] 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 066/569] 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 067/569] 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 068/569] 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 069/569] 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 070/569] 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 071/569] 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 072/569] 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 073/569] 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 074/569] 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 075/569] 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 076/569] 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 077/569] "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 078/569] 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 079/569] 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 080/569] 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 081/569] 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 082/569] 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 083/569] 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 084/569] 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 085/569] 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 086/569] 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 087/569] 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 088/569] 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 089/569] 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 090/569] 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 091/569] 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 092/569] 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 093/569] 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 094/569] 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 095/569] 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 096/569] 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 097/569] 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 098/569] 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 099/569] 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 100/569] 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 101/569] 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 102/569] 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 103/569] 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 104/569] 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 105/569] 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 106/569] 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 107/569] 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 108/569] 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 109/569] 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 110/569] 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 111/569] 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 112/569] 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 113/569] 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 114/569] 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 115/569] 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 116/569] 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 117/569] 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 118/569] 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 119/569] 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 120/569] 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 121/569] 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 122/569] 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 123/569] 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 124/569] 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 125/569] 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 126/569] 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 127/569] 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 128/569] 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 129/569] 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 130/569] 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 131/569] 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 132/569] 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 133/569] 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 134/569] 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 135/569] 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 136/569] 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 137/569] 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 138/569] 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 139/569] 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 140/569] 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 141/569] 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 142/569] 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 143/569] 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 144/569] 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 145/569] 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 146/569] 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 147/569] 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 148/569] 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 149/569] 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 150/569] 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 151/569] 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 152/569] 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 153/569] 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 154/569] 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 155/569] 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 156/569] 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 157/569] 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 158/569] 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 159/569] Retrigger checks From cc7e1a72c1385031cf98c1e4f2f7188725576476 Mon Sep 17 00:00:00 2001 From: wout Date: Sun, 14 Mar 2021 15:54:28 +0100 Subject: [PATCH 160/569] 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 161/569] 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 162/569] 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 163/569] 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 164/569] 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 165/569] 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 166/569] 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 167/569] 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 168/569] 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 169/569] 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 170/569] 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 171/569] 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 172/569] 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 173/569] 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 174/569] 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 175/569] 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 176/569] 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 177/569] 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 178/569] 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 179/569] 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 180/569] 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 181/569] 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 182/569] 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 183/569] 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 184/569] 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 185/569] 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 186/569] 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 187/569] 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 188/569] 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 189/569] 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 190/569] 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 191/569] 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 192/569] 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 193/569] 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 194/569] 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 195/569] 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 196/569] 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 197/569] 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 198/569] 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 199/569] 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 200/569] 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 201/569] 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 202/569] 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 203/569] 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 204/569] 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 205/569] 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 206/569] 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 207/569] 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 208/569] 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 209/569] 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 210/569] 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 211/569] 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 212/569] 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 213/569] 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 214/569] 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 215/569] 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 216/569] 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 217/569] 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 218/569] 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 219/569] 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 220/569] 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 221/569] 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 222/569] 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 223/569] 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 224/569] 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 225/569] 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 226/569] 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 227/569] 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 228/569] 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 229/569] 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 230/569] 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 231/569] 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 232/569] 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 233/569] 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 234/569] 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 235/569] 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 236/569] 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 237/569] 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 238/569] 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 239/569] 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 240/569] 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 241/569] 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 242/569] 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 243/569] 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 244/569] 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 245/569] 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 246/569] 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 247/569] 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 248/569] 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 249/569] 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 250/569] 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 251/569] 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 252/569] 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 253/569] 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 254/569] 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 255/569] 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 256/569] 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 257/569] 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 258/569] 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 259/569] 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 260/569] 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 261/569] 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 262/569] 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 263/569] 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 264/569] 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 265/569] 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 266/569] 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 267/569] 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 268/569] 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 269/569] 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 270/569] 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 271/569] 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 272/569] 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 273/569] 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 274/569] 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 275/569] 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 276/569] 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 277/569] 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 278/569] 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 279/569] 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 280/569] 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 281/569] 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 282/569] 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 283/569] 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 284/569] 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 285/569] 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 286/569] 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 287/569] 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 288/569] 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 289/569] 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 290/569] 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 291/569] 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 292/569] 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 293/569] 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 294/569] 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 295/569] 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 296/569] 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 297/569] 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 298/569] 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 299/569] 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 300/569] 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 301/569] 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 302/569] 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 303/569] 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 304/569] 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 305/569] 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 306/569] 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 307/569] 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 308/569] 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 309/569] [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 310/569] 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 311/569] 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 312/569] 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 313/569] 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 314/569] 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 315/569] 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 316/569] 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 317/569] 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 318/569] 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 319/569] 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 320/569] 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 321/569] 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 322/569] 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 323/569] 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 324/569] 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 325/569] 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 326/569] 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 327/569] 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 328/569] 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 329/569] 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 330/569] 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 331/569] 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 332/569] 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 333/569] 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 334/569] 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 335/569] 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 336/569] 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 337/569] 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 338/569] 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 339/569] 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 340/569] 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 341/569] 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 342/569] 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 343/569] 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 344/569] 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 345/569] 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 346/569] 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 347/569] 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 348/569] 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 349/569] 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 350/569] 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 351/569] 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 352/569] 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 353/569] 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 354/569] 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 355/569] 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 356/569] 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 357/569] 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 358/569] 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 359/569] 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 360/569] 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 361/569] 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 362/569] 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 363/569] 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 364/569] 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 365/569] 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 366/569] 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 367/569] 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 368/569] 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 369/569] 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 370/569] 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 371/569] 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 372/569] 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 373/569] 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 374/569] 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 375/569] 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 376/569] 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 377/569] 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 378/569] 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 379/569] 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 380/569] 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 381/569] 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 382/569] 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 383/569] 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 384/569] 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 385/569] 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 386/569] 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 387/569] 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 388/569] 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 389/569] 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 390/569] 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 391/569] 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 392/569] 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 393/569] 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 394/569] 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 395/569] 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 396/569] 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 397/569] 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 398/569] 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 399/569] 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 400/569] 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 401/569] 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 402/569] 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 403/569] 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 404/569] 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 405/569] 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 406/569] 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 407/569] 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 408/569] 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 409/569] 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 410/569] 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 411/569] 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 412/569] 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 413/569] 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 414/569] 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 415/569] 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 416/569] 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 417/569] 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 418/569] 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 419/569] 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 420/569] 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 421/569] 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 422/569] 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 423/569] 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 424/569] 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 425/569] 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 426/569] 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 427/569] 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 428/569] 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 429/569] 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 430/569] 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 431/569] 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 432/569] 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 433/569] 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 434/569] 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 435/569] 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 436/569] 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 437/569] 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 438/569] 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 439/569] 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 440/569] 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 441/569] 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 442/569] 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 443/569] 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 444/569] 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 445/569] 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 446/569] 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 447/569] 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 448/569] 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 449/569] 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 450/569] 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 451/569] 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 452/569] 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 453/569] 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 454/569] [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 455/569] 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 456/569] 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 457/569] 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 458/569] 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 459/569] 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 460/569] 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 461/569] 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 462/569] 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 463/569] 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 464/569] 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 465/569] 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 466/569] 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 467/569] 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 468/569] 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 469/569] 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 470/569] 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 471/569] 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 472/569] 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 473/569] 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 474/569] 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 475/569] 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 476/569] 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 477/569] 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 478/569] 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 479/569] 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 480/569] 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 481/569] 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 482/569] 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 483/569] 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 484/569] 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 485/569] 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 486/569] 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 487/569] 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 488/569] 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 489/569] 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 490/569] 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 491/569] 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 492/569] 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 493/569] 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 494/569] 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 495/569] 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 496/569] 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 497/569] 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 498/569] 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 499/569] 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 500/569] 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 501/569] 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 502/569] 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 503/569] 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 504/569] 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 505/569] 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 506/569] 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 507/569] 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 508/569] 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 509/569] 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 510/569] 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 511/569] 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 512/569] 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 513/569] 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 514/569] 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 515/569] 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 516/569] 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 517/569] 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 518/569] 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 519/569] 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 520/569] 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 521/569] 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 522/569] 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 523/569] 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 524/569] 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 525/569] 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 526/569] 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 527/569] 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 528/569] 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 529/569] 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 530/569] 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 531/569] 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 532/569] 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 533/569] 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 534/569] 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 535/569] 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 536/569] 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 537/569] 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 538/569] 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 539/569] 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 540/569] 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 541/569] 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 542/569] 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 543/569] 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 544/569] 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 545/569] 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 546/569] 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 547/569] 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 548/569] 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 549/569] =?UTF-8?q?fix(notify)=EF=BC=9Aremove=20nofity,mov?= =?UTF-8?q?e=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 550/569] 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 551/569] 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 552/569] 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 553/569] 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 554/569] 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 555/569] 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 556/569] 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 557/569] 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 558/569] 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 0d05f9ba800b94b455d3d57954b5f24db84da709 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 27 Mar 2022 12:08:24 +0800 Subject: [PATCH 559/569] 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 560/569] 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 561/569] 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 562/569] 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 563/569] 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 564/569] 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 565/569] 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 566/569] 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 567/569] typo From 0f607413d08a3e067a4852b27faf096d846854bf Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 3 Apr 2022 20:05:30 +0800 Subject: [PATCH 568/569] 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 569/569] 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"