pub struct DigestClient { /* private fields */ }
digest-scheme
only.Expand description
Client for a Digest
challenge, as in RFC 7616.
This can be constructed by the TryFrom<&ChallengeRef<'_>>
impl. However,
in most cases this client should be used only indirectly through the more
abstract crate::PasswordClient
.
Most of the information here is taken from the WWW-Authenticate
or
Proxy-Authenticate
header. This also internally maintains a nonce counter.
§Implementation notes
- Recalculates
H(A1)
on eachDigestClient::respond
call. It’d be more CPU-efficient to calculateH(A1)
only once by supplying the username and password at construction time or by caching (username, password) ->H(A1)
mappings internally.DigestClient
prioritizes simplicity instead. - There’s no support yet for parsing the
Authentication-Info
andProxy-Authentication-Info
header fields described by RFC 7616 section 3.5. PRs welcome! - Always responds using
UTF-8
, and thus doesn’t use or keep around thecharset
parameter. The RFC only allows that parameter to be set toUTF-8
anyway. - Supports RFC 2069 compatibility as in RFC 2617 section 3.2.2.1, even though RFC 7616 drops it. There are still RTSP cameras being sold in 2021 that use the RFC 2069-style calculations.
- Supports RFC 7616
userhash
, even though it seems impractical and only marginally useful. The server must index the userhash for each supported algorithm or calculate it on-the-fly for all users in the database. - The
-sess
algorithm variants haven’t been tested; there’s no example in the RFCs.
§Security considerations
We strongly advise servers against implementing Digest
:
- It’s actively harmful in that it prevents the server from securing their
password storage via salted password hashes. See RFC 7616 Section
5.2.
When your server offers
Digest
authentication, it is advertising that it stores plaintext passwords! - It’s no replacement for TLS in terms of protecting confidentiality of the password, much less confidentiality of any other information.
For clients, when a server supports both Digest
and Basic
, we advise
using Digest
. It provides (slightly) more confidentiality of passwords
over the wire.
Some servers only support Digest
. E.g.,
ONVIF mandates the
Digest
scheme. It doesn’t prohibit implementing other schemes, but some
cameras meet the specification’s requirement and do no more.
Implementations§
Source§impl DigestClient
impl DigestClient
Sourcepub fn realm(&self) -> &str
pub fn realm(&self) -> &str
Returns a string to be displayed to users so they know which username and password to use.
This string should contain at least the name of
the host performing the authentication and might additionally
indicate the collection of users who might have access. An
example is registered_users@example.com
. (See Section 2.2 of
RFC 7235 for
more details.)
Sourcepub fn domain(&self) -> &str
pub fn domain(&self) -> &str
Returns the domain, a space-separated list of URIs, as specified in RFC 3986, that define the protection space.
If the domain parameter is absent, returns an empty string, which is semantically identical according to the RFC.
Sourcepub fn nonce(&self) -> &str
pub fn nonce(&self) -> &str
Returns the nonce, a server-specified string which should be uniquely generated each time a 401 response is made.
Sourcepub fn opaque(&self) -> Option<&str>
pub fn opaque(&self) -> Option<&str>
Returns string of data, specified by the server, that SHOULD be returned by the client unchanged in the Authorization header field of subsequent requests with URIs in the same protection space.
Currently an empty opaque
is treated as an absent one.
Sourcepub fn stale(&self) -> bool
pub fn stale(&self) -> bool
Returns a flag indicating that the previous request from the client was rejected because the nonce value was stale.
Sourcepub fn rfc2069_compat(&self) -> bool
pub fn rfc2069_compat(&self) -> bool
Returns true if using RFC 2069 compatibility mode as in RFC 2617 section 3.2.2.1.
If so, request-digest
is calculated without the nonce count, conce, or qop.
Sourcepub fn algorithm(&self) -> Algorithm
pub fn algorithm(&self) -> Algorithm
Returns the algorithm used to produce the digest and an unkeyed digest.
Sourcepub fn nonce_count(&self) -> u32
pub fn nonce_count(&self) -> u32
Returns the number of times the server-supplied nonce has been used by
DigestClient::respond
.
Sourcepub fn respond(&mut self, p: &PasswordParams<'_>) -> Result<String, String>
pub fn respond(&mut self, p: &PasswordParams<'_>) -> Result<String, String>
Responds to the challenge with the supplied parameters.
The caller should use the returned string as an Authorization
or
Proxy-Authorization
header value.
Sourcepub fn respond_with_testing_cnonce(
&mut self,
p: &PasswordParams<'_>,
cnonce: &str,
) -> Result<String, String>
pub fn respond_with_testing_cnonce( &mut self, p: &PasswordParams<'_>, cnonce: &str, ) -> Result<String, String>
Responds using a fixed cnonce for testing only.
In production code, use DigestClient::respond
instead, which generates a new
random cnonce value.