From a6c744b09a3e08bd926d1eac8cd3dcb3ada3c688 Mon Sep 17 00:00:00 2001 From: mdecimus Date: Sun, 12 Jan 2025 10:53:58 +0100 Subject: [PATCH] config_get() expression function + moved lookup.default.[hostname|domain] to server.hostname and report.domain --- crates/common/src/config/network.rs | 35 ++++++++++++++++++- crates/common/src/config/scripts.rs | 14 ++++---- crates/common/src/config/smtp/auth.rs | 2 +- crates/common/src/config/smtp/queue.rs | 10 ++---- crates/common/src/config/smtp/report.rs | 12 +++---- crates/common/src/config/smtp/session.rs | 4 +-- crates/common/src/enterprise/config.rs | 4 ++- crates/common/src/expr/eval.rs | 33 +++++++++++++---- crates/common/src/expr/mod.rs | 21 +++++++++++ crates/common/src/expr/parser.rs | 20 ++++++----- crates/common/src/expr/tokenizer.rs | 7 ++++ crates/common/src/manager/boot.rs | 12 ------- crates/common/src/manager/config.rs | 3 +- crates/directory/src/backend/smtp/config.rs | 2 +- crates/jmap/src/api/autoconfig.rs | 12 +------ crates/jmap/src/api/management/dns.rs | 8 +---- crates/jmap/src/api/management/principal.rs | 28 +++++++++++++++ crates/jmap/src/api/management/spam.rs | 15 +++----- .../jmap/src/api/management/troubleshoot.rs | 24 +++---------- tests/src/imap/mod.rs | 2 +- tests/src/smtp/reporting/dmarc.rs | 6 ++-- 21 files changed, 167 insertions(+), 107 deletions(-) diff --git a/crates/common/src/config/network.rs b/crates/common/src/config/network.rs index afeed2083..f4056732f 100644 --- a/crates/common/src/config/network.rs +++ b/crates/common/src/config/network.rs @@ -14,6 +14,8 @@ use super::*; #[derive(Clone)] pub struct Network { pub node_id: u64, + pub server_name: String, + pub report_domain: String, pub security: Security, pub contact_form: Option, pub http_response_url: IfBlock, @@ -84,10 +86,12 @@ impl Default for Network { http_response_url: IfBlock::new::<()>( "server.http.url", [], - "protocol + '://' + key_get('default', 'hostname') + ':' + local_port", + "protocol + '://' + config_get('server.hostname') + ':' + local_port", ), http_allowed_endpoint: IfBlock::new::<()>("server.http.allowed-endpoint", [], "200"), asn_geo_lookup: AsnGeoLookupConfig::Disabled, + server_name: Default::default(), + report_domain: Default::default(), } } } @@ -148,8 +152,37 @@ impl FieldOrDefault { impl Network { pub fn parse(config: &mut Config) -> Self { + let server_name = config + .value("server.hostname") + .map(|v| v.to_string()) + .or_else(|| { + config + .value("lookup.default.hostname") + .map(|v| v.to_lowercase()) + }) + .unwrap_or_else(|| { + hostname::get() + .map(|v| v.to_string_lossy().to_lowercase()) + .unwrap_or_else(|_| "localhost".to_string()) + }); + let report_domain = config + .value("report.domain") + .map(|v| v.to_lowercase()) + .or_else(|| { + config + .value("lookup.default.domain") + .map(|v| v.to_lowercase()) + }) + .unwrap_or_else(|| { + psl::domain_str(&server_name) + .unwrap_or(server_name.as_str()) + .to_string() + }); + let mut network = Network { node_id: config.property("cluster.node-id").unwrap_or_default(), + report_domain, + server_name, security: Security::parse(config), contact_form: ContactForm::parse(config), asn_geo_lookup: AsnGeoLookupConfig::parse(config).unwrap_or_default(), diff --git a/crates/common/src/config/scripts.rs b/crates/common/src/config/scripts.rs index 1a372279f..184aa8d6c 100644 --- a/crates/common/src/config/scripts.rs +++ b/crates/common/src/config/scripts.rs @@ -265,7 +265,7 @@ impl Scripting { let hostname = config .value("sieve.trusted.hostname") - .or_else(|| config.value("lookup.default.hostname")) + .or_else(|| config.value("server.hostname")) .unwrap_or("localhost") .to_string(); trusted_runtime.set_local_hostname(hostname.clone()); @@ -327,7 +327,7 @@ impl Scripting { IfBlock::new::<()>( "sieve.trusted.from-addr", [], - "'MAILER-DAEMON@' + key_get('default', 'domain')", + "'MAILER-DAEMON@' + config_get('report.domain')", ) }), from_name: IfBlock::try_parse(config, "sieve.trusted.from-name", &token_map) @@ -342,8 +342,8 @@ impl Scripting { "sieve.trusted.sign", [], concat!( - "['rsa-' + key_get('default', 'domain'), ", - "'ed25519-' + key_get('default', 'domain')]" + "['rsa-' + config_get('report.domain'), ", + "'ed25519-' + config_get('report.domain')]" ), ) }, @@ -363,7 +363,7 @@ impl Default for Scripting { from_addr: IfBlock::new::<()>( "sieve.trusted.from-addr", [], - "'MAILER-DAEMON@' + key_get('default', 'domain')", + "'MAILER-DAEMON@' + config_get('report.domain')", ), from_name: IfBlock::new::<()>("sieve.trusted.from-name", [], "'Mailer Daemon'"), return_path: IfBlock::empty("sieve.trusted.return-path"), @@ -371,8 +371,8 @@ impl Default for Scripting { "sieve.trusted.sign", [], concat!( - "['rsa-' + key_get('default', 'domain'), ", - "'ed25519-' + key_get('default', 'domain')]" + "['rsa-' + config_get('report.domain'), ", + "'ed25519-' + config_get('report.domain')]" ), ), untrusted_scripts: AHashMap::new(), diff --git a/crates/common/src/config/smtp/auth.rs b/crates/common/src/config/smtp/auth.rs index 851a51e88..be66ee989 100644 --- a/crates/common/src/config/smtp/auth.rs +++ b/crates/common/src/config/smtp/auth.rs @@ -109,7 +109,7 @@ impl Default for MailAuthConfig { seal: IfBlock::new::<()>( "auth.arc.seal", [], - "'rsa-' + key_get('default', 'domain')", + "'rsa-' + config_get('report.domain')", ), }, spf: SpfAuthConfig { diff --git a/crates/common/src/config/smtp/queue.rs b/crates/common/src/config/smtp/queue.rs index 31e0e8450..57cc69d41 100644 --- a/crates/common/src/config/smtp/queue.rs +++ b/crates/common/src/config/smtp/queue.rs @@ -134,11 +134,7 @@ impl Default for QueueConfig { ), notify: IfBlock::new::<()>("queue.schedule.notify", [], "[1d, 3d]"), expire: IfBlock::new::<()>("queue.schedule.expire", [], "5d"), - hostname: IfBlock::new::<()>( - "queue.outbound.hostname", - [], - "key_get('default', 'hostname')", - ), + hostname: IfBlock::new::<()>("queue.outbound.hostname", [], "config_get('server.hostname')"), next_hop: IfBlock::new::<()>( "queue.outbound.next-hop", #[cfg(not(feature = "test_mode"))] @@ -187,12 +183,12 @@ impl Default for QueueConfig { address: IfBlock::new::<()>( "report.dsn.from-address", [], - "'MAILER-DAEMON@' + key_get('default', 'domain')", + "'MAILER-DAEMON@' + config_get('report.domain')", ), sign: IfBlock::new::<()>( "report.dsn.sign", [], - "['rsa-' + key_get('default', 'domain'), 'ed25519-' + key_get('default', 'domain')]", + "['rsa-' + config_get('report.domain'), 'ed25519-' + config_get('report.domain')]", ), }, timeout: QueueOutboundTimeout { diff --git a/crates/common/src/config/smtp/report.rs b/crates/common/src/config/smtp/report.rs index 4f81c3c28..b442d74ba 100644 --- a/crates/common/src/config/smtp/report.rs +++ b/crates/common/src/config/smtp/report.rs @@ -79,7 +79,7 @@ impl ReportConfig { &TokenMap::default().with_variables(RCPT_DOMAIN_VARS), ) .unwrap_or_else(|| { - IfBlock::new::<()>("report.submitter", [], "key_get('default', 'hostname')") + IfBlock::new::<()>("report.submitter", [], "config_get('server.hostname')") }), analysis: ReportAnalysis { addresses: config @@ -118,7 +118,7 @@ impl Report { address: IfBlock::new::<()>( format!("report.{id}.from-address"), [], - format!("'noreply-{id}@' + key_get('default', 'domain')"), + format!("'noreply-{id}@' + config_get('report.domain')"), ), subject: IfBlock::new::<()>( format!("report.{id}.subject"), @@ -131,7 +131,7 @@ impl Report { sign: IfBlock::new::<()>( format!("report.{id}.sign"), [], - "['rsa-' + key_get('default', 'domain'), 'ed25519-' + key_get('default', 'domain')]", + "['rsa-' + config_get('report.domain'), 'ed25519-' + config_get('report.domain')]", ), send: IfBlock::new::<()>(format!("report.{id}.send"), [], "[1, 1d]"), }; @@ -164,12 +164,12 @@ impl AggregateReport { address: IfBlock::new::<()>( format!("report.{id}.aggregate.from-address"), [], - format!("'noreply-{id}@' + key_get('default', 'domain')"), + format!("'noreply-{id}@' + config_get('report.domain')"), ), org_name: IfBlock::new::<()>( format!("report.{id}.aggregate.org-name"), [], - "key_get('default', 'domain')", + "config_get('report.domain')", ), contact_info: IfBlock::empty(format!("report.{id}.aggregate.contact-info")), send: IfBlock::new::( @@ -180,7 +180,7 @@ impl AggregateReport { sign: IfBlock::new::<()>( format!("report.{id}.aggregate.sign"), [], - "['rsa-' + key_get('default', 'domain'), 'ed25519-' + key_get('default', 'domain')]", + "['rsa-' + config_get('report.domain'), 'ed25519-' + config_get('report.domain')]", ), max_size: IfBlock::new::<()>(format!("report.{id}.aggregate.max-size"), [], "26214400"), }; diff --git a/crates/common/src/config/smtp/session.rs b/crates/common/src/config/smtp/session.rs index c49998d30..a02750096 100644 --- a/crates/common/src/config/smtp/session.rs +++ b/crates/common/src/config/smtp/session.rs @@ -702,13 +702,13 @@ impl Default for SessionConfig { hostname: IfBlock::new::<()>( "server.connect.hostname", [], - "key_get('default', 'hostname')", + "config_get('server.hostname')", ), script: IfBlock::empty("session.connect.script"), greeting: IfBlock::new::<()>( "session.connect.greeting", [], - "key_get('default', 'hostname') + ' Stalwart ESMTP at your service'", + "config_get('server.hostname') + ' Stalwart ESMTP at your service'", ), }, ehlo: Ehlo { diff --git a/crates/common/src/enterprise/config.rs b/crates/common/src/enterprise/config.rs index 244572ebe..e9b8f192b 100644 --- a/crates/common/src/enterprise/config.rs +++ b/crates/common/src/enterprise/config.rs @@ -37,7 +37,9 @@ impl Enterprise { stores: &Stores, data: &Store, ) -> Option { - let server_hostname = config.value("lookup.default.hostname")?; + let server_hostname = config + .value("server.hostname") + .or_else(|| config.value("lookup.default.hostname"))?; let mut update_license = None; let license_result = match ( diff --git a/crates/common/src/expr/eval.rs b/crates/common/src/expr/eval.rs index 79f63926b..a8a518551 100644 --- a/crates/common/src/expr/eval.rs +++ b/crates/common/src/expr/eval.rs @@ -14,12 +14,12 @@ use crate::Server; use super::{ functions::{ResolveVariable, FUNCTIONS}, if_block::IfBlock, - BinaryOperator, Constant, Expression, ExpressionItem, UnaryOperator, Variable, + BinaryOperator, Constant, Expression, ExpressionItem, Setting, UnaryOperator, Variable, }; impl Server { pub async fn eval_if<'x, R: TryFrom>, V: ResolveVariable>( - &self, + &'x self, if_block: &'x IfBlock, resolver: &'x V, session_id: u64, @@ -81,7 +81,7 @@ impl Server { } pub async fn eval_expr<'x, R: TryFrom>, V: ResolveVariable>( - &self, + &'x self, expr: &'x Expression, resolver: &'x V, expr_id: &str, @@ -137,15 +137,15 @@ impl Server { } } -struct EvalContext<'x, 'y, V: ResolveVariable, T, C> { +struct EvalContext<'x, V: ResolveVariable, T, C> { resolver: &'x V, - core: &'y Server, + core: &'x Server, expr: &'x T, captures: C, session_id: u64, } -impl<'x, V: ResolveVariable> EvalContext<'x, '_, V, IfBlock, Vec> { +impl<'x, V: ResolveVariable> EvalContext<'x, V, IfBlock, Vec> { async fn eval(&mut self) -> trc::Result> { for if_then in &self.expr.if_then { if (EvalContext { @@ -183,7 +183,7 @@ impl<'x, V: ResolveVariable> EvalContext<'x, '_, V, IfBlock, Vec> { } } -impl<'x, V: ResolveVariable> EvalContext<'x, '_, V, Expression, &mut Vec> { +impl<'x, V: ResolveVariable> EvalContext<'x, V, Expression, &mut Vec> { async fn eval(&mut self) -> trc::Result> { let mut stack = Vec::new(); let mut exprs = self.expr.items.iter(); @@ -208,6 +208,25 @@ impl<'x, V: ResolveVariable> EvalContext<'x, '_, V, Expression, &mut Vec .to_string(), ))); } + ExpressionItem::Setting(setting) => match setting { + Setting::Hostname => { + stack.push(self.core.core.network.server_name.as_str().into()) + } + Setting::ReportDomain => { + stack.push(self.core.core.network.report_domain.as_str().into()) + } + Setting::NodeId => stack.push(self.core.core.network.node_id.into()), + Setting::Other(key) => stack.push( + self.core + .core + .storage + .config + .get(key) + .await? + .unwrap_or_default() + .into(), + ), + }, ExpressionItem::UnaryOperator(op) => { let value = stack.pop().unwrap_or_default(); stack.push(match op { diff --git a/crates/common/src/expr/mod.rs b/crates/common/src/expr/mod.rs index de0b37574..19ed51bdf 100644 --- a/crates/common/src/expr/mod.rs +++ b/crates/common/src/expr/mod.rs @@ -88,6 +88,7 @@ pub struct Expression { pub enum ExpressionItem { Variable(u32), Global(String), + Setting(Setting), Capture(u32), Constant(Constant), BinaryOperator(BinaryOperator), @@ -200,6 +201,7 @@ pub enum Token { num_args: u32, }, Constant(Constant), + Setting(Setting), Regex(Regex), BinaryOperator(BinaryOperator), UnaryOperator(UnaryOperator), @@ -210,6 +212,25 @@ pub enum Token { Comma, } +#[derive(Debug, Clone)] +pub enum Setting { + Hostname, + ReportDomain, + NodeId, + Other(String), +} + +impl From for Setting { + fn from(value: String) -> Self { + match value.as_str() { + "server.hostname" => Setting::Hostname, + "report.domain" => Setting::ReportDomain, + "cluster.node-id" => Setting::NodeId, + _ => Setting::Other(value), + } + } +} + impl From for Variable<'_> { fn from(value: usize) -> Self { Variable::Integer(value as i64) diff --git a/crates/common/src/expr/parser.rs b/crates/common/src/expr/parser.rs index 552144384..63d2c71b4 100644 --- a/crates/common/src/expr/parser.rs +++ b/crates/common/src/expr/parser.rs @@ -109,6 +109,16 @@ impl<'x> ExpressionParser<'x> { self.output.push(ExpressionItem::Regex(regex.clone())); self.operator_stack.pop(); } + Some((Token::Setting(setting), _)) => { + if self.arg_count.pop().unwrap() != 0 { + return Err( + "Expression function \"config_get\" expected 1 argument" + .to_string(), + ); + } + self.output.push(ExpressionItem::Setting(setting.clone())); + self.operator_stack.pop(); + } _ => {} } @@ -156,16 +166,10 @@ impl<'x> ExpressionParser<'x> { self.operator_stack .push((Token::BinaryOperator(bop), jmp_pos)); } - Token::Function { id, name, num_args } => { - self.inc_arg_count(); - self.arg_count.push(0); - self.operator_stack - .push((Token::Function { id, name, num_args }, None)) - } - Token::Regex(regex) => { + token @ (Token::Function { .. } | Token::Regex(_) | Token::Setting(_)) => { self.inc_arg_count(); self.arg_count.push(0); - self.operator_stack.push((Token::Regex(regex), None)) + self.operator_stack.push((token, None)) } Token::OpenBracket => { // Array functions diff --git a/crates/common/src/expr/tokenizer.rs b/crates/common/src/expr/tokenizer.rs index b7534c5d6..c050cbd23 100644 --- a/crates/common/src/expr/tokenizer.rs +++ b/crates/common/src/expr/tokenizer.rs @@ -100,6 +100,13 @@ impl<'x> Tokenizer<'x> { self.buf.clear(); self.find_char(b",")?; (Token::Regex(regex).into(), b'(') + } else if ch == b'(' && self.buf.eq(b"config_get") { + // Parse setting + let stop_ch = self.find_char(b"\"'")?; + let setting_str = self.parse_string(stop_ch)?; + self.has_alpha = false; + self.buf.clear(); + (Token::Setting(Setting::from(setting_str)).into(), b'(') } else if !self.buf.is_empty() { self.is_start = false; (self.parse_buf()?.into(), ch) diff --git a/crates/common/src/manager/boot.rs b/crates/common/src/manager/boot.rs index 17b528372..b0fd1b42b 100644 --- a/crates/common/src/manager/boot.rs +++ b/crates/common/src/manager/boot.rs @@ -195,18 +195,6 @@ impl BootManager { StoreOp::None => { // Add hostname lookup if missing let mut insert_keys = Vec::new(); - if config - .value("lookup.default.hostname") - .filter(|v| !v.is_empty()) - .is_none() - { - insert_keys.push(ConfigKey::from(( - "lookup.default.hostname", - hostname::get() - .map(|v| v.to_string_lossy().into_owned()) - .unwrap_or_else(|_| "localhost".to_string()), - ))); - } // Generate an OAuth key if missing if config diff --git a/crates/common/src/manager/config.rs b/crates/common/src/manager/config.rs index 351d8eeb9..97945965f 100644 --- a/crates/common/src/manager/config.rs +++ b/crates/common/src/manager/config.rs @@ -423,7 +423,7 @@ impl ConfigManager { required_semver = value.as_str().try_into().unwrap_or_default(); } else if key.starts_with("spam-filter.") || key.starts_with("http-lookup.") - || (key.starts_with("lookup.") && !key.starts_with("lookup.default.")) + || key.starts_with("lookup.") || key.starts_with("asn.") { external.keys.push(ConfigKey::from((key, value))); @@ -537,7 +537,6 @@ impl Patterns { Pattern::Include(MatchType::Equal("storage.lookup".to_string())), Pattern::Include(MatchType::Equal("storage.fts".to_string())), Pattern::Include(MatchType::Equal("storage.directory".to_string())), - Pattern::Include(MatchType::Equal("lookup.default.hostname".to_string())), Pattern::Include(MatchType::Equal("enterprise.license-key".to_string())), ]; } diff --git a/crates/directory/src/backend/smtp/config.rs b/crates/directory/src/backend/smtp/config.rs index d5248f765..cdb75575d 100644 --- a/crates/directory/src/backend/smtp/config.rs +++ b/crates/directory/src/backend/smtp/config.rs @@ -40,7 +40,7 @@ impl SmtpDirectory { is_lmtp, credentials: None, local_host: config - .value("lookup.default.hostname") + .value("server.hostname") .unwrap_or("[127.0.0.1]") .to_string(), say_ehlo: false, diff --git a/crates/jmap/src/api/autoconfig.rs b/crates/jmap/src/api/autoconfig.rs index f1b2d9eff..101f3b857 100644 --- a/crates/jmap/src/api/autoconfig.rs +++ b/crates/jmap/src/api/autoconfig.rs @@ -180,17 +180,7 @@ impl Autoconfig for Server { })?; // Obtain server name - let server_name = self - .core - .storage - .config - .get("lookup.default.hostname") - .await? - .ok_or_else(|| { - trc::EventType::Config(trc::ConfigEvent::BuildError) - .caused_by(trc::location!()) - .details("Server name not configured") - })?; + let server_name = self.core.network.server_name.to_string(); // Find the account name by e-mail address let mut account_name = emailaddress.to_string(); diff --git a/crates/jmap/src/api/management/dns.rs b/crates/jmap/src/api/management/dns.rs index 420e02377..5703e35bc 100644 --- a/crates/jmap/src/api/management/dns.rs +++ b/crates/jmap/src/api/management/dns.rs @@ -77,13 +77,7 @@ impl DnsManagement for Server { async fn build_dns_records(&self, domain_name: &str) -> trc::Result> { // Obtain server name - let server_name = self - .core - .storage - .config - .get("lookup.default.hostname") - .await? - .unwrap_or_else(|| "localhost".to_string()); + let server_name = &self.core.network.server_name; let mut records = Vec::new(); // Obtain DKIM keys diff --git a/crates/jmap/src/api/management/principal.rs b/crates/jmap/src/api/management/principal.rs index cae93666c..2893ce0d5 100644 --- a/crates/jmap/src/api/management/principal.rs +++ b/crates/jmap/src/api/management/principal.rs @@ -146,6 +146,21 @@ impl PrincipalManager for Server { } } + // Set default report domain if missing + let report_domain = if principal.typ() == Type::Domain + && self + .core + .storage + .config + .get("report.domain") + .await + .is_ok_and(|v| v.is_none()) + { + principal.name().to_lowercase().into() + } else { + None + }; + // Create principal let result = self .core @@ -154,6 +169,19 @@ impl PrincipalManager for Server { .create_principal(principal, tenant_id, Some(&access_token.permissions)) .await?; + // Set report domain + if let Some(report_domain) = report_domain { + if let Err(err) = self + .core + .storage + .config + .set([("report.domain", report_domain)], true) + .await + { + trc::error!(err.details("Failed to set report domain")); + } + } + Ok(JsonResponse::new(json!({ "data": result, })) diff --git a/crates/jmap/src/api/management/spam.rs b/crates/jmap/src/api/management/spam.rs index 5c0dbd2ee..cc2c999fe 100644 --- a/crates/jmap/src/api/management/spam.rs +++ b/crates/jmap/src/api/management/spam.rs @@ -132,14 +132,7 @@ impl ManageSpamHandler for Server { let ehlo_domain = request.ehlo_domain.to_lowercase(); let mail_from = request.env_from.to_lowercase(); let mail_from_domain = mail_from.rsplit_once('@').map(|(_, domain)| domain); - let local_host = self - .core - .storage - .config - .get("lookup.default.hostname") - .await - .unwrap_or_default() - .unwrap_or_else(|| "local.host".to_string()); + let local_host = &self.core.network.server_name; let spf_ehlo_result = self.core @@ -147,7 +140,7 @@ impl ManageSpamHandler for Server { .resolvers .dns .verify_spf(self.inner.cache.build_auth_parameters( - SpfParameters::verify_ehlo(remote_ip, &ehlo_domain, &local_host), + SpfParameters::verify_ehlo(remote_ip, &ehlo_domain, local_host), )) .await; @@ -168,7 +161,7 @@ impl ManageSpamHandler for Server { remote_ip, mail_from_domain, &ehlo_domain, - &local_host, + local_host, &mail_from, ))) .await @@ -181,7 +174,7 @@ impl ManageSpamHandler for Server { remote_ip, &ehlo_domain, &ehlo_domain, - &local_host, + local_host, &format!("postmaster@{ehlo_domain}"), ))) .await diff --git a/crates/jmap/src/api/management/troubleshoot.rs b/crates/jmap/src/api/management/troubleshoot.rs index 179671909..b9efa7cf5 100644 --- a/crates/jmap/src/api/management/troubleshoot.rs +++ b/crates/jmap/src/api/management/troubleshoot.rs @@ -318,14 +318,7 @@ async fn delivery_troubleshoot( (domain_or_email, None) }; - let local_host = server - .core - .storage - .config - .get("lookup.default.hostname") - .await - .unwrap_or_default() - .unwrap_or_else(|| "local.host".to_string()); + let local_host = &server.core.network.server_name; tx.send(DeliveryStage::MxLookupStart { domain: domain.to_string(), @@ -897,14 +890,7 @@ async fn dmarc_troubleshoot( let mail_from = request.mail_from.to_lowercase(); let mail_from_domain = mail_from.rsplit_once('@').map(|(_, domain)| domain); - let local_host = server - .core - .storage - .config - .get("lookup.default.hostname") - .await - .unwrap_or_default() - .unwrap_or_else(|| "local.host".to_string()); + let local_host = &server.core.network.server_name; let now = Instant::now(); let ehlo_spf_output = server @@ -919,7 +905,7 @@ async fn dmarc_troubleshoot( .build_auth_parameters(SpfParameters::verify_ehlo( remote_ip, &ehlo_domain, - &local_host, + local_host, )), ) .await; @@ -941,7 +927,7 @@ async fn dmarc_troubleshoot( remote_ip, mail_from_domain, &ehlo_domain, - &local_host, + local_host, &mail_from, ))) .await @@ -955,7 +941,7 @@ async fn dmarc_troubleshoot( remote_ip, &ehlo_domain, &ehlo_domain, - &local_host, + local_host, &format!("postmaster@{ehlo_domain}"), ))) .await diff --git a/tests/src/imap/mod.rs b/tests/src/imap/mod.rs index 25c1b6703..d88a63527 100644 --- a/tests/src/imap/mod.rs +++ b/tests/src/imap/mod.rs @@ -56,7 +56,7 @@ use crate::{ }; const SERVER: &str = r#" -[lookup.default] +[server] hostname = "imap.example.org" [server.listener.imap] diff --git a/tests/src/smtp/reporting/dmarc.rs b/tests/src/smtp/reporting/dmarc.rs index d7c0f3648..93e2f1b32 100644 --- a/tests/src/smtp/reporting/dmarc.rs +++ b/tests/src/smtp/reporting/dmarc.rs @@ -29,15 +29,15 @@ const CONFIG: &str = r#" [session.rcpt] relay = true -[lookup.default] -domain = "example.org" +[server] +hostname = "mx.example.org" [report] submitter = "'mx.example.org'" [report.dmarc.aggregate] from-name = "'DMARC Report'" -from-address = "'reports@' + key_get('default', 'domain')" +from-address = "'reports@' + config_get('report.domain')" org-name = "'Foobar, Inc.'" contact-info = "'https://foobar.org/contact'" send = "daily"