Skip to content

Commit 0ff3572

Browse files
thomassagaborigloi
authored andcommitted
CP-24800: Make TLS cert generation atomic
Instead of concatenating text into the file in its final location and then setting its permissions, prepare the file (content and permissions) in a staging area and then use an atomic move operation to make it appear in its final location. Also some other improvements to reliability and safety. Signed-off-by: Thomas Sanders <[email protected]>
1 parent 4a82ec3 commit 0ff3572

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

scripts/generate_ssl_cert

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
#
55
# Generate a TLS certificate file to use with stunnel etc.
66
#
7-
8-
DIR=/tmp/ssl-generation-$$
7+
set -e
98
FILE=$1
109
CN=$2
11-
12-
if [ -z "${CN}" ]; then
10+
set -eu
11+
if [ -z "${CN}" -o -z "${FILE}" ]; then
1312
echo "usage: $0 <certname> <cn>"
1413
exit 2
1514
fi
@@ -22,8 +21,12 @@ fi
2221
dnsnames=$((hostname -A; hostname -f) | sort | uniq)
2322
addresses=$(hostname -I | sort | uniq)
2423
25-
mkdir -p ${DIR}
26-
chmod 700 ${DIR}
24+
DIR=$(mktemp -d tls-cert-generation-XXXXXXXXXX --tmpdir)
25+
26+
function cleanup {
27+
rm -rf "${DIR}"
28+
}
29+
trap cleanup ERR EXIT
2730
2831
pushd ${DIR}
2932
@@ -72,10 +75,20 @@ openssl dhparam 512 > dh.pem
7275
7376
popd
7477
75-
(cat ${DIR}/privkey.rsa; echo ""; cat ${DIR}/signedpubcert.pem; \
76-
echo ""; cat ${DIR}/dh.pem) > ${FILE}
77-
chmod 400 ${FILE}
78+
tmpcert="${DIR}/tmpcertcombined.pem"
7879
79-
rm -rf ${DIR}
80+
(cat ${DIR}/privkey.rsa; echo ""; cat ${DIR}/signedpubcert.pem; \
81+
echo ""; cat ${DIR}/dh.pem) > "${tmpcert}"
82+
83+
# Set up tmpcert the way we want it, then use mv to ensure that FILE
84+
# appears as an atomic event.
85+
chmod 400 "${tmpcert}"
86+
mv --no-clobber "${tmpcert}" "${FILE}"
87+
# Now check whether the mv succeeded (since it returns a 0 exit-code even if FILE existed already).
88+
if [ -e "${tmpcert}" ]; then
89+
# It still exists in original location: it has not been moved.
90+
echo "File has been created just now by someone else: cannot overwrite";
91+
exit 3 # Rely on the EXIT trap to clean up.
92+
fi
8093
81-
exit 0
94+
exit 0 # Rely on the EXIT trap to clean up.

0 commit comments

Comments
 (0)