From 3081958765dd7b2a24066fe0f20d56c1797962ee Mon Sep 17 00:00:00 2001 From: mdecimus Date: Thu, 7 Mar 2024 16:57:53 +0100 Subject: [PATCH] Escape regexes within matches() (#155) --- crates/utils/src/expr/eval.rs | 2 +- resources/config/directory/internal.toml | 2 +- resources/config/directory/ldap.toml | 2 +- resources/config/directory/memory.toml | 2 +- resources/config/directory/sql.toml | 2 +- resources/config/smtp/session.toml | 4 ++-- tests/src/directory/mod.rs | 14 +++++++++++++- tests/src/smtp/inbound/rewrite.rs | 2 +- 8 files changed, 21 insertions(+), 9 deletions(-) diff --git a/crates/utils/src/expr/eval.rs b/crates/utils/src/expr/eval.rs index df889fc0..453212f9 100644 --- a/crates/utils/src/expr/eval.rs +++ b/crates/utils/src/expr/eval.rs @@ -130,7 +130,7 @@ impl Expression { captures.clear(); let value = stack.pop().unwrap_or_default().into_string(); - for captures_ in regex.captures_iter(value.as_ref()) { + if let Some(captures_) = regex.captures(value.as_ref()) { for capture in captures_.iter() { captures.push(capture.map_or("", |m| m.as_str()).to_string()); } diff --git a/resources/config/directory/internal.toml b/resources/config/directory/internal.toml index 7cbbe7a3..0ca96d21 100644 --- a/resources/config/directory/internal.toml +++ b/resources/config/directory/internal.toml @@ -12,7 +12,7 @@ catch-all = true #catch-all = [ { if = "matches('(.+)@(.+)$', address)", then = "'info@' + $2" }, # { else = false } ] subaddressing = true -#subaddressing = [ { if = "matches('^([^.]+)\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, +#subaddressing = [ { if = "matches('^([^.]+)\\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, # { else = false } ] [directory."internal".cache] diff --git a/resources/config/directory/ldap.toml b/resources/config/directory/ldap.toml index 85dd75ae..bb55c5e8 100644 --- a/resources/config/directory/ldap.toml +++ b/resources/config/directory/ldap.toml @@ -30,7 +30,7 @@ catch-all = true #catch-all = [ { if = "matches('(.+)@(.+)$', address)", then = "'info@' + $2" }, # { else = false } ] subaddressing = true -#subaddressing = [ { if = "matches('^([^.]+)\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, +#subaddressing = [ { if = "matches('^([^.]+)\\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, # { else = false } ] [directory."ldap".pool] diff --git a/resources/config/directory/memory.toml b/resources/config/directory/memory.toml index ea13bc58..cb5bbb88 100644 --- a/resources/config/directory/memory.toml +++ b/resources/config/directory/memory.toml @@ -11,7 +11,7 @@ catch-all = true #catch-all = [ { if = "matches('(.+)@(.+)$', address)", then = "'info@' + $2" }, # { else = false } ] subaddressing = true -#subaddressing = [ { if = "matches('^([^.]+)\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, +#subaddressing = [ { if = "matches('^([^.]+)\\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, # { else = false } ] [[directory."memory".principals]] diff --git a/resources/config/directory/sql.toml b/resources/config/directory/sql.toml index 25941dee..49f0f06d 100644 --- a/resources/config/directory/sql.toml +++ b/resources/config/directory/sql.toml @@ -12,7 +12,7 @@ catch-all = true #catch-all = [ { if = "matches('(.+)@(.+)$', address)", then = "'info@' + $2" }, # { else = false } ] subaddressing = true -#subaddressing = [ { if = "matches('^([^.]+)\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, +#subaddressing = [ { if = "matches('^([^.]+)\\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, # { else = false } ] [directory."sql".cache] diff --git a/resources/config/smtp/session.toml b/resources/config/smtp/session.toml index 13484a75..df16c13c 100644 --- a/resources/config/smtp/session.toml +++ b/resources/config/smtp/session.toml @@ -49,14 +49,14 @@ wait = "5s" [session.mail] #script = "mail-from" -#rewrite = [ { if = "listener != 'smtp' & matches('^([^.]+)@([^.]+)\.(.+)$', rcpt)", then = "$1 + '@' + $3" }, +#rewrite = [ { if = "listener != 'smtp' & matches('^([^.]+)@([^.]+)\\.(.+)$', rcpt)", then = "$1 + '@' + $3" }, # { else = false } ] [session.rcpt] #script = "greylist" relay = [ { if = "!is_empty(authenticated_as)", then = true }, { else = false } ] -#rewrite = [ { if = "is_local_domain('%{DEFAULT_DIRECTORY}%', rcpt_domain) & matches('^([^.]+)\.([^.]+)@(.+)$', rcpt)", then = "$1 + '+' + $2 + '@' + $3" }, +#rewrite = [ { if = "is_local_domain('%{DEFAULT_DIRECTORY}%', rcpt_domain) & matches('^([^.]+)\\.([^.]+)@(.+)$', rcpt)", then = "$1 + '+' + $2 + '@' + $3" }, # { else = false } ] max-recipients = 25 directory = "'%{DEFAULT_DIRECTORY}%'" diff --git a/tests/src/directory/mod.rs b/tests/src/directory/mod.rs index 57345712..6f896dd5 100644 --- a/tests/src/directory/mod.rs +++ b/tests/src/directory/mod.rs @@ -620,23 +620,27 @@ async fn address_mappings() { catch-all = true subaddressing = true expected-sub = "john.doe@example.org" + expected-sub-nomatch = "jane@example.org" expected-catch = "@example.org" [disable] catch-all = false subaddressing = false expected-sub = "john.doe+alias@example.org" + expected-sub-nomatch = "jane@example.org" expected-catch = false [custom] catch-all = [{if = "matches('(.+)@(.+)$', address)", then = "'info@' + $2"}, {else = false}] - subaddressing = [{ if = "matches('^([^.]+)\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, {else = false}] + subaddressing = [{ if = "matches('^([^.]+)\\.([^.]+)@(.+)$', address)", then = "$2 + '@' + $3" }, {else = false}] expected-sub = "doe+alias@example.org" + expected-sub-nomatch = "jane@example.org" expected-catch = "info@example.org" "#; let config = utils::config::Config::new(MAPPINGS).unwrap(); const ADDR: &str = "john.doe+alias@example.org"; + const ADDR_NO_MATCH: &str = "jane@example.org"; for test in ["enable", "disable", "custom"] { let catch_all = AddressMapping::from_config(&config, (test, "catch-all")).unwrap(); @@ -648,6 +652,14 @@ async fn address_mappings() { "failed subaddress for {test:?}" ); + assert_eq!( + subaddressing.to_subaddress(ADDR_NO_MATCH).await, + config + .value_require((test, "expected-sub-nomatch")) + .unwrap(), + "failed subaddress no match for {test:?}" + ); + assert_eq!( catch_all.to_catch_all(ADDR).await, config diff --git a/tests/src/smtp/inbound/rewrite.rs b/tests/src/smtp/inbound/rewrite.rs index fc726211..58cf1a7e 100644 --- a/tests/src/smtp/inbound/rewrite.rs +++ b/tests/src/smtp/inbound/rewrite.rs @@ -45,7 +45,7 @@ script = [ { if = "sender_domain = 'foobar.org'", then = "'mail'" }, { else = false } ] [session.rcpt] -rewrite = [ { if = "rcpt_domain = 'foobar.net' & matches('^([^.]+)\.([^.]+)@(.+)$', rcpt)", then = "$1 + '+' + $2 + '@' + $3"}, +rewrite = [ { if = "rcpt_domain = 'foobar.net' & matches('^([^.]+)\\.([^.]+)@(.+)$', rcpt)", then = "$1 + '+' + $2 + '@' + $3"}, { else = false } ] script = [ { if = "rcpt_domain = 'foobar.org'", then = "'rcpt'" }, { else = false } ]