mirror of https://gitlab.com/xmpp-rs/xmpp-rs.git
118 lines
3.7 KiB
Rust
118 lines
3.7 KiB
Rust
use std::fmt;
|
|
|
|
use crate::common::Credentials;
|
|
|
|
#[cfg(feature = "scram")]
|
|
use crate::common::scram::DeriveError;
|
|
#[cfg(feature = "scram")]
|
|
use hmac::digest::InvalidLength;
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
pub enum MechanismError {
|
|
AnonymousRequiresNoCredentials,
|
|
|
|
PlainRequiresUsername,
|
|
PlainRequiresPlaintextPassword,
|
|
|
|
CannotGenerateNonce,
|
|
ScramRequiresUsername,
|
|
ScramRequiresPassword,
|
|
|
|
CannotDecodeChallenge,
|
|
NoServerNonce,
|
|
NoServerSalt,
|
|
NoServerIterations,
|
|
#[cfg(feature = "scram")]
|
|
DeriveError(DeriveError),
|
|
#[cfg(feature = "scram")]
|
|
InvalidKeyLength(InvalidLength),
|
|
InvalidState,
|
|
|
|
CannotDecodeSuccessResponse,
|
|
InvalidSignatureInSuccessResponse,
|
|
NoSignatureInSuccessResponse,
|
|
}
|
|
|
|
#[cfg(feature = "scram")]
|
|
#[cfg_attr(docsrs, doc(cfg(feature = "scram")))]
|
|
impl From<DeriveError> for MechanismError {
|
|
fn from(err: DeriveError) -> MechanismError {
|
|
MechanismError::DeriveError(err)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "scram")]
|
|
#[cfg_attr(docsrs, doc(cfg(feature = "scram")))]
|
|
impl From<InvalidLength> for MechanismError {
|
|
fn from(err: InvalidLength) -> 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",
|
|
#[cfg(feature = "scram")]
|
|
MechanismError::DeriveError(err) => return write!(fmt, "derive error: {}", err),
|
|
#[cfg(feature = "scram")]
|
|
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 {}
|
|
|
|
/// A trait which defines SASL mechanisms.
|
|
pub trait Mechanism {
|
|
/// The name of the mechanism.
|
|
fn name(&self) -> &str;
|
|
|
|
/// Creates this mechanism from `Credentials`.
|
|
fn from_credentials(credentials: Credentials) -> Result<Self, MechanismError>
|
|
where
|
|
Self: Sized;
|
|
|
|
/// Provides initial payload of the SASL mechanism.
|
|
fn initial(&mut self) -> Vec<u8> {
|
|
Vec::new()
|
|
}
|
|
|
|
/// Creates a response to the SASL challenge.
|
|
fn response(&mut self, _challenge: &[u8]) -> Result<Vec<u8>, MechanismError> {
|
|
Ok(Vec::new())
|
|
}
|
|
|
|
/// Verifies the server success response, if there is one.
|
|
fn success(&mut self, _data: &[u8]) -> Result<(), MechanismError> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub mod mechanisms;
|