Skip to content

Instantly share code, notes, and snippets.

@icgood
Last active December 16, 2015 22:49
Show Gist options
  • Save icgood/5509950 to your computer and use it in GitHub Desktop.
Save icgood/5509950 to your computer and use it in GitHub Desktop.
Sends a message over SMTP.
#!/usr/bin/env python
"""
Sends a file through an SMTP transaction.
Author: Ian Good <ian.good@rackspace.com>
"""
import sys
import smtplib
import optparse
import email
from textwrap import dedent
_default_mailfrom = "sender@example.com"
_default_rcptto = "recipient@example.com"
def _parse_args():
parser = optparse.OptionParser(version='Send File SMTP 1.0', usage='%prog [options] file')
parser.add_option('-s', '--host', action='store', type='string', dest='host', help='Host to connect to via SMTP.')
parser.add_option('-p', '--port', action='store', type='int', dest='port', help='Port to connect to via SMTP.')
parser.add_option('-e', '--ehlo', action='store', type='string', dest='ehlo', help='EHLO string to use.')
parser.add_option('-m', '--mailfrom', action='store', type='string', dest='mailfrom', help='MAIL FROM address to use.', metavar='MF')
parser.add_option('-r', '--rcptto', action='append', type='string', dest='rcptto', help='RCPT TO address to use.', metavar='RT')
parser.add_option('--spam', action='store_true', dest='spam', help='Attach GTUBE, to make the message spammy.')
parser.add_option('--virus', action='store_true', dest='virus', help='Attach EICAR, to give the message a fake virus.')
parser.add_option('--xclient', action='append', type='string', dest='xclient', help='Add an XCLIENT argument to send.', metavar='ARG')
parser.add_option('-q', '--quiet', action='store_false', dest='verbose', help='Suppress verbose debugging output.')
parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='Display verbose debugging output.')
parser.set_defaults(host='localhost', port=25, ehlo='there', mailfrom=_default_mailfrom, rcptto=[], xclient=[], verbose=True, spam=False, virus=False)
options, extras = parser.parse_args()
if not options.rcptto:
options.rcptto.append(_default_rcptto)
return options, extras
def _get_filedata(options, extras):
if len(extras) != 1:
filedata = dedent("""\
From: Test Sender <%s>
To: Test Recipient <%s>
Subject: test test
This is a test of the emergency broadcast system.
This is only a test.
""" % (options.mailfrom, options.rcptto[0]))
elif extras[0] == '-':
filedata = sys.stdin.read()
else:
f = file(extras[0])
filedata = f.read()
if options.spam:
msg = email.message_from_string(filedata)
msg['Subject'] = 'test spam'
msg.set_type('application/octet-stream')
msg.set_payload("XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X")
email.Encoders.encode_base64(msg)
msg.add_header('Content-Disposition', 'attachment; filename="gtube"')
filedata = msg.as_string()
if options.virus:
msg = email.message_from_string(filedata)
msg['Subject'] = 'test virus'
msg.set_type('application/octet-stream')
msg.set_payload("X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*")
email.Encoders.encode_base64(msg)
msg.add_header('Content-Disposition', 'attachment; filename="eicar"')
filedata = msg.as_string()
return filedata
def main():
options, extras = _parse_args()
filedata = _get_filedata(options, extras)
server = smtplib.SMTP()
server.set_debuglevel(options.verbose)
code, message = server.connect(options.host, options.port)
if options.xclient:
arg = ' '.join(options.xclient)
server.docmd('XCLIENT', arg)
if message.lower().find('esmtp') != -1:
server.ehlo(options.ehlo)
else:
server.helo(options.ehlo)
server.sendmail(options.mailfrom, options.rcptto, filedata)
server.quit()
if __name__ == '__main__':
main()
# vim:sw=4:ts=4:sts=4:ai:et:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment