module

Krikri::PluginHelpers::PostgresqlPasswordVerifier

PostgresqlPasswordVerifier - pure logic for postgresql_user's idempotency decision (see plugins/postgresql_user.cr): whether a desired password differs from the role's stored verifier, ported from real community.postgresql.postgresql_user's user_should_we_change_password() so a repeat call with an unchanged password reports changed: false instead of reissuing ALTER ROLE.

SCRAM-SHA-256 verifiers store a salted, iterated hash, so the stored value can never be compared to the plaintext directly; instead the ServerKey is recomputed client-side from the plaintext and the salt/iteration count parsed out of the stored verifier (RFC 5802: SaltedPassword = Hi(password, salt, i), ServerKey = HMAC(SaltedPassword, "Server Key")) - the same comparison the real module performs. Pre-hashed inputs (a SCRAM verifier string or an "md5" + 32-hex digest) are compared verbatim; a plaintext password against a server whose default is md5 computes PostgreSQL's own 'md5' + md5(password + username) form. Like the real module, an unreadable-but-existing current value that is neither SCRAM nor md5 against a scram-sha-256-default server always counts as changed (the verifier cannot be recomputed without the salt).

Constants

SCRAM_SHA256_REGEX = /^SCRAM-SHA-256\$(\d+):([A-Za-z0-9+\/=]+)\$([A-Za-z0-9+\/=]+):([A-Za-z0-9+\/=]+)$/

PostgreSQL's own pg_authid.rolpassword format: SCRAM-SHA-256$<iterations>:<salt b64>$<StoredKey b64>:<ServerKey b64>

Class methods

md5_verifier(user : String, plaintext : String) : String
Source
md5_verifier_format?(value : String) : Bool

Real module's is_pg_passwd_md5: "md5" prefix + 32 hex digits.

Source
needs_change?(current : String | Nil, desired : String | Nil, user : String, server_encryption : String) : Bool
Source
scram_verifier_matches?(stored : Regex::MatchData, plaintext : String) : Bool

Recomputes the stored verifier's ServerKey from the plaintext. The password is hashed verbatim - exactly what the server hashed when the verifier was created (no saslprep, matching CREATE USER/ALTER ROLE's own verifier generation; saslprep only applies during SASL authentication itself). A malformed verifier falls back to "different" - the real module's same except-clause.

Source