smtpd — SMTP-сервер


Данный модуль предлагает несколько классов для реализации SMTP (email) серверов.

См.также

Пакет aiosmtpd является рекомендуемой заменой данного модуля. Он основан на asyncio и предоставляет более простой API. smtpd следует считать устаревшим.

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

Кроме того, 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 должны быть кортежем (host, port). Объект наследуется от asyncore.dispatcher, поэтому при создании экземпляра он вставляется в цикл обработки событий asyncore.

data_size_limit указывает максимальное количество байтов, которые будут приняты в команде DATA. Значение None или 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, это будет байтовый объект.

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

class smtpd.MailmanProxy(localaddr, remoteaddr)

Создаёт новый чистый прокси-сервер. Аргументы соответствуют SMTPServer. Все будет ретранслироваться на remoteaddr, если локальные конфигурации почтальона не знают об адресе, и в этом случае он будет обрабатываться через почтальона. Учтите, что при выполнении его есть хороший шанс превратить вас в открытую ретрансляцию, поэтому будьте осторожны.

Объекты 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. Значение None или 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

Содержит полное доменное имя сервера, возвращенное socket.getfqdn().

peer

Содержит имя однорангового узла клиента, возвращенное conn.getpeername(), где conn — это conn.

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

Команда Предпринятое действие
HELO Принимает приветствие от клиента и сохраняет его в seen_greeting. Устанавливает сервер в базовый командный режим.
EHLO Принимает приветствие от клиента и сохраняет его в seen_greeting. Переводит сервер в режим расширенных команд.
NOOP Действия не выполняются.
QUIT Закрывает соединение чисто.
MAIL Принимает синтаксис «MAIL FROM:» и сохраняет указанный адрес как mailfrom. В режиме расширенной команды принимает RFC 1870 SIZE атрибут и отвечает соответствующим образом на основании значения data_size_limit.
RCPT Принимает синтаксис «RCPT TO:» и сохраняет предоставленные адреса в списке rcpttos.
RSET Сброс mailfrom, rcpttos и received_data, но не приветствуется.
DATA Задание внутренних состояний для DATA и хранения оставшихся строк от клиента в received_data до завершителя "\r\n.\r\n" получения.
HELP Возвращает минимальную информацию о синтаксисе команд.
VRFY Возвращает код 252 (сервер не знает, действителен ли адрес)
EXPN Сообщает, что команда не реализована.