smtpd — Servidor SMTP

Source code: Lib/smtpd.py


Este módulo ofrece varias clases para implementar servidores SMTP (correo electrónico).

Obsoleto desde la versión 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.

Este módulo ofrece varias implementaciones del servidor; una es una implementación genérica de no hace nada, pero cuyos métodos pueden ser sobrescritos para crear una implementación concreta, mientras que las otras dos ofrecen estrategias específicas de envío de correo.

Además, SMTPChannel puede ampliarse para implementar un comportamiento de interacción muy específico con clientes SMTP.

El código admite RFC 5321, más las extensiones RFC 1870 SIZE y RFC 6531 SMTPUTF8.

Objetos SMTPServer

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

Crea un nuevo objeto SMTPServer, que se vincula a la dirección local localaddr. Tratará remoteaddr como un transmisor SMTP ascendente. Tanto localaddr como remoteaddr deben ser una tupla (host, port). El objeto hereda de asyncore.dispatcher, por lo que se insertará en el bucle de eventos de asyncore en la instanciación.

data_size_limit especifica el número máximo de bytes que se aceptarán en un comando DATA. Un valor de None o 0 significa que no hay límite.

map es el mapa de conectores que se utilizará para las conexiones (un diccionario inicialmente vacío es un valor adecuado). Si no se especifica, se utiliza el mapa de socket global asyncore.

enable_SMTPUTF8 determina si la extensión SMTPUTF8 (como se define en RFC 6531) debe estar habilitada. El valor predeterminado es False. Cuando es True, SMTPUTF8 se acepta como parámetro para el comando MAIL y cuando está presente se pasa a process_message() en la lista kwargs[‘mail_options’] . decode_data y enable_SMTPUTF8 no se pueden establecer en True al mismo tiempo.

decode_data especifica si la porción de datos de la transacción SMTP debe decodificarse usando UTF-8. Cuando decode_data es False (el valor predeterminado), el servidor anuncia la extensión 8BITMIME (RFC 6152), acepta el parámetro BODY=8BITMIME al comando MAIL, y cuando está presente lo pasa a process_message() en la lista kwargs['mail_options']. decode_data y enable_SMTPUTF8 no se pueden establecer en True al mismo tiempo.

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

Lanza una excepción NotImplementedError. Sobrescribe este método en subclases para hacer algo útil con este mensaje. Todo lo que se haya pasado en el constructor como remoteaddr estará disponible en el atributo _remoteaddr. peer es la dirección del host remoto, mailfrom es el creador del sobre, rcpttos son los destinatarios del sobre y data es una cadena de caracteres que contiene el contenido del correo electrónico (que debe estar en formato RFC 5321).

Si la palabra clave del constructor decode_data se establece en True, el argumento data será una cadena Unicode. Si se establece en False, será un objeto de bytes.

kwargs es un diccionario que contiene información adicional. Está vacío si se proporcionó decode_data=True como argumento de inicialización; de lo contrario, contiene las siguientes claves:

mail_options:

una lista de todos los parámetros recibidos para el comando MAIL (los elementos son cadenas en mayúsculas; ejemplo: ['BODY=8BITMIME', 'SMTPUTF8']).

rcpt_options:

igual que mail_options pero para el comando RCPT. Actualmente, no se admiten las opciones RCPT TO, por lo que, por ahora, siempre será una lista vacía.

Las implementaciones de process_message deben usar la firma **kwargs para aceptar argumentos por palabra clave arbitrarios, ya que las mejoras de características futuras pueden agregar claves al diccionario de argumentos de palabras clave.

Retorne None para solicitar una respuesta normal de 250 Ok; de lo contrario, retorne la cadena de respuesta deseada en formato RFC 5321.

channel_class

Sobrescriba este método en las subclases para usar una clase SMTPChannel personalizada para administrar clientes SMTP.

Nuevo en la versión 3.4: El argumento del constructor map.

Distinto en la versión 3.5: localaddr y remoteaddr ahora pueden contener direcciones IPv6.

Nuevo en la versión 3.5: Los parámetros del constructor decode_data y enable_SMTPUTF8, y el parámetro kwargs para process_message() cuando decode_data es False.

Distinto en la versión 3.6: decode_data ahora es False por defecto.

Objetos DebuggingServer

class smtpd.DebuggingServer(localaddr, remoteaddr)

Crea un nuevo servidor de depuración. Los argumentos son iguales que en SMTPServer. Los mensajes se descartarán y se imprimirán en la salida estándar.

Objetos PureProxy

class smtpd.PureProxy(localaddr, remoteaddr)

