diff options
Diffstat (limited to 'tests/src/smtp/inbound')
-rw-r--r-- | tests/src/smtp/inbound/auth.rs | 4 | ||||
-rw-r--r-- | tests/src/smtp/inbound/data.rs | 6 | ||||
-rw-r--r-- | tests/src/smtp/inbound/dmarc.rs | 20 | ||||
-rw-r--r-- | tests/src/smtp/inbound/milter.rs | 10 | ||||
-rw-r--r-- | tests/src/smtp/inbound/mod.rs | 1 | ||||
-rw-r--r-- | tests/src/smtp/inbound/rcpt.rs | 6 | ||||
-rw-r--r-- | tests/src/smtp/inbound/rewrite.rs | 169 | ||||
-rw-r--r-- | tests/src/smtp/inbound/sign.rs | 16 | ||||
-rw-r--r-- | tests/src/smtp/inbound/vrfy.rs | 6 |
9 files changed, 213 insertions, 25 deletions
diff --git a/tests/src/smtp/inbound/auth.rs b/tests/src/smtp/inbound/auth.rs index 8cf014d0..013cccd8 100644 --- a/tests/src/smtp/inbound/auth.rs +++ b/tests/src/smtp/inbound/auth.rs @@ -23,7 +23,7 @@ use directory::config::ConfigDirectory; use smtp_proto::{AUTH_LOGIN, AUTH_PLAIN}; -use utils::config::Config; +use utils::config::{Config, DynValue}; use crate::smtp::{ session::{TestSession, VerifyResponse}, @@ -68,7 +68,7 @@ async fn auth() { .parse_if(&ctx); config.directory = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 'local'}, {else = false}]" - .parse_if::<Option<String>>(&ctx) + .parse_if::<Option<DynValue>>(&ctx) .map_if_block(&ctx.directory.directories, "", "") .unwrap(); config.errors_max = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 2}, diff --git a/tests/src/smtp/inbound/data.rs b/tests/src/smtp/inbound/data.rs index 411cbbed..c8169160 100644 --- a/tests/src/smtp/inbound/data.rs +++ b/tests/src/smtp/inbound/data.rs @@ -30,7 +30,7 @@ use crate::smtp::{ ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ - config::{ConfigContext, IfBlock}, + config::{ConfigContext, IfBlock, MaybeDynValue}, core::{Session, SMTP}, }; @@ -81,7 +81,9 @@ async fn data() { let mut qr = core.init_test_queue("smtp_data_test"); let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap(); let mut config = &mut core.session.config.rcpt; - config.directory = IfBlock::new(Some(directory.directories.get("local").unwrap().clone())); + config.directory = IfBlock::new(Some(MaybeDynValue::Static( + directory.directories.get("local").unwrap().clone(), + ))); let mut config = &mut core.session.config; config.data.add_auth_results = "[{if = 'remote-ip', eq = '10.0.0.3', then = true}, diff --git a/tests/src/smtp/inbound/dmarc.rs b/tests/src/smtp/inbound/dmarc.rs index d070e294..eadc1eac 100644 --- a/tests/src/smtp/inbound/dmarc.rs +++ b/tests/src/smtp/inbound/dmarc.rs @@ -34,7 +34,7 @@ use mail_auth::{ report::DmarcResult, spf::Spf, }; -use utils::config::{Config, Rate}; +use utils::config::{Config, DynValue, Rate}; use crate::smtp::{ inbound::{sign::TextConfigContext, TestMessage, TestQueueEvent, TestReportingEvent}, @@ -42,7 +42,7 @@ use crate::smtp::{ ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ - config::{AggregateFrequency, ConfigContext, IfBlock, VerifyStrategy}, + config::{AggregateFrequency, ConfigContext, IfBlock, MaybeDynValue, VerifyStrategy}, core::{Session, SMTP}, }; @@ -134,7 +134,9 @@ async fn dmarc() { let mut rr = core.init_test_report(); let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap(); let mut config = &mut core.session.config.rcpt; - config.directory = IfBlock::new(Some(directory.directories.get("local").unwrap().clone())); + config.directory = IfBlock::new(Some(MaybeDynValue::Static( + directory.directories.get("local").unwrap().clone(), + ))); let mut config = &mut core.session.config; config.data.add_auth_results = IfBlock::new(true); @@ -166,11 +168,17 @@ async fn dmarc() { let mut config = &mut core.report.config; config.spf.sign = "['rsa']" - .parse_if::<Vec<String>>(&ctx) + .parse_if::<Vec<DynValue>>(&ctx) + .map_if_block(&ctx.signers, "", "") + .unwrap(); + config.dmarc.sign = "['rsa']" + .parse_if::<Vec<DynValue>>(&ctx) + .map_if_block(&ctx.signers, "", "") + .unwrap(); + config.dkim.sign = "['rsa']" + .parse_if::<Vec<DynValue>>(&ctx) .map_if_block(&ctx.signers, "", "") .unwrap(); - config.dmarc.sign = config.spf.sign.clone(); - config.dkim.sign = config.spf.sign.clone(); // SPF must pass let core = Arc::new(core); diff --git a/tests/src/smtp/inbound/milter.rs b/tests/src/smtp/inbound/milter.rs index d9622678..fad22580 100644 --- a/tests/src/smtp/inbound/milter.rs +++ b/tests/src/smtp/inbound/milter.rs @@ -212,7 +212,7 @@ fn milter_address_modifications() { // ChangeFrom assert!(data - .apply_modifications( + .apply_milter_modifications( vec![Modification::ChangeFrom { sender: "<>".to_string(), args: String::new() @@ -227,7 +227,7 @@ fn milter_address_modifications() { // ChangeFrom with parameters assert!(data - .apply_modifications( + .apply_milter_modifications( vec![Modification::ChangeFrom { sender: "john@example.org".to_string(), args: "REQUIRETLS ENVID=abc123".to_string(), //"NOTIFY=SUCCESS,FAILURE ENVID=abc123\n".to_string() @@ -242,7 +242,7 @@ fn milter_address_modifications() { // Add recipients assert!(data - .apply_modifications( + .apply_milter_modifications( vec![ Modification::AddRcpt { recipient: "bill@example.org".to_string(), @@ -276,7 +276,7 @@ fn milter_address_modifications() { // Remove recipients assert!(data - .apply_modifications( + .apply_milter_modifications( vec![ Modification::DeleteRcpt { recipient: "bill@example.org".to_string(), @@ -319,7 +319,7 @@ fn milter_message_modifications() { test.result, String::from_utf8( session_data - .apply_modifications(test.modifications, &parsed_test_message) + .apply_milter_modifications(test.modifications, &parsed_test_message) .unwrap() ) .unwrap() diff --git a/tests/src/smtp/inbound/mod.rs b/tests/src/smtp/inbound/mod.rs index eb0fad89..0032c91f 100644 --- a/tests/src/smtp/inbound/mod.rs +++ b/tests/src/smtp/inbound/mod.rs @@ -42,6 +42,7 @@ pub mod limits; pub mod mail; pub mod milter; pub mod rcpt; +pub mod rewrite; pub mod scripts; pub mod sign; pub mod throttle; diff --git a/tests/src/smtp/inbound/rcpt.rs b/tests/src/smtp/inbound/rcpt.rs index 3441f183..80b50deb 100644 --- a/tests/src/smtp/inbound/rcpt.rs +++ b/tests/src/smtp/inbound/rcpt.rs @@ -32,7 +32,7 @@ use crate::smtp::{ ParseTestConfig, TestConfig, }; use smtp::{ - config::{ConfigContext, IfBlock}, + config::{ConfigContext, IfBlock, MaybeDynValue}, core::{Session, State, SMTP}, }; @@ -75,7 +75,9 @@ async fn rcpt() { let mut config_ext = &mut core.session.config.extensions; let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap(); let mut config = &mut core.session.config.rcpt; - config.directory = IfBlock::new(Some(directory.directories.get("local").unwrap().clone())); + config.directory = IfBlock::new(Some(MaybeDynValue::Static( + directory.directories.get("local").unwrap().clone(), + ))); config.max_recipients = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 3}, {else = 5}]" .parse_if(&ConfigContext::new(&[])); diff --git a/tests/src/smtp/inbound/rewrite.rs b/tests/src/smtp/inbound/rewrite.rs new file mode 100644 index 00000000..eb895f58 --- /dev/null +++ b/tests/src/smtp/inbound/rewrite.rs @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2023 Stalwart Labs Ltd. + * + * This file is part of Stalwart Mail Server. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * in the LICENSE file at the top-level directory of this distribution. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * You can be released from the requirements of the AGPLv3 license by + * purchasing a commercial license. Please contact licensing@stalw.art + * for more details. +*/ + +use crate::smtp::{inbound::sign::TextConfigContext, session::TestSession, TestConfig}; +use directory::config::ConfigDirectory; +use smtp::{ + config::{if_block::ConfigIf, scripts::ConfigSieve, ConfigContext, EnvelopeKey, IfBlock}, + core::{Session, SMTP}, +}; +use utils::config::{Config, DynValue}; + +const CONFIG: &str = r#" +[session.mail] +rewrite = [ { all-of = [ { if = "sender-domain", ends-with = ".foobar.net" }, + { if = "sender", matches = "^([^.]+)@([^.]+)\.(.+)$"}, + ], then = "${1}+${2}@${3}" }, + { else = false } ] +script = [ { if = "sender-domain", eq = "foobar.org", then = "mail" }, + { else = false } ] + +[session.rcpt] +rewrite = [ { all-of = [ { if = "rcpt-domain", eq = "foobar.net" }, + { if = "rcpt", matches = "^([^.]+)\.([^.]+)@(.+)$"}, + ], then = "${1}+${2}@${3}" }, + { else = false } ] +script = [ { if = "rcpt-domain", eq = "foobar.org", then = "rcpt" }, + { else = false } ] + +[sieve] +from-name = "Sieve Daemon" +from-addr = "sieve@foobar.org" +return-path = "" +hostname = "mx.foobar.org" + +[sieve.limits] +redirects = 3 +out-messages = 5 +received-headers = 50 +cpu = 10000 +nested-includes = 5 +duplicate-expiry = "7d" + +[sieve.scripts] +mail = ''' +require ["variables", "envelope"]; + +if allof( envelope :domain :is "from" "foobar.org", + envelope :localpart :contains "from" "admin" ) { + set "envelope.from" "MAILER-DAEMON@foobar.org"; +} + +''' + +rcpt = ''' +require ["variables", "envelope", "regex"]; + +if allof( envelope :localpart :contains "to" ".", + envelope :regex "to" "(.+)@(.+)$") { + set :replace "." "" "to" "${1}"; + set "envelope.to" "${to}@${2}"; +} + +''' + +"#; + +#[tokio::test] +async fn address_rewrite() { + /*tracing::subscriber::set_global_default( + tracing_subscriber::FmtSubscriber::builder() + .with_max_level(tracing::Level::TRACE) + .finish(), + ) + .unwrap();*/ + + // Prepare config + let available_keys = [ + EnvelopeKey::Sender, + EnvelopeKey::SenderDomain, + EnvelopeKey::Recipient, + EnvelopeKey::RecipientDomain, + ]; + let mut core = SMTP::test(); + let mut ctx = ConfigContext::new(&[]).parse_signatures(); + let settings = Config::parse(CONFIG).unwrap(); + ctx.directory = settings.parse_directory().unwrap(); + core.sieve = settings.parse_sieve(&mut ctx).unwrap(); + let config = &mut core.session.config; + config.mail.script = settings + .parse_if_block::<Option<String>>("session.mail.script", &ctx, &available_keys) + .unwrap() + .unwrap_or_default() + .map_if_block(&ctx.scripts, "session.mail.script", "script") + .unwrap(); + config.mail.rewrite = settings + .parse_if_block::<Option<DynValue>>("session.mail.rewrite", &ctx, &available_keys) + .unwrap() + .unwrap_or_default(); + config.rcpt.script = settings + .parse_if_block::<Option<String>>("session.rcpt.script", &ctx, &available_keys) + .unwrap() + .unwrap_or_default() + .map_if_block(&ctx.scripts, "session.rcpt.script", "script") + .unwrap(); + config.rcpt.rewrite = settings + .parse_if_block::<Option<DynValue>>("session.rcpt.rewrite", &ctx, &available_keys) + .unwrap() + .unwrap_or_default(); + config.rcpt.relay = IfBlock::new(true); + + // Init session + let mut session = Session::test(core); + session.data.remote_ip = "10.0.0.1".parse().unwrap(); + session.eval_session_params().await; + session.ehlo("mx.doe.org").await; + + // Sender rewrite using regex + session.mail_from("bill@doe.foobar.net", "250").await; + assert_eq!( + session.data.mail_from.as_ref().unwrap().address, + "bill+doe@foobar.net" + ); + session.reset(); + + // Sender rewrite using sieve + session.mail_from("this_is_admin@foobar.org", "250").await; + assert_eq!( + session.data.mail_from.as_ref().unwrap().address_lcase, + "mailer-daemon@foobar.org" + ); + + // Recipient rewrite using regex + session.rcpt_to("mary.smith@foobar.net", "250").await; + assert_eq!( + session.data.rcpt_to.last().unwrap().address, + "mary+smith@foobar.net" + ); + + // Remove duplicates + session.rcpt_to("mary.smith@foobar.net", "250").await; + assert_eq!(session.data.rcpt_to.len(), 1); + + // Recipient rewrite using sieve + session.rcpt_to("m.a.r.y.s.m.i.t.h@foobar.org", "250").await; + assert_eq!( + session.data.rcpt_to.last().unwrap().address, + "marysmith@foobar.org" + ); +} diff --git a/tests/src/smtp/inbound/sign.rs b/tests/src/smtp/inbound/sign.rs index 11c70cbe..6da52cc4 100644 --- a/tests/src/smtp/inbound/sign.rs +++ b/tests/src/smtp/inbound/sign.rs @@ -28,7 +28,7 @@ use mail_auth::{ common::{parse::TxtRecordParser, verify::DomainKey}, spf::Spf, }; -use utils::config::Config; +use utils::config::{Config, DynValue}; use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, @@ -36,7 +36,7 @@ use crate::smtp::{ ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ - config::{auth::ConfigAuth, ConfigContext, IfBlock, VerifyStrategy}, + config::{auth::ConfigAuth, ConfigContext, IfBlock, MaybeDynValue, VerifyStrategy}, core::{Session, SMTP}, }; @@ -81,7 +81,9 @@ report = true [signature.ed] public-key = '11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=' -private-key = 'nWGxne/9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A=' +private-key = '-----BEGIN PRIVATE KEY----- +nWGxne/9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A= +-----END PRIVATE KEY-----' domain = 'example.com' selector = 'ed' headers = ['From', 'To', 'Date', 'Subject', 'Message-ID'] @@ -152,7 +154,9 @@ async fn sign_and_seal() { let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap(); let mut config = &mut core.session.config.rcpt; - config.directory = IfBlock::new(Some(directory.directories.get("local").unwrap().clone())); + config.directory = IfBlock::new(Some(MaybeDynValue::Static( + directory.directories.get("local").unwrap().clone(), + ))); let mut config = &mut core.session.config; config.data.add_auth_results = IfBlock::new(true); @@ -170,11 +174,11 @@ async fn sign_and_seal() { config.arc.verify = config.spf.verify_ehlo.clone(); config.dmarc.verify = config.spf.verify_ehlo.clone(); config.dkim.sign = "['rsa']" - .parse_if::<Vec<String>>(&ctx) + .parse_if::<Vec<DynValue>>(&ctx) .map_if_block(&ctx.signers, "", "") .unwrap(); config.arc.seal = "'ed'" - .parse_if::<Option<String>>(&ctx) + .parse_if::<Option<DynValue>>(&ctx) .map_if_block(&ctx.sealers, "", "") .unwrap(); diff --git a/tests/src/smtp/inbound/vrfy.rs b/tests/src/smtp/inbound/vrfy.rs index 3acbb6bb..d88414dc 100644 --- a/tests/src/smtp/inbound/vrfy.rs +++ b/tests/src/smtp/inbound/vrfy.rs @@ -29,7 +29,7 @@ use crate::smtp::{ ParseTestConfig, TestConfig, }; use smtp::{ - config::{ConfigContext, IfBlock}, + config::{ConfigContext, IfBlock, MaybeDynValue}, core::{Session, SMTP}, }; @@ -67,7 +67,9 @@ async fn vrfy_expn() { let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap(); let mut config = &mut core.session.config.rcpt; - config.directory = IfBlock::new(Some(directory.directories.get("local").unwrap().clone())); + config.directory = IfBlock::new(Some(MaybeDynValue::Static( + directory.directories.get("local").unwrap().clone(), + ))); let mut config = &mut core.session.config.extensions; config.vrfy = r"[{if = 'remote-ip', eq = '10.0.0.1', then = true}, |