~whynothugo/vdirsyncer-rs#31: 
Support digest Auth

The main steps involved in Digest authentication are as follows:

  • Client sends a request to the server that requires authentication.
  • Server responds with a 401 Unauthorized status code and provides a "WWW-Authenticate" header that includes the authentication realm and other required information.
  • The client resends the request with the "Authorization" header, which includes a hashed value of the user's credentials.
Status
REPORTED
Submitter
~whynothugo
Assigned to
No-one
Submitted
6 months ago
Updated
6 months ago
Labels
No labels applied.

~whynothugo 6 months ago*

Quite untested:

use ring::digest;

fn calculate_digest(username: &str, realm: &str, password: &str, method: &str, uri: &str, nonce: &str, cnonce: &str) -> String {
    let ha1 = format!("{}:{}:{}", username, realm, password);
    let ha1_digest = digest::digest(&digest::MD5, ha1.as_bytes());

    let ha2 = format!("{}:{}", method, uri);
    let ha2_digest = digest::digest(&digest::MD5, ha2.as_bytes());

    let response = format!("{:x}:{nonce}:{nc}:{cnonce}:{qop}:{ha2}", ha1_digest, nonce, "00000001", cnonce, "auth", ha2_digest);
    let response_digest = digest::digest(&digest::MD5, response.as_bytes());

    format!("{:x}", response_digest)
}

fn main() {
    let username = "alice";
    let realm = "realm";
    let password = "password";
    let method = "GET";
    let uri = "/path";
    let nonce = "1234567890";
    let cnonce = "0987654321";

    let digest = calculate_digest(username, realm, password, method, uri, nonce, cnonce);
    println!("Digest: {}", digest);
}

The main pain point is the extra request to get the WWW-Authenticate header with the realm and stuff. I wonder if this can be done in a separate step or something (e.g. have the value ready before sync).

Register here or Log in to comment, or comment via email.