forked from wangbo/easyai
122 lines
3.9 KiB
Bash
Executable File
122 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=scripts/init-security-env.sh
|
|
. "${SCRIPT_DIR}/init-security-env.sh"
|
|
|
|
TMP_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
write_env() {
|
|
local file="$1"
|
|
shift
|
|
printf '%s\n' "$@" > "$file"
|
|
}
|
|
|
|
assert_min_length() {
|
|
local file="$1"
|
|
local key="$2"
|
|
local minimum="$3"
|
|
local value
|
|
value="$(read_env_value "$file" "$key")"
|
|
[ "${#value}" -ge "$minimum" ] || fail "$key must contain at least $minimum characters"
|
|
}
|
|
|
|
assert_value() {
|
|
local file="$1"
|
|
local key="$2"
|
|
local expected="$3"
|
|
local actual
|
|
actual="$(read_env_value "$file" "$key")"
|
|
[ "$actual" = "$expected" ] || fail "$key expected '$expected', got '$actual'"
|
|
}
|
|
|
|
assert_single_key() {
|
|
local file="$1"
|
|
local key="$2"
|
|
local count
|
|
count="$(grep -c "^${key}=" "$file" || true)"
|
|
[ "$count" -eq 1 ] || fail "$key must appear exactly once"
|
|
}
|
|
|
|
file_sha256() {
|
|
local file="$1"
|
|
if command -v sha256sum >/dev/null 2>&1; then
|
|
sha256sum "$file" | awk '{print $1}'
|
|
else
|
|
shasum -a 256 "$file" | awk '{print $1}'
|
|
fi
|
|
}
|
|
|
|
upgrade_env="$TMP_DIR/upgrade.env"
|
|
upgrade_log="$TMP_DIR/upgrade.log"
|
|
write_env "$upgrade_env" \
|
|
"CONFIG_JWT_SECRET='this is a very secret secret'" \
|
|
"CONFIG_SECURITY_CONFIG_ENCRYPTION_KEY=" \
|
|
"WS_AUTH_WS_TICKET_SECRET=" \
|
|
"WS_AUTH_METHODS=none,bearer"
|
|
init_security_env "$upgrade_env" upgrade > "$upgrade_log"
|
|
|
|
assert_min_length "$upgrade_env" "CONFIG_JWT_SECRET" 32
|
|
assert_min_length "$upgrade_env" "WS_AUTH_WS_TICKET_SECRET" 32
|
|
assert_value "$upgrade_env" "CONFIG_SECURITY_CONFIG_ENCRYPTION_KEY" ""
|
|
assert_value "$upgrade_env" "WS_AUTH_METHODS" "none,bearer,ws_ticket"
|
|
assert_single_key "$upgrade_env" "WS_AUTH_WS_TICKET_SECRET"
|
|
assert_single_key "$upgrade_env" "WS_AUTH_METHODS"
|
|
|
|
upgrade_jwt="$(read_env_value "$upgrade_env" "CONFIG_JWT_SECRET")"
|
|
upgrade_ws="$(read_env_value "$upgrade_env" "WS_AUTH_WS_TICKET_SECRET")"
|
|
if grep -Fq "$upgrade_jwt" "$upgrade_log" || grep -Fq "$upgrade_ws" "$upgrade_log"; then
|
|
fail "security initialization output must not reveal generated secrets"
|
|
fi
|
|
|
|
before_repeat="$(file_sha256 "$upgrade_env")"
|
|
init_security_env "$upgrade_env" upgrade > "$TMP_DIR/repeat.log"
|
|
after_repeat="$(file_sha256 "$upgrade_env")"
|
|
[ "$before_repeat" = "$after_repeat" ] || fail "repeated upgrade must preserve generated values byte-for-byte"
|
|
|
|
preserved_secret="existing-ws-ticket-secret-that-is-long-enough"
|
|
preserved_env="$TMP_DIR/preserved.env"
|
|
write_env "$preserved_env" \
|
|
"CONFIG_JWT_SECRET=existing-jwt-secret-that-is-long-enough" \
|
|
"WS_AUTH_WS_TICKET_SECRET=$preserved_secret" \
|
|
"WS_AUTH_METHODS=bearer,ws_ticket"
|
|
init_security_env "$preserved_env" upgrade > "$TMP_DIR/preserved.log"
|
|
assert_value "$preserved_env" "WS_AUTH_WS_TICKET_SECRET" "$preserved_secret"
|
|
assert_value "$preserved_env" "WS_AUTH_METHODS" "bearer,ws_ticket"
|
|
|
|
new_env="$TMP_DIR/new.env"
|
|
write_env "$new_env" \
|
|
"CONFIG_JWT_SECRET=" \
|
|
"CONFIG_SECURITY_CONFIG_ENCRYPTION_KEY=" \
|
|
"CONFIG_OTP_HASH_SECRET=" \
|
|
"CONFIG_AUDIT_HASH_PEPPER=" \
|
|
"CONFIG_AUDIT_INTEGRITY_KEY=" \
|
|
"CONFIG_INITIAL_ADMIN_PASSWORD=" \
|
|
"WS_AUTH_WS_TICKET_SECRET=" \
|
|
"WS_AUTH_METHODS="
|
|
init_security_env "$new_env" new > "$TMP_DIR/new.log"
|
|
for key in \
|
|
CONFIG_JWT_SECRET \
|
|
CONFIG_SECURITY_CONFIG_ENCRYPTION_KEY \
|
|
CONFIG_OTP_HASH_SECRET \
|
|
CONFIG_AUDIT_HASH_PEPPER \
|
|
CONFIG_AUDIT_INTEGRITY_KEY \
|
|
WS_AUTH_WS_TICKET_SECRET; do
|
|
assert_min_length "$new_env" "$key" 32
|
|
done
|
|
assert_min_length "$new_env" "CONFIG_INITIAL_ADMIN_PASSWORD" 12
|
|
assert_value "$new_env" "WS_AUTH_METHODS" "none,bearer,ws_ticket"
|
|
|
|
mode="$(stat -c '%a' "$new_env" 2>/dev/null || stat -f '%Lp' "$new_env")"
|
|
[ "$mode" = "600" ] || fail "generated environment file mode must be 600, got $mode"
|
|
|
|
echo "Security environment shell tests passed"
|