1 | #!/usr/bin/env python3
|
---|
2 |
|
---|
3 | import smtplib
|
---|
4 | import ssl
|
---|
5 | from django.core.mail.backends.smtp import EmailBackend
|
---|
6 | from django.core.mail.utils import DNS_NAME
|
---|
7 |
|
---|
8 |
|
---|
9 | class SmtpEmailBackendTls1(EmailBackend):
|
---|
10 | """
|
---|
11 | Overrides EmailBackend to require TLS v1.
|
---|
12 | """
|
---|
13 | def __init__(self, *args, **kwargs):
|
---|
14 | super().__init__(*args, **kwargs)
|
---|
15 | if not self.use_tls:
|
---|
16 | raise ValueError("This backend is specifically for TLS.")
|
---|
17 | # self.use_ssl will be False, by the superclass's checks
|
---|
18 |
|
---|
19 | def _protocol(self):
|
---|
20 | return ssl.PROTOCOL_TLSv1
|
---|
21 |
|
---|
22 | def open(self):
|
---|
23 | """
|
---|
24 | Ensures we have a connection to the email server. Returns whether or
|
---|
25 | not a new connection was required (True or False).
|
---|
26 | """
|
---|
27 | if self.connection:
|
---|
28 | # Nothing to do if the connection is already open.
|
---|
29 | return False
|
---|
30 |
|
---|
31 | connection_params = {'local_hostname': DNS_NAME.get_fqdn()}
|
---|
32 | if self.timeout is not None:
|
---|
33 | connection_params['timeout'] = self.timeout
|
---|
34 | try:
|
---|
35 | self.connection = smtplib.SMTP(self.host, self.port,
|
---|
36 | **connection_params)
|
---|
37 |
|
---|
38 | # TLS
|
---|
39 | context = ssl.SSLContext(self._protocol())
|
---|
40 | if self.ssl_certfile:
|
---|
41 | context.load_cert_chain(certfile=self.ssl_certfile,
|
---|
42 | keyfile=self.ssl_keyfile)
|
---|
43 | self.connection.ehlo()
|
---|
44 | self.connection.starttls(context=context)
|
---|
45 | self.connection.ehlo()
|
---|
46 | if self.username and self.password:
|
---|
47 | self.connection.login(self.username, self.password)
|
---|
48 | return True
|
---|
49 | except smtplib.SMTPException:
|
---|
50 | if not self.fail_silently:
|
---|
51 | raise
|
---|