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.

145 lines
5.2 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. if [ -z "${SYNO_Certificate}" ]; then
  57. _err "SYNO_Certificate needs to be defined (with the Certificate description name)"
  58. return 1
  59. fi
  60. _debug SYNO_Certificate "$SYNO_Certificate"
  61. # We can't use _get or _post because they lack support for cookies
  62. # use jq because I'm too lazy to figure out what is required to parse json
  63. # by hand. Also it seems to be in place for Synology DSM (6.2.1 at least)
  64. for x in curl jq; do
  65. if ! _exists "$x"; then
  66. _err "Please install $x first."
  67. _err "We need $x to work."
  68. return 1
  69. fi
  70. done
  71. _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port"
  72. _debug _base_url "$_base_url"
  73. _cookie_jar="$(_mktemp)"
  74. _debug _cookie_jar "$_cookie_jar"
  75. # Login, get the token from JSON and session id from cookie
  76. _debug "Logging into $SYNO_Hostname:$SYNO_Port"
  77. token=$(curl -sk -c $_cookie_jar "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken)
  78. if [ $token = "null" ]; then
  79. _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme."
  80. _err "Check your username and password."
  81. rm "$_cookie_jar"
  82. return 1
  83. fi
  84. # Now that we know the username and password are good, save them
  85. _saveaccountconf_mutable SYNO_Username "$SYNO_Username"
  86. _saveaccountconf_mutable SYNO_Password "$SYNO_Password"
  87. _secure_debug2 token "$token"
  88. # Use token and session id to get the list of certificates
  89. 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)
  90. _debug3 response "$response"
  91. # select the first certificate matching our description
  92. cert=$(echo "$response" | jq -r ".data.certificates | map(select(.desc == \"$SYNO_Certificate\"))[0]")
  93. _debug3 cert "$cert"
  94. if [ "$cert" = "null" ]; then
  95. _err "Unable to find certificate: $SYNO_Certificate"
  96. rm "$_cookie_jar"
  97. return 1
  98. fi
  99. # we've verified this certificate description is a thing, so save it
  100. _savedeployconf SYNO_Certificate "$SYNO_Certificate"
  101. id=$(echo $cert | jq -r ".id")
  102. default=$(echo "$cert" | jq -r ".is_default")
  103. _debug2 id "$id"
  104. _debug2 default "$default"
  105. # This is the heavy lifting, make the API call to update a certificate in place
  106. 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)
  107. _debug3 response "$response"
  108. success=$(echo "$response" | jq -r ".success")
  109. _debug2 success "$success"
  110. rm "$_cookie_jar"
  111. if [ "$success" = "true" ]; then
  112. restarted=$(echo "$response" | jq -r ".data.restart_httpd")
  113. if [ "$restarted" = "true" ]; then
  114. _info "http services were restarted"
  115. else
  116. _info "http services were NOT restarted"
  117. fi
  118. return 0;
  119. else
  120. code=$(echo "$response" | jq -r ".error.code")
  121. _err "Unable to update certificate, error code $code"
  122. return 1
  123. fi
  124. }