mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2024-09-20 07:16:18 +08:00
Increase SMTP transaction logging details
This commit is contained in:
parent
6d76b26fb8
commit
147d9ded86
85
Cargo.lock
generated
85
Cargo.lock
generated
|
@ -411,33 +411,6 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-rs"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ae74d9bd0a7530e8afd1770739ad34b36838829d6ad61818f9230f683f5ad77"
|
||||
dependencies = [
|
||||
"aws-lc-sys",
|
||||
"mirai-annotations",
|
||||
"paste",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-sys"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f0e249228c6ad2d240c2dc94b714d711629d52bad946075d8e9b2f5391f0703"
|
||||
dependencies = [
|
||||
"bindgen 0.69.4",
|
||||
"cc",
|
||||
"cmake",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
"libc",
|
||||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-region"
|
||||
version = "0.25.4"
|
||||
|
@ -598,9 +571,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.70.0"
|
||||
version = "0.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0127a1da21afb5adaae26910922c3f7afd3d329ba1a1b98a0884cab4907a251"
|
||||
checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"cexpr",
|
||||
|
@ -1787,12 +1760,6 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.17"
|
||||
|
@ -2222,12 +2189,6 @@ dependencies = [
|
|||
"syn 2.0.75",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
|
@ -3260,7 +3221,7 @@ dependencies = [
|
|||
"nlp",
|
||||
"p256",
|
||||
"pkcs8",
|
||||
"quick-xml 0.35.0",
|
||||
"quick-xml 0.36.1",
|
||||
"rand",
|
||||
"rasn",
|
||||
"rasn-cms",
|
||||
|
@ -3826,6 +3787,18 @@ dependencies = [
|
|||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.2"
|
||||
|
@ -3838,12 +3811,6 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mirai-annotations"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1"
|
||||
|
||||
[[package]]
|
||||
name = "mysql-common-derive"
|
||||
version = "0.31.1"
|
||||
|
@ -3864,9 +3831,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mysql_async"
|
||||
version = "0.34.2"
|
||||
version = "0.34.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0b66e411c31265e879d9814d03721f2daa7ad07337b6308cb4bb0cde7e6fd47"
|
||||
checksum = "fbfe87d7e35cb72363326216cc1712b865d8d4f70abf3b2d2e6b251fb6b2f427"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"crossbeam",
|
||||
|
@ -3875,20 +3842,23 @@ dependencies = [
|
|||
"futures-sink",
|
||||
"futures-util",
|
||||
"keyed_priority_queue",
|
||||
"lazy_static",
|
||||
"lru",
|
||||
"mio 0.8.11",
|
||||
"mysql_common",
|
||||
"once_cell",
|
||||
"pem",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"rand",
|
||||
"rustls 0.23.12",
|
||||
"rustls 0.22.4",
|
||||
"rustls-pemfile 2.1.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"socket2",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.0",
|
||||
"tokio-rustls 0.25.0",
|
||||
"tokio-util",
|
||||
"twox-hash",
|
||||
"url",
|
||||
|
@ -3904,7 +3874,7 @@ checksum = "478b0ff3f7d67b79da2b96f56f334431aef65e15ba4b29dd74a4236e29582bdc"
|
|||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bigdecimal",
|
||||
"bindgen 0.70.0",
|
||||
"bindgen 0.70.1",
|
||||
"bitflags 2.6.0",
|
||||
"bitvec",
|
||||
"btoi",
|
||||
|
@ -4773,9 +4743,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.35.0"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86e446ed58cef1bbfe847bc2fda0e2e4ea9f0e57b90c507d4781292590d72a4e"
|
||||
checksum = "96a05e2e8efddfa51a84ca47cec303fac86c8541b686d37cac5efc0e094417bc"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -5526,8 +5496,6 @@ version = "0.23.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring 0.17.8",
|
||||
"rustls-pki-types",
|
||||
|
@ -5602,7 +5570,6 @@ version = "0.102.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"ring 0.17.8",
|
||||
"rustls-pki-types",
|
||||
"untrusted 0.9.0",
|
||||
|
@ -6588,7 +6555,7 @@ dependencies = [
|
|||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"mio 1.0.2",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
|
|
|
@ -340,12 +340,12 @@ impl SpanCollector {
|
|||
fn into_vec(self) -> Vec<u64> {
|
||||
match self {
|
||||
Self::Vec(mut vec) => {
|
||||
vec.sort_unstable();
|
||||
vec.sort_unstable_by(|a, b| b.cmp(a));
|
||||
vec
|
||||
}
|
||||
Self::HashSet(set) => {
|
||||
let mut vec: Vec<u64> = set.into_iter().collect();
|
||||
vec.sort_unstable();
|
||||
vec.sort_unstable_by(|a, b| b.cmp(a));
|
||||
vec
|
||||
}
|
||||
Self::Empty => Vec::new(),
|
||||
|
|
|
@ -56,7 +56,7 @@ async-trait = "0.1.68"
|
|||
lz4_flex = { version = "0.11", default-features = false }
|
||||
rev_lines = "0.3.0"
|
||||
x509-parser = "0.16.0"
|
||||
quick-xml = "0.35"
|
||||
quick-xml = "0.36"
|
||||
|
||||
|
||||
[features]
|
||||
|
|
|
@ -617,3 +617,60 @@ pub enum StartTlsResult {
|
|||
smtp_client: SmtpClient<TcpStream>,
|
||||
},
|
||||
}
|
||||
|
||||
pub(crate) fn from_mail_send_error(error: &mail_send::Error) -> trc::Error {
|
||||
let event = trc::EventType::Smtp(trc::SmtpEvent::Error).into_err();
|
||||
match error {
|
||||
mail_send::Error::Io(err) => event.details("I/O Error").reason(err),
|
||||
mail_send::Error::Tls(err) => event.details("TLS Error").reason(err),
|
||||
mail_send::Error::Base64(err) => event.details("Base64 Error").reason(err),
|
||||
mail_send::Error::Auth(err) => event.details("SMTP Authentication Error").reason(err),
|
||||
mail_send::Error::UnparseableReply => event.details("Unparseable SMTP Reply"),
|
||||
mail_send::Error::UnexpectedReply(reply) => event
|
||||
.details("Unexpected SMTP Response")
|
||||
.ctx(trc::Key::Code, reply.code)
|
||||
.ctx(trc::Key::Reason, reply.message.clone()),
|
||||
mail_send::Error::AuthenticationFailed(reply) => event
|
||||
.details("SMTP Authentication Failed")
|
||||
.ctx(trc::Key::Code, reply.code)
|
||||
.ctx(trc::Key::Reason, reply.message.clone()),
|
||||
mail_send::Error::InvalidTLSName => event.details("Invalid TLS Name"),
|
||||
mail_send::Error::MissingCredentials => event.details("Missing Authentication Credentials"),
|
||||
mail_send::Error::MissingMailFrom => event.details("Missing Message Sender"),
|
||||
mail_send::Error::MissingRcptTo => event.details("Missing Message Recipients"),
|
||||
mail_send::Error::UnsupportedAuthMechanism => {
|
||||
event.details("Unsupported Authentication Mechanism")
|
||||
}
|
||||
mail_send::Error::Timeout => event.details("Connection Timeout"),
|
||||
mail_send::Error::MissingStartTls => event.details("STARTTLS not available"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_error_status(status: &Status<(), Error>) -> trc::Error {
|
||||
let event = trc::EventType::Smtp(trc::SmtpEvent::Error).into_err();
|
||||
let err = match status {
|
||||
Status::TemporaryFailure(err) | Status::PermanentFailure(err) => err,
|
||||
Status::Scheduled | Status::Completed(_) => return event, // This should not happen
|
||||
};
|
||||
|
||||
match err {
|
||||
Error::DnsError(err) => event.details("DNS Error").reason(err),
|
||||
Error::UnexpectedResponse(reply) => event
|
||||
.details("Unexpected SMTP Response")
|
||||
.ctx(trc::Key::Code, reply.response.code)
|
||||
.ctx(trc::Key::Reason, reply.response.message.clone()),
|
||||
Error::ConnectionError(err) => event
|
||||
.details("Connection Error")
|
||||
.ctx(trc::Key::Reason, err.details.clone()),
|
||||
Error::TlsError(err) => event
|
||||
.details("TLS Error")
|
||||
.ctx(trc::Key::Reason, err.details.clone()),
|
||||
Error::DaneError(err) => event
|
||||
.details("DANE Error")
|
||||
.ctx(trc::Key::Reason, err.details.clone()),
|
||||
Error::MtaStsError(err) => event.details("MTA-STS Error").reason(err),
|
||||
Error::RateLimited => todo!(),
|
||||
Error::ConcurrencyLimited => todo!(),
|
||||
Error::Io(err) => event.details("I/O Error").reason(err),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::outbound::client::SmtpClient;
|
||||
use crate::outbound::client::{from_error_status, from_mail_send_error, SmtpClient};
|
||||
use crate::outbound::mta_sts::verify::VerifyPolicy;
|
||||
use crate::outbound::{client::StartTlsResult, dane::verify::TlsaVerify};
|
||||
use common::config::{
|
||||
|
@ -325,7 +325,15 @@ impl DeliveryAttempt {
|
|||
TlsRpt(TlsRptEvent::RecordFetch),
|
||||
SpanId = message.span_id,
|
||||
Domain = domain.domain.clone(),
|
||||
Details = format!("{record:?}"),
|
||||
Details = record
|
||||
.rua
|
||||
.iter()
|
||||
.map(|uri| trc::Value::from(match uri {
|
||||
mail_auth::mta_sts::ReportUri::Mail(uri)
|
||||
| mail_auth::mta_sts::ReportUri::Http(uri) =>
|
||||
uri.to_string(),
|
||||
}))
|
||||
.collect::<Vec<_>>(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -364,7 +372,12 @@ impl DeliveryAttempt {
|
|||
MtaSts(MtaStsEvent::PolicyFetch),
|
||||
SpanId = message.span_id,
|
||||
Domain = domain.domain.clone(),
|
||||
Details = mta_sts_policy.to_string(),
|
||||
Strict = mta_sts_policy.enforce(),
|
||||
Details = mta_sts_policy
|
||||
.mx
|
||||
.iter()
|
||||
.map(|mx| trc::Value::String(mx.to_string()))
|
||||
.collect::<Vec<_>>(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -885,7 +898,7 @@ impl DeliveryAttempt {
|
|||
LocalIp = source_ip,
|
||||
RemoteIp = remote_ip,
|
||||
RemotePort = remote_host.port(),
|
||||
Reason = err.to_string(),
|
||||
CausedBy = from_mail_send_error(&err),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -1018,11 +1031,17 @@ impl DeliveryAttempt {
|
|||
Hostname = envelope.mx.to_string(),
|
||||
Version = format!(
|
||||
"{:?}",
|
||||
smtp_client.tls_connection().protocol_version()
|
||||
smtp_client
|
||||
.tls_connection()
|
||||
.protocol_version()
|
||||
.unwrap()
|
||||
),
|
||||
Details = format!(
|
||||
"{:?}",
|
||||
smtp_client.tls_connection().negotiated_cipher_suite()
|
||||
smtp_client
|
||||
.tls_connection()
|
||||
.negotiated_cipher_suite()
|
||||
.unwrap()
|
||||
),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
@ -1097,7 +1116,12 @@ impl DeliveryAttempt {
|
|||
SpanId = message.span_id,
|
||||
Domain = domain.domain.clone(),
|
||||
Hostname = envelope.mx.to_string(),
|
||||
Details = reason.clone(),
|
||||
Code = response.as_ref().map(|r| r.code()),
|
||||
Details = response
|
||||
.as_ref()
|
||||
.map(|r| r.message().as_str())
|
||||
.unwrap_or("STARTTLS was not advertised by host")
|
||||
.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -1141,7 +1165,7 @@ impl DeliveryAttempt {
|
|||
SpanId = message.span_id,
|
||||
Domain = domain.domain.clone(),
|
||||
Hostname = envelope.mx.to_string(),
|
||||
Reason = error.to_string(),
|
||||
Reason = from_mail_send_error(&error),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -1206,7 +1230,7 @@ impl DeliveryAttempt {
|
|||
SpanId = message.span_id,
|
||||
Domain = domain.domain.clone(),
|
||||
Hostname = envelope.mx.to_string(),
|
||||
Reason = format!("{error:?}"),
|
||||
Reason = from_mail_send_error(&error),
|
||||
);
|
||||
|
||||
last_status = Status::from_tls_error(envelope.mx, error);
|
||||
|
@ -1226,7 +1250,7 @@ impl DeliveryAttempt {
|
|||
SpanId = message.span_id,
|
||||
Domain = domain.domain.clone(),
|
||||
Hostname = envelope.mx.to_string(),
|
||||
Details = status.to_string(),
|
||||
Details = from_error_status(&status),
|
||||
);
|
||||
|
||||
last_status = status;
|
||||
|
@ -1333,12 +1357,12 @@ impl Message {
|
|||
|
||||
for (idx, domain) in self.domains.iter_mut().enumerate() {
|
||||
match &domain.status {
|
||||
Status::TemporaryFailure(err) if domain.expires <= now => {
|
||||
Status::TemporaryFailure(_) if domain.expires <= now => {
|
||||
trc::event!(
|
||||
Delivery(DeliveryEvent::Failed),
|
||||
SpanId = self.span_id,
|
||||
Domain = domain.domain.clone(),
|
||||
Reason = err.to_string(),
|
||||
Reason = from_error_status(&domain.status),
|
||||
);
|
||||
|
||||
for rcpt in &mut self.recipients {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
use common::config::smtp::queue::RequireOptional;
|
||||
use mail_send::{smtp::AssertReply, Credentials};
|
||||
use mail_send::Credentials;
|
||||
use smtp_proto::{
|
||||
EhloResponse, Severity, EXT_CHUNKING, EXT_DSN, EXT_REQUIRE_TLS, EXT_SIZE, EXT_SMTP_UTF8,
|
||||
MAIL_REQUIRETLS, MAIL_RET_FULL, MAIL_RET_HDRS, MAIL_SMTPUTF8, RCPT_NOTIFY_DELAY,
|
||||
|
@ -16,6 +16,7 @@ use std::{fmt::Write, time::Instant};
|
|||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use trc::DeliveryEvent;
|
||||
|
||||
use crate::outbound::client::{from_error_status, from_mail_send_error};
|
||||
use crate::{
|
||||
core::SMTP,
|
||||
queue::{ErrorDetails, HostResponse, RCPT_STATUS_CHANGED},
|
||||
|
@ -64,7 +65,7 @@ impl Message {
|
|||
Delivery(DeliveryEvent::EhloRejected),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
Reason = status.to_string(),
|
||||
CausedBy = from_error_status(&status),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
smtp_client.quit().await;
|
||||
|
@ -80,7 +81,7 @@ impl Message {
|
|||
Delivery(DeliveryEvent::AuthFailed),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
Reason = err.to_string(),
|
||||
CausedBy = from_mail_send_error(&err),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -117,31 +118,38 @@ impl Message {
|
|||
let time = Instant::now();
|
||||
smtp_client.timeout = params.timeout_mail;
|
||||
let cmd = self.build_mail_from(&capabilities);
|
||||
if let Err(err) = smtp_client
|
||||
.cmd(cmd.as_bytes())
|
||||
.await
|
||||
.and_then(|r| r.assert_positive_completion())
|
||||
{
|
||||
trc::event!(
|
||||
Delivery(DeliveryEvent::MailFromRejected),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
Reason = err.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
match smtp_client.cmd(cmd.as_bytes()).await.and_then(|r| {
|
||||
if r.is_positive_completion() {
|
||||
Ok(r)
|
||||
} else {
|
||||
Err(mail_send::Error::UnexpectedReply(r))
|
||||
}
|
||||
}) {
|
||||
Ok(response) => {
|
||||
trc::event!(
|
||||
Delivery(DeliveryEvent::MailFrom),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
From = self.return_path.to_string(),
|
||||
Code = response.code,
|
||||
Details = response.message.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
trc::event!(
|
||||
Delivery(DeliveryEvent::MailFromRejected),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
CausedBy = from_mail_send_error(&err),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
smtp_client.quit().await;
|
||||
return Status::from_smtp_error(params.hostname, &cmd, err);
|
||||
smtp_client.quit().await;
|
||||
return Status::from_smtp_error(params.hostname, &cmd, err);
|
||||
}
|
||||
}
|
||||
|
||||
trc::event!(
|
||||
Delivery(DeliveryEvent::MailFrom),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
From = self.return_path.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
// RCPT TO
|
||||
let mut total_rcpt = 0;
|
||||
let mut total_completed = 0;
|
||||
|
@ -167,7 +175,8 @@ impl Message {
|
|||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
To = rcpt.address.to_string(),
|
||||
Details = response.to_string(),
|
||||
Code = response.code,
|
||||
Details = response.message.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -185,7 +194,8 @@ impl Message {
|
|||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
To = rcpt.address.to_string(),
|
||||
Reason = response.to_string(),
|
||||
Code = response.code,
|
||||
Details = response.message.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -211,7 +221,7 @@ impl Message {
|
|||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
To = rcpt.address.to_string(),
|
||||
Reason = err.to_string(),
|
||||
CausedBy = from_mail_send_error(&err),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -234,7 +244,7 @@ impl Message {
|
|||
Delivery(DeliveryEvent::MessageRejected),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
Reason = status.to_string(),
|
||||
CausedBy = from_error_status(&status),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -257,7 +267,8 @@ impl Message {
|
|||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
To = rcpt.address.to_string(),
|
||||
Details = status.to_string(),
|
||||
Code = response.code,
|
||||
Details = response.message.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -270,7 +281,8 @@ impl Message {
|
|||
Delivery(DeliveryEvent::MessageRejected),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
Reason = response.to_string(),
|
||||
Code = response.code,
|
||||
Details = response.message.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -287,7 +299,7 @@ impl Message {
|
|||
Delivery(DeliveryEvent::MessageRejected),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
Reason = status.to_string(),
|
||||
CausedBy = from_error_status(&status),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -311,7 +323,8 @@ impl Message {
|
|||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
To = rcpt.address.to_string(),
|
||||
Details = response.to_string(),
|
||||
Code = response.code,
|
||||
Details = response.message.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -327,7 +340,8 @@ impl Message {
|
|||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
To = rcpt.address.to_string(),
|
||||
Reason = response.to_string(),
|
||||
Code = response.code,
|
||||
Details = response.message.to_string(),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
@ -356,7 +370,7 @@ impl Message {
|
|||
Delivery(DeliveryEvent::MessageRejected),
|
||||
SpanId = params.session_id,
|
||||
Hostname = params.hostname.to_string(),
|
||||
Reason = status.to_string(),
|
||||
CausedBy = from_error_status(&status),
|
||||
Elapsed = time.elapsed(),
|
||||
);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::time::Duration;
|
|||
use store::write::now;
|
||||
|
||||
use crate::core::SMTP;
|
||||
use crate::outbound::client::from_error_status;
|
||||
|
||||
use super::{
|
||||
Domain, Error, ErrorDetails, HostResponse, Message, MessageSource, QueueEnvelope, Recipient,
|
||||
|
@ -79,7 +80,8 @@ impl SMTP {
|
|||
SpanId = message.span_id,
|
||||
To = rcpt.address_lcase.clone(),
|
||||
Hostname = response.hostname.clone(),
|
||||
Details = response.response.to_string(),
|
||||
Code = response.response.code,
|
||||
Details = response.response.message.to_string(),
|
||||
);
|
||||
}
|
||||
Status::TemporaryFailure(response) if domain.notify.due <= now => {
|
||||
|
@ -88,7 +90,8 @@ impl SMTP {
|
|||
SpanId = message.span_id,
|
||||
To = rcpt.address_lcase.clone(),
|
||||
Hostname = response.hostname.entity.clone(),
|
||||
Details = response.response.to_string(),
|
||||
Code = response.response.code,
|
||||
Details = response.response.message.to_string(),
|
||||
NextRetry = trc::Value::Timestamp(domain.retry.due),
|
||||
Expires = trc::Value::Timestamp(domain.expires),
|
||||
Total = domain.retry.inner,
|
||||
|
@ -100,28 +103,29 @@ impl SMTP {
|
|||
SpanId = message.span_id,
|
||||
To = rcpt.address_lcase.clone(),
|
||||
Hostname = response.hostname.entity.clone(),
|
||||
Details = response.response.to_string(),
|
||||
Code = response.response.code,
|
||||
Details = response.response.message.to_string(),
|
||||
Total = domain.retry.inner,
|
||||
);
|
||||
}
|
||||
Status::Scheduled => {
|
||||
// There is no status for this address, use the domain's status.
|
||||
match &domain.status {
|
||||
Status::PermanentFailure(err) => {
|
||||
Status::PermanentFailure(_) => {
|
||||
trc::event!(
|
||||
Delivery(trc::DeliveryEvent::DsnPermFail),
|
||||
SpanId = message.span_id,
|
||||
To = rcpt.address_lcase.clone(),
|
||||
Details = err.to_string(),
|
||||
Details = from_error_status(&domain.status),
|
||||
Total = domain.retry.inner,
|
||||
);
|
||||
}
|
||||
Status::TemporaryFailure(err) if domain.notify.due <= now => {
|
||||
Status::TemporaryFailure(_) if domain.notify.due <= now => {
|
||||
trc::event!(
|
||||
Delivery(trc::DeliveryEvent::DsnTempFail),
|
||||
SpanId = message.span_id,
|
||||
To = rcpt.address_lcase.clone(),
|
||||
Details = err.to_string(),
|
||||
Details = from_error_status(&domain.status),
|
||||
NextRetry = trc::Value::Timestamp(domain.retry.due),
|
||||
Expires = trc::Value::Timestamp(domain.expires),
|
||||
Total = domain.retry.inner,
|
||||
|
|
|
@ -34,7 +34,7 @@ rustls = { version = "0.23.5", optional = true, default-features = false, featur
|
|||
rustls-pki-types = { version = "1", optional = true }
|
||||
ring = { version = "0.17", optional = true }
|
||||
bytes = { version = "1.0", optional = true }
|
||||
mysql_async = { version = "0.34", default-features = false, features = ["default-rustls"], optional = true }
|
||||
mysql_async = { version = "=0.34.1", default-features = false, features = ["default-rustls"], optional = true }
|
||||
elasticsearch = { version = "8.5.0-alpha.1", default-features = false, features = ["rustls-tls"], optional = true }
|
||||
serde_json = {version = "1.0.64", optional = true }
|
||||
regex = "1.7.0"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use std::{borrow::Cow, fmt::Debug, str::FromStr, time::Duration};
|
||||
|
||||
use mail_auth::common::headers::HeaderWriter;
|
||||
use mail_auth::common::verify::VerifySignature;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
@ -324,15 +324,8 @@ impl From<&mail_auth::DmarcResult> for Event<EventType> {
|
|||
impl From<&mail_auth::DkimOutput<'_>> for Event<EventType> {
|
||||
fn from(value: &mail_auth::DkimOutput<'_>) -> Self {
|
||||
Event::from(value.result()).ctx_opt(
|
||||
Key::Contents,
|
||||
value.signature().map(|s| {
|
||||
let mut buf = Vec::new();
|
||||
s.write_header(&mut buf);
|
||||
|
||||
String::from_utf8(buf)
|
||||
.map(Value::String)
|
||||
.unwrap_or_else(|err| Value::Bytes(err.into_bytes()))
|
||||
}),
|
||||
Key::Domain,
|
||||
value.signature().map(|s| s.domain().to_string()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,23 @@
|
|||
|
||||
use std::time::Duration;
|
||||
|
||||
use common::enterprise::{license::LicenseKey, undelete::DeletedBlob, Enterprise};
|
||||
use common::{
|
||||
config::telemetry::{StoreTracer, TelemetrySubscriberType},
|
||||
enterprise::{license::LicenseKey, undelete::DeletedBlob, Enterprise},
|
||||
telemetry::tracers::store::{TracingQuery, TracingStore},
|
||||
};
|
||||
use imap_proto::ResponseType;
|
||||
use jmap::api::management::enterprise::undelete::{UndeleteRequest, UndeleteResponse};
|
||||
use store::write::now;
|
||||
use trc::{
|
||||
ipc::{bitset::Bitset, subscriber::SubscriberBuilder},
|
||||
DeliveryEvent, EventType, SmtpEvent,
|
||||
};
|
||||
|
||||
use crate::imap::{ImapConnection, Type};
|
||||
use crate::{
|
||||
imap::{ImapConnection, Type},
|
||||
jmap::delivery::SmtpConnection,
|
||||
};
|
||||
|
||||
use super::{delivery::AssertResult, JMAPTest, ManagementApi};
|
||||
|
||||
|
@ -37,8 +48,14 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
params.server.shared_core.store(core.into());
|
||||
assert!(params.server.shared_core.load().is_enterprise_edition());
|
||||
|
||||
// Undelete
|
||||
// Create test account
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "secret", "John Doe")
|
||||
.await;
|
||||
|
||||
undelete(params).await;
|
||||
tracing(params).await;
|
||||
|
||||
// Disable Enterprise
|
||||
let mut core = params.server.shared_core.load_full().as_ref().clone();
|
||||
|
@ -53,20 +70,99 @@ Subject: undelete test
|
|||
test
|
||||
";
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct List<T> {
|
||||
pub items: Vec<T>,
|
||||
pub total: usize,
|
||||
async fn tracing(params: &mut JMAPTest) {
|
||||
// Enable tracing
|
||||
let store = params.server.core.storage.data.clone();
|
||||
TelemetrySubscriberType::StoreTracer(StoreTracer {
|
||||
store: store.clone(),
|
||||
})
|
||||
.spawn(
|
||||
SubscriberBuilder::new("store-tracer".to_string()).with_interests(Box::new(Bitset::all())),
|
||||
true,
|
||||
);
|
||||
|
||||
// Make sure there are no span entries in the db
|
||||
assert_eq!(
|
||||
store
|
||||
.query_spans(
|
||||
&[TracingQuery::EventType(EventType::Smtp(
|
||||
SmtpEvent::ConnectionStart
|
||||
))],
|
||||
0,
|
||||
0
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
Vec::<u64>::new()
|
||||
);
|
||||
|
||||
// Send an email
|
||||
let mut lmtp = SmtpConnection::connect().await;
|
||||
lmtp.ingest(
|
||||
"bill@example.com",
|
||||
&["jdoe@example.com"],
|
||||
concat!(
|
||||
"From: bill@example.com\r\n",
|
||||
"To: jdoe@example.com\r\n",
|
||||
"Subject: TPS Report\r\n",
|
||||
"X-Spam-Status: No\r\n",
|
||||
"\r\n",
|
||||
"I'm going to need those TPS reports ASAP. ",
|
||||
"So, if you could do that, that'd be great."
|
||||
),
|
||||
)
|
||||
.await;
|
||||
lmtp.quit().await;
|
||||
tokio::time::sleep(Duration::from_millis(200)).await;
|
||||
|
||||
// Purge should not delete anything at this point
|
||||
store.purge_spans(Duration::from_secs(1)).await.unwrap();
|
||||
|
||||
// There should be a span entry in the db
|
||||
for span_type in [
|
||||
EventType::Delivery(DeliveryEvent::AttemptStart),
|
||||
EventType::Smtp(SmtpEvent::ConnectionStart),
|
||||
] {
|
||||
let spans = store
|
||||
.query_spans(&[TracingQuery::EventType(span_type)], 0, 0)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(spans.len(), 1, "{span_type:?}");
|
||||
assert_eq!(
|
||||
store.get_span(spans[0]).await.unwrap()[0].inner.typ,
|
||||
span_type
|
||||
);
|
||||
}
|
||||
|
||||
// Try searching
|
||||
for keyword in ["bill@example.com", "jdoe@example.com", "example.com"] {
|
||||
let spans = store
|
||||
.query_spans(&[TracingQuery::Keywords(keyword.to_string())], 0, 0)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(spans.len(), 2, "keyword: {keyword}");
|
||||
assert!(spans[0] > spans[1], "keyword: {keyword}");
|
||||
}
|
||||
|
||||
// Purge should delete the span entries
|
||||
tokio::time::sleep(Duration::from_millis(800)).await;
|
||||
store.purge_spans(Duration::from_secs(1)).await.unwrap();
|
||||
|
||||
for query in [
|
||||
TracingQuery::EventType(EventType::Smtp(SmtpEvent::ConnectionStart)),
|
||||
TracingQuery::EventType(EventType::Delivery(DeliveryEvent::AttemptStart)),
|
||||
TracingQuery::Keywords("bill@example.com".to_string()),
|
||||
TracingQuery::Keywords("jdoe@example.com".to_string()),
|
||||
TracingQuery::Keywords("example.com".to_string()),
|
||||
] {
|
||||
assert_eq!(
|
||||
store.query_spans(&[query], 0, 0).await.unwrap(),
|
||||
Vec::<u64>::new()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async fn undelete(params: &mut JMAPTest) {
|
||||
// Create test account
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "secret", "John Doe")
|
||||
.await;
|
||||
|
||||
async fn undelete(_params: &mut JMAPTest) {
|
||||
// Authenticate
|
||||
let mut imap = ImapConnection::connect(b"_x ").await;
|
||||
imap.send("AUTHENTICATE PLAIN {32+}\r\nAGpkb2VAZXhhbXBsZS5jb20Ac2VjcmV0")
|
||||
|
@ -163,3 +259,10 @@ async fn undelete(params: &mut JMAPTest) {
|
|||
.await
|
||||
.assert_contains("Subject: undelete test");
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct List<T> {
|
||||
pub items: Vec<T>,
|
||||
pub total: usize,
|
||||
}
|
||||
|
|
|
@ -300,7 +300,7 @@ pub async fn jmap_tests() {
|
|||
)
|
||||
.await;
|
||||
|
||||
webhooks::test(&mut params).await;
|
||||
/*webhooks::test(&mut params).await;
|
||||
email_query::test(&mut params, delete).await;
|
||||
email_get::test(&mut params).await;
|
||||
email_set::test(&mut params).await;
|
||||
|
@ -325,7 +325,7 @@ pub async fn jmap_tests() {
|
|||
quota::test(&mut params).await;
|
||||
crypto::test(&mut params).await;
|
||||
blob::test(&mut params).await;
|
||||
purge::test(&mut params).await;
|
||||
purge::test(&mut params).await;*/
|
||||
enterprise::test(&mut params).await;
|
||||
|
||||
if delete {
|
||||
|
|
|
@ -100,18 +100,8 @@ public-suffix = "file://{LIST_PATH}/public-suffix.dat"
|
|||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn antispam() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_env_filter(
|
||||
tracing_subscriber::EnvFilter::builder()
|
||||
.parse(
|
||||
"smtp=debug,imap=debug,jmap=debug,store=debug,utils=debug,directory=debug,common=trace",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
// Prepare config
|
||||
let tests = [
|
||||
|
|
|
@ -68,12 +68,7 @@ future-release = [{if = '!is_empty(authenticated_as)', then = '1d'},
|
|||
#[tokio::test]
|
||||
async fn auth() {
|
||||
// Enable logging
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
crate::enable_logging();
|
||||
|
||||
let tmp_dir = TempDir::new("smtp_auth_test", true);
|
||||
let mut config = Config::new(tmp_dir.update_config(CONFIG)).unwrap();
|
||||
|
|
|
@ -14,6 +14,9 @@ use crate::smtp::{
|
|||
|
||||
#[tokio::test]
|
||||
async fn basic_commands() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
let mut session = Session::test(build_smtp(Core::default(), Inner::default()));
|
||||
|
||||
// STARTTLS should be available on clear text connections
|
||||
|
|
|
@ -102,13 +102,7 @@ enable = true
|
|||
#[tokio::test]
|
||||
async fn data() {
|
||||
// Enable logging
|
||||
/*let disable = 1;
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
crate::enable_logging();
|
||||
|
||||
// Create temp dir for queue
|
||||
let mut inner = Inner::default();
|
||||
|
|
|
@ -92,6 +92,9 @@ verify = [{if = "sender_domain = 'test.net'", then = 'relaxed'},
|
|||
|
||||
#[tokio::test]
|
||||
async fn dmarc() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
let mut inner = Inner::default();
|
||||
let tmp_dir = TempDir::new("smtp_dmarc_test", true);
|
||||
let mut config = Config::new(tmp_dir.update_config(CONFIG.to_string() + SIGNATURES)).unwrap();
|
||||
|
|
|
@ -38,6 +38,9 @@ ehlo = [{if = "remote_ip = '10.0.0.2'", then = 'strict'},
|
|||
|
||||
#[tokio::test]
|
||||
async fn ehlo() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
let mut config = Config::new(CONFIG).unwrap();
|
||||
let core = Core::parse(&mut config, Default::default(), Default::default()).await;
|
||||
core.smtp.resolvers.dns.txt_add(
|
||||
|
|
|
@ -29,6 +29,9 @@ duration = [{if = "remote_ip = '10.0.0.3'", then = '500ms'},
|
|||
|
||||
#[tokio::test]
|
||||
async fn limits() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
let mut config = Config::new(CONFIG).unwrap();
|
||||
let core = Core::parse(&mut config, Default::default(), Default::default()).await;
|
||||
|
||||
|
|
|
@ -70,6 +70,9 @@ enable = true
|
|||
|
||||
#[tokio::test]
|
||||
async fn mail() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
let tmp_dir = TempDir::new("smtp_mail_test", true);
|
||||
let mut config = Config::new(tmp_dir.update_config(CONFIG)).unwrap();
|
||||
let stores = Stores::parse_all(&mut config).await;
|
||||
|
|
|
@ -99,13 +99,7 @@ stages = ["data"]
|
|||
#[tokio::test]
|
||||
async fn milter_session() {
|
||||
// Enable logging
|
||||
/*let disable = "true";
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
crate::enable_logging();
|
||||
|
||||
// Configure tests
|
||||
let tmp_dir = TempDir::new("smtp_milter_test", true);
|
||||
|
|
|
@ -86,13 +86,8 @@ enable = true
|
|||
#[tokio::test]
|
||||
async fn rcpt() {
|
||||
// Enable logging
|
||||
/*
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
crate::enable_logging();
|
||||
|
||||
let tmp_dir = TempDir::new("smtp_rcpt_test", true);
|
||||
let mut config = Config::new(tmp_dir.update_config(CONFIG)).unwrap();
|
||||
let stores = Stores::parse_all(&mut config).await;
|
||||
|
|
|
@ -66,12 +66,9 @@ if allof( envelope :localpart :contains "to" ".",
|
|||
|
||||
#[tokio::test]
|
||||
async fn address_rewrite() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Prepare config
|
||||
let mut config = Config::new(CONFIG).unwrap();
|
||||
|
|
|
@ -125,13 +125,8 @@ verify = "relaxed"
|
|||
#[tokio::test]
|
||||
async fn sign_and_seal() {
|
||||
// Enable logging
|
||||
/*let disable = "true";
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
let tmp_dir = TempDir::new("smtp_sign_test", true);
|
||||
let mut config = Config::new(tmp_dir.update_config(CONFIG.to_string() + SIGNATURES)).unwrap();
|
||||
|
|
|
@ -45,13 +45,7 @@ enable = true
|
|||
#[tokio::test]
|
||||
async fn throttle_inbound() {
|
||||
// Enable logging
|
||||
/*let disable = "true";
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
crate::enable_logging();
|
||||
|
||||
let tmp_dir = TempDir::new("smtp_inbound_throttle", true);
|
||||
let mut config = Config::new(tmp_dir.update_config(CONFIG)).unwrap();
|
||||
|
|
|
@ -65,6 +65,9 @@ expn = [{if = "remote_ip = '10.0.0.1'", then = true},
|
|||
|
||||
#[tokio::test]
|
||||
async fn vrfy_expn() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
let tmp_dir = TempDir::new("smtp_vrfy_test", true);
|
||||
let mut config = Config::new(tmp_dir.update_config(CONFIG)).unwrap();
|
||||
let stores = Stores::parse_all(&mut config).await;
|
||||
|
|
|
@ -99,13 +99,7 @@ expect = "0-1-2-2"
|
|||
#[tokio::test]
|
||||
async fn lookup_sql() {
|
||||
// Enable logging
|
||||
/*let disable = true;
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
crate::enable_logging();
|
||||
|
||||
// Parse settings
|
||||
let temp_dir = TempDir::new("smtp_lookup_tests", true);
|
||||
|
|
|
@ -49,6 +49,9 @@ ip-strategy = "ipv6_then_ipv4"
|
|||
|
||||
#[tokio::test]
|
||||
async fn lookup_ip() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
let ipv6 = [
|
||||
"a:b::1".parse().unwrap(),
|
||||
"a:b::2".parse().unwrap(),
|
||||
|
|
|
@ -66,12 +66,9 @@ pub(super) struct List<T> {
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn manage_queue() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start remote test server
|
||||
let mut remote = TestServer::new("smtp_manage_queue_remote", REMOTE, true).await;
|
||||
|
|
|
@ -54,12 +54,9 @@ max-size = 1024
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn manage_reports() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::DEBUG)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start reporting service
|
||||
let local = TestServer::new("smtp_manage_reports", CONFIG, true).await;
|
||||
|
|
|
@ -82,13 +82,9 @@ return-path = false
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn dane_verify() {
|
||||
/*let disable = 1;
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start test server
|
||||
let mut remote = TestServer::new("smtp_dane_remote", REMOTE, true).await;
|
||||
|
|
|
@ -50,12 +50,9 @@ return-path = false
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn extensions() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start test server
|
||||
let mut remote = TestServer::new("smtp_ext_remote", REMOTE, true).await;
|
||||
|
|
|
@ -51,13 +51,9 @@ chunking = false
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn fallback_relay() {
|
||||
/*let disable = 1;
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start test server
|
||||
let mut remote = TestServer::new("smtp_fallback_remote", REMOTE, true).await;
|
||||
|
|
|
@ -30,12 +30,9 @@ relay = true
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn ip_lookup_strategy() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start test server
|
||||
let mut remote = TestServer::new("smtp_iplookup_remote", REMOTE, true).await;
|
||||
|
|
|
@ -62,12 +62,9 @@ allow-invalid-certs = true
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn lmtp_delivery() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start test server
|
||||
let mut remote = TestServer::new("lmtp_delivery_remote", REMOTE, true).await;
|
||||
|
|
|
@ -59,12 +59,9 @@ return-path = false
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn mta_sts_verify() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start test server
|
||||
let mut remote = TestServer::new("smtp_mta_sts_remote", REMOTE, true).await;
|
||||
|
|
|
@ -70,12 +70,9 @@ This is a smuggled message
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn smtp_delivery() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start test server
|
||||
let mut remote = TestServer::new("smtp_delivery_remote", REMOTE, true).await;
|
||||
|
|
|
@ -66,12 +66,9 @@ enable = true
|
|||
|
||||
#[tokio::test]
|
||||
async fn throttle_outbound() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Build test message
|
||||
let mut test_message = new_message(0);
|
||||
|
|
|
@ -43,13 +43,9 @@ chunking = false
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn starttls_optional() {
|
||||
/*let disable = 1;
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Start test server
|
||||
let mut remote = TestServer::new("smtp_starttls_remote", REMOTE, true).await;
|
||||
|
|
|
@ -33,13 +33,8 @@ relay = true
|
|||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn concurrent_queue() {
|
||||
/*let disable = true;
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::DEBUG)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
// Start test server
|
||||
let remote = TestServer::new("smtp_concurrent_queue_remote", REMOTE, true).await;
|
||||
|
|
|
@ -34,6 +34,9 @@ sign = "['rsa']"
|
|||
|
||||
#[tokio::test]
|
||||
async fn generate_dsn() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
path.push("resources");
|
||||
path.push("smtp");
|
||||
|
|
|
@ -23,6 +23,9 @@ relay = true
|
|||
|
||||
#[tokio::test]
|
||||
async fn queue_due() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
let local = TestServer::new("smtp_queue_due_test", CONFIG, true).await;
|
||||
let core = local.build_smtp();
|
||||
let qr = &local.qr;
|
||||
|
|
|
@ -35,12 +35,9 @@ expire = [{if = "sender_domain = 'test.org'", then = "6s"},
|
|||
|
||||
#[tokio::test]
|
||||
async fn queue_retry() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::DEBUG)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Create temp dir for queue
|
||||
let mut local = TestServer::new("smtp_queue_retry_test", CONFIG, true).await;
|
||||
|
|
|
@ -28,6 +28,9 @@ store = "1s"
|
|||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn report_analyze() {
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
// Create temp dir for queue
|
||||
let mut local = TestServer::new("smtp_analyze_report_test", CONFIG, true).await;
|
||||
|
||||
|
|
|
@ -46,12 +46,9 @@ sign = "['rsa']"
|
|||
|
||||
#[tokio::test]
|
||||
async fn report_dmarc() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::DEBUG)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
|
||||
// Create scheduler
|
||||
let mut local = TestServer::new(
|
||||
|
|
|
@ -33,12 +33,8 @@ send = "daily"
|
|||
|
||||
#[tokio::test]
|
||||
async fn report_scheduler() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::DEBUG)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
// Create scheduler
|
||||
let local = TestServer::new("smtp_report_queue_test", CONFIG, true).await;
|
||||
|
|
|
@ -42,13 +42,8 @@ sign = "['rsa']"
|
|||
|
||||
#[tokio::test]
|
||||
async fn report_tls() {
|
||||
/*let disable = "true";
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
// Enable logging
|
||||
crate::enable_logging();
|
||||
|
||||
// Create scheduler
|
||||
let mut local = TestServer::new(
|
||||
|
|
|
@ -175,7 +175,6 @@ impl TestSession for Session<DummyIo> {
|
|||
)
|
||||
.await
|
||||
.unwrap();
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
|
||||
self.response().assert_code(expected_code);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue