Skip to content

Commit aa8cf76

Browse files
authored
Merge pull request #4706 from scruel/syno-patch
Add SYNO_USE_TEMP_ADMIN variable & Fix broken logic
2 parents 10b4bb5 + 29b2960 commit aa8cf76

File tree

1 file changed

+72
-26
lines changed

1 file changed

+72
-26
lines changed

deploy/synology_dsm.sh

Lines changed: 72 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,24 @@
99
# Issues: https://github.com/acmesh-official/acme.sh/issues/2727
1010
################################################################################
1111
# Usage:
12-
# 1. export SYNO_Username="adminUser"
13-
# 2. export SYNO_Password="adminPassword"
12+
# - Create temp admin user automatically:
13+
# export SYNO_USE_TEMP_ADMIN=1
14+
# - Or provide your own admin user credential:
15+
# 1. export SYNO_Username="adminUser"
16+
# 2. export SYNO_Password="adminPassword"
1417
# Optional exports (shown values are the defaults):
15-
# - export SYNO_Certificate="" to replace a specific certificate via description
18+
# - export SYNO_Certificate="" - to replace a specific certificate via description
1619
# - export SYNO_Scheme="http"
1720
# - export SYNO_Hostname="localhost"
1821
# - export SYNO_Port="5000"
19-
# - export SYNO_Device_Name="CertRenewal" - required for skipping 2FA-OTP
22+
# - export SYNO_Create=1 - to allow creating the certificate if it doesn't exist
23+
# - export SYNO_Device_Name="CertRenewal" - required if 2FA-OTP enabled
2024
# - export SYNO_Device_ID="" - required for skipping 2FA-OTP
2125
# 3. acme.sh --deploy --deploy-hook synology_dsm -d example.com
2226
################################################################################
2327
# Dependencies:
2428
# - jq & curl
29+
# - synouser & synogroup (When available and SYNO_USE_TEMP_ADMIN is set)
2530
################################################################################
2631
# Return value:
2732
# 0 means success, otherwise error.
@@ -38,19 +43,33 @@ synology_dsm_deploy() {
3843
_debug _cdomain "$_cdomain"
3944

4045
# Get username & password, but don't save until we authenticated successfully
46+
_getdeployconf SYNO_USE_TEMP_ADMIN
4147
_getdeployconf SYNO_Username
4248
_getdeployconf SYNO_Password
4349
_getdeployconf SYNO_Create
4450
_getdeployconf SYNO_DID
4551
_getdeployconf SYNO_TOTP_SECRET
4652
_getdeployconf SYNO_Device_Name
4753
_getdeployconf SYNO_Device_ID
48-
if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then
49-
_err "SYNO_Username & SYNO_Password must be set"
50-
return 1
54+
55+
# Prepare temp admin user info if SYNO_USE_TEMP_ADMIN is set
56+
if [ -n "${SYNO_USE_TEMP_ADMIN:-}" ]; then
57+
if ! _exists synouser; then
58+
if ! _exists synogroup; then
59+
_err "Tools are missing for creating temp admin user, please set SYNO_Username & SYNO_Password instead."
60+
return 1
61+
fi
62+
fi
63+
_debug "Setting temp admin user credential..."
64+
SYNO_Username=sc-acmesh-tmp
65+
SYNO_Password=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)
66+
# Ignore 2FA-OTP settings which won't be needed.
67+
SYNO_Device_Name=
68+
SYNO_Device_ID=
5169
fi
52-
if [ -n "${SYNO_Device_Name:-}" ] && [ -z "${SYNO_Device_ID:-}" ]; then
53-
_err "SYNO_Device_Name set, but SYNO_Device_ID is empty"
70+
71+
if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then
72+
_err "You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_Username and SYNO_Password."
5473
return 1
5574
fi
5675
_debug2 SYNO_Username "$SYNO_Username"
@@ -69,6 +88,7 @@ synology_dsm_deploy() {
6988
[ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http"
7089
[ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost"
7190
[ -n "${SYNO_Port}" ] || SYNO_Port="5000"
91+
_savedeployconf SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN"
7292
_savedeployconf SYNO_Scheme "$SYNO_Scheme"
7393
_savedeployconf SYNO_Hostname "$SYNO_Hostname"
7494
_savedeployconf SYNO_Port "$SYNO_Port"
@@ -108,13 +128,11 @@ synology_dsm_deploy() {
108128
_info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!"
109129
_info " See synology_dsm.sh script or ACME.sh Wiki page for details:"
110130
_info " https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide"
111-
DEPRECATED_otp_code=""
112-
if _exists oathtool; then
113-
DEPRECATED_otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)"
114-
else
131+
if ! _exists oathtool; then
115132
_err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
116133
return 1
117134
fi
135+
DEPRECATED_otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)"
118136

119137
if [ -n "$SYNO_DID" ]; then
120138
_H1="Cookie: did=$SYNO_DID"
@@ -125,35 +143,49 @@ synology_dsm_deploy() {
125143
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_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes")
126144
_debug3 response "$response"
127145
# END - DEPRECATED, only kept for legacy compatibility reasons
146+
# If SYNO_DeviceDevice_ID & SYNO_Device_Name both empty, just log in normally
147+
elif [ -z "${SYNO_Device_ID:-}" ] && [ -z "${SYNO_Device_Name:-}" ]; then
148+
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then
149+
_debug "Creating temp admin user in Synology DSM"
150+
synouser --del "$SYNO_Username" >/dev/null 2>/dev/null
151+
synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "" 0 >/dev/null
152+
synogroup --memberadd administrators "$SYNO_Username" >/dev/null
153+
fi
154+
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")
155+
_debug3 response "$response"
128156
# Get device ID if still empty first, otherwise log in right away
129-
elif [ -z "${SYNO_Device_ID:-}" ]; then
157+
# If SYNO_Device_Name is set, we treat that account enabled two-factor authorization, consider SYNO_Device_ID is not set, so it won't be able to login without requiring the OTP code.
158+
elif [ -n "${SYNO_Device_Name:-}" ] && [ -z "${SYNO_Device_ID:-}" ]; then
130159
printf "Enter OTP code for user '%s': " "$SYNO_Username"
131160
read -r otp_code
132-
if [ -z "${SYNO_Device_Name:-}" ]; then
133-
printf "Enter device name or leave empty for default (CertRenewal): "
134-
read -r SYNO_Device_Name
135-
[ -n "${SYNO_Device_Name}" ] || SYNO_Device_Name="CertRenewal"
136-
fi
137-
138161
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name")
139162
_secure_debug3 response "$response"
140163

141164
id_property='device_id'
142165
[ "${api_version}" -gt '6' ] || id_property='did'
143166
SYNO_Device_ID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p')
144167
_secure_debug2 SYNO_Device_ID "$SYNO_Device_ID"
168+
# Otherwise, if SYNO_Device_ID is set, we can just use it to login.
145169
else
170+
if [ -z "${SYNO_Device_Name:-}" ]; then
171+
printf "Enter device name or leave empty for default (CertRenewal): "
172+
read -r SYNO_Device_Name
173+
[ -n "${SYNO_Device_Name}" ] || SYNO_Device_Name="CertRenewal"
174+
fi
146175
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")
147-
_debug3 response "$response"
176+
_secure_debug3 response "$response"
148177
fi
149178

150179
sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p')
151180
token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p')
152181
_debug "Session ID" "$sid"
153182
_debug SynoToken "$token"
154-
if [ -z "$SYNO_DID" ] && [ -z "$SYNO_Device_ID" ] || [ -z "$sid" ] || [ -z "$token" ]; then
183+
if [ -z "$sid" ] || [ -z "$token" ]; then
155184
_err "Unable to authenticate to $_base_url - check your username & password."
156-
_err "If two-factor authentication is enabled for the user, set SYNO_Device_ID."
185+
_err "If two-factor authentication is enabled for the user:"
186+
_err "- set SYNO_Device_Name then input *correct* OTP-code manually"
187+
_err "- get & set SYNO_Device_ID via your browser cookies"
188+
_remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username"
157189
return 1
158190
fi
159191

@@ -164,8 +196,10 @@ synology_dsm_deploy() {
164196
# Now that we know the username & password are good, save them
165197
_savedeployconf SYNO_Username "$SYNO_Username"
166198
_savedeployconf SYNO_Password "$SYNO_Password"
167-
_savedeployconf SYNO_Device_Name "$SYNO_Device_Name"
168-
_savedeployconf SYNO_Device_ID "$SYNO_Device_ID"
199+
if [ -z "${SYNO_USE_TEMP_ADMIN:-}" ]; then
200+
_savedeployconf SYNO_Device_Name "$SYNO_Device_Name"
201+
_savedeployconf SYNO_Device_ID "$SYNO_Device_ID"
202+
fi
169203

170204
_info "Getting certificates in Synology DSM"
171205
response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi")
@@ -177,6 +211,7 @@ synology_dsm_deploy() {
177211

178212
if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then
179213
_err "Unable to find certificate: $SYNO_Certificate & \$SYNO_Create is not set"
214+
_remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username"
180215
return 1
181216
fi
182217

@@ -211,10 +246,11 @@ synology_dsm_deploy() {
211246
else
212247
_info "Restarting HTTP services failed"
213248
fi
214-
249+
_remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username"
215250
_logout
216251
return 0
217252
else
253+
_remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username"
218254
_err "Unable to update certificate, error code $response"
219255
_logout
220256
return 1
@@ -227,3 +263,13 @@ _logout() {
227263
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=logout&_sid=$sid")
228264
_debug3 response "$response"
229265
}
266+
267+
_remove_temp_admin() {
268+
flag=$1
269+
username=$2
270+
271+
if [ -n "${flag}" ]; then
272+
_debug "Removing temp admin user in Synology DSM"
273+
synouser --del "$username" >/dev/null
274+
fi
275+
}

0 commit comments

Comments
 (0)