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:
parent
ab3346d187
commit
cca58d41fb
6 changed files with 128 additions and 13 deletions
|
|
@ -65,7 +65,7 @@ CREATE TABLE IF NOT EXISTS outbox (
|
|||
class TicketService:
|
||||
def __init__(self, db_path: str = ":memory:", id_factory: Callable[[], str] = default_ticket_id,
|
||||
smtp: Optional[tuple[str, int]] = None, closed_notice: bool = True,
|
||||
max_sent: Optional[int] = None):
|
||||
max_sent: Optional[int] = None, require_dmarc_pass: bool = False):
|
||||
self.db = sqlite3.connect(db_path, check_same_thread=False)
|
||||
self.db.row_factory = sqlite3.Row
|
||||
self.db.executescript(SCHEMA)
|
||||
|
|
@ -74,6 +74,8 @@ class TicketService:
|
|||
self.smtp = smtp
|
||||
self.closed_notice = closed_notice
|
||||
self.max_sent = max_sent # lifetime cap on mail actually sent via smtp
|
||||
# spec 14 item 10: auto-reply only to authenticated senders
|
||||
self.require_dmarc_pass = require_dmarc_pass
|
||||
|
||||
# -- event handling -------------------------------------------------------------
|
||||
|
||||
|
|
@ -149,6 +151,8 @@ class TicketService:
|
|||
bulk = (msg.get("precedence") or "").lower() in ("bulk", "list", "junk")
|
||||
if not to or auto or bulk:
|
||||
return False # never auto-reply to automated mail
|
||||
if self.require_dmarc_pass and (msg.get("authentication") or {}).get("dmarc") != "pass":
|
||||
return False # unauthenticated sender: keep the ticket, send nothing
|
||||
if not subject.lower().startswith("re:"):
|
||||
subject = "Re: " + subject
|
||||
self.db.execute("INSERT INTO outbox (ticket_id, mail_from, mail_to, subject, body, in_reply_to)"
|
||||
|
|
@ -241,10 +245,12 @@ if __name__ == "__main__":
|
|||
ap.add_argument("--db", default="tickets.sqlite3")
|
||||
ap.add_argument("--listen", default="127.0.0.1:8025")
|
||||
ap.add_argument("--smtp", metavar="HOST:PORT", help="send replies via this SMTP relay")
|
||||
ap.add_argument("--require-dmarc-pass", action="store_true",
|
||||
help="auto-reply only when the event says the sender passed DMARC")
|
||||
ap.add_argument("--max-sent", type=int, metavar="N",
|
||||
help="stop sending once N replies have been sent in total (kept in the db)")
|
||||
a = ap.parse_args()
|
||||
smtp = (a.smtp.rsplit(":", 1)[0], int(a.smtp.rsplit(":", 1)[1])) if a.smtp else None
|
||||
h, p = a.listen.rsplit(":", 1)
|
||||
print(f"ticket service on http://{a.listen}/mas-events")
|
||||
make_server(TicketService(a.db, smtp=smtp, max_sent=a.max_sent), h, int(p)).serve_forever()
|
||||
make_server(TicketService(a.db, smtp=smtp, max_sent=a.max_sent, require_dmarc_pass=a.require_dmarc_pass), h, int(p)).serve_forever()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue