Struct DigestClient

Source
pub struct DigestClient { /* private fields */ }
Available on crate feature 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 each DigestClient::respond call. It’d be more CPU-efficient to calculate H(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 and Proxy-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 the charset parameter. The RFC only allows that parameter to be set to UTF-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

Source

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.)

Source

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.

Source

pub fn nonce(&self) -> &str

Returns the nonce, a server-specified string which should be uniquely generated each time a 401 response is made.

Source

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.

Source

pub fn stale(&self) -> bool

Returns a flag indicating that the previous request from the client was rejected because the nonce value was stale.

Source

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.

Source

pub fn algorithm(&self) -> Algorithm

Returns the algorithm used to produce the digest and an unkeyed digest.

Source

pub fn session(&self) -> bool

Returns if the session style A1 will be used.

Source

pub fn qop(&self) -> QopSet

Returns the acceptable qop (quality of protection) values.

Source

pub fn nonce_count(&self) -> u32

Returns the number of times the server-supplied nonce has been used by DigestClient::respond.

Source

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.

Source

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.

Trait Implementations§

Source§

impl Debug for DigestClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for DigestClient

Source§

fn eq(&self, other: &DigestClient) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl TryFrom<&ChallengeRef<'_>> for DigestClient

Source§

type Error = String

The type returned in the event of a conversion error.
Source§

fn try_from(value: &ChallengeRef<'_>) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl Eq for DigestClient

Source§

impl StructuralPartialEq for DigestClient

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V