From 555e0de9e45f36ddd2507975a0368eaab9141074 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 29 Jun 2019 21:47:24 -0600 Subject: [PATCH 01/13] Initial support for Synology DSM This allows you to update a key on a Synology DSM using the existing API. Handles restarting the necessary services the certificate is attached to and all other internal stuff (copying the certificate around, etc.) This is way less error prone than most articles I've found on how to update a Synology DSM certificate. --- deploy/synology_dsm.sh | 145 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 deploy/synology_dsm.sh diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh new file mode 100644 index 00000000..45eab335 --- /dev/null +++ b/deploy/synology_dsm.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env sh + +# Here is a script to deploy cert to Synology DSM vault +# (https://www.vaultproject.io/) +# +# it requires the jq and curl are in the $PATH and the following +# environment variables must be set: +# +# SYNO_Username - Synology Username to login (must be an administrator) +# SYNO_Password - Synology Password to login +# SYNO_Certificate - Certificate description to target for replacement +# +# The following environmental variables may be set if you don't like their +# default values: +# +# SYNO_Scheme - defaults to http +# SYNO_Hostname - defaults to localhost +# SYNO_Port - defaults to 5000 +# +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +synology_dsm_deploy() { + + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + + _debug _cdomain "$_cdomain" + + # Get Username and Password, but don't save until we successfully authenticate + SYNO_Username="${SYNO_Username:-$(_readaccountconf_mutable SYNO_Username)}" + SYNO_Password="${SYNO_Password:-$(_readaccountconf_mutable SYNO_Password)}" + if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then + SYNO_Username="" + SYNO_Password="" + _err "SYNO_Username & SYNO_Password must be set" + return 1 + fi + _debug2 SYNO_Username "$SYNO_Username" + _secure_debug2 SYNO_Password "$SYNO_Password" + + # Optional scheme, hostname, and port for Synology DSM + SYNO_Scheme="${SYNO_Scheme:-$(_readaccountconf_mutable SYNO_Scheme)}" + SYNO_Hostname="${SYNO_Hostname:-$(_readaccountconf_mutable SYNO_Hostname)}" + SYNO_Port="${SYNO_Port:-$(_readaccountconf_mutable SYNO_Port)}" + _saveaccountconf_mutable SYNO_Scheme "$SYNO_Scheme" + _saveaccountconf_mutable SYNO_Hostname "$SYNO_Hostname" + _saveaccountconf_mutable SYNO_Port "$SYNO_Port" + + # default vaules for scheme, hostname, and port + # defaulting to localhost and http because it's localhost... + [ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http" + [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost" + [ -n "${SYNO_Port}" ] || SYNO_Port="5000" + + _debug2 SYNO_Scheme "$SYNO_Scheme" + _debug2 SYNO_Hostname "$SYNO_Hostname" + _debug2 SYNO_Port "$SYNO_Port" + + # Get the certificate description, but don't save it until we verfiy it's real + _getdeployconf SYNO_Certificate + if [ -z "${SYNO_Certificate}" ]; then + _err "SYNO_Certificate needs to be defined (with the Certificate description name)" + return 1 + fi + _debug SYNO_Certificate "$SYNO_Certificate" + + # We can't use _get or _post because they lack support for cookies + # use jq because I'm too lazy to figure out what is required to parse json + # by hand. Also it seems to be in place for Synology DSM (6.2.1 at least) + for x in curl jq; do + if ! _exists "$x"; then + _err "Please install $x first." + _err "We need $x to work." + return 1 + fi + done + + _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" + _debug _base_url "$_base_url" + + _cookie_jar="$(_mktemp)" + _debug _cookie_jar "$_cookie_jar" + + # Login, get the token from JSON and session id from cookie + _debug "Logging into $SYNO_Hostname:$SYNO_Port" + token=$(curl -sk -c $_cookie_jar "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken) + if [ $token = "null" ]; then + _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." + _err "Check your username and password." + rm "$_cookie_jar" + return 1 + fi + + # Now that we know the username and password are good, save them + _saveaccountconf_mutable SYNO_Username "$SYNO_Username" + _saveaccountconf_mutable SYNO_Password "$SYNO_Password" + _secure_debug2 token "$token" + + # Use token and session id to get the list of certificates + response=$(curl -sk -b $_cookie_jar $_base_url/webapi/entry.cgi -H "X-SYNO-TOKEN: $token" -d api=SYNO.Core.Certificate.CRT -d method=list -d version=1) + _debug3 response "$response" + # select the first certificate matching our description + cert=$(echo "$response" | jq -r ".data.certificates | map(select(.desc == \"$SYNO_Certificate\"))[0]") + _debug3 cert "$cert" + + if [ "$cert" = "null" ]; then + _err "Unable to find certificate: $SYNO_Certificate" + rm "$_cookie_jar" + return 1 + fi + + # we've verified this certificate description is a thing, so save it + _savedeployconf SYNO_Certificate "$SYNO_Certificate" + + id=$(echo $cert | jq -r ".id") + default=$(echo "$cert" | jq -r ".is_default") + _debug2 id "$id" + _debug2 default "$default" + + # This is the heavy lifting, make the API call to update a certificate in place + response=$(curl -sk -b $_cookie_jar "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" -F key=@$_ckey -F cert=@$_ccert -F inter_cert=@$_cca -F id=$id -F desc=$SYNO_Certificate -F as_default=$default) + _debug3 response "$response" + success=$(echo "$response" | jq -r ".success") + _debug2 success "$success" + rm "$_cookie_jar" + + if [ "$success" = "true" ]; then + restarted=$(echo "$response" | jq -r ".data.restart_httpd") + if [ "$restarted" = "true" ]; then + _info "http services were restarted" + else + _info "http services were NOT restarted" + fi + return 0; + else + code=$(echo "$response" | jq -r ".error.code") + _err "Unable to update certificate, error code $code" + return 1 + fi +} From 548f83c3adf4533140980774892cc484937960ac Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 30 Jun 2019 00:13:07 -0600 Subject: [PATCH 02/13] Cleanup shellcheck errors --- deploy/synology_dsm.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 45eab335..d131e9cd 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -63,6 +63,7 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verfiy it's real _getdeployconf SYNO_Certificate + # shellcheck disable=SC2154 if [ -z "${SYNO_Certificate}" ]; then _err "SYNO_Certificate needs to be defined (with the Certificate description name)" return 1 @@ -88,8 +89,8 @@ synology_dsm_deploy() { # Login, get the token from JSON and session id from cookie _debug "Logging into $SYNO_Hostname:$SYNO_Port" - token=$(curl -sk -c $_cookie_jar "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken) - if [ $token = "null" ]; then + token=$(curl -sk -c "$_cookie_jar" "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken) + if [ "$token" = "null" ]; then _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." _err "Check your username and password." rm "$_cookie_jar" @@ -102,7 +103,7 @@ synology_dsm_deploy() { _secure_debug2 token "$token" # Use token and session id to get the list of certificates - response=$(curl -sk -b $_cookie_jar $_base_url/webapi/entry.cgi -H "X-SYNO-TOKEN: $token" -d api=SYNO.Core.Certificate.CRT -d method=list -d version=1) + response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi" -H "X-SYNO-TOKEN: $token" -d api=SYNO.Core.Certificate.CRT -d method=list -d version=1) _debug3 response "$response" # select the first certificate matching our description cert=$(echo "$response" | jq -r ".data.certificates | map(select(.desc == \"$SYNO_Certificate\"))[0]") @@ -117,13 +118,13 @@ synology_dsm_deploy() { # we've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate" - id=$(echo $cert | jq -r ".id") + id=$(echo "$cert" | jq -r ".id") default=$(echo "$cert" | jq -r ".is_default") _debug2 id "$id" _debug2 default "$default" # This is the heavy lifting, make the API call to update a certificate in place - response=$(curl -sk -b $_cookie_jar "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" -F key=@$_ckey -F cert=@$_ccert -F inter_cert=@$_cca -F id=$id -F desc=$SYNO_Certificate -F as_default=$default) + response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" -F "key=@$_ckey" -F "cert=@$_ccert" -F "inter_cert=@$_cca" -F "id=$id" -F "desc=$SYNO_Certificate" -F "as_default=$default") _debug3 response "$response" success=$(echo "$response" | jq -r ".success") _debug2 success "$success" From 6459ccb18517c3f9f6c87410df8d76a0082020e3 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 30 Jun 2019 00:13:45 -0600 Subject: [PATCH 03/13] Cleanup shfmt warnings --- deploy/synology_dsm.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index d131e9cd..7fab47d8 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -74,11 +74,11 @@ synology_dsm_deploy() { # use jq because I'm too lazy to figure out what is required to parse json # by hand. Also it seems to be in place for Synology DSM (6.2.1 at least) for x in curl jq; do - if ! _exists "$x"; then - _err "Please install $x first." - _err "We need $x to work." - return 1 - fi + if ! _exists "$x"; then + _err "Please install $x first." + _err "We need $x to work." + return 1 + fi done _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" @@ -133,11 +133,11 @@ synology_dsm_deploy() { if [ "$success" = "true" ]; then restarted=$(echo "$response" | jq -r ".data.restart_httpd") if [ "$restarted" = "true" ]; then - _info "http services were restarted" + _info "http services were restarted" else - _info "http services were NOT restarted" + _info "http services were NOT restarted" fi - return 0; + return 0 else code=$(echo "$response" | jq -r ".error.code") _err "Unable to update certificate, error code $code" From 8e8cda132c0ab64548122478ab59f6eea7262dba Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 30 Jun 2019 00:30:35 -0600 Subject: [PATCH 04/13] Remove boilerplate from what I used for template --- deploy/synology_dsm.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 7fab47d8..e37d7d44 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -1,7 +1,6 @@ #!/usr/bin/env sh -# Here is a script to deploy cert to Synology DSM vault -# (https://www.vaultproject.io/) +# Here is a script to deploy cert to Synology DSM # # it requires the jq and curl are in the $PATH and the following # environment variables must be set: From b3b00b6700e7bc960d96ddd0f2abf1315cab0e03 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Mon, 30 Sep 2019 14:06:04 -0600 Subject: [PATCH 05/13] Using domainconf instead of account --- deploy/synology_dsm.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index e37d7d44..25b63767 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -31,8 +31,8 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" # Get Username and Password, but don't save until we successfully authenticate - SYNO_Username="${SYNO_Username:-$(_readaccountconf_mutable SYNO_Username)}" - SYNO_Password="${SYNO_Password:-$(_readaccountconf_mutable SYNO_Password)}" + SYNO_Username="${SYNO_Username:-$(_readdomainconf SYNO_Username)}" + SYNO_Password="${SYNO_Password:-$(_readdomainconf SYNO_Password)}" if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" @@ -43,12 +43,12 @@ synology_dsm_deploy() { _secure_debug2 SYNO_Password "$SYNO_Password" # Optional scheme, hostname, and port for Synology DSM - SYNO_Scheme="${SYNO_Scheme:-$(_readaccountconf_mutable SYNO_Scheme)}" - SYNO_Hostname="${SYNO_Hostname:-$(_readaccountconf_mutable SYNO_Hostname)}" - SYNO_Port="${SYNO_Port:-$(_readaccountconf_mutable SYNO_Port)}" - _saveaccountconf_mutable SYNO_Scheme "$SYNO_Scheme" - _saveaccountconf_mutable SYNO_Hostname "$SYNO_Hostname" - _saveaccountconf_mutable SYNO_Port "$SYNO_Port" + SYNO_Scheme="${SYNO_Scheme:-$(_readdomainconf SYNO_Scheme)}" + SYNO_Hostname="${SYNO_Hostname:-$(_readdomainconf SYNO_Hostname)}" + SYNO_Port="${SYNO_Port:-$(_readdomainconf SYNO_Port)}" + _savedomainconf SYNO_Scheme "$SYNO_Scheme" + _savedomainconf SYNO_Hostname "$SYNO_Hostname" + _savedomainconf SYNO_Port "$SYNO_Port" # default vaules for scheme, hostname, and port # defaulting to localhost and http because it's localhost... @@ -97,8 +97,8 @@ synology_dsm_deploy() { fi # Now that we know the username and password are good, save them - _saveaccountconf_mutable SYNO_Username "$SYNO_Username" - _saveaccountconf_mutable SYNO_Password "$SYNO_Password" + _savedomainconf SYNO_Username "$SYNO_Username" + _savedomainconf SYNO_Password "$SYNO_Password" _secure_debug2 token "$token" # Use token and session id to get the list of certificates From 52a168b96160d5c407e54067181bedebe2c9aad9 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sat, 8 Feb 2020 16:27:18 -0800 Subject: [PATCH 06/13] Stop using jq/curl directly This is a lot more fragile then the previous code due to treating JSON as just a string --- deploy/synology_dsm.sh | 105 ++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 25b63767..82645829 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -20,6 +20,12 @@ ######## Public functions ##################### +_syno_get_cookie_data() { + _debug2 Cookie "$1" + _debug3 grep "$(grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' )" + grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' +} + #domain keyfile certfile cafile fullchain synology_dsm_deploy() { @@ -31,8 +37,8 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" # Get Username and Password, but don't save until we successfully authenticate - SYNO_Username="${SYNO_Username:-$(_readdomainconf SYNO_Username)}" - SYNO_Password="${SYNO_Password:-$(_readdomainconf SYNO_Password)}" + SYNO_Username="${SYNO_Username:-$(_getdeployconf SYNO_Username)}" + SYNO_Password="${SYNO_Password:-$(_getdeployconf SYNO_Password)}" if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" @@ -43,12 +49,12 @@ synology_dsm_deploy() { _secure_debug2 SYNO_Password "$SYNO_Password" # Optional scheme, hostname, and port for Synology DSM - SYNO_Scheme="${SYNO_Scheme:-$(_readdomainconf SYNO_Scheme)}" - SYNO_Hostname="${SYNO_Hostname:-$(_readdomainconf SYNO_Hostname)}" - SYNO_Port="${SYNO_Port:-$(_readdomainconf SYNO_Port)}" - _savedomainconf SYNO_Scheme "$SYNO_Scheme" - _savedomainconf SYNO_Hostname "$SYNO_Hostname" - _savedomainconf SYNO_Port "$SYNO_Port" + SYNO_Scheme="${SYNO_Scheme:-$(_getdeployconf SYNO_Scheme)}" + SYNO_Hostname="${SYNO_Hostname:-$(_getdeployconf SYNO_Hostname)}" + SYNO_Port="${SYNO_Port:-$(_getdeployconf SYNO_Port)}" + _savedeployconf SYNO_Scheme "$SYNO_Scheme" + _savedeployconf SYNO_Hostname "$SYNO_Hostname" + _savedeployconf SYNO_Port "$SYNO_Port" # default vaules for scheme, hostname, and port # defaulting to localhost and http because it's localhost... @@ -69,77 +75,78 @@ synology_dsm_deploy() { fi _debug SYNO_Certificate "$SYNO_Certificate" - # We can't use _get or _post because they lack support for cookies - # use jq because I'm too lazy to figure out what is required to parse json - # by hand. Also it seems to be in place for Synology DSM (6.2.1 at least) - for x in curl jq; do - if ! _exists "$x"; then - _err "Please install $x first." - _err "We need $x to work." - return 1 - fi - done - _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" - _cookie_jar="$(_mktemp)" - _debug _cookie_jar "$_cookie_jar" - # Login, get the token from JSON and session id from cookie - _debug "Logging into $SYNO_Hostname:$SYNO_Port" - token=$(curl -sk -c "$_cookie_jar" "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken) - if [ "$token" = "null" ]; then + _info "Logging into $SYNO_Hostname:$SYNO_Port" + response=$(_get "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes") + token=$(echo "$response" | grep "SynoToken" | sed -n 's/.*"SynoToken" *: *"\([^"]*\).*/\1/p') + _debug3 response "$response" + + if [ -z "$token" ]; then _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." _err "Check your username and password." - rm "$_cookie_jar" return 1 fi + _H1="Cookie: $(_syno_get_cookie_data "id"); $(_syno_get_cookie_data "smid")" + _H2="X-SYNO-TOKEN: $token" + export _H1 + export _H2 + _debug3 H1 "${_H1}" + _debug3 H2 "${_H2}" + # Now that we know the username and password are good, save them - _savedomainconf SYNO_Username "$SYNO_Username" - _savedomainconf SYNO_Password "$SYNO_Password" + _savedeployconf SYNO_Username "$SYNO_Username" + _savedeployconf SYNO_Password "$SYNO_Password" _secure_debug2 token "$token" - # Use token and session id to get the list of certificates - response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi" -H "X-SYNO-TOKEN: $token" -d api=SYNO.Core.Certificate.CRT -d method=list -d version=1) + _info "Getting certificates in Synology DSM" + response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1" "$_base_url/webapi/entry.cgi") _debug3 response "$response" - # select the first certificate matching our description - cert=$(echo "$response" | jq -r ".data.certificates | map(select(.desc == \"$SYNO_Certificate\"))[0]") - _debug3 cert "$cert" + id=$(printf "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") + _debug2 id "$id" - if [ "$cert" = "null" ]; then + if [ -z "$id" ]; then _err "Unable to find certificate: $SYNO_Certificate" - rm "$_cookie_jar" return 1 fi # we've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate" - id=$(echo "$cert" | jq -r ".id") - default=$(echo "$cert" | jq -r ".is_default") - _debug2 id "$id" + default=false + if printf "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -q -- 'is_default":true'; then + default=true + fi _debug2 default "$default" - # This is the heavy lifting, make the API call to update a certificate in place - response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" -F "key=@$_ckey" -F "cert=@$_ccert" -F "inter_cert=@$_cca" -F "id=$id" -F "desc=$SYNO_Certificate" -F "as_default=$default") - _debug3 response "$response" - success=$(echo "$response" | jq -r ".success") - _debug2 success "$success" - rm "$_cookie_jar" + _info "Generate form POST request" + nl="\015\012" + delim="--------------------------$(date +%Y%m%d%H%M%S)" + content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\012" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\012" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\012" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}${default}" + content="$content${nl}--$delim--${nl}" + content="$(printf "%b_" "$content")";content="${content%_}" # protect trailing \n - if [ "$success" = "true" ]; then - restarted=$(echo "$response" | jq -r ".data.restart_httpd") - if [ "$restarted" = "true" ]; then + _info "Upload certificate to the Synology DSM" + response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" "" "POST" "multipart/form-data; boundary=${delim}") + _debug3 response "$response" + + if ! printf "$response" | grep -q '"error":'; then + if printf "$response" | grep -q '"restart_httpd":true'; then _info "http services were restarted" else _info "http services were NOT restarted" fi return 0 else - code=$(echo "$response" | jq -r ".error.code") - _err "Unable to update certificate, error code $code" + _err "Unable to update certificate, error code $response" return 1 fi } From 95769de464b6e21a3b31c644febd262738d0f63c Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 02:01:26 -0800 Subject: [PATCH 07/13] Fix shfmt/shellcheck issues --- deploy/synology_dsm.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 82645829..7d713930 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -22,7 +22,7 @@ _syno_get_cookie_data() { _debug2 Cookie "$1" - _debug3 grep "$(grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' )" + _debug3 grep "$(grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';')" grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' } @@ -105,7 +105,7 @@ synology_dsm_deploy() { _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1" "$_base_url/webapi/entry.cgi") _debug3 response "$response" - id=$(printf "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") + id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" if [ -z "$id" ]; then @@ -117,8 +117,8 @@ synology_dsm_deploy() { _savedeployconf SYNO_Certificate "$SYNO_Certificate" default=false - if printf "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -q -- 'is_default":true'; then - default=true + if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -q -- 'is_default":true'; then + default=true fi _debug2 default "$default" @@ -132,14 +132,15 @@ synology_dsm_deploy() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}${default}" content="$content${nl}--$delim--${nl}" - content="$(printf "%b_" "$content")";content="${content%_}" # protect trailing \n + content="$(printf "%b_" "$content")" + content="${content%_}" # protect trailing \n _info "Upload certificate to the Synology DSM" response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" "" "POST" "multipart/form-data; boundary=${delim}") _debug3 response "$response" - if ! printf "$response" | grep -q '"error":'; then - if printf "$response" | grep -q '"restart_httpd":true'; then + if ! echo "$response" | grep -q '"error":'; then + if echo "$response" | grep -q '"restart_httpd":true'; then _info "http services were restarted" else _info "http services were NOT restarted" From de25232a7345d8dfe221d1d1a131419182989ca6 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 02:26:55 -0800 Subject: [PATCH 08/13] Allow creating new certificates when certificate is not found --- deploy/synology_dsm.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 7d713930..71d9e7dc 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -39,6 +39,7 @@ synology_dsm_deploy() { # Get Username and Password, but don't save until we successfully authenticate SYNO_Username="${SYNO_Username:-$(_getdeployconf SYNO_Username)}" SYNO_Password="${SYNO_Password:-$(_getdeployconf SYNO_Password)}" + SYNO_Create="${SYNO_Create:-$(_getdeployconf SYNO_Create)}" if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" @@ -108,8 +109,8 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - if [ -z "$id" ]; then - _err "Unable to find certificate: $SYNO_Certificate" + if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then + _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set" return 1 fi From 5d3bc95ac529550077505189b4e2cc07ca4b5155 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 02:50:29 -0800 Subject: [PATCH 09/13] Fix some debug output --- deploy/synology_dsm.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 71d9e7dc..bb49f279 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -21,8 +21,6 @@ ######## Public functions ##################### _syno_get_cookie_data() { - _debug2 Cookie "$1" - _debug3 grep "$(grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';')" grep "\W$1=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';' } @@ -95,13 +93,13 @@ synology_dsm_deploy() { _H2="X-SYNO-TOKEN: $token" export _H1 export _H2 - _debug3 H1 "${_H1}" - _debug3 H2 "${_H2}" + _debug2 H1 "${_H1}" + _debug2 H2 "${_H2}" # Now that we know the username and password are good, save them _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" - _secure_debug2 token "$token" + _debug token "$token" _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1" "$_base_url/webapi/entry.cgi") From 1259341095f2b15946f0db39ce53f821b194c00f Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 03:10:11 -0800 Subject: [PATCH 10/13] Use deployconf properly --- deploy/synology_dsm.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index bb49f279..13728d66 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -35,9 +35,9 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" # Get Username and Password, but don't save until we successfully authenticate - SYNO_Username="${SYNO_Username:-$(_getdeployconf SYNO_Username)}" - SYNO_Password="${SYNO_Password:-$(_getdeployconf SYNO_Password)}" - SYNO_Create="${SYNO_Create:-$(_getdeployconf SYNO_Create)}" + _getdeployconf SYNO_Username + _getdeployconf SYNO_Password + _getdeployconf SYNO_Create if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" @@ -48,12 +48,9 @@ synology_dsm_deploy() { _secure_debug2 SYNO_Password "$SYNO_Password" # Optional scheme, hostname, and port for Synology DSM - SYNO_Scheme="${SYNO_Scheme:-$(_getdeployconf SYNO_Scheme)}" - SYNO_Hostname="${SYNO_Hostname:-$(_getdeployconf SYNO_Hostname)}" - SYNO_Port="${SYNO_Port:-$(_getdeployconf SYNO_Port)}" - _savedeployconf SYNO_Scheme "$SYNO_Scheme" - _savedeployconf SYNO_Hostname "$SYNO_Hostname" - _savedeployconf SYNO_Port "$SYNO_Port" + _getdeployconf SYNO_Scheme + _getdeployconf SYNO_Hostname + _getdeployconf SYNO_Port # default vaules for scheme, hostname, and port # defaulting to localhost and http because it's localhost... @@ -61,6 +58,10 @@ synology_dsm_deploy() { [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost" [ -n "${SYNO_Port}" ] || SYNO_Port="5000" + _savedeployconf SYNO_Scheme "$SYNO_Scheme" + _savedeployconf SYNO_Hostname "$SYNO_Hostname" + _savedeployconf SYNO_Port "$SYNO_Port" + _debug2 SYNO_Scheme "$SYNO_Scheme" _debug2 SYNO_Hostname "$SYNO_Hostname" _debug2 SYNO_Port "$SYNO_Port" @@ -107,6 +108,7 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" + # shellcheck disable=SC2154 if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set" return 1 From 79637097bada83f251c68159df4baa657f16d7ad Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 11:50:50 -0800 Subject: [PATCH 11/13] Use _utc_date --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 13728d66..dd26e3d8 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -125,7 +125,7 @@ synology_dsm_deploy() { _info "Generate form POST request" nl="\015\012" - delim="--------------------------$(date +%Y%m%d%H%M%S)" + delim="--------------------------$(_utc_date | tr -d -- '-: ')" content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\012" From d07172a52843b8eeb412e85f2cdfc9a527c646c6 Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Sun, 9 Feb 2020 12:06:13 -0800 Subject: [PATCH 12/13] Replace disabled linter with variable substituion --- deploy/synology_dsm.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index dd26e3d8..f1c08c36 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -68,8 +68,7 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verfiy it's real _getdeployconf SYNO_Certificate - # shellcheck disable=SC2154 - if [ -z "${SYNO_Certificate}" ]; then + if [ -z "${SYNO_Certificate:?}" ]; then _err "SYNO_Certificate needs to be defined (with the Certificate description name)" return 1 fi @@ -108,8 +107,7 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - # shellcheck disable=SC2154 - if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then + if [ -z "$id" ] && [ -z "${SYNO_Create:?}" ]; then _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set" return 1 fi From 1b475cf9f3997c27aae49ab578dd7070d9169b3d Mon Sep 17 00:00:00 2001 From: Brian Hartvigsen Date: Mon, 10 Feb 2020 21:02:27 -0700 Subject: [PATCH 13/13] Remove -q from greps --- deploy/synology_dsm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index f1c08c36..0c2b1185 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -116,7 +116,7 @@ synology_dsm_deploy() { _savedeployconf SYNO_Certificate "$SYNO_Certificate" default=false - if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -q -- 'is_default":true'; then + if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then default=true fi _debug2 default "$default" @@ -138,8 +138,8 @@ synology_dsm_deploy() { response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" "" "POST" "multipart/form-data; boundary=${delim}") _debug3 response "$response" - if ! echo "$response" | grep -q '"error":'; then - if echo "$response" | grep -q '"restart_httpd":true'; then + if ! echo "$response" | grep '"error":' >/dev/null; then + if echo "$response" | grep '"restart_httpd":true' >/dev/null; then _info "http services were restarted" else _info "http services were NOT restarted"