diff --git a/Cargo.lock b/Cargo.lock index 70b6ff7..7503ea8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1633,6 +1633,7 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "smtp-proto" version = "0.1.0" +source = "git+https://github.com/stalwartlabs/smtp-proto#cf9640069dac6aec0eb8120b84e17e31d8bce958" [[package]] name = "smtp-server" diff --git a/Cargo.toml b/Cargo.toml index 280ef9c..14b4ea7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,13 +3,12 @@ name = "smtp-server" version = "0.1.0" edition = "2021" - [dependencies] mail-auth = { path = "/home/vagrant/code/mail-auth" } mail-send = { path = "/home/vagrant/code/mail-send", default-features = false, features = ["cram-md5", "skip-ehlo"] } mail-parser = { git = "https://github.com/stalwartlabs/mail-parser", features = ["full_encoding", "ludicrous_mode"] } mail-builder = { path = "/home/vagrant/code/mail-builder", features = ["ludicrous_mode"] } -smtp-proto = { path = "/home/vagrant/code/smtp-proto" } +smtp-proto = { git = "https://github.com/stalwartlabs/smtp-proto" } ahash = { version = "0.8" } rustls = "0.20" rustls-pemfile = "1.0" diff --git a/README.md b/README.md index fe37445..91f0f9e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ Stalwart SMTP Server # TODO -- RBL - Greylist - Sieve - Spam filter diff --git a/src/inbound/ehlo.rs b/src/inbound/ehlo.rs index c6e68be..03b7ad8 100644 --- a/src/inbound/ehlo.rs +++ b/src/inbound/ehlo.rs @@ -261,6 +261,7 @@ impl Session { reply = ?ips, ); } + Err(mail_auth::Error::DnsRecordNotFound(_)) => (), Err(err) => { tracing::debug!(parent: &self.span, context = "dnsbl", diff --git a/src/reporting/dkim.rs b/src/reporting/dkim.rs index 3790444..dbe9f40 100644 --- a/src/reporting/dkim.rs +++ b/src/reporting/dkim.rs @@ -71,6 +71,7 @@ impl Session { report, &config.sign, &self.span, + true, ) .await; } diff --git a/src/reporting/dmarc.rs b/src/reporting/dmarc.rs index 2cf49ea..b1428f0 100644 --- a/src/reporting/dmarc.rs +++ b/src/reporting/dmarc.rs @@ -206,6 +206,7 @@ impl Session { report, &config.sign, &self.span, + true, ) .await; } else { @@ -379,7 +380,14 @@ impl GenerateDmarcReport for Arc { ); // Send report - handle.block_on(core.send_report(from_addr, rua.iter(), message, &config.sign, &span)); + handle.block_on(core.send_report( + from_addr, + rua.iter(), + message, + &config.sign, + &span, + false, + )); if let Err(err) = std::fs::remove_file(&path.path) { tracing::warn!( diff --git a/src/reporting/mod.rs b/src/reporting/mod.rs index 0577393..2014e0e 100644 --- a/src/reporting/mod.rs +++ b/src/reporting/mod.rs @@ -1,4 +1,7 @@ -use std::{sync::Arc, time::SystemTime}; +use std::{ + sync::Arc, + time::{Duration, SystemTime}, +}; use mail_auth::{ common::headers::HeaderWriter, @@ -9,6 +12,7 @@ use mail_auth::{ }, }; use mail_parser::DateTime; +use rand::Rng; use tokio::io::{AsyncRead, AsyncWrite}; use crate::{ @@ -104,6 +108,7 @@ impl Core { report: Vec, sign_config: &IfBlock>>, span: &tracing::Span, + deliver_now: bool, ) { // Build message let from_addr_lcase = from_addr.to_lowercase(); @@ -133,6 +138,19 @@ impl Core { // Sign message let signature = message.sign(sign_config, &report, span).await; + // Schedule delivery at a random time between now and the next 3 hours + if !deliver_now { + #[cfg(not(test))] + { + let delivery_time = Duration::from_secs(rand::thread_rng().gen_range(0..10800)); + for domain in &mut message.domains { + domain.retry.due += delivery_time; + domain.expires += delivery_time; + domain.notify.due += delivery_time; + } + } + } + // Queue message self.queue .queue_message(message, signature.as_deref(), &report, span) diff --git a/src/reporting/spf.rs b/src/reporting/spf.rs index 6b24e22..327f5ac 100644 --- a/src/reporting/spf.rs +++ b/src/reporting/spf.rs @@ -71,6 +71,7 @@ impl Session { report, &config.sign, &self.span, + true, ) .await; } diff --git a/src/reporting/tls.rs b/src/reporting/tls.rs index 95c11d4..453d052 100644 --- a/src/reporting/tls.rs +++ b/src/reporting/tls.rs @@ -238,6 +238,7 @@ impl GenerateTlsReport for Arc { message, &config.sign, &span, + false, )); } else { tracing::info!(