fix(scram): replace hand-rolled SCRAM client with postgres-protocol - #8
Conversation
…ScramSha256
The hand-rolled SCRAM-SHA-256 client in src/scram.rs built a malformed
client-final-message: it omitted the mandatory `p=` prefix on the proof
attribute (RFC 5802 §5.1), so the wire bytes were
`c=biws,r=NONCE,<base64proof>` instead of `c=biws,r=NONCE,p=<base64proof>`.
The CNPG backend rejected every connection with FATAL 08P01
"malformed SCRAM message — Expected character '=' for attribute 'Y'",
and the proxy then mis-decoded the resulting ErrorResponse as a SASL
frame ("expected R, got 45"), closing the client with an opaque
"early eof". Every connection from fn-cli through the proxy failed.
Replaces the entire src/scram.rs (~440 LOC of hand-rolled crypto) with
postgres-protocol::authentication::sasl::ScramSha256 — sfackler's
battle-tested implementation that powers tokio-postgres in production.
The three small SASL wire-framing helpers (write_sasl_initial_response,
write_sasl_response, read_sasl_auth_message) move into src/wire.rs
where the rest of the wire framing already lives, with byte-layout
unit tests.
After successful SASL exchange the new code explicitly reads the
AuthenticationOk (type 0) message before falling through to the
parameter-status drain loop, so the loop does not have to silently
swallow an `R` frame.
Drops now-unused crypto dependencies: hmac, sha2, base64. Keeps rand
(still used for BackendKeyData PIDs in proxy.rs).
|
coder (round 3): CI checks passed (e47aa7d) — all green: fmt, clippy, unit tests. Ready for review. |
|
pr-review-lead (round 4): PR Review: fix/scram-postgres-protocol5 reviewers ran — code, principles, silent-failure-hunter, test-analyzer, comment-analyzer. ✅ Critical Issues — None✅ Important Issues — None💡 Suggestions (3 found)
Strengths
VERDICT: LGTMAll suggestions are optional quality improvements — none block merge. |
- Add unit tests for read_sasl_auth_message error paths: wrong tag byte and auth_type mismatch - Add missing debug log on CleartextPassword auth success - Improve read_sasl_auth_message doc comment to list all three SASL auth type values explicitly
|
coder (round 5): Triage UpdateFixed
Remaining
All 3 suggestions addressed. CI green: fmt ✓ clippy ✓ 9 tests ✓. Ready to merge. |
Summary
src/scram.rs:67constructed the SCRAM client-final-message without thep=prefix on the proof attribute. Backend rejected every connection with08P01 malformed SCRAM message, then the proxy mis-decoded the ErrorResponse and reported "early eof" to the client.postgres-protocol = "0.6.11"and useScramSha256(the same impltokio-postgresuses in production).src/wire.rswith unit tests. Crypto depshmac,sha2,base64are dropped.Verification plan (post-merge)
CI builds and pushes the image; then:
kubectl -n supa-dev rollout restart deploy/pgwire-supabase-proxyauthenticated | supabase(NOT "server closed the connection unexpectedly").ttal log psp— should showclient authenticated,backend SCRAM-SHA-256 auth complete,session ready — entering byte-forward mode, and on disconnect a cleanconnection closedwith non-zero byte counts.If step 2/3 fails,
kubectl rollout undo deploy/pgwire-supabase-proxyand re-open the task.