1"""unit tests module for ndg.httpsclient.urllib2_build_opener module
2
3PyOpenSSL utility to make a httplib-like interface suitable for use with
4urllib2
5"""
6__author__ = "P J Kershaw (STFC)"
7__date__ = "06/01/12"
8__copyright__ = "(C) 2012 Science and Technology Facilities Council"
9__license__ = "BSD - see LICENSE file in top-level directory"
10__contact__ = "Philip.Kershaw@stfc.ac.uk"
11__revision__ = '$Id$'
12import sys
13
14if sys.version_info[0] > 2:
15    from urllib.error import URLError as URLError
16else:
17    from urllib2 import URLError as URLError
18
19import unittest
20
21from OpenSSL import SSL
22from ndg.httpsclient.test import Constants
23from ndg.httpsclient.urllib2_build_opener import build_opener
24from ndg.httpsclient.ssl_peer_verification import ServerSSLCertVerification
25
26
27class Urllib2TestCase(unittest.TestCase):
28    """Unit tests for urllib2 functionality"""
29
30    def test01_urllib2_build_opener(self):
31        opener = build_opener()
32        self.assertTrue(opener)
33
34    def test02_open(self):
35        opener = build_opener()
36        res = opener.open(Constants.TEST_URI)
37        self.assertTrue(res)
38        print("res = %s" % res.read())
39
40    # Skip this test for remote service as it can take a long time to timeout
41    @unittest.skipIf(Constants.HOSTNAME != 'localhost', 'Skip non-local host')
42    def test03_open_fails_unknown_loc(self):
43        opener = build_opener()
44        self.assertRaises(URLError, opener.open, Constants.TEST_URI2)
45
46    def test04_open_peer_cert_verification_fails(self):
47        # Explicitly set empty CA directory to make verification fail
48        ctx = SSL.Context(SSL.TLSv1_2_METHOD)
49        verify_callback = lambda conn, x509, errnum, errdepth, preverify_ok: \
50            preverify_ok
51
52        ctx.set_verify(SSL.VERIFY_PEER, verify_callback)
53        ctx.load_verify_locations(None, './')
54        opener = build_opener(ssl_context=ctx)
55        self.assertRaises(SSL.Error, opener.open, Constants.TEST_URI)
56
57    def test05_open_with_subj_alt_names_verification(self):
58        ctx = SSL.Context(SSL.TLSv1_2_METHOD)
59
60        # Set wildcard hostname for subject alternative name matching -
61        # setting a minimum of two name components for hostname
62        split_hostname = Constants.HOSTNAME.split('.', 1)
63        if len(split_hostname) > 1:
64            _hostname = '*.' + split_hostname[-1]
65        else:
66            _hostname = Constants.HOSTNAME
67
68        server_ssl_verify = ServerSSLCertVerification(hostname=_hostname)
69        verify_callback_ = server_ssl_verify.get_verify_server_cert_func()
70        ctx.set_verify(SSL.VERIFY_PEER, verify_callback_)
71
72        # Set default verify paths if testing with peer that has corresponding
73        # CA cert in bundle provided with the OS.  In this case, load verify
74        # locations is not needed.
75        #ctx.set_default_verify_paths()
76
77        ctx.set_verify_depth(9)
78
79        # Set correct location for CA certs to verify with
80        ctx.load_verify_locations(None, Constants.CACERT_DIR)
81
82        opener = build_opener(ssl_context=ctx)
83        res = opener.open(Constants.TEST_URI)
84        self.assertTrue(res)
85        print("res = %s" % res.read())
86
87
88if __name__ == "__main__":
89    unittest.main()
90