lldap/server/src/infra/ldap_server.rs

101 lines
3.3 KiB
Rust
Raw Normal View History

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;
use actix_server::ServerBuilder;
use actix_service::{fn_service, ServiceFactoryExt};
use anyhow::{bail, Context, Result};
use futures_util::future::ok;
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>,
session: &mut LdapHandler<Backend>,
2021-06-16 20:04:11 +00:00
) -> Result<bool>
where
Backend: BackendHandler + LoginHandler + OpaqueHandler,
2021-06-16 20:04:11 +00:00
{
2021-03-07 15:13:50 +00:00
use futures_util::SinkExt;
let msg = msg.context("while receiving LDAP op")?;
debug!("Received LDAP message: {:?}", &msg);
match session.handle_ldap_message(msg.op).await {
2021-03-07 15:13:50 +00:00
None => return Ok(false),
Some(result) => {
2021-11-07 13:57:34 +00:00
if result.is_empty() {
debug!("No response");
}
for result_op in result.into_iter() {
debug!("Replying with LDAP op: {:?}", &result_op);
resp.send(LdapMsg {
msgid: msg.msgid,
op: result_op,
ctrl: vec![],
})
.await
.context("while sending a response: {:#}")?
2021-03-07 15:13:50 +00:00
}
if let Err(e) = resp.flush().await {
bail!("Error while flushing responses: {:?}", e);
}
}
}
Ok(true)
}
pub fn build_ldap_server<Backend>(
config: &Configuration,
backend_handler: Backend,
server_builder: ServerBuilder,
) -> Result<ServerBuilder>
where
Backend: BackendHandler + LoginHandler + OpaqueHandler + 'static,
{
2021-03-06 22:39:34 +00:00
use futures_util::StreamExt;
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();
Ok(
server_builder.bind("ldap", ("0.0.0.0", config.ldap_port), move || {
let backend_handler = backend_handler.clone();
let ldap_base_dn = ldap_base_dn.clone();
2021-04-07 18:14:21 +00:00
let ldap_user_dn = ldap_user_dn.clone();
fn_service(move |mut stream: TcpStream| {
let backend_handler = backend_handler.clone();
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-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-06 22:39:34 +00:00
}