150 lines
4.5 KiB
Bash
Executable file
150 lines
4.5 KiB
Bash
Executable file
#!/bin/bash
|
|
# Provision the scoped GCP staging role without placing its cleartext password
|
|
# in SQL text, argv, command history, or PostgreSQL statement logs.
|
|
set +x
|
|
set -euo pipefail
|
|
umask 077
|
|
ulimit -c 0
|
|
|
|
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
export PATH
|
|
runtime_password=${TELEO_LEOCLEAN_DB_PASSWORD-}
|
|
administrator_password=${PGPASSWORD-}
|
|
unset TELEO_LEOCLEAN_DB_PASSWORD PGPASSWORD
|
|
|
|
script_path=${BASH_SOURCE[0]}
|
|
case "$script_path" in
|
|
*/*) script_directory=${script_path%/*} ;;
|
|
*) script_directory=. ;;
|
|
esac
|
|
SCRIPT_DIR="$(cd -- "$script_directory" && pwd -P)"
|
|
SQL_FILE="$SCRIPT_DIR/gcp_leoclean_runtime_role.sql"
|
|
SERVER_CA_FILE="$SCRIPT_DIR/gcp-teleo-pgvector-standby-server-ca.pem"
|
|
PSQL_BIN=/usr/bin/psql
|
|
SETSID_BIN=/usr/bin/setsid
|
|
ENV_BIN=/usr/bin/env
|
|
SHA256SUM_BIN=/usr/bin/sha256sum
|
|
SERVER_CA_SHA256=80701e768f0e1f6b9d621aa0b53f6e851daaa276c6d9a8e51a300fbc015539cb
|
|
|
|
assert_root_owned_nonwritable() {
|
|
local target="$1" state uid mode
|
|
state="$(stat -Lc '%u:%a' -- "$target")"
|
|
uid=${state%%:*}
|
|
mode=${state#*:}
|
|
if [ "$uid" != 0 ] || (( (8#$mode & 8#022) != 0 )); then
|
|
echo "Refusing an untrusted PostgreSQL executable path." >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
assert_trusted_executable() {
|
|
local requested="$1" resolved current
|
|
[ -x "$requested" ] || {
|
|
echo "Required PostgreSQL client is unavailable." >&2
|
|
return 1
|
|
}
|
|
resolved="$(readlink -f -- "$requested")"
|
|
[ -n "$resolved" ] && [ -f "$resolved" ] && [ -x "$resolved" ] || {
|
|
echo "Required PostgreSQL client did not resolve to an executable file." >&2
|
|
return 1
|
|
}
|
|
assert_root_owned_nonwritable "$requested"
|
|
current="$(dirname "$requested")"
|
|
while :; do
|
|
assert_root_owned_nonwritable "$current"
|
|
[ "$current" = / ] && break
|
|
current="$(dirname "$current")"
|
|
done
|
|
current="$resolved"
|
|
while :; do
|
|
assert_root_owned_nonwritable "$current"
|
|
[ "$current" = / ] && break
|
|
current="$(dirname "$current")"
|
|
done
|
|
}
|
|
|
|
if [ ! -f "$SQL_FILE" ] || [ -L "$SQL_FILE" ] || [ ! -f "$SERVER_CA_FILE" ] || [ -L "$SERVER_CA_FILE" ]; then
|
|
echo "Reviewed GCP runtime-role SQL is unavailable." >&2
|
|
exit 66
|
|
fi
|
|
assert_trusted_executable "$PSQL_BIN"
|
|
assert_trusted_executable "$SETSID_BIN"
|
|
assert_trusted_executable "$ENV_BIN"
|
|
assert_trusted_executable "$SHA256SUM_BIN"
|
|
if [ "$("$SHA256SUM_BIN" "$SERVER_CA_FILE")" != "$SERVER_CA_SHA256 $SERVER_CA_FILE" ]; then
|
|
echo "Reviewed Cloud SQL server CA does not match the pinned certificate." >&2
|
|
exit 66
|
|
fi
|
|
|
|
if [ -z "$runtime_password" ] || [ "${#runtime_password}" -gt 4096 ]; then
|
|
echo "TELEO_LEOCLEAN_DB_PASSWORD must contain a bounded nonempty value." >&2
|
|
exit 64
|
|
fi
|
|
case "$runtime_password" in
|
|
*$'\n'*|*$'\r'*)
|
|
echo "TELEO_LEOCLEAN_DB_PASSWORD must not contain line breaks." >&2
|
|
exit 64
|
|
;;
|
|
esac
|
|
if [ -z "$administrator_password" ] || [ "${#administrator_password}" -gt 4096 ]; then
|
|
echo "PGPASSWORD must contain a bounded nonempty administrator credential." >&2
|
|
exit 64
|
|
fi
|
|
case "$administrator_password" in
|
|
*$'\n'*|*$'\r'*)
|
|
echo "PGPASSWORD must not contain line breaks." >&2
|
|
exit 64
|
|
;;
|
|
esac
|
|
cleanup_password() {
|
|
runtime_password=
|
|
administrator_password=
|
|
unset runtime_password administrator_password
|
|
}
|
|
provision_pid=
|
|
terminate_provisioning() {
|
|
local exit_status="$1"
|
|
trap - INT TERM
|
|
if [[ "$provision_pid" =~ ^[1-9][0-9]*$ ]]; then
|
|
kill -TERM -- "-$provision_pid" 2>/dev/null || kill -TERM -- "$provision_pid" 2>/dev/null || true
|
|
wait "$provision_pid" 2>/dev/null || true
|
|
provision_pid=
|
|
fi
|
|
cleanup_password
|
|
exit "$exit_status"
|
|
}
|
|
trap cleanup_password EXIT
|
|
trap 'terminate_provisioning 130' INT
|
|
trap 'terminate_provisioning 143' TERM
|
|
|
|
# \password encrypts client-side. --no-password ensures an administrator-login
|
|
# prompt cannot consume either of the two runtime-password records from stdin.
|
|
# setsid detaches psql from any controlling terminal without --fork, keeping
|
|
# its PID as the session/process-group leader so an interruption can terminate
|
|
# and reap the complete credential-bearing child before this wrapper returns.
|
|
{
|
|
printf '%s\n' "$runtime_password"
|
|
printf '%s\n' "$runtime_password"
|
|
} | "$ENV_BIN" -i \
|
|
PATH="$PATH" \
|
|
LANG=C LC_ALL=C \
|
|
PYTHONNOUSERSITE=1 PYTHONSAFEPATH=1 \
|
|
PGHOST=10.61.0.3 \
|
|
PGPORT=5432 \
|
|
PGDATABASE=teleo_canonical \
|
|
PGUSER=postgres \
|
|
PGPASSWORD="$administrator_password" \
|
|
PGSSLMODE=verify-ca \
|
|
PGSSLROOTCERT="$SERVER_CA_FILE" \
|
|
"$SETSID_BIN" -- "$PSQL_BIN" \
|
|
--no-psqlrc \
|
|
--no-password \
|
|
--set=ON_ERROR_STOP=1 \
|
|
--file="$SQL_FILE" &
|
|
provision_pid=$!
|
|
set +e
|
|
wait "$provision_pid"
|
|
status=$?
|
|
set -e
|
|
provision_pid=
|
|
exit "$status"
|