Start collecting recipients
- Collect recipients for processed email. - Add proper email parsing
This commit is contained in:
+29
-13
@@ -26,6 +26,7 @@ use indymilter::{
|
||||
|
||||
use crate::types::husk_context::HuskContext;
|
||||
use crate::config::{HuskConfig, HuskConfigContainer};
|
||||
use crate::mail;
|
||||
|
||||
pub struct Daemon { }
|
||||
|
||||
@@ -105,19 +106,19 @@ impl Daemon {
|
||||
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() {
|
||||
Ok(s) => s.to_string(),
|
||||
_ => "corrupt".to_string()
|
||||
}
|
||||
},
|
||||
None => { "missing".to_string() }
|
||||
};
|
||||
let mut sender: Option<String> = None;
|
||||
|
||||
for arg in args {
|
||||
if let Some(s) = mail::to_email(&arg) {
|
||||
sender = Some(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if sender.is_none() { return Status::Tempfail; }
|
||||
|
||||
if let Some(ref mut context) = cx.data {
|
||||
context.set_sender(sender);
|
||||
context.reset_mail();
|
||||
context.set_sender(sender.unwrap());
|
||||
Status::Continue
|
||||
} else {
|
||||
Status::Tempfail
|
||||
@@ -129,9 +130,23 @@ impl Daemon {
|
||||
|
||||
if let Some(ref mut context) = cx.data {
|
||||
|
||||
let mut rcpt: Option<String> = None;
|
||||
for arg in args {
|
||||
if let Some(s) = mail::to_email(&arg) {
|
||||
rcpt = Some(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if rcpt.is_none() {
|
||||
Status::Tempfail
|
||||
} else {
|
||||
context.add_recipient(rcpt.unwrap()).unwrap();
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
} else {
|
||||
Status::Tempfail
|
||||
}
|
||||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
async fn handle_data(_cx: &mut Context<HuskContext<'_>>) -> Status {
|
||||
@@ -163,6 +178,7 @@ impl Daemon {
|
||||
|
||||
if let Some(ref mut context) = cx.data {
|
||||
log::debug!("Mail from {:?} complete", context.mail.sender);
|
||||
log::debug!("recipients: {:?}", context.mail.recipients);
|
||||
}
|
||||
|
||||
Status::Continue
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// Husk milter
|
||||
//
|
||||
// mail functions
|
||||
//
|
||||
|
||||
use std::ffi::CString;
|
||||
use sequoia_openpgp::packet::UserID;
|
||||
|
||||
pub fn to_userid(rcpt: &CString) -> Option<UserID> {
|
||||
match rcpt.to_str() {
|
||||
Ok(s) => Some(UserID::from(s)),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_email(rcpt: &CString) -> Option<String> {
|
||||
if let Some(u) = to_userid(rcpt) {
|
||||
if let Ok(Some(e)) = u.email() { Some(e.to_string()) }
|
||||
else { None }
|
||||
} else { None }
|
||||
}
|
||||
@@ -9,6 +9,7 @@ pub mod config;
|
||||
use config::{HuskConfig, HuskConfigContainer};
|
||||
pub mod types;
|
||||
pub mod crypto;
|
||||
pub mod mail;
|
||||
pub mod daemon;
|
||||
use daemon::Daemon;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
//
|
||||
|
||||
use anyhow;
|
||||
use sequoia_openpgp::policy::StandardPolicy;
|
||||
use std::path::PathBuf;
|
||||
use sequoia_openpgp::Cert;
|
||||
use sequoia_cert_store::{CertStore, StoreUpdate};
|
||||
@@ -14,6 +15,7 @@ use crate::{config::HuskConfig, crypto};
|
||||
use crate::types::mail_context::MailContext;
|
||||
|
||||
pub struct HuskContext<'hc> {
|
||||
pub policy: StandardPolicy<'hc>,
|
||||
pub cert_store: CertStore<'hc>,
|
||||
pub local_trust_root: Cert,
|
||||
pub mail: MailContext<'hc>,
|
||||
@@ -28,9 +30,12 @@ impl<'hc> HuskContext<'hc> {
|
||||
let cert_store_base = sequoia_home.data_dir(sequoia_directories::Component::CertD);
|
||||
let cert_store = CertStore::open(cert_store_base)?;
|
||||
|
||||
let policy = StandardPolicy::new();
|
||||
|
||||
let local_trust_root = crypto::get_local_trust_root(&cert_store)?;
|
||||
|
||||
Ok(HuskContext {
|
||||
policy,
|
||||
cert_store,
|
||||
local_trust_root,
|
||||
mail: MailContext::new(),
|
||||
@@ -41,4 +46,12 @@ impl<'hc> HuskContext<'hc> {
|
||||
self.mail.set_sender(sender);
|
||||
}
|
||||
|
||||
pub fn reset_mail(&mut self) {
|
||||
self.mail = MailContext::new();
|
||||
}
|
||||
|
||||
pub fn add_recipient(&mut self, rcpt: String) -> anyhow::Result<()> {
|
||||
self.mail.add_recipient(rcpt)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,15 +4,25 @@
|
||||
// Mail Context
|
||||
//
|
||||
|
||||
use std::ffi::CString;
|
||||
use anyhow;
|
||||
|
||||
use sequoia_openpgp::cert::ValidCert;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Recipient<'r> {
|
||||
pub email: CString,
|
||||
pub email: String,
|
||||
pub cert: Option<ValidCert<'r>>,
|
||||
}
|
||||
|
||||
impl From<String> for Recipient<'_> {
|
||||
fn from(email: String) -> Self {
|
||||
Recipient {
|
||||
email: email,
|
||||
cert: None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MailContext<'c> {
|
||||
pub sender: Option<String>,
|
||||
pub recipients: Vec<Recipient<'c>>,
|
||||
@@ -34,4 +44,12 @@ impl MailContext<'_> {
|
||||
self.sender = Some(sender);
|
||||
}
|
||||
|
||||
pub fn add_recipient(&mut self, rcpt: String) -> anyhow::Result<()> {
|
||||
let recipient: Recipient = rcpt.into();
|
||||
|
||||
self.recipients.push(recipient);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user