trivy / Check (pull_request) Canceled after 0s
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).
174 lines
6.3 KiB
Rust
174 lines
6.3 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
|
*/
|
|
|
|
use std::{sync::Arc, time::SystemTime};
|
|
|
|
use common::network::SessionStream;
|
|
|
|
use mail_auth::common::resolver::ToReverseName;
|
|
use sieve::{Envelope, Sieve, runtime::Variable};
|
|
use smtp_proto::*;
|
|
|
|
use crate::{core::Session, inbound::AuthResult};
|
|
|
|
use super::{ScriptParameters, ScriptResult, event_loop::RunScript};
|
|
|
|
impl<T: SessionStream> Session<T> {
|
|
pub fn build_script_parameters(&self, stage: &'static str) -> ScriptParameters<'_> {
|
|
let (tls_version, tls_cipher) = self.stream.tls_version_and_cipher();
|
|
let mut params = ScriptParameters::new()
|
|
.set_variable("remote_ip", self.data.remote_ip.to_string())
|
|
.set_variable("remote_ip.reverse", self.data.remote_ip.to_reverse_name())
|
|
.set_variable("helo_domain", self.data.helo_domain.as_str().to_lowercase())
|
|
.set_variable(
|
|
"authenticated_as",
|
|
self.authenticated_as().unwrap_or_default().to_string(),
|
|
)
|
|
.set_variable(
|
|
"now",
|
|
SystemTime::now()
|
|
.duration_since(SystemTime::UNIX_EPOCH)
|
|
.map_or(0, |d| d.as_secs()),
|
|
)
|
|
.set_variable(
|
|
"asn",
|
|
self.data
|
|
.asn_geo_data
|
|
.asn
|
|
.as_ref()
|
|
.map(|r| r.id)
|
|
.unwrap_or_default(),
|
|
)
|
|
.set_variable(
|
|
"country",
|
|
self.data
|
|
.asn_geo_data
|
|
.country
|
|
.as_ref()
|
|
.map(|r| r.as_str())
|
|
.unwrap_or_default(),
|
|
)
|
|
.set_variable(
|
|
"spf.result",
|
|
self.data
|
|
.spf_mail_from
|
|
.as_ref()
|
|
.map(|r| r.result().as_str())
|
|
.unwrap_or_default(),
|
|
)
|
|
.set_variable(
|
|
"spf_ehlo.result",
|
|
self.data
|
|
.spf_ehlo
|
|
.as_ref()
|
|
.map(|r| r.result().as_str())
|
|
.unwrap_or_default(),
|
|
)
|
|
.set_variable("tls.version", tls_version)
|
|
.set_variable("tls.cipher", tls_cipher)
|
|
.set_variable("stage", stage);
|
|
if let Some(ip_rev) = &self.data.iprev {
|
|
params = params.set_variable("iprev.result", ip_rev.result().as_str());
|
|
if let Some(ptr) = ip_rev.ptr.as_ref().and_then(|addrs| addrs.first()) {
|
|
params = params.set_variable(
|
|
"iprev.ptr",
|
|
ptr.strip_suffix('.').unwrap_or(ptr).to_lowercase(),
|
|
);
|
|
}
|
|
}
|
|
|
|
if let Some(mail_from) = &self.data.mail_from {
|
|
params
|
|
.envelope
|
|
.push((Envelope::From, mail_from.address_lcase.to_string().into()));
|
|
if let Some(env_id) = &mail_from.dsn_info {
|
|
params
|
|
.envelope
|
|
.push((Envelope::Envid, env_id.as_str().to_lowercase().into()));
|
|
}
|
|
|
|
if stage != "data" {
|
|
if let Some(rcpt) = self.data.rcpt_to.last() {
|
|
params
|
|
.envelope
|
|
.push((Envelope::To, rcpt.address_lcase.to_string().into()));
|
|
if let Some(orcpt) = rcpt.orcpt_parameter() {
|
|
params.envelope.push((Envelope::Orcpt, orcpt.into()));
|
|
}
|
|
}
|
|
} else {
|
|
// Build recipients list
|
|
let mut recipients = Vec::with_capacity(self.data.rcpt_to.len());
|
|
let mut orcpts = Vec::with_capacity(self.data.rcpt_to.len());
|
|
let mut has_orcpts = false;
|
|
|
|
for rcpt in &self.data.rcpt_to {
|
|
recipients.push(Variable::from(rcpt.address_lcase.to_string()));
|
|
orcpts.push(match rcpt.orcpt_parameter() {
|
|
Some(orcpt) => {
|
|
has_orcpts = true;
|
|
Variable::from(orcpt)
|
|
}
|
|
None => Variable::default(),
|
|
});
|
|
}
|
|
|
|
params.envelope.push((Envelope::To, recipients.into()));
|
|
if has_orcpts {
|
|
params.envelope.push((Envelope::Orcpt, orcpts.into()));
|
|
}
|
|
}
|
|
|
|
if (mail_from.flags & MAIL_RET_FULL) != 0 {
|
|
params.envelope.push((Envelope::Ret, "FULL".into()));
|
|
} else if (mail_from.flags & MAIL_RET_HDRS) != 0 {
|
|
params.envelope.push((Envelope::Ret, "HDRS".into()));
|
|
}
|
|
if (mail_from.flags & MAIL_BY_NOTIFY) != 0 {
|
|
params.envelope.push((Envelope::ByMode, "N".into()));
|
|
} else if (mail_from.flags & MAIL_BY_RETURN) != 0 {
|
|
params.envelope.push((Envelope::ByMode, "R".into()));
|
|
}
|
|
|
|
if (mail_from.flags & MAIL_BODY_7BIT) != 0 {
|
|
params = params.set_variable("param.body", "7bit");
|
|
} else if (mail_from.flags & MAIL_BODY_8BITMIME) != 0 {
|
|
params = params.set_variable("param.body", "8bitmime");
|
|
} else if (mail_from.flags & MAIL_BODY_BINARYMIME) != 0 {
|
|
params = params.set_variable("param.body", "binarymime");
|
|
}
|
|
|
|
if (mail_from.flags & MAIL_SMTPUTF8) != 0 {
|
|
params = params.set_variable("param.smtputf8", Variable::Integer(1));
|
|
}
|
|
if (mail_from.flags & MAIL_REQUIRETLS) != 0 {
|
|
params = params.set_variable("param.requiretls", Variable::Integer(1));
|
|
}
|
|
}
|
|
|
|
params
|
|
}
|
|
|
|
pub async fn run_script(
|
|
&self,
|
|
script_id: String,
|
|
script: Arc<Sieve>,
|
|
params: ScriptParameters<'_>,
|
|
) -> ScriptResult {
|
|
Box::pin(
|
|
self.server.run_script(
|
|
script_id,
|
|
script,
|
|
params
|
|
.with_session_id(self.data.session_id)
|
|
.with_envelope(&self.server, self, self.data.session_id)
|
|
.await,
|
|
),
|
|
)
|
|
.await
|
|
}
|
|
}
|