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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use crate::common::Credentials;
use crate::common::scram::DeriveError;
use std::fmt;
use hmac::crypto_mac::InvalidKeyLength;
#[derive(Debug, PartialEq)]
pub enum MechanismError {
AnonymousRequiresNoCredentials,
PlainRequiresUsername,
PlainRequiresPlaintextPassword,
CannotGenerateNonce,
ScramRequiresUsername,
ScramRequiresPassword,
CannotDecodeChallenge,
NoServerNonce,
NoServerSalt,
NoServerIterations,
DeriveError(DeriveError),
InvalidKeyLength(InvalidKeyLength),
InvalidState,
CannotDecodeSuccessResponse,
InvalidSignatureInSuccessResponse,
NoSignatureInSuccessResponse,
}
impl From<DeriveError> for MechanismError {
fn from(err: DeriveError) -> MechanismError {
MechanismError::DeriveError(err)
}
}
impl From<InvalidKeyLength> for MechanismError {
fn from(err: InvalidKeyLength) -> MechanismError {
MechanismError::InvalidKeyLength(err)
}
}
impl fmt::Display for MechanismError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{}", match self {
MechanismError::AnonymousRequiresNoCredentials => "ANONYMOUS mechanism requires no credentials",
MechanismError::PlainRequiresUsername => "PLAIN requires a username",
MechanismError::PlainRequiresPlaintextPassword => "PLAIN requires a plaintext password",
MechanismError::CannotGenerateNonce => "can't generate nonce",
MechanismError::ScramRequiresUsername => "SCRAM requires a username",
MechanismError::ScramRequiresPassword => "SCRAM requires a password",
MechanismError::CannotDecodeChallenge => "can't decode challenge",
MechanismError::NoServerNonce => "no server nonce",
MechanismError::NoServerSalt => "no server salt",
MechanismError::NoServerIterations => "no server iterations",
MechanismError::DeriveError(err) => return write!(fmt, "derive error: {}", err),
MechanismError::InvalidKeyLength(err) => return write!(fmt, "invalid key length: {}", err),
MechanismError::InvalidState => "not in the right state to receive this response",
MechanismError::CannotDecodeSuccessResponse => "can't decode success response",
MechanismError::InvalidSignatureInSuccessResponse => "invalid signature in success response",
MechanismError::NoSignatureInSuccessResponse => "no signature in success response",
})
}
}
impl std::error::Error for MechanismError {}
pub trait Mechanism {
fn name(&self) -> &str;
fn from_credentials(credentials: Credentials) -> Result<Self, MechanismError> where Self: Sized;
fn initial(&mut self) -> Vec<u8> {
Vec::new()
}
fn response(&mut self, _challenge: &[u8]) -> Result<Vec<u8>, MechanismError> {
Ok(Vec::new())
}
fn success(&mut self, _data: &[u8]) -> Result<(), MechanismError> {
Ok(())
}
}
pub mod mechanisms;