1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
use crate::SMime; use log::error; use samotop_core::{common::*, mail::*}; use std::collections::VecDeque; use std::path::PathBuf; #[derive(Debug, Clone)] pub struct SMimeMail { private_key_file: PathBuf, certificate_file: PathBuf, } impl SMimeMail { pub fn new(private_key_file: PathBuf, certificate_file: PathBuf) -> Self { Self { private_key_file, certificate_file, } } } impl MailSetup for SMimeMail { fn setup(self, builder: &mut Builder) { builder.dispatch.insert(0, Box::new(self)) } } impl MailDispatch for SMimeMail { fn send_mail<'a, 's, 'f>( &'a self, _session: &'s SessionInfo, mut transaction: Transaction, ) -> S2Fut<'f, DispatchResult> where 'a: 'f, 's: 'f, { Box::pin(async move { let my_key = match self.private_key_file.to_str() { None => { error!("Server private key is not a string"); return Err(DispatchError::FailedTemporarily); } Some(key) => key, }; let my_cert = match self.certificate_file.to_str() { None => { error!("Server certificate is not a string"); return Err(DispatchError::FailedTemporarily); } Some(cert) => cert, }; let mut certs = VecDeque::new(); for rcpt in transaction.rcpts.iter() { match rcpt.certificate { None => { error!("Recipient certificate is missing"); return Err(DispatchError::FailedTemporarily); } Some(Certificate::Bytes(_)) => { unimplemented!("Only files are supported for now") } Some(Certificate::File(ref file)) => certs.push_back(file.as_str()), } } let her_cert = match certs.pop_front() { None => { error!("No recipients"); return Err(DispatchError::FailedTemporarily); } Some(file) => file, }; let sink = match transaction.sink.take() { None => { error!("Mail sink is not in transaction"); return Err(DispatchError::FailedTemporarily); } Some(sink) => sink, }; transaction.sink = Some(Box::pin( SMime::sign_and_encrypt(sink, my_key, my_cert, her_cert, certs.into()) .expect("todo"), )); Ok(transaction) }) } }