Bump to mail-auth 0.11

This commit is contained in:
Maurus Decimus
2026-06-30 11:53:55 +02:00
parent 5f58fdb92b
commit e3c6f95bfd
35 changed files with 992 additions and 138 deletions

View File

@@ -30,7 +30,12 @@ use common::{
};
use mail_auth::{
AuthenticatedMessage, AuthenticationResults, DkimResult, DmarcResult, ReceivedSpf,
common::{crypto::Algorithm, headers::HeaderWriter, verify::VerifySignature},
common::{
crypto::Algorithm,
headers::{Header, HeaderWriter},
verify::VerifySignature,
},
dkim::DkimError,
dmarc::{self, verify::DmarcParameters},
};
use mail_builder::headers::{date::Date, message_id::generate_message_id_header};
@@ -108,17 +113,22 @@ impl<T: SessionStream> Session<T> {
.unwrap_or(VerifyStrategy::Relaxed);
let dkim_output = if dkim.verify() || dmarc.verify() {
// Remove insecure DKIM signatures before verification
for header in &mut auth_message.dkim_headers {
if let Ok(signature) = &mut header.header
&& (signature.algorithm() == Algorithm::RsaSha1
|| (signature.algorithm() == Algorithm::RsaSha256
&& signature.b.len() < 128))
auth_message.dkim_headers.retain(|header| {
let signature = &header.header;
if signature.algorithm() == Algorithm::RsaSha1
|| (signature.algorithm() == Algorithm::RsaSha256 && signature.b.len() < 128)
{
header.header = Err(mail_auth::Error::CryptoError(
"Insecure DKIM signature".into(),
));
auth_message.errors.push(Header {
name: header.name,
value: header.value,
header: mail_auth::Error::Dkim(DkimError::UnsupportedAlgorithm),
});
auth_message.has_dkim_errors = true;
false
} else {
true
}
}
});
let time = Instant::now();
let dkim_output = self

View File

@@ -345,7 +345,7 @@ impl QueuedMessage {
TlsRptOptions { record, interval }.into()
}
Err(mail_auth::Error::DnsRecordNotFound(_)) => {
Err(mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(_))) => {
trc::event!(
TlsRpt(TlsRptEvent::RecordNotFound),
SpanId = message.span_id,
@@ -400,7 +400,7 @@ impl QueuedMessage {
let strict = tls_strategy.is_mta_sts_required();
if let Some(tls_report) = &tls_report {
match &err {
mta_sts::Error::Dns(mail_auth::Error::DnsRecordNotFound(_)) => {
mta_sts::Error::Dns(mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(_))) => {
if strict {
server.schedule_report(TlsEvent {
policy: PolicyType::Sts(None),
@@ -417,7 +417,7 @@ impl QueuedMessage {
.await;
}
}
mta_sts::Error::Dns(mail_auth::Error::DnsError(_)) => (),
mta_sts::Error::Dns(mail_auth::Error::Dns(mail_auth::DnsError::Resolver(_))) => (),
_ => {
server
.schedule_report(TlsEvent {
@@ -436,7 +436,7 @@ impl QueuedMessage {
}
match &err {
mta_sts::Error::Dns(mail_auth::Error::DnsRecordNotFound(_)) => {
mta_sts::Error::Dns(mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(_))) => {
trc::event!(
MtaSts(MtaStsEvent::PolicyNotFound),
SpanId = message.span_id,
@@ -499,7 +499,7 @@ impl QueuedMessage {
let time = Instant::now();
mx_list = match server.mx_lookup(domain).await {
Ok(mx) => mx,
Err(mail_auth::Error::DnsRecordNotFound(_)) => {
Err(mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(_))) => {
trc::event!(
Delivery(DeliveryEvent::MxLookupFailed),
SpanId = message.span_id,
@@ -822,7 +822,7 @@ impl QueuedMessage {
}
Err(err) => {
let not_found =
matches!(&err, mail_auth::Error::DnsRecordNotFound(_));
matches!(&err, mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(_)));
if not_found {
trc::event!(

View File

@@ -116,7 +116,7 @@ impl DnsLookup for Server {
)
.await
.map_err(|err| {
if let mail_auth::Error::DnsRecordNotFound(_) = &err {
if let mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(_)) = &err {
if matches!(
remote_host,
NextHop::MX {

View File

@@ -156,10 +156,14 @@ impl Status<HostResponse<Box<str>>, ErrorDetails> {
pub fn from_mail_auth_error(entity: &str, err: mail_auth::Error) -> Self {
match &err {
mail_auth::Error::DnsRecordNotFound(code) => Status::PermanentFailure(ErrorDetails {
entity: entity.into(),
details: Error::DnsError(format!("Domain not found: {code:?}").into_boxed_str()),
}),
mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(code)) => {
Status::PermanentFailure(ErrorDetails {
entity: entity.into(),
details: Error::DnsError(
format!("Domain not found: {code:?}").into_boxed_str(),
),
})
}
_ => Status::TemporaryFailure(ErrorDetails {
entity: entity.into(),
details: Error::DnsError(err.to_string().into_boxed_str()),
@@ -170,7 +174,7 @@ impl Status<HostResponse<Box<str>>, ErrorDetails> {
pub fn from_mta_sts_error(entity: &str, err: mta_sts::Error) -> Self {
match &err {
mta_sts::Error::Dns(err) => match err {
mail_auth::Error::DnsRecordNotFound(code) => {
mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(code)) => {
Status::PermanentFailure(ErrorDetails {
entity: entity.into(),
details: Error::MtaStsError(
@@ -178,10 +182,12 @@ impl Status<HostResponse<Box<str>>, ErrorDetails> {
),
})
}
mail_auth::Error::InvalidRecordType => Status::PermanentFailure(ErrorDetails {
entity: entity.into(),
details: Error::MtaStsError("Failed to parse MTA-STS DNS record.".into()),
}),
mail_auth::Error::Dns(mail_auth::DnsError::InvalidRecordType) => {
Status::PermanentFailure(ErrorDetails {
entity: entity.into(),
details: Error::MtaStsError("Failed to parse MTA-STS DNS record.".into()),
})
}
_ => Status::TemporaryFailure(ErrorDetails {
entity: entity.into(),
details: Error::MtaStsError(

View File

@@ -114,10 +114,10 @@ impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::Dns(err) => match err {
mail_auth::Error::DnsRecordNotFound(code) => {
mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(code)) => {
write!(f, "Record not found: {code:?}")
}
mail_auth::Error::InvalidRecordType => {
mail_auth::Error::Dns(mail_auth::DnsError::InvalidRecordType) => {
f.write_str("Failed to parse MTA-STS DNS record.")
}
_ => write!(f, "DNS lookup error: {err}"),