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::types::husk_context::HuskContext;
|
||||||
use crate::config::{HuskConfig, HuskConfigContainer};
|
use crate::config::{HuskConfig, HuskConfigContainer};
|
||||||
|
use crate::mail;
|
||||||
|
|
||||||
pub struct Daemon { }
|
pub struct Daemon { }
|
||||||
|
|
||||||
@@ -105,19 +106,19 @@ impl Daemon {
|
|||||||
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:?}");
|
log::debug!("MAIL: {args:?}");
|
||||||
|
|
||||||
// XXX
|
let mut sender: Option<String> = None;
|
||||||
let sender = match args.first() {
|
|
||||||
Some(cs) => {
|
for arg in args {
|
||||||
match cs.to_str() {
|
if let Some(s) = mail::to_email(&arg) {
|
||||||
Ok(s) => s.to_string(),
|
sender = Some(s);
|
||||||
_ => "corrupt".to_string()
|
break;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => { "missing".to_string() }
|
if sender.is_none() { return Status::Tempfail; }
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(ref mut context) = cx.data {
|
if let Some(ref mut context) = cx.data {
|
||||||
context.set_sender(sender);
|
context.reset_mail();
|
||||||
|
context.set_sender(sender.unwrap());
|
||||||
Status::Continue
|
Status::Continue
|
||||||
} else {
|
} else {
|
||||||
Status::Tempfail
|
Status::Tempfail
|
||||||
@@ -129,9 +130,23 @@ impl Daemon {
|
|||||||
|
|
||||||
if let Some(ref mut context) = cx.data {
|
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
|
||||||
|
}
|
||||||
|
|
||||||
Status::Continue
|
} else {
|
||||||
|
Status::Tempfail
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_data(_cx: &mut Context<HuskContext<'_>>) -> Status {
|
async fn handle_data(_cx: &mut Context<HuskContext<'_>>) -> Status {
|
||||||
@@ -163,6 +178,7 @@ impl Daemon {
|
|||||||
|
|
||||||
if let Some(ref mut context) = cx.data {
|
if let Some(ref mut context) = cx.data {
|
||||||
log::debug!("Mail from {:?} complete", context.mail.sender);
|
log::debug!("Mail from {:?} complete", context.mail.sender);
|
||||||
|
log::debug!("recipients: {:?}", context.mail.recipients);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status::Continue
|
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};
|
use config::{HuskConfig, HuskConfigContainer};
|
||||||
pub mod types;
|
pub mod types;
|
||||||
pub mod crypto;
|
pub mod crypto;
|
||||||
|
pub mod mail;
|
||||||
pub mod daemon;
|
pub mod daemon;
|
||||||
use daemon::Daemon;
|
use daemon::Daemon;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
use anyhow;
|
use anyhow;
|
||||||
|
use sequoia_openpgp::policy::StandardPolicy;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use sequoia_openpgp::Cert;
|
use sequoia_openpgp::Cert;
|
||||||
use sequoia_cert_store::{CertStore, StoreUpdate};
|
use sequoia_cert_store::{CertStore, StoreUpdate};
|
||||||
@@ -14,6 +15,7 @@ use crate::{config::HuskConfig, crypto};
|
|||||||
use crate::types::mail_context::MailContext;
|
use crate::types::mail_context::MailContext;
|
||||||
|
|
||||||
pub struct HuskContext<'hc> {
|
pub struct HuskContext<'hc> {
|
||||||
|
pub policy: StandardPolicy<'hc>,
|
||||||
pub cert_store: CertStore<'hc>,
|
pub cert_store: CertStore<'hc>,
|
||||||
pub local_trust_root: Cert,
|
pub local_trust_root: Cert,
|
||||||
pub mail: MailContext<'hc>,
|
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_base = sequoia_home.data_dir(sequoia_directories::Component::CertD);
|
||||||
let cert_store = CertStore::open(cert_store_base)?;
|
let cert_store = CertStore::open(cert_store_base)?;
|
||||||
|
|
||||||
|
let policy = StandardPolicy::new();
|
||||||
|
|
||||||
let local_trust_root = crypto::get_local_trust_root(&cert_store)?;
|
let local_trust_root = crypto::get_local_trust_root(&cert_store)?;
|
||||||
|
|
||||||
Ok(HuskContext {
|
Ok(HuskContext {
|
||||||
|
policy,
|
||||||
cert_store,
|
cert_store,
|
||||||
local_trust_root,
|
local_trust_root,
|
||||||
mail: MailContext::new(),
|
mail: MailContext::new(),
|
||||||
@@ -41,4 +46,12 @@ impl<'hc> HuskContext<'hc> {
|
|||||||
self.mail.set_sender(sender);
|
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
|
// Mail Context
|
||||||
//
|
//
|
||||||
|
|
||||||
use std::ffi::CString;
|
use anyhow;
|
||||||
|
|
||||||
use sequoia_openpgp::cert::ValidCert;
|
use sequoia_openpgp::cert::ValidCert;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct Recipient<'r> {
|
pub struct Recipient<'r> {
|
||||||
pub email: CString,
|
pub email: String,
|
||||||
pub cert: Option<ValidCert<'r>>,
|
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 struct MailContext<'c> {
|
||||||
pub sender: Option<String>,
|
pub sender: Option<String>,
|
||||||
pub recipients: Vec<Recipient<'c>>,
|
pub recipients: Vec<Recipient<'c>>,
|
||||||
@@ -34,4 +44,12 @@ impl MailContext<'_> {
|
|||||||
self.sender = Some(sender);
|
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