1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
use crate::encoding::{
headers::{Authorization, WWWAuthenticate},
method::Method,
request::Request,
response::Response,
uri::Uri,
};
use anyhow::Result;
impl Authorization {
pub fn construct(
request: &Request,
failed_response: &Response,
username: &str,
password: &str,
) -> Result<Authorization> {
let challenge = failed_response.headers.get_res::<WWWAuthenticate>()?;
Ok(Authorization {
response: response_digest(
username.to_string(),
challenge.realm.clone(),
password.to_string(),
request.method,
challenge.nonce.clone(),
request.uri.clone(),
),
nonce: challenge.nonce,
realm: challenge.realm,
uri: request.uri.to_string(),
username: username.to_string(),
})
}
}
fn response_digest(
username: String,
realm: String,
password: String,
method: Method,
nonce: String,
uri: Uri,
) -> String {
let h = |s: String| hex::encode(md5::compute(s.as_bytes()).0);
let kd = |secret, data| h(format!("{secret}:{data}"));
let a1 = format!("{username}:{realm}:{password}");
let a2 = format!("{method}:{uri}");
let response_digest = kd(h(a1), format!("{nonce}:{}", h(a2)));
return response_digest;
}
|