MAS-WP-0005-T12: gateway reads trusted A-R verdict; ticket service replies only on DMARC pass

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 252470@bnt-lap001
Assistant-Session: ad628c8f-4be2-4979-94c9-76c7ed6f8241
This commit is contained in:
tegwick 2026-10-18 22:40:30 +02:00
parent ab3346d187
commit cca58d41fb
6 changed files with 128 additions and 13 deletions

View file

@ -203,3 +203,47 @@ def test_gateway_is_resource_type_agnostic():
("resource", "invoice", "RE=2026-4711", "dispute")
finally:
srv.shutdown()
# -- sender authentication (spec 14 item 10) ----------------------------------------
AR_OURS = "Authentication-Results: great-service.example; dkim=pass header.d=example.net; " \
"spf=pass smtp.mailfrom=example.net; dmarc=pass header.from=example.net\r\n"
RECEIVED = "Received: from mx.example.net by great-service.example; Sun, 18 Oct 2026 20:00:00 +0000\r\n"
def _meta(headers):
return message_meta_from_rfc822(raw(f"ticket!callback@{D}", "hi", extra=headers),
trusted_authserv_id=D)
def test_authentication_read_from_our_own_header():
a = _meta(AR_OURS + RECEIVED)["authentication"]
assert a == {"dkim": "pass", "spf": "pass", "dmarc": "pass", "header_from": "example.net"}
def test_forged_or_foreign_authentication_is_ignored():
forged = RECEIVED + AR_OURS # below our Received: brought by the sender
foreign = AR_OURS.replace("great-service.example;", "other.example;") + RECEIVED
assert _meta(forged)["authentication"] is None
assert _meta(foreign)["authentication"] is None
assert message_meta_from_rfc822(raw("x@y", "s", extra=AR_OURS))["authentication"] is None # no trusted id
def test_reply_only_to_authenticated_sender(env):
svc, send, *_ = env
svc.require_dmarc_pass = True
sent = []
svc.smtp, svc._send = ("127.0.0.1", 25), lambda *a: sent.append(a)
send(f"ticket!callback@{D}", "spoofed") # no verdict
assert sent == [] and svc.outbox() == [] and svc.ticket("GS-41872") is not None
def test_authenticated_sender_gets_reply(env):
svc, _, _, resolver = env
svc.require_dmarc_pass = True
sent = []
svc.smtp, svc._send = ("127.0.0.1", 25), lambda *a: sent.append(a)
event = build_event(f"ticket!callback@{D}", _meta(AR_OURS + RECEIVED), resolver)
status, body = svc.handle(event)
assert status == 201 and len(sent) == 1 and sent[0][1] == CUSTOMER