From c6ec8bc0d9f1db2fb0f90c20a5cfbc0ae552e2f9 Mon Sep 17 00:00:00 2001 From: rewqazxv <41326691+rewqazxv@users.noreply.github.com> Date: Wed, 6 Nov 2019 18:57:05 +0800 Subject: [PATCH 001/190] fix sudo issue --- acme.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 81a20b0b..4a1ce9b7 100755 --- a/acme.sh +++ b/acme.sh @@ -6362,11 +6362,17 @@ _checkSudo() { #it's root using sudo, no matter it's using sudo or not, just fine return 0 fi - if [ "$SUDO_COMMAND" = "/bin/su" ] || [ "$SUDO_COMMAND" = "/bin/bash" ]; then - #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s` - #fine - return 0 - fi + case "$SUDO_COMMAND" in + */su ) + #it's a normal user doing `sudo su`, no problem + return 0 ;; + esac + for i in `cat /etc/shells`; do + if [ "$SUDO_COMMAND" = "$i" ]; then + #it's a normal user running `sudo -i` or `sudo -s`, fine + return 0 + fi + done #otherwise return 1 fi From 6a5ee72722550c76cb925916cfde2f103bda8b40 Mon Sep 17 00:00:00 2001 From: rewqazxv <41326691+rewqazxv@users.noreply.github.com> Date: Wed, 6 Nov 2019 20:27:12 +0800 Subject: [PATCH 002/190] format code style --- acme.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 4a1ce9b7..d3c0fc7a 100755 --- a/acme.sh +++ b/acme.sh @@ -6363,11 +6363,12 @@ _checkSudo() { return 0 fi case "$SUDO_COMMAND" in - */su ) + */su) #it's a normal user doing `sudo su`, no problem - return 0 ;; + return 0 + ;; esac - for i in `cat /etc/shells`; do + for i in $(cat /etc/shells); do if [ "$SUDO_COMMAND" = "$i" ]; then #it's a normal user running `sudo -i` or `sudo -s`, fine return 0 From 79ad0ff56baac1a338d4155e40f77bc8eeae8109 Mon Sep 17 00:00:00 2001 From: rewqazxv <41326691+rewqazxv@users.noreply.github.com> Date: Wed, 15 Jan 2020 22:11:34 +0800 Subject: [PATCH 003/190] Simplify code --- acme.sh | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index d3c0fc7a..00d10fcc 100755 --- a/acme.sh +++ b/acme.sh @@ -6362,18 +6362,11 @@ _checkSudo() { #it's root using sudo, no matter it's using sudo or not, just fine return 0 fi - case "$SUDO_COMMAND" in - */su) - #it's a normal user doing `sudo su`, no problem - return 0 - ;; - esac - for i in $(cat /etc/shells); do - if [ "$SUDO_COMMAND" = "$i" ]; then - #it's a normal user running `sudo -i` or `sudo -s`, fine - return 0 - fi - done + if [ -n "$SUDO_COMMAND" ]; then + #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s` + _endswith "$SUDO_COMMAND" /bin/su || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1 + return $? + fi #otherwise return 1 fi From f5f0680ec768e5978d90aa1a63f1e4c91d04ff06 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 18:49:39 +0200 Subject: [PATCH 004/190] Added support for custom domains --- dnsapi/dns_dynv6.sh | 66 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index cf39282b..4ffd7009 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -13,14 +13,18 @@ dns_dynv6_add() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exists on your dynv6 account" - return 1 + + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -44,14 +48,17 @@ dns_dynv6_rm() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exists on your dynv6 account" - return 1 + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 @@ -72,29 +79,30 @@ _generate_new_key() { return 1 fi } -#Usage: _acme-challenge.www.example.dynv6.net + +#Usage: _acme-challenge.www.example.dynv6.net "$_your_hosts" +#where _your_hosts is the output of ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts #returns #_host= example.dynv6.net #_record=_acme-challenge.www #aborts if not a valid domain _get_domain() { + #_your_hosts="$(ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts)" _full_domain="$1" - _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy'; then - _err "The hosts does not seem to be a dynv6 host" - return 1 - fi - _record="${_full_domain%.*}" - _record="${_record%.*}" - _record="${_record%.*}" - _debug "The record we are ging to use is $_record" - _host="$_full_domain" - while [ "$(echo "$_host" | grep -o '\.' | wc -l)" != "2" ]; do - _host="${_host#*.}" - done - _debug "And the host is $_host" - return 0 + _your_hosts="$2" + _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" + for l in $_your_hosts; do + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi + done + _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" + return 1 } # Usage: No input required @@ -103,7 +111,7 @@ _get_domain() { _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug Your key is "$dynv6_keyfile" + _debug "Your key is $dynv6_keyfile" if [ -z "$dynv6_keyfile" ]; then if [ -z "$KEY" ]; then _err "You did not specify a key to use with dynv6" From 6cc9f49d975a10ea41951de3efad0c2b5a1e2cc0 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 19:09:27 +0200 Subject: [PATCH 005/190] first attempt to make travis happy --- dnsapi/dns_dynv6.sh | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 4ffd7009..dce7ce5f 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,17 +14,10 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -50,19 +43,12 @@ dns_dynv6_rm() { _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 - } #################### Private functions below ################################## #Usage: No Input required @@ -93,13 +79,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 From f5411ac9ab9f40b0501d99132a561605a9e8d714 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:42:45 +0200 Subject: [PATCH 006/190] no supporting HTTP API as well --- dnsapi/dns_dynv6.sh | 263 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 219 insertions(+), 44 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index dce7ce5f..0fd6fa4c 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -1,32 +1,41 @@ #!/usr/bin/env sh #Author StefanAbl #Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"' +#or use the HTTP REST API by by specifying a token 'export DYNV6_TOKEN="value" #if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub + +dynv6_api="https://dynv6.com/api/v2" ######## Public functions ##################### # Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide -#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Usage: dns_dynv6_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dynv6_add() { fulldomain=$1 txtvalue=$2 _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 - fi - _debug "found host on your account" - returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" - _debug "Dynv6 returend this after record was added: $returnval" - if _contains "$returnval" "created"; then - return 0 - elif _contains "$returnval" "updated"; then - return 0 - else - _err "Something went wrong! it does not seem like the record was added succesfully" + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_add_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" + _debug "Dynv6 returned this after record was added: $returnval" + if _contains "$returnval" "created"; then + return 0 + elif _contains "$returnval" "updated"; then + return 0 + else + _err "Something went wrong! it does not seem like the record was added successfully" + return 1 + fi return 1 fi return 1 @@ -36,24 +45,29 @@ dns_dynv6_add() { dns_dynv6_rm() { fulldomain=$1 txtvalue=$2 - _info "Using dynv6 api" + _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_rm_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" + return 0 fi - _debug "found host on your account" - _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" - return 0 } #################### Private functions below ################################## #Usage: No Input required #returns -#dynv6_keyfile the path to the new keyfile that has been generated +#dynv6_keyfile the path to the new key file that has been generated _generate_new_key() { dynv6_keyfile="$(eval echo ~"$USER")/.ssh/dynv6" _info "Path to key file used: $dynv6_keyfile" @@ -94,22 +108,183 @@ _get_domain() { # Usage: No input required #returns #dynv6_keyfile path to the key that will be used -_get_keyfile() { - _debug "get keyfile method called" - dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug "Your key is $dynv6_keyfile" - if [ -z "$dynv6_keyfile" ]; then - if [ -z "$KEY" ]; then - _err "You did not specify a key to use with dynv6" - _info "Creating new dynv6 api key to add to dynv6.com" - _generate_new_key - _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" - _info "Hit Enter to contiue" - read -r _ - #save the credentials to the account conf file. - else - dynv6_keyfile="$KEY" +_get_authentication() { + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else + _debug "no HTTP token found. Looking for an SSH key" + dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" + _debug "Your key is $dynv6_keyfile" + if [ -z "$dynv6_keyfile" ]; then + if [ -z "$KEY" ]; then + _err "You did not specify a key to use with dynv6" + _info "Creating new dynv6 API key to add to dynv6.com" + _generate_new_key + _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" + _info "Hit Enter to continue" + read -r _ + #save the credentials to the account conf file. + else + dynv6_keyfile="$KEY" + fi + _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" fi - _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" fi } + + + +_dns_dynv6_add_http(){ +_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain" ;then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi +} + +_dns_dynv6_rm_http(){ + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain" ;then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ] ; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} + + +#get the zoneid for a specifc record or zone +#usage: _get_zone_id §record +#where $record is the record to get the id for +#returns _zone_id the id of the zone +_get_zone_id(){ + record="$1" + _debug "getting zone id for $record" + _dynv6_rest GET zones + + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" +} + +_get_zone_name(){ + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n'| tr -d '{'|grep name|tr -d '"')" + _zone_name="${_zone_name#name:}" +} + +#usaage _get_record_id $zone_id $record +# where zone_id is thevalue returned by _get_zone_id +# and record ist in the form _acme.www for an fqdn of _acme.www.example.com +# returns _record_id +_get_record_id(){ + _zone_id="$1" + record="$2" + value="$3" + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response" ; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi +} + +_get_record_id_from_response(){ + response="$1" + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id |tr -d '"'|tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 +} +#usage: _set_record TXT _acme_challenge.www longvalue 12345678 +#zone id is optional can also be set as vairable bevor calling this method +_set_record(){ + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" +} +_del_record(){ + _zone_id=$1 + _record_id=$2 + _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" +} + +_dynv6_rest() { + m=$1 #method GET,POST,DELETE or PUT + ep="$2" #the endpoint + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$dynv6_token" | tr -d '"') + + export _H1="Authorization: Bearer $token_trimmed" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" + else + response="$(_get "$dynv6_api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} + From f8c8330258da736f7deb9b5bbdda0f8e734b65a3 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:49:25 +0200 Subject: [PATCH 007/190] formatting --- dnsapi/dns_dynv6.sh | 204 ++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 104 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 0fd6fa4c..c41aef3a 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -18,7 +18,7 @@ dns_dynv6_add() { if [ "$dynv6_token" ]; then _dns_dynv6_add_http return $? - else + else _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -49,10 +49,10 @@ dns_dynv6_rm() { _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" _get_authentication - if [ "$dynv6_token" ]; then + if [ "$dynv6_token" ]; then _dns_dynv6_rm_http return $? - else + else _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -109,14 +109,14 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" - else + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" _debug "Your key is $dynv6_keyfile" @@ -137,142 +137,139 @@ _get_authentication() { fi } - - -_dns_dynv6_add_http(){ -_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain" ;then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _set_record TXT "$record" "$txtvalue" - if _contains "$response" "$txtvalue"; then - _info "Successfully added record" - return 0 - else - _err "Something went wrong while adding the record" - return 1 - fi +_dns_dynv6_add_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi } -_dns_dynv6_rm_http(){ +_dns_dynv6_rm_http() { _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain" ;then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _get_record_id "$_zone_id" "$record" "$txtvalue" - _del_record "$_zone_id" "$_record_id" - if [ -z "$response" ] ; then - _info "Successfully deleted record" - return 0 - else - _err "Something went wrong while deleting the record" - return 1 - fi + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ]; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi } - #get the zoneid for a specifc record or zone #usage: _get_zone_id §record #where $record is the record to get the id for #returns _zone_id the id of the zone -_get_zone_id(){ +_get_zone_id() { record="$1" _debug "getting zone id for $record" _dynv6_rest GET zones - - zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" - #echo $zones - selected="" - for z in $zones; do - z="${z#name:}" - _debug zone: "$z" - if _contains "$record" "$z"; then - _debug "$z found in $record" - selected="$z" - fi - done - if [ -z "$selected" ]; then - _err "no zone found" - return 1 - fi - - zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" - _zone_id="${zone_id#id:}" - _debug "zone id: $_zone_id" + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" } -_get_zone_name(){ - _zone_id="$1" - _dynv6_rest GET zones/"$_zone_id" - _zone_name="$(echo "$response" | tr ',' '\n'| tr -d '{'|grep name|tr -d '"')" - _zone_name="${_zone_name#name:}" +_get_zone_name() { + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" + _zone_name="${_zone_name#name:}" } #usaage _get_record_id $zone_id $record # where zone_id is thevalue returned by _get_zone_id # and record ist in the form _acme.www for an fqdn of _acme.www.example.com # returns _record_id -_get_record_id(){ +_get_record_id() { _zone_id="$1" record="$2" value="$3" - _dynv6_rest GET "zones/$_zone_id/records" - if ! _get_record_id_from_response "$response" ; then - _err "no such record $record found in zone $_zone_id" - return 1 - fi + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response"; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi } -_get_record_id_from_response(){ +_get_record_id_from_response() { response="$1" - _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id |tr -d '"'|tr -d 'id:')" - #_record_id="${_record_id#id:}" - if [ -z "$_record_id" ]; then - _err "no such record: $record found in zone $_zone_id" - return 1 - fi - _debug "record id: $_record_id" - return 0 + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 } #usage: _set_record TXT _acme_challenge.www longvalue 12345678 #zone id is optional can also be set as vairable bevor calling this method -_set_record(){ - type="$1" - record="$2" - value="$3" - if [ "$4" ]; then - _zone_id="$4" - fi - data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" - #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' - echo "$data" - #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" - _dynv6_rest POST "zones/$_zone_id/records" "$data" +_set_record() { + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" } -_del_record(){ +_del_record() { _zone_id=$1 _record_id=$2 _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" } _dynv6_rest() { - m=$1 #method GET,POST,DELETE or PUT + m=$1 #method GET,POST,DELETE or PUT ep="$2" #the endpoint data="$3" _debug "$ep" token_trimmed=$(echo "$dynv6_token" | tr -d '"') - + export _H1="Authorization: Bearer $token_trimmed" export _H2="Content-Type: application/json" - + if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" @@ -287,4 +284,3 @@ _dynv6_rest() { _debug2 response "$response" return 0 } - From 65aa7b10844eeb9b2692e5e2731a4d4eda99d36e Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 16:01:46 +0200 Subject: [PATCH 008/190] formatting --- dnsapi/dns_dynv6.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index c41aef3a..e51e118a 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -109,13 +109,12 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" + dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" + if [ "$dynv6_token" ]; then + _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" + if [ "$DYNV6_TOKEN" ]; then + _saveaccountconf_mutable dynv6_token "$dynv6_token" + fi else _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" From e2a5af1cf7355f0c58d2f64b7c9579a5b6f32dea Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 14 Jul 2020 21:49:50 +0800 Subject: [PATCH 009/190] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 22eaaa86..f766ef2f 100755 --- a/acme.sh +++ b/acme.sh @@ -1039,7 +1039,7 @@ _sign() { _ec_s="0${_ec_s}" done fi - _debug3 "_ec_r" "$_ec_r" + _debug3 "_ec_r" "$_ec_r" _debug3 "_ec_s" "$_ec_s" printf "%s" "$_ec_r$_ec_s" | _h2b | _base64 else From 236e8cc95c28279d292706358e011f790912e1c2 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 15 Jul 2020 21:30:17 +0800 Subject: [PATCH 010/190] add gitads --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 67402f29..73532c65 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + + +acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial + GitAds + + + - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. - Support ACME v1 and ACME v2 From 5c295254bf73ae551869aede25c710efeabfaacb Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 15 Jul 2020 21:31:14 +0800 Subject: [PATCH 011/190] fix format --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 73532c65..0c69fb44 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial + + GitAds From d94f241d3cccf05589ac69d225b3cd4e442e357b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Wed, 15 Jul 2020 20:45:11 +0200 Subject: [PATCH 012/190] Upgrade Travis image --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 91da2731..a9785d0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: shell -dist: trusty +dist: bionic os: - linux From 9b23cd6d1998fada386cb8feeee5e73da578497e Mon Sep 17 00:00:00 2001 From: Andy Botting Date: Mon, 13 Jul 2020 15:53:15 +1000 Subject: [PATCH 013/190] Add OpenStack Barbican deploy support This provider relies on the the python-openstackclient and python-designateclient tools be installed and working, with either password or application credentials loaded in your env. --- deploy/openstack.sh | 262 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 deploy/openstack.sh diff --git a/deploy/openstack.sh b/deploy/openstack.sh new file mode 100644 index 00000000..42cf7848 --- /dev/null +++ b/deploy/openstack.sh @@ -0,0 +1,262 @@ +#!/usr/bin/env sh + +# OpenStack Barbican deploy hook +# +# This requires you to have OpenStackClient and python-barbicanclient +# installed. +# +# You will require Keystone V3 credentials loaded into your environment, which +# could be either password or v3applicationcredential type. +# +# Author: Andy Botting + +openstack_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if ! _exists openstack; then + _err "OpenStack client not found" + return 1 + fi + + _openstack_credentials || return $? + + _info "Generate import pkcs12" + _import_pkcs12="$(_mktemp)" + if ! _openstack_to_pkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca"; then + _err "Error creating pkcs12 certificate" + return 1 + fi + _debug _import_pkcs12 "$_import_pkcs12" + _base64_pkcs12=$(_base64 "multiline" < "$_import_pkcs12") + + secretHrefs=$(_openstack_get_secrets) + _debug secretHrefs "$secretHrefs" + _openstack_store_secret || return $? + + if [ -n "$secretHrefs" ]; then + _info "Cleaning up existing secret" + _openstack_delete_secrets || return $? + fi + + _info "Certificate successfully deployed" + return 0 +} + +_openstack_store_secret() { + if ! openstack secret store --name "$_cdomain." -t 'application/octet-stream' -e base64 --payload "$_base64_pkcs12"; then + _err "Failed to create OpenStack secret" + return 1 + fi + return +} + +_openstack_delete_secrets() { + echo "$secretHrefs" | while read -r secretHref; do + _info "Deleting old secret $secretHref" + if ! openstack secret delete "$secretHref"; then + _err "Failed to delete OpenStack secret" + return 1 + fi + done + return +} + +_openstack_get_secrets() { + if ! secretHrefs=$(openstack secret list -f value --name "$_cdomain." | cut -d' ' -f1); then + _err "Failed to list secrets" + return 1 + fi + echo "$secretHrefs" +} + +_openstack_to_pkcs() { + # The existing _toPkcs command can't allow an empty password, due to sh + # -z test, so copied here and forcing the empty password. + _cpfx="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + + ${ACME_OPENSSL_BIN:-openssl} pkcs12 -export -out "$_cpfx" -inkey "$_ckey" -in "$_ccert" -certfile "$_cca" -password "pass:" +} + +_openstack_credentials() { + _debug "Check OpenStack credentials" + + # If we have OS_AUTH_URL already set in the environment, then assume we want + # to use those, otherwise use stored credentials + if [ -n "$OS_AUTH_URL" ]; then + _debug "OS_AUTH_URL env var found, using environment" + else + _debug "OS_AUTH_URL not found, loading stored credentials" + OS_AUTH_URL="${OS_AUTH_URL:-$(_readaccountconf_mutable OS_AUTH_URL)}" + OS_IDENTITY_API_VERSION="${OS_IDENTITY_API_VERSION:-$(_readaccountconf_mutable OS_IDENTITY_API_VERSION)}" + OS_AUTH_TYPE="${OS_AUTH_TYPE:-$(_readaccountconf_mutable OS_AUTH_TYPE)}" + OS_APPLICATION_CREDENTIAL_ID="${OS_APPLICATION_CREDENTIAL_ID:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID)}" + OS_APPLICATION_CREDENTIAL_SECRET="${OS_APPLICATION_CREDENTIAL_SECRET:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET)}" + OS_USERNAME="${OS_USERNAME:-$(_readaccountconf_mutable OS_USERNAME)}" + OS_PASSWORD="${OS_PASSWORD:-$(_readaccountconf_mutable OS_PASSWORD)}" + OS_PROJECT_NAME="${OS_PROJECT_NAME:-$(_readaccountconf_mutable OS_PROJECT_NAME)}" + OS_PROJECT_ID="${OS_PROJECT_ID:-$(_readaccountconf_mutable OS_PROJECT_ID)}" + OS_USER_DOMAIN_NAME="${OS_USER_DOMAIN_NAME:-$(_readaccountconf_mutable OS_USER_DOMAIN_NAME)}" + OS_USER_DOMAIN_ID="${OS_USER_DOMAIN_ID:-$(_readaccountconf_mutable OS_USER_DOMAIN_ID)}" + OS_PROJECT_DOMAIN_NAME="${OS_PROJECT_DOMAIN_NAME:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_NAME)}" + OS_PROJECT_DOMAIN_ID="${OS_PROJECT_DOMAIN_ID:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_ID)}" + fi + + # Check each var and either save or clear it depending on whether its set. + # The helps us clear out old vars in the case where a user may want + # to switch between password and app creds + _debug "OS_AUTH_URL" "$OS_AUTH_URL" + if [ -n "$OS_AUTH_URL" ]; then + export OS_AUTH_URL + _saveaccountconf_mutable OS_AUTH_URL "$OS_AUTH_URL" + else + unset OS_AUTH_URL + _clearaccountconf SAVED_OS_AUTH_URL + fi + + _debug "OS_IDENTITY_API_VERSION" "$OS_IDENTITY_API_VERSION" + if [ -n "$OS_IDENTITY_API_VERSION" ]; then + export OS_IDENTITY_API_VERSION + _saveaccountconf_mutable OS_IDENTITY_API_VERSION "$OS_IDENTITY_API_VERSION" + else + unset OS_IDENTITY_API_VERSION + _clearaccountconf SAVED_OS_IDENTITY_API_VERSION + fi + + _debug "OS_AUTH_TYPE" "$OS_AUTH_TYPE" + if [ -n "$OS_AUTH_TYPE" ]; then + export OS_AUTH_TYPE + _saveaccountconf_mutable OS_AUTH_TYPE "$OS_AUTH_TYPE" + else + unset OS_AUTH_TYPE + _clearaccountconf SAVED_OS_AUTH_TYPE + fi + + _debug "OS_APPLICATION_CREDENTIAL_ID" "$OS_APPLICATION_CREDENTIAL_ID" + if [ -n "$OS_APPLICATION_CREDENTIAL_ID" ]; then + export OS_APPLICATION_CREDENTIAL_ID + _saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID "$OS_APPLICATION_CREDENTIAL_ID" + else + unset OS_APPLICATION_CREDENTIAL_ID + _clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_ID + fi + + _secure_debug "OS_APPLICATION_CREDENTIAL_SECRET" "$OS_APPLICATION_CREDENTIAL_SECRET" + if [ -n "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then + export OS_APPLICATION_CREDENTIAL_SECRET + _saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET "$OS_APPLICATION_CREDENTIAL_SECRET" + else + unset OS_APPLICATION_CREDENTIAL_SECRET + _clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_SECRET + fi + + _debug "OS_USERNAME" "$OS_USERNAME" + if [ -n "$OS_USERNAME" ]; then + export OS_USERNAME + _saveaccountconf_mutable OS_USERNAME "$OS_USERNAME" + else + unset OS_USERNAME + _clearaccountconf SAVED_OS_USERNAME + fi + + _secure_debug "OS_PASSWORD" "$OS_PASSWORD" + if [ -n "$OS_PASSWORD" ]; then + export OS_PASSWORD + _saveaccountconf_mutable OS_PASSWORD "$OS_PASSWORD" + else + unset OS_PASSWORD + _clearaccountconf SAVED_OS_PASSWORD + fi + + _debug "OS_PROJECT_NAME" "$OS_PROJECT_NAME" + if [ -n "$OS_PROJECT_NAME" ]; then + export OS_PROJECT_NAME + _saveaccountconf_mutable OS_PROJECT_NAME "$OS_PROJECT_NAME" + else + unset OS_PROJECT_NAME + _clearaccountconf SAVED_OS_PROJECT_NAME + fi + + _debug "OS_PROJECT_ID" "$OS_PROJECT_ID" + if [ -n "$OS_PROJECT_ID" ]; then + export OS_PROJECT_ID + _saveaccountconf_mutable OS_PROJECT_ID "$OS_PROJECT_ID" + else + unset OS_PROJECT_ID + _clearaccountconf SAVED_OS_PROJECT_ID + fi + + _debug "OS_USER_DOMAIN_NAME" "$OS_USER_DOMAIN_NAME" + if [ -n "$OS_USER_DOMAIN_NAME" ]; then + export OS_USER_DOMAIN_NAME + _saveaccountconf_mutable OS_USER_DOMAIN_NAME "$OS_USER_DOMAIN_NAME" + else + unset OS_USER_DOMAIN_NAME + _clearaccountconf SAVED_OS_USER_DOMAIN_NAME + fi + + _debug "OS_USER_DOMAIN_ID" "$OS_USER_DOMAIN_ID" + if [ -n "$OS_USER_DOMAIN_ID" ]; then + export OS_USER_DOMAIN_ID + _saveaccountconf_mutable OS_USER_DOMAIN_ID "$OS_USER_DOMAIN_ID" + else + unset OS_USER_DOMAIN_ID + _clearaccountconf SAVED_OS_USER_DOMAIN_ID + fi + + _debug "OS_PROJECT_DOMAIN_NAME" "$OS_PROJECT_DOMAIN_NAME" + if [ -n "$OS_PROJECT_DOMAIN_NAME" ]; then + export OS_PROJECT_DOMAIN_NAME + _saveaccountconf_mutable OS_PROJECT_DOMAIN_NAME "$OS_PROJECT_DOMAIN_NAME" + else + unset OS_PROJECT_DOMAIN_NAME + _clearaccountconf SAVED_OS_PROJECT_DOMAIN_NAME + fi + + _debug "OS_PROJECT_DOMAIN_ID" "$OS_PROJECT_DOMAIN_ID" + if [ -n "$OS_PROJECT_DOMAIN_ID" ]; then + export OS_PROJECT_DOMAIN_ID + _saveaccountconf_mutable OS_PROJECT_DOMAIN_ID "$OS_PROJECT_DOMAIN_ID" + else + unset OS_PROJECT_DOMAIN_ID + _clearaccountconf SAVED_OS_PROJECT_DOMAIN_ID + fi + + if [ "$OS_AUTH_TYPE" = "v3applicationcredential" ]; then + # Application Credential auth + if [ -z "$OS_APPLICATION_CREDENTIAL_ID" ] || [ -z "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then + _err "When using OpenStack application credentials, OS_APPLICATION_CREDENTIAL_ID" + _err "and OS_APPLICATION_CREDENTIAL_SECRET must be set." + _err "Please check your credentials and try again." + return 1 + fi + else + # Password auth + if [ -z "$OS_USERNAME" ] || [ -z "$OS_PASSWORD" ]; then + _err "OpenStack username or password not found." + _err "Please check your credentials and try again." + return 1 + fi + + if [ -z "$OS_PROJECT_NAME" ] && [ -z "$OS_PROJECT_ID" ]; then + _err "When using password authentication, OS_PROJECT_NAME or" + _err "OS_PROJECT_ID must be set." + _err "Please check your credentials and try again." + return 1 + fi + fi + + return 0 +} From aad9afad59fc5efd1c4da2de731324041de4ae76 Mon Sep 17 00:00:00 2001 From: Andy Botting Date: Mon, 13 Jul 2020 13:18:57 +1000 Subject: [PATCH 014/190] Add OpenStack Designate DNS API support This provider relies on the the python-openstackclient and python-designateclient tools be installed and working, with either password or application credentials loaded in your env. --- dnsapi/openstack.sh | 348 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100755 dnsapi/openstack.sh diff --git a/dnsapi/openstack.sh b/dnsapi/openstack.sh new file mode 100755 index 00000000..38619e6f --- /dev/null +++ b/dnsapi/openstack.sh @@ -0,0 +1,348 @@ +#!/usr/bin/env sh + +# OpenStack Designate API plugin +# +# This requires you to have OpenStackClient and python-desginateclient +# installed. +# +# You will require Keystone V3 credentials loaded into your environment, which +# could be either password or v3applicationcredential type. +# +# Author: Andy Botting + +######## Public functions ##################### + +# Usage: dns_openstack_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_openstack_add() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _dns_openstack_credentials || return $? + _dns_openstack_check_setup || return $? + _dns_openstack_find_zone || return $? + _dns_openstack_get_recordset || return $? + _debug _recordset_id "$_recordset_id" + if [ -n "$_recordset_id" ]; then + _dns_openstack_get_records || return $? + _debug _records "$_records" + fi + _dns_openstack_create_recordset || return $? +} + +# Usage: dns_openstack_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Remove the txt record after validation. +dns_openstack_rm() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _dns_openstack_credentials || return $? + _dns_openstack_check_setup || return $? + _dns_openstack_find_zone || return $? + _dns_openstack_get_recordset || return $? + _debug _recordset_id "$_recordset_id" + if [ -n "$_recordset_id" ]; then + _dns_openstack_get_records || return $? + _debug _records "$_records" + fi + _dns_openstack_delete_recordset || return $? +} + +#################### Private functions below ################################## + +_dns_openstack_create_recordset() { + + if [ -z "$_recordset_id" ]; then + _info "Creating a new recordset" + if ! _recordset_id=$(openstack recordset create -c id -f value --type TXT --record "$txtvalue" "$_zone_id" "$fulldomain."); then + _err "No recordset ID found after create" + return 1 + fi + else + _info "Updating existing recordset" + # Build new list of --record args for update + _record_args="--record $txtvalue" + for _rec in $_records; do + _record_args="$_record_args --record $_rec" + done + # shellcheck disable=SC2086 + if ! _recordset_id=$(openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain."); then + _err "Recordset update failed" + return 1 + fi + fi + + _max_retries=60 + _sleep_sec=5 + _retry_times=0 + while [ "$_retry_times" -lt "$_max_retries" ]; do + _retry_times=$(_math "$_retry_times" + 1) + _debug3 _retry_times "$_retry_times" + + _record_status=$(openstack recordset show -c status -f value "$_zone_id" "$_recordset_id") + _info "Recordset status is $_record_status" + if [ "$_record_status" = "ACTIVE" ]; then + return 0 + elif [ "$_record_status" = "ERROR" ]; then + return 1 + else + _sleep $_sleep_sec + fi + done + + _err "Recordset failed to become ACTIVE" + return 1 +} + +_dns_openstack_delete_recordset() { + + if [ "$_records" = "$txtvalue" ]; then + _info "Only one record found, deleting recordset" + if ! openstack recordset delete "$_zone_id" "$fulldomain." >/dev/null; then + _err "Failed to delete recordset" + return 1 + fi + else + _info "Found existing records, updating recordset" + # Build new list of --record args for update + _record_args="" + for _rec in $_records; do + if [ "$_rec" = "$txtvalue" ]; then + continue + fi + _record_args="$_record_args --record $_rec" + done + # shellcheck disable=SC2086 + if ! openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain." >/dev/null; then + _err "Recordset update failed" + return 1 + fi + fi +} + +_dns_openstack_get_root() { + # Take the full fqdn and strip away pieces until we get an exact zone name + # match. For example, _acme-challenge.something.domain.com might need to go + # into something.domain.com or domain.com + _zone_name=$1 + _zone_list=$2 + while [ "$_zone_name" != "" ]; do + _zone_name="$(echo "$_zone_name" | sed 's/[^.]*\.*//')" + echo "$_zone_list" | while read -r id name; do + if _startswith "$_zone_name." "$name"; then + echo "$id" + fi + done + done | _head_n 1 +} + +_dns_openstack_find_zone() { + if ! _zone_list="$(openstack zone list -c id -c name -f value)"; then + _err "Can't list zones. Check your OpenStack credentials" + return 1 + fi + _debug _zone_list "$_zone_list" + + if ! _zone_id="$(_dns_openstack_get_root "$fulldomain" "$_zone_list")"; then + _err "Can't find a matching zone. Check your OpenStack credentials" + return 1 + fi + _debug _zone_id "$_zone_id" +} + +_dns_openstack_get_records() { + if ! _records=$(openstack recordset show -c records -f value "$_zone_id" "$fulldomain."); then + _err "Failed to get records" + return 1 + fi + return 0 +} + +_dns_openstack_get_recordset() { + if ! _recordset_id=$(openstack recordset list -c id -f value --name "$fulldomain." "$_zone_id"); then + _err "Failed to get recordset" + return 1 + fi + return 0 +} + +_dns_openstack_check_setup() { + if ! _exists openstack; then + _err "OpenStack client not found" + return 1 + fi +} + +_dns_openstack_credentials() { + _debug "Check OpenStack credentials" + + # If we have OS_AUTH_URL already set in the environment, then assume we want + # to use those, otherwise use stored credentials + if [ -n "$OS_AUTH_URL" ]; then + _debug "OS_AUTH_URL env var found, using environment" + else + _debug "OS_AUTH_URL not found, loading stored credentials" + OS_AUTH_URL="${OS_AUTH_URL:-$(_readaccountconf_mutable OS_AUTH_URL)}" + OS_IDENTITY_API_VERSION="${OS_IDENTITY_API_VERSION:-$(_readaccountconf_mutable OS_IDENTITY_API_VERSION)}" + OS_AUTH_TYPE="${OS_AUTH_TYPE:-$(_readaccountconf_mutable OS_AUTH_TYPE)}" + OS_APPLICATION_CREDENTIAL_ID="${OS_APPLICATION_CREDENTIAL_ID:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID)}" + OS_APPLICATION_CREDENTIAL_SECRET="${OS_APPLICATION_CREDENTIAL_SECRET:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET)}" + OS_USERNAME="${OS_USERNAME:-$(_readaccountconf_mutable OS_USERNAME)}" + OS_PASSWORD="${OS_PASSWORD:-$(_readaccountconf_mutable OS_PASSWORD)}" + OS_PROJECT_NAME="${OS_PROJECT_NAME:-$(_readaccountconf_mutable OS_PROJECT_NAME)}" + OS_PROJECT_ID="${OS_PROJECT_ID:-$(_readaccountconf_mutable OS_PROJECT_ID)}" + OS_USER_DOMAIN_NAME="${OS_USER_DOMAIN_NAME:-$(_readaccountconf_mutable OS_USER_DOMAIN_NAME)}" + OS_USER_DOMAIN_ID="${OS_USER_DOMAIN_ID:-$(_readaccountconf_mutable OS_USER_DOMAIN_ID)}" + OS_PROJECT_DOMAIN_NAME="${OS_PROJECT_DOMAIN_NAME:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_NAME)}" + OS_PROJECT_DOMAIN_ID="${OS_PROJECT_DOMAIN_ID:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_ID)}" + fi + + # Check each var and either save or clear it depending on whether its set. + # The helps us clear out old vars in the case where a user may want + # to switch between password and app creds + _debug "OS_AUTH_URL" "$OS_AUTH_URL" + if [ -n "$OS_AUTH_URL" ]; then + export OS_AUTH_URL + _saveaccountconf_mutable OS_AUTH_URL "$OS_AUTH_URL" + else + unset OS_AUTH_URL + _clearaccountconf SAVED_OS_AUTH_URL + fi + + _debug "OS_IDENTITY_API_VERSION" "$OS_IDENTITY_API_VERSION" + if [ -n "$OS_IDENTITY_API_VERSION" ]; then + export OS_IDENTITY_API_VERSION + _saveaccountconf_mutable OS_IDENTITY_API_VERSION "$OS_IDENTITY_API_VERSION" + else + unset OS_IDENTITY_API_VERSION + _clearaccountconf SAVED_OS_IDENTITY_API_VERSION + fi + + _debug "OS_AUTH_TYPE" "$OS_AUTH_TYPE" + if [ -n "$OS_AUTH_TYPE" ]; then + export OS_AUTH_TYPE + _saveaccountconf_mutable OS_AUTH_TYPE "$OS_AUTH_TYPE" + else + unset OS_AUTH_TYPE + _clearaccountconf SAVED_OS_AUTH_TYPE + fi + + _debug "OS_APPLICATION_CREDENTIAL_ID" "$OS_APPLICATION_CREDENTIAL_ID" + if [ -n "$OS_APPLICATION_CREDENTIAL_ID" ]; then + export OS_APPLICATION_CREDENTIAL_ID + _saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID "$OS_APPLICATION_CREDENTIAL_ID" + else + unset OS_APPLICATION_CREDENTIAL_ID + _clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_ID + fi + + _secure_debug "OS_APPLICATION_CREDENTIAL_SECRET" "$OS_APPLICATION_CREDENTIAL_SECRET" + if [ -n "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then + export OS_APPLICATION_CREDENTIAL_SECRET + _saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET "$OS_APPLICATION_CREDENTIAL_SECRET" + else + unset OS_APPLICATION_CREDENTIAL_SECRET + _clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_SECRET + fi + + _debug "OS_USERNAME" "$OS_USERNAME" + if [ -n "$OS_USERNAME" ]; then + export OS_USERNAME + _saveaccountconf_mutable OS_USERNAME "$OS_USERNAME" + else + unset OS_USERNAME + _clearaccountconf SAVED_OS_USERNAME + fi + + _secure_debug "OS_PASSWORD" "$OS_PASSWORD" + if [ -n "$OS_PASSWORD" ]; then + export OS_PASSWORD + _saveaccountconf_mutable OS_PASSWORD "$OS_PASSWORD" + else + unset OS_PASSWORD + _clearaccountconf SAVED_OS_PASSWORD + fi + + _debug "OS_PROJECT_NAME" "$OS_PROJECT_NAME" + if [ -n "$OS_PROJECT_NAME" ]; then + export OS_PROJECT_NAME + _saveaccountconf_mutable OS_PROJECT_NAME "$OS_PROJECT_NAME" + else + unset OS_PROJECT_NAME + _clearaccountconf SAVED_OS_PROJECT_NAME + fi + + _debug "OS_PROJECT_ID" "$OS_PROJECT_ID" + if [ -n "$OS_PROJECT_ID" ]; then + export OS_PROJECT_ID + _saveaccountconf_mutable OS_PROJECT_ID "$OS_PROJECT_ID" + else + unset OS_PROJECT_ID + _clearaccountconf SAVED_OS_PROJECT_ID + fi + + _debug "OS_USER_DOMAIN_NAME" "$OS_USER_DOMAIN_NAME" + if [ -n "$OS_USER_DOMAIN_NAME" ]; then + export OS_USER_DOMAIN_NAME + _saveaccountconf_mutable OS_USER_DOMAIN_NAME "$OS_USER_DOMAIN_NAME" + else + unset OS_USER_DOMAIN_NAME + _clearaccountconf SAVED_OS_USER_DOMAIN_NAME + fi + + _debug "OS_USER_DOMAIN_ID" "$OS_USER_DOMAIN_ID" + if [ -n "$OS_USER_DOMAIN_ID" ]; then + export OS_USER_DOMAIN_ID + _saveaccountconf_mutable OS_USER_DOMAIN_ID "$OS_USER_DOMAIN_ID" + else + unset OS_USER_DOMAIN_ID + _clearaccountconf SAVED_OS_USER_DOMAIN_ID + fi + + _debug "OS_PROJECT_DOMAIN_NAME" "$OS_PROJECT_DOMAIN_NAME" + if [ -n "$OS_PROJECT_DOMAIN_NAME" ]; then + export OS_PROJECT_DOMAIN_NAME + _saveaccountconf_mutable OS_PROJECT_DOMAIN_NAME "$OS_PROJECT_DOMAIN_NAME" + else + unset OS_PROJECT_DOMAIN_NAME + _clearaccountconf SAVED_OS_PROJECT_DOMAIN_NAME + fi + + _debug "OS_PROJECT_DOMAIN_ID" "$OS_PROJECT_DOMAIN_ID" + if [ -n "$OS_PROJECT_DOMAIN_ID" ]; then + export OS_PROJECT_DOMAIN_ID + _saveaccountconf_mutable OS_PROJECT_DOMAIN_ID "$OS_PROJECT_DOMAIN_ID" + else + unset OS_PROJECT_DOMAIN_ID + _clearaccountconf SAVED_OS_PROJECT_DOMAIN_ID + fi + + if [ "$OS_AUTH_TYPE" = "v3applicationcredential" ]; then + # Application Credential auth + if [ -z "$OS_APPLICATION_CREDENTIAL_ID" ] || [ -z "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then + _err "When using OpenStack application credentials, OS_APPLICATION_CREDENTIAL_ID" + _err "and OS_APPLICATION_CREDENTIAL_SECRET must be set." + _err "Please check your credentials and try again." + return 1 + fi + else + # Password auth + if [ -z "$OS_USERNAME" ] || [ -z "$OS_PASSWORD" ]; then + _err "OpenStack username or password not found." + _err "Please check your credentials and try again." + return 1 + fi + + if [ -z "$OS_PROJECT_NAME" ] && [ -z "$OS_PROJECT_ID" ]; then + _err "When using password authentication, OS_PROJECT_NAME or" + _err "OS_PROJECT_ID must be set." + _err "Please check your credentials and try again." + return 1 + fi + fi + + return 0 +} From 3ce967d8e52df4d934fda63363953311f31d3932 Mon Sep 17 00:00:00 2001 From: Andy Botting Date: Thu, 16 Jul 2020 13:53:21 +1000 Subject: [PATCH 015/190] Fix CI test failure for deploy/openstack.sh --- deploy/openstack.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/openstack.sh b/deploy/openstack.sh index 42cf7848..f2058853 100644 --- a/deploy/openstack.sh +++ b/deploy/openstack.sh @@ -37,7 +37,7 @@ openstack_deploy() { return 1 fi _debug _import_pkcs12 "$_import_pkcs12" - _base64_pkcs12=$(_base64 "multiline" < "$_import_pkcs12") + _base64_pkcs12=$(_base64 "multiline" <"$_import_pkcs12") secretHrefs=$(_openstack_get_secrets) _debug secretHrefs "$secretHrefs" From 61613bee98b5d69c054f2842d01b71cb9bf2b890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:13:15 +0200 Subject: [PATCH 016/190] Fix SC2230 --- deploy/vault_cli.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/vault_cli.sh b/deploy/vault_cli.sh index 5395d87e..8b854137 100644 --- a/deploy/vault_cli.sh +++ b/deploy/vault_cli.sh @@ -43,7 +43,7 @@ vault_cli_deploy() { return 1 fi - VAULT_CMD=$(which vault) + VAULT_CMD=$(command -v vault) if [ ! $? ]; then _err "cannot find vault binary!" return 1 From fe4111a9f52382b138af2536426dab3c2588b79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:14:50 +0200 Subject: [PATCH 017/190] Fix SC2236 --- dnsapi/dns_cloudns.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_cloudns.sh b/dnsapi/dns_cloudns.sh index df824e86..381d17ec 100755 --- a/dnsapi/dns_cloudns.sh +++ b/dnsapi/dns_cloudns.sh @@ -69,7 +69,7 @@ dns_cloudns_rm() { for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g') - if [ ! -z "$record_id" ]; then + if [ -n "$record_id" ]; then _debug zone "$zone" _debug host "$host" _debug record "$record" @@ -91,7 +91,7 @@ dns_cloudns_rm() { #################### Private functions below ################################## _dns_cloudns_init_check() { - if [ ! -z "$CLOUDNS_INIT_CHECK_COMPLETED" ]; then + if [ -n "$CLOUDNS_INIT_CHECK_COMPLETED" ]; then return 0 fi @@ -164,7 +164,7 @@ _dns_cloudns_http_api_call() { _debug CLOUDNS_SUB_AUTH_ID "$CLOUDNS_SUB_AUTH_ID" _debug CLOUDNS_AUTH_PASSWORD "$CLOUDNS_AUTH_PASSWORD" - if [ ! -z "$CLOUDNS_SUB_AUTH_ID" ]; then + if [ -n "$CLOUDNS_SUB_AUTH_ID" ]; then auth_user="sub-auth-id=$CLOUDNS_SUB_AUTH_ID" else auth_user="auth-id=$CLOUDNS_AUTH_ID" From 49094120d927d4e846555564fb292212f4899a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:17:11 +0200 Subject: [PATCH 018/190] Fix SC2236 --- dnsapi/dns_cyon.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cyon.sh b/dnsapi/dns_cyon.sh index 8db3011d..2dca90c0 100644 --- a/dnsapi/dns_cyon.sh +++ b/dnsapi/dns_cyon.sh @@ -66,7 +66,7 @@ _cyon_load_credentials() { _debug "Save credentials to account.conf" _saveaccountconf CY_Username "${CY_Username}" _saveaccountconf CY_Password_B64 "$CY_Password_B64" - if [ ! -z "${CY_OTP_Secret}" ]; then + if [ -n "${CY_OTP_Secret}" ]; then _saveaccountconf CY_OTP_Secret "$CY_OTP_Secret" else _clearaccountconf CY_OTP_Secret @@ -164,7 +164,7 @@ _cyon_login() { # todo: instead of just checking if the env variable is defined, check if we actually need to do a 2FA auth request. # 2FA authentication with OTP? - if [ ! -z "${CY_OTP_Secret}" ]; then + if [ -n "${CY_OTP_Secret}" ]; then _info " - Authorising with OTP code..." if ! _exists oathtool; then From 14089f8c6af3c8808702e4f58801deb10e492ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:18:12 +0200 Subject: [PATCH 019/190] Fix SC2236 --- dnsapi/dns_dgon.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh index 515e87d5..ac14da48 100755 --- a/dnsapi/dns_dgon.sh +++ b/dnsapi/dns_dgon.sh @@ -122,12 +122,12 @@ dns_dgon_rm() { ## check for what we are looking for: "type":"A","name":"$_sub_domain" record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")" - if [ ! -z "$record" ]; then + if [ -n "$record" ]; then ## we found records rec_ids="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")" _debug rec_ids "$rec_ids" - if [ ! -z "$rec_ids" ]; then + if [ -n "$rec_ids" ]; then echo "$rec_ids" | while IFS= read -r rec_id; do ## delete the record ## delete URL for removing the one we dont want @@ -218,7 +218,7 @@ _get_base_domain() { ## we got part of a domain back - grep it out found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")" ## check if it exists - if [ ! -z "$found" ]; then + if [ -n "$found" ]; then ## exists - exit loop returning the parts sub_point=$(_math $i - 1) _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point") From eb9005ad744224e54b291532328b52d8d87e3431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Thu, 16 Jul 2020 06:18:46 +0200 Subject: [PATCH 020/190] Fix SC2236 --- dnsapi/dns_yandex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index 5721f994..0a2c3330 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -25,7 +25,7 @@ dns_yandex_add() { _PDD_get_record_ids || return 1 _debug "Record_ids: $record_ids" - if [ ! -z "$record_ids" ]; then + if [ -n "$record_ids" ]; then _info "All existing $subdomain records from $domain will be removed at the very end." fi From f18f4c69f26a8606e6f95754ebebdc762242a88d Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Thu, 23 Jul 2020 13:53:53 +0100 Subject: [PATCH 021/190] Adds Docker multi-arch build support --- .github/workflows/dockerhub.yml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index f1c0025d..7b44f938 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -8,9 +8,19 @@ jobs: build: runs-on: ubuntu-latest steps: - - name: trigger - run: curl -X POST https://hub.docker.com/api/build/v1/source/1813a660-2ee5-4583-a238-dd54e9a6ebac/trigger/c8cd9f1f-f269-45bc-9750-a08327257f62/call/ - - - - + - name: checkout code + uses: actions/checkout@v2 + - name: install buildx + id: buildx + uses: crazy-max/ghaction-docker-buildx@v1 + with: + version: latest + - name: login to docker hub + run: | + echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin + - name: build the image + run: | + docker buildx build \ + --push \ + --tag neilpang/acme.sh:latest \ + --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . From 67360e93b8564228035b4a7604d3c70e887ff6e7 Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 24 Jul 2020 09:25:58 +0100 Subject: [PATCH 022/190] Correctly labels Docker images per branch --- .github/workflows/dockerhub.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 7b44f938..8c277827 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -18,9 +18,17 @@ jobs: - name: login to docker hub run: | echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - - name: build the image + - name: build and push the image (master branch) run: | docker buildx build \ --push \ --tag neilpang/acme.sh:latest \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . + if: ${{ github.ref == 'refs/heads/master' }} + - name: build and push the image (dev branch) + run: | + docker buildx build \ + --push \ + --tag neilpang/acme.sh:dev \ + --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . + if: ${{ github.ref == 'refs/heads/dev' }} From 6a0ed51f5ee7c1af00652890b34603dc5f4d201d Mon Sep 17 00:00:00 2001 From: Adrian Fedoreanu Date: Fri, 24 Jul 2020 16:28:34 +0200 Subject: [PATCH 023/190] replace response equals with contains --- dnsapi/dns_1984hosting.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 09f02796..bcb675ab 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -3,7 +3,7 @@ #So, here must be a method dns_1984hosting_add() #Which will be called by acme.sh to add the txt record to your api system. #returns 0 means success, otherwise error. -# + #Author: Adrian Fedoreanu #Report Bugs here: https://github.com/acmesh-official/acme.sh # or here... https://github.com/acmesh-official/acme.sh/issues/2851 @@ -100,7 +100,7 @@ _1984hosting_add_txt_record() { elif _contains "$response" ""; then _err "1984Hosting failed to add TXT record for $subdomain. Check $HTTP_HEADER file" return 1 - elif [ "$response" = '{"auth": false, "ok": false}' ]; then + elif _contains "$response" '"auth": false'; then _err "1984Hosting failed to add TXT record for $subdomain. Invalid or expired cookie" return 1 fi @@ -167,7 +167,7 @@ _1984hosting_login() { response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" - if [ "$response" = '{"loggedin": true, "ok": true}' ]; then + if _contains "$response" '"loggedin": true'; then One984HOSTING_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" export One984HOSTING_COOKIE _saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE" @@ -196,7 +196,7 @@ _check_cookie() { _authget "https://management.1984hosting.com/accounts/loginstatus/" response="$(echo "$_response" | _normalizeJson)" - if [ "$_response" = '{"ok": true}' ]; then + if _contains "$response" '"ok": true'; then _debug "Cached cookie still valid" return 0 fi From 4b35aef728eb3d35f3faac08f44e0615b6797e3e Mon Sep 17 00:00:00 2001 From: 12bbf7608ae1 <33011786+pdxgf1208@users.noreply.github.com> Date: Sat, 25 Jul 2020 21:48:11 +0800 Subject: [PATCH 024/190] Update dns_dynv6.sh Add support for domains like '*.v6.rocks' --- dnsapi/dns_dynv6.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 819372c2..50eda74b 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -80,7 +80,7 @@ _generate_new_key() { _get_domain() { _full_domain="$1" _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy'; then + if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks' ; then _err "The hosts does not seem to be a dynv6 host" return 1 fi From 5f5096e1d40f17acd414f20d582f43a634831e56 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 25 Jul 2020 21:48:35 -0600 Subject: [PATCH 025/190] Addressing issues found in DS218+ DSM DS218+ appears to have a slighly different DSM that sends back headers in lowercase. Reported by @BartSiwek in #2727 --- deploy/synology_dsm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index c57d50bc..2ec0ceb3 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -22,7 +22,7 @@ ######## Public functions ##################### _syno_get_cookie_data() { - grep "\W$1=" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' + grep -i "\W$1=" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' } #domain keyfile certfile cafile fullchain @@ -79,7 +79,7 @@ synology_dsm_deploy() { encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" encoded_did="$(printf "%s" "$SYNO_DID" | _url_encode)" response=$(_get "$_base_url/webman/login.cgi?username=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_id=$encoded_did" 1) - token=$(echo "$response" | grep "X-SYNO-TOKEN:" | sed -n 's/^X-SYNO-TOKEN: \(.*\)$/\1/p' | tr -d "\r\n") + token=$(echo "$response" | grep -i "X-SYNO-TOKEN:" | sed -n 's/^X-SYNO-TOKEN: \(.*\)$/\1/pI' | tr -d "\r\n") _debug3 response "$response" _debug token "$token" From 4f3f4e23e4f9ca5c11d381c435944c9229128f74 Mon Sep 17 00:00:00 2001 From: Vinton Huang Date: Mon, 27 Jul 2020 03:55:07 +0800 Subject: [PATCH 026/190] Fix failed test in acmetest. Item alpine:latest - test 12: le_test_standandalone_deactivate_v2 - Message of failed test [1]: /root/.acme.sh/acme.sh --deactivate -d testdocker.acme.sh [FAIL] - Reason of failure: left brace was not escaped. According to the standard [2], if special chars appear first in an ERE, it will produce undefined results. - egrep from busybox (and thus alpine) take it as an error, but egrep from GNU grep (included in most distros) and *BSD are more tolerant, just ignore it. - Fix: consider the right brace at the right-hand side of the ERE, the result string will not contain right brace. So the left-hand side should not contain left brace, too. [1] https://github.com/acmesh-official/acmetest/blob/446939706e07c26267d83f71e4d0b8b152b0d3de/logs/alpine-latest.out#L119 [2] 9.4.3 ERE Special Characters, The Open Group Base Specifications. https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index f766ef2f..04c60ee6 100755 --- a/acme.sh +++ b/acme.sh @@ -5642,7 +5642,7 @@ _deactivate() { _URL_NAME="uri" fi - entries="$(echo "$response" | _egrep_o "{ *\"type\":\"[^\"]*\", *\"status\": *\"valid\", *\"$_URL_NAME\"[^}]*")" + entries="$(echo "$response" | _egrep_o "[^{]*\"type\":\"[^\"]*\", *\"status\": *\"valid\", *\"$_URL_NAME\"[^}]*")" if [ -z "$entries" ]; then _info "No valid entries found." if [ -z "$thumbprint" ]; then From f190de39a6de6451a3922b745cc825898595f20b Mon Sep 17 00:00:00 2001 From: JP Mens Date: Mon, 27 Jul 2020 14:34:35 +0200 Subject: [PATCH 027/190] Remove unecessary word from README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c69fb44..7e49a714 100644 --- a/README.md +++ b/README.md @@ -309,7 +309,7 @@ https://github.com/acmesh-official/acme.sh/wiki/dnsapi See: https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode first. -If your dns provider doesn't support any api access, you can add the txt record by your hand. +If your dns provider doesn't support any api access, you can add the txt record by hand. ```bash acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com From 1f5cafc2d15eb60fef724f1854d731725b6d2bd2 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Tue, 28 Jul 2020 09:32:15 +0800 Subject: [PATCH 028/190] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0c69fb44..953b2c0e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") +[![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial From 5207e111e112cee233911873c21323d43db92bd5 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Sun, 2 Aug 2020 00:19:28 +0200 Subject: [PATCH 029/190] initial kapper.net DNS API support hopefully this time we get it right ;) Co-Authored-By: Harald Kapper --- dnsapi/dns_kappernet.sh | 141 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 dnsapi/dns_kappernet.sh diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh new file mode 100644 index 00000000..71dae73d --- /dev/null +++ b/dnsapi/dns_kappernet.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env sh + +# kapper.net domain api +# for further questions please contact: support@kapper.net + +#KAPPERNETDNS_Key="yourKAPPERNETapikey" +#KAPPERNETDNS_Secret="yourKAPPERNETapisecret" + +KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.1?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" + +############################################################################### +# called with +# fullhostname: something.example.com +# txtvalue: someacmegenerated string +dns_kappernet_add() { + fullhostname=$1 + txtvalue=$2 + + if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then + KAPPERNETDNS_Key="" + KAPPERNETDNS_Secret="" + _err "You haven't defined kapper.net api key and secret yet." + _err "Please send us mail to support@kapper.net get your key and secret." + return 1 + fi + + #store the api key and email to the account conf file. + _saveaccountconf KAPPERNETDNS_Key "$KAPPERNETDNS_Key" + _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" + _debug "Checking Domain ..." + if ! _get_root "$fullhostname"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "SUBDOMAIN: $_sub_domain" + _debug _domain "DOMAIN: $_domain" + + _info "Trying to add TXT DNS Record" + data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" + if _kappernet_api GET "action=new&subject=$_domain&data=$data"; then + + if _contains "$response" "{\"OK\":true"; then + _info "Waiting 120 seconds for DNS to spread the new record" + _sleep 120 + return 0 + else + _err "Error creating a TXT DNS Record: $fullhostname TXT $txtvalue" + _err "Error Message: $response" + return 1 + fi + fi + _err "Failed creating TXT Record" +} + +############################################################################### +# called with +# fullhostname: something.example.com +dns_kappernet_rm() { + fullhostname=$1 + txtvalue=$2 + + if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then + KAPPERNETDNS_Key="" + KAPPERNETDNS_Secret="" + _err "You haven't defined kapper.net api key and secret yet." + _err "Please send us mail to get your key and secret." + return 1 + fi + + #store the api key and email to the account conf file. + _saveaccountconf KAPPERNETDNS_Key "$KAPPERNETDNS_Key" + _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" + + _info "Trying to remove the TXT Record: $fullhostname" + + if _kappernet_api GET "action=del&subject=$fullhostname"; then + if _contains "$response" "{\"OK\":true"; then + return 0 + else + _err "Error deleting DNS Record: $fullhostname" + _err "Problem: $response" + return 1 + fi + fi + _err "Problem creating TXT DNS record" +} + +#################### Private functions below ################################## +# called with hostname +# e.g._acme-challenge.www.domain.com returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + if ! _kappernet_api GET "action=list&subject=$h"; then + return 1 + fi + if _contains "$response" '"OK":false'; then + _debug "$h not found" + else + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +################################################################################ +# calls the kapper.net DNS Panel API +# with +# method +# param +_kappernet_api() { + method=$1 + param="$2" + + _debug param "PARAMETER=$param" + url="$KAPPERNETDNS_Api&$param" + _debug url "URL=$url" + + if [ "$method" = "GET" ]; then + response="$(_get "$url")" + else + _err "Unsupported method" + return 1 + fi + + _debug2 response "$response" + return 0 +} From 494a1603e4a49cc894ac9a9a239e1fc29dc99fd1 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Sun, 2 Aug 2020 01:41:26 +0200 Subject: [PATCH 030/190] Update dns_kappernet.sh add issue-link in sourcecode Co-Authored-By: Harald Kapper --- dnsapi/dns_kappernet.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 71dae73d..75450549 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -2,6 +2,7 @@ # kapper.net domain api # for further questions please contact: support@kapper.net +# please report issues here: https://github.com/acmesh-official/acme.sh/issues/2977 #KAPPERNETDNS_Key="yourKAPPERNETapikey" #KAPPERNETDNS_Secret="yourKAPPERNETapisecret" From 2ba6a85eca0ab2aa1fe869f37639d87a9d22eb28 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Sun, 2 Aug 2020 15:59:46 +0200 Subject: [PATCH 031/190] fix multiple txt-records delete + API update new API version fix to delete specific TXT records for wildcard-certs with LE Co-Authored-By: Harald Kapper --- dnsapi/dns_kappernet.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 75450549..a059447a 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -7,7 +7,7 @@ #KAPPERNETDNS_Key="yourKAPPERNETapikey" #KAPPERNETDNS_Secret="yourKAPPERNETapisecret" -KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.1?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" +KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" ############################################################################### # called with @@ -73,8 +73,8 @@ dns_kappernet_rm() { _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" _info "Trying to remove the TXT Record: $fullhostname" - - if _kappernet_api GET "action=del&subject=$fullhostname"; then + data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" + if _kappernet_api GET "action=del&subject=$fullhostname&data=$data"; then if _contains "$response" "{\"OK\":true"; then return 0 else From 40cda9220aa3902b11cb9f38a7dc38b3efd89fc1 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 3 Aug 2020 21:22:32 +0800 Subject: [PATCH 032/190] fix https://github.com/acmesh-official/acme.sh/issues/3077 --- dnsapi/dns_azure.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index bf7cf2bf..28b6572a 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -172,7 +172,7 @@ dns_azure_rm() { _azure_rest GET "$acmeRecordURI" "" "$accesstoken" timestamp="$(_time)" if [ "$_code" = "200" ]; then - vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"" | grep -v "$txtvalue")" + vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"" | grep -v -- "$txtvalue")" values="" comma="" for v in $vlist; do From e8bcde31b778ecf1d3c880805b99c3caf322ccc2 Mon Sep 17 00:00:00 2001 From: Draevin Luke Date: Tue, 4 Aug 2020 16:33:24 -0700 Subject: [PATCH 033/190] Add Netlify API support --- dnsapi/dns_netlify.sh | 160 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 dnsapi/dns_netlify.sh diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh new file mode 100644 index 00000000..4da97f48 --- /dev/null +++ b/dnsapi/dns_netlify.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env sh + +#NETLIFY_ACCESS_TOKEN="xxxx" + +NETLIFY_HOST="api.netlify.com/api/v1/" +NETLIFY_URL="https://$NETLIFY_HOST" + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_netlify_add() { + fulldomain=$1 + txtvalue=$2 + + NETLIFY_ACCESS_TOKEN="${NETLIFY_ACCESS_TOKEN:-$(_readaccountconf_mutable NETLIFY_ACCESS_TOKEN)}" + + if [ -z "$NETLIFY_ACCESS_TOKEN" ]; then + NETLIFY_ACCESS_TOKEN="" + _err "Please specify your Netlify Access Token and try again." + return 1 + fi + + _info "Using Netlify" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN" + + if ! _get_root "$fulldomain" "$accesstoken"; then + _err "invalid domain" + return 1 + fi + + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + dnsRecordURI="dns_zones/$_domain_id/dns_records" + + body="{\"type\":\"TXT\", \"hostname\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"ttl\":\"10\"}" + + _netlify_rest POST "$dnsRecordURI" "$body" "$NETLIFY_ACCESS_TOKEN" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then + _info "validation value added" + return 0 + else + _err "error adding validation value ($_code)" + return 1 + fi + + _err "Not fully implemented!" + return 1 +} + +#Usage: dns_myapi_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Remove the txt record after validation. +dns_netlify_rm() { + _info "Using Netlify" + _debug txtdomain "$txtdomain" + _debug txt "$txt" + + _saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN" + + if ! _get_root "$txtdomain" "$accesstoken"; then + _err "invalid domain" + return 1 + fi + + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + dnsRecordURI="dns_zones/$_domain_id/dns_records" + + _netlify_rest GET "$dnsRecordURI" "" "$NETLIFY_ACCESS_TOKEN" + + _record_id=$(echo "$response" | _egrep_o "\"type\":\"TXT\",[^\}]*\"value\":\"$txt\"" | head -n 1 | _egrep_o "\"id\":\"[^\"\}]*\"" | cut -d : -f 2 | tr -d \" ) + _debug _record_id "$_record_id" + if [ "$_record_id" ]; then + _netlify_rest DELETE "$dnsRecordURI/$_record_id" "" "$NETLIFY_ACCESS_TOKEN" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + if [ "$_code" = "200" ] || [ "$_code" = '204' ]; then + _info "validation value removed" + return 0 + else + _err "error removing validation value ($_code)" + return 1 + fi + return 0 + fi + return 1 +} + +#################### Private functions below ################################## + +_get_root() { + domain=$1 + accesstoken=$2 + i=1 + p=1 + + _netlify_rest GET "dns_zones" "" "$accesstoken" + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug2 "Checking domain: $h" + if [ -z "$h" ]; then + #not valid + _err "Invalid domain" + return 1 + fi + + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + _domain_id=$(echo "$response" | _egrep_o "\"[^\"]*\",\"name\":\"$h" | cut -d , -f 1 | tr -d \" ) + if [ "$_domain_id" ]; then + if [ "$i" = 1 ]; then + #create the record at the domain apex (@) if only the domain name was provided as --domain-alias + _sub_domain="@" + else + _sub_domain=$(echo "$domain" | cut -d . -f 1-$p) + fi + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_netlify_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$NETLIFY_ACCESS_TOKEN" | tr -d '"') + + export _H1="Content-Type: application/json" + export _H2="Authorization: Bearer $token_trimmed" + + :>"$HTTP_HEADER" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$NETLIFY_URL$ep" "" "$m")" + else + response="$(_get "$NETLIFY_URL$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} \ No newline at end of file From 70b49980cbed1f1c98d916dfe469512872aae171 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 9 Aug 2020 09:40:22 +0800 Subject: [PATCH 034/190] fix format --- dnsapi/dns_dynv6.sh | 2 +- dnsapi/dns_netlify.sh | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 50eda74b..3c222d3a 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -80,7 +80,7 @@ _generate_new_key() { _get_domain() { _full_domain="$1" _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks' ; then + if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks'; then _err "The hosts does not seem to be a dynv6 host" return 1 fi diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index 4da97f48..137ac1fb 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -57,6 +57,8 @@ dns_netlify_add() { #Remove the txt record after validation. dns_netlify_rm() { _info "Using Netlify" + txtdomain="$1" + txt="$2" _debug txtdomain "$txtdomain" _debug txt "$txt" @@ -70,12 +72,12 @@ dns_netlify_rm() { _debug _domain_id "$_domain_id" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - + dnsRecordURI="dns_zones/$_domain_id/dns_records" _netlify_rest GET "$dnsRecordURI" "" "$NETLIFY_ACCESS_TOKEN" - _record_id=$(echo "$response" | _egrep_o "\"type\":\"TXT\",[^\}]*\"value\":\"$txt\"" | head -n 1 | _egrep_o "\"id\":\"[^\"\}]*\"" | cut -d : -f 2 | tr -d \" ) + _record_id=$(echo "$response" | _egrep_o "\"type\":\"TXT\",[^\}]*\"value\":\"$txt\"" | head -n 1 | _egrep_o "\"id\":\"[^\"\}]*\"" | cut -d : -f 2 | tr -d \") _debug _record_id "$_record_id" if [ "$_record_id" ]; then _netlify_rest DELETE "$dnsRecordURI/$_record_id" "" "$NETLIFY_ACCESS_TOKEN" @@ -101,7 +103,7 @@ _get_root() { p=1 _netlify_rest GET "dns_zones" "" "$accesstoken" - + while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug2 "Checking domain: $h" @@ -112,7 +114,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(echo "$response" | _egrep_o "\"[^\"]*\",\"name\":\"$h" | cut -d , -f 1 | tr -d \" ) + _domain_id=$(echo "$response" | _egrep_o "\"[^\"]*\",\"name\":\"$h" | cut -d , -f 1 | tr -d \") if [ "$_domain_id" ]; then if [ "$i" = 1 ]; then #create the record at the domain apex (@) if only the domain name was provided as --domain-alias @@ -157,4 +159,4 @@ _netlify_rest() { fi _debug2 response "$response" return 0 -} \ No newline at end of file +} From e932be0fb3b145a6c6cf161de74d29a96ea8a3d0 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 9 Aug 2020 09:34:43 +0800 Subject: [PATCH 035/190] eab --- acme.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 6a600087..1f6d2605 100755 --- a/acme.sh +++ b/acme.sh @@ -1507,6 +1507,19 @@ _url_replace() { tr '/+' '_-' | tr -d '= ' } +#base64 string +_durl_replace_base64() { + _l=$((${#1} % 4)) + if [ $_l -eq 2 ]; then + _s="$1"'==' + elif [ $_l -eq 3 ]; then + _s="$1"'=' + else + _s="$1" + fi + echo "$_s" | tr '_-' '/+' +} + _time2str() { #BSD if date -u -r "$1" 2>/dev/null; then @@ -3406,10 +3419,13 @@ _on_issue_success() { } +#account_key_length eab-kid eab-hmac-key registeraccount() { - _reg_length="$1" + _account_key_length="$1" + _eab_id="$2" + _eab_hmac_key="$3" _initpath - _regAccount "$_reg_length" + _regAccount "$_account_key_length" "$_eab_id" "$_eab_hmac_key" } __calcAccountKeyHash() { @@ -3424,6 +3440,8 @@ __calc_account_thumbprint() { _regAccount() { _initpath _reg_length="$1" + _eab_id="$2" + _eab_hmac_key="$3" _debug3 _regAccount "$_regAccount" _initAPI @@ -3448,12 +3466,41 @@ _regAccount() { if ! _calcjwk "$ACCOUNT_KEY_PATH"; then return 1 fi - + if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then + _savecaconf CA_EAB_KEY_ID "$_eab_id" + _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" + fi + _eab_id=$(_readcaconf "CA_EAB_KEY_ID") + _eab_hmac_key=$(_readcaconf "CA_EAB_HMAC_KEY") + _secure_debug3 _eab_id "$_eab_id" + _secure_debug3 _eab_hmac_key "$_eab_hmac_key" if [ "$ACME_VERSION" = "2" ]; then - regjson='{"termsOfServiceAgreed": true}' + if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then + eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" + _debug3 eab_protected "$eab_protected" + + eab_protected64=$(printf "%s" "$eab_protected" | _base64 | _url_replace) + _debug3 eab_protected64 "$eab_protected64" + + eab_payload64=$(printf "%s" "$jwk" | _base64 | _url_replace) + _debug3 eab_payload64 "$eab_payload64" + + eab_sign_t="$eab_protected64.$eab_payload64" + _debug3 eab_sign_t "$eab_sign_t" + + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + _debug3 key_hex "$key_hex" + + eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) + _debug3 eab_signature "$eab_signature" + + externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" + _debug3 externalBinding "$externalBinding" + fi if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"], "termsOfServiceAgreed": true}' + email_sg="\"contact\": [\"mailto:$ACCOUNT_EMAIL\"], " fi + regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" else _reg_res="$ACME_NEW_ACCOUNT_RES" regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' @@ -6278,6 +6325,10 @@ Parameters: --log-level 1|2 Specifies the log level, default is 1. --syslog [0|3|6|7] Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. + --eab-kid EAB_KID Key Identifier for External Account Binding. + --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. + + These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6510,6 +6561,8 @@ _process() { _notify_level="" _notify_mode="" _revoke_reason="" + _eab_kid="" + _eab_hmac_key="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -6990,6 +7043,14 @@ _process() { fi shift ;; + --eab-kid) + _eab_kid="$2" + shift + ;; + --eab-hmac-key) + _eab_hmac_key="$2" + shift + ;; *) _err "Unknown parameter : $1" return 1 @@ -7086,7 +7147,7 @@ _process() { deactivate "$_domain,$_altdomains" ;; registeraccount) - registeraccount "$_accountkeylength" + registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key" ;; updateaccount) updateaccount From 7d20db93d3711b53dfc3bb435112f7ad1eaf1a9e Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Aug 2020 23:28:52 +0800 Subject: [PATCH 036/190] 1. Support short names for `--server` parameter, The valid values are: letsencrypt, letsencrypt_test, buypass, buypass_test and zerossl 2. Support Zerossl.com acme protocol. 3. Add "--set-default-ca --server xxxx" command to set the default CA to use. --- acme.sh | 93 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/acme.sh b/acme.sh index 1f6d2605..4bddab25 100755 --- a/acme.sh +++ b/acme.sh @@ -23,11 +23,27 @@ _SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY" LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory" -LETSENCRYPT_CA_V2="https://acme-v02.api.letsencrypt.org/directory" -LETSENCRYPT_STAGING_CA_V2="https://acme-staging-v02.api.letsencrypt.org/directory" +CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory" +CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory" -DEFAULT_CA=$LETSENCRYPT_CA_V2 -DEFAULT_STAGING_CA=$LETSENCRYPT_STAGING_CA_V2 +CA_BUYPASS="https://api.buypass.com/acme/directory" +CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" + +CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" + + +DEFAULT_CA=$CA_LETSENCRYPT_V2 +DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST + +CA_NAMES=" +letsencrypt +letsencrypt_test,letsencrypttest +buypass +buypass_test,buypasstest +zerossl +" + +CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" DEFAULT_ACCOUNT_EMAIL="" @@ -140,6 +156,8 @@ _SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo" _REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert" +_ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -2577,16 +2595,22 @@ _initpath() { fi if [ "$ACME_VERSION" = "2" ]; then - DEFAULT_CA="$LETSENCRYPT_CA_V2" - DEFAULT_STAGING_CA="$LETSENCRYPT_STAGING_CA_V2" + DEFAULT_CA="$CA_LETSENCRYPT_V2" + DEFAULT_STAGING_CA="$CA_LETSENCRYPT_V2_TEST" fi if [ -z "$ACME_DIRECTORY" ]; then - if [ -z "$STAGE" ]; then - ACME_DIRECTORY="$DEFAULT_CA" + default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") + _debug default_acme_server "$default_acme_server" + if [ "$default_acme_server" ]; then + ACME_DIRECTORY="$default_acme_server" else - ACME_DIRECTORY="$DEFAULT_STAGING_CA" - _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + if [ -z "$STAGE" ]; then + ACME_DIRECTORY="$DEFAULT_CA" + else + ACME_DIRECTORY="$DEFAULT_STAGING_CA" + _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + fi fi fi @@ -6301,6 +6325,7 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. + --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6344,7 +6369,7 @@ Parameters: --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. --config-home Specifies the home dir to save all the configurations. --useragent Specifies the user agent string. it will be saved for future use too. - --accountemail Specifies the account email, only valid for the '--install' and '--update-account' command. + --accountemail, -m Specifies the account email, only valid for the '--install' and '--update-account' command. --accountkey Specifies the account key path, only valid for the '--install' command. --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. @@ -6510,6 +6535,39 @@ _checkSudo() { return 0 } +#server +_selectServer() { + _server="$1" + _server_lower="$(echo "$_server" | _lower_case)" + _sindex=0 + for snames in $CA_NAMES; do + snames="$(echo "$snames" | _lower_case)" + _sindex="$(_math $_sindex + 1)" + _debug2 "_selectServer try snames" "$snames" + for sname in $(echo "$snames" | tr ',' ' '); do + if [ "$_server_lower" = "$sname" ]; then + _debug2 "_selectServer match $sname" + _serverdir="$(_getfield "$CA_SERVERS" $_sindex)" + _debug "Selected server: $_serverdir" + ACME_DIRECTORY="$_serverdir" + export ACME_DIRECTORY + return + fi + done + done + ACME_DIRECTORY="$_server" + export ACME_DIRECTORY +} + +#set default ca to $ACME_DIRECTORY +setdefaultca() { + if [ -z "$ACME_DIRECTORY" ]; then + _err "Please give a --server parameter." + return 1 + fi + _saveaccountconf "DEFAULT_ACME_SERVER" "$ACME_DIRECTORY" +} + _process() { _CMD="" _domain="" @@ -6652,6 +6710,9 @@ _process() { --set-notify) _CMD="setnotify" ;; + --set-default-ca) + _CMD="setdefaultca" + ;; --domain | -d) _dvalue="$2" @@ -6690,9 +6751,8 @@ _process() { STAGE="1" ;; --server) - ACME_DIRECTORY="$2" - _server="$ACME_DIRECTORY" - export ACME_DIRECTORY + _server="$2" + _selectServer "$_server" shift ;; --debug) @@ -6849,7 +6909,7 @@ _process() { USER_AGENT="$_useragent" shift ;; - --accountemail) + --accountemail | -m) _accountemail="$2" ACCOUNT_EMAIL="$_accountemail" shift @@ -7179,6 +7239,9 @@ _process() { setnotify) setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" ;; + setdefaultca) + setdefaultca + ;; *) if [ "$_CMD" ]; then _err "Invalid command: $_CMD" From 1e967eceef105f55e3e68c649ff6e77cf1c6e896 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Aug 2020 23:45:12 +0800 Subject: [PATCH 037/190] fix format --- acme.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 4bddab25..70795ff3 100755 --- a/acme.sh +++ b/acme.sh @@ -31,7 +31,6 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" - DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST @@ -3512,10 +3511,10 @@ _regAccount() { eab_sign_t="$eab_protected64.$eab_payload64" _debug3 eab_sign_t "$eab_sign_t" - key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" _debug3 key_hex "$key_hex" - eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) + eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) _debug3 eab_signature "$eab_signature" externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" @@ -7110,7 +7109,7 @@ _process() { --eab-hmac-key) _eab_hmac_key="$2" shift - ;; + ;; *) _err "Unknown parameter : $1" return 1 From edbe026b490d7da30a37a21d86142fc0bc31dcde Mon Sep 17 00:00:00 2001 From: Andy Botting Date: Wed, 12 Aug 2020 11:24:45 +1000 Subject: [PATCH 038/190] Rename openstack to dns_openstack Although the DNS API dev guide at https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide says `The script file name must be myapi.sh`, it should really be names dns_myapi.sh for consistency. --- dnsapi/{openstack.sh => dns_openstack.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dnsapi/{openstack.sh => dns_openstack.sh} (100%) diff --git a/dnsapi/openstack.sh b/dnsapi/dns_openstack.sh similarity index 100% rename from dnsapi/openstack.sh rename to dnsapi/dns_openstack.sh From 4e0de2237522c2c3814aefdd39751144c079fbcc Mon Sep 17 00:00:00 2001 From: Alexilmarranen Date: Wed, 12 Aug 2020 15:17:54 +0300 Subject: [PATCH 039/190] Issue2547 wrong url construction for multiple dns services Fix for problem in https://github.com/acmesh-official/acme.sh/issues/2547#issuecomment-672830796 --- dnsapi/dns_nic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 5052ee10..56170f87 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -166,7 +166,7 @@ _get_root() { if _contains "$_all_domains" "^$h$"; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h - _service=$(printf "%s" "$response" | grep "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/") + _service=$(printf "%s" "$response" | grep -m 1 "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/") return 0 fi p="$i" From 8d811760a91be47927ed842b8d7f056704c13574 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:43:44 +0800 Subject: [PATCH 040/190] 1. move email to ca conf 2. get EAB credentials from Zerossl by email automatically --- README.md | 1 + acme.sh | 94 ++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 2da103b2..f5631475 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ https://github.com/acmesh-official/acmetest # Supported CA - Letsencrypt.org CA(default) +- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA) - [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) diff --git a/acme.sh b/acme.sh index 70795ff3..d359a4bb 100755 --- a/acme.sh +++ b/acme.sh @@ -30,6 +30,8 @@ CA_BUYPASS="https://api.buypass.com/acme/directory" CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" +_ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email" + DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST @@ -45,7 +47,6 @@ zerossl CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" -DEFAULT_ACCOUNT_EMAIL="" DEFAULT_ACCOUNT_KEY_LENGTH=2048 DEFAULT_DOMAIN_KEY_LENGTH=2048 @@ -3459,6 +3460,21 @@ __calc_account_thumbprint() { printf "%s" "$jwk" | tr -d ' ' | _digest "sha256" | _url_replace } +_getAccountEmail() { + if [ "$ACCOUNT_EMAIL" ]; then + echo "$ACCOUNT_EMAIL" + return 0 + fi + if [ -z "$CA_EMAIL" ]; then + CA_EMAIL="$(_readcaconf CA_EMAIL)" + fi + if [ "$CA_EMAIL" ]; then + echo "$CA_EMAIL" + return 0 + fi + _readaccountconf "ACCOUNT_EMAIL" +} + #keylength _regAccount() { _initpath @@ -3497,7 +3513,38 @@ _regAccount() { _eab_hmac_key=$(_readcaconf "CA_EAB_HMAC_KEY") _secure_debug3 _eab_id "$_eab_id" _secure_debug3 _eab_hmac_key "$_eab_hmac_key" + _email="$(_getAccountEmail)" + if [ "$_email" ]; then + _savecaconf "CA_EMAIL" "$_email" + fi if [ "$ACME_VERSION" = "2" ]; then + if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then + if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then + _info "No EAB credentials found for ZeroSSL, let's get one" + if [ -z "$_email" ]; then + _err "Please provide a email address for zerossl account." + return 1 + fi + _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) + if [ "$?" != "0" ]; then + _debug2 "$_eabresp" + _err "Can not get EAB credentials from zerossl." + return 1 + fi + _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_id" ]; then + _err "Can not resolve _eab_id"; + return 1 + fi + _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_hmac_key" ]; then + _err "Can not resolve _eab_hmac_key"; + return 1 + fi + _savecaconf CA_EAB_KEY_ID "$_eab_id" + _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" + fi + fi if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" _debug3 eab_protected "$eab_protected" @@ -3520,44 +3567,52 @@ _regAccount() { externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" _debug3 externalBinding "$externalBinding" fi - if [ "$ACCOUNT_EMAIL" ]; then - email_sg="\"contact\": [\"mailto:$ACCOUNT_EMAIL\"], " + if [ "$_email" ]; then + email_sg="\"contact\": [\"mailto:$_email\"], " fi regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" else _reg_res="$ACME_NEW_ACCOUNT_RES" regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' - if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$ACCOUNT_EMAIL'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' + if [ "$_email" ]; then + regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$_email'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' fi fi - _info "Registering account" + _info "Registering account: $ACME_DIRECTORY" if ! _send_signed_request "${ACME_NEW_ACCOUNT}" "$regjson"; then _err "Register account Error: $response" return 1 fi + _eabAlreadyBound="" if [ "$code" = "" ] || [ "$code" = '201' ]; then echo "$response" >"$ACCOUNT_JSON_PATH" _info "Registered" elif [ "$code" = '409' ] || [ "$code" = '200' ]; then _info "Already registered" + elif [ "$code" = '400' ] && _contains "$response" 'The account is not awaiting external account binding'; then + _info "Already register EAB." + _eabAlreadyBound=1 else _err "Register account Error: $response" return 1 fi - _debug2 responseHeaders "$responseHeaders" - _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" - _debug "_accUri" "$_accUri" - if [ -z "$_accUri" ]; then - _err "Can not find account id url." - _err "$responseHeaders" - return 1 + if [ -z "$_eabAlreadyBound" ]; then + _debug2 responseHeaders "$responseHeaders" + _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" + _debug "_accUri" "$_accUri" + if [ -z "$_accUri" ]; then + _err "Can not find account id url." + _err "$responseHeaders" + return 1 + fi + _savecaconf "ACCOUNT_URL" "$_accUri" + else + ACCOUNT_URL="$(_readcaconf ACCOUNT_URL)" fi - _savecaconf "ACCOUNT_URL" "$_accUri" export ACCOUNT_URL="$_accUri" CA_KEY_HASH="$(__calcAccountKeyHash)" @@ -3606,9 +3661,10 @@ updateaccount() { fi _initAPI + _email="$(_getAccountEmail)" if [ "$ACME_VERSION" = "2" ]; then if [ "$ACCOUNT_EMAIL" ]; then - updjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"]}' + updjson='{"contact": ["mailto:'$_email'"]}' else updjson='{"contact": []}' fi @@ -4036,7 +4092,7 @@ issue() { else _cleardomainconf Le_API fi - + _info "Using CA: $ACME_DIRECTORY" if [ "$_alt_domains" = "$NO_VALUE" ]; then _alt_domains="" fi @@ -6491,12 +6547,6 @@ _processAccountConf() { _saveaccountconf "USER_AGENT" "$USER_AGENT" fi - if [ "$_accountemail" ]; then - _saveaccountconf "ACCOUNT_EMAIL" "$_accountemail" - elif [ "$ACCOUNT_EMAIL" ] && [ "$ACCOUNT_EMAIL" != "$DEFAULT_ACCOUNT_EMAIL" ]; then - _saveaccountconf "ACCOUNT_EMAIL" "$ACCOUNT_EMAIL" - fi - if [ "$_openssl_bin" ]; then _saveaccountconf "ACME_OPENSSL_BIN" "$_openssl_bin" elif [ "$ACME_OPENSSL_BIN" ] && [ "$ACME_OPENSSL_BIN" != "$DEFAULT_OPENSSL_BIN" ]; then From 85503655ab3a98854e69a302c1eaad370711c1e3 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:47:17 +0800 Subject: [PATCH 041/190] Display ZeroSSL usage --- acme.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index d359a4bb..544555b9 100755 --- a/acme.sh +++ b/acme.sh @@ -3522,13 +3522,14 @@ _regAccount() { if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then _info "No EAB credentials found for ZeroSSL, let's get one" if [ -z "$_email" ]; then - _err "Please provide a email address for zerossl account." + _err "Please provide a email address for ZeroSSL account." + _err "See ZeroSSL usage: $_ZEROSSL_WIKI" return 1 fi _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) if [ "$?" != "0" ]; then _debug2 "$_eabresp" - _err "Can not get EAB credentials from zerossl." + _err "Can not get EAB credentials from ZeroSSL." return 1 fi _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" From f96d91cb6c518c93ba93c827228892b9ed36bc82 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 9 Aug 2020 09:34:43 +0800 Subject: [PATCH 042/190] eab --- acme.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 6a600087..1f6d2605 100755 --- a/acme.sh +++ b/acme.sh @@ -1507,6 +1507,19 @@ _url_replace() { tr '/+' '_-' | tr -d '= ' } +#base64 string +_durl_replace_base64() { + _l=$((${#1} % 4)) + if [ $_l -eq 2 ]; then + _s="$1"'==' + elif [ $_l -eq 3 ]; then + _s="$1"'=' + else + _s="$1" + fi + echo "$_s" | tr '_-' '/+' +} + _time2str() { #BSD if date -u -r "$1" 2>/dev/null; then @@ -3406,10 +3419,13 @@ _on_issue_success() { } +#account_key_length eab-kid eab-hmac-key registeraccount() { - _reg_length="$1" + _account_key_length="$1" + _eab_id="$2" + _eab_hmac_key="$3" _initpath - _regAccount "$_reg_length" + _regAccount "$_account_key_length" "$_eab_id" "$_eab_hmac_key" } __calcAccountKeyHash() { @@ -3424,6 +3440,8 @@ __calc_account_thumbprint() { _regAccount() { _initpath _reg_length="$1" + _eab_id="$2" + _eab_hmac_key="$3" _debug3 _regAccount "$_regAccount" _initAPI @@ -3448,12 +3466,41 @@ _regAccount() { if ! _calcjwk "$ACCOUNT_KEY_PATH"; then return 1 fi - + if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then + _savecaconf CA_EAB_KEY_ID "$_eab_id" + _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" + fi + _eab_id=$(_readcaconf "CA_EAB_KEY_ID") + _eab_hmac_key=$(_readcaconf "CA_EAB_HMAC_KEY") + _secure_debug3 _eab_id "$_eab_id" + _secure_debug3 _eab_hmac_key "$_eab_hmac_key" if [ "$ACME_VERSION" = "2" ]; then - regjson='{"termsOfServiceAgreed": true}' + if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then + eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" + _debug3 eab_protected "$eab_protected" + + eab_protected64=$(printf "%s" "$eab_protected" | _base64 | _url_replace) + _debug3 eab_protected64 "$eab_protected64" + + eab_payload64=$(printf "%s" "$jwk" | _base64 | _url_replace) + _debug3 eab_payload64 "$eab_payload64" + + eab_sign_t="$eab_protected64.$eab_payload64" + _debug3 eab_sign_t "$eab_sign_t" + + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + _debug3 key_hex "$key_hex" + + eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) + _debug3 eab_signature "$eab_signature" + + externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" + _debug3 externalBinding "$externalBinding" + fi if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"], "termsOfServiceAgreed": true}' + email_sg="\"contact\": [\"mailto:$ACCOUNT_EMAIL\"], " fi + regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" else _reg_res="$ACME_NEW_ACCOUNT_RES" regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' @@ -6278,6 +6325,10 @@ Parameters: --log-level 1|2 Specifies the log level, default is 1. --syslog [0|3|6|7] Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. + --eab-kid EAB_KID Key Identifier for External Account Binding. + --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. + + These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6510,6 +6561,8 @@ _process() { _notify_level="" _notify_mode="" _revoke_reason="" + _eab_kid="" + _eab_hmac_key="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -6990,6 +7043,14 @@ _process() { fi shift ;; + --eab-kid) + _eab_kid="$2" + shift + ;; + --eab-hmac-key) + _eab_hmac_key="$2" + shift + ;; *) _err "Unknown parameter : $1" return 1 @@ -7086,7 +7147,7 @@ _process() { deactivate "$_domain,$_altdomains" ;; registeraccount) - registeraccount "$_accountkeylength" + registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key" ;; updateaccount) updateaccount From 737e9e48cac1e415d8405f9e7e9cabf131da52df Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Aug 2020 23:28:52 +0800 Subject: [PATCH 043/190] 1. Support short names for `--server` parameter, The valid values are: letsencrypt, letsencrypt_test, buypass, buypass_test and zerossl 2. Support Zerossl.com acme protocol. 3. Add "--set-default-ca --server xxxx" command to set the default CA to use. --- acme.sh | 93 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/acme.sh b/acme.sh index 1f6d2605..4bddab25 100755 --- a/acme.sh +++ b/acme.sh @@ -23,11 +23,27 @@ _SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY" LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory" -LETSENCRYPT_CA_V2="https://acme-v02.api.letsencrypt.org/directory" -LETSENCRYPT_STAGING_CA_V2="https://acme-staging-v02.api.letsencrypt.org/directory" +CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory" +CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory" -DEFAULT_CA=$LETSENCRYPT_CA_V2 -DEFAULT_STAGING_CA=$LETSENCRYPT_STAGING_CA_V2 +CA_BUYPASS="https://api.buypass.com/acme/directory" +CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" + +CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" + + +DEFAULT_CA=$CA_LETSENCRYPT_V2 +DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST + +CA_NAMES=" +letsencrypt +letsencrypt_test,letsencrypttest +buypass +buypass_test,buypasstest +zerossl +" + +CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" DEFAULT_ACCOUNT_EMAIL="" @@ -140,6 +156,8 @@ _SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo" _REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert" +_ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -2577,16 +2595,22 @@ _initpath() { fi if [ "$ACME_VERSION" = "2" ]; then - DEFAULT_CA="$LETSENCRYPT_CA_V2" - DEFAULT_STAGING_CA="$LETSENCRYPT_STAGING_CA_V2" + DEFAULT_CA="$CA_LETSENCRYPT_V2" + DEFAULT_STAGING_CA="$CA_LETSENCRYPT_V2_TEST" fi if [ -z "$ACME_DIRECTORY" ]; then - if [ -z "$STAGE" ]; then - ACME_DIRECTORY="$DEFAULT_CA" + default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") + _debug default_acme_server "$default_acme_server" + if [ "$default_acme_server" ]; then + ACME_DIRECTORY="$default_acme_server" else - ACME_DIRECTORY="$DEFAULT_STAGING_CA" - _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + if [ -z "$STAGE" ]; then + ACME_DIRECTORY="$DEFAULT_CA" + else + ACME_DIRECTORY="$DEFAULT_STAGING_CA" + _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + fi fi fi @@ -6301,6 +6325,7 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. + --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6344,7 +6369,7 @@ Parameters: --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. --config-home Specifies the home dir to save all the configurations. --useragent Specifies the user agent string. it will be saved for future use too. - --accountemail Specifies the account email, only valid for the '--install' and '--update-account' command. + --accountemail, -m Specifies the account email, only valid for the '--install' and '--update-account' command. --accountkey Specifies the account key path, only valid for the '--install' command. --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. @@ -6510,6 +6535,39 @@ _checkSudo() { return 0 } +#server +_selectServer() { + _server="$1" + _server_lower="$(echo "$_server" | _lower_case)" + _sindex=0 + for snames in $CA_NAMES; do + snames="$(echo "$snames" | _lower_case)" + _sindex="$(_math $_sindex + 1)" + _debug2 "_selectServer try snames" "$snames" + for sname in $(echo "$snames" | tr ',' ' '); do + if [ "$_server_lower" = "$sname" ]; then + _debug2 "_selectServer match $sname" + _serverdir="$(_getfield "$CA_SERVERS" $_sindex)" + _debug "Selected server: $_serverdir" + ACME_DIRECTORY="$_serverdir" + export ACME_DIRECTORY + return + fi + done + done + ACME_DIRECTORY="$_server" + export ACME_DIRECTORY +} + +#set default ca to $ACME_DIRECTORY +setdefaultca() { + if [ -z "$ACME_DIRECTORY" ]; then + _err "Please give a --server parameter." + return 1 + fi + _saveaccountconf "DEFAULT_ACME_SERVER" "$ACME_DIRECTORY" +} + _process() { _CMD="" _domain="" @@ -6652,6 +6710,9 @@ _process() { --set-notify) _CMD="setnotify" ;; + --set-default-ca) + _CMD="setdefaultca" + ;; --domain | -d) _dvalue="$2" @@ -6690,9 +6751,8 @@ _process() { STAGE="1" ;; --server) - ACME_DIRECTORY="$2" - _server="$ACME_DIRECTORY" - export ACME_DIRECTORY + _server="$2" + _selectServer "$_server" shift ;; --debug) @@ -6849,7 +6909,7 @@ _process() { USER_AGENT="$_useragent" shift ;; - --accountemail) + --accountemail | -m) _accountemail="$2" ACCOUNT_EMAIL="$_accountemail" shift @@ -7179,6 +7239,9 @@ _process() { setnotify) setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" ;; + setdefaultca) + setdefaultca + ;; *) if [ "$_CMD" ]; then _err "Invalid command: $_CMD" From d42ff227f1ce31f881d6f783874bc89733d0f007 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 11 Aug 2020 23:45:12 +0800 Subject: [PATCH 044/190] fix format --- acme.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 4bddab25..70795ff3 100755 --- a/acme.sh +++ b/acme.sh @@ -31,7 +31,6 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" - DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST @@ -3512,10 +3511,10 @@ _regAccount() { eab_sign_t="$eab_protected64.$eab_payload64" _debug3 eab_sign_t "$eab_sign_t" - key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" _debug3 key_hex "$key_hex" - eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) + eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) _debug3 eab_signature "$eab_signature" externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" @@ -7110,7 +7109,7 @@ _process() { --eab-hmac-key) _eab_hmac_key="$2" shift - ;; + ;; *) _err "Unknown parameter : $1" return 1 From 389518e1b89e5bf9b353b10026d3f4b203410ff9 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:43:44 +0800 Subject: [PATCH 045/190] 1. move email to ca conf 2. get EAB credentials from Zerossl by email automatically --- README.md | 1 + acme.sh | 94 ++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 2da103b2..f5631475 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ https://github.com/acmesh-official/acmetest # Supported CA - Letsencrypt.org CA(default) +- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA) - [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [Pebble strict Mode](https://github.com/letsencrypt/pebble) diff --git a/acme.sh b/acme.sh index 70795ff3..d359a4bb 100755 --- a/acme.sh +++ b/acme.sh @@ -30,6 +30,8 @@ CA_BUYPASS="https://api.buypass.com/acme/directory" CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" +_ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email" + DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST @@ -45,7 +47,6 @@ zerossl CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" -DEFAULT_ACCOUNT_EMAIL="" DEFAULT_ACCOUNT_KEY_LENGTH=2048 DEFAULT_DOMAIN_KEY_LENGTH=2048 @@ -3459,6 +3460,21 @@ __calc_account_thumbprint() { printf "%s" "$jwk" | tr -d ' ' | _digest "sha256" | _url_replace } +_getAccountEmail() { + if [ "$ACCOUNT_EMAIL" ]; then + echo "$ACCOUNT_EMAIL" + return 0 + fi + if [ -z "$CA_EMAIL" ]; then + CA_EMAIL="$(_readcaconf CA_EMAIL)" + fi + if [ "$CA_EMAIL" ]; then + echo "$CA_EMAIL" + return 0 + fi + _readaccountconf "ACCOUNT_EMAIL" +} + #keylength _regAccount() { _initpath @@ -3497,7 +3513,38 @@ _regAccount() { _eab_hmac_key=$(_readcaconf "CA_EAB_HMAC_KEY") _secure_debug3 _eab_id "$_eab_id" _secure_debug3 _eab_hmac_key "$_eab_hmac_key" + _email="$(_getAccountEmail)" + if [ "$_email" ]; then + _savecaconf "CA_EMAIL" "$_email" + fi if [ "$ACME_VERSION" = "2" ]; then + if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then + if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then + _info "No EAB credentials found for ZeroSSL, let's get one" + if [ -z "$_email" ]; then + _err "Please provide a email address for zerossl account." + return 1 + fi + _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) + if [ "$?" != "0" ]; then + _debug2 "$_eabresp" + _err "Can not get EAB credentials from zerossl." + return 1 + fi + _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_id" ]; then + _err "Can not resolve _eab_id"; + return 1 + fi + _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" + if [ -z "$_eab_hmac_key" ]; then + _err "Can not resolve _eab_hmac_key"; + return 1 + fi + _savecaconf CA_EAB_KEY_ID "$_eab_id" + _savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" + fi + fi if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" _debug3 eab_protected "$eab_protected" @@ -3520,44 +3567,52 @@ _regAccount() { externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" _debug3 externalBinding "$externalBinding" fi - if [ "$ACCOUNT_EMAIL" ]; then - email_sg="\"contact\": [\"mailto:$ACCOUNT_EMAIL\"], " + if [ "$_email" ]; then + email_sg="\"contact\": [\"mailto:$_email\"], " fi regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}" else _reg_res="$ACME_NEW_ACCOUNT_RES" regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' - if [ "$ACCOUNT_EMAIL" ]; then - regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$ACCOUNT_EMAIL'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' + if [ "$_email" ]; then + regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$_email'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}' fi fi - _info "Registering account" + _info "Registering account: $ACME_DIRECTORY" if ! _send_signed_request "${ACME_NEW_ACCOUNT}" "$regjson"; then _err "Register account Error: $response" return 1 fi + _eabAlreadyBound="" if [ "$code" = "" ] || [ "$code" = '201' ]; then echo "$response" >"$ACCOUNT_JSON_PATH" _info "Registered" elif [ "$code" = '409' ] || [ "$code" = '200' ]; then _info "Already registered" + elif [ "$code" = '400' ] && _contains "$response" 'The account is not awaiting external account binding'; then + _info "Already register EAB." + _eabAlreadyBound=1 else _err "Register account Error: $response" return 1 fi - _debug2 responseHeaders "$responseHeaders" - _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" - _debug "_accUri" "$_accUri" - if [ -z "$_accUri" ]; then - _err "Can not find account id url." - _err "$responseHeaders" - return 1 + if [ -z "$_eabAlreadyBound" ]; then + _debug2 responseHeaders "$responseHeaders" + _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" + _debug "_accUri" "$_accUri" + if [ -z "$_accUri" ]; then + _err "Can not find account id url." + _err "$responseHeaders" + return 1 + fi + _savecaconf "ACCOUNT_URL" "$_accUri" + else + ACCOUNT_URL="$(_readcaconf ACCOUNT_URL)" fi - _savecaconf "ACCOUNT_URL" "$_accUri" export ACCOUNT_URL="$_accUri" CA_KEY_HASH="$(__calcAccountKeyHash)" @@ -3606,9 +3661,10 @@ updateaccount() { fi _initAPI + _email="$(_getAccountEmail)" if [ "$ACME_VERSION" = "2" ]; then if [ "$ACCOUNT_EMAIL" ]; then - updjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"]}' + updjson='{"contact": ["mailto:'$_email'"]}' else updjson='{"contact": []}' fi @@ -4036,7 +4092,7 @@ issue() { else _cleardomainconf Le_API fi - + _info "Using CA: $ACME_DIRECTORY" if [ "$_alt_domains" = "$NO_VALUE" ]; then _alt_domains="" fi @@ -6491,12 +6547,6 @@ _processAccountConf() { _saveaccountconf "USER_AGENT" "$USER_AGENT" fi - if [ "$_accountemail" ]; then - _saveaccountconf "ACCOUNT_EMAIL" "$_accountemail" - elif [ "$ACCOUNT_EMAIL" ] && [ "$ACCOUNT_EMAIL" != "$DEFAULT_ACCOUNT_EMAIL" ]; then - _saveaccountconf "ACCOUNT_EMAIL" "$ACCOUNT_EMAIL" - fi - if [ "$_openssl_bin" ]; then _saveaccountconf "ACME_OPENSSL_BIN" "$_openssl_bin" elif [ "$ACME_OPENSSL_BIN" ] && [ "$ACME_OPENSSL_BIN" != "$DEFAULT_OPENSSL_BIN" ]; then From 578c338d40781689dc6e1ce9ae6d12da92f03893 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:47:17 +0800 Subject: [PATCH 046/190] Display ZeroSSL usage --- acme.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index d359a4bb..544555b9 100755 --- a/acme.sh +++ b/acme.sh @@ -3522,13 +3522,14 @@ _regAccount() { if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then _info "No EAB credentials found for ZeroSSL, let's get one" if [ -z "$_email" ]; then - _err "Please provide a email address for zerossl account." + _err "Please provide a email address for ZeroSSL account." + _err "See ZeroSSL usage: $_ZEROSSL_WIKI" return 1 fi _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) if [ "$?" != "0" ]; then _debug2 "$_eabresp" - _err "Can not get EAB credentials from zerossl." + _err "Can not get EAB credentials from ZeroSSL." return 1 fi _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" From 365aa69afd04d732c14c6e0b8bf7509fcd0ffafb Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 20:48:21 +0800 Subject: [PATCH 047/190] fix format --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 544555b9..d57ff9a8 100755 --- a/acme.sh +++ b/acme.sh @@ -3534,12 +3534,12 @@ _regAccount() { fi _eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" if [ -z "$_eab_id" ]; then - _err "Can not resolve _eab_id"; + _err "Can not resolve _eab_id" return 1 fi _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" if [ -z "$_eab_hmac_key" ]; then - _err "Can not resolve _eab_hmac_key"; + _err "Can not resolve _eab_hmac_key" return 1 fi _savecaconf CA_EAB_KEY_ID "$_eab_id" From df22f68088d28a6f7f020259afc222c989f6f9cd Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 21:25:35 +0800 Subject: [PATCH 048/190] Add info for set-default-ca --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index ea5676f9..bcfaa8b1 100755 --- a/acme.sh +++ b/acme.sh @@ -6618,6 +6618,7 @@ setdefaultca() { return 1 fi _saveaccountconf "DEFAULT_ACME_SERVER" "$ACME_DIRECTORY" + _info "Changed default CA to: $(__green "$ACME_DIRECTORY")" } _process() { From 269847d19dd396ca0c4885ff57e737839fa98296 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 21:45:20 +0800 Subject: [PATCH 049/190] Add CA name to the `--list` command output. --- acme.sh | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index bcfaa8b1..b7d45f5d 100755 --- a/acme.sh +++ b/acme.sh @@ -37,11 +37,11 @@ DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST CA_NAMES=" -letsencrypt -letsencrypt_test,letsencrypttest -buypass -buypass_test,buypasstest -zerossl +Letsencrypt.org,letsencrypt +Letsencrypt.org_test,letsencrypt_test,letsencrypttest +BuyPass.com,buypass +BuyPass.com_test,buypass_test,buypasstest +ZeroSSL.com,zerossl " CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" @@ -5254,7 +5254,7 @@ list() { _sep="|" if [ "$_raw" ]; then - printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}Created${_sep}Renew" + printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}CA${_sep}Created${_sep}Renew" for di in "${CERT_HOME}"/*.*/; do d=$(basename "$di") _debug d "$d" @@ -5266,7 +5266,8 @@ list() { DOMAIN_CONF="$di/$d.conf" if [ -f "$DOMAIN_CONF" ]; then . "$DOMAIN_CONF" - printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr" + _ca="$(_getCAShortName "$Le_API")" + printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr" fi ) done @@ -6611,6 +6612,27 @@ _selectServer() { export ACME_DIRECTORY } +#url +_getCAShortName() { + caurl="$1" + caurl_lower="$(echo $caurl | _lower_case)" + _sindex=0 + for surl in $(echo "$CA_SERVERS" | _lower_case | tr , ' '); do + _sindex="$(_math $_sindex + 1)" + if [ "$caurl_lower" = "$surl" ]; then + _nindex=0 + for snames in $CA_NAMES; do + _nindex="$(_math $_nindex + 1)" + if [ $_nindex -ge $_sindex ]; then + _getfield "$snames" 1 + return + fi + done + fi + done + echo "$caurl" +} + #set default ca to $ACME_DIRECTORY setdefaultca() { if [ -z "$ACME_DIRECTORY" ]; then From 1177cc3f29964db6983143a1d25d6758e7798e6d Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 12 Aug 2020 22:09:37 +0800 Subject: [PATCH 050/190] fix format --- acme.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/acme.sh b/acme.sh index b7d45f5d..9505ae2c 100755 --- a/acme.sh +++ b/acme.sh @@ -32,7 +32,6 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" _ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email" - DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST From f1318636428eefaa0472f28902d2fd19a832a0c4 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Wed, 12 Aug 2020 23:48:11 +0200 Subject: [PATCH 051/190] now with "_saveaccountconf_mutable" _saveaccountconf_mutable instead of _saveaccountconf now used. Co-Authored-By: kapper.net support account <33451837+kappernet@users.noreply.github.com> --- dnsapi/dns_kappernet.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index a059447a..70a3ea23 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -26,8 +26,8 @@ dns_kappernet_add() { fi #store the api key and email to the account conf file. - _saveaccountconf KAPPERNETDNS_Key "$KAPPERNETDNS_Key" - _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" + _saveaccountconf_mutable KAPPERNETDNS_Key "$KAPPERNETDNS_Key" + _saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" _debug "Checking Domain ..." if ! _get_root "$fullhostname"; then _err "invalid domain" @@ -69,8 +69,8 @@ dns_kappernet_rm() { fi #store the api key and email to the account conf file. - _saveaccountconf KAPPERNETDNS_Key "$KAPPERNETDNS_Key" - _saveaccountconf KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" + _saveaccountconf_mutable KAPPERNETDNS_Key "$KAPPERNETDNS_Key" + _saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" _info "Trying to remove the TXT Record: $fullhostname" data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" From 0052ab7148a930183e39db4192ec250a3b84bfc0 Mon Sep 17 00:00:00 2001 From: "kapper.net support account" Date: Thu, 13 Aug 2020 00:23:57 +0200 Subject: [PATCH 052/190] more mutable + style-update more mutable config-read-calls more details for TXT records info + errors; typo fixed (create instead of delete) --- dnsapi/dns_kappernet.sh | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 70a3ea23..47a871c1 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -17,11 +17,15 @@ dns_kappernet_add() { fullhostname=$1 txtvalue=$2 + KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}" + KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}" + if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then KAPPERNETDNS_Key="" KAPPERNETDNS_Secret="" - _err "You haven't defined kapper.net api key and secret yet." - _err "Please send us mail to support@kapper.net get your key and secret." + _err "Please specify your kapper.net api key and secret." + _err "If you have not received yours - send your mail to" + _err "support@kapper.net to get your key and secret." return 1 fi @@ -60,11 +64,15 @@ dns_kappernet_rm() { fullhostname=$1 txtvalue=$2 + KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}" + KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}" + if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then KAPPERNETDNS_Key="" KAPPERNETDNS_Secret="" - _err "You haven't defined kapper.net api key and secret yet." - _err "Please send us mail to get your key and secret." + _err "Please specify your kapper.net api key and secret." + _err "If you have not received yours - send your mail to" + _err "support@kapper.net to get your key and secret." return 1 fi @@ -72,18 +80,18 @@ dns_kappernet_rm() { _saveaccountconf_mutable KAPPERNETDNS_Key "$KAPPERNETDNS_Key" _saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" - _info "Trying to remove the TXT Record: $fullhostname" + _info "Trying to remove the TXT Record: $fullhostname containing $txtvalue" data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" if _kappernet_api GET "action=del&subject=$fullhostname&data=$data"; then if _contains "$response" "{\"OK\":true"; then return 0 else - _err "Error deleting DNS Record: $fullhostname" + _err "Error deleting DNS Record: $fullhostname containing $txtvalue" _err "Problem: $response" return 1 fi fi - _err "Problem creating TXT DNS record" + _err "Problem deleting TXT DNS record" } #################### Private functions below ################################## From 0415c050a5dbce75ed8bf89abb9ef2d361a1e589 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 13 Aug 2020 23:04:19 +0800 Subject: [PATCH 053/190] remove gitads --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index f5631475..e50489dc 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,6 @@ acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial - GitAds - - - - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. - Support ACME v1 and ACME v2 From a6d22e3b2215f85ca1f5cae7fa73adbc34697125 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 13 Aug 2020 23:12:30 +0800 Subject: [PATCH 054/190] 1. save the CA url anyway. 2. clear some code. --- acme.sh | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/acme.sh b/acme.sh index 9505ae2c..406a158d 100755 --- a/acme.sh +++ b/acme.sh @@ -52,9 +52,6 @@ DEFAULT_DOMAIN_KEY_LENGTH=2048 DEFAULT_OPENSSL_BIN="openssl" -_OLD_CA_HOST="https://acme-v01.api.letsencrypt.org" -_OLD_STAGE_CA_HOST="https://acme-staging.api.letsencrypt.org" - VTYPE_HTTP="http-01" VTYPE_DNS="dns-01" VTYPE_ALPN="tls-alpn-01" @@ -2595,11 +2592,6 @@ _initpath() { CA_HOME="$DEFAULT_CA_HOME" fi - if [ "$ACME_VERSION" = "2" ]; then - DEFAULT_CA="$CA_LETSENCRYPT_V2" - DEFAULT_STAGING_CA="$CA_LETSENCRYPT_V2_TEST" - fi - if [ -z "$ACME_DIRECTORY" ]; then default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") _debug default_acme_server "$default_acme_server" @@ -4088,12 +4080,9 @@ issue() { _cleardomainconf "Le_ChallengeAlias" fi - if [ "$ACME_DIRECTORY" != "$DEFAULT_CA" ]; then - Le_API="$ACME_DIRECTORY" - _savedomainconf "Le_API" "$Le_API" - else - _cleardomainconf Le_API - fi + Le_API="$ACME_DIRECTORY" + _savedomainconf "Le_API" "$Le_API" + _info "Using CA: $ACME_DIRECTORY" if [ "$_alt_domains" = "$NO_VALUE" ]; then _alt_domains="" @@ -4980,14 +4969,6 @@ renew() { fi if [ "$Le_API" ]; then - if [ "$_OLD_CA_HOST" = "$Le_API" ]; then - export Le_API="$DEFAULT_CA" - _savedomainconf Le_API "$Le_API" - fi - if [ "$_OLD_STAGE_CA_HOST" = "$Le_API" ]; then - export Le_API="$DEFAULT_STAGING_CA" - _savedomainconf Le_API "$Le_API" - fi export ACME_DIRECTORY="$Le_API" #reload ca configs ACCOUNT_KEY_PATH="" From b3a801df110d75886e15e8f6f10e8b1c77b0301a Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 15 Aug 2020 10:33:24 +0800 Subject: [PATCH 055/190] fix test endpoint --- acme.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index 406a158d..a7e6d7ef 100755 --- a/acme.sh +++ b/acme.sh @@ -2593,16 +2593,16 @@ _initpath() { fi if [ -z "$ACME_DIRECTORY" ]; then - default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") - _debug default_acme_server "$default_acme_server" - if [ "$default_acme_server" ]; then - ACME_DIRECTORY="$default_acme_server" + if [ "$STAGE" ]; then + ACME_DIRECTORY="$DEFAULT_STAGING_CA" + _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" else - if [ -z "$STAGE" ]; then - ACME_DIRECTORY="$DEFAULT_CA" + default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") + _debug default_acme_server "$default_acme_server" + if [ "$default_acme_server" ]; then + ACME_DIRECTORY="$default_acme_server" else - ACME_DIRECTORY="$DEFAULT_STAGING_CA" - _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + ACME_DIRECTORY="$DEFAULT_CA" fi fi fi From 95ef046d0a04836c465e720841cb3811ec7e2a3b Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 15 Aug 2020 12:32:15 +0800 Subject: [PATCH 056/190] fix https://github.com/acmesh-official/acme.sh/issues/3103 --- acme.sh | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index a7e6d7ef..d1e6f399 100755 --- a/acme.sh +++ b/acme.sh @@ -5228,13 +5228,17 @@ showcsr() { _info "KeyLength=$_csrkeylength" } +#listraw domain list() { _raw="$1" + _domain="$2" _initpath _sep="|" if [ "$_raw" ]; then - printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}CA${_sep}Created${_sep}Renew" + if [ -z "$_domain" ]; then + printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}CA${_sep}Created${_sep}Renew" + fi for di in "${CERT_HOME}"/*.*/; do d=$(basename "$di") _debug d "$d" @@ -5247,15 +5251,21 @@ list() { if [ -f "$DOMAIN_CONF" ]; then . "$DOMAIN_CONF" _ca="$(_getCAShortName "$Le_API")" - printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr" + if [ -z "$_domain" ]; then + printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr" + else + if [ "$_domain" = "$d" ]; then + cat "$DOMAIN_CONF" + fi + fi fi ) done else if _exists column; then - list "raw" | column -t -s "$_sep" + list "raw" "$_domain" | column -t -s "$_sep" else - list "raw" | tr "$_sep" '\t' + list "raw" "$_domain" | tr "$_sep" '\t' fi fi @@ -6595,6 +6605,9 @@ _selectServer() { #url _getCAShortName() { caurl="$1" + if [ -z "$caurl" ]; then + caurl="$DEFAULT_CA" + fi caurl_lower="$(echo $caurl | _lower_case)" _sindex=0 for surl in $(echo "$CA_SERVERS" | _lower_case | tr , ' '); do @@ -7271,7 +7284,7 @@ _process() { deactivateaccount ;; list) - list "$_listraw" + list "$_listraw" "$_domain" ;; installcronjob) installcronjob "$_confighome" ;; uninstallcronjob) uninstallcronjob ;; From e3ebd582ec62aacd77c73dbc11b7567492b00c51 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 16 Aug 2020 16:57:06 +0800 Subject: [PATCH 057/190] support "--preferred-chain" to select chain https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain --- acme.sh | 145 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 112 insertions(+), 33 deletions(-) diff --git a/acme.sh b/acme.sh index d1e6f399..e0f11e30 100755 --- a/acme.sh +++ b/acme.sh @@ -146,6 +146,8 @@ _DNS_ALIAS_WIKI="https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode" _DNS_MANUAL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode" +_DNS_API_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnsapi" + _NOTIFY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/notify" _SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo" @@ -156,6 +158,8 @@ _ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA" _SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server" +_PREFERRED_CHAIN_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -3985,6 +3989,20 @@ _check_dns_entries() { } +#file +_get_cert_issuer() { + _cfile="$1" + echo $(openssl x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2) +} + +#cert issuer +_match_issuer() { + _cfile="$1" + _missuer="$2" + _fissuer=$(_get_cert_issuer $_cfile) + [ "$_missuer" = "$_fissuer" ] +} + #webroot, domain domainlist keylength issue() { if [ -z "$2" ]; then @@ -4017,16 +4035,7 @@ issue() { _renew_hook="${12}" _local_addr="${13}" _challenge_alias="${14}" - #remove these later. - if [ "$_web_roots" = "dns-cf" ]; then - _web_roots="dns_cf" - fi - if [ "$_web_roots" = "dns-dp" ]; then - _web_roots="dns_dp" - fi - if [ "$_web_roots" = "dns-cx" ]; then - _web_roots="dns_cx" - fi + _preferred_chain="${15}" if [ ! "$IS_RENEW" ]; then _initpath "$_main_domain" "$_key_length" @@ -4079,6 +4088,11 @@ issue() { else _cleardomainconf "Le_ChallengeAlias" fi + if [ "$_preferred_chain" ]; then + _savedomainconf "Le_Preferred_Chain" "$_preferred_chain" "base64" + else + _cleardomainconf "Le_Preferred_Chain" + fi Le_API="$ACME_DIRECTORY" _savedomainconf "Le_API" "$Le_API" @@ -4746,7 +4760,7 @@ $_authorizations_map" _on_issue_err "$_post_hook" return 1 fi - _info "Download cert, Le_LinkCert: $Le_LinkCert" + _info "Downloading cert, Le_LinkCert: $Le_LinkCert" if ! _send_signed_request "$Le_LinkCert"; then _err "Sign failed, can not download cert:$Le_LinkCert." _err "$response" @@ -4755,17 +4769,36 @@ $_authorizations_map" fi echo "$response" >"$CERT_PATH" - - if [ "$(grep -- "$BEGIN_CERT" "$CERT_PATH" | wc -l)" -gt "1" ]; then - _debug "Found cert chain" - cat "$CERT_PATH" >"$CERT_FULLCHAIN_PATH" - _end_n="$(grep -n -- "$END_CERT" "$CERT_FULLCHAIN_PATH" | _head_n 1 | cut -d : -f 1)" - _debug _end_n "$_end_n" - sed -n "1,${_end_n}p" "$CERT_FULLCHAIN_PATH" >"$CERT_PATH" - _end_n="$(_math $_end_n + 1)" - sed -n "${_end_n},9999p" "$CERT_FULLCHAIN_PATH" >"$CA_CERT_PATH" + _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" + + if [ "$_preferred_chain" ]; then + _cert_issuer=$(_get_cert_issuer "$CA_CERT_PATH") + _debug _cert_issuer "$_cert_issuer" + if ! _match_issuer "$CA_CERT_PATH" "$_preferred_chain"; then + rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" + _debug2 "rels" "$rels" + for rel in $rels; do + _info "Try rel: $rel" + if ! _send_signed_request "$rel"; then + _err "Sign failed, can not download cert:$rel" + _err "$response" + continue + fi + _relcert="$CERT_PATH.alt" + _relfullchain="$CERT_FULLCHAIN_PATH.alt" + _relca="$CA_CERT_PATH.alt" + echo "$response" >"$_relcert" + _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" + if _match_issuer "$_relca" "$_preferred_chain"; then + _info "Matched issuer in: $rel" + cat $_relcert >"$CERT_PATH" + cat $_relfullchain >"$CERT_FULLCHAIN_PATH" + cat $_relca >"$CA_CERT_PATH" + break + fi + done + fi fi - else if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then _err "Sign failed. $response" @@ -4934,6 +4967,22 @@ $_authorizations_map" fi } +#in_out_cert out_fullchain out out_ca +_split_cert_chain() { + _certf="$1" + _fullchainf="$2" + _caf="$3" + if [ "$(grep -- "$BEGIN_CERT" "$_certf" | wc -l)" -gt "1" ]; then + _debug "Found cert chain" + cat "$_certf" >"$_fullchainf" + _end_n="$(grep -n -- "$END_CERT" "$_fullchainf" | _head_n 1 | cut -d : -f 1)" + _debug _end_n "$_end_n" + sed -n "1,${_end_n}p" "$_fullchainf" >"$_certf" + _end_n="$(_math $_end_n + 1)" + sed -n "${_end_n},9999p" "$_fullchainf" >"$_caf" + fi +} + #domain [isEcc] renew() { Le_Domain="$1" @@ -4994,7 +5043,7 @@ renew() { Le_PreHook="$(_readdomainconf Le_PreHook)" Le_PostHook="$(_readdomainconf Le_PostHook)" Le_RenewHook="$(_readdomainconf Le_RenewHook)" - issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" + issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain" res="$?" if [ "$res" != "0" ]; then return "$res" @@ -6379,19 +6428,34 @@ Commands: Parameters: --domain, -d domain.tld Specifies a domain, used to issue, renew or revoke etc. - --challenge-alias domain.tld The challenge domain alias for DNS alias mode: $_DNS_ALIAS_WIKI - --domain-alias domain.tld The domain alias for DNS alias mode: $_DNS_ALIAS_WIKI + --challenge-alias domain.tld The challenge domain alias for DNS alias mode. + See: $_DNS_ALIAS_WIKI + + --domain-alias domain.tld The domain alias for DNS alias mode. + See: $_DNS_ALIAS_WIKI + + --preferred-chain CHAIN If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. + If no match, the default offered chain will be used. (default: empty) + See: $_PREFERRED_CHAIN_WIKI + --force, -f Used to force to install or force to renew a cert immediately. --staging, --test Use staging server, just for test. --debug Output debug info. - --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for security. + --output-insecure Output all the sensitive messages. + By default all the credentials/sensitive messages are hidden from the output/debug/log for security. + --webroot, -w /path/to/webroot Specifies the web root folder for web root mode. --standalone Use standalone mode. --alpn Use standalone alpn mode. - --stateless Use stateless mode, see: $_STATELESS_WIKI + --stateless Use stateless mode. + See: $_STATELESS_WIKI + --apache Use apache mode. - --dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api. - --dnssleep 300 The time in seconds to wait for all the txt records to take effect in dns api mode. It's not necessary to use this by default, $PROJECT_NAME polls dns status automatically. + --dns [dns_hook] Use dns mode or dns api. + See: $_DNS_API_WIKI + + --dnssleep 300 The time in seconds to wait for all the txt records to propagate in dns api mode. + It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically. --keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. --accountkeylength, -ak [2048] Specifies the account key length: 2048, 3072, 4096 @@ -6412,7 +6476,9 @@ Parameters: --reloadcmd \"service nginx reload\" After issue/renew, it's used to reload the server. - --server SERVER ACME Directory Resource URI. See: $_SERVER_WIKI (default: $DEFAULT_CA) + --server SERVER ACME Directory Resource URI. (default: $DEFAULT_CA) + See: $_SERVER_WIKI + --accountconf Specifies a customized account config file. --home Specifies the home dir for $PROJECT_NAME. --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. @@ -6429,7 +6495,9 @@ Parameters: --insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted. --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. - --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. + --nocron Only valid for '--install' command, which means: do not install the default cron job. + In this case, the certs will not be renewed automatically. + --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. @@ -6446,7 +6514,9 @@ Parameters: --listen-v6 Force standalone/tls server to listen at ipv6. --openssl-bin Specifies a custom openssl bin location. --use-wget Force to use wget, if you have both curl and wget installed. - --yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode: $_DNS_MANUAL_WIKI + --yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode. + See: $_DNS_MANUAL_WIKI + --branch, -b Only valid for '--upgrade' command, specifies the branch name to upgrade to. --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. @@ -6454,11 +6524,15 @@ Parameters: 1: send notifications only when there is an error. 2: send notifications when a cert is successfully renewed, or there is an error. 3: send notifications when a cert is skipped, renewed, or error. + --notify-mode 0|1 Set notification mode. Default value is $NOTIFY_MODE_DEFAULT. 0: Bulk mode. Send all the domain's notifications in one message(mail). 1: Cert mode. Send a message for every single cert. + --notify-hook [hookname] Set the notify hook - --revoke-reason [0-10] The reason for '--revoke' command. See: $_REVOKE_WIKI + --revoke-reason [0-10] The reason for '--revoke' command. + See: $_REVOKE_WIKI + " } @@ -6689,6 +6763,7 @@ _process() { _revoke_reason="" _eab_kid="" _eab_hmac_key="" + _preferred_chain="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -7179,6 +7254,10 @@ _process() { _eab_hmac_key="$2" shift ;; + --preferred-chain) + _preferred_chain="$2" + shift + ;; *) _err "Unknown parameter : $1" return 1 @@ -7245,7 +7324,7 @@ _process() { uninstall) uninstall "$_nocron" ;; upgrade) upgrade ;; issue) - issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" + issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" ;; deploy) deploy "$_domain" "$_deploy_hook" "$_ecc" From 0b531e9fbce6a8493a8a9b8af53fead0528af0f3 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 16 Aug 2020 16:59:08 +0800 Subject: [PATCH 058/190] fix format --- dnsapi/dns_kappernet.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 47a871c1..b3481c6c 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -25,7 +25,7 @@ dns_kappernet_add() { KAPPERNETDNS_Secret="" _err "Please specify your kapper.net api key and secret." _err "If you have not received yours - send your mail to" - _err "support@kapper.net to get your key and secret." + _err "support@kapper.net to get your key and secret." return 1 fi @@ -72,7 +72,7 @@ dns_kappernet_rm() { KAPPERNETDNS_Secret="" _err "Please specify your kapper.net api key and secret." _err "If you have not received yours - send your mail to" - _err "support@kapper.net to get your key and secret." + _err "support@kapper.net to get your key and secret." return 1 fi From bd04638d2779804524986c87d65f13f159460582 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 16 Aug 2020 17:36:24 +0800 Subject: [PATCH 059/190] minor --- acme.sh | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/acme.sh b/acme.sh index e0f11e30..bc64f377 100755 --- a/acme.sh +++ b/acme.sh @@ -1473,7 +1473,7 @@ createDomainKey() { _initpath "$domain" "$_cdl" - if [ ! -f "$CERT_KEY_PATH" ] || [ ! -s "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then + if [ ! -f "$CERT_KEY_PATH" ] || [ ! -s "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$_ACME_IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then if _createkey "$_cdl" "$CERT_KEY_PATH"; then _savedomainconf Le_Keylength "$_cdl" _info "The domain key is here: $(__green $CERT_KEY_PATH)" @@ -1483,7 +1483,7 @@ createDomainKey() { return 1 fi else - if [ "$IS_RENEW" ]; then + if [ "$_ACME_IS_RENEW" ]; then _info "Domain key exists, skip" return 0 else @@ -1509,7 +1509,7 @@ createCSR() { _initpath "$domain" "$_isEcc" - if [ -f "$CSR_PATH" ] && [ "$IS_RENEW" ] && [ -z "$FORCE" ]; then + if [ -f "$CSR_PATH" ] && [ "$_ACME_IS_RENEW" ] && [ -z "$FORCE" ]; then _info "CSR exists, skip" return fi @@ -2585,7 +2585,7 @@ _initpath() { . "$ACCOUNT_CONF_PATH" fi - if [ "$ACME_IN_CRON" ]; then + if [ "$_ACME_IN_CRON" ]; then if [ ! "$_USER_PATH_EXPORTED" ]; then _USER_PATH_EXPORTED=1 export PATH="$USER_PATH:$PATH" @@ -2599,7 +2599,7 @@ _initpath() { if [ -z "$ACME_DIRECTORY" ]; then if [ "$STAGE" ]; then ACME_DIRECTORY="$DEFAULT_STAGING_CA" - _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY" + _info "Using ACME_DIRECTORY: $ACME_DIRECTORY" else default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER") _debug default_acme_server "$default_acme_server" @@ -3387,7 +3387,7 @@ _on_issue_err() { ) fi - if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "$W_DNS"; then + if [ "$_ACME_IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "$W_DNS"; then _err "$_DNS_MANUAL_ERR" fi @@ -3419,7 +3419,7 @@ _on_issue_success() { fi #run renew hook - if [ "$IS_RENEW" ] && [ "$_chk_renew_hook" ]; then + if [ "$_ACME_IS_RENEW" ] && [ "$_chk_renew_hook" ]; then _info "Run renew hook:'$_chk_renew_hook'" if ! ( export CERT_PATH @@ -4037,7 +4037,7 @@ issue() { _challenge_alias="${14}" _preferred_chain="${15}" - if [ ! "$IS_RENEW" ]; then + if [ -z "$_ACME_IS_RENEW" ]; then _initpath "$_main_domain" "$_key_length" mkdir -p "$DOMAIN_PATH" fi @@ -4689,7 +4689,8 @@ $_authorizations_map" der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" if [ "$ACME_VERSION" = "2" ]; then - _info "Lets finalize the order, Le_OrderFinalize: $Le_OrderFinalize" + _info "Lets finalize the order." + _info "Le_OrderFinalize" "$Le_OrderFinalize" if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then _err "Sign failed." _on_issue_err "$_post_hook" @@ -4760,7 +4761,8 @@ $_authorizations_map" _on_issue_err "$_post_hook" return 1 fi - _info "Downloading cert, Le_LinkCert: $Le_LinkCert" + _info "Downloading cert." + _info "Le_LinkCert" "$Le_LinkCert" if ! _send_signed_request "$Le_LinkCert"; then _err "Sign failed, can not download cert:$Le_LinkCert." _err "$response" @@ -4842,7 +4844,7 @@ $_authorizations_map" _info "Your cert key is in $(__green " $CERT_KEY_PATH ")" fi - if [ ! "$USER_PATH" ] || [ ! "$ACME_IN_CRON" ]; then + if [ ! "$USER_PATH" ] || [ ! "$_ACME_IN_CRON" ]; then USER_PATH="$PATH" _saveaccountconf "USER_PATH" "$USER_PATH" fi @@ -5033,12 +5035,12 @@ renew() { return "$RENEW_SKIP" fi - if [ "$ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then + if [ "$_ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then _info "Skip invalid cert for: $Le_Domain" return $RENEW_SKIP fi - IS_RENEW="1" + _ACME_IS_RENEW="1" Le_ReloadCmd="$(_readdomainconf Le_ReloadCmd)" Le_PreHook="$(_readdomainconf Le_PreHook)" Le_PostHook="$(_readdomainconf Le_PostHook)" @@ -5054,7 +5056,7 @@ renew() { res="$?" fi - IS_RENEW="" + _ACME_IS_RENEW="" return "$res" } @@ -5094,7 +5096,7 @@ renewAll() { _error_level="$NOTIFY_LEVEL_RENEW" _notify_code=0 fi - if [ "$ACME_IN_CRON" ]; then + if [ "$_ACME_IN_CRON" ]; then if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then _send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0 @@ -5108,7 +5110,7 @@ renewAll() { _error_level="$NOTIFY_LEVEL_SKIP" _notify_code=$RENEW_SKIP fi - if [ "$ACME_IN_CRON" ]; then + if [ "$_ACME_IN_CRON" ]; then if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then _send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" @@ -5123,7 +5125,7 @@ renewAll() { _error_level="$NOTIFY_LEVEL_ERROR" _notify_code=1 fi - if [ "$ACME_IN_CRON" ]; then + if [ "$_ACME_IN_CRON" ]; then if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then _send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1 @@ -5144,7 +5146,7 @@ renewAll() { done _debug _error_level "$_error_level" _debug _set_level "$_set_level" - if [ "$ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then + if [ "$_ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then _msg_subject="Renew" if [ "$_error_msg" ]; then @@ -5442,7 +5444,7 @@ _installcert() { if [ "$_real_cert" ]; then _info "Installing cert to:$_real_cert" - if [ -f "$_real_cert" ] && [ ! "$IS_RENEW" ]; then + if [ -f "$_real_cert" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_cert" "$_backup_path/cert.bak" fi cat "$CERT_PATH" >"$_real_cert" || return 1 @@ -5454,7 +5456,7 @@ _installcert() { echo "" >>"$_real_ca" cat "$CA_CERT_PATH" >>"$_real_ca" || return 1 else - if [ -f "$_real_ca" ] && [ ! "$IS_RENEW" ]; then + if [ -f "$_real_ca" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_ca" "$_backup_path/ca.bak" fi cat "$CA_CERT_PATH" >"$_real_ca" || return 1 @@ -5463,7 +5465,7 @@ _installcert() { if [ "$_real_key" ]; then _info "Installing key to:$_real_key" - if [ -f "$_real_key" ] && [ ! "$IS_RENEW" ]; then + if [ -f "$_real_key" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_key" "$_backup_path/key.bak" fi if [ -f "$_real_key" ]; then @@ -5476,7 +5478,7 @@ _installcert() { if [ "$_real_fullchain" ]; then _info "Installing full chain to:$_real_fullchain" - if [ -f "$_real_fullchain" ] && [ ! "$IS_RENEW" ]; then + if [ -f "$_real_fullchain" ] && [ ! "$_ACME_IS_RENEW" ]; then cp "$_real_fullchain" "$_backup_path/fullchain.bak" fi cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain" || return 1 @@ -6093,7 +6095,7 @@ install() { _debug "Skip install cron job" fi - if [ "$ACME_IN_CRON" != "1" ]; then + if [ "$_ACME_IN_CRON" != "1" ]; then if ! _precheck "$_nocron"; then _err "Pre-check failed, can not install." return 1 @@ -6150,7 +6152,7 @@ install() { _info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY" - if [ "$ACME_IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then + if [ "$_ACME_IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then _installalias "$_c_home" fi @@ -6248,7 +6250,7 @@ _uninstallalias() { } cron() { - export ACME_IN_CRON=1 + export _ACME_IN_CRON=1 _initpath _info "$(__green "===Starting cron===")" if [ "$AUTO_UPGRADE" = "1" ]; then @@ -6269,7 +6271,7 @@ cron() { fi renewAll _ret="$?" - ACME_IN_CRON="" + _ACME_IN_CRON="" _info "$(__green "===End cron===")" exit $_ret } From d5d38b3331d2c4018ff4d5662e8a6f62d1055f9a Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:06:02 +0800 Subject: [PATCH 060/190] support multiple intermediate CA matching for `--preferred-chain` --- acme.sh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/acme.sh b/acme.sh index bc64f377..e7f6a5d9 100755 --- a/acme.sh +++ b/acme.sh @@ -3990,17 +3990,22 @@ _check_dns_entries() { } #file -_get_cert_issuer() { +_get_cert_issuers() { _cfile="$1" - echo $(openssl x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2) + if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7"; then + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | openssl pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + else + ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + fi } #cert issuer _match_issuer() { _cfile="$1" _missuer="$2" - _fissuer=$(_get_cert_issuer $_cfile) - [ "$_missuer" = "$_fissuer" ] + _fissuers="$(_get_cert_issuers $_cfile)" + _debug2 _fissuers "$_fissuers" + _contains "$_fissuers" "$_missuer" } #webroot, domain domainlist keylength @@ -4773,10 +4778,8 @@ $_authorizations_map" echo "$response" >"$CERT_PATH" _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" - if [ "$_preferred_chain" ]; then - _cert_issuer=$(_get_cert_issuer "$CA_CERT_PATH") - _debug _cert_issuer "$_cert_issuer" - if ! _match_issuer "$CA_CERT_PATH" "$_preferred_chain"; then + if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then + if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" _debug2 "rels" "$rels" for rel in $rels; do @@ -4791,7 +4794,7 @@ $_authorizations_map" _relca="$CA_CERT_PATH.alt" echo "$response" >"$_relcert" _split_cert_chain "$_relcert" "$_relfullchain" "$_relca" - if _match_issuer "$_relca" "$_preferred_chain"; then + if _match_issuer "$_relfullchain" "$_preferred_chain"; then _info "Matched issuer in: $rel" cat $_relcert >"$CERT_PATH" cat $_relfullchain >"$CERT_FULLCHAIN_PATH" From 19c4345162ddcba0d5c2b985f8739761c361582a Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:18:20 +0800 Subject: [PATCH 061/190] fix shfmt --- acme.sh | 1596 +++++++++++++++++------------------ deploy/exim4.sh | 4 +- deploy/ssh.sh | 10 +- deploy/vsftpd.sh | 6 +- dnsapi/dns_arvan.sh | 2 +- dnsapi/dns_aws.sh | 18 +- dnsapi/dns_azure.sh | 2 +- dnsapi/dns_conoha.sh | 6 +- dnsapi/dns_cyon.sh | 28 +- dnsapi/dns_da.sh | 34 +- dnsapi/dns_do.sh | 24 +- dnsapi/dns_easydns.sh | 2 +- dnsapi/dns_freedns.sh | 18 +- dnsapi/dns_gandi_livedns.sh | 16 +- dnsapi/dns_gcloud.sh | 12 +- dnsapi/dns_he.sh | 4 +- dnsapi/dns_hetzner.sh | 8 +- dnsapi/dns_ispconfig.sh | 74 +- dnsapi/dns_joker.sh | 2 +- dnsapi/dns_kappernet.sh | 8 +- dnsapi/dns_netlify.sh | 2 +- dnsapi/dns_one.sh | 4 +- dnsapi/dns_ovh.sh | 68 +- dnsapi/dns_pleskxml.sh | 41 +- dnsapi/dns_regru.sh | 10 +- notify/mail.sh | 56 +- notify/teams.sh | 18 +- notify/xmpp.sh | 14 +- 28 files changed, 1045 insertions(+), 1042 deletions(-) diff --git a/acme.sh b/acme.sh index e7f6a5d9..45e0c246 100755 --- a/acme.sh +++ b/acme.sh @@ -524,27 +524,27 @@ _math() { _h_char_2_dec() { _ch=$1 case "${_ch}" in - a | A) - printf "10" - ;; - b | B) - printf "11" - ;; - c | C) - printf "12" - ;; - d | D) - printf "13" - ;; - e | E) - printf "14" - ;; - f | F) - printf "15" - ;; - *) - printf "%s" "$_ch" - ;; + a | A) + printf "10" + ;; + b | B) + printf "11" + ;; + c | C) + printf "12" + ;; + d | D) + printf "13" + ;; + e | E) + printf "14" + ;; + f | F) + printf "15" + ;; + *) + printf "%s" "$_ch" + ;; esac } @@ -652,211 +652,211 @@ _url_encode() { for _hex_code in $_hex_str; do #upper case case "${_hex_code}" in - "41") - printf "%s" "A" - ;; - "42") - printf "%s" "B" - ;; - "43") - printf "%s" "C" - ;; - "44") - printf "%s" "D" - ;; - "45") - printf "%s" "E" - ;; - "46") - printf "%s" "F" - ;; - "47") - printf "%s" "G" - ;; - "48") - printf "%s" "H" - ;; - "49") - printf "%s" "I" - ;; - "4a") - printf "%s" "J" - ;; - "4b") - printf "%s" "K" - ;; - "4c") - printf "%s" "L" - ;; - "4d") - printf "%s" "M" - ;; - "4e") - printf "%s" "N" - ;; - "4f") - printf "%s" "O" - ;; - "50") - printf "%s" "P" - ;; - "51") - printf "%s" "Q" - ;; - "52") - printf "%s" "R" - ;; - "53") - printf "%s" "S" - ;; - "54") - printf "%s" "T" - ;; - "55") - printf "%s" "U" - ;; - "56") - printf "%s" "V" - ;; - "57") - printf "%s" "W" - ;; - "58") - printf "%s" "X" - ;; - "59") - printf "%s" "Y" - ;; - "5a") - printf "%s" "Z" - ;; + "41") + printf "%s" "A" + ;; + "42") + printf "%s" "B" + ;; + "43") + printf "%s" "C" + ;; + "44") + printf "%s" "D" + ;; + "45") + printf "%s" "E" + ;; + "46") + printf "%s" "F" + ;; + "47") + printf "%s" "G" + ;; + "48") + printf "%s" "H" + ;; + "49") + printf "%s" "I" + ;; + "4a") + printf "%s" "J" + ;; + "4b") + printf "%s" "K" + ;; + "4c") + printf "%s" "L" + ;; + "4d") + printf "%s" "M" + ;; + "4e") + printf "%s" "N" + ;; + "4f") + printf "%s" "O" + ;; + "50") + printf "%s" "P" + ;; + "51") + printf "%s" "Q" + ;; + "52") + printf "%s" "R" + ;; + "53") + printf "%s" "S" + ;; + "54") + printf "%s" "T" + ;; + "55") + printf "%s" "U" + ;; + "56") + printf "%s" "V" + ;; + "57") + printf "%s" "W" + ;; + "58") + printf "%s" "X" + ;; + "59") + printf "%s" "Y" + ;; + "5a") + printf "%s" "Z" + ;; #lower case - "61") - printf "%s" "a" - ;; - "62") - printf "%s" "b" - ;; - "63") - printf "%s" "c" - ;; - "64") - printf "%s" "d" - ;; - "65") - printf "%s" "e" - ;; - "66") - printf "%s" "f" - ;; - "67") - printf "%s" "g" - ;; - "68") - printf "%s" "h" - ;; - "69") - printf "%s" "i" - ;; - "6a") - printf "%s" "j" - ;; - "6b") - printf "%s" "k" - ;; - "6c") - printf "%s" "l" - ;; - "6d") - printf "%s" "m" - ;; - "6e") - printf "%s" "n" - ;; - "6f") - printf "%s" "o" - ;; - "70") - printf "%s" "p" - ;; - "71") - printf "%s" "q" - ;; - "72") - printf "%s" "r" - ;; - "73") - printf "%s" "s" - ;; - "74") - printf "%s" "t" - ;; - "75") - printf "%s" "u" - ;; - "76") - printf "%s" "v" - ;; - "77") - printf "%s" "w" - ;; - "78") - printf "%s" "x" - ;; - "79") - printf "%s" "y" - ;; - "7a") - printf "%s" "z" - ;; + "61") + printf "%s" "a" + ;; + "62") + printf "%s" "b" + ;; + "63") + printf "%s" "c" + ;; + "64") + printf "%s" "d" + ;; + "65") + printf "%s" "e" + ;; + "66") + printf "%s" "f" + ;; + "67") + printf "%s" "g" + ;; + "68") + printf "%s" "h" + ;; + "69") + printf "%s" "i" + ;; + "6a") + printf "%s" "j" + ;; + "6b") + printf "%s" "k" + ;; + "6c") + printf "%s" "l" + ;; + "6d") + printf "%s" "m" + ;; + "6e") + printf "%s" "n" + ;; + "6f") + printf "%s" "o" + ;; + "70") + printf "%s" "p" + ;; + "71") + printf "%s" "q" + ;; + "72") + printf "%s" "r" + ;; + "73") + printf "%s" "s" + ;; + "74") + printf "%s" "t" + ;; + "75") + printf "%s" "u" + ;; + "76") + printf "%s" "v" + ;; + "77") + printf "%s" "w" + ;; + "78") + printf "%s" "x" + ;; + "79") + printf "%s" "y" + ;; + "7a") + printf "%s" "z" + ;; #numbers - "30") - printf "%s" "0" - ;; - "31") - printf "%s" "1" - ;; - "32") - printf "%s" "2" - ;; - "33") - printf "%s" "3" - ;; - "34") - printf "%s" "4" - ;; - "35") - printf "%s" "5" - ;; - "36") - printf "%s" "6" - ;; - "37") - printf "%s" "7" - ;; - "38") - printf "%s" "8" - ;; - "39") - printf "%s" "9" - ;; - "2d") - printf "%s" "-" - ;; - "5f") - printf "%s" "_" - ;; - "2e") - printf "%s" "." - ;; - "7e") - printf "%s" "~" - ;; - #other hex - *) - printf '%%%s' "$_hex_code" - ;; + "30") + printf "%s" "0" + ;; + "31") + printf "%s" "1" + ;; + "32") + printf "%s" "2" + ;; + "33") + printf "%s" "3" + ;; + "34") + printf "%s" "4" + ;; + "35") + printf "%s" "5" + ;; + "36") + printf "%s" "6" + ;; + "37") + printf "%s" "7" + ;; + "38") + printf "%s" "8" + ;; + "39") + printf "%s" "9" + ;; + "2d") + printf "%s" "-" + ;; + "5f") + printf "%s" "_" + ;; + "2e") + printf "%s" "." + ;; + "7e") + printf "%s" "~" + ;; + #other hex + *) + printf '%%%s' "$_hex_code" + ;; esac done } @@ -1077,11 +1077,11 @@ _isEccKey() { return 1 fi - [ "$_length" != "1024" ] \ - && [ "$_length" != "2048" ] \ - && [ "$_length" != "3072" ] \ - && [ "$_length" != "4096" ] \ - && [ "$_length" != "8192" ] + [ "$_length" != "1024" ] && + [ "$_length" != "2048" ] && + [ "$_length" != "3072" ] && + [ "$_length" != "4096" ] && + [ "$_length" != "8192" ] } # _createkey 2048|ec-256 file @@ -1630,22 +1630,22 @@ _calcjwk() { crv_oid="$(${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^ASN1 OID:" | cut -d ":" -f 2 | tr -d " \r\n")" _debug3 crv_oid "$crv_oid" case "${crv_oid}" in - "prime256v1") - crv="P-256" - __ECC_KEY_LEN=256 - ;; - "secp384r1") - crv="P-384" - __ECC_KEY_LEN=384 - ;; - "secp521r1") - crv="P-521" - __ECC_KEY_LEN=512 - ;; - *) - _err "ECC oid : $crv_oid" - return 1 - ;; + "prime256v1") + crv="P-256" + __ECC_KEY_LEN=256 + ;; + "secp384r1") + crv="P-384" + __ECC_KEY_LEN=384 + ;; + "secp521r1") + crv="P-521" + __ECC_KEY_LEN=512 + ;; + *) + _err "ECC oid : $crv_oid" + return 1 + ;; esac _debug3 crv "$crv" fi @@ -6772,501 +6772,501 @@ _process() { while [ ${#} -gt 0 ]; do case "${1}" in - --help | -h) - showhelp - return - ;; - --version | -v) - version - return - ;; - --install) - _CMD="install" - ;; - --uninstall) - _CMD="uninstall" - ;; - --upgrade) - _CMD="upgrade" - ;; - --issue) - _CMD="issue" - ;; - --deploy) - _CMD="deploy" - ;; - --signcsr) - _CMD="signcsr" - ;; - --showcsr) - _CMD="showcsr" - ;; - --installcert | -i | --install-cert) - _CMD="installcert" - ;; - --renew | -r) - _CMD="renew" - ;; - --renewAll | --renewall | --renew-all) - _CMD="renewAll" - ;; - --revoke) - _CMD="revoke" - ;; - --remove) - _CMD="remove" - ;; - --list) - _CMD="list" - ;; - --installcronjob | --install-cronjob) - _CMD="installcronjob" - ;; - --uninstallcronjob | --uninstall-cronjob) - _CMD="uninstallcronjob" - ;; - --cron) - _CMD="cron" - ;; - --toPkcs) - _CMD="toPkcs" - ;; - --toPkcs8) - _CMD="toPkcs8" - ;; - --createAccountKey | --createaccountkey | -cak | --create-account-key) - _CMD="createAccountKey" - ;; - --createDomainKey | --createdomainkey | -cdk | --create-domain-key) - _CMD="createDomainKey" - ;; - --createCSR | --createcsr | -ccr) - _CMD="createCSR" - ;; - --deactivate) - _CMD="deactivate" - ;; - --updateaccount | --update-account) - _CMD="updateaccount" - ;; - --registeraccount | --register-account) - _CMD="registeraccount" - ;; - --deactivate-account) - _CMD="deactivateaccount" - ;; - --set-notify) - _CMD="setnotify" - ;; - --set-default-ca) - _CMD="setdefaultca" - ;; - --domain | -d) - _dvalue="$2" + --help | -h) + showhelp + return + ;; + --version | -v) + version + return + ;; + --install) + _CMD="install" + ;; + --uninstall) + _CMD="uninstall" + ;; + --upgrade) + _CMD="upgrade" + ;; + --issue) + _CMD="issue" + ;; + --deploy) + _CMD="deploy" + ;; + --signcsr) + _CMD="signcsr" + ;; + --showcsr) + _CMD="showcsr" + ;; + --installcert | -i | --install-cert) + _CMD="installcert" + ;; + --renew | -r) + _CMD="renew" + ;; + --renewAll | --renewall | --renew-all) + _CMD="renewAll" + ;; + --revoke) + _CMD="revoke" + ;; + --remove) + _CMD="remove" + ;; + --list) + _CMD="list" + ;; + --installcronjob | --install-cronjob) + _CMD="installcronjob" + ;; + --uninstallcronjob | --uninstall-cronjob) + _CMD="uninstallcronjob" + ;; + --cron) + _CMD="cron" + ;; + --toPkcs) + _CMD="toPkcs" + ;; + --toPkcs8) + _CMD="toPkcs8" + ;; + --createAccountKey | --createaccountkey | -cak | --create-account-key) + _CMD="createAccountKey" + ;; + --createDomainKey | --createdomainkey | -cdk | --create-domain-key) + _CMD="createDomainKey" + ;; + --createCSR | --createcsr | -ccr) + _CMD="createCSR" + ;; + --deactivate) + _CMD="deactivate" + ;; + --updateaccount | --update-account) + _CMD="updateaccount" + ;; + --registeraccount | --register-account) + _CMD="registeraccount" + ;; + --deactivate-account) + _CMD="deactivateaccount" + ;; + --set-notify) + _CMD="setnotify" + ;; + --set-default-ca) + _CMD="setdefaultca" + ;; + --domain | -d) + _dvalue="$2" - if [ "$_dvalue" ]; then - if _startswith "$_dvalue" "-"; then - _err "'$_dvalue' is not a valid domain for parameter '$1'" - return 1 - fi - if _is_idn "$_dvalue" && ! _exists idn; then - _err "It seems that $_dvalue is an IDN( Internationalized Domain Names), please install 'idn' command first." - return 1 - fi + if [ "$_dvalue" ]; then + if _startswith "$_dvalue" "-"; then + _err "'$_dvalue' is not a valid domain for parameter '$1'" + return 1 + fi + if _is_idn "$_dvalue" && ! _exists idn; then + _err "It seems that $_dvalue is an IDN( Internationalized Domain Names), please install 'idn' command first." + return 1 + fi - if _startswith "$_dvalue" "*."; then - _debug "Wildcard domain" - export ACME_VERSION=2 - fi - if [ -z "$_domain" ]; then - _domain="$_dvalue" + if _startswith "$_dvalue" "*."; then + _debug "Wildcard domain" + export ACME_VERSION=2 + fi + if [ -z "$_domain" ]; then + _domain="$_dvalue" + else + if [ "$_altdomains" = "$NO_VALUE" ]; then + _altdomains="$_dvalue" else - if [ "$_altdomains" = "$NO_VALUE" ]; then - _altdomains="$_dvalue" - else - _altdomains="$_altdomains,$_dvalue" - fi + _altdomains="$_altdomains,$_dvalue" fi fi + fi - shift - ;; + shift + ;; - --force | -f) - FORCE="1" - ;; - --staging | --test) - STAGE="1" - ;; - --server) - _server="$2" - _selectServer "$_server" - shift - ;; - --debug) - if [ -z "$2" ] || _startswith "$2" "-"; then - DEBUG="$DEBUG_LEVEL_DEFAULT" - else - DEBUG="$2" - shift - fi - ;; - --output-insecure) - export OUTPUT_INSECURE=1 - ;; - --webroot | -w) - wvalue="$2" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - shift - ;; - --challenge-alias) - cvalue="$2" - _challenge_alias="$_challenge_alias$cvalue," - shift - ;; - --domain-alias) - cvalue="$DNS_ALIAS_PREFIX$2" - _challenge_alias="$_challenge_alias$cvalue," + --force | -f) + FORCE="1" + ;; + --staging | --test) + STAGE="1" + ;; + --server) + _server="$2" + _selectServer "$_server" + shift + ;; + --debug) + if [ -z "$2" ] || _startswith "$2" "-"; then + DEBUG="$DEBUG_LEVEL_DEFAULT" + else + DEBUG="$2" shift - ;; - --standalone) - wvalue="$NO_VALUE" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --alpn) - wvalue="$W_ALPN" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --stateless) - wvalue="$MODE_STATELESS" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --local-address) - lvalue="$2" - _local_address="$_local_address$lvalue," + fi + ;; + --output-insecure) + export OUTPUT_INSECURE=1 + ;; + --webroot | -w) + wvalue="$2" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + shift + ;; + --challenge-alias) + cvalue="$2" + _challenge_alias="$_challenge_alias$cvalue," + shift + ;; + --domain-alias) + cvalue="$DNS_ALIAS_PREFIX$2" + _challenge_alias="$_challenge_alias$cvalue," + shift + ;; + --standalone) + wvalue="$NO_VALUE" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --alpn) + wvalue="$W_ALPN" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --stateless) + wvalue="$MODE_STATELESS" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --local-address) + lvalue="$2" + _local_address="$_local_address$lvalue," + shift + ;; + --apache) + wvalue="apache" + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --nginx) + wvalue="$NGINX" + if [ "$2" ] && ! _startswith "$2" "-"; then + wvalue="$NGINX$2" shift - ;; - --apache) - wvalue="apache" - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --nginx) - wvalue="$NGINX" - if [ "$2" ] && ! _startswith "$2" "-"; then - wvalue="$NGINX$2" - shift - fi - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --dns) - wvalue="$W_DNS" - if [ "$2" ] && ! _startswith "$2" "-"; then - wvalue="$2" - shift - fi - if [ -z "$_webroot" ]; then - _webroot="$wvalue" - else - _webroot="$_webroot,$wvalue" - fi - ;; - --dnssleep) - _dnssleep="$2" - Le_DNSSleep="$_dnssleep" + fi + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --dns) + wvalue="$W_DNS" + if [ "$2" ] && ! _startswith "$2" "-"; then + wvalue="$2" shift - ;; + fi + if [ -z "$_webroot" ]; then + _webroot="$wvalue" + else + _webroot="$_webroot,$wvalue" + fi + ;; + --dnssleep) + _dnssleep="$2" + Le_DNSSleep="$_dnssleep" + shift + ;; - --keylength | -k) - _keylength="$2" - shift - ;; - --accountkeylength | -ak) - _accountkeylength="$2" - shift - ;; + --keylength | -k) + _keylength="$2" + shift + ;; + --accountkeylength | -ak) + _accountkeylength="$2" + shift + ;; - --cert-file | --certpath) - _cert_file="$2" - shift - ;; - --key-file | --keypath) - _key_file="$2" - shift - ;; - --ca-file | --capath) - _ca_file="$2" - shift - ;; - --fullchain-file | --fullchainpath) - _fullchain_file="$2" - shift - ;; - --reloadcmd | --reloadCmd) - _reloadcmd="$2" - shift - ;; - --password) - _password="$2" - shift - ;; - --accountconf) - _accountconf="$2" - ACCOUNT_CONF_PATH="$_accountconf" - shift - ;; - --home) - LE_WORKING_DIR="$2" - shift - ;; - --certhome | --cert-home) - _certhome="$2" - CERT_HOME="$_certhome" - shift - ;; - --config-home) - _confighome="$2" - LE_CONFIG_HOME="$_confighome" - shift - ;; - --useragent) - _useragent="$2" - USER_AGENT="$_useragent" - shift - ;; - --accountemail | -m) - _accountemail="$2" - ACCOUNT_EMAIL="$_accountemail" - shift - ;; - --accountkey) - _accountkey="$2" - ACCOUNT_KEY_PATH="$_accountkey" - shift - ;; - --days) - _days="$2" - Le_RenewalDays="$_days" - shift - ;; - --httpport) - _httpport="$2" - Le_HTTPPort="$_httpport" - shift - ;; - --tlsport) - _tlsport="$2" - Le_TLSPort="$_tlsport" - shift - ;; - --listraw) - _listraw="raw" - ;; - --stopRenewOnError | --stoprenewonerror | -se) - _stopRenewOnError="1" - ;; - --insecure) - #_insecure="1" - HTTPS_INSECURE="1" - ;; - --ca-bundle) - _ca_bundle="$(_readlink "$2")" - CA_BUNDLE="$_ca_bundle" - shift - ;; - --ca-path) - _ca_path="$2" - CA_PATH="$_ca_path" - shift - ;; - --nocron) - _nocron="1" - ;; - --noprofile) - _noprofile="1" - ;; - --no-color) - export ACME_NO_COLOR=1 - ;; - --force-color) - export ACME_FORCE_COLOR=1 - ;; - --ecc) - _ecc="isEcc" - ;; - --csr) - _csr="$2" - shift - ;; - --pre-hook) - _pre_hook="$2" - shift - ;; - --post-hook) - _post_hook="$2" - shift - ;; - --renew-hook) - _renew_hook="$2" - shift - ;; - --deploy-hook) - if [ -z "$2" ] || _startswith "$2" "-"; then - _usage "Please specify a value for '--deploy-hook'" - return 1 - fi - _deploy_hook="$_deploy_hook$2," - shift - ;; - --ocsp-must-staple | --ocsp) - Le_OCSP_Staple="1" - ;; - --always-force-new-domain-key) - if [ -z "$2" ] || _startswith "$2" "-"; then - Le_ForceNewDomainKey=1 - else - Le_ForceNewDomainKey="$2" - shift - fi - ;; - --yes-I-know-dns-manual-mode-enough-go-ahead-please) - export FORCE_DNS_MANUAL=1 - ;; - --log | --logfile) - _log="1" - _logfile="$2" - if _startswith "$_logfile" '-'; then - _logfile="" - else - shift - fi - LOG_FILE="$_logfile" - if [ -z "$LOG_LEVEL" ]; then - LOG_LEVEL="$DEFAULT_LOG_LEVEL" - fi - ;; - --log-level) - _log_level="$2" - LOG_LEVEL="$_log_level" - shift - ;; - --syslog) - if ! _startswith "$2" '-'; then - _syslog="$2" - shift - fi - if [ -z "$_syslog" ]; then - _syslog="$SYSLOG_LEVEL_DEFAULT" - fi - ;; - --auto-upgrade) - _auto_upgrade="$2" - if [ -z "$_auto_upgrade" ] || _startswith "$_auto_upgrade" '-'; then - _auto_upgrade="1" - else - shift - fi - AUTO_UPGRADE="$_auto_upgrade" - ;; - --listen-v4) - _listen_v4="1" - Le_Listen_V4="$_listen_v4" - ;; - --listen-v6) - _listen_v6="1" - Le_Listen_V6="$_listen_v6" - ;; - --openssl-bin) - _openssl_bin="$2" - ACME_OPENSSL_BIN="$_openssl_bin" - shift - ;; - --use-wget) - _use_wget="1" - ACME_USE_WGET="1" - ;; - --branch | -b) - export BRANCH="$2" - shift - ;; - --notify-hook) - _nhook="$2" - if _startswith "$_nhook" "-"; then - _err "'$_nhook' is not a hook name for '$1'" - return 1 - fi - if [ "$_notify_hook" ]; then - _notify_hook="$_notify_hook,$_nhook" - else - _notify_hook="$_nhook" - fi - shift - ;; - --notify-level) - _nlevel="$2" - if _startswith "$_nlevel" "-"; then - _err "'$_nlevel' is not a integer for '$1'" - return 1 - fi - _notify_level="$_nlevel" - shift - ;; - --notify-mode) - _nmode="$2" - if _startswith "$_nmode" "-"; then - _err "'$_nmode' is not a integer for '$1'" - return 1 - fi - _notify_mode="$_nmode" - shift - ;; - --revoke-reason) - _revoke_reason="$2" - if _startswith "$_revoke_reason" "-"; then - _err "'$_revoke_reason' is not a integer for '$1'" - return 1 - fi + --cert-file | --certpath) + _cert_file="$2" + shift + ;; + --key-file | --keypath) + _key_file="$2" + shift + ;; + --ca-file | --capath) + _ca_file="$2" + shift + ;; + --fullchain-file | --fullchainpath) + _fullchain_file="$2" + shift + ;; + --reloadcmd | --reloadCmd) + _reloadcmd="$2" + shift + ;; + --password) + _password="$2" + shift + ;; + --accountconf) + _accountconf="$2" + ACCOUNT_CONF_PATH="$_accountconf" + shift + ;; + --home) + LE_WORKING_DIR="$2" + shift + ;; + --certhome | --cert-home) + _certhome="$2" + CERT_HOME="$_certhome" + shift + ;; + --config-home) + _confighome="$2" + LE_CONFIG_HOME="$_confighome" + shift + ;; + --useragent) + _useragent="$2" + USER_AGENT="$_useragent" + shift + ;; + --accountemail | -m) + _accountemail="$2" + ACCOUNT_EMAIL="$_accountemail" + shift + ;; + --accountkey) + _accountkey="$2" + ACCOUNT_KEY_PATH="$_accountkey" + shift + ;; + --days) + _days="$2" + Le_RenewalDays="$_days" + shift + ;; + --httpport) + _httpport="$2" + Le_HTTPPort="$_httpport" + shift + ;; + --tlsport) + _tlsport="$2" + Le_TLSPort="$_tlsport" + shift + ;; + --listraw) + _listraw="raw" + ;; + --stopRenewOnError | --stoprenewonerror | -se) + _stopRenewOnError="1" + ;; + --insecure) + #_insecure="1" + HTTPS_INSECURE="1" + ;; + --ca-bundle) + _ca_bundle="$(_readlink "$2")" + CA_BUNDLE="$_ca_bundle" + shift + ;; + --ca-path) + _ca_path="$2" + CA_PATH="$_ca_path" + shift + ;; + --nocron) + _nocron="1" + ;; + --noprofile) + _noprofile="1" + ;; + --no-color) + export ACME_NO_COLOR=1 + ;; + --force-color) + export ACME_FORCE_COLOR=1 + ;; + --ecc) + _ecc="isEcc" + ;; + --csr) + _csr="$2" + shift + ;; + --pre-hook) + _pre_hook="$2" + shift + ;; + --post-hook) + _post_hook="$2" + shift + ;; + --renew-hook) + _renew_hook="$2" + shift + ;; + --deploy-hook) + if [ -z "$2" ] || _startswith "$2" "-"; then + _usage "Please specify a value for '--deploy-hook'" + return 1 + fi + _deploy_hook="$_deploy_hook$2," + shift + ;; + --ocsp-must-staple | --ocsp) + Le_OCSP_Staple="1" + ;; + --always-force-new-domain-key) + if [ -z "$2" ] || _startswith "$2" "-"; then + Le_ForceNewDomainKey=1 + else + Le_ForceNewDomainKey="$2" shift - ;; - --eab-kid) - _eab_kid="$2" + fi + ;; + --yes-I-know-dns-manual-mode-enough-go-ahead-please) + export FORCE_DNS_MANUAL=1 + ;; + --log | --logfile) + _log="1" + _logfile="$2" + if _startswith "$_logfile" '-'; then + _logfile="" + else shift - ;; - --eab-hmac-key) - _eab_hmac_key="$2" + fi + LOG_FILE="$_logfile" + if [ -z "$LOG_LEVEL" ]; then + LOG_LEVEL="$DEFAULT_LOG_LEVEL" + fi + ;; + --log-level) + _log_level="$2" + LOG_LEVEL="$_log_level" + shift + ;; + --syslog) + if ! _startswith "$2" '-'; then + _syslog="$2" shift - ;; - --preferred-chain) - _preferred_chain="$2" + fi + if [ -z "$_syslog" ]; then + _syslog="$SYSLOG_LEVEL_DEFAULT" + fi + ;; + --auto-upgrade) + _auto_upgrade="$2" + if [ -z "$_auto_upgrade" ] || _startswith "$_auto_upgrade" '-'; then + _auto_upgrade="1" + else shift - ;; - *) - _err "Unknown parameter : $1" + fi + AUTO_UPGRADE="$_auto_upgrade" + ;; + --listen-v4) + _listen_v4="1" + Le_Listen_V4="$_listen_v4" + ;; + --listen-v6) + _listen_v6="1" + Le_Listen_V6="$_listen_v6" + ;; + --openssl-bin) + _openssl_bin="$2" + ACME_OPENSSL_BIN="$_openssl_bin" + shift + ;; + --use-wget) + _use_wget="1" + ACME_USE_WGET="1" + ;; + --branch | -b) + export BRANCH="$2" + shift + ;; + --notify-hook) + _nhook="$2" + if _startswith "$_nhook" "-"; then + _err "'$_nhook' is not a hook name for '$1'" return 1 - ;; + fi + if [ "$_notify_hook" ]; then + _notify_hook="$_notify_hook,$_nhook" + else + _notify_hook="$_nhook" + fi + shift + ;; + --notify-level) + _nlevel="$2" + if _startswith "$_nlevel" "-"; then + _err "'$_nlevel' is not a integer for '$1'" + return 1 + fi + _notify_level="$_nlevel" + shift + ;; + --notify-mode) + _nmode="$2" + if _startswith "$_nmode" "-"; then + _err "'$_nmode' is not a integer for '$1'" + return 1 + fi + _notify_mode="$_nmode" + shift + ;; + --revoke-reason) + _revoke_reason="$2" + if _startswith "$_revoke_reason" "-"; then + _err "'$_revoke_reason' is not a integer for '$1'" + return 1 + fi + shift + ;; + --eab-kid) + _eab_kid="$2" + shift + ;; + --eab-hmac-key) + _eab_hmac_key="$2" + shift + ;; + --preferred-chain) + _preferred_chain="$2" + shift + ;; + *) + _err "Unknown parameter : $1" + return 1 + ;; esac shift 1 @@ -7325,82 +7325,82 @@ _process() { fi _debug "Running cmd: ${_CMD}" case "${_CMD}" in - install) install "$_nocron" "$_confighome" "$_noprofile" ;; - uninstall) uninstall "$_nocron" ;; - upgrade) upgrade ;; - issue) - issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" - ;; - deploy) - deploy "$_domain" "$_deploy_hook" "$_ecc" - ;; - signcsr) - signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" - ;; - showcsr) - showcsr "$_csr" "$_domain" - ;; - installcert) - installcert "$_domain" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_ecc" - ;; - renew) - renew "$_domain" "$_ecc" - ;; - renewAll) - renewAll "$_stopRenewOnError" - ;; - revoke) - revoke "$_domain" "$_ecc" "$_revoke_reason" - ;; - remove) - remove "$_domain" "$_ecc" - ;; - deactivate) - deactivate "$_domain,$_altdomains" - ;; - registeraccount) - registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key" - ;; - updateaccount) - updateaccount - ;; - deactivateaccount) - deactivateaccount - ;; - list) - list "$_listraw" "$_domain" - ;; - installcronjob) installcronjob "$_confighome" ;; - uninstallcronjob) uninstallcronjob ;; - cron) cron ;; - toPkcs) - toPkcs "$_domain" "$_password" "$_ecc" - ;; - toPkcs8) - toPkcs8 "$_domain" "$_ecc" - ;; - createAccountKey) - createAccountKey "$_accountkeylength" - ;; - createDomainKey) - createDomainKey "$_domain" "$_keylength" - ;; - createCSR) - createCSR "$_domain" "$_altdomains" "$_ecc" - ;; - setnotify) - setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" - ;; - setdefaultca) - setdefaultca - ;; - *) - if [ "$_CMD" ]; then - _err "Invalid command: $_CMD" - fi - showhelp - return 1 - ;; + install) install "$_nocron" "$_confighome" "$_noprofile" ;; + uninstall) uninstall "$_nocron" ;; + upgrade) upgrade ;; + issue) + issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" + ;; + deploy) + deploy "$_domain" "$_deploy_hook" "$_ecc" + ;; + signcsr) + signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" + ;; + showcsr) + showcsr "$_csr" "$_domain" + ;; + installcert) + installcert "$_domain" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_ecc" + ;; + renew) + renew "$_domain" "$_ecc" + ;; + renewAll) + renewAll "$_stopRenewOnError" + ;; + revoke) + revoke "$_domain" "$_ecc" "$_revoke_reason" + ;; + remove) + remove "$_domain" "$_ecc" + ;; + deactivate) + deactivate "$_domain,$_altdomains" + ;; + registeraccount) + registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key" + ;; + updateaccount) + updateaccount + ;; + deactivateaccount) + deactivateaccount + ;; + list) + list "$_listraw" "$_domain" + ;; + installcronjob) installcronjob "$_confighome" ;; + uninstallcronjob) uninstallcronjob ;; + cron) cron ;; + toPkcs) + toPkcs "$_domain" "$_password" "$_ecc" + ;; + toPkcs8) + toPkcs8 "$_domain" "$_ecc" + ;; + createAccountKey) + createAccountKey "$_accountkeylength" + ;; + createDomainKey) + createDomainKey "$_domain" "$_keylength" + ;; + createCSR) + createCSR "$_domain" "$_altdomains" "$_ecc" + ;; + setnotify) + setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" + ;; + setdefaultca) + setdefaultca + ;; + *) + if [ "$_CMD" ]; then + _err "Invalid command: $_CMD" + fi + showhelp + return 1 + ;; esac _ret="$?" if [ "$_ret" != "0" ]; then diff --git a/deploy/exim4.sh b/deploy/exim4.sh index 573f762b..260b8798 100644 --- a/deploy/exim4.sh +++ b/deploy/exim4.sh @@ -69,8 +69,8 @@ exim4_deploy() { cp "$_exim4_conf" "$_backup_conf" _info "Modify exim4 conf: $_exim4_conf" - if _setopt "$_exim4_conf" "tls_certificate" "=" "$_real_fullchain" \ - && _setopt "$_exim4_conf" "tls_privatekey" "=" "$_real_key"; then + if _setopt "$_exim4_conf" "tls_certificate" "=" "$_real_fullchain" && + _setopt "$_exim4_conf" "tls_privatekey" "=" "$_real_key"; then _info "Set config success!" else _err "Config exim4 server error, please report bug to us." diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 06d4b2b4..18de4aa6 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -195,8 +195,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ -n "$Le_Deploy_ssh_cafile" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] \ - || [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then + if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] || + [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then # if filename is same as previous file then append. _pipe=">>" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then @@ -222,9 +222,9 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ -n "$Le_Deploy_ssh_fullchain" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] \ - || [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] \ - || [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] || + [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] || + [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then # if filename is same as previous file then append. _pipe=">>" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then diff --git a/deploy/vsftpd.sh b/deploy/vsftpd.sh index ed44e709..8cf24e4f 100644 --- a/deploy/vsftpd.sh +++ b/deploy/vsftpd.sh @@ -65,9 +65,9 @@ vsftpd_deploy() { cp "$_vsftpd_conf" "$_backup_conf" _info "Modify vsftpd conf: $_vsftpd_conf" - if _setopt "$_vsftpd_conf" "rsa_cert_file" "=" "$_real_fullchain" \ - && _setopt "$_vsftpd_conf" "rsa_private_key_file" "=" "$_real_key" \ - && _setopt "$_vsftpd_conf" "ssl_enable" "=" "YES"; then + if _setopt "$_vsftpd_conf" "rsa_cert_file" "=" "$_real_fullchain" && + _setopt "$_vsftpd_conf" "rsa_private_key_file" "=" "$_real_key" && + _setopt "$_vsftpd_conf" "ssl_enable" "=" "YES"; then _info "Set config success!" else _err "Config vsftpd server error, please report bug to us." diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index edeb56ca..ca1f56c7 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -5,7 +5,7 @@ ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" #Author: Ehsan Aliakbar -#Report Bugs here: https://github.com/Neilpang/acme.sh +#Report Bugs here: https://github.com/Neilpang/acme.sh # ######## Public functions ##################### diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index ea4736c4..068c337c 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -222,21 +222,21 @@ _use_instance_role() { _use_metadata() { _aws_creds="$( - _get "$1" "" 1 \ - | _normalizeJson \ - | tr '{,}' '\n' \ - | while read -r _line; do + _get "$1" "" 1 | + _normalizeJson | + tr '{,}' '\n' | + while read -r _line; do _key="$(echo "${_line%%:*}" | tr -d '"')" _value="${_line#*:}" _debug3 "_key" "$_key" _secure_debug3 "_value" "$_value" case "$_key" in - AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;; - SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;; - Token) echo "AWS_SESSION_TOKEN=$_value" ;; + AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;; + SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;; + Token) echo "AWS_SESSION_TOKEN=$_value" ;; esac - done \ - | paste -sd' ' - + done | + paste -sd' ' - )" _secure_debug "_aws_creds" "$_aws_creds" diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 28b6572a..ce8a3fa7 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -220,7 +220,7 @@ _azure_rest() { export _H2="accept: application/json" export _H3="Content-Type: application/json" # clear headers from previous request to avoid getting wrong http code on timeouts - :>"$HTTP_HEADER" + : >"$HTTP_HEADER" _debug "$ep" if [ "$m" != "GET" ]; then _secure_debug2 "data $data" diff --git a/dnsapi/dns_conoha.sh b/dnsapi/dns_conoha.sh index d3bee130..ddc32074 100755 --- a/dnsapi/dns_conoha.sh +++ b/dnsapi/dns_conoha.sh @@ -115,9 +115,9 @@ dns_conoha_rm() { return 1 fi - record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' \ - | grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" \ - | _head_n 1 | cut -d : -f 2 | tr -d \") + record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' | + grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" | + _head_n 1 | cut -d : -f 2 | tr -d \") if [ -z "$record_id" ]; then _err "Can not get record id to remove." return 1 diff --git a/dnsapi/dns_cyon.sh b/dnsapi/dns_cyon.sh index 2dca90c0..2c08812b 100644 --- a/dnsapi/dns_cyon.sh +++ b/dnsapi/dns_cyon.sh @@ -18,23 +18,23 @@ ######## dns_cyon_add() { - _cyon_load_credentials \ - && _cyon_load_parameters "$@" \ - && _cyon_print_header "add" \ - && _cyon_login \ - && _cyon_change_domain_env \ - && _cyon_add_txt \ - && _cyon_logout + _cyon_load_credentials && + _cyon_load_parameters "$@" && + _cyon_print_header "add" && + _cyon_login && + _cyon_change_domain_env && + _cyon_add_txt && + _cyon_logout } dns_cyon_rm() { - _cyon_load_credentials \ - && _cyon_load_parameters "$@" \ - && _cyon_print_header "delete" \ - && _cyon_login \ - && _cyon_change_domain_env \ - && _cyon_delete_txt \ - && _cyon_logout + _cyon_load_credentials && + _cyon_load_parameters "$@" && + _cyon_print_header "delete" && + _cyon_login && + _cyon_change_domain_env && + _cyon_delete_txt && + _cyon_logout } ######################### diff --git a/dnsapi/dns_da.sh b/dnsapi/dns_da.sh index 4e9c4ef0..4d3e09b1 100755 --- a/dnsapi/dns_da.sh +++ b/dnsapi/dns_da.sh @@ -115,23 +115,23 @@ _da_api() { _debug response "$response" case "${cmd}" in - CMD_API_DNS_CONTROL) - # Parse the result in general - # error=0&text=Records Deleted&details= - # error=1&text=Cannot View Dns Record&details=No domain provided - err_field="$(_getfield "$response" 1 '&')" - txt_field="$(_getfield "$response" 2 '&')" - details_field="$(_getfield "$response" 3 '&')" - error="$(_getfield "$err_field" 2 '=')" - text="$(_getfield "$txt_field" 2 '=')" - details="$(_getfield "$details_field" 2 '=')" - _debug "error: ${error}, text: ${text}, details: ${details}" - if [ "$error" != "0" ]; then - _err "error $response" - return 1 - fi - ;; - CMD_API_SHOW_DOMAINS) ;; + CMD_API_DNS_CONTROL) + # Parse the result in general + # error=0&text=Records Deleted&details= + # error=1&text=Cannot View Dns Record&details=No domain provided + err_field="$(_getfield "$response" 1 '&')" + txt_field="$(_getfield "$response" 2 '&')" + details_field="$(_getfield "$response" 3 '&')" + error="$(_getfield "$err_field" 2 '=')" + text="$(_getfield "$txt_field" 2 '=')" + details="$(_getfield "$details_field" 2 '=')" + _debug "error: ${error}, text: ${text}, details: ${details}" + if [ "$error" != "0" ]; then + _err "error $response" + return 1 + fi + ;; + CMD_API_SHOW_DOMAINS) ;; esac return 0 } diff --git a/dnsapi/dns_do.sh b/dnsapi/dns_do.sh index 3a2f8f49..3850890c 100755 --- a/dnsapi/dns_do.sh +++ b/dnsapi/dns_do.sh @@ -67,14 +67,14 @@ _dns_do_list_rrs() { _err "getRRList origin ${_domain} failed" return 1 fi - _rr_list="$(echo "${response}" \ - | tr -d "\n\r\t" \ - | sed -e 's//\n/g' \ - | grep ">$(_regexcape "$fulldomain")" \ - | sed -e 's/<\/item>/\n/g' \ - | grep '>id[0-9]{1,16}<' \ - | tr -d '><')" + _rr_list="$(echo "${response}" | + tr -d "\n\r\t" | + sed -e 's//\n/g' | + grep ">$(_regexcape "$fulldomain")" | + sed -e 's/<\/item>/\n/g' | + grep '>id[0-9]{1,16}<' | + tr -d '><')" [ "${_rr_list}" ] } @@ -120,10 +120,10 @@ _get_root() { i=1 _dns_do_soap getDomainList - _all_domains="$(echo "${response}" \ - | tr -d "\n\r\t " \ - | _egrep_o 'domain]+>[^<]+' \ - | sed -e 's/^domain<\/key>]*>//g')" + _all_domains="$(echo "${response}" | + tr -d "\n\r\t " | + _egrep_o 'domain]+>[^<]+' | + sed -e 's/^domain<\/key>]*>//g')" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh index f466f1e2..ab47a0bc 100644 --- a/dnsapi/dns_easydns.sh +++ b/dnsapi/dns_easydns.sh @@ -3,7 +3,7 @@ ####################################################### # # easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh -# +# # API Documentation: https://sandbox.rest.easydns.net:3001/ # # Author: wurzelpanzer [wurzelpanzer@maximolider.net] diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 4a58931f..29cee430 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -303,10 +303,10 @@ _freedns_domain_id() { return 1 fi - domain_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ - | grep "$search_domain\|$search_domain(.*)" \ - | sed -n 's/.*\(edit\.php?edit_domain_id=[0-9a-zA-Z]*\).*/\1/p' \ - | cut -d = -f 2)" + domain_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' | + grep "$search_domain\|$search_domain(.*)" | + sed -n 's/.*\(edit\.php?edit_domain_id=[0-9a-zA-Z]*\).*/\1/p' | + cut -d = -f 2)" # The above beauty extracts domain ID from the html page... # strip out all blank space and new lines. Then insert newlines # before each table row @@ -349,11 +349,11 @@ _freedns_data_id() { return 1 fi - data_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' \ - | grep "$record_type" \ - | grep "$search_domain" \ - | sed -n 's/.*\(edit\.php?data_id=[0-9a-zA-Z]*\).*/\1/p' \ - | cut -d = -f 2)" + data_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's//@/g' | tr '@' '\n' | + grep "$record_type" | + grep "$search_domain" | + sed -n 's/.*\(edit\.php?data_id=[0-9a-zA-Z]*\).*/\1/p' | + cut -d = -f 2)" # The above beauty extracts data ID from the html page... # strip out all blank space and new lines. Then insert newlines # before each table row diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh index cdda4775..87119521 100644 --- a/dnsapi/dns_gandi_livedns.sh +++ b/dnsapi/dns_gandi_livedns.sh @@ -69,9 +69,9 @@ dns_gandi_livedns_rm() { _gandi_livedns_rest PUT \ "domains/$_domain/records/$_sub_domain/TXT" \ - "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" \ - && _contains "$response" '{"message": "DNS Record Created"}' \ - && _info "Removing record $(__green "success")" + "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" && + _contains "$response" '{"message": "DNS Record Created"}' && + _info "Removing record $(__green "success")" } #################### Private functions below ################################## @@ -125,9 +125,9 @@ _dns_gandi_append_record() { fi _debug new_rrset_values "$_rrset_values" _gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \ - "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" \ - && _contains "$response" '{"message": "DNS Record Created"}' \ - && _info "Adding record $(__green "success")" + "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" && + _contains "$response" '{"message": "DNS Record Created"}' && + _info "Adding record $(__green "success")" } _dns_gandi_existing_rrset_values() { @@ -145,8 +145,8 @@ _dns_gandi_existing_rrset_values() { return 1 fi _debug "Already has TXT record." - _rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' \ - | _egrep_o '\[".*\"]') + _rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' | + _egrep_o '\[".*\"]') return 0 } diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index 6365b338..03060a8c 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -78,8 +78,8 @@ _dns_gcloud_execute_tr() { for i in $(seq 1 120); do if gcloud dns record-sets changes list \ --zone="$managedZone" \ - --filter='status != done' \ - | grep -q '^.*'; then + --filter='status != done' | + grep -q '^.*'; then _info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ($i/120)..." sleep 5 else @@ -137,11 +137,11 @@ _dns_gcloud_find_zone() { # List domains and find the zone with the deepest sub-domain (in case of some levels of delegation) if ! match=$(gcloud dns managed-zones list \ --format="value(name, dnsName)" \ - --filter="$filter" \ - | while read -r dnsName name; do + --filter="$filter" | + while read -r dnsName name; do printf "%s\t%s\t%s\n" "$(echo "$name" | awk -F"." '{print NF-1}')" "$dnsName" "$name" - done \ - | sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then + done | + sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then _err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?" return 1 fi diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index 5829e00e..ef09fa0a 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -101,8 +101,8 @@ dns_he_rm() { body="$body&hosted_dns_editzone=1" body="$body&hosted_dns_delrecord=1" body="$body&hosted_dns_delconfirm=delete" - _post "$body" "https://dns.he.net/" \ - | grep '
Successfully removed record.
' \ + _post "$body" "https://dns.he.net/" | + grep '
Successfully removed record.
' \ >/dev/null exit_code="$?" if [ "$exit_code" -eq 0 ]; then diff --git a/dnsapi/dns_hetzner.sh b/dnsapi/dns_hetzner.sh index 5db0418c..911d4a35 100644 --- a/dnsapi/dns_hetzner.sh +++ b/dnsapi/dns_hetzner.sh @@ -123,10 +123,10 @@ _find_record() { return 1 else _record_id=$( - echo "$response" \ - | grep -o "{[^\{\}]*\"name\":\"$_record_name\"[^\}]*}" \ - | grep "\"value\":\"$_record_value\"" \ - | while read -r record; do + echo "$response" | + grep -o "{[^\{\}]*\"name\":\"$_record_name\"[^\}]*}" | + grep "\"value\":\"$_record_value\"" | + while read -r record; do # test for type and if [ -n "$(echo "$record" | _egrep_o '"type":"TXT"')" ]; then echo "$record" | _egrep_o '"id":"[^"]*"' | cut -d : -f 2 | tr -d \" diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 2d8d6b0a..bd1e0391 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -95,29 +95,29 @@ _ISPC_getZoneInfo() { server_id=$(echo "${curResult}" | _egrep_o "server_id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Server ID: '${server_id}'" case "${server_id}" in - '' | *[!0-9]*) - _err "Server ID is not numeric." - return 1 - ;; - *) _info "Retrieved Server ID" ;; + '' | *[!0-9]*) + _err "Server ID is not numeric." + return 1 + ;; + *) _info "Retrieved Server ID" ;; esac zone=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Zone: '${zone}'" case "${zone}" in - '' | *[!0-9]*) - _err "Zone ID is not numeric." - return 1 - ;; - *) _info "Retrieved Zone ID" ;; + '' | *[!0-9]*) + _err "Zone ID is not numeric." + return 1 + ;; + *) _info "Retrieved Zone ID" ;; esac client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Client ID: '${client_id}'" case "${client_id}" in - '' | *[!0-9]*) - _err "Client ID is not numeric." - return 1 - ;; - *) _info "Retrieved Client ID." ;; + '' | *[!0-9]*) + _err "Client ID is not numeric." + return 1 + ;; + *) _info "Retrieved Client ID." ;; esac zoneFound="" zoneEnd="" @@ -135,11 +135,11 @@ _ISPC_addTxt() { record_id=$(echo "${curResult}" | _egrep_o "\"response.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Record ID: '${record_id}'" case "${record_id}" in - '' | *[!0-9]*) - _err "Couldn't add ACME Challenge TXT record to zone." - return 1 - ;; - *) _info "Added ACME Challenge TXT record to zone." ;; + '' | *[!0-9]*) + _err "Couldn't add ACME Challenge TXT record to zone." + return 1 + ;; + *) _info "Added ACME Challenge TXT record to zone." ;; esac } @@ -153,24 +153,24 @@ _ISPC_rmTxt() { record_id=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _debug "Record ID: '${record_id}'" case "${record_id}" in - '' | *[!0-9]*) - _err "Record ID is not numeric." + '' | *[!0-9]*) + _err "Record ID is not numeric." + return 1 + ;; + *) + unset IFS + _info "Retrieved Record ID." + curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\",\"update_serial\":true}" + curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")" + _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'" + _debug "Result of _ISPC_rmTxt: '$curResult'" + if _contains "${curResult}" '"code":"ok"'; then + _info "Removed ACME Challenge TXT record from zone." + else + _err "Couldn't remove ACME Challenge TXT record from zone." return 1 - ;; - *) - unset IFS - _info "Retrieved Record ID." - curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\",\"update_serial\":true}" - curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")" - _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'" - _debug "Result of _ISPC_rmTxt: '$curResult'" - if _contains "${curResult}" '"code":"ok"'; then - _info "Removed ACME Challenge TXT record from zone." - else - _err "Couldn't remove ACME Challenge TXT record from zone." - return 1 - fi - ;; + fi + ;; esac fi } diff --git a/dnsapi/dns_joker.sh b/dnsapi/dns_joker.sh index 5d50953e..78399a1d 100644 --- a/dnsapi/dns_joker.sh +++ b/dnsapi/dns_joker.sh @@ -100,7 +100,7 @@ _get_root() { fi # Try to remove a test record. With correct root domain, username and password this will return "OK: ..." regardless - # of record in question existing or not. + # of record in question existing or not. if _joker_rest "username=$JOKER_USERNAME&password=$JOKER_PASSWORD&zone=$h&label=jokerTXTUpdateTest&type=TXT&value="; then if _startswith "$response" "OK"; then _sub_domain="$(echo "$fulldomain" | sed "s/\\.$h\$//")" diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index b3481c6c..83a7e5f8 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -5,12 +5,12 @@ # please report issues here: https://github.com/acmesh-official/acme.sh/issues/2977 #KAPPERNETDNS_Key="yourKAPPERNETapikey" -#KAPPERNETDNS_Secret="yourKAPPERNETapisecret" +#KAPPERNETDNS_Secret="yourKAPPERNETapisecret" KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" ############################################################################### -# called with +# called with # fullhostname: something.example.com # txtvalue: someacmegenerated string dns_kappernet_add() { @@ -97,7 +97,7 @@ dns_kappernet_rm() { #################### Private functions below ################################## # called with hostname # e.g._acme-challenge.www.domain.com returns -# _sub_domain=_acme-challenge.www +# _sub_domain=_acme-challenge.www # _domain=domain.com _get_root() { domain=$1 @@ -127,7 +127,7 @@ _get_root() { ################################################################################ # calls the kapper.net DNS Panel API -# with +# with # method # param _kappernet_api() { diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index 137ac1fb..2ce13e2b 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -144,7 +144,7 @@ _netlify_rest() { export _H1="Content-Type: application/json" export _H2="Authorization: Bearer $token_trimmed" - :>"$HTTP_HEADER" + : >"$HTTP_HEADER" if [ "$m" != "GET" ]; then _debug data "$data" diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 96ef5969..890cc804 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -6,10 +6,10 @@ # Created: 2019-02-17 # Fixed by: @der-berni # Modified: 2020-04-07 -# +# # Use ONECOM_KeepCnameProxy to keep the CNAME DNS record # export ONECOM_KeepCnameProxy="1" -# +# # export ONECOM_User="username" # export ONECOM_Password="password" # diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 7c18d009..dda47dda 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -41,40 +41,40 @@ _ovh_get_api() { case "${_ogaep}" in - ovh-eu | ovheu) - printf "%s" $OVH_EU - return - ;; - ovh-ca | ovhca) - printf "%s" $OVH_CA - return - ;; - kimsufi-eu | kimsufieu) - printf "%s" $KSF_EU - return - ;; - kimsufi-ca | kimsufica) - printf "%s" $KSF_CA - return - ;; - soyoustart-eu | soyoustarteu) - printf "%s" $SYS_EU - return - ;; - soyoustart-ca | soyoustartca) - printf "%s" $SYS_CA - return - ;; - runabove-ca | runaboveca) - printf "%s" $RAV_CA - return - ;; - - *) - - _err "Unknown parameter : $1" - return 1 - ;; + ovh-eu | ovheu) + printf "%s" $OVH_EU + return + ;; + ovh-ca | ovhca) + printf "%s" $OVH_CA + return + ;; + kimsufi-eu | kimsufieu) + printf "%s" $KSF_EU + return + ;; + kimsufi-ca | kimsufica) + printf "%s" $KSF_CA + return + ;; + soyoustart-eu | soyoustarteu) + printf "%s" $SYS_EU + return + ;; + soyoustart-ca | soyoustartca) + printf "%s" $SYS_CA + return + ;; + runabove-ca | runaboveca) + printf "%s" $RAV_CA + return + ;; + + *) + + _err "Unknown parameter : $1" + return 1 + ;; esac } diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index fe18bef4..f5986827 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -136,11 +136,12 @@ dns_pleskxml_rm() { # Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have) # Also strip out spaces between tags, redundant and group tags and any tags - reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' \ - | sed 's# \{1,\}<\([a-zA-Z]\)#<\1#g;s###g;s#<[a-z][^/<>]*/>##g' \ - | grep "${root_domain_id}" \ - | grep '[0-9]\{1,\}' \ - | grep 'TXT' + reclist="$( + _api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | + sed 's# \{1,\}<\([a-zA-Z]\)#<\1#g;s###g;s#<[a-z][^/<>]*/>##g' | + grep "${root_domain_id}" | + grep '[0-9]\{1,\}' | + grep 'TXT' )" if [ -z "$reclist" ]; then @@ -151,10 +152,11 @@ dns_pleskxml_rm() { _debug "Got list of DNS TXT records for root domain '$root_domain_name':" _debug "$reclist" - recid="$(_value "$reclist" \ - | grep "${fulldomain}." \ - | grep "${txtvalue}" \ - | sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' + recid="$( + _value "$reclist" | + grep "${fulldomain}." | + grep "${txtvalue}" | + sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' )" if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then @@ -220,11 +222,11 @@ _countdots() { # Last line could change to instead, with suitable escaping of ['"/$], # if future Plesk XML API changes ever require extended regex _api_response_split() { - printf '%s' "$1" \ - | sed 's/^ +//;s/ +$//' \ - | tr -d '\n\r' \ - | sed "s/<\/\{0,1\}$2>/${NEWLINE}/g" \ - | grep "$3" + printf '%s' "$1" | + sed 's/^ +//;s/ +$//' | + tr -d '\n\r' | + sed "s/<\/\{0,1\}$2>/${NEWLINE}/g" | + grep "$3" } #################### Private functions below (DNS functions) ################################## @@ -261,14 +263,15 @@ _call_api() { elif [ "$statuslines_count_okay" -ne "$statuslines_count_total" ]; then # We have some status lines that aren't "ok". Any available details are in API response fields "status" "errcode" and "errtext" - # Workaround for basic regex: + # Workaround for basic regex: # - filter output to keep only lines like this: "SPACEStextSPACES" (shouldn't be necessary with prettyprint but guarantees subsequent code is ok) # - then edit the 3 "useful" error tokens individually and remove closing tags on all lines # - then filter again to remove all lines not edited (which will be the lines not starting A-Z) - errtext="$(_value "$pleskxml_prettyprint_result" \ - | grep '^ *<[a-z]\{1,\}>[^<]*<\/[a-z]\{1,\}> *$' \ - | sed 's/^ */Status: /;s/^ */Error code: /;s/^ */Error text: /;s/<\/.*$//' \ - | grep '^[A-Z]' + errtext="$( + _value "$pleskxml_prettyprint_result" | + grep '^ *<[a-z]\{1,\}>[^<]*<\/[a-z]\{1,\}> *$' | + sed 's/^ */Status: /;s/^ */Error code: /;s/^ */Error text: /;s/<\/.*$//' | + grep '^[A-Z]' )" fi diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index b5729fda..a50821eb 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -87,11 +87,11 @@ _get_root() { for ITEM in ${domains_list}; do case "${domain}" in - *${ITEM}*) - _domain=${ITEM} - _debug _domain "${_domain}" - return 0 - ;; + *${ITEM}*) + _domain=${ITEM} + _debug _domain "${_domain}" + return 0 + ;; esac done diff --git a/notify/mail.sh b/notify/mail.sh index 54b2a6d4..d33fd0d2 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -98,24 +98,24 @@ _mail_cmnd() { _MAIL_ARGS="" case $(basename "$_MAIL_BIN") in - sendmail) - if [ -n "$MAIL_FROM" ]; then - _MAIL_ARGS="-f '$MAIL_FROM'" - fi - ;; - mutt | mail) - _MAIL_ARGS="-s '$_subject'" - ;; - msmtp) - if [ -n "$MAIL_FROM" ]; then - _MAIL_ARGS="-f '$MAIL_FROM'" - fi - - if [ -n "$MAIL_MSMTP_ACCOUNT" ]; then - _MAIL_ARGS="$_MAIL_ARGS -a '$MAIL_MSMTP_ACCOUNT'" - fi - ;; - *) ;; + sendmail) + if [ -n "$MAIL_FROM" ]; then + _MAIL_ARGS="-f '$MAIL_FROM'" + fi + ;; + mutt | mail) + _MAIL_ARGS="-s '$_subject'" + ;; + msmtp) + if [ -n "$MAIL_FROM" ]; then + _MAIL_ARGS="-f '$MAIL_FROM'" + fi + + if [ -n "$MAIL_MSMTP_ACCOUNT" ]; then + _MAIL_ARGS="$_MAIL_ARGS -a '$MAIL_MSMTP_ACCOUNT'" + fi + ;; + *) ;; esac echo "'$_MAIL_BIN' $_MAIL_ARGS '$MAIL_TO'" @@ -123,16 +123,16 @@ _mail_cmnd() { _mail_body() { case $(basename "$_MAIL_BIN") in - sendmail | ssmtp | msmtp) - if [ -n "$MAIL_FROM" ]; then - echo "From: $MAIL_FROM" - fi - - echo "To: $MAIL_TO" - echo "Subject: $subject" - echo "Content-Type: $contenttype" - echo - ;; + sendmail | ssmtp | msmtp) + if [ -n "$MAIL_FROM" ]; then + echo "From: $MAIL_FROM" + fi + + echo "To: $MAIL_TO" + echo "Subject: $subject" + echo "Content-Type: $contenttype" + echo + ;; esac echo "$_content" diff --git a/notify/teams.sh b/notify/teams.sh index e50ea703..1bc5ed08 100644 --- a/notify/teams.sh +++ b/notify/teams.sh @@ -52,15 +52,15 @@ teams_send() { _content=$(echo "$_content" | _json_encode) case "$_statusCode" in - 0) - _color="${TEAMS_SUCCESS_COLOR:-$_color_success}" - ;; - 1) - _color="${TEAMS_ERROR_COLOR:-$_color_danger}" - ;; - 2) - _color="${TEAMS_SKIP_COLOR:-$_color_muted}" - ;; + 0) + _color="${TEAMS_SUCCESS_COLOR:-$_color_success}" + ;; + 1) + _color="${TEAMS_ERROR_COLOR:-$_color_danger}" + ;; + 2) + _color="${TEAMS_SKIP_COLOR:-$_color_muted}" + ;; esac _color=$(echo "$_color" | tr -cd 'a-fA-F0-9') diff --git a/notify/xmpp.sh b/notify/xmpp.sh index 580f471e..0ce1119e 100644 --- a/notify/xmpp.sh +++ b/notify/xmpp.sh @@ -71,13 +71,13 @@ _xmpp_bin() { _xmpp_cmnd() { case $(basename "$_XMPP_BIN") in - sendxmpp) - echo "'$_XMPP_BIN' '$XMPP_TO' $XMPP_BIN_ARGS" - ;; - *) - _err "Command $XMPP_BIN is not supported, use sendxmpp." - return 1 - ;; + sendxmpp) + echo "'$_XMPP_BIN' '$XMPP_TO' $XMPP_BIN_ARGS" + ;; + *) + _err "Command $XMPP_BIN is not supported, use sendxmpp." + return 1 + ;; esac } From 284de4ac5df7b42c611fee24c23a9420a7314c65 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:46:52 +0800 Subject: [PATCH 062/190] add actions --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..2eab1f34 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,20 @@ + + +name: CI +on:[push, pull_request] + +jobs: + formatCheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Shellcheck + run: sudo apt-get install -y shellcheck + - name: DoShellcheck + run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" + - name: Install shfmt + with: + SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 + run: curl -sSL ${{ SHFMT_URL }} -o ~/shfmt && chmod +x ~/shfmt + - name: shfmt + run: ~/shfmt -l -w -i 2 . ; git diff --exit-code && echo "shfmt OK" From f1338aca846a7842ecff52425d35320330b9efa2 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:49:09 +0800 Subject: [PATCH 063/190] fix --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2eab1f34..0a35e000 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,5 @@ - - name: CI -on:[push, pull_request] +on: [push, pull_request] jobs: formatCheck: From cf500cd817cc6cb1419a0a65f58e7814f63b690e Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 22:50:19 +0800 Subject: [PATCH 064/190] fix --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a35e000..af98aca6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" - name: Install shfmt with: - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 + SHFMT_URL: "https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64" run: curl -sSL ${{ SHFMT_URL }} -o ~/shfmt && chmod +x ~/shfmt - name: shfmt run: ~/shfmt -l -w -i 2 . ; git diff --exit-code && echo "shfmt OK" From d9e7cf659e609e5952950479f35ee9369711e0c5 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Mon, 17 Aug 2020 22:52:59 +0800 Subject: [PATCH 065/190] Update ci.yml --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af98aca6..eb2f9b46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,8 +11,6 @@ jobs: - name: DoShellcheck run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" - name: Install shfmt - with: - SHFMT_URL: "https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64" - run: curl -sSL ${{ SHFMT_URL }} -o ~/shfmt && chmod +x ~/shfmt + run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt - name: shfmt run: ~/shfmt -l -w -i 2 . ; git diff --exit-code && echo "shfmt OK" From 72235a5f72d97694da7f69ff0ae9ce26478ac34c Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Aug 2020 23:13:00 +0800 Subject: [PATCH 066/190] add shellcheck badge --- .github/workflows/{ci.yml => shellcheck.yml} | 2 +- README.md | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) rename .github/workflows/{ci.yml => shellcheck.yml} (94%) diff --git a/.github/workflows/ci.yml b/.github/workflows/shellcheck.yml similarity index 94% rename from .github/workflows/ci.yml rename to .github/workflows/shellcheck.yml index eb2f9b46..529f41e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/shellcheck.yml @@ -1,4 +1,4 @@ -name: CI +name: shellcheck on: [push, pull_request] jobs: diff --git a/README.md b/README.md index e50489dc..a2a40dc9 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) - [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +[![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") [![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") - +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial From de692d3dcce6743641236fa0b720fbaea93648a4 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Tue, 18 Aug 2020 13:14:00 +0300 Subject: [PATCH 067/190] Vault deploy hook --- Dockerfile | 1 + deploy/vault.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 deploy/vault.sh diff --git a/Dockerfile b/Dockerfile index f00d03bd..3109ffd2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ RUN apk update -f \ coreutils \ bind-tools \ curl \ + sed \ socat \ tzdata \ oath-toolkit-oathtool \ diff --git a/deploy/vault.sh b/deploy/vault.sh new file mode 100644 index 00000000..ae771967 --- /dev/null +++ b/deploy/vault.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env sh + +# Here is a script to deploy cert to hashicorp vault using curl +# (https://www.vaultproject.io/) +# +# it requires following environment variables: +# +# VAULT_PREFIX - this contains the prefix path in vault +# VAULT_ADDR - vault requires this to find your vault server +# +# additionally, you need to ensure that VAULT_TOKEN is avialable +# to access the vault server + +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +vault_deploy() { + + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + # validate required env vars + if [ -z "$VAULT_PREFIX" ]; then + _err "VAULT_PREFIX needs to be defined (contains prefix path in vault)" + return 1 + fi + + if [ -z "$VAULT_ADDR" ]; then + _err "VAULT_ADDR needs to be defined (contains vault connection address)" + return 1 + fi + + # JSON does not allow multiline strings. + # So replacing new-lines with "\n" here + _ckey=$(sed -z 's/\n/\\n/g' <"$2") + _ccert=$(sed -z 's/\n/\\n/g' <"$3") + _cca=$(sed -z 's/\n/\\n/g' <"$4") + _cfullchain=$(sed -z 's/\n/\\n/g' <"$5") + + URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain" + + if [ -n "$FABIO" ]; then + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" || return 1 + else + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_ccert\"}" "$URL/cert.pem" || return 1 + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_ckey\"}" "$URL/cert.key" || return 1 + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_cca\"}" "$URL/chain.pem" || return 1 + curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" || return 1 + fi + +} From d8bd45c2bda3f520bc31d6510f6802ee736bf4a1 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Tue, 18 Aug 2020 13:53:48 +0200 Subject: [PATCH 068/190] Fix issue #2833 with backslash in JSON Backslash will be removed form JSON responses for each request and for the initial configuration request --- acme.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 45e0c246..1ba8734a 100755 --- a/acme.sh +++ b/acme.sh @@ -2086,7 +2086,7 @@ _send_signed_request() { _debug2 original "$response" if echo "$responseHeaders" | grep -i "Content-Type: *application/json" >/dev/null 2>&1; then - response="$(echo "$response" | _normalizeJson)" + response="$(echo "$response" | _normalizeJson | _json_decode)" fi _debug2 response "$response" @@ -2503,6 +2503,7 @@ _initAPI() { _err "Can not init api." return 1 fi + response=$(echo "$response" | _json_decode) _debug2 "response" "$response" ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'key-change" *: *"[^"]*"' | cut -d '"' -f 3) @@ -6428,7 +6429,7 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. - --set-default-ca Used with '--server' , to set the default CA to use to use. + --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6470,8 +6471,8 @@ Parameters: --eab-kid EAB_KID Key Identifier for External Account Binding. --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. - - + + These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6502,7 +6503,7 @@ Parameters: --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. - + --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. From ab47bf6451b4c9d01fc8a87eb0c8f2158707e607 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Tue, 18 Aug 2020 14:01:02 +0200 Subject: [PATCH 069/190] Removed content for clean pull request --- acme.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/acme.sh b/acme.sh index 1ba8734a..0827ad66 100755 --- a/acme.sh +++ b/acme.sh @@ -6429,7 +6429,6 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. - --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6471,8 +6470,6 @@ Parameters: --eab-kid EAB_KID Key Identifier for External Account Binding. --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. - - These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6503,7 +6500,6 @@ Parameters: --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. - --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. From 2d5f14388e976dac65974ee4284cc67a1378bc9d Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Tue, 18 Aug 2020 14:52:23 +0200 Subject: [PATCH 070/190] Revert "Removed content for clean pull request" This reverts commit ab47bf6451b4c9d01fc8a87eb0c8f2158707e607. --- acme.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/acme.sh b/acme.sh index 0827ad66..1ba8734a 100755 --- a/acme.sh +++ b/acme.sh @@ -6429,6 +6429,7 @@ Commands: --createCSR, -ccsr Create CSR , professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. + --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: @@ -6470,6 +6471,8 @@ Parameters: --eab-kid EAB_KID Key Identifier for External Account Binding. --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. + + These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: --cert-file After issue/renew, the cert will be copied to this path. @@ -6500,6 +6503,7 @@ Parameters: --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. + --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. From 9021f006f0eacc921da8aeca22b704129dee985e Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 18 Aug 2020 22:22:03 +0800 Subject: [PATCH 071/190] update shfmt --- .travis.yml | 2 +- README.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a9785d0c..2741e719 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ services: env: global: - - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64 + - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 install: diff --git a/README.md b/README.md index a2a40dc9..6a42fae6 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ acme.sh is being sponsored by the following tool; please help to support us by t - Support ACME v2 wildcard certs - Simple, powerful and very easy to use. You only need 3 minutes to learn it. - Bash, dash and sh compatible. -- Simplest shell script for Let's Encrypt free certificate client. - Purely written in Shell with no dependencies on python or the official Let's Encrypt client. - Just one script to issue, renew and install your certificates automatically. - DOES NOT require `root/sudoer` access. From 50fefc3bb00f528869b8cdeca29f0333c9602a65 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 18 Aug 2020 23:28:06 +0800 Subject: [PATCH 072/190] minor --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 45e0c246..84714324 100755 --- a/acme.sh +++ b/acme.sh @@ -36,8 +36,8 @@ DEFAULT_CA=$CA_LETSENCRYPT_V2 DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST CA_NAMES=" -Letsencrypt.org,letsencrypt -Letsencrypt.org_test,letsencrypt_test,letsencrypttest +LetsEncrypt.org,letsencrypt +LetsEncrypt.org_test,letsencrypt_test,letsencrypttest BuyPass.com,buypass BuyPass.com_test,buypass_test,buypasstest ZeroSSL.com,zerossl From 956114fc4250cae30116f5d998c48ab827272945 Mon Sep 17 00:00:00 2001 From: Alexilmarranen Date: Wed, 19 Aug 2020 00:50:18 +0300 Subject: [PATCH 073/190] Issue2336 Add subdomain (3 and more) support Fix for issue in https://github.com/acmesh-official/acme.sh/issues/2336#issuecomment-670522738 --- dnsapi/dns_regru.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index b5729fda..469d8d20 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -33,8 +33,11 @@ dns_regru_add() { fi _debug _domain "$_domain" + _subdomain=$(echo "$fulldomain" | sed -r "s/.$_domain//") + _debug _subdomain "$_subdomain" + _info "Adding TXT record to ${fulldomain}" - _regru_rest POST "zone/add_txt" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json" + _regru_rest POST "zone/add_txt" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22${_subdomain}%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json" if ! _contains "${response}" 'error'; then return 0 @@ -64,8 +67,11 @@ dns_regru_rm() { fi _debug _domain "$_domain" + _subdomain=$(echo "$fulldomain" | sed -r "s/.$_domain//") + _debug _subdomain "$_subdomain" + _info "Deleting resource record $fulldomain" - _regru_rest POST "zone/remove_record" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json" + _regru_rest POST "zone/remove_record" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22${_subdomain}%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json" if ! _contains "${response}" 'error'; then return 0 From b7b01999d9616c44e006b41ac78143efadb875b0 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Thu, 20 Aug 2020 09:13:44 +0800 Subject: [PATCH 074/190] fix preferred chain for renewal fix https://github.com/acmesh-official/acme.sh/issues/3116 --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index c750757c..d1a08e6c 100755 --- a/acme.sh +++ b/acme.sh @@ -5049,6 +5049,7 @@ renew() { Le_PreHook="$(_readdomainconf Le_PreHook)" Le_PostHook="$(_readdomainconf Le_PostHook)" Le_RenewHook="$(_readdomainconf Le_RenewHook)" + Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)" issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain" res="$?" if [ "$res" != "0" ]; then From a70f377388dfab5163f99fbf456b73aecddf837e Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:18:53 +0800 Subject: [PATCH 075/190] add pebble --- .github/workflows/PebbleStrict.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/PebbleStrict.yml diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml new file mode 100644 index 00000000..20670eb2 --- /dev/null +++ b/.github/workflows/PebbleStrict.yml @@ -0,0 +1,25 @@ +name: PebbleStrict +on: [push, pull_request] + +jobs: + formatCheck: + runs-on: ubuntu-latest + env: + TestingDomain: example.com + TestingAltDomains: www.example.com + ACME_DIRECTORY: https://localhost:14000/dir + HTTPS_INSECURE: 1 + Le_HTTPPort: 5002 + TEST_LOCAL: 1 + TEST_CA: todo + + steps: + - uses: actions/checkout@v2 + - name: Run Pebble + run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d + - name: Set up Pebble + run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 + - name: Clone acmetest + run: git clone https://github.com/acmesh-official/acmetest.git && mv acme.sh acmetest/ + - name: Run acmetest + run: cd acmetest && ./letest.sh \ No newline at end of file From c131b63852b66305cb13f4d51acd424057a440f4 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:32:22 +0800 Subject: [PATCH 076/190] typo --- .github/workflows/PebbleStrict.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 20670eb2..1b31d791 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -2,7 +2,7 @@ name: PebbleStrict on: [push, pull_request] jobs: - formatCheck: + PebbleStrict: runs-on: ubuntu-latest env: TestingDomain: example.com From edd76f595a626a9e6d0b8e35ae3075d8ae84255e Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:37:23 +0800 Subject: [PATCH 077/190] fix dir --- .github/workflows/PebbleStrict.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 1b31d791..a1c56724 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run Pebble - run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d + run: cd "$GITHUB_WORKSPACE" && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d - name: Set up Pebble run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 - name: Clone acmetest - run: git clone https://github.com/acmesh-official/acmetest.git && mv acme.sh acmetest/ + run: cd "$GITHUB_WORKSPACE" && git clone https://github.com/acmesh-official/acmetest.git && mv acme.sh acmetest/ - name: Run acmetest run: cd acmetest && ./letest.sh \ No newline at end of file From b805ea9bf6155445bcba330f5a527ecf1893427c Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:52:42 +0800 Subject: [PATCH 078/190] fix dir --- .github/workflows/PebbleStrict.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index a1c56724..77ba5f3d 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run Pebble - run: cd "$GITHUB_WORKSPACE" && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d + run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d - name: Set up Pebble run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 - name: Clone acmetest - run: cd "$GITHUB_WORKSPACE" && git clone https://github.com/acmesh-official/acmetest.git && mv acme.sh acmetest/ + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd acmetest && ./letest.sh \ No newline at end of file + run: cd ../acmetest && ./letest.sh \ No newline at end of file From 3cd85fb3950c5140ed0308f8a05c30b17f5ec64a Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 20:54:27 +0800 Subject: [PATCH 079/190] install socat --- .github/workflows/PebbleStrict.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 77ba5f3d..836437fa 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -15,6 +15,8 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat - name: Run Pebble run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d - name: Set up Pebble From 7ddc2ccf1ab5ae19ae5671c74e4afbc09d294eaf Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 21:06:21 +0800 Subject: [PATCH 080/190] add TEST_CA --- .github/workflows/PebbleStrict.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 836437fa..a339f727 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -11,7 +11,7 @@ jobs: HTTPS_INSECURE: 1 Le_HTTPPort: 5002 TEST_LOCAL: 1 - TEST_CA: todo + TEST_CA: "Pebble Intermediate CA" steps: - uses: actions/checkout@v2 From c1668c9bdba0c860bb93f39e9e954bb80839e569 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 21:26:42 +0800 Subject: [PATCH 081/190] add pebble badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6a42fae6..3012f676 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") [![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial From 966c744992b8d00819ec4225cc4bb8eb45cf7931 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 20 Aug 2020 21:41:36 +0800 Subject: [PATCH 082/190] minor, just move badge position --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3012f676..e0fcd679 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) +# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) + [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") [![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) + acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial From d9f9477a52d3e5e937b1e4b56a9eec7113e84e89 Mon Sep 17 00:00:00 2001 From: neil <8305679+Neilpang@users.noreply.github.com> Date: Thu, 20 Aug 2020 21:44:37 +0800 Subject: [PATCH 083/190] move badge move badge --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e0fcd679..bf6ea06c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) +# An ACME Shell script: acme.sh +[![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) From c0fbe8237bbd4df2a32636e383419732a5b1b104 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Wed, 19 Aug 2020 13:33:08 +0200 Subject: [PATCH 084/190] reformat usage message for consistency & clarity --- acme.sh | 137 +++++++++++++++++++++++++------------------------------- 1 file changed, 62 insertions(+), 75 deletions(-) diff --git a/acme.sh b/acme.sh index d1a08e6c..a00e314f 100755 --- a/acme.sh +++ b/acme.sh @@ -6402,8 +6402,8 @@ showhelp() { version echo "Usage: $PROJECT_ENTRY command ...[parameters].... Commands: - --help, -h Show this help message. - --version, -v Show version info. + -h, --help Show this help message. + -v, --version Show version info. --install Install $PROJECT_NAME to your system. --uninstall Uninstall $PROJECT_NAME, and uninstall the cron job. --upgrade Upgrade $PROJECT_NAME to the latest code from $PROJECT. @@ -6411,7 +6411,7 @@ Commands: --signcsr Issue a cert from an existing csr. --deploy Deploy the cert to your server. --install-cert Install the issued cert to apache/nginx or any other server. - --renew, -r Renew a cert. + -r, --renew Renew a cert. --renew-all Renew all the certs. --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. @@ -6427,117 +6427,104 @@ Commands: --deactivate-account Deactivate the account. --create-account-key Create an account private key, professional use. --create-domain-key Create an domain private key, professional use. - --createCSR, -ccsr Create CSR , professional use. + -ccsr, --createCSR Create CSR, professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. --set-default-ca Used with '--server' , to set the default CA to use to use. Parameters: - --domain, -d domain.tld Specifies a domain, used to issue, renew or revoke etc. - --challenge-alias domain.tld The challenge domain alias for DNS alias mode. + -d, --domain Specifies a domain, used to issue, renew or revoke etc. + --challenge-alias The challenge domain alias for DNS alias mode. See: $_DNS_ALIAS_WIKI - - --domain-alias domain.tld The domain alias for DNS alias mode. + --domain-alias The domain alias for DNS alias mode. See: $_DNS_ALIAS_WIKI - - --preferred-chain CHAIN If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. + --preferred-chain If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used. (default: empty) See: $_PREFERRED_CHAIN_WIKI - - --force, -f Used to force to install or force to renew a cert immediately. - --staging, --test Use staging server, just for test. - --debug Output debug info. + -f, --force Force install, force cert renewal or override sudo restrictions. + --staging, --test Use staging server, for testing. + --debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted. --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for security. - - --webroot, -w /path/to/webroot Specifies the web root folder for web root mode. + -w, --webroot Specifies the web root folder for web root mode. --standalone Use standalone mode. --alpn Use standalone alpn mode. --stateless Use stateless mode. See: $_STATELESS_WIKI - --apache Use apache mode. - --dns [dns_hook] Use dns mode or dns api. + --dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted. See: $_DNS_API_WIKI - - --dnssleep 300 The time in seconds to wait for all the txt records to propagate in dns api mode. + --dnssleep The time in seconds to wait for all the txt records to propagate in dns api mode. It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically. - - --keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. - --accountkeylength, -ak [2048] Specifies the account key length: 2048, 3072, 4096 - --log [/path/to/logfile] Specifies the log file. The default is: \"$DEFAULT_LOG_FILE\" if you don't give a file path here. - --log-level 1|2 Specifies the log level, default is 1. - --syslog [0|3|6|7] Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. - - --eab-kid EAB_KID Key Identifier for External Account Binding. - --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding. + -k, --keylength Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. + -ak, --accountkeylength Specifies the account key length: 2048, 3072, 4096 + --log [/path/to/logfile] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted. + --log-level <1|2> Specifies the log level, default is 1. + --syslog <0|3|6|7> Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. + --eab-kid Key Identifier for External Account Binding. + --eab-hmac-key HMAC key for External Account Binding. These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: - --cert-file After issue/renew, the cert will be copied to this path. - --key-file After issue/renew, the key will be copied to this path. - --ca-file After issue/renew, the intermediate cert will be copied to this path. - --fullchain-file After issue/renew, the fullchain cert will be copied to this path. + --cert-file Path to copy the cert file to after issue/renew.. + --key-file Path to copy the key file to after issue/renew. + --ca-file Path to copy the intermediate cert file to after issue/renew. + --fullchain-file Path to copy the fullchain cert file to after issue/renew. - --reloadcmd \"service nginx reload\" After issue/renew, it's used to reload the server. + --reloadcmd Command to execute after issue/renew to reload the server. - --server SERVER ACME Directory Resource URI. (default: $DEFAULT_CA) + --server ACME Directory Resource URI. (default: $DEFAULT_CA) See: $_SERVER_WIKI - --accountconf Specifies a customized account config file. - --home Specifies the home dir for $PROJECT_NAME. - --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. - --config-home Specifies the home dir to save all the configurations. - --useragent Specifies the user agent string. it will be saved for future use too. - --accountemail, -m Specifies the account email, only valid for the '--install' and '--update-account' command. - --accountkey Specifies the account key path, only valid for the '--install' command. - --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. - --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. - --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer. - --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses. + --accountconf Specifies a customized account config file. + --home Specifies the home dir for $PROJECT_NAME. + --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. + --config-home Specifies the home dir to save all the configurations. + --useragent Specifies the user agent string. it will be saved for future use too. + -m, --accountemail Specifies the account email, only valid for the '--install' and '--update-account' command. + --accountkey Specifies the account key path, only valid for the '--install' command. + --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days. + --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer. + --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer. + --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses. --listraw Only used for '--list' command, list the certs in raw format. - --stopRenewOnError, -se Only valid for '--renew-all' command. Stop if one cert has error in renewal. + -se, --stopRenewOnError Only valid for '--renew-all' command. Stop if one cert has error in renewal. --insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted. - --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. - --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. + --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. + --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. - --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' - --csr Specifies the input csr. - --pre-hook Command to be run before obtaining any certificates. - --post-hook Command to be run after attempting to obtain/renew certificates. No matter the obtain/renew is success or failed. - --renew-hook Command to be run once for each successfully renewed certificate. - --deploy-hook The hook file to deploy cert - --ocsp-must-staple, --ocsp Generate ocsp must Staple extension. - --always-force-new-domain-key Generate new domain key when renewal. Otherwise, the domain key is not changed by default. - --auto-upgrade [0|1] Valid for '--upgrade' command, indicating whether to upgrade automatically in future. + --csr Specifies the input csr. + --pre-hook Command to be run before obtaining any certificates. + --post-hook Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed. + --renew-hook Command to be run after each successfully renewed certificate. + --deploy-hook The hook file to deploy cert + --ocsp, --ocsp-must-staple Generate OCSP-Must-Staple extension. + --always-force-new-domain-key Generate new domain key on renewal. Otherwise, the domain key is not changed by default. + --auto-upgrade [0|1] Valid for '--upgrade' command, indicating whether to upgrade automatically in future. Defaults to 1 if argument is omitted. --listen-v4 Force standalone/tls server to listen at ipv4. --listen-v6 Force standalone/tls server to listen at ipv6. - --openssl-bin Specifies a custom openssl bin location. + --openssl-bin Specifies a custom openssl bin location. --use-wget Force to use wget, if you have both curl and wget installed. - --yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode. + --yes-I-know-dns-manual-mode-enough-go-ahead-please Force use ofdns manual mode. See: $_DNS_MANUAL_WIKI - - --branch, -b Only valid for '--upgrade' command, specifies the branch name to upgrade to. - - --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. - 0: disabled, no notification will be sent. - 1: send notifications only when there is an error. - 2: send notifications when a cert is successfully renewed, or there is an error. - 3: send notifications when a cert is skipped, renewed, or error. - - --notify-mode 0|1 Set notification mode. Default value is $NOTIFY_MODE_DEFAULT. - 0: Bulk mode. Send all the domain's notifications in one message(mail). - 1: Cert mode. Send a message for every single cert. - - --notify-hook [hookname] Set the notify hook - --revoke-reason [0-10] The reason for '--revoke' command. + -b, --branch Only valid for '--upgrade' command, specifies the branch name to upgrade to. + --notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. + 0: disabled, no notification will be sent. + 1: send notifications only when there is an error. + 2: send notifications when a cert is successfully renewed, or there is an error. + 3: send notifications when a cert is skipped, renewed, or error. + --notify-mode <0|1> Set notification mode. Default value is $NOTIFY_MODE_DEFAULT. + 0: Bulk mode. Send all the domain's notifications in one message(mail). + 1: Cert mode. Send a message for every single cert. + --notify-hook Set the notify hook + --revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command. See: $_REVOKE_WIKI From d81369d63a79e3b0ea41d772b1dcafd332efa642 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Wed, 19 Aug 2020 17:37:51 +0200 Subject: [PATCH 085/190] add hyphenated options, fix wrong -ccr in usage() --- acme.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index a00e314f..76c55ca2 100755 --- a/acme.sh +++ b/acme.sh @@ -6410,27 +6410,27 @@ Commands: --issue Issue a cert. --signcsr Issue a cert from an existing csr. --deploy Deploy the cert to your server. - --install-cert Install the issued cert to apache/nginx or any other server. + -i, --install-cert Install the issued cert to apache/nginx or any other server. -r, --renew Renew a cert. --renew-all Renew all the certs. --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. --list List all the certs. - --showcsr Show the content of a csr. + --show-csr Show the content of a csr. --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. --uninstall-cronjob Uninstall the cron job. The 'uninstall' command can do this automatically. --cron Run cron job to renew all the certs. - --toPkcs Export the certificate and key to a pfx file. - --toPkcs8 Convert to pkcs8 format. + --to-pkcs Export the certificate and key to a pfx file. + --to-pkcs8 Convert to pkcs8 format. --update-account Update account info. --register-account Register account key. --deactivate-account Deactivate the account. --create-account-key Create an account private key, professional use. --create-domain-key Create an domain private key, professional use. - -ccsr, --createCSR Create CSR, professional use. + -ccr, --create-csr Create CSR, professional use. --deactivate Deactivate the domain authz, professional use. --set-notify Set the cron notification hook, level or mode. - --set-default-ca Used with '--server' , to set the default CA to use to use. + --set-default-ca Used with '--server', to set the default CA to use to use. Parameters: @@ -6490,14 +6490,14 @@ Parameters: --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer. --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses. --listraw Only used for '--list' command, list the certs in raw format. - -se, --stopRenewOnError Only valid for '--renew-all' command. Stop if one cert has error in renewal. + -se, --stop-renew-on-error Only valid for '--renew-all' command. Stop if one cert has error in renewal. --insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted. --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate. --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. - --no-color Do not output color text. + --nocolor Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' --csr Specifies the input csr. @@ -6817,10 +6817,10 @@ _process() { --cron) _CMD="cron" ;; - --toPkcs) + --toPkcs | --to-pkcs) _CMD="toPkcs" ;; - --toPkcs8) + --toPkcs8 | --to-pkcs8) _CMD="toPkcs8" ;; --createAccountKey | --createaccountkey | -cak | --create-account-key) @@ -6829,7 +6829,7 @@ _process() { --createDomainKey | --createdomainkey | -cdk | --create-domain-key) _CMD="createDomainKey" ;; - --createCSR | --createcsr | -ccr) + --createCSR | --createcsr | -ccr | --create-csr) _CMD="createCSR" ;; --deactivate) @@ -7074,7 +7074,7 @@ _process() { --listraw) _listraw="raw" ;; - --stopRenewOnError | --stoprenewonerror | -se) + --stopRenewOnError | --stoprenewonerror | -se | --stop-renew-on-error) _stopRenewOnError="1" ;; --insecure) From 7decf768837d51b41bf474009e8e54368d4b4caf Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 08:33:37 +0200 Subject: [PATCH 086/190] group commands logically, rearrange option forms in _process() Commands have been reordered in showhelp() to a more consistent grouping, help > version > install > certs > csr > account > cron > other All option alternatives in _process() case statement have been reordered toshow the canonical variants first, legacy variants after. --- acme.sh | 58 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/acme.sh b/acme.sh index 76c55ca2..fc4b7e7c 100755 --- a/acme.sh +++ b/acme.sh @@ -6408,7 +6408,6 @@ Commands: --uninstall Uninstall $PROJECT_NAME, and uninstall the cron job. --upgrade Upgrade $PROJECT_NAME to the latest code from $PROJECT. --issue Issue a cert. - --signcsr Issue a cert from an existing csr. --deploy Deploy the cert to your server. -i, --install-cert Install the issued cert to apache/nginx or any other server. -r, --renew Renew a cert. @@ -6416,20 +6415,21 @@ Commands: --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. --list List all the certs. - --show-csr Show the content of a csr. - --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. - --uninstall-cronjob Uninstall the cron job. The 'uninstall' command can do this automatically. - --cron Run cron job to renew all the certs. --to-pkcs Export the certificate and key to a pfx file. --to-pkcs8 Convert to pkcs8 format. + --sign-csr Issue a cert from an existing csr. + --show-csr Show the content of a csr. + -ccr, --create-csr Create CSR, professional use. + --create-domain-key Create an domain private key, professional use. --update-account Update account info. --register-account Register account key. --deactivate-account Deactivate the account. --create-account-key Create an account private key, professional use. - --create-domain-key Create an domain private key, professional use. - -ccr, --create-csr Create CSR, professional use. - --deactivate Deactivate the domain authz, professional use. + --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. + --uninstall-cronjob Uninstall the cron job. The 'uninstall' command can do this automatically. + --cron Run cron job to renew all the certs. --set-notify Set the cron notification hook, level or mode. + --deactivate Deactivate the domain authz, professional use. --set-default-ca Used with '--server', to set the default CA to use to use. @@ -6784,19 +6784,19 @@ _process() { --deploy) _CMD="deploy" ;; - --signcsr) + --sign-csr | --signcsr) _CMD="signcsr" ;; - --showcsr) + --show-csr | --showcsr) _CMD="showcsr" ;; - --installcert | -i | --install-cert) + -i | --install-cert | --installcert) _CMD="installcert" ;; --renew | -r) _CMD="renew" ;; - --renewAll | --renewall | --renew-all) + --renew-all | --renewAll | --renewall) _CMD="renewAll" ;; --revoke) @@ -6808,37 +6808,37 @@ _process() { --list) _CMD="list" ;; - --installcronjob | --install-cronjob) + --install-cronjob | --installcronjob) _CMD="installcronjob" ;; - --uninstallcronjob | --uninstall-cronjob) + --uninstall-cronjob | --uninstallcronjob) _CMD="uninstallcronjob" ;; --cron) _CMD="cron" ;; - --toPkcs | --to-pkcs) + --to-pkcs | --toPkcs) _CMD="toPkcs" ;; - --toPkcs8 | --to-pkcs8) + --to-pkcs8 | --toPkcs8) _CMD="toPkcs8" ;; - --createAccountKey | --createaccountkey | -cak | --create-account-key) + --create-account-key | --createAccountKey | --createaccountkey | -cak) _CMD="createAccountKey" ;; - --createDomainKey | --createdomainkey | -cdk | --create-domain-key) + --create-domain-key | --createDomainKey | --createdomainkey | -cdk) _CMD="createDomainKey" ;; - --createCSR | --createcsr | -ccr | --create-csr) + -ccr | --create-csr | --createCSR | --createcsr) _CMD="createCSR" ;; --deactivate) _CMD="deactivate" ;; - --updateaccount | --update-account) + --update-account | --updateaccount) _CMD="updateaccount" ;; - --registeraccount | --register-account) + --register-account | --registeraccount) _CMD="registeraccount" ;; --deactivate-account) @@ -6850,7 +6850,7 @@ _process() { --set-default-ca) _CMD="setdefaultca" ;; - --domain | -d) + -d | --domain) _dvalue="$2" if [ "$_dvalue" ]; then @@ -6881,7 +6881,7 @@ _process() { shift ;; - --force | -f) + -f | --force) FORCE="1" ;; --staging | --test) @@ -6903,7 +6903,7 @@ _process() { --output-insecure) export OUTPUT_INSECURE=1 ;; - --webroot | -w) + -w | --webroot) wvalue="$2" if [ -z "$_webroot" ]; then _webroot="$wvalue" @@ -6993,7 +6993,7 @@ _process() { _keylength="$2" shift ;; - --accountkeylength | -ak) + -ak | --accountkeylength) _accountkeylength="$2" shift ;; @@ -7031,7 +7031,7 @@ _process() { LE_WORKING_DIR="$2" shift ;; - --certhome | --cert-home) + --cert-home | --certhome) _certhome="$2" CERT_HOME="$_certhome" shift @@ -7046,7 +7046,7 @@ _process() { USER_AGENT="$_useragent" shift ;; - --accountemail | -m) + -m | --accountemail) _accountemail="$2" ACCOUNT_EMAIL="$_accountemail" shift @@ -7074,7 +7074,7 @@ _process() { --listraw) _listraw="raw" ;; - --stopRenewOnError | --stoprenewonerror | -se | --stop-renew-on-error) + -se | --stop-renew-on-error | --stopRenewOnError | --stoprenewonerror) _stopRenewOnError="1" ;; --insecure) @@ -7097,7 +7097,7 @@ _process() { --noprofile) _noprofile="1" ;; - --no-color) + --nocolor | --no-color) export ACME_NO_COLOR=1 ;; --force-color) From b086afb2720731176ce63823409d4287516bbe24 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 09:00:58 +0200 Subject: [PATCH 087/190] fix some more issues in showhelp() --- acme.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/acme.sh b/acme.sh index fc4b7e7c..3ac44d35 100755 --- a/acme.sh +++ b/acme.sh @@ -6447,7 +6447,7 @@ Parameters: --debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted. --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for security. - -w, --webroot Specifies the web root folder for web root mode. + -w, --webroot Specifies the web root folder for web root mode. --standalone Use standalone mode. --alpn Use standalone alpn mode. --stateless Use stateless mode. @@ -6459,7 +6459,7 @@ Parameters: It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically. -k, --keylength Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. -ak, --accountkeylength Specifies the account key length: 2048, 3072, 4096 - --log [/path/to/logfile] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted. + --log [file] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted. --log-level <1|2> Specifies the log level, default is 1. --syslog <0|3|6|7> Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. --eab-kid Key Identifier for External Account Binding. @@ -6468,11 +6468,10 @@ Parameters: These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: - --cert-file Path to copy the cert file to after issue/renew.. - --key-file Path to copy the key file to after issue/renew. - --ca-file Path to copy the intermediate cert file to after issue/renew. - --fullchain-file Path to copy the fullchain cert file to after issue/renew. - + --cert-file Path to copy the cert file to after issue/renew.. + --key-file Path to copy the key file to after issue/renew. + --ca-file Path to copy the intermediate cert file to after issue/renew. + --fullchain-file Path to copy the fullchain cert file to after issue/renew. --reloadcmd Command to execute after issue/renew to reload the server. --server ACME Directory Resource URI. (default: $DEFAULT_CA) From e7a6ff39f9b3ae514165d4773c326b68bd6a67d1 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 09:14:15 +0200 Subject: [PATCH 088/190] fix wrong indentation --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3ac44d35..990e422b 100755 --- a/acme.sh +++ b/acme.sh @@ -7045,7 +7045,7 @@ _process() { USER_AGENT="$_useragent" shift ;; - -m | --accountemail) + -m | --accountemail) _accountemail="$2" ACCOUNT_EMAIL="$_accountemail" shift From 58150f5dcd62a99eec2f4565d581e12358fbcf05 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 17:17:30 +0200 Subject: [PATCH 089/190] change --pkcs to --pkcs12 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 990e422b..22b5a580 100755 --- a/acme.sh +++ b/acme.sh @@ -6415,7 +6415,7 @@ Commands: --revoke Revoke a cert. --remove Remove the cert from list of certs known to $PROJECT_NAME. --list List all the certs. - --to-pkcs Export the certificate and key to a pfx file. + --to-pkcs12 Export the certificate and key to a pfx file. --to-pkcs8 Convert to pkcs8 format. --sign-csr Issue a cert from an existing csr. --show-csr Show the content of a csr. @@ -6816,7 +6816,7 @@ _process() { --cron) _CMD="cron" ;; - --to-pkcs | --toPkcs) + --to-pkcs12 | --toPkcs) _CMD="toPkcs" ;; --to-pkcs8 | --toPkcs8) From 07fdb087dccd9df358c2bdfef9b61c4208408fe7 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Thu, 20 Aug 2020 17:23:40 +0200 Subject: [PATCH 090/190] fix typo --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 22b5a580..87cb927f 100755 --- a/acme.sh +++ b/acme.sh @@ -6511,7 +6511,7 @@ Parameters: --listen-v6 Force standalone/tls server to listen at ipv6. --openssl-bin Specifies a custom openssl bin location. --use-wget Force to use wget, if you have both curl and wget installed. - --yes-I-know-dns-manual-mode-enough-go-ahead-please Force use ofdns manual mode. + --yes-I-know-dns-manual-mode-enough-go-ahead-please Force use of dns manual mode. See: $_DNS_MANUAL_WIKI -b, --branch Only valid for '--upgrade' command, specifies the branch name to upgrade to. --notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. From 2910be82a4d5684490db30b2d2be6cdb8a17f086 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 09:54:47 +0200 Subject: [PATCH 091/190] revert change of --no-color option --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 87cb927f..d2424dee 100755 --- a/acme.sh +++ b/acme.sh @@ -6496,7 +6496,7 @@ Parameters: --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. - --nocolor Do not output color text. + --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' --csr Specifies the input csr. @@ -7096,7 +7096,7 @@ _process() { --noprofile) _noprofile="1" ;; - --nocolor | --no-color) + --no-color) export ACME_NO_COLOR=1 ;; --force-color) From 1521199e443bddf8e13eb695af3090c6d0a1586a Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 09:56:57 +0200 Subject: [PATCH 092/190] add hidden alias --to-pkcs for --to-pkcs12 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d2424dee..6719d1e6 100755 --- a/acme.sh +++ b/acme.sh @@ -6816,7 +6816,7 @@ _process() { --cron) _CMD="cron" ;; - --to-pkcs12 | --toPkcs) + --to-pkcs12 | --to-pkcs | --toPkcs) _CMD="toPkcs" ;; --to-pkcs8 | --toPkcs8) From a48c22d14fab2f29c95eefc04460adf4e3f7888a Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 09:58:58 +0200 Subject: [PATCH 093/190] add missing blank lines after links to wiki --- acme.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/acme.sh b/acme.sh index 6719d1e6..3679cc0b 100755 --- a/acme.sh +++ b/acme.sh @@ -6437,11 +6437,14 @@ Parameters: -d, --domain Specifies a domain, used to issue, renew or revoke etc. --challenge-alias The challenge domain alias for DNS alias mode. See: $_DNS_ALIAS_WIKI + --domain-alias The domain alias for DNS alias mode. See: $_DNS_ALIAS_WIKI + --preferred-chain If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used. (default: empty) See: $_PREFERRED_CHAIN_WIKI + -f, --force Force install, force cert renewal or override sudo restrictions. --staging, --test Use staging server, for testing. --debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted. @@ -6452,9 +6455,11 @@ Parameters: --alpn Use standalone alpn mode. --stateless Use stateless mode. See: $_STATELESS_WIKI + --apache Use apache mode. --dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted. See: $_DNS_API_WIKI + --dnssleep The time in seconds to wait for all the txt records to propagate in dns api mode. It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically. -k, --keylength Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. @@ -6513,6 +6518,7 @@ Parameters: --use-wget Force to use wget, if you have both curl and wget installed. --yes-I-know-dns-manual-mode-enough-go-ahead-please Force use of dns manual mode. See: $_DNS_MANUAL_WIKI + -b, --branch Only valid for '--upgrade' command, specifies the branch name to upgrade to. --notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. 0: disabled, no notification will be sent. From 6fbf33c8f4f9a643f83caf279ff8ca292598f4d7 Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 21 Aug 2020 09:54:24 +0100 Subject: [PATCH 094/190] More changes --- .github/workflows/dockerhub.yml | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 8c277827..fc1db8e5 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -2,7 +2,12 @@ name: Build DockerHub on: push: - branches: [ master, dev ] + branches: + - master + - dev + - temp + tags: + - '*' jobs: build: @@ -12,23 +17,21 @@ jobs: uses: actions/checkout@v2 - name: install buildx id: buildx - uses: crazy-max/ghaction-docker-buildx@v1 + uses: crazy-max/ghaction-docker-buildx@v3 with: - version: latest + buildx-version: latest + qemu-version: latest - name: login to docker hub run: | echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - - name: build and push the image (master branch) - run: | - docker buildx build \ - --push \ - --tag neilpang/acme.sh:latest \ - --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . - if: ${{ github.ref == 'refs/heads/master' }} - - name: build and push the image (dev branch) + - name: build and push the image run: | + DOCKER_IMAGE_TAG=$(echo ${GITHUB_REF#refs/heads/} | sed 's/^master$/latest/') + [ "$DOCKER_IMAGE" == "latest" ] && AUTO_UPGRADE="1" || AUTO_UPGRADE="" + docker buildx build \ - --push \ - --tag neilpang/acme.sh:dev \ + --output "type=image,push=true" \ + --tag ei99070/acme.sh:${DOCKER_IMAGE_TAG} \ + --tag ei99070/acme.sh:${GITHUB_SHA} \ + --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . - if: ${{ github.ref == 'refs/heads/dev' }} From abc62b9348d6d01a0da8c17b6d6afe9e42ec84df Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 21 Aug 2020 10:34:43 +0100 Subject: [PATCH 095/190] more --- .github/workflows/dockerhub.yml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index fc1db8e5..4a5efc38 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -26,12 +26,25 @@ jobs: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - name: build and push the image run: | - DOCKER_IMAGE_TAG=$(echo ${GITHUB_REF#refs/heads/} | sed 's/^master$/latest/') - [ "$DOCKER_IMAGE" == "latest" ] && AUTO_UPGRADE="1" || AUTO_UPGRADE="" + DOCKER_IMAGE=ei99070/acme.sh + + if [[ $GITHUB_REF == refs/tags/* ]]; then + BRANCH_TAG=${GITHUB_REF#refs/tags/} + AUTO_UPGRADE=1 + fi + + if [[ $GITHUB_REF == refs/heads/* ]]; then + BRANCH_TAG=${GITHUB_REF#refs/heads/} + + if [[ $BRANCH_TAG == master ]]; then + BRANCH_TAG=latest + AUTO_UPGRADE=1 + fi + fi docker buildx build \ + --tag ${DOCKER_IMAGE}:${BRANCH_TAG} \ + --tag ${DOCKER_IMAGE}:${GITHUB_SHA} \ --output "type=image,push=true" \ - --tag ei99070/acme.sh:${DOCKER_IMAGE_TAG} \ - --tag ei99070/acme.sh:${GITHUB_SHA} \ --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . From fcb6198a823da64f1e02815f4d994d05bceb9fa0 Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 21 Aug 2020 10:55:07 +0100 Subject: [PATCH 096/190] More updated following PR comments --- .github/workflows/dockerhub.yml | 15 ++++++--------- Dockerfile | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index bd96a8de..cf65f4a6 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -3,8 +3,7 @@ name: Build DockerHub on: push: branches: - - master - - dev + - '*' tags: - '*' @@ -28,22 +27,20 @@ jobs: DOCKER_IMAGE=neilpang/acme.sh if [[ $GITHUB_REF == refs/tags/* ]]; then - BRANCH_TAG=${GITHUB_REF#refs/tags/} - AUTO_UPGRADE=1 + DOCKER_IMAGE_TAG=${GITHUB_REF#refs/tags/} fi if [[ $GITHUB_REF == refs/heads/* ]]; then - BRANCH_TAG=${GITHUB_REF#refs/heads/} + DOCKER_IMAGE_TAG=${GITHUB_REF#refs/heads/} - if [[ $BRANCH_TAG == master ]]; then - BRANCH_TAG=latest + if [[ $DOCKER_IMAGE_TAG == master ]]; then + DOCKER_IMAGE_TAG=latest AUTO_UPGRADE=1 fi fi docker buildx build \ - --tag ${DOCKER_IMAGE}:${BRANCH_TAG} \ - --tag ${DOCKER_IMAGE}:${GITHUB_SHA} \ + --tag ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG} \ --output "type=image,push=true" \ --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . diff --git a/Dockerfile b/Dockerfile index f00d03bd..a61c6ab4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ RUN apk update -f \ ENV LE_CONFIG_HOME /acme.sh -ENV AUTO_UPGRADE 1 +ARG AUTO_UPGRADE=1 #Install ADD ./ /install_acme.sh/ From 05477c1a0312215615241871c42b4376f9565027 Mon Sep 17 00:00:00 2001 From: Pedro Lamas Date: Fri, 21 Aug 2020 11:03:53 +0100 Subject: [PATCH 097/190] Fixes Dockerfile --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index a61c6ab4..4cea3c06 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,6 +17,8 @@ ENV LE_CONFIG_HOME /acme.sh ARG AUTO_UPGRADE=1 +ENV AUTO_UPGRADE $AUTO_UPGRADE + #Install ADD ./ /install_acme.sh/ RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/ From 2e87e64bd1036b2d98f831a5a686003303b0c350 Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 12:12:30 +0200 Subject: [PATCH 098/190] update individual Usage: messages to match showHelp --- acme.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/acme.sh b/acme.sh index 3679cc0b..168ab8da 100755 --- a/acme.sh +++ b/acme.sh @@ -1375,7 +1375,7 @@ toPkcs() { domain="$1" pfxPassword="$2" if [ -z "$domain" ]; then - _usage "Usage: $PROJECT_ENTRY --toPkcs -d domain [--password pfx-password]" + _usage "Usage: $PROJECT_ENTRY --to-pkcs12 --domain [--password ] [--ecc]" return 1 fi @@ -1396,7 +1396,7 @@ toPkcs8() { domain="$1" if [ -z "$domain" ]; then - _usage "Usage: $PROJECT_ENTRY --toPkcs8 -d domain [--ecc]" + _usage "Usage: $PROJECT_ENTRY --to-pkcs8 --domain [--ecc]" return 1 fi @@ -1416,7 +1416,7 @@ toPkcs8() { createAccountKey() { _info "Creating account key" if [ -z "$1" ]; then - _usage "Usage: $PROJECT_ENTRY --createAccountKey --accountkeylength 2048" + _usage "Usage: $PROJECT_ENTRY --create-account-key [--accountkeylength ]" return fi @@ -1459,7 +1459,7 @@ _create_account_key() { createDomainKey() { _info "Creating domain key" if [ -z "$1" ]; then - _usage "Usage: $PROJECT_ENTRY --createDomainKey -d domain.com [ --keylength 2048 ]" + _usage "Usage: $PROJECT_ENTRY --create-domain-key --domain [--keylength ]" return fi @@ -1499,7 +1499,7 @@ createDomainKey() { createCSR() { _info "Creating csr" if [ -z "$1" ]; then - _usage "Usage: $PROJECT_ENTRY --createCSR -d domain1.com [-d domain2.com -d domain3.com ... ]" + _usage "Usage: $PROJECT_ENTRY --create-csr --domain [--domain ...]" return fi @@ -2888,7 +2888,7 @@ Allow from all if _restoreApache; then _err "The apache config file is restored." else - _err "Sorry, The apache config file can not be restored, please report bug." + _err "Sorry, the apache config file can not be restored, please report bug." fi return 1 fi @@ -4012,7 +4012,7 @@ _match_issuer() { #webroot, domain domainlist keylength issue() { if [ -z "$2" ]; then - _usage "Usage: $PROJECT_ENTRY --issue -d a.com -w /path/to/webroot/a.com/ " + _usage "Usage: $PROJECT_ENTRY --issue --domain --webroot " return 1 fi if [ -z "$1" ]; then @@ -4993,7 +4993,7 @@ _split_cert_chain() { renew() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then - _usage "Usage: $PROJECT_ENTRY --renew -d domain.com [--ecc]" + _usage "Usage: $PROJECT_ENTRY --renew --domain [--ecc]" return 1 fi @@ -5003,7 +5003,7 @@ renew() { _info "$(__green "Renew: '$Le_Domain'")" if [ ! -f "$DOMAIN_CONF" ]; then - _info "'$Le_Domain' is not a issued domain, skip." + _info "'$Le_Domain' is not an issued domain, skip." return $RENEW_SKIP fi @@ -5082,7 +5082,7 @@ renewAll() { for di in "${CERT_HOME}"/*.*/; do _debug di "$di" if ! [ -d "$di" ]; then - _debug "Not directory, skip: $di" + _debug "Not a directory, skip: $di" continue fi d=$(basename "$di") @@ -5185,7 +5185,7 @@ signcsr() { _csrfile="$1" _csrW="$2" if [ -z "$_csrfile" ] || [ -z "$_csrW" ]; then - _usage "Usage: $PROJECT_ENTRY --signcsr --csr mycsr.csr -w /path/to/webroot/a.com/ " + _usage "Usage: $PROJECT_ENTRY --sign-csr --csr --webroot " return 1 fi @@ -5253,7 +5253,7 @@ showcsr() { _csrfile="$1" _csrd="$2" if [ -z "$_csrfile" ] && [ -z "$_csrd" ]; then - _usage "Usage: $PROJECT_ENTRY --showcsr --csr mycsr.csr" + _usage "Usage: $PROJECT_ENTRY --show-csr --csr " return 1 fi @@ -5370,7 +5370,7 @@ deploy() { _hooks="$2" _isEcc="$3" if [ -z "$_hooks" ]; then - _usage "Usage: $PROJECT_ENTRY --deploy -d domain.com --deploy-hook cpanel [--ecc] " + _usage "Usage: $PROJECT_ENTRY --deploy --domain --deploy-hook [--ecc] " return 1 fi @@ -5391,7 +5391,7 @@ deploy() { installcert() { _main_domain="$1" if [ -z "$_main_domain" ]; then - _usage "Usage: $PROJECT_ENTRY --installcert -d domain.com [--ecc] [--cert-file cert-file-path] [--key-file key-file-path] [--ca-file ca-cert-file-path] [ --reloadCmd reloadCmd] [--fullchain-file fullchain-path]" + _usage "Usage: $PROJECT_ENTRY --install-cert --domain [--ecc] [--cert-file ] [--key-file ] [--ca-file ] [ --reloadcmd ] [--fullchain-file ]" return 1 fi @@ -5670,7 +5670,7 @@ uninstallcronjob() { revoke() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then - _usage "Usage: $PROJECT_ENTRY --revoke -d domain.com [--ecc]" + _usage "Usage: $PROJECT_ENTRY --revoke --domain [--ecc]" return 1 fi @@ -5741,7 +5741,7 @@ revoke() { remove() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then - _usage "Usage: $PROJECT_ENTRY --remove -d domain.com [--ecc]" + _usage "Usage: $PROJECT_ENTRY --remove --domain [--ecc]" return 1 fi @@ -5901,7 +5901,7 @@ deactivate() { _initAPI _debug _d_domain_list "$_d_domain_list" if [ -z "$(echo $_d_domain_list | cut -d , -f 1)" ]; then - _usage "Usage: $PROJECT_ENTRY --deactivate -d domain.com [-d domain.com]" + _usage "Usage: $PROJECT_ENTRY --deactivate --domain [--domain ...]" return 1 fi for _d_dm in $(echo "$_d_domain_list" | tr ',' ' '); do @@ -6361,7 +6361,7 @@ setnotify() { _initpath if [ -z "$_nhook$_nlevel$_nmode" ]; then - _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook mailgun] [--notify-level $NOTIFY_LEVEL_DEFAULT] [--notify-mode $NOTIFY_MODE_DEFAULT]" + _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook ] [--notify-level <0|1|2|3>] [--notify-mode <0|1>]" _usage "$_NOTIFY_WIKI" return 1 fi @@ -6400,7 +6400,7 @@ setnotify() { showhelp() { _initpath version - echo "Usage: $PROJECT_ENTRY command ...[parameters].... + echo "Usage: $PROJECT_ENTRY ... [parameters ...] Commands: -h, --help Show this help message. -v, --version Show version info. From dd6c5c9eea7d76d9e6eb32c606cab2192430b7ab Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 12:15:45 +0200 Subject: [PATCH 099/190] add documentation for --password option --- acme.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acme.sh b/acme.sh index 168ab8da..3b56b8d6 100755 --- a/acme.sh +++ b/acme.sh @@ -6532,6 +6532,8 @@ Parameters: --revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command. See: $_REVOKE_WIKI + --password Add a password to exported pfx file. Use with --to-pkcs12. + " } From b67d663a388660ceb0a4f0f3ded422b25affb40d Mon Sep 17 00:00:00 2001 From: Christopher Engelhard Date: Fri, 21 Aug 2020 12:19:26 +0200 Subject: [PATCH 100/190] fix wrong options listed in --ecc help entry --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3b56b8d6..b5fafa4b 100755 --- a/acme.sh +++ b/acme.sh @@ -6503,7 +6503,7 @@ Parameters: --noprofile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. - --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' + --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--to-pkcs12' and '--create-csr' --csr Specifies the input csr. --pre-hook Command to be run before obtaining any certificates. --post-hook Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed. From 328b6d1cc696b93c129e2ee165eb520fbbf22934 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 21 Aug 2020 18:19:26 +0800 Subject: [PATCH 101/190] add docker hub badge --- .github/workflows/shellcheck.yml | 2 +- README.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 529f41e1..a6f82d9e 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -1,4 +1,4 @@ -name: shellcheck +name: Shellcheck on: [push, pull_request] jobs: diff --git a/README.md b/README.md index bf6ea06c..812e5602 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/shellcheck/badge.svg) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) From f511a5270590a7fc834df02470b4709629768bb7 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Mon, 24 Aug 2020 00:05:21 +0300 Subject: [PATCH 102/190] Using _post function --- deploy/vault.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/deploy/vault.sh b/deploy/vault.sh index ae771967..c51ceb0f 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -49,14 +49,15 @@ vault_deploy() { _cfullchain=$(sed -z 's/\n/\\n/g' <"$5") URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain" + export _H1="X-Vault-Token: $VAULT_TOKEN" if [ -n "$FABIO" ]; then - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" || return 1 + _post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" else - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_ccert\"}" "$URL/cert.pem" || return 1 - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_ckey\"}" "$URL/cert.key" || return 1 - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_cca\"}" "$URL/chain.pem" || return 1 - curl --silent -H "X-Vault-Token: $VAULT_TOKEN" --request POST --data "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" || return 1 + _post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" + _post "{\"value\": \"$_ckey\"}" "$URL/cert.key" + _post "{\"value\": \"$_cca\"}" "$URL/chain.pem" + _post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" fi } From 8d0e4851200ef060cb2344225acbd875b834d84f Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 27 Aug 2020 18:07:26 +0800 Subject: [PATCH 103/190] add set-default-ca --- Dockerfile | 1 + acme.sh | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 4cea3c06..2ccf6800 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,6 +54,7 @@ RUN for verb in help \ deactivate \ deactivate-account \ set-notify \ + set-default-ca \ ; do \ printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \ ; done diff --git a/acme.sh b/acme.sh index b5fafa4b..ad29669c 100755 --- a/acme.sh +++ b/acme.sh @@ -6430,7 +6430,8 @@ Commands: --cron Run cron job to renew all the certs. --set-notify Set the cron notification hook, level or mode. --deactivate Deactivate the domain authz, professional use. - --set-default-ca Used with '--server', to set the default CA to use to use. + --set-default-ca Used with '--server', Set the default CA to use. + See: $_SERVER_WIKI Parameters: From fdb96e91f1bc585bbb2145e999fdc83147fe4ab8 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 21:41:18 +0800 Subject: [PATCH 104/190] match issuer ignoring case --- acme.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/acme.sh b/acme.sh index ad29669c..891f0d81 100755 --- a/acme.sh +++ b/acme.sh @@ -4006,6 +4006,11 @@ _match_issuer() { _missuer="$2" _fissuers="$(_get_cert_issuers $_cfile)" _debug2 _fissuers "$_fissuers" + if _contains "$_fissuers" "$_missuer"; then + return 0 + fi + _fissuers="$(echo "$_fissuers" | _lower_case)" + _missuer="$(echo "$_missuer" | _lower_case)" _contains "$_fissuers" "$_missuer" } From f1692b3436725e0f43d285d4fc46390ba8600584 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 20:10:12 +0800 Subject: [PATCH 105/190] begin 2.8.8 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 891f0d81..c36ce80e 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.8.7 +VER=2.8.8 PROJECT_NAME="acme.sh" From 1ad450d753959bf1231655d70899acfe222459cb Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 21:45:26 +0800 Subject: [PATCH 106/190] add ubuntu test in github actions --- .github/workflows/Ubuntu.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/Ubuntu.yml diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml new file mode 100644 index 00000000..1b89c28c --- /dev/null +++ b/.github/workflows/Ubuntu.yml @@ -0,0 +1,14 @@ +name: PebbleStrict +on: [push, pull_request] + +jobs: + PebbleStrict: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh From 5f4d08ada5962f9d3d0adfdba72af4d5a5c402c4 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 21:46:29 +0800 Subject: [PATCH 107/190] fix name --- .github/workflows/Ubuntu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 1b89c28c..523bfefb 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -1,8 +1,8 @@ -name: PebbleStrict +name: Ubuntu on: [push, pull_request] jobs: - PebbleStrict: + Ubuntu: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From 8017774bf398c13fe6d43d85d5e7189781216046 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 21:49:19 +0800 Subject: [PATCH 108/190] add token --- .github/workflows/Ubuntu.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 523bfefb..5c0859a4 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -4,6 +4,8 @@ on: [push, pull_request] jobs: Ubuntu: runs-on: ubuntu-latest + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} steps: - uses: actions/checkout@v2 - name: Install tools From e087bccd339e054790300297fbd3e6b0c53fdb55 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 22:17:10 +0800 Subject: [PATCH 109/190] remove travis --- .github/workflows/LetsEncrypt.yml | 30 +++++++++++++++++++++++++ .github/workflows/Ubuntu.yml | 16 ------------- .travis.yml | 37 ------------------------------- 3 files changed, 30 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/LetsEncrypt.yml delete mode 100644 .github/workflows/Ubuntu.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml new file mode 100644 index 00000000..83a1a931 --- /dev/null +++ b/.github/workflows/LetsEncrypt.yml @@ -0,0 +1,30 @@ +name: LetsEncrypt +on: [push, pull_request] + +jobs: + Ubuntu: + runs-on: ubuntu-latest + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh + + MacOS: + needs: Ubuntu + runs-on: macos-latest + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: brew update && brew install socat; + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh \ No newline at end of file diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml deleted file mode 100644 index 5c0859a4..00000000 --- a/.github/workflows/Ubuntu.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Ubuntu -on: [push, pull_request] - -jobs: - Ubuntu: - runs-on: ubuntu-latest - env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} - steps: - - uses: actions/checkout@v2 - - name: Install tools - run: sudo apt-get install -y socat - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - name: Run acmetest - run: cd ../acmetest && ./letest.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2741e719..00000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -language: shell -dist: bionic - -os: - - linux - - osx - -services: - - docker - -env: - global: - - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 - - -install: - - if [ "$TRAVIS_OS_NAME" = 'osx' ]; then - brew update && brew install socat; - export PATH="/usr/local/opt/openssl@1.1/bin:$PATH" ; - fi - -script: - - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" - - command -V openssl && openssl version - - if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -sSL $SHFMT_URL -o ~/shfmt && chmod +x ~/shfmt && ~/shfmt -l -w -i 2 . ; fi - - if [ "$TRAVIS_OS_NAME" = "linux" ]; then git diff --exit-code && echo "shfmt OK" ; fi - - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi - - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" ; fi - - cd .. - - git clone --depth 1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./rundocker.sh testplat ubuntu:latest ; fi - - if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ACME_OPENSSL_BIN="$ACME_OPENSSL_BIN" ./letest.sh ; fi - -matrix: - fast_finish: true - - From e66337a1db904359691c23133342998f492cb153 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 27 Aug 2020 22:35:05 +0800 Subject: [PATCH 110/190] fix badge --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 812e5602..9b7d48cc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # An ACME Shell script: acme.sh -[![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh) + +![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) ![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) @@ -11,8 +12,6 @@ [![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub") -acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial - - An ACME protocol client written purely in Shell (Unix shell) language. - Full ACME protocol implementation. @@ -77,7 +76,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) |18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris |19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux -|20|[![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh)|Mac OSX +|20|[![Build Status](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX |21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): From f0c710b245be71acb4aa98dca8aee88f5f3788e5 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 09:32:38 +0800 Subject: [PATCH 111/190] Update LetsEncrypt.yml --- .github/workflows/LetsEncrypt.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 83a1a931..a239a9ca 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -6,6 +6,7 @@ jobs: runs-on: ubuntu-latest env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 - name: Install tools @@ -13,13 +14,14 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && ./letest.sh + run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh MacOS: needs: Ubuntu runs-on: macos-latest env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 steps: - uses: actions/checkout@v2 - name: Install tools @@ -27,4 +29,4 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && ./letest.sh \ No newline at end of file + run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh From f170ee9e598851dfc593beb6299fa8d459dd1969 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 23:18:05 +0800 Subject: [PATCH 112/190] add Windows --- .github/workflows/LetsEncrypt.yml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index a239a9ca..5145d006 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -17,8 +17,8 @@ jobs: run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh MacOS: - needs: Ubuntu runs-on: macos-latest + needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -30,3 +30,32 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh + + Windows: + runs-on: windows-latest + needs: MacOS + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 + steps: + - uses: actions/checkout@v2 + - name: Install cygwin base packages with chocolatey + run: | + choco config get cacheLocation + choco install cygwin + shell: cmd + - name: Install cygwin additional packages + run: | + C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,git + shell: cmd + - name: Set ENV + run: | + echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' + - name: Clone acmetest + shell: cmd + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + shell: cmd + run: cd ../acmetest && bash.exe -c ./letest.sh + + From 9f80df3fcb4989170e01e7432eb8bf0f1808176d Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 23:31:18 +0800 Subject: [PATCH 113/190] add unzip --- .github/workflows/LetsEncrypt.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 5145d006..86d9ad3e 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -42,11 +42,11 @@ jobs: - name: Install cygwin base packages with chocolatey run: | choco config get cacheLocation - choco install cygwin + choco install --no-progress cygwin shell: cmd - name: Install cygwin additional packages run: | - C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,git + C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git shell: cmd - name: Set ENV run: | From 763c05313beae4e25acee004f4debfd064f34dc6 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 28 Aug 2020 23:54:39 +0800 Subject: [PATCH 114/190] 80 port of github windows server is already used. --- .github/workflows/LetsEncrypt.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 86d9ad3e..90a94982 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -37,6 +37,7 @@ jobs: env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 + Le_HTTPPort: 8888 steps: - uses: actions/checkout@v2 - name: Install cygwin base packages with chocolatey From 3b3d7eff3c95adc2893c2898b3b717d8476e69a1 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 00:35:33 +0800 Subject: [PATCH 115/190] remove \r --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 90a94982..23d1f055 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -54,7 +54,7 @@ jobs: echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' - name: Clone acmetest shell: cmd - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ && sed -i 's/\r//g' acmetest/acme.sh/acme.sh - name: Run acmetest shell: cmd run: cd ../acmetest && bash.exe -c ./letest.sh From 395fdc9d61701bd3a9fb4b1bb812663461a579ae Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 18:49:39 +0200 Subject: [PATCH 116/190] Added support for custom domains --- dnsapi/dns_dynv6.sh | 66 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 3c222d3a..f1471643 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -13,14 +13,18 @@ dns_dynv6_add() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exist on your dynv6 account" - return 1 + + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -44,14 +48,17 @@ dns_dynv6_rm() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exist on your dynv6 account" - return 1 + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 @@ -72,29 +79,30 @@ _generate_new_key() { return 1 fi } -#Usage: _acme-challenge.www.example.dynv6.net + +#Usage: _acme-challenge.www.example.dynv6.net "$_your_hosts" +#where _your_hosts is the output of ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts #returns #_host= example.dynv6.net #_record=_acme-challenge.www #aborts if not a valid domain _get_domain() { + #_your_hosts="$(ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts)" _full_domain="$1" - _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks'; then - _err "The hosts does not seem to be a dynv6 host" - return 1 - fi - _record="${_full_domain%.*}" - _record="${_record%.*}" - _record="${_record%.*}" - _debug "The record we are ging to use is $_record" - _host="$_full_domain" - while [ "$(echo "$_host" | grep -o '\.' | wc -l)" != "2" ]; do - _host="${_host#*.}" - done - _debug "And the host is $_host" - return 0 + _your_hosts="$2" + _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" + for l in $_your_hosts; do + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi + done + _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" + return 1 } # Usage: No input required @@ -103,7 +111,7 @@ _get_domain() { _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug Your key is "$dynv6_keyfile" + _debug "Your key is $dynv6_keyfile" if [ -z "$dynv6_keyfile" ]; then if [ -z "$KEY" ]; then _err "You did not specify a key to use with dynv6" From 0b539a597710a69e8aa2521fc8d0f4c48c6f1a0c Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 19:09:27 +0200 Subject: [PATCH 117/190] first attempt to make travis happy --- dnsapi/dns_dynv6.sh | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index f1471643..473bb243 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,17 +14,14 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" +<<<<<<< HEAD +======= +>>>>>>> first attempt to make travis happy if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -50,19 +47,12 @@ dns_dynv6_rm() { _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 - } #################### Private functions below ################################## #Usage: No Input required @@ -93,13 +83,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 From 0d4904f05dd9356a72caf7f5941bdcbdd975c654 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:42:45 +0200 Subject: [PATCH 118/190] no supporting HTTP API as well --- dnsapi/dns_dynv6.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 473bb243..dce7ce5f 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,10 +14,6 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" -<<<<<<< HEAD - -======= ->>>>>>> first attempt to make travis happy if ! _get_domain "$fulldomain" "$_your_hosts"; then _err "Host not found on your account" return 1 From 3cd7a2e6d6f6f6babee36e087abf98510c897f39 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:49:25 +0200 Subject: [PATCH 119/190] formatting --- dnsapi/dns_dynv6.sh | 212 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index dce7ce5f..5f36cef8 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -11,6 +11,7 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" @@ -27,6 +28,30 @@ dns_dynv6_add() { return 0 else _err "Something went wrong! it does not seem like the record was added succesfully" +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_add_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" + _debug "Dynv6 returned this after record was added: $returnval" + if _contains "$returnval" "created"; then + return 0 + elif _contains "$returnval" "updated"; then + return 0 + else + _err "Something went wrong! it does not seem like the record was added successfully" + return 1 + fi +>>>>>>> formatting return 1 fi return 1 @@ -39,12 +64,29 @@ dns_dynv6_rm() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then _err "Host not found on your account" return 1 +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_rm_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" + return 0 +>>>>>>> formatting fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" @@ -94,6 +136,7 @@ _get_domain() { # Usage: No input required #returns #dynv6_keyfile path to the key that will be used +<<<<<<< HEAD _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" @@ -111,5 +154,174 @@ _get_keyfile() { dynv6_keyfile="$KEY" fi _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" +======= +_get_authentication() { + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else + _debug "no HTTP token found. Looking for an SSH key" + dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" + _debug "Your key is $dynv6_keyfile" + if [ -z "$dynv6_keyfile" ]; then + if [ -z "$KEY" ]; then + _err "You did not specify a key to use with dynv6" + _info "Creating new dynv6 API key to add to dynv6.com" + _generate_new_key + _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" + _info "Hit Enter to continue" + read -r _ + #save the credentials to the account conf file. + else + dynv6_keyfile="$KEY" + fi + _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" + fi + fi +} + +_dns_dynv6_add_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi +} + +_dns_dynv6_rm_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ]; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} + +#get the zoneid for a specifc record or zone +#usage: _get_zone_id §record +#where $record is the record to get the id for +#returns _zone_id the id of the zone +_get_zone_id() { + record="$1" + _debug "getting zone id for $record" + _dynv6_rest GET zones + + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" +} + +_get_zone_name() { + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" + _zone_name="${_zone_name#name:}" +} + +#usaage _get_record_id $zone_id $record +# where zone_id is thevalue returned by _get_zone_id +# and record ist in the form _acme.www for an fqdn of _acme.www.example.com +# returns _record_id +_get_record_id() { + _zone_id="$1" + record="$2" + value="$3" + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response"; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi +} + +_get_record_id_from_response() { + response="$1" + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 +} +#usage: _set_record TXT _acme_challenge.www longvalue 12345678 +#zone id is optional can also be set as vairable bevor calling this method +_set_record() { + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" +} +_del_record() { + _zone_id=$1 + _record_id=$2 + _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" +} + +_dynv6_rest() { + m=$1 #method GET,POST,DELETE or PUT + ep="$2" #the endpoint + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$dynv6_token" | tr -d '"') + + export _H1="Authorization: Bearer $token_trimmed" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" + else + response="$(_get "$dynv6_api/$ep")" +>>>>>>> formatting fi } From c849738c6fbd15524e8e2047ffe10203101aa2a8 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 16:01:46 +0200 Subject: [PATCH 120/190] formatting --- dnsapi/dns_dynv6.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 5f36cef8..5ccab1a4 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -156,13 +156,12 @@ _get_keyfile() { _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" ======= _get_authentication() { - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" + dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" + if [ "$dynv6_token" ]; then + _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" + if [ "$DYNV6_TOKEN" ]; then + _saveaccountconf_mutable dynv6_token "$dynv6_token" + fi else _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" From 4632035581599994ed7a7349de002f2e260b76a8 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 01:32:10 +0800 Subject: [PATCH 121/190] no need to run for PR from dev to master --- .github/workflows/LetsEncrypt.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 23d1f055..4916c78b 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -1,5 +1,11 @@ name: LetsEncrypt -on: [push, pull_request] +on: + push: + branches: + - '*' + pull_request: + branches: + - dev jobs: Ubuntu: From 185b558561f8cbeef9598f97f6b8b18d2cdfe099 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Fri, 28 Aug 2020 19:46:45 +0200 Subject: [PATCH 122/190] fix shfmt error --- dnsapi/dns_dynv6.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index e51e118a..9efc9aeb 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -260,7 +260,7 @@ _del_record() { _dynv6_rest() { m=$1 #method GET,POST,DELETE or PUT - ep="$2" #the endpoint + ep="$2" #the endpoint data="$3" _debug "$ep" From 7d7e5bac123cff13061e3e957bf1ba4460e4e8b3 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 09:54:02 +0800 Subject: [PATCH 123/190] add comments --- .github/workflows/LetsEncrypt.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 4916c78b..ad31b752 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -43,6 +43,7 @@ jobs: env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 + #The 80 port is used by Windows server, we have to use a custom port, ngrok will also use this port. Le_HTTPPort: 8888 steps: - uses: actions/checkout@v2 From c2214cd4b509ed5b136fad91b59f02ca539bd8f5 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 13:06:58 +0800 Subject: [PATCH 124/190] minor --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b7d48cc..953c44a5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # An ACME Shell script: acme.sh -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) -![shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) +![LetsEncrypt](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg) +![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) +![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) +![DockerHub](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) From 918c8f9295ac385ad5478746b35cc74179a3aacf Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 13:14:28 +0800 Subject: [PATCH 125/190] filer events --- .github/workflows/LetsEncrypt.yml | 5 +++++ .github/workflows/PebbleStrict.yml | 12 +++++++++++- .github/workflows/shellcheck.yml | 12 +++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index ad31b752..3af574a7 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -3,9 +3,14 @@ on: push: branches: - '*' + paths: + - '**.sh' pull_request: branches: - dev + paths: + - '**.sh' + jobs: Ubuntu: diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index a339f727..ffc2ccdc 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -1,5 +1,15 @@ name: PebbleStrict -on: [push, pull_request] +on: + push: + branches: + - '*' + paths: + - '**.sh' + pull_request: + branches: + - dev + paths: + - '**.sh' jobs: PebbleStrict: diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index a6f82d9e..402492ad 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -1,5 +1,15 @@ name: Shellcheck -on: [push, pull_request] +on: + push: + branches: + - '*' + paths: + - '**.sh' + pull_request: + branches: + - dev + paths: + - '**.sh' jobs: formatCheck: From b639683ac1c821f675b1ddd2f6b2c5539744c91e Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 14:11:11 +0800 Subject: [PATCH 126/190] don't run if "${{ secrets.NGROK_TOKEN }}" is not set. --- .github/workflows/LetsEncrypt.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 3af574a7..e9f0897d 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -15,6 +15,7 @@ on: jobs: Ubuntu: runs-on: ubuntu-latest + if: "${{ secrets.NGROK_TOKEN }}" env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -29,6 +30,7 @@ jobs: MacOS: runs-on: macos-latest + if: "${{ secrets.NGROK_TOKEN }}" needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} @@ -44,6 +46,7 @@ jobs: Windows: runs-on: windows-latest + if: "${{ secrets.NGROK_TOKEN }}" needs: MacOS env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} From e88180b4d5b7168c99bd10a85e51b885fdc5f9f8 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 14:19:17 +0800 Subject: [PATCH 127/190] fix if --- .github/workflows/LetsEncrypt.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index e9f0897d..3101205c 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -15,7 +15,7 @@ on: jobs: Ubuntu: runs-on: ubuntu-latest - if: "${{ secrets.NGROK_TOKEN }}" + if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -30,7 +30,7 @@ jobs: MacOS: runs-on: macos-latest - if: "${{ secrets.NGROK_TOKEN }}" + if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} @@ -46,7 +46,7 @@ jobs: Windows: runs-on: windows-latest - if: "${{ secrets.NGROK_TOKEN }}" + if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" needs: MacOS env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} From 70366a98bd596ba8d6bd8160251c3d08b5a48d7d Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 14:33:33 +0800 Subject: [PATCH 128/190] fix if --- .github/workflows/LetsEncrypt.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 3101205c..818e2d19 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -15,7 +15,7 @@ on: jobs: Ubuntu: runs-on: ubuntu-latest - if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" + if: "contains(secrets.NGROK_TOKEN, '-')" env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -30,7 +30,7 @@ jobs: MacOS: runs-on: macos-latest - if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" + if: "contains(secrets.NGROK_TOKEN, '-')" needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} @@ -46,7 +46,7 @@ jobs: Windows: runs-on: windows-latest - if: "${{ contains(secrets.NGROK_TOKEN, 0) }}" + if: "contains(secrets.NGROK_TOKEN, '-')" needs: MacOS env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} From faaa7bfa3ae577161f24718c3f82cc6f80e56d0c Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 23:14:18 +0800 Subject: [PATCH 129/190] check token before run --- .github/workflows/LetsEncrypt.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 818e2d19..92d378c0 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -13,9 +13,23 @@ on: jobs: + CheckToken: + runs-on: ubuntu-latest + outputs: + hasToken: ${{ steps.step_one.outputs.hasToken }} + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + steps: + - name: Set the value + id: step_one + run: [ "$NGROK_TOKEN" ] && echo "::set-output name=hasToken::true" || echo "::set-output name=hasToken::false" + - name: Check the value + run: echo ${{ steps.step_one.outputs.hasToken }} + Ubuntu: runs-on: ubuntu-latest - if: "contains(secrets.NGROK_TOKEN, '-')" + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'true')" env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} TEST_LOCAL: 1 @@ -30,7 +44,6 @@ jobs: MacOS: runs-on: macos-latest - if: "contains(secrets.NGROK_TOKEN, '-')" needs: Ubuntu env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} @@ -46,7 +59,6 @@ jobs: Windows: runs-on: windows-latest - if: "contains(secrets.NGROK_TOKEN, '-')" needs: MacOS env: NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} From 900eedfc2e5f807e19c3981952fbcd3a0e5d7948 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 23:19:21 +0800 Subject: [PATCH 130/190] fix checktoken --- .github/workflows/LetsEncrypt.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 92d378c0..0dff3592 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -22,7 +22,12 @@ jobs: steps: - name: Set the value id: step_one - run: [ "$NGROK_TOKEN" ] && echo "::set-output name=hasToken::true" || echo "::set-output name=hasToken::false" + run: | + if [ "$NGROK_TOKEN" ] ; then + echo "::set-output name=hasToken::true" + else + echo "::set-output name=hasToken::false" + fi - name: Check the value run: echo ${{ steps.step_one.outputs.hasToken }} From 45cf5c4c0f150cb59a6c53680a45604a303f6f5f Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Aug 2020 23:23:07 +0800 Subject: [PATCH 131/190] trigger build --- .github/workflows/LetsEncrypt.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 0dff3592..57948e3a 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -5,6 +5,7 @@ on: - '*' paths: - '**.sh' + - '**.yml' pull_request: branches: - dev From 41754c92c3125feaf7d9a8a8c8c998ebfa2957e3 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 30 Aug 2020 23:26:10 +0800 Subject: [PATCH 132/190] --preserve-env --- .github/workflows/LetsEncrypt.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 57948e3a..afa4da68 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -46,7 +46,7 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh + run: cd ../acmetest && sudo --preserve-env ./letest.sh MacOS: runs-on: macos-latest @@ -61,7 +61,7 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh + run: cd ../acmetest && sudo --preserve-env ./letest.sh Windows: runs-on: windows-latest From 91a8b97cf47a108e0c2f9adda3542424c1e02f4b Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 18:49:39 +0200 Subject: [PATCH 133/190] Added support for custom domains --- dnsapi/dns_dynv6.sh | 66 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 3c222d3a..f1471643 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -13,14 +13,18 @@ dns_dynv6_add() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exist on your dynv6 account" - return 1 + + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -44,14 +48,17 @@ dns_dynv6_rm() { _debug txtvalue "$txtvalue" _get_keyfile _info "using keyfile $dynv6_keyfile" - _get_domain "$fulldomain" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _contains "$_your_hosts" "$_host"; then - _debug "The host is $_host and the record $_record" - _debug "Dynv6 returned $_your_hosts" - _err "The host $_host does not exist on your dynv6 account" - return 1 + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 fi +# if ! _contains "$_your_hosts" "$_host"; then +# _debug "The host is $_host and the record $_record" +# _debug "Dynv6 returned $_your_hosts" +# _err "The host $_host does not exists on your dynv6 account" +# return 1 +# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 @@ -72,29 +79,30 @@ _generate_new_key() { return 1 fi } -#Usage: _acme-challenge.www.example.dynv6.net + +#Usage: _acme-challenge.www.example.dynv6.net "$_your_hosts" +#where _your_hosts is the output of ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts #returns #_host= example.dynv6.net #_record=_acme-challenge.www #aborts if not a valid domain _get_domain() { + #_your_hosts="$(ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts)" _full_domain="$1" - _debug "getting domain for $_full_domain" - if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks'; then - _err "The hosts does not seem to be a dynv6 host" - return 1 - fi - _record="${_full_domain%.*}" - _record="${_record%.*}" - _record="${_record%.*}" - _debug "The record we are ging to use is $_record" - _host="$_full_domain" - while [ "$(echo "$_host" | grep -o '\.' | wc -l)" != "2" ]; do - _host="${_host#*.}" - done - _debug "And the host is $_host" - return 0 + _your_hosts="$2" + _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" + for l in $_your_hosts; do + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi + done + _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" + return 1 } # Usage: No input required @@ -103,7 +111,7 @@ _get_domain() { _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug Your key is "$dynv6_keyfile" + _debug "Your key is $dynv6_keyfile" if [ -z "$dynv6_keyfile" ]; then if [ -z "$KEY" ]; then _err "You did not specify a key to use with dynv6" From a83b16e12ac83ec67374f5d6986d10e8e898b9b1 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 19:09:27 +0200 Subject: [PATCH 134/190] first attempt to make travis happy --- dnsapi/dns_dynv6.sh | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index f1471643..473bb243 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,17 +14,14 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" +<<<<<<< HEAD +======= +>>>>>>> first attempt to make travis happy if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" _debug "Dynv6 returend this after record was added: $returnval" @@ -50,19 +47,12 @@ dns_dynv6_rm() { _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 + _err "Host not found on your account" + return 1 fi -# if ! _contains "$_your_hosts" "$_host"; then -# _debug "The host is $_host and the record $_record" -# _debug "Dynv6 returned $_your_hosts" -# _err "The host $_host does not exists on your dynv6 account" -# return 1 -# fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 - } #################### Private functions below ################################## #Usage: No Input required @@ -93,13 +83,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 From 06e7ebbdebfe6aa442140412cf901bb4b18eaa66 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:42:45 +0200 Subject: [PATCH 135/190] no supporting HTTP API as well --- dnsapi/dns_dynv6.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 473bb243..dce7ce5f 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,10 +14,6 @@ dns_dynv6_add() { _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" -<<<<<<< HEAD - -======= ->>>>>>> first attempt to make travis happy if ! _get_domain "$fulldomain" "$_your_hosts"; then _err "Host not found on your account" return 1 From 9dd50899404b774a351bea75fd8f01deeb85f3ce Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:49:25 +0200 Subject: [PATCH 136/190] formatting --- dnsapi/dns_dynv6.sh | 212 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index dce7ce5f..5f36cef8 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -11,6 +11,7 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" @@ -27,6 +28,30 @@ dns_dynv6_add() { return 0 else _err "Something went wrong! it does not seem like the record was added succesfully" +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_add_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" + _debug "Dynv6 returned this after record was added: $returnval" + if _contains "$returnval" "created"; then + return 0 + elif _contains "$returnval" "updated"; then + return 0 + else + _err "Something went wrong! it does not seem like the record was added successfully" + return 1 + fi +>>>>>>> formatting return 1 fi return 1 @@ -39,12 +64,29 @@ dns_dynv6_rm() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_keyfile _info "using keyfile $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then _err "Host not found on your account" return 1 +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_rm_http + return $? + else + _info "using key file $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" + return 0 +>>>>>>> formatting fi _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" @@ -94,6 +136,7 @@ _get_domain() { # Usage: No input required #returns #dynv6_keyfile path to the key that will be used +<<<<<<< HEAD _get_keyfile() { _debug "get keyfile method called" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" @@ -111,5 +154,174 @@ _get_keyfile() { dynv6_keyfile="$KEY" fi _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" +======= +_get_authentication() { + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else + _debug "no HTTP token found. Looking for an SSH key" + dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" + _debug "Your key is $dynv6_keyfile" + if [ -z "$dynv6_keyfile" ]; then + if [ -z "$KEY" ]; then + _err "You did not specify a key to use with dynv6" + _info "Creating new dynv6 API key to add to dynv6.com" + _generate_new_key + _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" + _info "Hit Enter to continue" + read -r _ + #save the credentials to the account conf file. + else + dynv6_keyfile="$KEY" + fi + _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" + fi + fi +} + +_dns_dynv6_add_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi +} + +_dns_dynv6_rm_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ]; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} + +#get the zoneid for a specifc record or zone +#usage: _get_zone_id §record +#where $record is the record to get the id for +#returns _zone_id the id of the zone +_get_zone_id() { + record="$1" + _debug "getting zone id for $record" + _dynv6_rest GET zones + + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" +} + +_get_zone_name() { + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" + _zone_name="${_zone_name#name:}" +} + +#usaage _get_record_id $zone_id $record +# where zone_id is thevalue returned by _get_zone_id +# and record ist in the form _acme.www for an fqdn of _acme.www.example.com +# returns _record_id +_get_record_id() { + _zone_id="$1" + record="$2" + value="$3" + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response"; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi +} + +_get_record_id_from_response() { + response="$1" + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 +} +#usage: _set_record TXT _acme_challenge.www longvalue 12345678 +#zone id is optional can also be set as vairable bevor calling this method +_set_record() { + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" +} +_del_record() { + _zone_id=$1 + _record_id=$2 + _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" +} + +_dynv6_rest() { + m=$1 #method GET,POST,DELETE or PUT + ep="$2" #the endpoint + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$dynv6_token" | tr -d '"') + + export _H1="Authorization: Bearer $token_trimmed" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" + else + response="$(_get "$dynv6_api/$ep")" +>>>>>>> formatting fi } From 551316bcb6a2a3140972bf7e06bfc84d4ac1f5e8 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 16:01:46 +0200 Subject: [PATCH 137/190] formatting --- dnsapi/dns_dynv6.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 5f36cef8..5ccab1a4 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -156,13 +156,12 @@ _get_keyfile() { _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" ======= _get_authentication() { - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" + dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" + if [ "$dynv6_token" ]; then + _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" + if [ "$DYNV6_TOKEN" ]; then + _saveaccountconf_mutable dynv6_token "$dynv6_token" + fi else _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" From 943d419f98ce81b4896b012ad25e2c2c1b570ae3 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 18:49:39 +0200 Subject: [PATCH 138/190] Added support for custom domains --- dnsapi/dns_dynv6.sh | 70 +++++++-------------------------------------- 1 file changed, 10 insertions(+), 60 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 5ccab1a4..51d2df48 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -11,24 +11,7 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" -<<<<<<< HEAD - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 - fi - _debug "found host on your account" - returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" - _debug "Dynv6 returend this after record was added: $returnval" - if _contains "$returnval" "created"; then - return 0 - elif _contains "$returnval" "updated"; then - return 0 - else - _err "Something went wrong! it does not seem like the record was added succesfully" -======= + _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_add_http @@ -51,7 +34,6 @@ dns_dynv6_add() { _err "Something went wrong! it does not seem like the record was added successfully" return 1 fi ->>>>>>> formatting return 1 fi return 1 @@ -61,17 +43,9 @@ dns_dynv6_add() { dns_dynv6_rm() { fulldomain=$1 txtvalue=$2 - _info "Using dynv6 api" + _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" -<<<<<<< HEAD - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 -======= _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_rm_http @@ -86,11 +60,7 @@ dns_dynv6_rm() { _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 ->>>>>>> formatting fi - _debug "found host on your account" - _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" - return 0 } #################### Private functions below ################################## #Usage: No Input required @@ -121,13 +91,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 @@ -136,25 +106,6 @@ _get_domain() { # Usage: No input required #returns #dynv6_keyfile path to the key that will be used -<<<<<<< HEAD -_get_keyfile() { - _debug "get keyfile method called" - dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" - _debug "Your key is $dynv6_keyfile" - if [ -z "$dynv6_keyfile" ]; then - if [ -z "$KEY" ]; then - _err "You did not specify a key to use with dynv6" - _info "Creating new dynv6 api key to add to dynv6.com" - _generate_new_key - _info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")" - _info "Hit Enter to contiue" - read -r _ - #save the credentials to the account conf file. - else - dynv6_keyfile="$KEY" - fi - _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" -======= _get_authentication() { dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" if [ "$dynv6_token" ]; then @@ -307,7 +258,7 @@ _del_record() { _dynv6_rest() { m=$1 #method GET,POST,DELETE or PUT - ep="$2" #the endpoint + ep="$2" #the endpoint data="$3" _debug "$ep" @@ -321,6 +272,5 @@ _dynv6_rest() { response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" else response="$(_get "$dynv6_api/$ep")" ->>>>>>> formatting fi } From 90e2064d720ec1e3e72790ae78354e98cd637135 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Sun, 31 May 2020 19:09:27 +0200 Subject: [PATCH 139/190] first attempt to make travis happy --- dnsapi/dns_dynv6.sh | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 51d2df48..dbb36255 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -11,11 +11,28 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_add_http return $? +======= + _get_keyfile + _info "using keyfile $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" + _debug "Dynv6 returend this after record was added: $returnval" + if _contains "$returnval" "created"; then + return 0 + elif _contains "$returnval" "updated"; then + return 0 +>>>>>>> first attempt to make travis happy else _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" @@ -46,6 +63,7 @@ dns_dynv6_rm() { _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_rm_http @@ -61,6 +79,18 @@ dns_dynv6_rm() { _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 fi +======= + _get_keyfile + _info "using keyfile $dynv6_keyfile" + _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" + if ! _get_domain "$fulldomain" "$_your_hosts"; then + _err "Host not found on your account" + return 1 + fi + _debug "found host on your account" + _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" + return 0 +>>>>>>> first attempt to make travis happy } #################### Private functions below ################################## #Usage: No Input required @@ -91,13 +121,13 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do - #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" - _host=$l - _debug "The host is $_host and the record $_record" - return 0 - fi + #echo "host: $l" + if test "${_full_domain#*$l}" != "$_full_domain"; then + _record="${_full_domain%.$l}" + _host=$l + _debug "The host is $_host and the record $_record" + return 0 + fi done _err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key" return 1 From 9190ce37011453be1bbf236c359b81a36b5bf8bc Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:42:45 +0200 Subject: [PATCH 140/190] no supporting HTTP API as well --- dnsapi/dns_dynv6.sh | 193 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index dbb36255..9c6d330d 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh #Author StefanAbl #Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"' +#or use the HTTP REST API by by specifying a token 'export DYNV6_TOKEN="value" #if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub + +dynv6_api="https://dynv6.com/api/v2" ######## Public functions ##################### # Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide -#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +#Usage: dns_dynv6_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dynv6_add() { fulldomain=$1 txtvalue=$2 @@ -12,11 +15,15 @@ dns_dynv6_add() { _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> no supporting HTTP API as well _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_add_http return $? +<<<<<<< HEAD ======= _get_keyfile _info "using keyfile $dynv6_keyfile" @@ -34,6 +41,9 @@ dns_dynv6_add() { return 0 >>>>>>> first attempt to make travis happy else +======= + else +>>>>>>> no supporting HTTP API as well _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -63,12 +73,20 @@ dns_dynv6_rm() { _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" +<<<<<<< HEAD <<<<<<< HEAD _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_rm_http return $? else +======= + _get_authentication + if [ "$dynv6_token" ]; then + _dns_dynv6_rm_http + return $? + else +>>>>>>> no supporting HTTP API as well _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -78,6 +96,7 @@ dns_dynv6_rm() { _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 +<<<<<<< HEAD fi ======= _get_keyfile @@ -91,11 +110,14 @@ dns_dynv6_rm() { _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 >>>>>>> first attempt to make travis happy +======= + fi +>>>>>>> no supporting HTTP API as well } #################### Private functions below ################################## #Usage: No Input required #returns -#dynv6_keyfile the path to the new keyfile that has been generated +#dynv6_keyfile the path to the new key file that has been generated _generate_new_key() { dynv6_keyfile="$(eval echo ~"$USER")/.ssh/dynv6" _info "Path to key file used: $dynv6_keyfile" @@ -137,6 +159,7 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { +<<<<<<< HEAD dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" if [ "$dynv6_token" ]; then _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" @@ -144,6 +167,16 @@ _get_authentication() { _saveaccountconf_mutable dynv6_token "$dynv6_token" fi else +======= + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else +>>>>>>> no supporting HTTP API as well _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" _debug "Your key is $dynv6_keyfile" @@ -160,6 +193,7 @@ _get_authentication() { dynv6_keyfile="$KEY" fi _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" +<<<<<<< HEAD fi fi } @@ -302,5 +336,160 @@ _dynv6_rest() { response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" else response="$(_get "$dynv6_api/$ep")" +======= + fi +>>>>>>> no supporting HTTP API as well fi } + + + +_dns_dynv6_add_http(){ +_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain" ;then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi +} + +_dns_dynv6_rm_http(){ + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain" ;then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ] ; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi +} + + +#get the zoneid for a specifc record or zone +#usage: _get_zone_id §record +#where $record is the record to get the id for +#returns _zone_id the id of the zone +_get_zone_id(){ + record="$1" + _debug "getting zone id for $record" + _dynv6_rest GET zones + + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" +} + +_get_zone_name(){ + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n'| tr -d '{'|grep name|tr -d '"')" + _zone_name="${_zone_name#name:}" +} + +#usaage _get_record_id $zone_id $record +# where zone_id is thevalue returned by _get_zone_id +# and record ist in the form _acme.www for an fqdn of _acme.www.example.com +# returns _record_id +_get_record_id(){ + _zone_id="$1" + record="$2" + value="$3" + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response" ; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi +} + +_get_record_id_from_response(){ + response="$1" + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id |tr -d '"'|tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 +} +#usage: _set_record TXT _acme_challenge.www longvalue 12345678 +#zone id is optional can also be set as vairable bevor calling this method +_set_record(){ + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" +} +_del_record(){ + _zone_id=$1 + _record_id=$2 + _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" +} + +_dynv6_rest() { + m=$1 #method GET,POST,DELETE or PUT + ep="$2" #the endpoint + data="$3" + _debug "$ep" + + token_trimmed=$(echo "$dynv6_token" | tr -d '"') + + export _H1="Authorization: Bearer $token_trimmed" + export _H2="Content-Type: application/json" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" + else + response="$(_get "$dynv6_api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} + From 6651801b3f958c8b2a0e2afad67b1b27cc85a46b Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 15:49:25 +0200 Subject: [PATCH 141/190] formatting --- dnsapi/dns_dynv6.sh | 205 ++++++++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 95 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 9c6d330d..4ab278ce 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -24,6 +24,7 @@ dns_dynv6_add() { _dns_dynv6_add_http return $? <<<<<<< HEAD +<<<<<<< HEAD ======= _get_keyfile _info "using keyfile $dynv6_keyfile" @@ -44,6 +45,9 @@ dns_dynv6_add() { ======= else >>>>>>> no supporting HTTP API as well +======= + else +>>>>>>> formatting _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -82,11 +86,15 @@ dns_dynv6_rm() { else ======= _get_authentication - if [ "$dynv6_token" ]; then + if [ "$dynv6_token" ]; then _dns_dynv6_rm_http return $? +<<<<<<< HEAD else >>>>>>> no supporting HTTP API as well +======= + else +>>>>>>> formatting _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -159,6 +167,7 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { +<<<<<<< HEAD <<<<<<< HEAD dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" if [ "$dynv6_token" ]; then @@ -177,6 +186,16 @@ _get_authentication() { dynv6_token="$(_readaccountconf_mutable dynv6_token)" else >>>>>>> no supporting HTTP API as well +======= + if [ "$DYNV6_TOKEN" ]; then + _debug "Going to use the HTTP Token you specifed and saving it for futur use" + _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" + dynv6_token="$DYNV6_TOKEN" + elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then + _debug "Found a previously used HTTP token going to use that" + dynv6_token="$(_readaccountconf_mutable dynv6_token)" + else +>>>>>>> formatting _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" _debug "Your key is $dynv6_keyfile" @@ -342,142 +361,139 @@ _dynv6_rest() { fi } - - -_dns_dynv6_add_http(){ -_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain" ;then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _set_record TXT "$record" "$txtvalue" - if _contains "$response" "$txtvalue"; then - _info "Successfully added record" - return 0 - else - _err "Something went wrong while adding the record" - return 1 - fi +_dns_dynv6_add_http() { + _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _set_record TXT "$record" "$txtvalue" + if _contains "$response" "$txtvalue"; then + _info "Successfully added record" + return 0 + else + _err "Something went wrong while adding the record" + return 1 + fi } -_dns_dynv6_rm_http(){ +_dns_dynv6_rm_http() { _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain" ;then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _get_record_id "$_zone_id" "$record" "$txtvalue" - _del_record "$_zone_id" "$_record_id" - if [ -z "$response" ] ; then - _info "Successfully deleted record" - return 0 - else - _err "Something went wrong while deleting the record" - return 1 - fi + if ! _get_zone_id "$fulldomain"; then + _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" + return 1 + fi + _get_zone_name "$_zone_id" + record="${fulldomain%%.$_zone_name}" + _get_record_id "$_zone_id" "$record" "$txtvalue" + _del_record "$_zone_id" "$_record_id" + if [ -z "$response" ]; then + _info "Successfully deleted record" + return 0 + else + _err "Something went wrong while deleting the record" + return 1 + fi } - #get the zoneid for a specifc record or zone #usage: _get_zone_id §record #where $record is the record to get the id for #returns _zone_id the id of the zone -_get_zone_id(){ +_get_zone_id() { record="$1" _debug "getting zone id for $record" _dynv6_rest GET zones - - zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" - #echo $zones - - selected="" - for z in $zones; do - z="${z#name:}" - _debug zone: "$z" - if _contains "$record" "$z"; then - _debug "$z found in $record" - selected="$z" - fi - done - if [ -z "$selected" ]; then - _err "no zone found" - return 1 - fi - - zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" - _zone_id="${zone_id#id:}" - _debug "zone id: $_zone_id" + + zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" + #echo $zones + + selected="" + for z in $zones; do + z="${z#name:}" + _debug zone: "$z" + if _contains "$record" "$z"; then + _debug "$z found in $record" + selected="$z" + fi + done + if [ -z "$selected" ]; then + _err "no zone found" + return 1 + fi + + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + _zone_id="${zone_id#id:}" + _debug "zone id: $_zone_id" } -_get_zone_name(){ - _zone_id="$1" - _dynv6_rest GET zones/"$_zone_id" - _zone_name="$(echo "$response" | tr ',' '\n'| tr -d '{'|grep name|tr -d '"')" - _zone_name="${_zone_name#name:}" +_get_zone_name() { + _zone_id="$1" + _dynv6_rest GET zones/"$_zone_id" + _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" + _zone_name="${_zone_name#name:}" } #usaage _get_record_id $zone_id $record # where zone_id is thevalue returned by _get_zone_id # and record ist in the form _acme.www for an fqdn of _acme.www.example.com # returns _record_id -_get_record_id(){ +_get_record_id() { _zone_id="$1" record="$2" value="$3" - _dynv6_rest GET "zones/$_zone_id/records" - if ! _get_record_id_from_response "$response" ; then - _err "no such record $record found in zone $_zone_id" - return 1 - fi + _dynv6_rest GET "zones/$_zone_id/records" + if ! _get_record_id_from_response "$response"; then + _err "no such record $record found in zone $_zone_id" + return 1 + fi } -_get_record_id_from_response(){ +_get_record_id_from_response() { response="$1" - _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id |tr -d '"'|tr -d 'id:')" - #_record_id="${_record_id#id:}" - if [ -z "$_record_id" ]; then - _err "no such record: $record found in zone $_zone_id" - return 1 - fi - _debug "record id: $_record_id" - return 0 + _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" + #_record_id="${_record_id#id:}" + if [ -z "$_record_id" ]; then + _err "no such record: $record found in zone $_zone_id" + return 1 + fi + _debug "record id: $_record_id" + return 0 } #usage: _set_record TXT _acme_challenge.www longvalue 12345678 #zone id is optional can also be set as vairable bevor calling this method -_set_record(){ - type="$1" - record="$2" - value="$3" - if [ "$4" ]; then - _zone_id="$4" - fi - data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" - #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' - echo "$data" - #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" - _dynv6_rest POST "zones/$_zone_id/records" "$data" +_set_record() { + type="$1" + record="$2" + value="$3" + if [ "$4" ]; then + _zone_id="$4" + fi + data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" + #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' + echo "$data" + #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" + _dynv6_rest POST "zones/$_zone_id/records" "$data" } -_del_record(){ +_del_record() { _zone_id=$1 _record_id=$2 _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" } _dynv6_rest() { - m=$1 #method GET,POST,DELETE or PUT + m=$1 #method GET,POST,DELETE or PUT ep="$2" #the endpoint data="$3" _debug "$ep" token_trimmed=$(echo "$dynv6_token" | tr -d '"') - + export _H1="Authorization: Bearer $token_trimmed" export _H2="Content-Type: application/json" - + if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" @@ -492,4 +508,3 @@ _dynv6_rest() { _debug2 response "$response" return 0 } - From 8728389c881f83f72bb6f473093c055fc1cb91e1 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Mon, 13 Jul 2020 16:01:46 +0200 Subject: [PATCH 142/190] formatting --- dnsapi/dns_dynv6.sh | 225 -------------------------------------------- 1 file changed, 225 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 4ab278ce..e51e118a 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -14,40 +14,11 @@ dns_dynv6_add() { _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" -<<<<<<< HEAD -<<<<<<< HEAD - -======= ->>>>>>> no supporting HTTP API as well _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_add_http return $? -<<<<<<< HEAD -<<<<<<< HEAD -======= - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 - fi - _debug "found host on your account" - returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")" - _debug "Dynv6 returend this after record was added: $returnval" - if _contains "$returnval" "created"; then - return 0 - elif _contains "$returnval" "updated"; then - return 0 ->>>>>>> first attempt to make travis happy else -======= - else ->>>>>>> no supporting HTTP API as well -======= - else ->>>>>>> formatting _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -77,24 +48,11 @@ dns_dynv6_rm() { _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" -<<<<<<< HEAD -<<<<<<< HEAD - _get_authentication - if [ "$dynv6_token" ]; then - _dns_dynv6_rm_http - return $? - else -======= _get_authentication if [ "$dynv6_token" ]; then _dns_dynv6_rm_http return $? -<<<<<<< HEAD - else ->>>>>>> no supporting HTTP API as well -======= else ->>>>>>> formatting _info "using key file $dynv6_keyfile" _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" if ! _get_domain "$fulldomain" "$_your_hosts"; then @@ -104,23 +62,7 @@ dns_dynv6_rm() { _debug "found host on your account" _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" return 0 -<<<<<<< HEAD - fi -======= - _get_keyfile - _info "using keyfile $dynv6_keyfile" - _your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)" - if ! _get_domain "$fulldomain" "$_your_hosts"; then - _err "Host not found on your account" - return 1 - fi - _debug "found host on your account" - _info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)" - return 0 ->>>>>>> first attempt to make travis happy -======= fi ->>>>>>> no supporting HTTP API as well } #################### Private functions below ################################## #Usage: No Input required @@ -167,8 +109,6 @@ _get_domain() { #returns #dynv6_keyfile path to the key that will be used _get_authentication() { -<<<<<<< HEAD -<<<<<<< HEAD dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}" if [ "$dynv6_token" ]; then _debug "Found HTTP Token. Going to use the HTTP API and not the SSH API" @@ -176,26 +116,6 @@ _get_authentication() { _saveaccountconf_mutable dynv6_token "$dynv6_token" fi else -======= - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" - else ->>>>>>> no supporting HTTP API as well -======= - if [ "$DYNV6_TOKEN" ]; then - _debug "Going to use the HTTP Token you specifed and saving it for futur use" - _saveaccountconf_mutable dynv6_token "$DYNV6_TOKEN" - dynv6_token="$DYNV6_TOKEN" - elif [ "$(_readaccountconf_mutable dynv6_token)" ]; then - _debug "Found a previously used HTTP token going to use that" - dynv6_token="$(_readaccountconf_mutable dynv6_token)" - else ->>>>>>> formatting _debug "no HTTP token found. Looking for an SSH key" dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}" _debug "Your key is $dynv6_keyfile" @@ -212,152 +132,7 @@ _get_authentication() { dynv6_keyfile="$KEY" fi _saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile" -<<<<<<< HEAD - fi - fi -} - -_dns_dynv6_add_http() { - _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain"; then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _set_record TXT "$record" "$txtvalue" - if _contains "$response" "$txtvalue"; then - _info "Successfully added record" - return 0 - else - _err "Something went wrong while adding the record" - return 1 - fi -} - -_dns_dynv6_rm_http() { - _debug "Got HTTP token form _get_authentication method. Going to use the HTTP API" - if ! _get_zone_id "$fulldomain"; then - _err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone" - return 1 - fi - _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" - _get_record_id "$_zone_id" "$record" "$txtvalue" - _del_record "$_zone_id" "$_record_id" - if [ -z "$response" ]; then - _info "Successfully deleted record" - return 0 - else - _err "Something went wrong while deleting the record" - return 1 - fi -} - -#get the zoneid for a specifc record or zone -#usage: _get_zone_id §record -#where $record is the record to get the id for -#returns _zone_id the id of the zone -_get_zone_id() { - record="$1" - _debug "getting zone id for $record" - _dynv6_rest GET zones - - zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')" - #echo $zones - - selected="" - for z in $zones; do - z="${z#name:}" - _debug zone: "$z" - if _contains "$record" "$z"; then - _debug "$z found in $record" - selected="$z" - fi - done - if [ -z "$selected" ]; then - _err "no zone found" - return 1 - fi - - zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" - _zone_id="${zone_id#id:}" - _debug "zone id: $_zone_id" -} - -_get_zone_name() { - _zone_id="$1" - _dynv6_rest GET zones/"$_zone_id" - _zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')" - _zone_name="${_zone_name#name:}" -} - -#usaage _get_record_id $zone_id $record -# where zone_id is thevalue returned by _get_zone_id -# and record ist in the form _acme.www for an fqdn of _acme.www.example.com -# returns _record_id -_get_record_id() { - _zone_id="$1" - record="$2" - value="$3" - _dynv6_rest GET "zones/$_zone_id/records" - if ! _get_record_id_from_response "$response"; then - _err "no such record $record found in zone $_zone_id" - return 1 - fi -} - -_get_record_id_from_response() { - response="$1" - _record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')" - #_record_id="${_record_id#id:}" - if [ -z "$_record_id" ]; then - _err "no such record: $record found in zone $_zone_id" - return 1 - fi - _debug "record id: $_record_id" - return 0 -} -#usage: _set_record TXT _acme_challenge.www longvalue 12345678 -#zone id is optional can also be set as vairable bevor calling this method -_set_record() { - type="$1" - record="$2" - value="$3" - if [ "$4" ]; then - _zone_id="$4" - fi - data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}" - #data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}' - echo "$data" - #"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}" - _dynv6_rest POST "zones/$_zone_id/records" "$data" -} -_del_record() { - _zone_id=$1 - _record_id=$2 - _dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id" -} - -_dynv6_rest() { - m=$1 #method GET,POST,DELETE or PUT - ep="$2" #the endpoint - data="$3" - _debug "$ep" - - token_trimmed=$(echo "$dynv6_token" | tr -d '"') - - export _H1="Authorization: Bearer $token_trimmed" - export _H2="Content-Type: application/json" - - if [ "$m" != "GET" ]; then - _debug data "$data" - response="$(_post "$data" "$dynv6_api/$ep" "" "$m")" - else - response="$(_get "$dynv6_api/$ep")" -======= fi ->>>>>>> no supporting HTTP API as well fi } From 4242354c036d42547eb5309d0892f0d055e6d2f4 Mon Sep 17 00:00:00 2001 From: StefanAbl Date: Fri, 28 Aug 2020 19:46:45 +0200 Subject: [PATCH 143/190] fix shfmt error --- dnsapi/dns_dynv6.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index e51e118a..9efc9aeb 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -260,7 +260,7 @@ _del_record() { _dynv6_rest() { m=$1 #method GET,POST,DELETE or PUT - ep="$2" #the endpoint + ep="$2" #the endpoint data="$3" _debug "$ep" From d73438a3979b303d19b3669bf3d73bbef22eb8dd Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Sep 2020 21:30:56 +0800 Subject: [PATCH 144/190] update comments --- .github/workflows/LetsEncrypt.yml | 5 ++++- acme.sh | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index afa4da68..5994fd9b 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -72,6 +72,9 @@ jobs: #The 80 port is used by Windows server, we have to use a custom port, ngrok will also use this port. Le_HTTPPort: 8888 steps: + - name: Set git to use LF + run: | + git config --global core.autocrlf false - uses: actions/checkout@v2 - name: Install cygwin base packages with chocolatey run: | @@ -87,7 +90,7 @@ jobs: echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' - name: Clone acmetest shell: cmd - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ && sed -i 's/\r//g' acmetest/acme.sh/acme.sh + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest shell: cmd run: cd ../acmetest && bash.exe -c ./letest.sh diff --git a/acme.sh b/acme.sh index c36ce80e..4c9fa96e 100755 --- a/acme.sh +++ b/acme.sh @@ -4978,7 +4978,7 @@ $_authorizations_map" fi } -#in_out_cert out_fullchain out out_ca +#in_out_cert out_fullchain out_ca _split_cert_chain() { _certf="$1" _fullchainf="$2" From d25b2890becb69edd2661d63074db0f6b450ab65 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Sep 2020 21:34:44 +0800 Subject: [PATCH 145/190] split shellcheck --- .github/workflows/LetsEncrypt.yml | 2 +- .github/workflows/shellcheck.yml | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 5994fd9b..16e42902 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -73,7 +73,7 @@ jobs: Le_HTTPPort: 8888 steps: - name: Set git to use LF - run: | + run: | git config --global core.autocrlf false - uses: actions/checkout@v2 - name: Install cygwin base packages with chocolatey diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 402492ad..099b9f7d 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -12,7 +12,7 @@ on: - '**.sh' jobs: - formatCheck: + ShellCheck: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -20,6 +20,11 @@ jobs: run: sudo apt-get install -y shellcheck - name: DoShellcheck run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" + + shfmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 - name: Install shfmt run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt - name: shfmt From 1f5b6a6a35c25785cf4681462138630c00ba9b03 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 1 Sep 2020 21:39:44 +0800 Subject: [PATCH 146/190] fix filter to *.yml --- .github/workflows/LetsEncrypt.yml | 1 + .github/workflows/PebbleStrict.yml | 2 ++ .github/workflows/shellcheck.yml | 2 ++ 3 files changed, 5 insertions(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 16e42902..9a0175b5 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -11,6 +11,7 @@ on: - dev paths: - '**.sh' + - '**.yml' jobs: diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index ffc2ccdc..976e5373 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -5,11 +5,13 @@ on: - '*' paths: - '**.sh' + - '**.yml' pull_request: branches: - dev paths: - '**.sh' + - '**.yml' jobs: PebbleStrict: diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 099b9f7d..b22a2fd8 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -5,11 +5,13 @@ on: - '*' paths: - '**.sh' + - '**.yml' pull_request: branches: - dev paths: - '**.sh' + - '**.yml' jobs: ShellCheck: From 0c9c1ae673812c14aa4e8ac83831b31961ab9ade Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 2 Sep 2020 18:22:39 +0800 Subject: [PATCH 147/190] fix https://github.com/acmesh-official/acme.sh/issues/3140 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 4c9fa96e..40621515 100755 --- a/acme.sh +++ b/acme.sh @@ -4714,7 +4714,7 @@ $_authorizations_map" return 1 fi if [ -z "$Le_LinkOrder" ]; then - Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d ":" -f 2-)" + Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n \t" | cut -d ":" -f 2-)" fi _savedomainconf "Le_LinkOrder" "$Le_LinkOrder" From b5c382f929afc9dd7e4fcc3055079909e066d7be Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Thu, 3 Sep 2020 21:45:26 +0800 Subject: [PATCH 148/190] fix misaka.io api: breaking changes introduced by apiv1 --- dnsapi/dns_misaka.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_misaka.sh b/dnsapi/dns_misaka.sh index eed4170e..36ba5cfd 100755 --- a/dnsapi/dns_misaka.sh +++ b/dnsapi/dns_misaka.sh @@ -47,7 +47,7 @@ dns_misaka_add() { if [ "$count" = "0" ]; then _info "Adding record" - if _misaka_rest PUT "zones/${_domain}/recordsets/${_sub_domain}/TXT" "{\"records\":[{\"value\":\"\\\"$txtvalue\\\"\"}],\"filters\":[],\"ttl\":1}"; then + if _misaka_rest POST "zones/${_domain}/recordsets/${_sub_domain}/TXT" "{\"records\":[{\"value\":\"\\\"$txtvalue\\\"\"}],\"filters\":[],\"ttl\":1}"; then _debug response "$response" if _contains "$response" "$_sub_domain"; then _info "Added" @@ -61,7 +61,7 @@ dns_misaka_add() { else _info "Updating record" - _misaka_rest POST "zones/${_domain}/recordsets/${_sub_domain}/TXT?append=true" "{\"records\": [{\"value\": \"\\\"$txtvalue\\\"\"}],\"ttl\":1}" + _misaka_rest PUT "zones/${_domain}/recordsets/${_sub_domain}/TXT?append=true" "{\"records\": [{\"value\": \"\\\"$txtvalue\\\"\"}],\"ttl\":1}" if [ "$?" = "0" ] && _contains "$response" "$_sub_domain"; then _info "Updated!" #todo: check if the record takes effect From 2c7d2230b3c2f07127ef3ac4584e75b5f6d8a5b2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 4 Sep 2020 18:25:00 +0800 Subject: [PATCH 149/190] minor --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 40621515..3be3849d 100755 --- a/acme.sh +++ b/acme.sh @@ -956,9 +956,9 @@ _dbase64() { _checkcert() { _cf="$1" if [ "$DEBUG" ]; then - openssl x509 -noout -text -in "$_cf" + ${ACME_OPENSSL_BIN:-openssl} x509 -noout -text -in "$_cf" else - openssl x509 -noout -text -in "$_cf" >/dev/null 2>&1 + ${ACME_OPENSSL_BIN:-openssl} x509 -noout -text -in "$_cf" >/dev/null 2>&1 fi } @@ -3994,7 +3994,7 @@ _check_dns_entries() { _get_cert_issuers() { _cfile="$1" if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7"; then - ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | openssl pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 + ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 else ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 fi From 1e4ea900214e99f5676898948cf89139158a0278 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Sep 2020 11:26:53 +0800 Subject: [PATCH 150/190] add zerossl test --- .github/workflows/ZeroSSL.yml | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/ZeroSSL.yml diff --git a/.github/workflows/ZeroSSL.yml b/.github/workflows/ZeroSSL.yml new file mode 100644 index 00000000..97cb798b --- /dev/null +++ b/.github/workflows/ZeroSSL.yml @@ -0,0 +1,47 @@ +name: ZeroSSL +on: + push: + branches: + - '*' + paths: + - '**.sh' + - '**.yml' + + +jobs: + CheckToken: + runs-on: ubuntu-latest + outputs: + hasToken: ${{ steps.step_one.outputs.hasToken }} + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + steps: + - name: Set the value + id: step_one + run: | + if [ "$NGROK_TOKEN" ] ; then + echo "::set-output name=hasToken::true" + else + echo "::set-output name=hasToken::false" + fi + - name: Check the value + run: echo ${{ steps.step_one.outputs.hasToken }} + + ZeroSSL: + runs-on: ubuntu-latest + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'true')" + env: + ACME_DIRECTORY: https://acme.zerossl.com/v2/DV90 + TEST_LOCAL: 1 + TEST_CA: "ZeroSSL" + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: sudo apt-get install -y socat + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh From 98124de362422b750ad3545eb68b595f4cf5597f Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Sep 2020 11:31:22 +0800 Subject: [PATCH 151/190] add email for zerossl --- .github/workflows/ZeroSSL.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ZeroSSL.yml b/.github/workflows/ZeroSSL.yml index 97cb798b..fd92d0fc 100644 --- a/.github/workflows/ZeroSSL.yml +++ b/.github/workflows/ZeroSSL.yml @@ -36,6 +36,7 @@ jobs: TEST_LOCAL: 1 TEST_CA: "ZeroSSL" NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + ACCOUNT_EMAIL: githubCI@acme.sh steps: - uses: actions/checkout@v2 From f405f4bbc445c49b304dcf37be4bbf52e6b9396f Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Sep 2020 12:22:09 +0800 Subject: [PATCH 152/190] fix zerossl --- .github/workflows/ZeroSSL.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ZeroSSL.yml b/.github/workflows/ZeroSSL.yml index fd92d0fc..e812ca13 100644 --- a/.github/workflows/ZeroSSL.yml +++ b/.github/workflows/ZeroSSL.yml @@ -45,4 +45,4 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && ./letest.sh + run: cd ../acmetest && sudo --preserve-env ./letest.sh From 6f62995c96029f1ef8d06d67bec5c1fd0d93d200 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 6 Sep 2020 12:29:23 +0800 Subject: [PATCH 153/190] remove ZeroSSL test --- .github/workflows/ZeroSSL.yml | 48 ----------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 .github/workflows/ZeroSSL.yml diff --git a/.github/workflows/ZeroSSL.yml b/.github/workflows/ZeroSSL.yml deleted file mode 100644 index e812ca13..00000000 --- a/.github/workflows/ZeroSSL.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: ZeroSSL -on: - push: - branches: - - '*' - paths: - - '**.sh' - - '**.yml' - - -jobs: - CheckToken: - runs-on: ubuntu-latest - outputs: - hasToken: ${{ steps.step_one.outputs.hasToken }} - env: - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} - steps: - - name: Set the value - id: step_one - run: | - if [ "$NGROK_TOKEN" ] ; then - echo "::set-output name=hasToken::true" - else - echo "::set-output name=hasToken::false" - fi - - name: Check the value - run: echo ${{ steps.step_one.outputs.hasToken }} - - ZeroSSL: - runs-on: ubuntu-latest - needs: CheckToken - if: "contains(needs.CheckToken.outputs.hasToken, 'true')" - env: - ACME_DIRECTORY: https://acme.zerossl.com/v2/DV90 - TEST_LOCAL: 1 - TEST_CA: "ZeroSSL" - NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} - ACCOUNT_EMAIL: githubCI@acme.sh - - steps: - - uses: actions/checkout@v2 - - name: Install tools - run: sudo apt-get install -y socat - - name: Clone acmetest - run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - name: Run acmetest - run: cd ../acmetest && sudo --preserve-env ./letest.sh From fabd26f85b40d0a6c9163c587672a5417c3075e5 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 8 Sep 2020 22:44:43 +0800 Subject: [PATCH 154/190] check token first --- .github/workflows/dockerhub.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index cf65f4a6..92308218 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -8,8 +8,28 @@ on: - '*' jobs: + CheckToken: + runs-on: ubuntu-latest + outputs: + hasToken: ${{ steps.step_one.outputs.hasToken }} + env: + DOCKER_PASSWORD : ${{ secrets.DOCKER_PASSWORD }} + steps: + - name: Set the value + id: step_one + run: | + if [ "$DOCKER_PASSWORD" ] ; then + echo "::set-output name=hasToken::true" + else + echo "::set-output name=hasToken::false" + fi + - name: Check the value + run: echo ${{ steps.step_one.outputs.hasToken }} + build: runs-on: ubuntu-latest + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'true')" steps: - name: checkout code uses: actions/checkout@v2 From c8ee9e64478b0ef5b0cc02402c8406e0051ff974 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 11 Sep 2020 23:11:26 +0800 Subject: [PATCH 155/190] add dns api check --- .github/workflows/DNS.yml | 132 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 .github/workflows/DNS.yml diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml new file mode 100644 index 00000000..eb6600f4 --- /dev/null +++ b/.github/workflows/DNS.yml @@ -0,0 +1,132 @@ +name: DNS +on: + push: + branches: + - 'dev' + paths: + - 'dnsapi/*.sh' + - '.github/workflows/DNS.yml' + pull_request: + branches: + - 'dev' + paths: + - 'dnsapi/*.sh' + - '.github/workflows/DNS.yml' + + +jobs: + CheckToken: + runs-on: ubuntu-latest + outputs: + hasToken: ${{ steps.step_one.outputs.hasToken }} + env: + ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + steps: + - name: Set the value + id: step_one + run: | + if [ "$${{ secrets.TokenName1 }}" ] ; then + echo "::set-output name=hasToken::true" + else + echo "::set-output name=hasToken::false" + fi + - name: Check the value + run: echo ${{ steps.step_one.outputs.hasToken }} + + Fail: + runs-on: ubuntu-latest + needs: CheckToken + if: "${{needs.CheckToken.outputs.hasToken}} == 'false'" + steps: + - name: Show help page + run: | + echo "Plese see this page to fix the error: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" + - name: Fail + if: "github.actor != 'Neilpang'" + run: false + + Docker: + runs-on: ubuntu-latest + needs: CheckToken + if: "contains(needs.CheckToken.outputs.hasToken, 'true')" + env: + ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Set env file + run: cd ../acmetest && echo "${{ secrets.TokenName1 }}" >> env.list && echo "${{ secrets.TokenName2 }}" >> env.list && echo "TEST_DNS_NO_WILDCARD" >> env.list && echo "TEST_DNS_SLEEP" >> env.list + - name: Run acmetest + run: cd ../acmetest && ./rundocker.sh _cron + + MacOS: + runs-on: macos-latest + needs: Docker + env: + ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Install tools + run: brew update && brew install socat; + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + run: cd ../acmetest && ./letest.sh + + Windows: + runs-on: windows-latest + needs: MacOS + env: + ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - name: Set git to use LF + run: | + git config --global core.autocrlf false + - uses: actions/checkout@v2 + - name: Install cygwin base packages with chocolatey + run: | + choco config get cacheLocation + choco install --no-progress cygwin + shell: cmd + - name: Install cygwin additional packages + run: | + C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git + shell: cmd + - name: Set ENV + run: | + echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin' + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - name: Run acmetest + shell: cmd + run: cd ../acmetest && bash.exe -c ./letest.sh + + From e7a6c17260731cf659c55cad9378d2187d846f2e Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 11 Sep 2020 23:35:27 +0800 Subject: [PATCH 156/190] fix dns check --- .github/workflows/DNS.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index eb6600f4..0f60ace2 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -20,12 +20,12 @@ jobs: outputs: hasToken: ${{ steps.step_one.outputs.hasToken }} env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} + _ACME_CHECK_TOKEN_${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} steps: - name: Set the value id: step_one run: | - if [ "$${{ secrets.TokenName1 }}" ] ; then + if [ "$_ACME_CHECK_TOKEN_${{ secrets.TokenName1}}" ] ; then echo "::set-output name=hasToken::true" else echo "::set-output name=hasToken::false" @@ -36,9 +36,9 @@ jobs: Fail: runs-on: ubuntu-latest needs: CheckToken - if: "${{needs.CheckToken.outputs.hasToken}} == 'false'" + if: "contains(needs.CheckToken.outputs.hasToken, 'false')" steps: - - name: Show help page + - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" run: | echo "Plese see this page to fix the error: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" - name: Fail From b561666d803fadf8e226400d7115e92d8c43f1f6 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 12 Sep 2020 08:47:46 +0800 Subject: [PATCH 157/190] fix https://github.com/acmesh-official/acme.sh/issues/3159 --- dnsapi/dns_ovh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index dda47dda..f6f9689a 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -248,7 +248,7 @@ _ovh_authentication() { # _domain=domain.com _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From b147195189bc258d9fcf7b623f0154c8009c2741 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 12 Sep 2020 14:22:18 +0800 Subject: [PATCH 158/190] use testall target --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 0f60ace2..0274afcf 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -67,7 +67,7 @@ jobs: - name: Set env file run: cd ../acmetest && echo "${{ secrets.TokenName1 }}" >> env.list && echo "${{ secrets.TokenName2 }}" >> env.list && echo "TEST_DNS_NO_WILDCARD" >> env.list && echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest - run: cd ../acmetest && ./rundocker.sh _cron + run: cd ../acmetest && ./rundocker.sh testall MacOS: runs-on: macos-latest From 490a7d4a78b6b9282cf5769aa7cad44b54952c28 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Sep 2020 00:16:04 +0800 Subject: [PATCH 159/190] support more dns tokens --- .github/workflows/DNS.yml | 71 ++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 0274afcf..ae71d594 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -19,13 +19,11 @@ jobs: runs-on: ubuntu-latest outputs: hasToken: ${{ steps.step_one.outputs.hasToken }} - env: - _ACME_CHECK_TOKEN_${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} steps: - name: Set the value id: step_one run: | - if [ "$_ACME_CHECK_TOKEN_${{ secrets.TokenName1}}" ] ; then + if [ "${{secrets.TokenName1}}" ] ; then echo "::set-output name=hasToken::true" else echo "::set-output name=hasToken::false" @@ -50,11 +48,8 @@ jobs: needs: CheckToken if: "contains(needs.CheckToken.outputs.hasToken, 'true')" env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} - ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi @@ -65,7 +60,25 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Set env file - run: cd ../acmetest && echo "${{ secrets.TokenName1 }}" >> env.list && echo "${{ secrets.TokenName2 }}" >> env.list && echo "TEST_DNS_NO_WILDCARD" >> env.list && echo "TEST_DNS_SLEEP" >> env.list + run: | + cd ../acmetest + if [ "${{ secrets.TokenName1}}" ] ; then + echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> env.list + fi + if [ "${{ secrets.TokenName2}}" ] ; then + echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> env.list + fi + if [ "${{ secrets.TokenName3}}" ] ; then + echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> env.list + fi + if [ "${{ secrets.TokenName4}}" ] ; then + echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> env.list + fi + if [ "${{ secrets.TokenName5}}" ] ; then + echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list + fi + echo "TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall @@ -73,11 +86,8 @@ jobs: runs-on: macos-latest needs: Docker env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} - ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi @@ -90,17 +100,31 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - run: cd ../acmetest && ./letest.sh + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh Windows: runs-on: windows-latest needs: MacOS env: - ${{ secrets.TokenName1 }} : ${{ secrets.TokenValue1 }} - ${{ secrets.TokenName2 }} : ${{ secrets.TokenValue2 }} TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} - TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} CASE: le_test_dnsapi @@ -127,6 +151,23 @@ jobs: run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest shell: cmd - run: cd ../acmetest && bash.exe -c ./letest.sh + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + set ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + set ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + set ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + set ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + set ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + bash.exe -c ./letest.sh From b74a501fac2a8503e8d14a06d0ba6d966355ff56 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Sep 2020 21:51:21 +0800 Subject: [PATCH 160/190] fix for Windows --- .github/workflows/DNS.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index ae71d594..5591b8f1 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -150,24 +150,24 @@ jobs: - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest - shell: cmd + shell: bash run: | if [ "${{ secrets.TokenName1}}" ] ; then - set ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} fi if [ "${{ secrets.TokenName2}}" ] ; then - set ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} fi if [ "${{ secrets.TokenName3}}" ] ; then - set ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} fi if [ "${{ secrets.TokenName4}}" ] ; then - set ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} fi if [ "${{ secrets.TokenName5}}" ] ; then - set ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} fi cd ../acmetest - bash.exe -c ./letest.sh + ./letest.sh From 5e3aa2db1d6af012d574cc5c71ee5a247b0c54e9 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Sep 2020 22:22:36 +0800 Subject: [PATCH 161/190] add debug info for duckdns --- dnsapi/dns_duckdns.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 11b685c0..7c2ecfb2 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -112,6 +112,9 @@ _duckdns_rest() { param="$2" _debug param "$param" url="$DuckDNS_API?$param" + if [ "$DEBUG" -gt 0 ]; then + url="$url&verbose=true" + fi _debug url "$url" # DuckDNS uses GET to update domain info From db24ca3dc19e246c7952ea5b8120dff14fc3acca Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 14 Sep 2020 22:29:23 +0800 Subject: [PATCH 162/190] fix debug info --- dnsapi/dns_duckdns.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index 7c2ecfb2..f0af2741 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -120,11 +120,13 @@ _duckdns_rest() { # DuckDNS uses GET to update domain info if [ "$method" = "GET" ]; then response="$(_get "$url")" + _debug2 response "$response" + if [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then + response="OK" + fi else _err "Unsupported method" return 1 fi - - _debug2 response "$response" return 0 } From 60fe987a5f8d43a6c67d048b79839200d7de5cf1 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 21 Sep 2020 19:57:10 +0800 Subject: [PATCH 163/190] enable for any branches. --- .github/workflows/DNS.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 5591b8f1..3ad9506b 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -1,8 +1,6 @@ name: DNS on: push: - branches: - - 'dev' paths: - 'dnsapi/*.sh' - '.github/workflows/DNS.yml' From 8694e0ad19f3320ab677cc72678a220d5b112b73 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Sep 2020 21:37:51 +0800 Subject: [PATCH 164/190] add freebsd --- .github/workflows/LetsEncrypt.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 9a0175b5..69ff35ff 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -96,4 +96,20 @@ jobs: shell: cmd run: cd ../acmetest && bash.exe -c ./letest.sh + FreeBSD: + runs-on: macos-latest + needs: Windows + env: + NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }} + TEST_LOCAL: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/freebsd@main + with: + envs: 'NGROK_TOKEN TEST_LOCAL' + prepare: pkg install -y socat + run: | + cd ../acmetest && ./letest.sh From 9073c4554f93dc0e934f206555e1b9b45fd59763 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Sep 2020 22:18:38 +0800 Subject: [PATCH 165/190] add curl to freebsd --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 69ff35ff..4a8d4336 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -109,7 +109,7 @@ jobs: - uses: vmactions/freebsd@main with: envs: 'NGROK_TOKEN TEST_LOCAL' - prepare: pkg install -y socat + prepare: pkg install -y socat curl run: | cd ../acmetest && ./letest.sh From 07979a13fb2d30c967111d93211ddbaa986171ca Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Sep 2020 22:57:26 +0800 Subject: [PATCH 166/190] add FreeBSD --- .github/workflows/DNS.yml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 3ad9506b..fd9a98b3 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -168,4 +168,42 @@ jobs: cd ../acmetest ./letest.sh + FreeBSD: + runs-on: macos-latest + needs: Windows + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: 1 + steps: + - uses: actions/checkout@v2 + - name: Clone acmetest + run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/freebsd@main + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + prepare: pkg install -y socat curl + run: | + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + fi + cd ../acmetest + ./letest.sh + From be7b87cda32fb022d903e5c049ac02cf1a71d444 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 28 Sep 2020 21:50:20 +0800 Subject: [PATCH 167/190] fix message --- .github/workflows/DNS.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index fd9a98b3..191ae8c9 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -36,10 +36,10 @@ jobs: steps: - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" run: | - echo "Plese see this page to fix the error: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" - - name: Fail - if: "github.actor != 'Neilpang'" - run: false + echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" + if [ "${{github.actor}}" != "Neilpang" ]; then + false + fi Docker: runs-on: ubuntu-latest From 238efb02c6c743a24142f724f0cee0223b66e033 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 16:17:16 +0800 Subject: [PATCH 168/190] update freebsd-vm --- .github/workflows/DNS.yml | 2 +- .github/workflows/LetsEncrypt.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 191ae8c9..1c0165c0 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,7 +183,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd@main + - uses: vmactions/freebsd-vm@v0.0.4 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 4a8d4336..ba5e933d 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,7 +106,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd@main + - uses: vmactions/freebsd-vm@v0.0.4 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl From c9ff536e245e17765a95bd06f41676536268cc23 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 16:20:27 +0800 Subject: [PATCH 169/190] minor --- .github/workflows/DNS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 1c0165c0..976aff56 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -206,4 +206,5 @@ jobs: cd ../acmetest ./letest.sh + From a017fbadd3b4debd2d605e35de883f5f39215b57 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 17:11:04 +0800 Subject: [PATCH 170/190] update badge --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 953c44a5..6fb88daf 100644 --- a/README.md +++ b/README.md @@ -57,26 +57,26 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) | NO | Status| Platform| |----|-------|---------| -|1|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu -|2|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian -|3|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS -|4|[![](https://acmesh-official.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included) -|5|[![](https://acmesh-official.github.io/acmetest/status/freebsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|FreeBSD -|6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense -|7|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE -|8|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl) -|9|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux -|10|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora -|11|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux -|12|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux -|13|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) -|14|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|15|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD -|16|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia -|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) -|18|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris -|19|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux -|20|[![Build Status](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX +|1|[![MacOS](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX +|2|[![Windows](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included) +|3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD +|4|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense +|5|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD +|6|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris +|7|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu +|8|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian +|9|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS +|10|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE +|11|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl) +|12|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux +|13|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora +|14|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux +|15|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux +|16|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) +|17|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 +|18|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia +|19|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) +|20|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux |21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest): From 4db7f6f59c64dcd3045365ef83629ea09b68337a Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Oct 2020 17:17:31 +0800 Subject: [PATCH 171/190] update badge --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6fb88daf..7215785c 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |1|[![MacOS](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX |2|[![Windows](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included) |3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD -|4|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense -|5|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD -|6|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris -|7|[![](https://acmesh-official.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu +|4|[![Ubuntu](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)| Ubuntu +|5|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense +|6|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD +|7|[![](https://acmesh-official.github.io/acmetest/status/solaris.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris |8|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian |9|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS |10|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE From 784b914e0741099feb1ccd22d2f09a91f09a0ded Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 9 Oct 2020 22:33:21 +0800 Subject: [PATCH 172/190] update freebsd --- .github/workflows/DNS.yml | 3 ++- .github/workflows/LetsEncrypt.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 976aff56..b06db229 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,10 +183,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl + usesh: true run: | if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index ba5e933d..d71f3ac1 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,10 +106,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl + usesh: true run: | cd ../acmetest && ./letest.sh From 05141b4f527d8aaacf75b9762e82affa1acac07c Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Mon, 21 Sep 2020 14:17:23 +0200 Subject: [PATCH 173/190] Added dnsapi/dns_infomaniak.sh --- dnsapi/dns_infomaniak.sh | 199 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100755 dnsapi/dns_infomaniak.sh diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh new file mode 100755 index 00000000..e2328a36 --- /dev/null +++ b/dnsapi/dns_infomaniak.sh @@ -0,0 +1,199 @@ +#!/usr/bin/env sh + +############################################################################### +# Infomaniak API integration +# +# To use this API you need visit the API dashboard of your account +# once logged into https://manager.infomaniak.com add /api/dashboard to the URL +# +# Please report bugs to +# https://github.com/acmesh-official/acme.sh/issues/3188 +# +# Note: the URL looks like this: +# https://manager.infomaniak.com/v3//api/dashboard +# Then generate a token with the scope Domain +# this is given as an environment variable INFOMANIAK_API_TOKEN +############################################################################### + +# base variables + +DEFAULT_INFOMANIAK_API_URL="https://api.infomaniak.com" +DEFAULT_INFOMANIAK_TTL=300 + +######## Public functions ##################### + +#Usage: dns_infomaniak_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_infomaniak_add() { + + INFOMANIAK_API_TOKEN="${INFOMANIAK_API_TOKEN:-$(_readaccountconf_mutable INFOMANIAK_API_TOKEN)}" + INFOMANIAK_API_URL="${INFOMANIAK_API_URL:-$(_readaccountconf_mutable INFOMANIAK_API_URL)}" + INFOMANIAK_TTL="${INFOMANIAK_TTL:-$(_readaccountconf_mutable INFOMANIAK_TTL)}" + + if [ -z "$INFOMANIAK_API_TOKEN" ]; then + INFOMANIAK_API_TOKEN="" + _err "Please provide a valid Infomaniak API token in variable INFOMANIAK_API_TOKEN" + return 1 + fi + + if [ -z "$INFOMANIAK_API_URL" ]; then + INFOMANIAK_API_URL="$DEFAULT_INFOMANIAK_API_URL" + fi + + if [ -z "$INFOMANIAK_TTL" ]; then + INFOMANIAK_TTL="$DEFAULT_INFOMANIAK_TTL" + fi + + #save the token to the account conf file. + _saveaccountconf_mutable INFOMANIAK_API_TOKEN "$INFOMANIAK_API_TOKEN" + + if [ "$INFOMANIAK_API_URL" != "$DEFAULT_INFOMANIAK_API_URL" ]; then + _saveaccountconf_mutable INFOMANIAK_API_URL "$INFOMANIAK_API_URL" + fi + + if [ "$INFOMANIAK_TTL" != "$DEFAULT_INFOMANIAK_TTL" ]; then + _saveaccountconf_mutable INFOMANIAK_TTL "$INFOMANIAK_TTL" + fi + + export _H1="Authorization: Bearer $INFOMANIAK_API_TOKEN" + export _H2="Content-Type: application/json" + + fulldomain="$1" + txtvalue="$2" + + _info "Infomaniak DNS API" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + fqdn=${fulldomain#_acme-challenge.} + + # guess which base domain to add record to + zone_and_id=$(_find_zone "$fqdn") + if [ -z "$zone_and_id" ]; then + _err "cannot find zone to modify" + return 1 + fi + zone=${zone_and_id% *} + domain_id=${zone_and_id#* } + + # extract first part of domain + key=${fulldomain%.$zone} + + _debug "zone:$zone id:$domain_id key:$key" + + # payload + data="{\"type\": \"TXT\", \"source\": \"$key\", \"target\": \"$txtvalue\", \"ttl\": $INFOMANIAK_TTL}" + + # API call + response=$(_post "$data" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record") + if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + _info "Record added" + _debug "Response: $response" + return 0 + fi + _err "could not create record" + _debug "Response: $response" + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_infomaniak_rm() { + + INFOMANIAK_API_TOKEN="${INFOMANIAK_API_TOKEN:-$(_readaccountconf_mutable INFOMANIAK_API_TOKEN)}" + INFOMANIAK_API_URL="${INFOMANIAK_API_URL:-$(_readaccountconf_mutable INFOMANIAK_API_URL)}" + INFOMANIAK_TTL="${INFOMANIAK_TTL:-$(_readaccountconf_mutable INFOMANIAK_TTL)}" + + if [ -z "$INFOMANIAK_API_TOKEN" ]; then + INFOMANIAK_API_TOKEN="" + _err "Please provide a valid Infomaniak API token in variable INFOMANIAK_API_TOKEN" + return 1 + fi + + if [ -z "$INFOMANIAK_API_URL" ]; then + INFOMANIAK_API_URL="$DEFAULT_INFOMANIAK_API_URL" + fi + + if [ -z "$INFOMANIAK_TTL" ]; then + INFOMANIAK_TTL="$DEFAULT_INFOMANIAK_TTL" + fi + + #save the token to the account conf file. + _saveaccountconf_mutable INFOMANIAK_API_TOKEN "$INFOMANIAK_API_TOKEN" + + if [ "$INFOMANIAK_API_URL" != "$DEFAULT_INFOMANIAK_API_URL" ]; then + _saveaccountconf_mutable INFOMANIAK_API_URL "$INFOMANIAK_API_URL" + fi + + if [ "$INFOMANIAK_TTL" != "$DEFAULT_INFOMANIAK_TTL" ]; then + _saveaccountconf_mutable INFOMANIAK_TTL "$INFOMANIAK_TTL" + fi + + export _H1="Authorization: Bearer $INFOMANIAK_API_TOKEN" + export _H2="ContentType: application/json" + + fulldomain=$1 + txtvalue=$2 + _info "Infomaniak DNS API" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + fqdn=${fulldomain#_acme-challenge.} + + # guess which base domain to add record to + zone_and_id=$(_find_zone "$fqdn") + if [ -z "$zone_and_id" ]; then + _err "cannot find zone to modify" + return 1 + fi + zone=${zone_and_id% *} + domain_id=${zone_and_id#* } + + # extract first part of domain + key=${fulldomain%.$zone} + + _debug "zone:$zone id:$domain_id key:$key" + + # find previous record + # shellcheck disable=SC1004 + record_id=$(_get "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record" | sed 's/.*"data":\[\(.*\)\]}/\1/; s/},{/}\ +{/g' | sed -n 's/.*"id":"*\([0-9]*\)"*.*"source_idn":"'"$fulldomain"'".*"target_idn":"'"$txtvalue"'".*/\1/p') + if [ -z "$record_id" ]; then + _err "could not find record to delete" + return 1 + fi + _debug "record_id: $record_id" + + # API call + response=$(_post "" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record/$record_id" "" DELETE) + if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + _info "Record deleted" + return 0 + fi + _err "could not delete record" + return 1 +} + +#################### Private functions below ################################## + +_get_domain_id() { + domain="$1" + + # shellcheck disable=SC1004 + _get "${INFOMANIAK_API_URL}/1/product?service_name=domain&customer_name=$domain" | sed 's/.*"data":\[{\(.*\)}\]}/\1/; s/,/\ +/g' | sed -n 's/^"id":\(.*\)/\1/p' +} + +_find_zone() { + zone="$1" + + # find domain in list, removing . parts sequentialy + while echo "$zone" | grep -q '\.'; do + _debug "testing $zone" + id=$(_get_domain_id "$zone") + if [ -n "$id" ]; then + echo "$zone $id" + return + fi + zone=${zone#*.} + done +} From 472dbd641ca9e545523ab059fc8316885906b482 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Fri, 2 Oct 2020 12:47:33 +0200 Subject: [PATCH 174/190] dnsapi/dns_infomaniak.sh: Replace grep by _contains --- dnsapi/dns_infomaniak.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh index e2328a36..765cf39d 100755 --- a/dnsapi/dns_infomaniak.sh +++ b/dnsapi/dns_infomaniak.sh @@ -85,7 +85,7 @@ dns_infomaniak_add() { # API call response=$(_post "$data" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record") - if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + if [ -n "$response" ] && echo "$response" | _contains '"result":"success"'; then _info "Record added" _debug "Response: $response" return 0 @@ -165,7 +165,7 @@ dns_infomaniak_rm() { # API call response=$(_post "" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record/$record_id" "" DELETE) - if [ -n "$response" ] && echo "$response" | grep -qF '"result":"success"'; then + if [ -n "$response" ] && echo "$response" | _contains '"result":"success"'; then _info "Record deleted" return 0 fi @@ -187,7 +187,7 @@ _find_zone() { zone="$1" # find domain in list, removing . parts sequentialy - while echo "$zone" | grep -q '\.'; do + while _contains "$zone" '\.'; do _debug "testing $zone" id=$(_get_domain_id "$zone") if [ -n "$id" ]; then From f864416e39753b66f26d8d3fa19cbb094493731a Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Thu, 8 Oct 2020 23:42:05 +0200 Subject: [PATCH 175/190] Fix DNS workflow use variables TEST_DNS_SLEEP and TEST_DNS_NO_WILDCARD --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index b06db229..1909cb03 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -75,8 +75,8 @@ jobs: if [ "${{ secrets.TokenName5}}" ] ; then echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list fi - echo "TEST_DNS_NO_WILDCARD" >> env.list - echo "TEST_DNS_SLEEP" >> env.list + echo "TEST_DNS_NO_WILDCARD=$TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_SLEEP=$TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall From e05dc99006f5548c20f5caec8b1a89a23ed492a0 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Sat, 10 Oct 2020 18:20:26 +0200 Subject: [PATCH 176/190] Revert "Fix DNS workflow use variables TEST_DNS_SLEEP and TEST_DNS_NO_WILDCARD" This reverts commit f864416e39753b66f26d8d3fa19cbb094493731a. --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 1909cb03..b06db229 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -75,8 +75,8 @@ jobs: if [ "${{ secrets.TokenName5}}" ] ; then echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list fi - echo "TEST_DNS_NO_WILDCARD=$TEST_DNS_NO_WILDCARD" >> env.list - echo "TEST_DNS_SLEEP=$TEST_DNS_SLEEP" >> env.list + echo "TEST_DNS_NO_WILDCARD" >> env.list + echo "TEST_DNS_SLEEP" >> env.list - name: Run acmetest run: cd ../acmetest && ./rundocker.sh testall From 6bc00fc5e51c9cfa9319e4e44265b52d059230e2 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 16 Oct 2020 18:47:02 +0800 Subject: [PATCH 177/190] Update DNS.yml --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index b06db229..25d92137 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,7 +183,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.5 + - uses: vmactions/freebsd-vm@v0.0.7 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl From 348bae53fe04ce0723adba6921ea74292cd9af7a Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 16 Oct 2020 18:47:27 +0800 Subject: [PATCH 178/190] Update LetsEncrypt.yml --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index d71f3ac1..39e91161 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,7 +106,7 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.5 + - uses: vmactions/freebsd-vm@v0.0.7 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl From 5dbfc2786d9a5eb6018dadbd4d834b58fef21087 Mon Sep 17 00:00:00 2001 From: Adrian Fedoreanu Date: Mon, 19 Oct 2020 20:45:52 +0200 Subject: [PATCH 179/190] fix dnsapi/dns_1984hosting --- dnsapi/dns_1984hosting.sh | 84 +++++++++++++++------------------------ 1 file changed, 33 insertions(+), 51 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index bcb675ab..d720c1c5 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -40,8 +40,35 @@ dns_1984hosting_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _1984hosting_add_txt_record "$_domain" "$_sub_domain" "$txtvalue" - return $? + _debug "Add TXT record $fulldomain with value '$txtvalue'" + value="$(printf '%s' "$txtvalue" | _url_encode)" + url="https://management.1984hosting.com/domains/entry/" + + postdata="entry=new" + postdata="$postdata&type=TXT" + postdata="$postdata&ttl=3600" + postdata="$postdata&zone=$_domain" + postdata="$postdata&host=$_sub_domain" + postdata="$postdata&rdata=%22$value%22" + _debug2 postdata "$postdata" + + _authpost "$postdata" "$url" + response="$(echo "$_response" | _normalizeJson)" + _debug2 response "$response" + + if _contains "$response" '"haserrors": true'; then + _err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post" + return 1 + elif _contains "$response" ""; then + _err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file" + return 1 + elif _contains "$response" '"auth": false'; then + _err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie" + return 1 + fi + + _info "Added acme challenge TXT record for $fulldomain at 1984Hosting" + return 0 } #Usage: fulldomain txtvalue @@ -67,57 +94,10 @@ dns_1984hosting_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _1984hosting_delete_txt_record "$_domain" "$_sub_domain" - return $? -} - -#################### Private functions below ################################## - -# usage _1984hosting_add_txt_record domain subdomain value -# returns 0 success -_1984hosting_add_txt_record() { - _debug "Add TXT record $1 with value '$3'" - domain="$1" - subdomain="$2" - value="$(printf '%s' "$3" | _url_encode)" - url="https://management.1984hosting.com/domains/entry/" - - postdata="entry=new" - postdata="$postdata&type=TXT" - postdata="$postdata&ttl=3600" - postdata="$postdata&zone=$domain" - postdata="$postdata&host=$subdomain" - postdata="$postdata&rdata=%22$value%22" - _debug2 postdata "$postdata" - - _authpost "$postdata" "$url" - response="$(echo "$_response" | _normalizeJson)" - _debug2 response "$response" - - if _contains "$response" '"haserrors": true'; then - _err "1984Hosting failed to add TXT record for $subdomain bad RC from _post" - return 1 - elif _contains "$response" ""; then - _err "1984Hosting failed to add TXT record for $subdomain. Check $HTTP_HEADER file" - return 1 - elif _contains "$response" '"auth": false'; then - _err "1984Hosting failed to add TXT record for $subdomain. Invalid or expired cookie" - return 1 - fi - - _info "Added acme challenge TXT record for $fulldomain at 1984Hosting" - return 0 -} - -# usage _1984hosting_delete_txt_record entry_id -# returns 0 success -_1984hosting_delete_txt_record() { _debug "Delete $fulldomain TXT record" - domain="$1" - subdomain="$2" url="https://management.1984hosting.com/domains" - _htmlget "$url" "$domain" + _htmlget "$url" "$_domain" _debug2 _response "$_response" zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')" _debug2 zone_id "$zone_id" @@ -126,7 +106,7 @@ _1984hosting_delete_txt_record() { return 1 fi - _htmlget "$url/$zone_id" "$subdomain" + _htmlget "$url/$zone_id" "$_sub_domain" _debug2 _response "$_response" entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" _debug2 entry_id "$entry_id" @@ -148,6 +128,8 @@ _1984hosting_delete_txt_record() { return 0 } +#################### Private functions below ################################## + # usage: _1984hosting_login username password # returns 0 success _1984hosting_login() { From 23eccb2f20f4c2f3d5350d268fb94226b34712d7 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 21 Oct 2020 15:00:33 +0800 Subject: [PATCH 180/190] Update LetsEncrypt.yml --- .github/workflows/LetsEncrypt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index 39e91161..5f0bba72 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -58,7 +58,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install tools - run: brew update && brew install socat; + run: brew install socat - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest From 5fd0e5add2b29c6e05b482c3c49bf82b9a905e22 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 21 Oct 2020 15:07:25 +0800 Subject: [PATCH 181/190] Update DNS.yml --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 25d92137..b7153506 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -94,7 +94,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install tools - run: brew update && brew install socat; + run: brew install socat - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Run acmetest From 7cc30c268b6c1f79be55fa3a8d31ec50892a4a78 Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 11:14:44 +0100 Subject: [PATCH 182/190] Script to use with Anexia CloudDNS --- dnsapi/dns_anx.sh | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 dnsapi/dns_anx.sh diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh new file mode 100644 index 00000000..9865adc2 --- /dev/null +++ b/dnsapi/dns_anx.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env sh + +#ANX_Token="xxxx" + +ANX_API='https://engine.anexia-it.com/api/clouddns/v1' + +######## Public functions ##################### + +dns_anx_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Using ANX CDNS API" + + ANX_Token="${ANX_Token:-$(_readaccountconf_mutable ANX_Token)}" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + if [ "$ANX_Token" ]; then + _saveaccountconf_mutable ANX_Token "$ANX_Token" + else + _err "You didn't specify a ANEXIA Engine API token." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + # Always add records, wildcard need two records with the same name + _anx_rest POST "zone.json/${_domain}/records" "{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"rdata\":\"$txtvalue\"}" + if _contains "$response" "$txtvalue"; then + return 0 + else + return 1 + fi +} + +dns_anx_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Using ANX CDNS API" + + ANX_Token="${ANX_Token:-$(_readaccountconf_mutable ANX_Token)}" + + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _get_record_id + + if _is_uuid "$_record_id"; then + if ! _anx_rest DELETE "zone.json/${_domain}/records/$_record_id"; then + _err "Delete record" + return 1 + fi + else + _info "No record found." + fi + echo "$response" | tr -d " " | grep \"status\":\"OK\" >/dev/null +} + +#################### Private functions below ################################## + +_is_uuid() { + pattern='^\{?[A-Z0-9a-z]{8}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{12}\}?$' + if echo "$1" | _egrep_o "$pattern" >/dev/null; then + return 0 + fi + return 1 +} + +_get_record_id() { + _debug subdomain "$_sub_domain" + _debug domain "$_domain" + + if _anx_rest GET "zone.json/${_domain}/records?name=$_sub_domain&type=TXT"; then + _debug response "$response" + if _contains "$response" "\"name\":\"$_sub_domain\"" >/dev/null; then + _record_id=$(printf "%s\n" "$response" | _egrep_o "\[.\"identifier\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") + else + _record_id='' + fi + else + _err "Search existing record" + fi +} + +_anx_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + export _H1="Content-Type: application/json" + export _H2="Authorization: Token $ANX_Token" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "${ANX_API}/$ep" "" "$m")" + else + response="$(_get "${ANX_API}/$ep")" + fi + + # shellcheck disable=SC2181 + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug response "$response" + return 0 +} + + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + # Does a zone with that name exist? + _anx_rest GET "zone.json/$h" + # shellcheck disable=SC2154 + if [ "$code" -ne 200 ]; then + continue + fi + + if _contains "$response" "\"name\":\"$h\""; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + + p=$i + i=$(_math "$i" + 1) + done + return 1 +} From fe54d5b8aeef06a7244e08c380af68eaea9884bc Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 12:51:49 +0100 Subject: [PATCH 183/190] fixed spacing in two lines --- dnsapi/dns_anx.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index 9865adc2..66430d3e 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -19,8 +19,8 @@ dns_anx_add() { if [ "$ANX_Token" ]; then _saveaccountconf_mutable ANX_Token "$ANX_Token" else - _err "You didn't specify a ANEXIA Engine API token." - return 1 + _err "You didn't specify a ANEXIA Engine API token." + return 1 fi _debug "First detect the root zone" From bc62d49fc900e2f5b31881e02c432433435ae245 Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 13:04:29 +0100 Subject: [PATCH 184/190] removed empty line to make shfmt happy --- dnsapi/dns_anx.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index 66430d3e..b84fac8c 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -119,7 +119,6 @@ _anx_rest() { return 0 } - #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www From 92bbdce4351028909e83c189dc77ab313b3684d4 Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 13:35:53 +0100 Subject: [PATCH 185/190] changed comment --- dnsapi/dns_anx.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index b84fac8c..027f6820 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -1,5 +1,6 @@ #!/usr/bin/env sh +### Anexia CloudDNS acme.sh hook #ANX_Token="xxxx" ANX_API='https://engine.anexia-it.com/api/clouddns/v1' From 812333e9aef404d3b5e7b5f0cdfa935b20c3895c Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Thu, 29 Oct 2020 14:01:08 +0100 Subject: [PATCH 186/190] Changed comment once more --- dnsapi/dns_anx.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index 027f6820..8c46e405 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -1,6 +1,8 @@ #!/usr/bin/env sh -### Anexia CloudDNS acme.sh hook +# Anexia CloudDNS acme.sh hook +# Author: MA + #ANX_Token="xxxx" ANX_API='https://engine.anexia-it.com/api/clouddns/v1' From d58fb2bbc01f8d2596c5365db9e644d1fc99773a Mon Sep 17 00:00:00 2001 From: ma331 <59875686+ma331@users.noreply.github.com> Date: Fri, 30 Oct 2020 14:13:32 +0100 Subject: [PATCH 187/190] Speedup for _get_root function --- dnsapi/dns_anx.sh | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index 8c46e405..c1a1130a 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -122,15 +122,13 @@ _anx_rest() { return 0 } -#_acme-challenge.www.domain.com -#returns -# _sub_domain=_acme-challenge.www -# _domain=domain.com _get_root() { domain=$1 i=1 p=1 + _anx_rest GET "zone.json" + while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug h "$h" @@ -139,13 +137,6 @@ _get_root() { return 1 fi - # Does a zone with that name exist? - _anx_rest GET "zone.json/$h" - # shellcheck disable=SC2154 - if [ "$code" -ne 200 ]; then - continue - fi - if _contains "$response" "\"name\":\"$h\""; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 9fcd1040650b80e2799e048e7089882f48a804a7 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Mon, 2 Nov 2020 13:35:12 +0300 Subject: [PATCH 188/190] Use _getdeployconf for env vars --- deploy/vault.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/vault.sh b/deploy/vault.sh index c51ceb0f..e742b0fb 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -31,11 +31,13 @@ vault_deploy() { _debug _cfullchain "$_cfullchain" # validate required env vars + _getdeployconf VAULT_PREFIX if [ -z "$VAULT_PREFIX" ]; then _err "VAULT_PREFIX needs to be defined (contains prefix path in vault)" return 1 fi + _getdeployconf VAULT_ADDR if [ -z "$VAULT_ADDR" ]; then _err "VAULT_ADDR needs to be defined (contains vault connection address)" return 1 From e203e9837577cf2b8f976baf19a29a1ed1ef2654 Mon Sep 17 00:00:00 2001 From: Sergey Pashinin Date: Mon, 2 Nov 2020 16:46:09 +0300 Subject: [PATCH 189/190] Use _savedeployconf --- deploy/vault.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/vault.sh b/deploy/vault.sh index e742b0fb..70c80444 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -36,12 +36,14 @@ vault_deploy() { _err "VAULT_PREFIX needs to be defined (contains prefix path in vault)" return 1 fi + _savedeployconf VAULT_PREFIX "$VAULT_PREFIX" _getdeployconf VAULT_ADDR if [ -z "$VAULT_ADDR" ]; then _err "VAULT_ADDR needs to be defined (contains vault connection address)" return 1 fi + _savedeployconf VAULT_ADDR "$VAULT_ADDR" # JSON does not allow multiline strings. # So replacing new-lines with "\n" here From 075dc1e4e95f3668eeee94ad916a3e7142e7282e Mon Sep 17 00:00:00 2001 From: MaxPeal <30347730+MaxPeal@users.noreply.github.com> Date: Thu, 5 Nov 2020 01:25:07 +0100 Subject: [PATCH 190/190] add linux/ppc64le and linux/s390x --- .github/workflows/dockerhub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 92308218..89915af7 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -63,4 +63,4 @@ jobs: --tag ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG} \ --output "type=image,push=true" \ --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ - --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386 . + --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386,linux/ppc64le,linux/s390x .