mod.rs

  1use crate::common::Identity;
  2use crate::secret::Secret;
  3use std::fmt;
  4
  5#[cfg(feature = "scram")]
  6use crate::common::scram::DeriveError;
  7
  8#[macro_export]
  9macro_rules! impl_validator_using_provider {
 10    ( $validator:ty, $secret:ty ) => {
 11        impl $crate::server::Validator<$secret> for $validator {
 12            fn validate(
 13                &self,
 14                identity: &$crate::common::Identity,
 15                value: &$secret,
 16            ) -> Result<(), $crate::server::ValidatorError> {
 17                if $crate::server::Provider::<$secret>::provide(self, identity).is_ok() {
 18                    Ok(())
 19                } else {
 20                    Err($crate::server::ValidatorError::AuthenticationFailed)
 21                }
 22            }
 23        }
 24    };
 25}
 26
 27pub trait Provider<S: Secret>: Validator<S> {
 28    fn provide(&self, identity: &Identity) -> Result<S, ProviderError>;
 29}
 30
 31pub trait Validator<S: Secret> {
 32    fn validate(&self, identity: &Identity, value: &S) -> Result<(), ValidatorError>;
 33}
 34
 35#[derive(Debug, PartialEq)]
 36pub enum ProviderError {
 37    AuthenticationFailed,
 38    #[cfg(feature = "scram")]
 39    DeriveError(DeriveError),
 40}
 41
 42#[derive(Debug, PartialEq)]
 43pub enum ValidatorError {
 44    AuthenticationFailed,
 45    ProviderError(ProviderError),
 46}
 47
 48#[derive(Debug, PartialEq)]
 49pub enum MechanismError {
 50    NoUsernameSpecified,
 51    ErrorDecodingUsername,
 52    NoPasswordSpecified,
 53    ErrorDecodingPassword,
 54    ValidatorError(ValidatorError),
 55
 56    FailedToDecodeMessage,
 57    ChannelBindingNotSupported,
 58    ChannelBindingIsSupported,
 59    ChannelBindingMechanismIncorrect,
 60    CannotDecodeInitialMessage,
 61    NoUsername,
 62    NoNonce,
 63    FailedToGenerateNonce,
 64    ProviderError(ProviderError),
 65
 66    CannotDecodeResponse,
 67    #[cfg(feature = "scram")]
 68    InvalidKeyLength(hmac::digest::InvalidLength),
 69    #[cfg(any(feature = "scram", feature = "anonymous"))]
 70    RandomFailure(getrandom::Error),
 71    NoProof,
 72    CannotDecodeProof,
 73    AuthenticationFailed,
 74    SaslSessionAlreadyOver,
 75}
 76
 77#[cfg(feature = "scram")]
 78impl From<DeriveError> for ProviderError {
 79    fn from(err: DeriveError) -> ProviderError {
 80        ProviderError::DeriveError(err)
 81    }
 82}
 83
 84impl From<ProviderError> for ValidatorError {
 85    fn from(err: ProviderError) -> ValidatorError {
 86        ValidatorError::ProviderError(err)
 87    }
 88}
 89
 90impl From<ProviderError> for MechanismError {
 91    fn from(err: ProviderError) -> MechanismError {
 92        MechanismError::ProviderError(err)
 93    }
 94}
 95
 96impl From<ValidatorError> for MechanismError {
 97    fn from(err: ValidatorError) -> MechanismError {
 98        MechanismError::ValidatorError(err)
 99    }
100}
101
102#[cfg(feature = "scram")]
103impl From<hmac::digest::InvalidLength> for MechanismError {
104    fn from(err: hmac::digest::InvalidLength) -> MechanismError {
105        MechanismError::InvalidKeyLength(err)
106    }
107}
108
109#[cfg(any(feature = "scram", feature = "anonymous"))]
110impl From<getrandom::Error> for MechanismError {
111    fn from(err: getrandom::Error) -> MechanismError {
112        MechanismError::RandomFailure(err)
113    }
114}
115
116impl fmt::Display for ProviderError {
117    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
118        write!(fmt, "provider error")
119    }
120}
121
122impl fmt::Display for ValidatorError {
123    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
124        write!(fmt, "validator error")
125    }
126}
127
128impl fmt::Display for MechanismError {
129    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
130        match self {
131            MechanismError::NoUsernameSpecified => write!(fmt, "no username specified"),
132            MechanismError::ErrorDecodingUsername => write!(fmt, "error decoding username"),
133            MechanismError::NoPasswordSpecified => write!(fmt, "no password specified"),
134            MechanismError::ErrorDecodingPassword => write!(fmt, "error decoding password"),
135            MechanismError::ValidatorError(err) => write!(fmt, "validator error: {}", err),
136
137            MechanismError::FailedToDecodeMessage => write!(fmt, "failed to decode message"),
138            MechanismError::ChannelBindingNotSupported => {
139                write!(fmt, "channel binding not supported")
140            }
141            MechanismError::ChannelBindingIsSupported => {
142                write!(fmt, "channel binding is supported")
143            }
144            MechanismError::ChannelBindingMechanismIncorrect => {
145                write!(fmt, "channel binding mechanism is incorrect")
146            }
147            MechanismError::CannotDecodeInitialMessage => {
148                write!(fmt, "can’t decode initial message")
149            }
150            MechanismError::NoUsername => write!(fmt, "no username"),
151            MechanismError::NoNonce => write!(fmt, "no nonce"),
152            MechanismError::FailedToGenerateNonce => write!(fmt, "failed to generate nonce"),
153            MechanismError::ProviderError(err) => write!(fmt, "provider error: {}", err),
154
155            MechanismError::CannotDecodeResponse => write!(fmt, "can’t decode response"),
156            #[cfg(feature = "scram")]
157            MechanismError::InvalidKeyLength(err) => write!(fmt, "invalid key length: {}", err),
158            #[cfg(any(feature = "scram", feature = "anonymous"))]
159            MechanismError::RandomFailure(err) => {
160                write!(fmt, "failure to get random data: {}", err)
161            }
162            MechanismError::NoProof => write!(fmt, "no proof"),
163            MechanismError::CannotDecodeProof => write!(fmt, "can’t decode proof"),
164            MechanismError::AuthenticationFailed => write!(fmt, "authentication failed"),
165            MechanismError::SaslSessionAlreadyOver => write!(fmt, "SASL session already over"),
166        }
167    }
168}
169
170impl Error for ProviderError {}
171
172impl Error for ValidatorError {}
173
174use std::error::Error;
175impl Error for MechanismError {
176    fn source(&self) -> Option<&(dyn Error + 'static)> {
177        match self {
178            MechanismError::ValidatorError(err) => Some(err),
179            MechanismError::ProviderError(err) => Some(err),
180            // TODO: figure out how to enable the std feature on this crate.
181            //MechanismError::InvalidKeyLength(err) => Some(err),
182            _ => None,
183        }
184    }
185}
186
187pub trait Mechanism {
188    fn name(&self) -> &str;
189    fn respond(&mut self, payload: &[u8]) -> Result<Response, MechanismError>;
190}
191
192#[derive(Debug, Clone, PartialEq, Eq)]
193pub enum Response {
194    Success(Identity, Vec<u8>),
195    Proceed(Vec<u8>),
196}
197
198pub mod mechanisms;