Files
bongo/contrib/testing/smtp-binarymime-check.py
2026-07-27 19:56:16 +02:00

116 lines
3.5 KiB
Python
Executable File

#!/usr/bin/env python3
# This program is free software, licensed under the terms of the GNU GPL.
# See the Bongo COPYING file for full details.
# Copyright (c) 2026 Bongo Project contributors
"""Verify that BINARYMIME remains unavailable while CHUNKING is enabled."""
from __future__ import annotations
import importlib.util
import os
from pathlib import Path
import sys
import time
TOKEN = f"smtp16-{os.getpid()}-{int(time.time())}"
TOKEN_PREFIX = b"smtp16-"
ALLOW_LIVE = os.environ.get("BONGO_ALLOW_LIVE_SMTP_TEST") == "1"
class SMTP16Error(RuntimeError):
"""Raised when SMTP exposes or accepts unsupported BINARYMIME."""
def load_helpers():
path = Path(__file__).with_name("smtp-pipelining-check.py")
specification = importlib.util.spec_from_file_location(
"bongo_smtp16_helpers", path
)
if specification is None or specification.loader is None:
raise SMTP16Error(f"cannot load SMTP test helpers from {path}")
module = importlib.util.module_from_spec(specification)
sys.modules[specification.name] = module
specification.loader.exec_module(module)
module.TOKEN_PREFIX = TOKEN_PREFIX
return module
HELPERS = load_helpers()
def reject_binary(client, parameters: str) -> None:
client.command(
f"MAIL FROM:<{TOKEN}@example.test> {parameters}", 504
)
client.command(
f"RCPT TO:<{HELPERS.USER}@{HELPERS.DOMAIN}>", 503
)
client.command("NOOP", 250)
def main() -> int:
if not ALLOW_LIVE:
raise SMTP16Error(
"set BONGO_ALLOW_LIVE_SMTP_TEST=1 for the live protocol test"
)
if not HELPERS.PASSWORD:
raise SMTP16Error("BONGO_TEST_PASSWORD is required")
store = HELPERS.open_store()
try:
HELPERS.cleanup(store)
client = HELPERS.SMTPConnection()
try:
client.require(220, "greeting")
capabilities = client.command(
"EHLO smtp16-client.example", 250
)
if b"CHUNKING" not in capabilities:
raise SMTP16Error("EHLO did not advertise CHUNKING")
if b"BINARYMIME" in capabilities:
raise SMTP16Error("EHLO advertised unsupported BINARYMIME")
reject_binary(client, "BODY=BINARYMIME")
reject_binary(client, "BODY=binarymime")
reject_binary(client, "SIZE=123 BODY=BINARYMIME")
reject_binary(client, "BODY=BINARYMIME SIZE=123")
client.command(
f"MAIL FROM:<{TOKEN}@example.test> BODY=7BIT", 250
)
client.command("RSET", 250)
client.command(
f"MAIL FROM:<{TOKEN}@example.test> BODY=8BITMIME", 250
)
client.command("RSET", 250)
client.command("QUIT", 221)
finally:
client.close()
HELPERS.cleanup(store)
if HELPERS.store_token_documents(store) or HELPERS.queue_token_ids():
raise SMTP16Error("test content remains after cleanup")
finally:
try:
HELPERS.cleanup(store)
finally:
store.Quit()
print(
"SMTP-16 PASS advertised=chunking/no-binarymime "
"body-binarymime=504 case-insensitive=504 combined=504 "
"transaction-state=clean body-7bit=accepted "
"body-8bitmime=accepted queue-clean=yes store-clean=yes"
)
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except (OSError, SMTP16Error, ValueError) as error:
print(f"SMTP-16 FAIL: {type(error).__name__}: {error}")
raise SystemExit(1)