1import unittest
2from test import support
3from test.support import import_helper
4from test.support import socket_helper
5import smtplib
6import socket
7
8ssl = import_helper.import_module("ssl")
9
10support.requires("network")
11
12def check_ssl_verifiy(host, port):
13    context = ssl.create_default_context()
14    with socket.create_connection((host, port)) as sock:
15        try:
16            sock = context.wrap_socket(sock, server_hostname=host)
17        except Exception:
18            return False
19        else:
20            sock.close()
21            return True
22
23
24class SmtpTest(unittest.TestCase):
25    testServer = 'smtp.gmail.com'
26    remotePort = 587
27
28    def test_connect_starttls(self):
29        support.get_attribute(smtplib, 'SMTP_SSL')
30        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
31        context.check_hostname = False
32        context.verify_mode = ssl.CERT_NONE
33        with socket_helper.transient_internet(self.testServer):
34            server = smtplib.SMTP(self.testServer, self.remotePort)
35            try:
36                server.starttls(context=context)
37            except smtplib.SMTPException as e:
38                if e.args[0] == 'STARTTLS extension not supported by server.':
39                    unittest.skip(e.args[0])
40                else:
41                    raise
42            server.ehlo()
43            server.quit()
44
45
46class SmtpSSLTest(unittest.TestCase):
47    testServer = 'smtp.gmail.com'
48    remotePort = 465
49
50    def test_connect(self):
51        support.get_attribute(smtplib, 'SMTP_SSL')
52        with socket_helper.transient_internet(self.testServer):
53            server = smtplib.SMTP_SSL(self.testServer, self.remotePort)
54            server.ehlo()
55            server.quit()
56
57    def test_connect_default_port(self):
58        support.get_attribute(smtplib, 'SMTP_SSL')
59        with socket_helper.transient_internet(self.testServer):
60            server = smtplib.SMTP_SSL(self.testServer)
61            server.ehlo()
62            server.quit()
63
64    def test_connect_using_sslcontext(self):
65        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
66        context.check_hostname = False
67        context.verify_mode = ssl.CERT_NONE
68        support.get_attribute(smtplib, 'SMTP_SSL')
69        with socket_helper.transient_internet(self.testServer):
70            server = smtplib.SMTP_SSL(self.testServer, self.remotePort, context=context)
71            server.ehlo()
72            server.quit()
73
74    def test_connect_using_sslcontext_verified(self):
75        with socket_helper.transient_internet(self.testServer):
76            can_verify = check_ssl_verifiy(self.testServer, self.remotePort)
77            if not can_verify:
78                self.skipTest("SSL certificate can't be verified")
79
80        support.get_attribute(smtplib, 'SMTP_SSL')
81        context = ssl.create_default_context()
82        with socket_helper.transient_internet(self.testServer):
83            server = smtplib.SMTP_SSL(self.testServer, self.remotePort, context=context)
84            server.ehlo()
85            server.quit()
86
87
88if __name__ == "__main__":
89    unittest.main()
90