mod.rs

  1use std::fmt;
  2
  3use crate::common::Credentials;
  4
  5#[cfg(feature = "scram")]
  6use crate::common::scram::DeriveError;
  7#[cfg(feature = "scram")]
  8use hmac::digest::InvalidLength;
  9
 10#[derive(Debug, PartialEq)]
 11pub enum MechanismError {
 12    AnonymousRequiresNoCredentials,
 13
 14    PlainRequiresUsername,
 15    PlainRequiresPlaintextPassword,
 16
 17    CannotGenerateNonce,
 18    ScramRequiresUsername,
 19    ScramRequiresPassword,
 20
 21    CannotDecodeChallenge,
 22    NoServerNonce,
 23    NoServerSalt,
 24    NoServerIterations,
 25    #[cfg(feature = "scram")]
 26    DeriveError(DeriveError),
 27    #[cfg(feature = "scram")]
 28    InvalidKeyLength(InvalidLength),
 29    InvalidState,
 30
 31    CannotDecodeSuccessResponse,
 32    InvalidSignatureInSuccessResponse,
 33    NoSignatureInSuccessResponse,
 34}
 35
 36#[cfg(feature = "scram")]
 37impl From<DeriveError> for MechanismError {
 38    fn from(err: DeriveError) -> MechanismError {
 39        MechanismError::DeriveError(err)
 40    }
 41}
 42
 43#[cfg(feature = "scram")]
 44impl From<InvalidLength> for MechanismError {
 45    fn from(err: InvalidLength) -> MechanismError {
 46        MechanismError::InvalidKeyLength(err)
 47    }
 48}
 49
 50impl fmt::Display for MechanismError {
 51    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 52        write!(
 53            fmt,
 54            "{}",
 55            match self {
 56                MechanismError::AnonymousRequiresNoCredentials =>
 57                    "ANONYMOUS mechanism requires no credentials",
 58
 59                MechanismError::PlainRequiresUsername => "PLAIN requires a username",
 60                MechanismError::PlainRequiresPlaintextPassword =>
 61                    "PLAIN requires a plaintext password",
 62
 63                MechanismError::CannotGenerateNonce => "can't generate nonce",
 64                MechanismError::ScramRequiresUsername => "SCRAM requires a username",
 65                MechanismError::ScramRequiresPassword => "SCRAM requires a password",
 66
 67                MechanismError::CannotDecodeChallenge => "can't decode challenge",
 68                MechanismError::NoServerNonce => "no server nonce",
 69                MechanismError::NoServerSalt => "no server salt",
 70                MechanismError::NoServerIterations => "no server iterations",
 71                #[cfg(feature = "scram")]
 72                MechanismError::DeriveError(err) => return write!(fmt, "derive error: {}", err),
 73                #[cfg(feature = "scram")]
 74                MechanismError::InvalidKeyLength(err) =>
 75                    return write!(fmt, "invalid key length: {}", err),
 76                MechanismError::InvalidState => "not in the right state to receive this response",
 77
 78                MechanismError::CannotDecodeSuccessResponse => "can't decode success response",
 79                MechanismError::InvalidSignatureInSuccessResponse =>
 80                    "invalid signature in success response",
 81                MechanismError::NoSignatureInSuccessResponse => "no signature in success response",
 82            }
 83        )
 84    }
 85}
 86
 87impl std::error::Error for MechanismError {}
 88
 89/// A trait which defines SASL mechanisms.
 90pub trait Mechanism {
 91    /// The name of the mechanism.
 92    fn name(&self) -> &str;
 93
 94    /// Creates this mechanism from `Credentials`.
 95    fn from_credentials(credentials: Credentials) -> Result<Self, MechanismError>
 96    where
 97        Self: Sized;
 98
 99    /// Provides initial payload of the SASL mechanism.
100    fn initial(&mut self) -> Vec<u8> {
101        Vec::new()
102    }
103
104    /// Creates a response to the SASL challenge.
105    fn response(&mut self, _challenge: &[u8]) -> Result<Vec<u8>, MechanismError> {
106        Ok(Vec::new())
107    }
108
109    /// Verifies the server success response, if there is one.
110    fn success(&mut self, _data: &[u8]) -> Result<(), MechanismError> {
111        Ok(())
112    }
113}
114
115pub mod mechanisms;