Muffinresearch Labs by Stuart Colville

Fake SMTP server with Python | 6 Comments

Posted in Code, Linux/Unix on 15th October 2010, 10:17 pm by

The other day a colleague was testing some code which relied on sending mail to a local mailserver and it was failing when the mailserver couldn’t be found. Needing to install postfix seemed overkill so I decided to look into what could be done to make a fake smtp service.

All that was required was something to pretend to be a real SMTP service as we didn’t need to view the messages at all.

Here’s the snippet I came up with using the smtpd module in Python:

#!/usr/bin/env python
"""A noddy fake smtp server."""

import smtpd
import asyncore

class FakeSMTPServer(smtpd.SMTPServer):
    """A Fake smtp server"""
    
    def __init__(*args, **kwargs):
        print "Running fake smtp server on port 25"
        smtpd.SMTPServer.__init__(*args, **kwargs)
    
    def process_message(*args, **kwargs):
        pass

if __name__ == "__main__":
    smtp_server = FakeSMTPServer(('localhost', 25), None)
    try:
        asyncore.loop()
    except KeyboardInterrupt:
        smtp_server.close()

To use this, save the above as fake_stmp.py and:

chmod +x fake_smtp.py
sudo ./fake_smtp.py

NOTE: Running this requires sudo to bind to port 25 as binding any port < 1024 requires superuser privileges.

Clearly you could easily adapt that to do something more useful if you want to see what's in the messages sent, either by writing messages to a file or printing them to stdout.

If printing them to stdout is what you need then there's also smtpd.DebuggingServer which is a subclass of SMTPServer which prints messages out to stdout. Using that is even easier and can be done with the following one liner:

sudo python -m smtpd -n -c DebuggingServer localhost:25

Again we use sudo in this case because we’re using port 25 if you don’t want that you can use a port higher than 1024.

To test this out we can use telnet like so:

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
220 localhost6.localdomain6 Python SMTP proxy version 0.2
HELO localhost
250 localhost6.localdomain6
MAIL FROM: test@test.com
250 Ok
RCPT TO: test@testing.com
250 Ok
DATA
354 End data with .
subject: Hello
to: test@test.com
This is my message
.
250 Ok
QUIT
221 Bye
Connection closed by foreign host.

Over on the terminal running the debugging server you should see the following:

$ sudo python -m smtpd -n -c DebuggingServer localhost:25
[sudo] password for moo: 
---------- MESSAGE FOLLOWS ----------
subject: Hello
to: test@test.com
This is my message
------------ END MESSAGE ------------

Post Tools

Insert a tab character in vim when expand tabs is on|(0)

I have vim set-up to use spaces in place of tabs. Sometimes you need to use an actual tab e.g. editing a Makefile. Now whilst it’s possible to change settings so that tabs are used for specific files, a quick tip to remember is to simply type in insert mode:

Ctrl+v tab

That is Ctrl and “V” and hit the tab key, et voila you’ve entered an actual tab.

GNU screen: open tab in current working directory|(1)

A nice trick for having screen open a new tab in the same directory as the one you’re currently in. To use it add it to your .screenrc

# Open new window in current dir.
bind c stuff "screen -X chdir \$PWD;screen^M"
bind ^c stuff "screen -X chdir \$PWD;screen^M"

Hat tip: mteckert on SuperUser.com

Photos on Flickr

© Copyright 2004-13 Stuart Colville, all rights reserved. May contain traces of Muffin. Powered by WordPress. Hosting by Slicehost.com This page was baked in 1.197s.