From 3a802eb193d0ba473cd9bdcc52bce656258c6e54 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sat, 25 Dec 2021 16:15:08 +0100 Subject: [PATCH] Implement SASL ANONYMOUS on the server side Fixes #11. --- sasl/src/server/mechanisms/anonymous.rs | 28 +++++++++++++++++++++++++ sasl/src/server/mechanisms/mod.rs | 2 ++ sasl/src/server/mod.rs | 10 +++++++++ 3 files changed, 40 insertions(+) create mode 100644 sasl/src/server/mechanisms/anonymous.rs diff --git a/sasl/src/server/mechanisms/anonymous.rs b/sasl/src/server/mechanisms/anonymous.rs new file mode 100644 index 0000000..1ee311b --- /dev/null +++ b/sasl/src/server/mechanisms/anonymous.rs @@ -0,0 +1,28 @@ +use crate::common::Identity; +use crate::server::{Mechanism, MechanismError, Response}; +use getrandom::getrandom; + +pub struct Anonymous; + +impl Anonymous { + pub fn new() -> Anonymous { + Anonymous + } +} + +impl Mechanism for Anonymous { + fn name(&self) -> &str { + "ANONYMOUS" + } + + fn respond(&mut self, payload: &[u8]) -> Result { + if !payload.is_empty() { + return Err(MechanismError::FailedToDecodeMessage); + } + let mut rand = [0u8; 16]; + getrandom(&mut rand)?; + let username = format!("{:02x?}", rand); + let ident = Identity::Username(username); + Ok(Response::Success(ident, Vec::new())) + } +} diff --git a/sasl/src/server/mechanisms/mod.rs b/sasl/src/server/mechanisms/mod.rs index 7718102..9d4c9a5 100644 --- a/sasl/src/server/mechanisms/mod.rs +++ b/sasl/src/server/mechanisms/mod.rs @@ -1,7 +1,9 @@ +mod anonymous; mod plain; #[cfg(feature = "scram")] mod scram; +pub use self::anonymous::Anonymous; pub use self::plain::Plain; #[cfg(feature = "scram")] pub use self::scram::Scram; diff --git a/sasl/src/server/mod.rs b/sasl/src/server/mod.rs index 8d1bece..5ee233c 100644 --- a/sasl/src/server/mod.rs +++ b/sasl/src/server/mod.rs @@ -62,6 +62,7 @@ pub enum MechanismError { CannotDecodeResponse, InvalidKeyLength(hmac::digest::InvalidLength), + RandomFailure(getrandom::Error), NoProof, CannotDecodeProof, AuthenticationFailed, @@ -98,6 +99,12 @@ impl From for MechanismError { } } +impl From for MechanismError { + fn from(err: getrandom::Error) -> MechanismError { + MechanismError::RandomFailure(err) + } +} + impl fmt::Display for ProviderError { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "provider error") @@ -139,6 +146,9 @@ impl fmt::Display for MechanismError { MechanismError::CannotDecodeResponse => write!(fmt, "can’t decode response"), MechanismError::InvalidKeyLength(err) => write!(fmt, "invalid key length: {}", err), + MechanismError::RandomFailure(err) => { + write!(fmt, "failure to get random data: {}", err) + } MechanismError::NoProof => write!(fmt, "no proof"), MechanismError::CannotDecodeProof => write!(fmt, "can’t decode proof"), MechanismError::AuthenticationFailed => write!(fmt, "authentication failed"),