From 4635dacf7ff0285f523b7a7b3fc9b54e8f40891a Mon Sep 17 00:00:00 2001 From: Nasser Alansari Date: Sat, 13 Nov 2021 12:56:10 +0300 Subject: [PATCH 1/8] Add SYNO_TOTP_SECRET for user with two-factor authentication --- deploy/synology_dsm.sh | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 177b3fbe..66e28f93 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -2,8 +2,7 @@ # Here is a script to deploy cert to Synology DSM # -# it requires the jq and curl are in the $PATH and the following -# environment variables must be set: +# It requires following environment variables: # # SYNO_Username - Synology Username to login (must be an administrator) # SYNO_Password - Synology Password to login @@ -16,6 +15,12 @@ # SYNO_Hostname - defaults to localhost # SYNO_Port - defaults to 5000 # SYNO_DID - device ID to skip OTP - defaults to empty +# SYNO_TOTP_SECRET - TOTP secret to generate OTP - defaults to empty +# +# Dependencies: +# ------------- +# - jq and curl +# - oathtool (When using 2 Factor Authentication and SYNO_TOTP_SECRET is set) # #returns 0 means success, otherwise error. @@ -36,6 +41,7 @@ synology_dsm_deploy() { _getdeployconf SYNO_Password _getdeployconf SYNO_Create _getdeployconf SYNO_DID + _getdeployconf SYNO_TOTP_SECRET if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then _err "SYNO_Username & SYNO_Password must be set" return 1 @@ -86,13 +92,18 @@ synology_dsm_deploy() { encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" + otp_code="" + if [ -n "$SYNO_TOTP_SECRET" ]; then + otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" + fi + if [ -n "$SYNO_DID" ]; then _H1="Cookie: did=$SYNO_DID" export _H1 _debug3 H1 "${_H1}" fi - response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') _debug3 response "$response" _debug token "$token" @@ -100,7 +111,7 @@ synology_dsm_deploy() { if [ -z "$token" ]; then _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." _err "Check your username and password." - _err "If two-factor authentication is enabled for the user, you have to choose another user." + _err "If two-factor authentication is enabled for the user, set SYNO_TOTP_SECRET." return 1 fi sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p') @@ -113,6 +124,7 @@ synology_dsm_deploy() { _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" _savedeployconf SYNO_DID "$SYNO_DID" + _savedeployconf SYNO_TOTP_SECRET "$SYNO_TOTP_SECRET" _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") From 6aa1ec08020ca9edb9813cb4148d0f467524d46d Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Thu, 6 Jan 2022 16:20:43 +0100 Subject: [PATCH 2/8] deploy/fritzbox: allow hook to be used with multiple fritzboxes Previously the deploy hook config was stored in the account config. This seems odd and adds unnecessary limitations to the hook. Now we're using the correct _*deployconf() functions to read and write the deploy hook config. --- deploy/fritzbox.sh | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/deploy/fritzbox.sh b/deploy/fritzbox.sh index 2ca7ab7d..416a4121 100644 --- a/deploy/fritzbox.sh +++ b/deploy/fritzbox.sh @@ -36,43 +36,51 @@ fritzbox_deploy() { fi fi - _fritzbox_username="${DEPLOY_FRITZBOX_USERNAME}" - _fritzbox_password="${DEPLOY_FRITZBOX_PASSWORD}" - _fritzbox_url="${DEPLOY_FRITZBOX_URL}" + # Clear traces of incorrectly stored values + _clearaccountconf DEPLOY_FRITZBOX_USERNAME + _clearaccountconf DEPLOY_FRITZBOX_PASSWORD + _clearaccountconf DEPLOY_FRITZBOX_URL - _debug _fritzbox_url "$_fritzbox_url" - _debug _fritzbox_username "$_fritzbox_username" - _secure_debug _fritzbox_password "$_fritzbox_password" - if [ -z "$_fritzbox_username" ]; then + # Read config from saved values or env + _getdeployconf DEPLOY_FRITZBOX_USERNAME + _getdeployconf DEPLOY_FRITZBOX_PASSWORD + _getdeployconf DEPLOY_FRITZBOX_URL + + _debug DEPLOY_FRITZBOX_URL "$DEPLOY_FRITZBOX_URL" + _debug DEPLOY_FRITZBOX_USERNAME "$DEPLOY_FRITZBOX_USERNAME" + _secure_debug DEPLOY_FRITZBOX_PASSWORD "$DEPLOY_FRITZBOX_PASSWORD" + + if [ -z "$DEPLOY_FRITZBOX_USERNAME" ]; then _err "FRITZ!Box username is not found, please define DEPLOY_FRITZBOX_USERNAME." return 1 fi - if [ -z "$_fritzbox_password" ]; then + if [ -z "$DEPLOY_FRITZBOX_PASSWORD" ]; then _err "FRITZ!Box password is not found, please define DEPLOY_FRITZBOX_PASSWORD." return 1 fi - if [ -z "$_fritzbox_url" ]; then + if [ -z "$DEPLOY_FRITZBOX_URL" ]; then _err "FRITZ!Box url is not found, please define DEPLOY_FRITZBOX_URL." return 1 fi - _saveaccountconf DEPLOY_FRITZBOX_USERNAME "${_fritzbox_username}" - _saveaccountconf DEPLOY_FRITZBOX_PASSWORD "${_fritzbox_password}" - _saveaccountconf DEPLOY_FRITZBOX_URL "${_fritzbox_url}" + # Save current values + _savedeployconf DEPLOY_FRITZBOX_USERNAME "$DEPLOY_FRITZBOX_USERNAME" + _savedeployconf DEPLOY_FRITZBOX_PASSWORD "$DEPLOY_FRITZBOX_PASSWORD" + _savedeployconf DEPLOY_FRITZBOX_URL "$DEPLOY_FRITZBOX_URL" # Do not check for a valid SSL certificate, because initially the cert is not valid, so it could not install the LE generated certificate export HTTPS_INSECURE=1 _info "Log in to the FRITZ!Box" - _fritzbox_challenge="$(_get "${_fritzbox_url}/login_sid.lua" | sed -e 's/^.*//' -e 's/<\/Challenge>.*$//')" + _fritzbox_challenge="$(_get "${DEPLOY_FRITZBOX_URL}/login_sid.lua" | sed -e 's/^.*//' -e 's/<\/Challenge>.*$//')" if _exists iconv; then - _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | _digest md5 hex)" + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${DEPLOY_FRITZBOX_PASSWORD}" | iconv -f ASCII -t UTF16LE | _digest md5 hex)" elif _exists uconv; then - _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | uconv -f ASCII -t UTF16LE | _digest md5 hex)" + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${DEPLOY_FRITZBOX_PASSWORD}" | uconv -f ASCII -t UTF16LE | _digest md5 hex)" else - _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | _digest md5 hex)" + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${DEPLOY_FRITZBOX_PASSWORD}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | _digest md5 hex)" fi - _fritzbox_sid="$(_get "${_fritzbox_url}/login_sid.lua?sid=0000000000000000&username=${_fritzbox_username}&response=${_fritzbox_challenge}-${_fritzbox_hash}" | sed -e 's/^.*//' -e 's/<\/SID>.*$//')" + _fritzbox_sid="$(_get "${DEPLOY_FRITZBOX_URL}/login_sid.lua?sid=0000000000000000&username=${DEPLOY_FRITZBOX_USERNAME}&response=${_fritzbox_challenge}-${_fritzbox_hash}" | sed -e 's/^.*//' -e 's/<\/SID>.*$//')" if [ -z "${_fritzbox_sid}" ] || [ "${_fritzbox_sid}" = "0000000000000000" ]; then _err "Logging in to the FRITZ!Box failed. Please check username, password and URL." @@ -104,7 +112,7 @@ fritzbox_deploy() { _info "Upload certificate to the FRITZ!Box" export _H1="Content-type: multipart/form-data boundary=${_post_boundary}" - _post "$(cat "${_post_request}")" "${_fritzbox_url}/cgi-bin/firmwarecfg" | grep SSL + _post "$(cat "${_post_request}")" "${DEPLOY_FRITZBOX_URL}/cgi-bin/firmwarecfg" | grep SSL retval=$? if [ $retval = 0 ]; then From 8cdceb83b2422b17ba5c5e6242a46c6cd481c669 Mon Sep 17 00:00:00 2001 From: Jacob Vandborg <16362036+jvandborg@users.noreply.github.com> Date: Thu, 6 Jan 2022 19:21:05 +0100 Subject: [PATCH 3/8] Cannot wait for PR #3673 to be completed PR #3673 Fix simply.com API seems abandoned by maintainer and I need this fixed asap Changes implemented * Normalize JSON and fix not handling return code correctly * Add some information to comments * Fix trailing slash on URIs * Add 60 second sleep for zone to be written * Fix parsing record_data and record_type --- dnsapi/dns_simply.sh | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index e0e05017..2baa4581 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -1,15 +1,15 @@ #!/usr/bin/env sh -# +# API-integration for Simply.com (https://www.simply.com) + #SIMPLY_AccountName="accountname" -# #SIMPLY_ApiKey="apikey" # #SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]" SIMPLY_Api_Default="https://api.simply.com/1" #This is used for determining success of REST call -SIMPLY_SUCCESS_CODE='"status": 200' +SIMPLY_SUCCESS_CODE='"status":200' ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -51,7 +51,7 @@ dns_simply_rm() { _simply_save_config - _debug "First detect the root zone" + _debug "Find the DNS zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -77,8 +77,8 @@ dns_simply_rm() { for record in $records; do _debug record "$record" - record_data=$(echo "$record" | cut -d "," -f 3 | sed 's/"//g' | grep "data" | cut -d ":" -f 2) - record_type=$(echo "$record" | cut -d "," -f 4 | sed 's/"//g' | grep "type" | cut -d ":" -f 2) + record_data=$(echo "$record" | sed -n "s/.*\"data\":\"\([^\"]*\)\".*/\1/p") + record_type=$(echo "$record" | sed -n "s/.*\"type\":\"\([^\"]*\)\".*/\1/p") _debug2 record_data "$record_data" _debug2 record_type "$record_type" @@ -151,7 +151,7 @@ _simply_save_config() { _simply_get_all_records() { domain=$1 - if ! _simply_rest GET "my/products/$domain/dns/records"; then + if ! _simply_rest GET "my/products/$domain/dns/records/"; then return 1 fi @@ -169,7 +169,7 @@ _get_root() { return 1 fi - if ! _simply_rest GET "my/products/$h/dns"; then + if ! _simply_rest GET "my/products/$h/dns/"; then return 1 fi @@ -193,7 +193,7 @@ _simply_add_record() { data="{\"name\": \"$sub_domain\", \"type\":\"TXT\", \"data\": \"$txtval\", \"priority\":0, \"ttl\": 3600}" - if ! _simply_rest POST "my/products/$domain/dns/records" "$data"; then + if ! _simply_rest POST "my/products/$domain/dns/records/" "$data"; then _err "Adding record not successfull!" return 1 fi @@ -203,6 +203,9 @@ _simply_add_record() { _err "$response" return 1 fi + + _info "Waiting 60 seconds for DNS changes to be written" + _sleep 60 return 0 } @@ -214,7 +217,7 @@ _simply_delete_record() { _debug record_id "Delete record with id $record_id" - if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id"; then + if ! _simply_rest DELETE "my/products/$domain/dns/records/$record_id/"; then _err "Deleting record not successfull!" return 1 fi @@ -249,6 +252,8 @@ _simply_rest() { _err "error $ep" return 1 fi + + response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" From 459faf4dfb121154aa0e9a48bac3c07cd3657239 Mon Sep 17 00:00:00 2001 From: jvandborg <16362036+jvandborg@users.noreply.github.com> Date: Thu, 6 Jan 2022 22:03:39 +0100 Subject: [PATCH 4/8] Format to comply with style guide --- dnsapi/dns_simply.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 2baa4581..85819ab8 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -203,7 +203,7 @@ _simply_add_record() { _err "$response" return 1 fi - + _info "Waiting 60 seconds for DNS changes to be written" _sleep 60 @@ -252,7 +252,7 @@ _simply_rest() { _err "error $ep" return 1 fi - + response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" From e23c02575db58790a4e3c96734549afa4aefe40e Mon Sep 17 00:00:00 2001 From: Jacob Vandborg <16362036+jvandborg@users.noreply.github.com> Date: Fri, 7 Jan 2022 08:10:31 +0100 Subject: [PATCH 5/8] Removed DNS sleep Users should use command line parameter --dnssleep instead --- dnsapi/dns_simply.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 85819ab8..437e5e5c 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -204,9 +204,6 @@ _simply_add_record() { return 1 fi - _info "Waiting 60 seconds for DNS changes to be written" - _sleep 60 - return 0 } From 75ae57e1945c7f6883aa8b494a9b0f6a43a79f63 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jan 2022 19:19:51 +0800 Subject: [PATCH 6/8] report false --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 32d97614..46fd8283 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -37,7 +37,7 @@ jobs: - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" run: | echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test" - if [ "${{github.actor}}" != "Neilpang" ]; then + if [ "${{github.repository_owner}}" != "acmesh-official" ]; then false fi From 86c3fa0df030d3b5ac7c1597b19b0b36d9616e1a Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jan 2022 19:51:04 +0800 Subject: [PATCH 7/8] remove retry for get and post --- acme.sh | 72 ++++----------------------------------------------------- 1 file changed, 5 insertions(+), 67 deletions(-) diff --git a/acme.sh b/acme.sh index b536d742..b0a4388b 100755 --- a/acme.sh +++ b/acme.sh @@ -1831,8 +1831,6 @@ _inithttp() { } -_HTTP_MAX_RETRY=8 - # body url [needbase64] [POST|PUT|DELETE] [ContentType] _post() { body="$1" @@ -1840,33 +1838,6 @@ _post() { needbase64="$3" httpmethod="$4" _postContentType="$5" - _sleep_retry_sec=1 - _http_retry_times=0 - _hcode=0 - while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do - [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] - _lastHCode="$?" - _debug "Retrying post" - _post_impl "$body" "$_post_url" "$needbase64" "$httpmethod" "$_postContentType" "$_lastHCode" - _hcode="$?" - _debug _hcode "$_hcode" - if [ "$_hcode" = "0" ]; then - break - fi - _http_retry_times=$(_math $_http_retry_times + 1) - _sleep $_sleep_retry_sec - done - return $_hcode -} - -# body url [needbase64] [POST|PUT|DELETE] [ContentType] [displayError] -_post_impl() { - body="$1" - _post_url="$2" - needbase64="$3" - httpmethod="$4" - _postContentType="$5" - displayError="$6" if [ -z "$httpmethod" ]; then httpmethod="POST" @@ -1918,9 +1889,7 @@ _post_impl() { fi _ret="$?" if [ "$_ret" != "0" ]; then - if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" - fi + _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _err "Here is the curl dump log:" _err "$(cat "$_CURL_DUMP")" @@ -1976,9 +1945,7 @@ _post_impl() { _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." fi if [ "$_ret" != "0" ]; then - if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then - _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" - fi + _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" fi _sed_i "s/^ *//g" "$HTTP_HEADER" else @@ -1992,38 +1959,13 @@ _post_impl() { # url getheader timeout _get() { - url="$1" - onlyheader="$2" - t="$3" - _sleep_retry_sec=1 - _http_retry_times=0 - _hcode=0 - while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do - [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] - _lastHCode="$?" - _debug "Retrying GET" - _get_impl "$url" "$onlyheader" "$t" "$_lastHCode" - _hcode="$?" - _debug _hcode "$_hcode" - if [ "$_hcode" = "0" ]; then - break - fi - _http_retry_times=$(_math $_http_retry_times + 1) - _sleep $_sleep_retry_sec - done - return $_hcode -} - -# url getheader timeout displayError -_get_impl() { _debug GET url="$1" onlyheader="$2" t="$3" - displayError="$4" _debug url "$url" _debug "timeout=$t" - _debug "displayError" "$displayError" + _inithttp if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then @@ -2042,9 +1984,7 @@ _get_impl() { fi ret=$? if [ "$ret" != "0" ]; then - if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then - _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" - fi + _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _err "Here is the curl dump log:" _err "$(cat "$_CURL_DUMP")" @@ -2070,9 +2010,7 @@ _get_impl() { _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." fi if [ "$ret" != "0" ]; then - if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then - _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret" - fi + _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret" fi else ret=$? From e67d26caeb94c54d4daee8b8ce691b77d4861ce3 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jan 2022 19:58:49 +0800 Subject: [PATCH 8/8] fix https://github.com/acmesh-official/acme.sh/issues/3845#issuecomment-999367478 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index b0a4388b..b25619bf 100755 --- a/acme.sh +++ b/acme.sh @@ -1252,7 +1252,7 @@ _createcsr() { else domainlist="$(_idn "$domainlist")" _debug2 domainlist "$domainlist" - alt="$(_getIdType "$domain" | _upper_case):$domain" + alt="$(_getIdType "$domain" | _upper_case):$(_idn "$domain")" for dl in $(echo "$domainlist" | tr "," ' '); do alt="$alt,$(_getIdType "$dl" | _upper_case):$dl" done