2023-05-28 21:42:53 +02:00
#!/bin/bash
################################################################################
# ACME.sh 3rd party deploy plugin for Synology DSM
################################################################################
# Authors: Brian Hartvigsen (creator), https://github.com/tresni
# Martin Arndt (contributor), https://troublezone.net/
2023-07-04 15:47:19 +02:00
# Updated: 2023-07-03
2023-05-28 21:42:53 +02:00
# Issues: https://github.com/acmesh-official/acme.sh/issues/2727
################################################################################
2024-02-26 12:52:06 +01:00
# Usage (shown values are the examples):
2024-02-25 21:50:30 +01:00
# 1. Set required environment variables:
# - use automatically created temp admin user to authenticate
2024-02-26 12:52:06 +01:00
# export SYNO_USE_TEMP_ADMIN=1
2024-02-25 21:50:30 +01:00
# - or provide your own admin user credential to authenticate
2024-02-26 12:52:06 +01:00
# 1. export SYNO_USERNAME="adminUser"
# 2. export SYNO_PASSWORD="adminPassword"
# 2. Set optional environment variables
2024-02-25 21:50:30 +01:00
# - common optional variables
2024-02-26 12:52:06 +01:00
# - export SYNO_SCHEME="http" - defaults to "http"
# - export SYNO_HOSTNAME="localhost" - defaults to "localhost"
# - export SYNO_PORT="5000" - defaults to "5000"
# - export SYNO_CREATE=1 - to allow creating the cert if it doesn't exist
# - export SYNO_CERTIFICATE="" - to replace a specific cert by its
2024-02-25 21:50:30 +01:00
# description
# - 2FA-OTP optional variables (with your own admin user)
2024-02-26 12:52:06 +01:00
# - export SYNO_OTP_CODE="XXXXXX" - if set, script won't require to
# interactive input the OTP code
# - export SYNO_DEVICE_NAME="CertRenewal" - if set, script won't require to
# interactive input the device name
# - export SYNO_DEVICE_ID="" - (deprecated) required for omitting 2FA-OTP
# (please auth with OTP code instead)
# - temp admin optional variables
# - export SYNO_LOCAL_HOSTNAME=1 - if set to 1, force to treat hostname is
# targeting current local machine (since
# this method only locally supported)
2024-02-22 05:38:51 +01:00
# 3. Run command:
2024-02-26 12:52:06 +01:00
# acme.sh --deploy --deploy-hook synology_dsm -d example.com
2023-05-28 21:42:53 +02:00
################################################################################
2021-11-13 10:56:10 +01:00
# Dependencies:
2024-02-25 21:50:30 +01:00
# - curl
2024-02-26 13:55:49 +01:00
# - synouser & synogroup (When available and SYNO_USE_TEMP_ADMIN is set)
2023-05-28 21:42:53 +02:00
################################################################################
# Return value:
# 0 means success, otherwise error.
################################################################################
2019-06-30 05:47:24 +02:00
2023-05-28 21:42:53 +02:00
########## Public functions ####################################################
2019-06-30 05:47:24 +02:00
#domain keyfile certfile cafile fullchain
synology_dsm_deploy( ) {
_cdomain = " $1 "
_ckey = " $2 "
_ccert = " $3 "
_cca = " $4 "
_debug _cdomain " $_cdomain "
2024-02-23 12:58:24 +01:00
# Get username and password, but don't save until we authenticated successfully
2024-02-26 13:55:49 +01:00
_migratedeployconf SYNO_Username SYNO_USERNAME
_migratedeployconf SYNO_Password SYNO_PASSWORD
_migratedeployconf SYNO_Device_ID SYNO_DEVICE_ID
_migratedeployconf SYNO_Device_Name SYNO_DEVICE_NAME
_getdeployconf SYNO_USERNAME
_getdeployconf SYNO_PASSWORD
_getdeployconf SYNO_DEVICE_ID
_getdeployconf SYNO_DEVICE_NAME
# Prepare to use temp admin if SYNO_USE_TEMP_ADMIN is set
_debug2 SYNO_USE_TEMP_ADMIN " $SYNO_USE_TEMP_ADMIN "
_getdeployconf SYNO_USE_TEMP_ADMIN
2024-02-26 16:38:44 +01:00
_check2cleardeployconfexp SYNO_USE_TEMP_ADMIN
2024-02-26 13:55:49 +01:00
_debug2 SYNO_USE_TEMP_ADMIN " $SYNO_USE_TEMP_ADMIN "
if [ -n " $SYNO_USE_TEMP_ADMIN " ] ; then
2024-02-23 12:58:24 +01:00
if ! _exists synouser || ! _exists synogroup; then
2024-02-26 13:55:49 +01:00
_err "Tools are missing for creating temp admin user, please set SYNO_USERNAME and SYNO_PASSWORD instead."
2024-02-23 12:58:24 +01:00
return 1
2023-07-19 20:48:29 +02:00
fi
2024-02-25 21:50:30 +01:00
2024-02-26 13:55:49 +01:00
[ -n " $SYNO_USERNAME " ] || _savedeployconf SYNO_USERNAME ""
[ -n " $SYNO_PASSWORD " ] || _savedeployconf SYNO_PASSWORD ""
2024-02-23 12:58:24 +01:00
2023-07-19 20:48:29 +02:00
_debug "Setting temp admin user credential..."
2024-02-26 13:55:49 +01:00
SYNO_USERNAME = sc-acmesh-tmp
SYNO_PASSWORD = $( head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)
2024-02-25 21:50:30 +01:00
# Set 2FA-OTP settings to empty consider they won't be needed.
2024-02-26 13:55:49 +01:00
SYNO_DEVICE_ID =
SYNO_DEVICE_NAME =
SYNO_OTP_CODE =
2024-02-23 12:58:24 +01:00
else
2024-02-26 13:55:49 +01:00
_debug2 SYNO_USERNAME " $SYNO_USERNAME "
_secure_debug2 SYNO_PASSWORD " $SYNO_PASSWORD "
_debug2 SYNO_DEVICE_NAME " $SYNO_DEVICE_NAME "
_secure_debug2 SYNO_DEVICE_ID " $SYNO_DEVICE_ID "
2019-06-30 05:47:24 +02:00
fi
2023-07-20 07:34:57 +02:00
2024-02-26 13:55:49 +01:00
if [ -z " $SYNO_USERNAME " ] || [ -z " $SYNO_PASSWORD " ] ; then
_err "You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_USERNAME and SYNO_PASSWORD."
2023-05-28 21:42:53 +02:00
return 1
fi
2019-06-30 05:47:24 +02:00
2024-02-23 12:58:24 +01:00
# Optional scheme, hostname and port for Synology DSM
2024-02-26 13:55:49 +01:00
_migratedeployconf SYNO_Scheme SYNO_SCHEME
_migratedeployconf SYNO_Hostname SYNO_HOSTNAME
_migratedeployconf SYNO_Port SYNO_PORT
_getdeployconf SYNO_SCHEME
_getdeployconf SYNO_HOSTNAME
_getdeployconf SYNO_PORT
2019-06-30 05:47:24 +02:00
2024-02-23 12:58:24 +01:00
# Default values for scheme, hostname and port
# Defaulting to localhost and http, because it's localhost…
2024-02-26 13:55:49 +01:00
[ -n " $SYNO_SCHEME " ] || SYNO_SCHEME = "http"
[ -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 "
2019-06-30 05:47:24 +02:00
2023-07-04 15:47:19 +02:00
# Get the certificate description, but don't save it until we verify it's real
2024-02-26 13:55:49 +01:00
_migratedeployconf SYNO_Certificate SYNO_CERTIFICATE "base64"
_getdeployconf SYNO_CERTIFICATE
2024-02-26 16:38:44 +01:00
_check2cleardeployconfexp SYNO_CERTIFICATE
2024-02-26 13:55:49 +01:00
_debug SYNO_CERTIFICATE " ${ SYNO_CERTIFICATE :- } "
2019-06-30 05:47:24 +02:00
2021-05-26 23:24:50 +02:00
# shellcheck disable=SC1003 # We are not trying to escape a single quote
2024-02-26 13:55:49 +01:00
if printf "%s" " $SYNO_CERTIFICATE " | grep '\\' ; then
2021-05-26 23:07:23 +02:00
_err "Do not use a backslash (\) in your certificate description"
return 1
fi
2024-02-23 13:00:00 +01:00
_debug "Getting API version..."
2024-02-26 13:55:49 +01:00
_base_url = " $SYNO_SCHEME :// $SYNO_HOSTNAME : $SYNO_PORT "
2019-06-30 05:47:24 +02:00
_debug _base_url " $_base_url "
2020-12-09 11:45:25 +01:00
response = $( _get " $_base_url /webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth " )
2023-09-25 17:43:01 +02:00
api_path = $( echo " $response " | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([^"]*\)".*/\1/p' )
2020-12-09 11:45:25 +01:00
api_version = $( echo " $response " | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p' )
_debug3 response " $response "
2023-08-09 19:52:37 +02:00
_debug3 api_path " $api_path "
2020-12-09 11:45:25 +01:00
_debug3 api_version " $api_version "
2024-02-23 12:58:24 +01:00
# Login, get the session ID and SynoToken from JSON
2024-02-26 13:55:49 +01:00
_info " Logging into $SYNO_HOSTNAME : $SYNO_PORT ... "
encoded_username = " $( printf "%s" " $SYNO_USERNAME " | _url_encode) "
encoded_password = " $( printf "%s" " $SYNO_PASSWORD " | _url_encode) "
2023-07-04 16:58:14 +02:00
2024-02-23 12:58:24 +01:00
# ## START ## - DEPRECATED, for backward compatibility
_getdeployconf SYNO_TOTP_SECRET
2023-07-04 15:47:19 +02:00
if [ -n " $SYNO_TOTP_SECRET " ] ; then
_info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!"
_info " See synology_dsm.sh script or ACME.sh Wiki page for details:"
_info " https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide"
2023-07-19 20:48:29 +02:00
if ! _exists oathtool; then
2023-07-04 15:47:19 +02:00
_err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
return 1
fi
2024-02-23 12:58:24 +01:00
DEPRECATED_otp_code = " $( oathtool --base32 --totp " $SYNO_TOTP_SECRET " 2>/dev/null) "
2020-12-09 11:45:25 +01:00
2024-02-26 13:55:49 +01:00
if [ -z " $SYNO_DEVICE_ID " ] ; then
2024-02-23 12:58:24 +01:00
_getdeployconf SYNO_DID
2024-02-26 13:55:49 +01:00
[ -n " $SYNO_DID " ] || SYNO_DEVICE_ID = " $SYNO_DID "
2024-02-23 12:58:24 +01:00
fi
2024-02-26 13:55:49 +01:00
if [ -n " $SYNO_DEVICE_ID " ] ; then
_H1 = " Cookie: did= $SYNO_DEVICE_ID "
2023-07-04 15:47:19 +02:00
export _H1
_debug3 H1 " ${ _H1 } "
fi
2024-02-26 13:55:49 +01:00
response = $( _post " method=login&account= $encoded_username &passwd= $encoded_password &api=SYNO.API.Auth&version= $api_version &enable_syno_token=yes&otp_code= $DEPRECATED_otp_code &device_name=certrenewal&device_id= $SYNO_DEVICE_ID " " $_base_url /webapi/auth.cgi?enable_syno_token=yes " )
2023-07-04 15:47:19 +02:00
_debug3 response " $response "
2024-02-23 12:58:24 +01:00
# ## END ## - DEPRECATED, for backward compatibility
2024-02-26 13:55:49 +01:00
# If SYNO_DEVICE_ID or SYNO_OTP_CODE is set, we treat current account enabled 2FA-OTP.
# Notice that if SYNO_USE_TEMP_ADMIN=1, both variables will be unset
2024-02-25 21:50:30 +01:00
else
2024-02-26 13:55:49 +01:00
if [ -n " $SYNO_DEVICE_ID " ] || [ -n " $SYNO_OTP_CODE " ] ; then
2024-02-25 21:50:30 +01:00
response = '{"error":{"code":403}}'
# Assume the current account disabled 2FA-OTP, try to log in right away.
else
2024-02-26 13:55:49 +01:00
if [ -n " $SYNO_USE_TEMP_ADMIN " ] ; then
2024-02-26 12:52:06 +01:00
_getdeployconf SYNO_LOCAL_HOSTNAME
_debug SYNO_LOCAL_HOSTNAME " ${ SYNO_LOCAL_HOSTNAME :- } "
if [ " $SYNO_LOCAL_HOSTNAME " != "1" ] && [ " $SYNO_LOCAL_HOSTNAME " = = " $SYNO_HOSTNAME " ] ; then
if [ " $SYNO_HOSTNAME " != "localhost" ] && [ " $SYNO_HOSTNAME " != "127.0.0.1" ] ; then
_err " SYNO_USE_TEMP_ADMIN=1 Only support locally deployment, if you are sure that hostname $SYNO_HOSTNAME is targeting to your **current local machine**, execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun. "
return 1
fi
fi
2024-02-25 23:21:03 +01:00
_debug "Creating temp admin user in Synology DSM..."
2024-02-26 16:38:44 +01:00
if synogroup --help | grep -q '\-\-memberadd ' ; then
_temp_admin_create $SYNO_USERNAME $SYNO_PASSWORD
2024-02-26 13:55:49 +01:00
synogroup --memberadd administrators " $SYNO_USERNAME " >/dev/null
2024-02-26 16:38:44 +01:00
elif synogroup --help | grep -q '\-\-member ' ; then
2024-02-25 23:21:03 +01:00
# For supporting DSM 6.x which only has `--member` parameter.
cur_admins = $( synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}' )
2024-02-26 16:38:44 +01:00
if [ -n " $cur_admins " ] ; then
_temp_admin_create $SYNO_USERNAME $SYNO_PASSWORD
_secure_debug3 admin_users " $cur_admins $SYNO_USERNAME "
# shellcheck disable=SC2086
synogroup --member administrators $cur_admins $SYNO_USERNAME >/dev/null
else
_err "Tool synogroup may be broken, please set SYNO_USERNAME and SYNO_PASSWORD instead."
return 1
fi
else
_err "Unsupported synogroup tool detected, please set SYNO_USERNAME and SYNO_PASSWORD instead."
return 1
2024-02-25 23:21:03 +01:00
fi
# havig a workaround to temporary disable enforce 2FA-OTP
otp_enforce_option = $( synogetkeyvalue /etc/synoinfo.conf otp_enforce_option)
if [ -n " $otp_enforce_option " ] && [ " ${ otp_enforce_option :- "none" } " != "none" ] ; then
synosetkeyvalue /etc/synoinfo.conf otp_enforce_option none
_info "Temporary disabled enforce 2FA-OTP to complete authentication."
_info "previous_otp_enforce_option" " $otp_enforce_option "
else
otp_enforce_option = ""
fi
fi
2024-02-25 21:50:30 +01:00
response = $( _get " $_base_url /webapi/entry.cgi?api=SYNO.API.Auth&version= $api_version &method=login&format=sid&account= $encoded_username &passwd= $encoded_password &enable_syno_token=yes " )
2024-02-26 13:55:49 +01:00
if [ -n " $SYNO_USE_TEMP_ADMIN " ] && [ -n " $otp_enforce_option " ] ; then
2024-02-25 23:21:03 +01:00
synosetkeyvalue /etc/synoinfo.conf otp_enforce_option " $otp_enforce_option "
_info "Restored previous enforce 2FA-OTP option."
fi
2024-02-25 21:50:30 +01:00
_debug3 response " $response "
fi
fi
error_code = $( echo " $response " | grep '"error"' | grep -oP '(?<="code":)\d+' )
# Account has 2FA-OTP enabled, since error 403 reported.
2024-02-25 23:21:03 +01:00
# https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_Administration_CLI_Guide.pdf
if [ " $error_code " = = "403" ] ; then
2024-02-26 13:55:49 +01:00
if [ -z " $SYNO_DEVICE_NAME " ] ; then
2024-02-25 21:50:30 +01:00
printf "Enter device name or leave empty for default (CertRenewal): "
2024-02-26 13:55:49 +01:00
read -r SYNO_DEVICE_NAME
[ -n " $SYNO_DEVICE_NAME " ] || SYNO_DEVICE_NAME = "CertRenewal"
2024-02-25 21:50:30 +01:00
fi
2024-02-26 13:55:49 +01:00
if [ -n " $SYNO_DEVICE_ID " ] ; then
# Omit OTP code with SYNO_DEVICE_ID.
response = $( _get " $_base_url /webapi/ $api_path ?api=SYNO.API.Auth&version= $api_version &method=login&format=sid&account= $encoded_username &passwd= $encoded_password &enable_syno_token=yes&device_name= $SYNO_DEVICE_NAME &device_id= $SYNO_DEVICE_ID " )
2024-02-25 21:50:30 +01:00
_secure_debug3 response " $response "
else
# Require the OTP code if still unset.
2024-02-26 13:55:49 +01:00
if [ -z " $SYNO_OTP_CODE " ] ; then
printf "Enter OTP code for user '%s': " " $SYNO_USERNAME "
read -r SYNO_OTP_CODE
2024-02-25 21:50:30 +01:00
fi
2024-02-26 12:52:06 +01:00
_secure_debug SYNO_OTP_CODE " ${ SYNO_OTP_CODE :- } "
2024-02-25 21:50:30 +01:00
2024-02-26 13:55:49 +01:00
if [ -z " $SYNO_OTP_CODE " ] ; then
2024-02-25 21:50:30 +01:00
response = '{"error":{"code":404}}'
else
2024-02-26 13:55:49 +01:00
response = $( _get " $_base_url /webapi/ $api_path ?api=SYNO.API.Auth&version= $api_version &method=login&format=sid&account= $encoded_username &passwd= $encoded_password &enable_syno_token=yes&enable_device_token=yes&device_name= $SYNO_DEVICE_NAME &otp_code= $SYNO_OTP_CODE " )
2024-02-23 12:58:24 +01:00
_secure_debug3 response " $response "
2023-08-11 17:55:45 +02:00
2024-02-23 12:58:24 +01:00
id_property = 'device_id'
[ " ${ api_version } " -gt '6' ] || id_property = 'did'
2024-02-26 13:55:49 +01:00
SYNO_DEVICE_ID = $( echo " $response " | grep " $id_property " | sed -n 's/.*"' $id_property '" *: *"\([^"]*\).*/\1/p' )
_secure_debug2 SYNO_DEVICE_ID " $SYNO_DEVICE_ID "
2024-02-25 21:50:30 +01:00
fi
2023-07-19 20:48:29 +02:00
fi
2024-02-25 21:50:30 +01:00
error_code = $( echo " $response " | grep '"error"' | grep -oP '(?<="code":)\d+' )
fi
if [ -n " $error_code " ] ; then
2024-02-26 13:55:49 +01:00
if [ " $error_code " = = "403" ] && [ -n " $SYNO_DEVICE_ID " ] ; then
_cleardeployconf SYNO_DEVICE_ID
_err "Failed to authenticate with SYNO_DEVICE_ID (may expired or invalid), please try again in a new terminal window."
2024-02-25 23:21:03 +01:00
elif [ " $error_code " = = "404" ] ; then
2024-02-25 21:50:30 +01:00
_err "Failed to authenticate with provided 2FA-OTP code, please try again in a new terminal window."
2024-02-25 23:21:03 +01:00
elif [ " $error_code " = = "406" ] ; then
2024-02-26 13:55:49 +01:00
if [ -n " $SYNO_USE_TEMP_ADMIN " ] ; then
_err "SYNO_USE_TEMP_ADMIN=1 is not supported if enforce auth with 2FA-OTP is enabled."
2024-02-25 21:50:30 +01:00
else
_err "Enforce auth with 2FA-OTP enabled, please configure the user to enable 2FA-OTP to continue."
fi
2024-02-25 23:21:03 +01:00
elif [ " $error_code " = = "400" ] || [ " $error_code " = = "401" ] || [ " $error_code " = = "408" ] || [ " $error_code " = = "409" ] || [ " $error_code " = = "410" ] ; then
2024-02-25 21:50:30 +01:00
_err "Failed to authenticate with a non-existent or disabled account, or the account password is incorrect or has expired."
else
_err " Failed to authenticate with error: $error_code . "
fi
2024-02-26 13:55:49 +01:00
_temp_admin_cleanup " $SYNO_USE_TEMP_ADMIN " " $SYNO_USERNAME "
2024-02-25 21:50:30 +01:00
return 1
2020-12-09 11:45:25 +01:00
fi
2023-05-28 21:42:53 +02:00
sid = $( echo " $response " | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p' )
2020-12-09 11:45:25 +01:00
token = $( echo " $response " | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p' )
2023-05-28 22:33:15 +02:00
_debug "Session ID" " $sid "
2023-05-28 21:42:53 +02:00
_debug SynoToken " $token "
2023-07-19 20:48:29 +02:00
if [ -z " $sid " ] || [ -z " $token " ] ; then
2024-02-25 21:50:30 +01:00
# Still can't get necessary info even got no errors, may Synology have API updated?
_err " Unable to authenticate to $_base_url , you may report the full log to the community. "
2024-02-26 13:55:49 +01:00
_temp_admin_cleanup " $SYNO_USE_TEMP_ADMIN " " $SYNO_USERNAME "
2019-06-30 05:47:24 +02:00
return 1
fi
2020-12-09 11:45:25 +01:00
_H1 = " X-SYNO-TOKEN: $token "
2020-02-09 01:27:18 +01:00
export _H1
2020-02-09 11:50:29 +01:00
_debug2 H1 " ${ _H1 } "
2020-02-09 01:27:18 +01:00
2024-02-23 12:58:24 +01:00
# Now that we know the username and password are good, save them if not in temp admin mode.
2024-02-26 13:55:49 +01:00
if [ -n " $SYNO_USE_TEMP_ADMIN " ] ; then
_cleardeployconf SYNO_USERNAME
_cleardeployconf SYNO_PASSWORD
_cleardeployconf SYNO_DEVICE_ID
_cleardeployconf SYNO_DEVICE_NAME
_savedeployconf SYNO_USE_TEMP_ADMIN " $SYNO_USE_TEMP_ADMIN "
2024-02-26 12:52:06 +01:00
_savedeployconf SYNO_LOCAL_HOSTNAME " $SYNO_HOSTNAME "
2024-02-25 21:50:30 +01:00
else
2024-02-26 13:55:49 +01:00
_savedeployconf SYNO_USERNAME " $SYNO_USERNAME "
_savedeployconf SYNO_PASSWORD " $SYNO_PASSWORD "
_savedeployconf SYNO_DEVICE_ID " $SYNO_DEVICE_ID "
_savedeployconf SYNO_DEVICE_NAME " $SYNO_DEVICE_NAME "
2023-07-19 20:48:29 +02:00
fi
2019-06-30 05:47:24 +02:00
2024-02-23 12:58:24 +01:00
_info "Getting certificates in Synology DSM..."
2020-12-09 11:45:25 +01:00
response = $( _post " api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid= $sid " " $_base_url /webapi/entry.cgi " )
2019-06-30 05:47:24 +02:00
_debug3 response " $response "
2024-02-26 13:55:49 +01:00
escaped_certificate = " $( printf "%s" " $SYNO_CERTIFICATE " | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g' ) "
2021-05-26 23:07:23 +02:00
_debug escaped_certificate " $escaped_certificate "
id = $( echo " $response " | sed -n " s/.*\"desc\":\" $escaped_certificate \",\"id\":\"\([^\"]*\).*/\1/p " )
2020-02-09 01:27:18 +01:00
_debug2 id " $id "
2019-06-30 05:47:24 +02:00
2024-02-25 21:50:30 +01:00
error_code = $( echo " $response " | grep '"error"' | grep -oP '(?<="code":)\d+' )
if [ -n " $error_code " ] ; then
if [ " $error_code " -eq 105 ] ; then
_err "Current user is not administrator and does not have sufficient permission for deploying."
else
2024-02-26 12:52:06 +01:00
_err " Failed to fetch certificate info with error: $error_code , please try again or contact Synology to learn more. "
2024-02-25 21:50:30 +01:00
fi
2024-02-26 13:55:49 +01:00
_temp_admin_cleanup " $SYNO_USE_TEMP_ADMIN " " $SYNO_USERNAME "
2024-02-25 21:50:30 +01:00
return 1
fi
2024-02-26 13:55:49 +01:00
_migratedeployconf SYNO_Create SYNO_CREATE
_getdeployconf SYNO_CREATE
_debug2 SYNO_CREATE " $SYNO_CREATE "
2024-02-25 21:50:30 +01:00
2024-02-26 13:55:49 +01:00
if [ -z " $id " ] && [ -z " $SYNO_CREATE " ] ; then
_err " Unable to find certificate: $SYNO_CERTIFICATE and $SYNO_CREATE is not set. "
_temp_admin_cleanup " $SYNO_USE_TEMP_ADMIN " " $SYNO_USERNAME "
2019-06-30 05:47:24 +02:00
return 1
fi
2023-07-04 15:47:19 +02:00
# We've verified this certificate description is a thing, so save it
2024-02-26 13:55:49 +01:00
_savedeployconf SYNO_CERTIFICATE " $SYNO_CERTIFICATE " "base64"
2019-06-30 05:47:24 +02:00
2024-02-25 23:21:03 +01:00
_info "Generating form POST request..."
2020-05-19 07:27:00 +02:00
nl = "\0015\0012"
2020-02-09 20:50:50 +01:00
delim = " -------------------------- $( _utc_date | tr -d -- '-: ' ) "
2020-05-19 07:27:00 +02:00
content = " -- $delim ${ nl } Content-Disposition: form-data; name=\"key\"; filename=\" $( basename " $_ckey " ) \" ${ nl } Content-Type: application/octet-stream ${ nl } ${ nl } $( cat " $_ckey " ) \0012 "
content = " $content ${ nl } -- $delim ${ nl } Content-Disposition: form-data; name=\"cert\"; filename=\" $( basename " $_ccert " ) \" ${ nl } Content-Type: application/octet-stream ${ nl } ${ nl } $( cat " $_ccert " ) \0012 "
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 "
2020-02-09 01:27:18 +01:00
content = " $content ${ nl } -- $delim ${ nl } Content-Disposition: form-data; name=\"id\" ${ nl } ${ nl } $id "
2024-02-26 13:55:49 +01:00
content = " $content ${ nl } -- $delim ${ nl } Content-Disposition: form-data; name=\"desc\" ${ nl } ${ nl } ${ SYNO_CERTIFICATE } "
2021-05-26 23:07:23 +02:00
if echo " $response " | sed -n " s/.*\"desc\":\" $escaped_certificate \",\([^{]*\).*/\1/p " | grep -- 'is_default":true' >/dev/null; then
2023-07-04 15:47:19 +02:00
_debug2 default "This is the default certificate"
2021-05-19 21:21:34 +02:00
content = " $content ${ nl } -- $delim ${ nl } Content-Disposition: form-data; name=\"as_default\" ${ nl } ${ nl } true "
else
2023-07-04 15:47:19 +02:00
_debug2 default "This is NOT the default certificate"
2021-05-19 21:21:34 +02:00
fi
2020-02-09 01:27:18 +01:00
content = " $content ${ nl } -- $delim -- ${ nl } "
2020-02-09 11:01:26 +01:00
content = " $( printf "%b_" " $content " ) "
content = " ${ content %_ } " # protect trailing \n
2020-02-09 01:27:18 +01:00
2024-02-23 12:58:24 +01:00
_info "Upload certificate to the Synology DSM."
2020-12-09 11:45:25 +01:00
response = $( _post " $content " " $_base_url /webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken= $token &_sid= $sid " "" "POST" " multipart/form-data; boundary= ${ delim } " )
2019-06-30 05:47:24 +02:00
_debug3 response " $response "
2020-02-11 05:02:27 +01:00
if ! echo " $response " | grep '"error":' >/dev/null; then
if echo " $response " | grep '"restart_httpd":true' >/dev/null; then
2024-02-25 23:21:03 +01:00
_info "Restart HTTP services succeeded."
2019-06-30 05:47:24 +02:00
else
2024-02-25 23:21:03 +01:00
_info "Restart HTTP services failed."
2019-06-30 05:47:24 +02:00
fi
2024-02-26 13:55:49 +01:00
_temp_admin_cleanup " $SYNO_USE_TEMP_ADMIN " " $SYNO_USERNAME "
2023-05-28 21:42:53 +02:00
_logout
2019-06-30 08:13:45 +02:00
return 0
2019-06-30 05:47:24 +02:00
else
2024-02-26 13:55:49 +01:00
_temp_admin_cleanup " $SYNO_USE_TEMP_ADMIN " " $SYNO_USERNAME "
2024-02-25 23:21:03 +01:00
_err " Unable to update certificate, got error response: $response . "
2023-05-28 21:42:53 +02:00
_logout
2019-06-30 05:47:24 +02:00
return 1
fi
}
2023-05-28 21:42:53 +02:00
#################### Private functions below ##################################
_logout( ) {
2023-12-22 20:36:52 +01:00
# Logout CERT user only to not occupy a permanent session, e.g. in DSM's "Connected Users" widget (based on previous variables)
2023-12-22 15:09:29 +01:00
response = $( _get " $_base_url /webapi/ $api_path ?api=SYNO.API.Auth&version= $api_version &method=logout&_sid= $sid " )
2023-05-28 21:42:53 +02:00
_debug3 response " $response "
}
2023-07-19 20:48:29 +02:00
2024-02-26 16:38:44 +01:00
_temp_admin_create( ) {
_username = " $1 "
_password = " $2 "
synouser --del " $_username " >/dev/null 2>/dev/null
synouser --add " $_username " " $_password " "" 0 "scruelt@hotmail.com" 0 >/dev/null
}
2024-02-25 21:50:30 +01:00
_temp_admin_cleanup( ) {
2024-02-26 16:38:44 +01:00
_flag = $1
_username = $2
2023-07-20 07:34:57 +02:00
2024-02-26 16:38:44 +01:00
if [ -n " ${ _flag } " ] ; then
2024-02-25 21:50:30 +01:00
_debug "Cleanuping temp admin info..."
2024-02-26 16:38:44 +01:00
synouser --del " $_username " >/dev/null
2023-07-19 20:48:29 +02:00
fi
}
2024-02-26 13:55:49 +01:00
#_cleardeployconf key
_cleardeployconf( ) {
_cleardomainconf " SAVED_ $1 "
}
# key
2024-02-26 16:38:44 +01:00
_check2cleardeployconfexp( ) {
2024-02-26 13:55:49 +01:00
_key = " $1 "
_clear_key = " CLEAR_ $_key "
# Clear saved settings if explicitly requested
2024-02-26 14:07:15 +01:00
if [ -n " $( eval echo \$ " $_clear_key " ) " ] ; then
2024-02-26 13:55:49 +01:00
_debug2 " $_key : value cleared from config, exported value will be ignored. "
_cleardeployconf " $_key "
2024-02-26 14:07:15 +01:00
eval " $_key " =
export " $_key " =
eval SAVED_" $_key " =
export SAVED_" $_key " =
2024-02-26 13:55:49 +01:00
fi
}