smtpd — Сервер SMTP

Вихідний код: Lib/smtpd.py


Цей модуль пропонує кілька класів для реалізації серверів SMTP (електронної пошти).

Застаріло починаючи з версії 3.6: smtpd will be removed in Python 3.12 (see PEP 594 for details). The aiosmtpd package is a recommended replacement for this module. It is based on asyncio and provides a more straightforward API.

Присутні кілька реалізацій сервера; один — це загальна реалізація нічого не робити, яку можна перевизначити, тоді як інші два пропонують спеціальні стратегії надсилання пошти.

Крім того, SMTPChannel можна розширити, щоб реалізувати дуже специфічну поведінку взаємодії з клієнтами SMTP.

Код підтримує RFC 5321, а також розширення RFC 1870 SIZE і RFC 6531 SMTPUTF8.

Об’єкти SMTPServer

class smtpd.SMTPServer(localaddr, remoteaddr, data_size_limit=33554432, map=None, enable_SMTPUTF8=False, decode_data=False)

Створіть новий об’єкт SMTPServer, який прив’язується до локальної адреси localaddr. Він розглядатиме remoteaddr як вихідний ретранслятор SMTP. І localaddr, і remoteaddr мають бути кортежем (хост, порт). Об’єкт успадковується від asyncore.dispatcher, тому вставлятиметься в цикл подій asyncore під час створення екземпляра.

data_size_limit вказує максимальну кількість байтів, яка буде прийнята в команді DATA. Значення «Немає» або «0» означає відсутність обмежень.

map — це карта сокетів, яка використовується для підключення (спочатку порожній словник є відповідним значенням). Якщо не вказано, використовується глобальна карта сокетів asyncore.

enable_SMTPUTF8 визначає, чи слід увімкнути розширення SMTPUTF8 (як визначено в RFC 6531). Типовим значенням є False. Якщо True, SMTPUTF8 приймається як параметр команди MAIL, а якщо присутній, передається до process_message() у списку kwargs['mail_options'] . decode_data і enable_SMTPUTF8 не можуть бути встановлені на True одночасно.

decode_data вказує, чи слід декодувати частину даних транзакції SMTP за допомогою UTF-8. Коли decode_data має значення False (за замовчуванням), сервер повідомляє про розширення 8BITMIME (RFC 6152), приймає параметр BODY=8BITMIME до MAIL і за наявності передає її до process_message() у списку kwargs['mail_options']. decode_data і enable_SMTPUTF8 не можуть бути встановлені на True одночасно.

process_message(peer, mailfrom, rcpttos, data, **kwargs)

Викликати виняток NotImplementedError. Перевизначте це в підкласах, щоб зробити щось корисне з цим повідомленням. Все, що було передано в конструктор як remoteaddr, буде доступним як атрибут _remoteaddr. peer — це адреса віддаленого хоста, mailfrom — джерело конверта, rcpttos — одержувачі конверта, а data — це рядок, що містить вміст електронного листа (який має бути в RFC 5321 формат).

Якщо ключове слово конструктора decode_data має значення True, аргумент data буде рядком Юнікод. Якщо для нього встановлено значення False, це буде об’єкт bytes.

kwargs — словник, що містить додаткову інформацію. Він порожній, якщо decode_data=True було задано як аргумент ініціалізації, інакше він містить такі ключі:

mail_options:

список усіх отриманих параметрів команди MAIL (елементи є рядками у верхньому регістрі; приклад: ['BODY=8BITMIME', 'SMTPUTF8']).

rcpt_options:

те саме, що mail_options, але для команди RCPT. Наразі параметри RCPT TO не підтримуються, тому наразі це завжди буде порожній список.

Реалізації process_message мають використовувати підпис **kwargs для прийняття довільних аргументів ключових слів, оскільки майбутні покращення функцій можуть додавати ключі до словника kwargs.

Поверніть None для запиту нормальної відповіді 250 Ok; інакше поверніть потрібний рядок відповіді у форматі RFC 5321.

channel_class

Перевизначте це в підкласах, щоб використовувати спеціальний SMTPChannel для керування клієнтами SMTP.

Нове в версії 3.4: Аргумент конструктора map.

Змінено в версії 3.5: localaddr і remoteaddr тепер можуть містити адреси IPv6.

Нове в версії 3.5: Параметри конструктора decode_data і enable_SMTPUTF8, а також параметр kwargs для process_message(), коли decode_data має значення False.

Змінено в версії 3.6: decode_data тепер має значення False за замовчуванням.

Об’єкти DebuggingServer

class smtpd.DebuggingServer(localaddr, remoteaddr)

Створіть новий сервер налагодження. Аргументи відповідають SMTPServer. Повідомлення буде видалено та надруковано на стандартному виводі.

Об’єкти PureProxy

