Steps towards encryption
- Added certstore and retrieval of the local trust root. - Major work on keeping the context between calls to the milter. - Added a context for an email in processing - Added Husk specific errors
This commit is contained in:
+42
-24
@@ -25,13 +25,15 @@ use indymilter::{
|
||||
};
|
||||
|
||||
use crate::types::husk_context::HuskContext;
|
||||
use crate::config::HuskConfig;
|
||||
use crate::config::{HuskConfig, HuskConfigContainer};
|
||||
|
||||
pub struct Daemon { }
|
||||
|
||||
impl Daemon {
|
||||
|
||||
pub async fn run(config: &HuskConfig) -> anyhow::Result<()> {
|
||||
pub async fn run(config_container: HuskConfigContainer) -> anyhow::Result<()> {
|
||||
|
||||
let config: HuskConfig = config_container.clone().into();
|
||||
|
||||
let listener = TcpListener::bind(&config.connection)
|
||||
.await
|
||||
@@ -40,7 +42,7 @@ impl Daemon {
|
||||
let callbacks = Callbacks::new()
|
||||
.on_negotiate(|cx, actions, opts| Box::pin(Self::handle_negotiate(cx, actions, opts)))
|
||||
.on_connect(|cx, hostname, socket_info| Box::pin(Self::handle_connect(cx, hostname, socket_info)))
|
||||
.on_helo(|cx, hostname| Box::pin(Self::handle_helo(cx, hostname)))
|
||||
.on_helo(move |cx, hostname| Box::pin(Self::handle_helo(cx, config_container.clone(), hostname)))
|
||||
.on_mail(|cx, args| Box::pin(Self::handle_mail(cx, args)))
|
||||
.on_rcpt(|cx, args| Box::pin(Self::handle_rcpt(cx, args)))
|
||||
.on_data(|cx| Box::pin(Self::handle_data(cx)))
|
||||
@@ -62,7 +64,7 @@ impl Daemon {
|
||||
}
|
||||
|
||||
async fn handle_negotiate(
|
||||
_cx: &mut NegotiateContext<HuskContext>,
|
||||
_cx: &mut NegotiateContext<HuskContext<'_>>,
|
||||
actions: Actions,
|
||||
opts: ProtoOpts,
|
||||
) -> Status {
|
||||
@@ -72,7 +74,7 @@ impl Daemon {
|
||||
}
|
||||
|
||||
async fn handle_connect(
|
||||
_cx: &mut Context<HuskContext>,
|
||||
_cx: &mut Context<HuskContext<'_>>,
|
||||
hostname: CString,
|
||||
socket_info: SocketInfo,
|
||||
) -> Status {
|
||||
@@ -82,15 +84,28 @@ impl Daemon {
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_helo(_cx: &mut Context<HuskContext>, hostname: CString) -> Status {
|
||||
async fn handle_helo(cx: &mut Context<HuskContext<'_>>, config_container: HuskConfigContainer, hostname: CString) -> Status {
|
||||
log::debug!("HELO: hostname: {hostname:?}");
|
||||
|
||||
Status::Continue
|
||||
let config: HuskConfig = config_container.into();
|
||||
|
||||
// setup Context
|
||||
match HuskContext::new(&config) {
|
||||
Ok(context) => {
|
||||
cx.data = Some(context).take();
|
||||
Status::Continue
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("{}", e);
|
||||
Status::Tempfail
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_mail(cx: &mut Context<HuskContext>, args: Vec<CString>) -> Status {
|
||||
async fn handle_mail(cx: &mut Context<HuskContext<'_>>, args: Vec<CString>) -> Status {
|
||||
log::debug!("MAIL: {args:?}");
|
||||
|
||||
// XXX
|
||||
let sender = match args.first() {
|
||||
Some(cs) => {
|
||||
match cs.to_str() {
|
||||
@@ -101,68 +116,71 @@ impl Daemon {
|
||||
None => { "missing".to_string() }
|
||||
};
|
||||
|
||||
// setup Context
|
||||
if let Some(mut context) = HuskContext::new() {
|
||||
if let Some(ref mut context) = cx.data {
|
||||
context.set_sender(sender);
|
||||
cx.data = Some(context).take();
|
||||
Status::Continue
|
||||
} else {
|
||||
Status::Tempfail
|
||||
}
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_rcpt(_cx: &mut Context<HuskContext>, args: Vec<CString>) -> Status {
|
||||
async fn handle_rcpt(cx: &mut Context<HuskContext<'_>>, args: Vec<CString>) -> Status {
|
||||
log::debug!("RCPT: {args:?}");
|
||||
|
||||
if let Some(ref mut context) = cx.data {
|
||||
|
||||
}
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_data(_cx: &mut Context<HuskContext>) -> Status {
|
||||
async fn handle_data(_cx: &mut Context<HuskContext<'_>>) -> Status {
|
||||
log::debug!("DATA");
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_header(_cx: &mut Context<HuskContext>, name: CString, value: CString) -> Status {
|
||||
async fn handle_header(_cx: &mut Context<HuskContext<'_>>, name: CString, value: CString) -> Status {
|
||||
log::debug!("HEADER: {name:?} = {value:?}");
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_eoh(_cx: &mut Context<HuskContext>) -> Status {
|
||||
async fn handle_eoh(_cx: &mut Context<HuskContext<'_>>) -> Status {
|
||||
log::debug!("EOH");
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_body(_cx: &mut Context<HuskContext>, chunk: Bytes) -> Status {
|
||||
async fn handle_body(_cx: &mut Context<HuskContext<'_>>, chunk: Bytes) -> Status {
|
||||
log::debug!("BODY: chunk with {:?} bytes received", &chunk.len());
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_eom(cx: &mut EomContext<HuskContext>) -> Status {
|
||||
async fn handle_eom(cx: &mut EomContext<HuskContext<'_>>) -> Status {
|
||||
log::debug!("EOM");
|
||||
|
||||
if let Some(ref mut context_data) = cx.data {
|
||||
log::debug!("Mail from {:?} complete", context_data.sender);
|
||||
if let Some(ref mut context) = cx.data {
|
||||
log::debug!("Mail from {:?} complete", context.mail.sender);
|
||||
}
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_abort(_cx: &mut Context<HuskContext>) -> Status {
|
||||
async fn handle_abort(_cx: &mut Context<HuskContext<'_>>) -> Status {
|
||||
log::debug!("ABORT");
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_close(_cx: &mut Context<HuskContext>) -> Status {
|
||||
async fn handle_close(_cx: &mut Context<HuskContext<'_>>) -> Status {
|
||||
log::debug!("CLOSE");
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_unknown(_cx: &mut Context<HuskContext>, arg: CString) -> Status {
|
||||
async fn handle_unknown(_cx: &mut Context<HuskContext<'_>>, arg: CString) -> Status {
|
||||
log::debug!("UNKNOWN: {arg:?}");
|
||||
|
||||
Status::Continue
|
||||
|
||||
Reference in New Issue
Block a user