From 7909273a21434b507d3330a9c34a0687b6799bff Mon Sep 17 00:00:00 2001
From: neilpang <github@neilpang.com>
Date: Tue, 25 May 2021 21:57:15 +0800
Subject: [PATCH 01/10] add debug info

---
 dnsapi/dns_ionos.sh | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh
index aaf8580f..c2c431bb 100755
--- a/dnsapi/dns_ionos.sh
+++ b/dnsapi/dns_ionos.sh
@@ -149,14 +149,15 @@ _ionos_rest() {
     response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")"
   else
     export _H2="Accept: */*"
-
+    export _H3=
     response="$(_get "$IONOS_API$route")"
   fi
 
   if [ "$?" != "0" ]; then
-    _err "Error $route"
+    _err "Error $route: $response"
     return 1
   fi
+  _debug2 "response" "$response"
 
   return 0
 }

From 74a4a788b142d9febe351da61a86636542aba2f9 Mon Sep 17 00:00:00 2001
From: Brian Hartvigsen <brian.andrew@brianandjenny.com>
Date: Wed, 26 May 2021 15:07:23 -0600
Subject: [PATCH 02/10] Make certificate descriptions sed safe

This escapes special characters used in POSIX sed to prevent mismatches.
e.g. `SYNO_Certficiate=*.example.com` would not match a description of
"*.example.com" and would look to match any number of double quotes (the
last character in the sed regex prior to certificate description),
followed by any single character, followed by "example", followed by any
character, followed by "com".

After this change, it will properly match `*.example.com` and not
`""zexamplefcom`.

Additionally we now store the certificate description as base64 encoded
to prevent issues with single quotes.

Tested on DSM 7.0-41222 (VDSM) and DSM 6.2.4-25556 (DS1515+).
---
 deploy/synology_dsm.sh | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh
