2021-10-28 16:04:09 +00:00
|
|
|
use crate::{
|
|
|
|
domain::{
|
|
|
|
handler::{BackendHandler, LoginHandler},
|
|
|
|
opaque_handler::OpaqueHandler,
|
|
|
|
},
|
|
|
|
infra::{configuration::Configuration, ldap_handler::LdapHandler},
|
|
|
|
};
|
2021-03-06 22:39:34 +00:00
|
|
|
use actix_rt::net::TcpStream;
|
2021-03-07 11:36:12 +00:00
|
|
|
use actix_server::ServerBuilder;
|
2021-05-08 11:27:48 +00:00
|
|
|
use actix_service::{fn_service, ServiceFactoryExt};
|
2021-10-24 09:03:09 +00:00
|
|
|
use anyhow::{anyhow, bail, Result};
|
2021-03-07 11:36:12 +00:00
|
|
|
use futures_util::future::ok;
|
2021-10-24 09:03:09 +00:00
|
|
|
use ldap3_server::{proto::LdapMsg, LdapCodec};
|
2021-03-06 22:39:34 +00:00
|
|
|
use log::*;
|
2021-03-07 15:13:50 +00:00
|
|
|
use tokio::net::tcp::WriteHalf;
|
|
|
|
use tokio_util::codec::{FramedRead, FramedWrite};
|
2021-03-06 22:39:34 +00:00
|
|
|
|
2021-06-16 20:04:11 +00:00
|
|
|
async fn handle_incoming_message<Backend>(
|
2021-03-07 15:13:50 +00:00
|
|
|
msg: Result<LdapMsg, std::io::Error>,
|
|
|
|
resp: &mut FramedWrite<WriteHalf<'_>, LdapCodec>,
|
2021-03-11 09:14:15 +00:00
|
|
|
session: &mut LdapHandler<Backend>,
|
2021-06-16 20:04:11 +00:00
|
|
|
) -> Result<bool>
|
|
|
|
where
|
2021-10-28 16:04:09 +00:00
|
|
|
Backend: BackendHandler + LoginHandler + OpaqueHandler,
|
2021-06-16 20:04:11 +00:00
|
|
|
{
|
2021-03-07 15:13:50 +00:00
|
|
|
use futures_util::SinkExt;
|
2021-10-24 09:03:09 +00:00
|
|
|
let msg = msg.map_err(|e| anyhow!("Error while receiving LDAP op: {:#}", e))?;
|
|
|
|
match session.handle_ldap_message(msg.op).await {
|
2021-03-07 15:13:50 +00:00
|
|
|
None => return Ok(false),
|
|
|
|
Some(result) => {
|
2021-10-24 09:03:09 +00:00
|
|
|
for result_op in result.into_iter() {
|
|
|
|
if let Err(e) = resp
|
|
|
|
.send(LdapMsg {
|
|
|
|
msgid: msg.msgid,
|
|
|
|
op: result_op,
|
|
|
|
ctrl: vec![],
|
|
|
|
})
|
|
|
|
.await
|
|
|
|
{
|
2021-03-07 15:13:50 +00:00
|
|
|
bail!("Error while sending a response: {:?}", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Err(e) = resp.flush().await {
|
|
|
|
bail!("Error while flushing responses: {:?}", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(true)
|
|
|
|
}
|
|
|
|
|
2021-03-11 09:14:15 +00:00
|
|
|
pub fn build_ldap_server<Backend>(
|
2021-03-07 11:36:12 +00:00
|
|
|
config: &Configuration,
|
2021-03-11 09:14:15 +00:00
|
|
|
backend_handler: Backend,
|
2021-03-07 11:36:12 +00:00
|
|
|
server_builder: ServerBuilder,
|
2021-03-11 09:14:15 +00:00
|
|
|
) -> Result<ServerBuilder>
|
|
|
|
where
|
2021-10-28 16:04:09 +00:00
|
|
|
Backend: BackendHandler + LoginHandler + OpaqueHandler + 'static,
|
2021-03-11 09:14:15 +00:00
|
|
|
{
|
2021-03-06 22:39:34 +00:00
|
|
|
use futures_util::StreamExt;
|
|
|
|
|
2021-03-16 17:27:31 +00:00
|
|
|
let ldap_base_dn = config.ldap_base_dn.clone();
|
2021-04-07 18:14:21 +00:00
|
|
|
let ldap_user_dn = config.ldap_user_dn.clone();
|
2021-03-07 11:36:12 +00:00
|
|
|
Ok(
|
|
|
|
server_builder.bind("ldap", ("0.0.0.0", config.ldap_port), move || {
|
2021-03-11 09:14:15 +00:00
|
|
|
let backend_handler = backend_handler.clone();
|
2021-03-16 17:27:31 +00:00
|
|
|
let ldap_base_dn = ldap_base_dn.clone();
|
2021-04-07 18:14:21 +00:00
|
|
|
let ldap_user_dn = ldap_user_dn.clone();
|
2021-05-08 11:27:48 +00:00
|
|
|
fn_service(move |mut stream: TcpStream| {
|
2021-03-11 09:14:15 +00:00
|
|
|
let backend_handler = backend_handler.clone();
|
2021-03-16 17:27:31 +00:00
|
|
|
let ldap_base_dn = ldap_base_dn.clone();
|
2021-04-07 18:14:21 +00:00
|
|
|
let ldap_user_dn = ldap_user_dn.clone();
|
2021-03-07 15:13:50 +00:00
|
|
|
async move {
|
|
|
|
// Configure the codec etc.
|
|
|
|
let (r, w) = stream.split();
|
|
|
|
let mut requests = FramedRead::new(r, LdapCodec);
|
|
|
|
let mut resp = FramedWrite::new(w, LdapCodec);
|
2021-03-06 22:39:34 +00:00
|
|
|
|
2021-04-07 18:14:21 +00:00
|
|
|
let mut session = LdapHandler::new(backend_handler, ldap_base_dn, ldap_user_dn);
|
2021-03-06 22:39:34 +00:00
|
|
|
|
2021-03-07 15:13:50 +00:00
|
|
|
while let Some(msg) = requests.next().await {
|
|
|
|
if !handle_incoming_message(msg, &mut resp, &mut session).await? {
|
|
|
|
break;
|
2021-03-06 22:39:34 +00:00
|
|
|
}
|
2021-03-07 15:13:50 +00:00
|
|
|
}
|
2021-03-06 22:39:34 +00:00
|
|
|
|
2021-03-07 15:13:50 +00:00
|
|
|
Ok(stream)
|
|
|
|
}
|
2021-05-08 11:27:48 +00:00
|
|
|
})
|
2021-03-07 15:13:50 +00:00
|
|
|
.map_err(|err: anyhow::Error| error!("Service Error: {:?}", err))
|
2021-03-06 22:39:34 +00:00
|
|
|
// catch
|
|
|
|
.and_then(move |_| {
|
|
|
|
// finally
|
|
|
|
ok(())
|
|
|
|
})
|
2021-03-07 11:36:12 +00:00
|
|
|
})?,
|
|
|
|
)
|
2021-03-06 22:39:34 +00:00
|
|
|
}
|