2022-03-15 20:00:43 +01:00
|
|
|
|
2022-03-15 17:52:47 +01:00
|
|
|
use crate::users::Users;
|
2022-03-15 20:00:43 +01:00
|
|
|
use rsasl::error::{SessionError};
|
2022-03-12 01:27:58 +01:00
|
|
|
use rsasl::mechname::Mechname;
|
2022-03-15 17:52:47 +01:00
|
|
|
use rsasl::property::{AuthId, Password};
|
2022-03-13 22:50:37 +01:00
|
|
|
use rsasl::session::{Session, SessionData};
|
2022-03-15 17:52:47 +01:00
|
|
|
use rsasl::validate::{validations, Validation};
|
2022-03-15 20:00:43 +01:00
|
|
|
use rsasl::{SASL};
|
2022-03-15 17:52:47 +01:00
|
|
|
use std::sync::Arc;
|
2022-03-08 18:52:49 +01:00
|
|
|
|
2022-03-13 22:50:37 +01:00
|
|
|
struct Callback {
|
|
|
|
users: Users,
|
|
|
|
}
|
|
|
|
impl Callback {
|
|
|
|
pub fn new(users: Users) -> Self {
|
2022-03-15 17:52:47 +01:00
|
|
|
Self { users }
|
2022-03-13 22:50:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
impl rsasl::callback::Callback for Callback {
|
2022-03-15 17:52:47 +01:00
|
|
|
fn validate(
|
|
|
|
&self,
|
|
|
|
session: &mut SessionData,
|
|
|
|
validation: Validation,
|
2022-03-15 20:00:43 +01:00
|
|
|
_mechanism: &Mechname,
|
2022-03-15 17:52:47 +01:00
|
|
|
) -> Result<(), SessionError> {
|
|
|
|
match validation {
|
|
|
|
validations::SIMPLE => {
|
|
|
|
let authnid = session
|
|
|
|
.get_property::<AuthId>()
|
|
|
|
.ok_or(SessionError::no_property::<AuthId>())?;
|
|
|
|
let user = self
|
|
|
|
.users
|
|
|
|
.get_user(authnid.as_str())
|
|
|
|
.ok_or(SessionError::AuthenticationFailure)?;
|
|
|
|
let passwd = session
|
|
|
|
.get_property::<Password>()
|
|
|
|
.ok_or(SessionError::no_property::<Password>())?;
|
|
|
|
|
|
|
|
if user
|
|
|
|
.check_password(passwd.as_bytes())
|
2022-03-15 20:00:43 +01:00
|
|
|
.map_err(|_e| SessionError::AuthenticationFailure)?
|
2022-03-15 17:52:47 +01:00
|
|
|
{
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(SessionError::AuthenticationFailure)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => Err(SessionError::no_validate(validation)),
|
|
|
|
}
|
2022-03-13 22:50:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-12 01:27:58 +01:00
|
|
|
struct Inner {
|
|
|
|
rsasl: SASL,
|
|
|
|
}
|
|
|
|
impl Inner {
|
|
|
|
pub fn new(rsasl: SASL) -> Self {
|
|
|
|
Self { rsasl }
|
|
|
|
}
|
|
|
|
}
|
2022-03-10 20:52:34 +01:00
|
|
|
|
2022-03-12 01:27:58 +01:00
|
|
|
#[derive(Clone)]
|
2022-03-12 17:31:53 +01:00
|
|
|
pub struct AuthenticationHandle {
|
2022-03-12 01:27:58 +01:00
|
|
|
inner: Arc<Inner>,
|
2022-03-10 20:52:34 +01:00
|
|
|
}
|
|
|
|
|
2022-03-12 17:31:53 +01:00
|
|
|
impl AuthenticationHandle {
|
2022-03-13 22:50:37 +01:00
|
|
|
pub fn new(userdb: Users) -> Self {
|
|
|
|
let mut rsasl = SASL::new();
|
|
|
|
rsasl.install_callback(Arc::new(Callback::new(userdb)));
|
2022-03-15 17:52:47 +01:00
|
|
|
Self {
|
|
|
|
inner: Arc::new(Inner::new(rsasl)),
|
|
|
|
}
|
2022-03-12 01:27:58 +01:00
|
|
|
}
|
2022-03-10 20:52:34 +01:00
|
|
|
|
2022-03-12 17:31:53 +01:00
|
|
|
pub fn start(&self, mechanism: &Mechname) -> anyhow::Result<Session> {
|
|
|
|
Ok(self.inner.rsasl.server_start(mechanism)?)
|
|
|
|
}
|
|
|
|
|
2022-03-15 17:52:47 +01:00
|
|
|
pub fn list_available_mechs(&self) -> impl IntoIterator<Item = &Mechname> {
|
|
|
|
self.inner
|
|
|
|
.rsasl
|
|
|
|
.server_mech_list()
|
|
|
|
.into_iter()
|
|
|
|
.map(|m| m.mechanism)
|
2022-03-12 01:27:58 +01:00
|
|
|
}
|
2022-03-15 17:52:47 +01:00
|
|
|
}
|