I am trying to make an open SMTP relay using the new aiosmtpd
library that replaces smtpd
. The program below instantiates a Proxy
handler that is passed onto the mail controller, which is started afterwards in the background. A message is then created with a standard smtplib
client that connects to the relay.
All is good until the SMTP conversation between the client and the relay ends with the message never leaving the relay. The relay never replies with a 250 OK\r\n
and a ctrl+c
shows that sendmail
is waiting for a reply.
Any ideas? Is the script missing something?
Edit: mail.example.com
is only an example server. An smtpd DebuggingServer
prints nothing upon execution of the script with relay = aiosmtpd.handlers.Proxy("localhost", 1025)
.
$ python3.6 -m smtpd -n -c DebuggingServer -d localhost:1025 DebuggingServer started at Fri Apr 7 18:41:09 2017 Local addr: ('localhost', 1025) Remote addr:('localhost', 25) ...nothing printed out...
Script:
from aiosmtpd.handlers import Debugging, Proxy from aiosmtpd.controller import Controller from smtplib import SMTP # relay = aiosmtpd.handlers.Debugging() relay = aiosmtpd.handlers.Proxy("localhost", 1025) # relay = aiosmtpd.handlers.Proxy("mail.example.com", 25) controller = Controller(relay) controller.start() print(controller, controller.hostname, controller.port) input("ready... press enter to continue") print("creating SMTP with debug") client = SMTP() client.set_debuglevel(1) print("connecting to the SMTP server") client.connect(controller.hostname, controller.port) print("sending message") client.sendmail('alice@example.com', ['bob@example.com'], """\ From: Alice <alice@example.com> To: Bob <bob@example.com> Subject: Title Body. """) print("stopping controller") controller.stop() print("checking if controller really stopped") client.connect(controller.hostname, controller.port)
Here is the output of the script:
$ python3.6 relay.py <aiosmtpd.controller.Controller object at 0x10199f710> ::0 8025 ready... press enter to continue creating SMTP with debug connecting to the SMTP server connect: ('::0', 8025) connect: to ('::0', 8025) None reply: b'220 localhost Python SMTP 1.0a4\r\n' reply: retcode (220); Msg: b'localhost Python SMTP 1.0a4' connect: b'localhost Python SMTP 1.0a4' sending message send: 'ehlo localhost\r\n' reply: b'250-localhost\r\n' reply: b'250-SIZE 33554432\r\n' reply: b'250-8BITMIME\r\n' reply: b'250 HELP\r\n' reply: retcode (250); Msg: b'localhost\nSIZE 33554432\n8BITMIME\nHELP' send: 'mail FROM:<alice@example.com> size=85\r\n' reply: b'250 OK\r\n' reply: retcode (250); Msg: b'OK' send: 'rcpt TO:<bob@example.com>\r\n' reply: b'250 OK\r\n' reply: retcode (250); Msg: b'OK' send: 'data\r\n' reply: b'354 End data with <CR><LF>.<CR><LF>\r\n' reply: retcode (354); Msg: b'End data with <CR><LF>.<CR><LF>' data: (354, b'End data with <CR><LF>.<CR><LF>') send: b'From: Alice <alice@example.com>\r\nTo: Bob <bob@example.com>\r\nSubject: Title\r\n\r\nBody.\r\n.\r\n' ...nothing happens at this point... ^CTraceback (most recent call last): File "relay.py", line 49, in <module> """) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 881, in sendmail (code, resp) = self.data(msg) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 568, in data (code, msg) = self.getreply() File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 386, in getreply line = self.file.readline(_MAXLINE + 1) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 586, in readinto return self._sock.recv_into(b) KeyboardInterrupt
For comparison, here is the output using the debug handler:
$ python3.6 relay.py <aiosmtpd.controller.Controller object at 0x10189f710> ::0 8025 ready... press enter to continue creating SMTP with debug connecting to the SMTP server connect: ('::0', 8025) connect: to ('::0', 8025) None reply: b'220 localhost Python SMTP 1.0a4\r\n' reply: retcode (220); Msg: b'localhost Python SMTP 1.0a4' connect: b'localhost Python SMTP 1.0a4' sending message send: 'ehlo localhost\r\n' reply: b'250-localhost\r\n' reply: b'250-SIZE 33554432\r\n' reply: b'250-8BITMIME\r\n' reply: b'250 HELP\r\n' reply: retcode (250); Msg: b'localhost\nSIZE 33554432\n8BITMIME\nHELP' send: 'mail FROM:<alice@example.com> size=85\r\n' reply: b'250 OK\r\n' reply: retcode (250); Msg: b'OK' send: 'rcpt TO:<bob@example.com>\r\n' reply: b'250 OK\r\n' reply: retcode (250); Msg: b'OK' send: 'data\r\n' reply: b'354 End data with <CR><LF>.<CR><LF>\r\n' reply: retcode (354); Msg: b'End data with <CR><LF>.<CR><LF>' data: (354, b'End data with <CR><LF>.<CR><LF>') send: b'From: Alice <alice@example.com>\r\nTo: Bob <bob@example.com>\r\nSubject: Title\r\n\r\nBody.\r\n.\r\n' ---------- MESSAGE FOLLOWS ---------- mail options: ['SIZE=85'] rcpt options: [] From: Alice <alice@example.com> To: Bob <bob@example.com> Subject: Title X-Peer: ('::1', 64397, 0, 0) Body. ------------ END MESSAGE ------------ reply: b'250 OK\r\n' reply: retcode (250); Msg: b'OK' data: (250, b'OK') stopping controller checking if controller really stopped connect: ('::0', 8025) connect: to ('::0', 8025) None Traceback (most recent call last): File "relay.py", line 51, in <module> client.connect(controller.hostname, controller.port) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 335, in connect self.sock = self._get_socket(host, port, self.timeout) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 306, in _get_socket self.source_address) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 722, in create_connection raise err File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 713, in create_connection sock.connect(sa) ConnectionRefusedError: [Errno 61] Connection refused