You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
5.3 KiB

  1. #!/usr/bin/env sh
  2. # Here is a script to deploy cert to Synology DSM vault
  3. # (https://www.vaultproject.io/)
  4. #
  5. # it requires the jq and curl are in the $PATH and the following
  6. # environment variables must be set:
  7. #
  8. # SYNO_Username - Synology Username to login (must be an administrator)
  9. # SYNO_Password - Synology Password to login
  10. # SYNO_Certificate - Certificate description to target for replacement
  11. #
  12. # The following environmental variables may be set if you don't like their
  13. # default values:
  14. #
  15. # SYNO_Scheme - defaults to http
  16. # SYNO_Hostname - defaults to localhost
  17. # SYNO_Port - defaults to 5000
  18. #
  19. #returns 0 means success, otherwise error.
  20. ######## Public functions #####################
  21. #domain keyfile certfile cafile fullchain
  22. synology_dsm_deploy() {
  23. _cdomain="$1"
  24. _ckey="$2"
  25. _ccert="$3"
  26. _cca="$4"
  27. _debug _cdomain "$_cdomain"
  28. # Get Username and Password, but don't save until we successfully authenticate
  29. SYNO_Username="${SYNO_Username:-$(_readaccountconf_mutable SYNO_Username)}"
  30. SYNO_Password="${SYNO_Password:-$(_readaccountconf_mutable SYNO_Password)}"
  31. if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then
  32. SYNO_Username=""
  33. SYNO_Password=""
  34. _err "SYNO_Username & SYNO_Password must be set"
  35. return 1
  36. fi
  37. _debug2 SYNO_Username "$SYNO_Username"
  38. _secure_debug2 SYNO_Password "$SYNO_Password"
  39. # Optional scheme, hostname, and port for Synology DSM
  40. SYNO_Scheme="${SYNO_Scheme:-$(_readaccountconf_mutable SYNO_Scheme)}"
  41. SYNO_Hostname="${SYNO_Hostname:-$(_readaccountconf_mutable SYNO_Hostname)}"
  42. SYNO_Port="${SYNO_Port:-$(_readaccountconf_mutable SYNO_Port)}"
  43. _saveaccountconf_mutable SYNO_Scheme "$SYNO_Scheme"
  44. _saveaccountconf_mutable SYNO_Hostname "$SYNO_Hostname"
  45. _saveaccountconf_mutable SYNO_Port "$SYNO_Port"
  46. # default vaules for scheme, hostname, and port
  47. # defaulting to localhost and http because it's localhost...
  48. [ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http"
  49. [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost"
  50. [ -n "${SYNO_Port}" ] || SYNO_Port="5000"
  51. _debug2 SYNO_Scheme "$SYNO_Scheme"
  52. _debug2 SYNO_Hostname "$SYNO_Hostname"
  53. _debug2 SYNO_Port "$SYNO_Port"
  54. # Get the certificate description, but don't save it until we verfiy it's real
  55. _getdeployconf SYNO_Certificate
  56. # shellcheck disable=SC2154
  57. if [ -z "${SYNO_Certificate}" ]; then
  58. _err "SYNO_Certificate needs to be defined (with the Certificate description name)"
  59. return 1
  60. fi
  61. _debug SYNO_Certificate "$SYNO_Certificate"
  62. # We can't use _get or _post because they lack support for cookies
  63. # use jq because I'm too lazy to figure out what is required to parse json
  64. # by hand. Also it seems to be in place for Synology DSM (6.2.1 at least)
  65. for x in curl jq; do
  66. if ! _exists "$x"; then
  67. _err "Please install $x first."
  68. _err "We need $x to work."
  69. return 1
  70. fi
  71. done
  72. _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port"
  73. _debug _base_url "$_base_url"
  74. _cookie_jar="$(_mktemp)"
  75. _debug _cookie_jar "$_cookie_jar"
  76. # Login, get the token from JSON and session id from cookie
  77. _debug "Logging into $SYNO_Hostname:$SYNO_Port"
  78. token=$(curl -sk -c "$_cookie_jar" "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken)
  79. if [ "$token" = "null" ]; then
  80. _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme."
  81. _err "Check your username and password."
  82. rm "$_cookie_jar"
  83. return 1
  84. fi
  85. # Now that we know the username and password are good, save them
  86. _saveaccountconf_mutable SYNO_Username "$SYNO_Username"
  87. _saveaccountconf_mutable SYNO_Password "$SYNO_Password"
  88. _secure_debug2 token "$token"
  89. # Use token and session id to get the list of certificates
  90. 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)
  91. _debug3 response "$response"
  92. # select the first certificate matching our description
  93. cert=$(echo "$response" | jq -r ".data.certificates | map(select(.desc == \"$SYNO_Certificate\"))[0]")
  94. _debug3 cert "$cert"
  95. if [ "$cert" = "null" ]; then
  96. _err "Unable to find certificate: $SYNO_Certificate"
  97. rm "$_cookie_jar"
  98. return 1
  99. fi
  100. # we've verified this certificate description is a thing, so save it
  101. _savedeployconf SYNO_Certificate "$SYNO_Certificate"
  102. id=$(echo "$cert" | jq -r ".id")
  103. default=$(echo "$cert" | jq -r ".is_default")
  104. _debug2 id "$id"
  105. _debug2 default "$default"
  106. # This is the heavy lifting, make the API call to update a certificate in place
  107. 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")
  108. _debug3 response "$response"
  109. success=$(echo "$response" | jq -r ".success")
  110. _debug2 success "$success"
  111. rm "$_cookie_jar"
  112. if [ "$success" = "true" ]; then
  113. restarted=$(echo "$response" | jq -r ".data.restart_httpd")
  114. if [ "$restarted" = "true" ]; then
  115. _info "http services were restarted"
  116. else
  117. _info "http services were NOT restarted"
  118. fi
  119. return 0
  120. else
  121. code=$(echo "$response" | jq -r ".error.code")
  122. _err "Unable to update certificate, error code $code"
  123. return 1
  124. fi
  125. }