}
-- Message id validity
-local sane_msgid = 'Message-Id=/^<?[^<>\\\\ \\t\\n\\r\\x0b\\x80-\\xff]+\\@[^<>\\\\ \\t\\n\\r\\x0b\\x80-\\xff]+>?\\s*$/H'
+-- Permit non-ASCII bytes in EAI/SMTPUTF8 Message-IDs (RFC 6532) when mime_utf8 is enabled
+local sane_msgid
+if rspamd_config:is_mime_utf8() then
+ sane_msgid = 'Message-Id=/^<?[^<>\\\\ \\t\\n\\r\\x0b]+\\@[^<>\\\\ \\t\\n\\r\\x0b]+>?\\s*$/H'
+else
+ sane_msgid = 'Message-Id=/^<?[^<>\\\\ \\t\\n\\r\\x0b\\x80-\\xff]+\\@[^<>\\\\ \\t\\n\\r\\x0b\\x80-\\xff]+>?\\s*$/H'
+end
local msgid_comment = 'Message-Id=/\\(.*\\)/H'
reconf['INVALID_MSGID'] = {
re = string.format('(%s) & !((%s) | (%s))', has_mid, sane_msgid, msgid_comment),
G_STRUCT_OFFSET(struct rspamd_config, enable_mime_utf),
0,
"Enable UTF8 mode for mime");
+ /* Alias matching the Lua API name rspamd_config:is_mime_utf8() */
+ rspamd_rcl_add_default_handler(sub,
+ "enable_mime_utf8",
+ rspamd_rcl_parse_struct_boolean,
+ G_STRUCT_OFFSET(struct rspamd_config, enable_mime_utf),
+ 0,
+ "Enable UTF8 mode for mime (alias of enable_mime_utf)");
rspamd_rcl_add_default_handler(sub,
"enable_url_rewrite",
rspamd_rcl_parse_struct_boolean,
--- /dev/null
+*** Settings ***
+Suite Setup Rspamd Setup
+Suite Teardown Rspamd Teardown
+Library ${RSPAMD_TESTDIR}/lib/rspamd.py
+Resource ${RSPAMD_TESTDIR}/lib/rspamd.robot
+Variables ${RSPAMD_TESTDIR}/lib/vars.py
+
+*** Variables ***
+${CONFIG} ${RSPAMD_TESTDIR}/configs/mid_utf8.conf
+${RSPAMD_SCOPE} Suite
+${RSPAMD_URL_TLD} ${RSPAMD_TESTDIR}/../lua/unit/test_tld.dat
+${SETTINGS_MID_UTF8} {symbols_enabled = [INVALID_MSGID,MISSING_MID]}
+
+*** Test Cases ***
+MID UTF8 - valid EAI Message-ID is not flagged as invalid
+ [Documentation] RFC 6532: when enable_mime_utf8 is enabled, a Message-ID
+ ... with a UTF-8 internationalized domain must be accepted.
+ Scan File ${RSPAMD_TESTDIR}/messages/mid_eai_utf8.eml
+ ... Settings=${SETTINGS_MID_UTF8}
+ Do Not Expect Symbol INVALID_MSGID
+ Do Not Expect Symbol MISSING_MID
+
+MID UTF8 - structurally broken Message-ID is still flagged
+ [Documentation] Even with enable_mime_utf8 enabled, a Message-ID that
+ ... violates structural rules (no @) must still be detected.
+ Scan File ${RSPAMD_TESTDIR}/messages/fws_fp.eml
+ ... Settings=${SETTINGS_MID_UTF8}
+ Expect Symbol With Score INVALID_MSGID 1.70
--- /dev/null
+options = {
+ filters = ["regexp"]
+ url_tld = "{= env.TESTDIR =}/../lua/unit/test_tld.dat"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid";
+ lua_path = "{= env.INSTALLROOT =}/share/rspamd/lib/?.lua";
+ # Enable UTF-8 mime mode (SMTPUTF8/EAI per RFC 6532).
+ # Use the alias name to also cover the option-name compatibility fix.
+ enable_mime_utf8 = true;
+ dns {
+ retransmits = 2;
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log";
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+}
+
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ keypair {
+ pubkey = "{= env.KEY_PUB1 =}";
+ privkey = "{= env.KEY_PVT1 =}";
+ }
+ task_timeout = 10s;
+}
+
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+
+modules {
+ path = "{= env.TESTDIR =}/../../src/plugins/lua/"
+}
+lua = "{= env.INSTALLROOT =}/share/rspamd/rules/rspamd.lua"
--- /dev/null
+From: Sender <sender@example.com>
+To: Receiver <receiver@example.com>
+Date: Fri, 5 Oct 2018 19:56:40 -0400
+Message-Id: <49faaad5-3d90-2713-583b-6cb8a5d06345@wildduck.รครครค.test>
+Subject: EAI/SMTPUTF8 message with internationalized Message-ID
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+This message has a valid Message-ID containing a UTF-8 internationalized
+domain (RFC 6532) and must not trigger INVALID_MSGID when
+enable_mime_utf8 is enabled.