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