trivy / Check (pull_request) Waiting to run
Upstream commit: 9d1c75ab68435e4417337f768291e5f947686203 Enterprise-only files removed or emptied: 63 Enterprise-only snippets removed: 118 in 50 files Dangling module declarations removed: 5 Edits turning enterprise off: 25 Third-party code: 14 files, 0 not in THIRD-PARTY.md Verification: clean One snippet more than v0.16.22, in crates/common/src/auth/authentication.rs (3, was 2).
151 lines
4.6 KiB
Rust
151 lines
4.6 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
|
*/
|
|
|
|
use crate::{
|
|
inbound::dkim::DkimSign,
|
|
queue::{
|
|
MessageSource,
|
|
spool::{QueueParams, SmtpSpool},
|
|
},
|
|
};
|
|
use common::{Server, expr::if_block::IfBlock, ipc::ReportingEvent};
|
|
|
|
pub trait MtaReportSend: Sync + Send {
|
|
fn is_local_report_domain(
|
|
&self,
|
|
domain: &str,
|
|
session_id: u64,
|
|
) -> impl Future<Output = bool> + Send;
|
|
|
|
fn send_report(
|
|
&self,
|
|
from_addr: &str,
|
|
rcpts: impl Iterator<Item = impl AsRef<str> + Sync + Send> + Sync + Send,
|
|
report: Vec<u8>,
|
|
sign_config: &IfBlock,
|
|
deliver_now: bool,
|
|
parent_session_id: u64,
|
|
) -> impl Future<Output = ()> + Send;
|
|
|
|
fn send_autogenerated(
|
|
&self,
|
|
from_addr: impl AsRef<str> + Sync + Send,
|
|
rcpts: impl Iterator<Item = impl AsRef<str> + Sync + Send> + Sync + Send,
|
|
raw_message: Vec<u8>,
|
|
sign_config: Option<&IfBlock>,
|
|
parent_session_id: u64,
|
|
) -> impl Future<Output = ()> + Send;
|
|
|
|
fn schedule_report(
|
|
&self,
|
|
report: impl Into<ReportingEvent> + Sync + Send,
|
|
) -> impl Future<Output = ()> + Send;
|
|
}
|
|
|
|
impl MtaReportSend for Server {
|
|
async fn is_local_report_domain(&self, domain: &str, session_id: u64) -> bool {
|
|
match self.domain(domain).await {
|
|
Ok(domain) => domain.is_some(),
|
|
Err(err) => {
|
|
trc::error!(
|
|
err.caused_by(trc::location!())
|
|
.span_id(session_id)
|
|
.details("Failed to lookup local domain")
|
|
);
|
|
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn send_report(
|
|
&self,
|
|
from_addr: &str,
|
|
rcpts: impl Iterator<Item = impl AsRef<str> + Sync + Send> + Sync + Send,
|
|
report: Vec<u8>,
|
|
sign_config: &IfBlock,
|
|
deliver_now: bool,
|
|
parent_session_id: u64,
|
|
) {
|
|
// Build message
|
|
let mut message = self.new_message(from_addr, MessageSource::Report, parent_session_id);
|
|
for rcpt_ in rcpts {
|
|
message.add_expanded_recipient(rcpt_.as_ref(), self).await;
|
|
}
|
|
|
|
// Schedule delivery at a random time between now and the next 3 hours
|
|
if !deliver_now {
|
|
#[cfg(not(feature = "test_mode"))]
|
|
{
|
|
use common::config::smtp::queue::QueueExpiry;
|
|
use rand::RngExt;
|
|
|
|
let delivery_time = rand::rng().random_range(0u64..10800u64);
|
|
for rcpt in &mut message.message.recipients {
|
|
rcpt.retry.due += delivery_time;
|
|
rcpt.notify.due += delivery_time;
|
|
if let QueueExpiry::Ttl(expires) = &mut rcpt.expires {
|
|
*expires += delivery_time;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Queue message
|
|
let dkim_signers = self
|
|
.eval_signers(sign_config, &message.message, parent_session_id)
|
|
.await;
|
|
let _ = message
|
|
.queue(
|
|
QueueParams::new(&report, parent_session_id, self).with_dkim_signers(dkim_signers),
|
|
)
|
|
.await;
|
|
}
|
|
|
|
async fn send_autogenerated(
|
|
&self,
|
|
from_addr: impl AsRef<str> + Sync + Send,
|
|
rcpts: impl Iterator<Item = impl AsRef<str> + Sync + Send> + Sync + Send,
|
|
raw_message: Vec<u8>,
|
|
sign_config: Option<&IfBlock>,
|
|
parent_session_id: u64,
|
|
) {
|
|
// Build message
|
|
let mut message = self.new_message(
|
|
from_addr.as_ref(),
|
|
MessageSource::Autogenerated,
|
|
parent_session_id,
|
|
);
|
|
for rcpt in rcpts {
|
|
message.add_expanded_recipient(rcpt, self).await;
|
|
}
|
|
|
|
// Queue message
|
|
let dkim_signers = if let Some(sign_config) = sign_config {
|
|
self.eval_signers(sign_config, &message.message, parent_session_id)
|
|
.await
|
|
} else {
|
|
None
|
|
};
|
|
let _ = message
|
|
.queue(
|
|
QueueParams::new(&raw_message, parent_session_id, self)
|
|
.with_dkim_signers(dkim_signers),
|
|
)
|
|
.await;
|
|
}
|
|
|
|
async fn schedule_report(&self, report: impl Into<ReportingEvent> + Sync + Send) {
|
|
if self.inner.ipc.report_tx.send(report.into()).await.is_err() {
|
|
trc::event!(
|
|
Server(trc::ServerEvent::ThreadError),
|
|
CausedBy = trc::location!(),
|
|
Details = "Failed to send event to ReportScheduler"
|
|
);
|
|
}
|
|
}
|
|
}
|