class smtpd.PureProxy(localaddr, remoteaddr)

Створіть новий чистий проксі-сервер. Аргументи відповідають SMTPServer. Усе буде передано на remoteaddr. Зауважте, що це має хороші шанси зробити вас відкритим реле, тому будьте обережні.

MailmanProxy Objects

class smtpd.MailmanProxy(localaddr, remoteaddr)

Deprecated since version 3.9, will be removed in version 3.11: MailmanProxy is deprecated, it depends on a Mailman module which no longer exists and therefore is already broken.

Create a new pure proxy server. Arguments are as per SMTPServer. Everything will be relayed to remoteaddr, unless local mailman configurations knows about an address, in which case it will be handled via mailman. Note that running this has a good chance to make you into an open relay, so please be careful.

Об’єкти SMTPChannel

class smtpd.SMTPChannel(server, conn, addr, data_size_limit=33554432, map=None, enable_SMTPUTF8=False, decode_data=False)

Створіть новий об’єкт SMTPChannel, який керуватиме зв’язком між сервером і одним клієнтом SMTP.

conn і addr відповідають змінним екземпляра, описаним нижче.

data_size_limit вказує максимальну кількість байтів, яка буде прийнята в команді DATA. Значення «Немає» або «0» означає відсутність обмежень.

enable_SMTPUTF8 визначає, чи слід увімкнути розширення SMTPUTF8 (як визначено в RFC 6531). Типовим значенням є False. decode_data і enable_SMTPUTF8 не можуть бути встановлені на True одночасно.

Словник можна вказати в map, щоб уникнути використання глобальної карти сокетів.

decode_data вказує, чи слід декодувати частину даних транзакції SMTP за допомогою UTF-8. Типовим значенням є False. decode_data і enable_SMTPUTF8 не можуть бути встановлені на True одночасно.

Щоб використовувати спеціальну реалізацію SMTPChannel, вам потрібно перевизначити SMTPServer.channel_class вашого SMTPServer.

Змінено в версії 3.5: Додано параметри decode_data і enable_SMTPUTF8.

Змінено в версії 3.6: decode_data тепер має значення False за замовчуванням.

SMTPChannel має такі змінні екземпляра:

smtp_server

Містить SMTPServer, який породив цей канал.

conn

Зберігає об’єкт сокета, який підключається до клієнта.

addr

Містить адресу клієнта, друге значення повертає socket.accept

received_lines

Містить список рядків (декодованих за допомогою UTF-8), отриманих від клієнта. Закінчення рядків "\r\n" перекладено на "\n".

smtp_state

Зберігає поточний стан каналу. Спочатку це буде COMMAND, а потім DATA після того, як клієнт надішле рядок «DATA».

seen_greeting

Містить рядок, що містить привітання, надіслане клієнтом, у своєму «HELO».

mailfrom

Містить рядок, що містить адресу, визначену в рядку «MAIL FROM:» від клієнта.

rcpttos

Містить список рядків, що містять адреси, визначені клієнтом у рядках «RCPT TO:».

received_data

Містить рядок, що містить усі дані, надіслані клієнтом під час стану DATA, окрім кінцевого "\r\n.\r\n".

fqdn

Holds the fully-qualified domain name of the server as returned by socket.getfqdn().

peer

Зберігає ім’я однорангового клієнта, яке повертає conn.getpeername(), де conn є conn.

SMTPChannel працює, викликаючи методи з назвою smtp_<command> після отримання командного рядка від клієнта. У базовий клас SMTPChannel вбудовано методи обробки наступних команд (і відповідної відповіді на них):

Команда

Дії прийняті

ПРИВІТ

Приймає привітання від клієнта та зберігає його в seen_greeting. Перемикає сервер у базовий командний режим.

EHLO

Приймає привітання від клієнта та зберігає його в seen_greeting. Встановлює сервер у режим розширених команд.

NOOP

Не вживає жодних заходів.

ВИЙТИ

Чисто закриває з’єднання.

ПОШТА

Приймає синтаксис «MAIL FROM:» і зберігає надану адресу як mailfrom. У розширеному командному режимі приймає атрибут RFC 1870 SIZE і відповідає належним чином на основі значення data_size_limit.

RCPT

Приймає синтаксис «RCPT TO:» і зберігає надані адреси в списку rcpttos.

RESET

Скидає mailfrom, rcpttos і received_data, але не привітання.

ДАНІ

Встановлює внутрішній стан на DATA і зберігає решту рядків від клієнта в received_data, доки не буде отримано термінатор "\r\n.\r\n".

ДОПОМОГА

Повертає мінімальну інформацію про синтаксис команди

VRFY

Повертає код 252 (сервер не знає, чи адреса дійсна)

EXPN

Повідомляє, що команда не реалізована.