3 Demonstrate sending mail via SMTP while employing TLS and performing
9 from OpenSSL.SSL import SSLv3_METHOD
11 from twisted.mail.smtp import ESMTPSenderFactory
12 from twisted.python.usage import Options, UsageError
13 from twisted.internet.ssl import ClientContextFactory
14 from twisted.internet.defer import Deferred
15 from twisted.internet import reactor
18 authenticationUsername, authenticationSecret,
19 fromAddress, toAddress,
24 @param authenticationUsername: The username with which to authenticate.
25 @param authenticationSecret: The password with which to authenticate.
26 @param fromAddress: The SMTP reverse path (ie, MAIL FROM)
27 @param toAddress: The SMTP forward path (ie, RCPT TO)
28 @param messageFile: A file-like object containing the headers and body of
30 @param smtpHost: The MX host to which to connect.
31 @param smtpPort: The port number to which to connect.
33 @return: A Deferred which will be called back when the message has been
34 sent or which will errback if it cannot be sent.
37 # Create a context factory which only allows SSLv3 and does not verify
38 # the peer's certificate.
39 contextFactory = ClientContextFactory()
40 contextFactory.method = SSLv3_METHOD
42 resultDeferred = Deferred()
44 senderFactory = ESMTPSenderFactory(
45 authenticationUsername,
51 contextFactory=contextFactory)
53 reactor.connectTCP(smtpHost, smtpPort, senderFactory)
59 class SendmailOptions(Options):
60 synopsis = "smtpclient_tls.py [options]"
63 ('username', 'u', None,
64 'The username with which to authenticate to the SMTP server.'),
65 ('password', 'p', None,
66 'The password with which to authenticate to the SMTP server.'),
67 ('from-address', 'f', None,
68 'The address from which to send the message.'),
69 ('to-address', 't', None,
70 'The address to which to send the message.'),
71 ('message', 'm', None,
72 'The filename which contains the message to send.'),
73 ('smtp-host', 'h', None,
74 'The host through which to send the message.'),
75 ('smtp-port', None, '25',
76 'The port number on smtp-host to which to connect.')]
79 def postOptions(self):
81 Parse integer parameters, open the message file, and make sure all
82 required parameters have been specified.
85 self['smtp-port'] = int(self['smtp-port'])
87 raise UsageError("--smtp-port argument must be an integer.")
88 if self['username'] is None:
90 "Must specify authentication username with --username")
91 if self['password'] is None:
93 "Must specify authentication password with --password")
94 if self['from-address'] is None:
95 raise UsageError("Must specify from address with --from-address")
96 if self['to-address'] is None:
97 raise UsageError("Must specify from address with --to-address")
98 if self['smtp-host'] is None:
99 raise UsageError("Must specify smtp host with --smtp-host")
100 if self['message'] is None:
102 "Must specify a message file to send with --message")
104 self['message'] = file(self['message'])
110 def cbSentMessage(result):
112 Called when the message has been sent.
114 Report success to the user and then stop the reactor.
121 def ebSentMessage(err):
123 Called if the message cannot be sent.
125 Report the failure to the user and then stop the reactor.
134 Parse arguments and send an email based on them.
136 o = SendmailOptions()
139 except UsageError, e:
142 from twisted.python import log
143 log.startLogging(sys.stdout)
152 result.addCallbacks(cbSentMessage, ebSentMessage)
156 if __name__ == '__main__':