index d7e8ace8..649a48da 100644
--- a/deploy/synology_dsm.sh
+++ b/deploy/synology_dsm.sh
@@ -66,6 +66,11 @@ synology_dsm_deploy() {
   _getdeployconf SYNO_Certificate
   _debug SYNO_Certificate "${SYNO_Certificate:-}"
 
+  if printf "%s" "$SYNO_Certificate" | grep '\\'; then
+    _err "Do not use a backslash (\) in your certificate description"
+    return 1
+  fi
+
   _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port"
   _debug _base_url "$_base_url"
 
@@ -110,7 +115,9 @@ synology_dsm_deploy() {
   _info "Getting certificates in Synology DSM"
   response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi")
   _debug3 response "$response"
-  id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p")
+  escaped_certificate="$(printf "%s" "$SYNO_Certificate" | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g')"
+  _debug escaped_certificate "$escaped_certificate"
+  id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p")
   _debug2 id "$id"
 
   if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then
@@ -119,7 +126,7 @@ synology_dsm_deploy() {
   fi
 
   # we've verified this certificate description is a thing, so save it
-  _savedeployconf SYNO_Certificate "$SYNO_Certificate"
+  _savedeployconf SYNO_Certificate "$SYNO_Certificate" "base64"
 
   _info "Generate form POST request"
   nl="\0015\0012"
@@ -129,7 +136,7 @@ synology_dsm_deploy() {
   content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\0012"
   content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id"
   content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}"
-  if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then
+  if echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then
     _debug2 default "this is the default certificate"
     content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}true"
   else

From dcb51683c5204feda587c2944baaa50c8bf30632 Mon Sep 17 00:00:00 2001
From: Brian Hartvigsen <brian.andrew@brianandjenny.com>
Date: Wed, 26 May 2021 15:24:50 -0600
Subject: [PATCH 03/10] shellcheck cleanup

shellcheck sees '\\' as trying to escape the trailing quote (see
koalaman/shellcheck#1548 ).
---
 deploy/synology_dsm.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh
index 649a48da..5a70c74e 100644
--- a/deploy/synology_dsm.sh
+++ b/deploy/synology_dsm.sh
@@ -66,6 +66,7 @@ synology_dsm_deploy() {
   _getdeployconf SYNO_Certificate
   _debug SYNO_Certificate "${SYNO_Certificate:-}"
 
+  # shellcheck disable=SC1003 # We are not trying to escape a single quote
   if printf "%s" "$SYNO_Certificate" | grep '\\'; then
     _err "Do not use a backslash (\) in your certificate description"
     return 1

From 7aa4b8247cf2aae0253977206b2d9a739f1bb4db Mon Sep 17 00:00:00 2001
From: neil <win10@neilpang.com>
Date: Sat, 29 May 2021 15:17:11 +0800
Subject: [PATCH 04/10] upgrade cf-tunnel

---
 .github/workflows/LetsEncrypt.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml
index fd79125f..bdc9072e 100644
--- a/.github/workflows/LetsEncrypt.yml
+++ b/.github/workflows/LetsEncrypt.yml
@@ -82,7 +82,7 @@ jobs:
       TEST_LOCAL: 1
     steps:
     - uses: actions/checkout@v2
-    - uses: vmactions/cf-tunnel@v0.0.1
+    - uses: vmactions/cf-tunnel@v0.0.2
       id: tunnel
       with:
         protocol: http
@@ -107,7 +107,7 @@ jobs:
       TEST_LOCAL: 1
     steps:
     - uses: actions/checkout@v2
-    - uses: vmactions/cf-tunnel@v0.0.1
+    - uses: vmactions/cf-tunnel@v0.0.2
       id: tunnel
       with:
         protocol: http

From 1e5e3353f392f0bf9535d04fa55475a3aeb98bf7 Mon Sep 17 00:00:00 2001
From: Roman Zabaluev <github@haarolean.dev>
Date: Sun, 30 May 2021 18:17:39 +0300
Subject: [PATCH 05/10] Fix porkbun issues

See gh-3450
---
 dnsapi/dns_porkbun.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh
index 90caec4a..ad4455b6 100644
--- a/dnsapi/dns_porkbun.sh
+++ b/dnsapi/dns_porkbun.sh
@@ -110,8 +110,8 @@ _get_root() {
 
     if _porkbun_rest POST "dns/retrieve/$h"; then
       if _contains "$response" "\"status\":\"SUCCESS\""; then
-        _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
         _domain=$h
+        _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
         return 0
       else
         _debug "Go to next level of $_domain"

From 3891a52aeb28329dc5f8c8dd3f582489ed49609f Mon Sep 17 00:00:00 2001
From: Christophe B Billheimer <cbillhei@gmu.edu>
Date: Mon, 31 May 2021 15:12:11 -0400
Subject: [PATCH 06/10] change "$url" -> $url so the value of $url gets passed
 by reference, and the string "$url" does not erroneously get passed as a
 variable into _post()

---
 dnsapi/dns_1984hosting.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh
index d720c1c5..d7e558a1 100755
--- a/dnsapi/dns_1984hosting.sh
+++ b/dnsapi/dns_1984hosting.sh
@@ -145,7 +145,7 @@ _1984hosting_login() {
   password=$(printf '%s' "$One984HOSTING_Password" | _url_encode)
   url="https://management.1984hosting.com/accounts/checkuserauth/"
 
-  response="$(_post "username=$username&password=$password&otpkey=" "$url")"
+  response="$(_post "username=$username&password=$password&otpkey=" $url)"
   response="$(echo "$response" | _normalizeJson)"
   _debug2 response "$response"
 

From 5f9daa66408c751e76ba2b66366e3dc3e2e49ac1 Mon Sep 17 00:00:00 2001
From: neil <win10@neilpang.com>
Date: Tue, 1 Jun 2021 21:23:00 +0800
Subject: [PATCH 07/10] check initAPI error

---
 acme.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/acme.sh b/acme.sh
index 02014657..86ed4b43 100755
--- a/acme.sh
+++ b/acme.sh
@@ -4132,7 +4132,9 @@ issue() {
 
   _debug "Using ACME_DIRECTORY: $ACME_DIRECTORY"
 
-  _initAPI
+  if ! _initAPI; then
+    return 1
+  fi
 
   if [ -f "$DOMAIN_CONF" ]; then
     Le_NextRenewTime=$(_readdomainconf Le_NextRenewTime)

From f627a028869491be5f0f18704669b73121849a4b Mon Sep 17 00:00:00 2001
From: neil <win10@neilpang.com>
Date: Tue, 1 Jun 2021 21:24:37 +0800
Subject: [PATCH 08/10] add error message

---
 acme.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/acme.sh b/acme.sh
index 86ed4b43..47eb5a9a 100755
--- a/acme.sh
+++ b/acme.sh
@@ -2538,7 +2538,7 @@ _initAPI() {
     response=$(_get "$_api_server")
     if [ "$?" != "0" ]; then
       _debug2 "response" "$response"
-      _err "Can not init api."
+      _err "Can not init api for: $_api_server."
       return 1
     fi
     response=$(echo "$response" | _json_decode)

From c2273d2c8e274201a7ccc11fd5ee27a0750d60b9 Mon Sep 17 00:00:00 2001
From: neil <win10@neilpang.com>
Date: Tue, 1 Jun 2021 22:15:41 +0800
Subject: [PATCH 09/10] add debug info

---
 dnsapi/dns_1984hosting.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh
index d7e558a1..fee59127 100755
--- a/dnsapi/dns_1984hosting.sh
+++ b/dnsapi/dns_1984hosting.sh
@@ -194,7 +194,7 @@ _check_cookie() {
 # _domain=domain.com
 _get_root() {
   domain="$1"
-  i=2
+  i=1
   p=1
   while true; do
     h=$(printf "%s" "$domain" | cut -d . -f $i-100)
@@ -220,6 +220,7 @@ _get_root() {
 _authget() {
   export _H1="Cookie: $One984HOSTING_COOKIE"
   _response=$(_get "$1")
+  _debug2 _response "$_response"
 }
 
 # truncate huge HTML response

From d154118600bd1cf061a7afd233f2639bffbf4830 Mon Sep 17 00:00:00 2001
From: neil <win10@neilpang.com>
Date: Tue, 1 Jun 2021 22:21:17 +0800
Subject: [PATCH 10/10] fix bug

---
 dnsapi/dns_1984hosting.sh | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh
index fee59127..f371f2c1 100755
--- a/dnsapi/dns_1984hosting.sh
+++ b/dnsapi/dns_1984hosting.sh
@@ -177,7 +177,6 @@ _check_cookie() {
   fi
 
   _authget "https://management.1984hosting.com/accounts/loginstatus/"
-  response="$(echo "$_response" | _normalizeJson)"
   if _contains "$response" '"ok": true'; then
     _debug "Cached cookie still valid"
     return 0
@@ -205,7 +204,7 @@ _get_root() {
     fi
 
     _authget "https://management.1984hosting.com/domains/soacheck/?zone=$h&nameserver=ns0.1984.is."
-    if _contains "$_response" "serial"; then
+    if _contains "$_response" "serial" && ! _contains "$_response" 'null}'; then
       _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
       _domain="$h"
       return 0
@@ -219,7 +218,7 @@ _get_root() {
 # add extra headers to request
 _authget() {
   export _H1="Cookie: $One984HOSTING_COOKIE"
-  _response=$(_get "$1")
+  _response=$(_get "$1" | _normalizeJson)
   _debug2 _response "$_response"
 }