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
52
use super::{AuthMethod, Dict};
use crate::error::Error;
use std::marker::PhantomData;
const CRA_AUTH_METHOD_ID: &str = "wampcra";
struct WAMPCra<F, E>(F, PhantomData<E>)
where
F: FnMut(&str) -> Result<Vec<u8>, E>,
E: std::error::Error + Sync + Send + 'static;
impl<F, E> AuthMethod for WAMPCra<F, E>
where
F: FnMut(&str) -> Result<Vec<u8>, E>,
E: std::error::Error + Sync + Send + 'static,
{
fn auth_method(&self) -> &str {
CRA_AUTH_METHOD_ID
}
fn challenge(&mut self, auth_id: &str, extra: &Dict) -> Result<(String, Dict), Error> {
use hmac::Mac;
let challenge = match extra
.get("challenge")
.and_then(|challenge| challenge.as_str())
{
Some(challenge) => challenge,
None => return Err(Error::protocol_err("missing challenge field")),
};
let secret = self.0(auth_id)?;
let mut hmac = hmac::Hmac::<sha2::Sha256>::new_varkey(secret.as_ref())?;
hmac.input(challenge.as_bytes());
let r = hmac.result().code();
Ok((base64::encode(&r), Dict::default()))
}
}
pub fn challenge_response_auth<SecretProvider, Err>(
secret_provider: SecretProvider,
) -> impl AuthMethod + Sync + Send + 'static
where
SecretProvider: FnMut(&str) -> Result<Vec<u8>, Err> + Sync + Send + 'static,
Err: std::error::Error + Sync + Send + 'static,
{
WAMPCra(secret_provider, PhantomData)
}