Crea un nuevo servidor proxy puro. Los argumentos son iguales que en SMTPServer. Todo se transmitirá a remoteaddr. Tenga en cuenta que ejecutar esto implica una buena posibilidad de convertirlo en un relé abierto, así que tenga cuidado.

Objetos MailmanProxy

class smtpd.MailmanProxy(localaddr, remoteaddr)

Obsoleto desde la versión 3.9, se eliminará en la versión 3.11: MailmanProxy está obsoleto, ya que depende del módulo Mailman el cual ya no existe.

Crea un nuevo servidor proxy puro. Los argumentos son iguales que en SMTPServer. Todo se transmitirá a remoteaddr, a menos que las configuraciones locales de mailman conozcan una dirección, en cuyo caso se manejará a través de mailman. Tenga en cuenta que ejecutar esto implica una buena posibilidad de convertirlo en un relé abierto, así que tenga cuidado.

Objetos SMTPChannel

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

Crea un nuevo objeto SMTPChannel que gestiona la comunicación entre el servidor y un único cliente SMTP.

conn y addr son según las variables de instancia que se describen a continuación.

data_size_limit especifica el número máximo de bytes que se aceptarán en un comando DATA. Un valor de None o 0 significa que no hay límite.

enable_SMTPUTF8 determina si la extensión SMTPUTF8 (como se define en RFC 6531) debe estar habilitada. El valor predeterminado es False. decode_data y enable_SMTPUTF8 no se pueden establecer en True al mismo tiempo.

Se puede especificar un diccionario en map para evitar el uso de un mapa de socket global.

decode_data especifica si la porción de datos de la transacción SMTP debe decodificarse usando UTF-8. El valor predeterminado es False. decode_data y enable_SMTPUTF8 no se pueden establecer en True al mismo tiempo.

Para utilizar una implementación SMTPChannel personalizada, debe anular SMTPServer.channel_class de su SMTPServer.

Distinto en la versión 3.5: Se agregaron los parámetros decode_data y enable_SMTPUTF8.

Distinto en la versión 3.6: decode_data ahora es False por defecto.

La clase SMTPChannel tiene las siguientes variables de instancia:

smtp_server

Contiene el SMTPServer que generó este canal.

conn

Contiene el objeto de socket que se conecta al cliente.

addr

Contiene la dirección del cliente, el segundo valor retornado por socket.accept

received_lines

Contiene una lista de las cadenas de línea (decodificadas mediante UTF-8) recibidas del cliente. Las líneas tienen su final de línea "\r\n" traducido a "\n".

smtp_state

Contiene el estado actual del canal. Será COMMAND inicialmente y luego DATA después de que el cliente envíe una línea «DATA».

seen_greeting

Contiene una cadena de caracteres que contiene el saludo enviado por el cliente en su «HELO».

mailfrom

Contiene una cadena de caracteres que contiene la dirección identificada en la línea «MAIL FROM:» del cliente.

rcpttos

Contiene una lista de cadenas de caracteres que contienen las direcciones identificadas en las líneas «RCPT TO:» del cliente.

received_data

Contiene una cadena de caracteres que contiene todos los datos enviados por el cliente durante el estado de DATA, hasta pero sin incluir la terminación "\r\n.\r\n".

fqdn

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

peer

Contiene el nombre del par del cliente como lo retorna conn.getpeername() donde conn es conn.

La clase SMTPChannel opera invocando métodos llamados smtp_<command> al recibir una línea de comando del cliente. Construidos en la clase base SMTPChannel, son métodos para manejar los siguientes comandos (y responder a ellos de manera apropiada):

Comando

Acción tomada

HELO

Acepta el saludo del cliente y lo almacena en seen_greeting. Establece el servidor en el modo de comando base.

EHLO

Acepta el saludo del cliente y lo almacena en seen_greeting. Establece el servidor en el modo de comando extendido.

NOOP

No realiza ninguna acción.

QUIT

Cierra la conexión limpiamente.

MAIL

Acepta la sintaxis «MAIL FROM:» y almacena la dirección proporcionada como mailfrom. En el modo de comando extendido, acepta el atributo RFC 1870 SIZE y responde apropiadamente según el valor de data_size_limit.

RCPT

Acepta la sintaxis «RCPT TO:» y almacena las direcciones proporcionadas en la lista rcpttos.

RSET

Restablece mailfrom, rcpttos y received_data, pero no el saludo.

DATA

Establece el estado interno en DATA y almacena las líneas restantes del cliente en received_data hasta que se recibe el terminador ”\r\n.\r\n”.

HELP

Retorna información mínima sobre la sintaxis del comando

VRFY

Retorna el código 252 (el servidor no sabe si la dirección es válida)

EXPN

Informa que el comando no está implementado.