From 86e1f9cd4049f4548f17f2edf393c06259a2be4a Mon Sep 17 00:00:00 2001 From: Dominik Chilla Date: Fri, 9 Jul 2021 09:58:01 +0200 Subject: [PATCH] https://github.com/chillout2k/ExOTA-Milter/issues/35 --- app/exota-milter.py | 34 +++++++++---- tests/miltertest_multiple_tenantid.lua | 70 ++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 tests/miltertest_multiple_tenantid.lua diff --git a/app/exota-milter.py b/app/exota-milter.py index ddeb81d..f2a6284 100644 --- a/app/exota-milter.py +++ b/app/exota-milter.py @@ -86,6 +86,7 @@ class ExOTAMilter(Milter.Base): self.forwarded = False self.hdr_tenant_id = None self.hdr_tenant_id_count = 0 + self.hdr_different_tenant_id = False self.x509_whitelisted = False self.dkim_valid = False self.passed_dkim_results = [] @@ -202,11 +203,18 @@ class ExOTAMilter(Milter.Base): # Parse non-standardized X-MS-Exchange-CrossTenant-Id header elif(name.lower() == "X-MS-Exchange-CrossTenant-Id".lower()): - self.hdr_tenant_id_count += 1 - self.hdr_tenant_id = hval.lower() log_debug(self.mconn_id + "/" + str(self.getsymval('i')) + - "/HDR: Tenant-ID: {0}".format(self.hdr_tenant_id) - ) + "/HDR: Tenant-ID: {0}".format(self.hdr_tenant_id) + ) + if self.hdr_tenant_id_count > 0: + if not self.hdr_tenant_id == hval.lower(): + self.hdr_different_tenant_id = True + log_info(self.mconn_id + "/" + str(self.getsymval('i')) + + "/HDR: Different Tenant-IDs found!" + ) + else: + self.hdr_tenant_id_count += 1 + self.hdr_tenant_id = hval.lower() # Parse RFC-7601 Authentication-Results header elif(name.lower() == "Authentication-Results".lower()): @@ -292,6 +300,17 @@ class ExOTAMilter(Milter.Base): reason = '5322.from header missing' ) + if self.hdr_different_tenant_id == True: + log_info(self.mconn_id + "/" + str(self.getsymval('i')) + + "/EOM: Multiple/different tenant-ID headers found for {0} - action=reject".format( + self.hdr_from_domain + ) + ) + return self.smfir_reject( + queue_id = self.getsymval('i'), + reason = 'Multiple/different tenant-IDs headers found!' + ) + # Get policy for 5322.from_domain policy = None try: @@ -384,13 +403,6 @@ class ExOTAMilter(Milter.Base): queue_id = self.getsymval('i'), reason = 'Tenant-ID is missing!' ) - if self.hdr_tenant_id_count > 1: - log_info(self.mconn_id + "/" + str(self.getsymval('i')) + - "/EOM: More than one tenant-IDs for {0} found - action=reject".format( - self.hdr_from_domain - ) - ) - return self.smfir_reject(queue_id=self.getsymval('i')) if self.hdr_tenant_id == policy.get_tenant_id(): log_info(self.mconn_id + "/" + str(self.getsymval('i')) + "/EOM: tenant_id={0} status=match".format(self.hdr_tenant_id) diff --git a/tests/miltertest_multiple_tenantid.lua b/tests/miltertest_multiple_tenantid.lua new file mode 100644 index 0000000..10fb596 --- /dev/null +++ b/tests/miltertest_multiple_tenantid.lua @@ -0,0 +1,70 @@ +-- https://mopano.github.io/sendmail-filter-api/constant-values.html#com.sendmail.milter.MilterConstants +-- http://www.opendkim.org/miltertest.8.html + +-- socket must be defined as miltertest global variable (-D) +conn = mt.connect(socket) +if conn == nil then + error "mt.connect() failed" +end +if mt.conninfo(conn, "localhost", "::1") ~= nil then + error "mt.conninfo() failed" +end + +mt.set_timeout(60) + +-- 5321.FROM +if mt.mailfrom(conn, "envelope.sender@example.org") ~= nil then + error "mt.mailfrom() failed" +end +if mt.getreply(conn) ~= SMFIR_CONTINUE then + error "mt.mailfrom() unexpected reply" +end + +-- 5321.RCPT+MACROS +mt.macro(conn, SMFIC_RCPT, "i", "4CgSNs5Q9sz7SllQ", '{cert_subject}', "mail.protection.outlook.comx") +if mt.rcptto(conn, "") ~= nil then + error "mt.rcptto() failed" +end +if mt.getreply(conn) ~= SMFIR_CONTINUE then + error "mt.rcptto() unexpected reply" +end + +-- HEADER +if mt.header(conn, "fRoM", '"Blah Blubb" ') ~= nil then + error "mt.header(From) failed" +end +if mt.header(conn, "x-mS-EXCHANGE-crosstenant-id", "1234abcd-18c5-45e8-88de-123456789abc") ~= nil then + error "mt.header(tenant-id pass) failed" +end +if mt.header(conn, "x-mS-EXCHANGE-crosstenant-id", "1234abcd-18c5-45e8-88de-123456789abc") ~= nil then + error "mt.header(tenant-id pass) failed" +end +if mt.header(conn, "X-MS-Exchange-CrossTenant-Id", "4321abcd-18c5-45e8-88de-blahblubb") ~= nil then + error "mt.header(tenant-id fail) failed" +end +if mt.header(conn, "Authentication-RESULTS", "my-auth-serv-id;\n dkim=pass header.d=chillout2k.de header.s=selector1-yad-onmicrosoft-com header.b=mmmjFpv8") ~= nil then + error "mt.header(DKIM-AR) failed" +end +if mt.header(conn, "X-ExOTA-Authentication-Results", "my-auth-serv-id;\n exota=pass") ~= nil then + error "mt.header(Exota-AR) failed" +end + +-- EOM +if mt.eom(conn) ~= nil then + error "mt.eom() failed" +end +mt.echo("EOM: " .. mt.getreply(conn)) +if mt.getreply(conn) == SMFIR_CONTINUE then + mt.echo("EOM-continue") +elseif mt.getreply(conn) == SMFIR_REPLYCODE then + mt.echo("EOM-reject") +end + +if not mt.eom_check(conn, MT_HDRADD, "X-ExOTA-Authentication-Results") then + mt.echo("no header added") +else + mt.echo("X-ExOTA-Authentication-Results header added") +end + +-- DISCONNECT +mt.disconnect(conn) \ No newline at end of file