Expand description
HTTP Basic authentication helpers shared by the H1 and H2 mux paths.
The runtime stores credentials as username:hex(sha256(password))
entries on each cluster’s authorized_hashes. On every request that
traverses a frontend with required_auth = true, the mux extracts the
Authorization: Basic <token> header from the front kawa, decodes the
base64 token, splits on the first : into <user>:<password>, hashes
the password with SHA-256, and rebuilds the canonical
<user>:<hex(sha256)> form. Comparison against the cluster’s hash list
uses subtle::ConstantTimeEq over a full pass, never short-circuiting,
so the time spent validating a credential does not leak which slot
matched (or whether any did at all).
The extractor is intentionally permissive (Option-returning) — any
malformed input is reported as “no credential”, and the caller emits
the standard 401 response. We never panic on hostile input.
Functions§
- canonicalize_
basic_ credentials - Decode a
Basic <token>value into the canonicalusername:hex(sha256(password))shape thatcheck_authorized_hashescompares against. ReturnsNonefor any malformed input — wrong scheme, non-base64 token, missing:, non-UTF-8 username, or oversized payload. - check_
authorized_ hashes - Compare
candidateagainst every entry inauthorized_hashesusing constant-time equality. Returnstrueif any entry matches. - check_
basic - Convenience: pull
Authorizationfrom the kawa, canonicalise, and compare in constant time against the authorized list. - extract_
authorization_ header - Find the first
Authorizationheader value in the front kawa. - set_
max_ decoded_ credential_ bytes - Install the operator-configured cap. Called from
lib::server::Server::try_new_from_configexactly once per worker process. Subsequent calls are no-ops (theOnceLockrejects the secondset); the first wins. A0value is treated as “use the built-in default” so an operator config that explicitly sets0does not disable Basic-auth length-bound protection by accident.