diff --git a/scripts/capture-dsh-token.sh b/scripts/capture-dsh-token.sh index 0f1f532..d0a87e9 100755 --- a/scripts/capture-dsh-token.sh +++ b/scripts/capture-dsh-token.sh @@ -10,6 +10,7 @@ # 6. Reloads nginx set -euo pipefail +umask 077 # Kill any existing dsh-web instance first systemctl stop dsh-web 2>/dev/null || true @@ -39,18 +40,36 @@ fi # Extract the token value (everything after "?token=") TOKEN_VALUE=$(echo "$TOKEN" | grep -oP "(?<=token=)[^ ]+") -# Write the token to a file +# Reject tokens that could break nginx config or the request URI +if ! printf '%s' "$TOKEN_VALUE" | grep -qE '^[A-Za-z0-9._~+/=%:@-]+$'; then + echo "ERROR: token contains unsupported characters" >&2 + exit 1 +fi + +# Write the token to a restricted file mkdir -p /etc/dsh-web -echo "$TOKEN_VALUE" > /etc/dsh-web/launch-token -echo "Captured token: $TOKEN_VALUE" +printf '%s\n' "$TOKEN_VALUE" > /etc/dsh-web/launch-token +chmod 600 /etc/dsh-web/launch-token +echo "Captured dsh-web launch token" # Create the nginx config with the token (using printf to control expansion) +NGINX_ENABLED="/etc/nginx/sites-enabled/dsh.token" +NGINX_STAGE_DIR="/etc/nginx/sites-available" +mkdir -p "$NGINX_STAGE_DIR" + +TMP_CONFIG="$(mktemp "$NGINX_STAGE_DIR/dsh.token.XXXXXX")" +BACKUP="" +if [ -f "$NGINX_ENABLED" ]; then + BACKUP="$(mktemp "$NGINX_STAGE_DIR/dsh.token.bak.XXXXXX")" + cp -p "$NGINX_ENABLED" "$BACKUP" +fi + { printf "server {\n" - printf " listen 8081;\n" + printf " listen 127.0.0.1:8081;\n" printf " server_name _;\n" printf " \n" - printf " location /dsh-web-login {\n" + printf " location = /dsh-web-login {\n" printf " proxy_pass http://127.0.0.1:3080/?token=%s;\n" "$TOKEN_VALUE" printf " proxy_http_version 1.1;\n" printf " proxy_set_header Host 127.0.0.1:3080;\n" @@ -66,12 +85,28 @@ echo "Captured token: $TOKEN_VALUE" printf " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n" printf " }\n" printf "}\n" -} > /etc/nginx/sites-enabled/dsh.token +} > "$TMP_CONFIG" +chmod 600 "$TMP_CONFIG" -# Reload nginx -nginx -t && /usr/sbin/nginx -s reload || { - echo "ERROR: failed to reload nginx" >&2 - exit 1 +mv "$TMP_CONFIG" "$NGINX_ENABLED" +CONFIG_APPLIED=1 +restore_on_exit() { + if [ "$CONFIG_APPLIED" -eq 1 ]; then + if [ -n "$BACKUP" ]; then + if cp -p "$BACKUP" "$NGINX_ENABLED" 2>/dev/null; then rm -f "$BACKUP"; fi + else + rm -f "$NGINX_ENABLED" + fi + fi } +trap restore_on_exit EXIT -echo "Token captured and nginx reloaded" +if nginx -t; then + /usr/sbin/nginx -s reload + CONFIG_APPLIED=0 + if [ -n "$BACKUP" ]; then rm -f "$BACKUP"; fi + echo "Token captured and nginx reloaded" +else + echo "ERROR: nginx config test failed; rolling back" >&2 + exit 1 +fi diff --git a/zulip-health.prose.md b/zulip-health.prose.md index cc47dcb..c6dff2a 100644 --- a/zulip-health.prose.md +++ b/zulip-health.prose.md @@ -292,9 +292,14 @@ The script: ssh root@192.168.68.15 "pct exec 112 -- curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8081/dsh-web-login" # Expected: 303 -# Check if the cookie works: -ssh root@192.168.68.15 "pct exec 112 -- curl -s -o /dev/null -w '%{http_code}' -b 'dsh-auth-*' http://127.0.0.1:3080/" -# Expected: 200 (after the cookie has been set) +# Mint the 30-day cookie from the login endpoint: +ssh root@192.168.68.15 "pct exec 112 -- rm -f /tmp/dsh.jar" +ssh root@192.168.68.15 "pct exec 112 -- curl -s -c /tmp/dsh.jar -o /dev/null -w '%{http_code}' http://127.0.0.1:8081/dsh-web-login" +# Expected: 303 + +# Check if the stored cookie authenticates against dsh-web: +ssh root@192.168.68.15 "pct exec 112 -- curl -s -b /tmp/dsh.jar -o /dev/null -w '%{http_code}' http://127.0.0.1:3080/" +# Expected: 200 ```