class TestHttpLibSSLTests(unittest.TestCase): def setUp(self): libcloud.security.VERIFY_SSL_CERT = False self.httplib_object = LibcloudHTTPSConnection('foo.bar') def test_verify_hostname(self): cert1 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )) } cert2 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1'))) } cert3 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'python.org'), )) } cert4 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', '*.api.joyentcloud.com'), )) } self.assertFalse( self.httplib_object._verify_hostname(hostname='invalid', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname(hostname='machine.python.org', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname( hostname='foomachine.python.org', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname( hostname='somesomemachine.python.org', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname( hostname='somemachine.python.orga', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname( hostname='somemachine.python.org.org', cert=cert1)) self.assertTrue( self.httplib_object._verify_hostname( hostname='somemachine.python.org', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname(hostname='invalid', cert=cert2)) self.assertFalse( self.httplib_object._verify_hostname(hostname='afoo.alt.name.1', cert=cert2)) self.assertFalse( self.httplib_object._verify_hostname(hostname='a.foo.alt.name.1', cert=cert2)) self.assertFalse( self.httplib_object._verify_hostname(hostname='foo.alt.name.1.2', cert=cert2)) self.assertFalse( self.httplib_object._verify_hostname(hostname='afoo.alt.name.1.2', cert=cert2)) self.assertTrue( self.httplib_object._verify_hostname(hostname='foo.alt.name.1', cert=cert2)) self.assertTrue( self.httplib_object._verify_hostname(hostname='python.org', cert=cert3)) self.assertFalse( self.httplib_object._verify_hostname(hostname='opython.org', cert=cert3)) self.assertFalse( self.httplib_object._verify_hostname(hostname='ython.org', cert=cert3)) self.assertTrue( self.httplib_object._verify_hostname( hostname='us-east-1.api.joyentcloud.com', cert=cert4)) self.assertTrue( self.httplib_object._verify_hostname( hostname='useast-1.api.joyentcloud.com', cert=cert4)) def test_get_subject_alt_names(self): cert1 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )) } cert2 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1'))) } self.assertEqual( self.httplib_object._get_subject_alt_names(cert=cert1), []) alt_names = self.httplib_object._get_subject_alt_names(cert=cert2) self.assertEqual(len(alt_names), 2) self.assertTrue('foo.alt.name' in alt_names) self.assertTrue('foo.alt.name.1' in alt_names) def test_get_common_name(self): cert = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )) } self.assertEqual( self.httplib_object._get_common_name(cert)[0], 'somemachine.python.org') self.assertEqual(self.httplib_object._get_common_name({}), None) def test_setup_verify(self): # @TODO: catch warnings # non-strict mode,s hould just emit a warning libcloud.security.VERIFY_SSL_CERT = True libcloud.security.VERIFY_SSL_CERT_STRICT = False self.httplib_object._setup_verify() # strict mode, should throw a runtime error libcloud.security.VERIFY_SSL_CERT = True libcloud.security.VERIFY_SSL_CERT_STRICT = True try: self.httplib_object._setup_verify() except: pass else: self.fail('Exception not thrown') libcloud.security.VERIFY_SSL_CERT = False libcloud.security.VERIFY_SSL_CERT_STRICT = False self.httplib_object._setup_verify() def test_setup_ca_cert(self): # @TODO: catch warnings self.httplib_object.verify = False self.httplib_object.strict = False self.httplib_object._setup_ca_cert() self.assertEqual(self.httplib_object.ca_cert, None) self.httplib_object.verify = True libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)] self.httplib_object._setup_ca_cert() self.assertTrue(self.httplib_object.ca_cert is not None) libcloud.security.CA_CERTS_PATH = [] self.httplib_object._setup_ca_cert() self.assertFalse(self.httplib_object.ca_cert) self.assertFalse(self.httplib_object.verify)
class TestHttpLibSSLTests(unittest.TestCase): def setUp(self): libcloud.security.VERIFY_SSL_CERT = False self.httplib_object = LibcloudHTTPSConnection('foo.bar') def test_verify_hostname(self): cert1 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),))} cert2 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),)), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1')))} self.assertFalse(self.httplib_object._verify_hostname( hostname='invalid', cert=cert1)) self.assertTrue(self.httplib_object._verify_hostname( hostname='somemachine.python.org', cert=cert1)) self.assertFalse(self.httplib_object._verify_hostname( hostname='invalid', cert=cert2)) self.assertTrue(self.httplib_object._verify_hostname( hostname='foo.alt.name.1', cert=cert2)) def test_get_subject_alt_names(self): cert1 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),))} cert2 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),)), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1')))} self.assertEqual(self.httplib_object._get_subject_alt_names(cert=cert1), []) alt_names = self.httplib_object._get_subject_alt_names(cert=cert2) self.assertEqual(len(alt_names), 2) self.assertTrue('foo.alt.name' in alt_names) self.assertTrue('foo.alt.name.1' in alt_names) def test_get_common_name(self): cert = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),))} self.assertEqual(self.httplib_object._get_common_name(cert)[0], 'somemachine.python.org') self.assertEqual(self.httplib_object._get_common_name({}), None) def test_setup_verify(self): # @TODO: catch warnings # non-strict mode,s hould just emit a warning libcloud.security.VERIFY_SSL_CERT = True libcloud.security.VERIFY_SSL_CERT_STRICT = False self.httplib_object._setup_verify() # strict mode, should throw a runtime error libcloud.security.VERIFY_SSL_CERT = True libcloud.security.VERIFY_SSL_CERT_STRICT = True try: self.httplib_object._setup_verify() except: pass else: self.fail('Exception not thrown') libcloud.security.VERIFY_SSL_CERT = False libcloud.security.VERIFY_SSL_CERT_STRICT = False self.httplib_object._setup_verify() def test_setup_ca_cert(self): # @TODO: catch warnings self.httplib_object.verify = False self.httplib_object.strict = False self.httplib_object._setup_ca_cert() self.assertEqual(self.httplib_object.ca_cert, None) self.httplib_object.verify = True libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)] self.httplib_object._setup_ca_cert() self.assertTrue(self.httplib_object.ca_cert is not None) libcloud.security.CA_CERTS_PATH = [] self.httplib_object._setup_ca_cert() self.assertFalse(self.httplib_object.ca_cert) self.assertFalse(self.httplib_object.verify)
class TestHttpLibSSLTests(unittest.TestCase): def setUp(self): libcloud.security.VERIFY_SSL_CERT = False libcloud.security.CA_CERTS_PATH = ORIGINAL_CA_CERS_PATH self.httplib_object = LibcloudHTTPSConnection('foo.bar') def test_custom_ca_path_using_env_var_doesnt_exist(self): os.environ['SSL_CERT_FILE'] = '/foo/doesnt/exist' try: reload(libcloud.security) except ValueError: e = sys.exc_info()[1] msg = 'Certificate file /foo/doesnt/exist doesn\'t exist' self.assertEqual(str(e), msg) else: self.fail('Exception was not thrown') def test_custom_ca_path_using_env_var_is_directory(self): file_path = os.path.dirname(os.path.abspath(__file__)) os.environ['SSL_CERT_FILE'] = file_path expected_msg = 'Certificate file can\'t be a directory' self.assertRaisesRegexp(ValueError, expected_msg, reload, libcloud.security) def test_custom_ca_path_using_env_var_exist(self): # When setting a path we don't actually check that a valid CA file is # provided. # This happens later in the code in httplib_ssl.connect method file_path = os.path.abspath(__file__) os.environ['SSL_CERT_FILE'] = file_path reload(libcloud.security) self.assertEqual(libcloud.security.CA_CERTS_PATH, [file_path]) @patch('warnings.warn') def test_setup_verify(self, _): libcloud.security.CA_CERTS_PATH = [] # Should throw a runtime error libcloud.security.VERIFY_SSL_CERT = True expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG self.assertRaisesRegexp(RuntimeError, expected_msg, self.httplib_object._setup_verify) libcloud.security.VERIFY_SSL_CERT = False self.httplib_object._setup_verify() @patch('warnings.warn') def test_setup_ca_cert(self, _): # verify = False, _setup_ca_cert should be a no-op self.httplib_object.verify = False self.httplib_object._setup_ca_cert() self.assertEqual(self.httplib_object.ca_cert, None) # verify = True, a valid path is provided, self.ca_cert should be set to # a valid path self.httplib_object.verify = True libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)] self.httplib_object._setup_ca_cert() self.assertTrue(self.httplib_object.ca_cert is not None) # verify = True, no CA certs are available, exception should be thrown libcloud.security.CA_CERTS_PATH = [] expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG self.assertRaisesRegexp(RuntimeError, expected_msg, self.httplib_object._setup_ca_cert) @mock.patch('socket.create_connection', mock.MagicMock()) @mock.patch('socket.socket', mock.MagicMock()) @mock.patch('ssl.wrap_socket') def test_connect_throws_friendly_error_message_on_ssl_wrap_connection_reset_by_peer( self, mock_wrap_socket): # Test that we re-throw a more friendly error message in case # "connection reset by peer" error occurs when trying to establish a # SSL connection libcloud.security.VERIFY_SSL_CERT = True self.httplib_object.verify = True self.httplib_object.http_proxy_used = False # No connection reset by peer, original exception should be thrown mock_wrap_socket.side_effect = Exception('foo bar fail') expected_msg = 'foo bar fail' self.assertRaisesRegexp(Exception, expected_msg, self.httplib_object.connect) # Connection reset by peer, wrapped exception with friendly error # message should be thrown mock_wrap_socket.side_effect = socket.error('Connection reset by peer') expected_msg = 'Failed to establish SSL / TLS connection' self.assertRaisesRegexp(socket.error, expected_msg, self.httplib_object.connect) # Same error but including errno with self.assertRaises(socket.error) as cm: mock_wrap_socket.side_effect = socket.error( 104, 'Connection reset by peer') self.httplib_object.connect() e = cm.exception self.assertEqual(e.errno, 104) self.assertTrue(expected_msg in str(e)) # Test original exception is propagated correctly on non reset by peer # error with self.assertRaises(socket.error) as cm: mock_wrap_socket.side_effect = socket.error( 105, 'Some random error') self.httplib_object.connect() e = cm.exception self.assertEqual(e.errno, 105) self.assertTrue('Some random error' in str(e)) def test_certifi_ca_bundle_in_search_path(self): mock_certifi_ca_bundle_path = '/certifi/bundle/path' # Certifi not available import libcloud.security reload(libcloud.security) original_length = len(libcloud.security.CA_CERTS_PATH) self.assertTrue( mock_certifi_ca_bundle_path not in libcloud.security.CA_CERTS_PATH) # Certifi is available mock_certifi = mock.Mock() mock_certifi.where.return_value = mock_certifi_ca_bundle_path sys.modules['certifi'] = mock_certifi # Certifi CA bundle path should be injected at the begining of search list import libcloud.security reload(libcloud.security) self.assertEqual(libcloud.security.CA_CERTS_PATH[0], mock_certifi_ca_bundle_path) self.assertEqual(len(libcloud.security.CA_CERTS_PATH), (original_length + 1)) # Certifi is available, but USE_CERTIFI is set to False os.environ['LIBCLOUD_SSL_USE_CERTIFI'] = 'false' import libcloud.security reload(libcloud.security) self.assertTrue( mock_certifi_ca_bundle_path not in libcloud.security.CA_CERTS_PATH) self.assertEqual(len(libcloud.security.CA_CERTS_PATH), original_length) # And enabled os.environ['LIBCLOUD_SSL_USE_CERTIFI'] = 'true' import libcloud.security reload(libcloud.security) self.assertEqual(libcloud.security.CA_CERTS_PATH[0], mock_certifi_ca_bundle_path) self.assertEqual(len(libcloud.security.CA_CERTS_PATH), (original_length + 1))
class TestHttpLibSSLTests(unittest.TestCase): def setUp(self): libcloud.security.VERIFY_SSL_CERT = False libcloud.security.CA_CERTS_PATH = ORIGINAL_CA_CERS_PATH self.httplib_object = LibcloudHTTPSConnection('foo.bar') def test_custom_ca_path_using_env_var_doesnt_exist(self): os.environ['SSL_CERT_FILE'] = '/foo/doesnt/exist' try: reload(libcloud.security) except ValueError: e = sys.exc_info()[1] msg = 'Certificate file /foo/doesnt/exist doesn\'t exist' self.assertEqual(str(e), msg) else: self.fail('Exception was not thrown') def test_custom_ca_path_using_env_var_is_directory(self): file_path = os.path.dirname(os.path.abspath(__file__)) os.environ['SSL_CERT_FILE'] = file_path expected_msg = 'Certificate file can\'t be a directory' self.assertRaisesRegexp(ValueError, expected_msg, reload, libcloud.security) def test_custom_ca_path_using_env_var_exist(self): # When setting a path we don't actually check that a valid CA file is # provided. # This happens later in the code in httplib_ssl.connect method file_path = os.path.abspath(__file__) os.environ['SSL_CERT_FILE'] = file_path reload(libcloud.security) self.assertEqual(libcloud.security.CA_CERTS_PATH, [file_path]) @patch('warnings.warn') def test_setup_verify(self, _): libcloud.security.CA_CERTS_PATH = [] # Should throw a runtime error libcloud.security.VERIFY_SSL_CERT = True expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG self.assertRaisesRegexp(RuntimeError, expected_msg, self.httplib_object._setup_verify) libcloud.security.VERIFY_SSL_CERT = False self.httplib_object._setup_verify() @patch('warnings.warn') def test_setup_ca_cert(self, _): # verify = False, _setup_ca_cert should be a no-op self.httplib_object.verify = False self.httplib_object._setup_ca_cert() self.assertEqual(self.httplib_object.ca_cert, None) # verify = True, a valid path is provided, self.ca_cert should be set to # a valid path self.httplib_object.verify = True libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)] self.httplib_object._setup_ca_cert() self.assertTrue(self.httplib_object.ca_cert is not None) # verify = True, no CA certs are available, exception should be thrown libcloud.security.CA_CERTS_PATH = [] expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG self.assertRaisesRegexp(RuntimeError, expected_msg, self.httplib_object._setup_ca_cert)
class TestHttpLibSSLTests(unittest.TestCase): def setUp(self): libcloud.security.VERIFY_SSL_CERT = False libcloud.security.CA_CERTS_PATH = ORIGINAL_CA_CERS_PATH self.httplib_object = LibcloudHTTPSConnection('foo.bar') def test_custom_ca_path_using_env_var_doesnt_exist(self): os.environ['SSL_CERT_FILE'] = '/foo/doesnt/exist' try: reload(libcloud.security) except ValueError: e = sys.exc_info()[1] msg = 'Certificate file /foo/doesnt/exist doesn\'t exist' self.assertEqual(str(e), msg) else: self.fail('Exception was not thrown') def test_custom_ca_path_using_env_var_is_directory(self): file_path = os.path.dirname(os.path.abspath(__file__)) os.environ['SSL_CERT_FILE'] = file_path expected_msg = 'Certificate file can\'t be a directory' self.assertRaisesRegexp(ValueError, expected_msg, reload, libcloud.security) def test_custom_ca_path_using_env_var_exist(self): # When setting a path we don't actually check that a valid CA file is # provided. # This happens later in the code in httplib_ssl.connect method file_path = os.path.abspath(__file__) os.environ['SSL_CERT_FILE'] = file_path reload(libcloud.security) self.assertEqual(libcloud.security.CA_CERTS_PATH, [file_path]) def test_verify_hostname(self): # commonName cert1 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),))} # commonName cert2 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),)), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1')))} # commonName cert3 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'python.org'),))} # wildcard commonName cert4 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', '*.api.joyentcloud.com'),))} self.assertFalse(self.httplib_object._verify_hostname( hostname='invalid', cert=cert1)) self.assertFalse(self.httplib_object._verify_hostname( hostname='machine.python.org', cert=cert1)) self.assertFalse(self.httplib_object._verify_hostname( hostname='foomachine.python.org', cert=cert1)) self.assertFalse(self.httplib_object._verify_hostname( hostname='somesomemachine.python.org', cert=cert1)) self.assertFalse(self.httplib_object._verify_hostname( hostname='somemachine.python.orga', cert=cert1)) self.assertFalse(self.httplib_object._verify_hostname( hostname='somemachine.python.org.org', cert=cert1)) self.assertTrue(self.httplib_object._verify_hostname( hostname='somemachine.python.org', cert=cert1)) self.assertFalse(self.httplib_object._verify_hostname( hostname='invalid', cert=cert2)) self.assertFalse(self.httplib_object._verify_hostname( hostname='afoo.alt.name.1', cert=cert2)) self.assertFalse(self.httplib_object._verify_hostname( hostname='a.foo.alt.name.1', cert=cert2)) self.assertFalse(self.httplib_object._verify_hostname( hostname='foo.alt.name.1.2', cert=cert2)) self.assertFalse(self.httplib_object._verify_hostname( hostname='afoo.alt.name.1.2', cert=cert2)) self.assertTrue(self.httplib_object._verify_hostname( hostname='foo.alt.name.1', cert=cert2)) self.assertTrue(self.httplib_object._verify_hostname( hostname='python.org', cert=cert3)) self.assertFalse(self.httplib_object._verify_hostname( hostname='opython.org', cert=cert3)) self.assertFalse(self.httplib_object._verify_hostname( hostname='ython.org', cert=cert3)) self.assertTrue(self.httplib_object._verify_hostname( hostname='us-east-1.api.joyentcloud.com', cert=cert4)) self.assertTrue(self.httplib_object._verify_hostname( hostname='useast-1.api.joyentcloud.com', cert=cert4)) self.assertFalse(self.httplib_object._verify_hostname( hostname='t1.useast-1.api.joyentcloud.com', cert=cert4)) self.assertFalse(self.httplib_object._verify_hostname( hostname='ponies.useast-1.api.joyentcloud.com', cert=cert4)) self.assertFalse(self.httplib_object._verify_hostname( hostname='api.useast-1.api.joyentcloud.com', cert=cert4)) def test_get_subject_alt_names(self): cert1 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),))} cert2 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),)), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1')))} self.assertEqual(self.httplib_object._get_subject_alt_names(cert=cert1), []) alt_names = self.httplib_object._get_subject_alt_names(cert=cert2) self.assertEqual(len(alt_names), 2) self.assertTrue('foo.alt.name' in alt_names) self.assertTrue('foo.alt.name.1' in alt_names) def test_get_common_name(self): cert = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),))} self.assertEqual(self.httplib_object._get_common_name(cert)[0], 'somemachine.python.org') self.assertEqual(self.httplib_object._get_common_name({}), None) @patch('warnings.warn') def test_setup_verify(self, _): libcloud.security.CA_CERTS_PATH = [] # Should throw a runtime error libcloud.security.VERIFY_SSL_CERT = True expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG self.assertRaisesRegexp(RuntimeError, expected_msg, self.httplib_object._setup_verify) libcloud.security.VERIFY_SSL_CERT = False self.httplib_object._setup_verify() @patch('warnings.warn') def test_setup_ca_cert(self, _): # verify = False, _setup_ca_cert should be a no-op self.httplib_object.verify = False self.httplib_object._setup_ca_cert() self.assertEqual(self.httplib_object.ca_cert, None) # verify = True, a valid path is provided, self.ca_cert should be set to # a valid path self.httplib_object.verify = True libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)] self.httplib_object._setup_ca_cert() self.assertTrue(self.httplib_object.ca_cert is not None) # verify = True, no CA certs are available, exception should be thrown libcloud.security.CA_CERTS_PATH = [] expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG self.assertRaisesRegexp(RuntimeError, expected_msg, self.httplib_object._setup_ca_cert)
class TestHttpLibSSLTests(unittest.TestCase): def setUp(self): libcloud.security.VERIFY_SSL_CERT = False libcloud.security.CA_CERTS_PATH = ORIGINAL_CA_CERS_PATH self.httplib_object = LibcloudHTTPSConnection('foo.bar') def test_custom_ca_path_using_env_var_doesnt_exist(self): os.environ['SSL_CERT_FILE'] = '/foo/doesnt/exist' try: reload(libcloud.security) except ValueError: e = sys.exc_info()[1] msg = 'Certificate file /foo/doesnt/exist doesn\'t exist' self.assertEqual(str(e), msg) else: self.fail('Exception was not thrown') def test_custom_ca_path_using_env_var_is_directory(self): file_path = os.path.dirname(os.path.abspath(__file__)) os.environ['SSL_CERT_FILE'] = file_path expected_msg = 'Certificate file can\'t be a directory' self.assertRaisesRegexp(ValueError, expected_msg, reload, libcloud.security) def test_custom_ca_path_using_env_var_exist(self): # When setting a path we don't actually check that a valid CA file is # provided. # This happens later in the code in httplib_ssl.connect method file_path = os.path.abspath(__file__) os.environ['SSL_CERT_FILE'] = file_path reload(libcloud.security) self.assertEqual(libcloud.security.CA_CERTS_PATH, [file_path]) def test_verify_hostname(self): # commonName cert1 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )) } # commonName cert2 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1'))) } # commonName cert3 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'python.org'), )) } # wildcard commonName cert4 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', '*.api.joyentcloud.com'), )) } self.assertFalse( self.httplib_object._verify_hostname(hostname='invalid', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname(hostname='machine.python.org', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname( hostname='foomachine.python.org', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname( hostname='somesomemachine.python.org', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname( hostname='somemachine.python.orga', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname( hostname='somemachine.python.org.org', cert=cert1)) self.assertTrue( self.httplib_object._verify_hostname( hostname='somemachine.python.org', cert=cert1)) self.assertFalse( self.httplib_object._verify_hostname(hostname='invalid', cert=cert2)) self.assertFalse( self.httplib_object._verify_hostname(hostname='afoo.alt.name.1', cert=cert2)) self.assertFalse( self.httplib_object._verify_hostname(hostname='a.foo.alt.name.1', cert=cert2)) self.assertFalse( self.httplib_object._verify_hostname(hostname='foo.alt.name.1.2', cert=cert2)) self.assertFalse( self.httplib_object._verify_hostname(hostname='afoo.alt.name.1.2', cert=cert2)) self.assertTrue( self.httplib_object._verify_hostname(hostname='foo.alt.name.1', cert=cert2)) self.assertTrue( self.httplib_object._verify_hostname(hostname='python.org', cert=cert3)) self.assertFalse( self.httplib_object._verify_hostname(hostname='opython.org', cert=cert3)) self.assertFalse( self.httplib_object._verify_hostname(hostname='ython.org', cert=cert3)) self.assertTrue( self.httplib_object._verify_hostname( hostname='us-east-1.api.joyentcloud.com', cert=cert4)) self.assertTrue( self.httplib_object._verify_hostname( hostname='useast-1.api.joyentcloud.com', cert=cert4)) self.assertFalse( self.httplib_object._verify_hostname( hostname='t1.useast-1.api.joyentcloud.com', cert=cert4)) self.assertFalse( self.httplib_object._verify_hostname( hostname='ponies.useast-1.api.joyentcloud.com', cert=cert4)) self.assertFalse( self.httplib_object._verify_hostname( hostname='api.useast-1.api.joyentcloud.com', cert=cert4)) def test_get_subject_alt_names(self): cert1 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )) } cert2 = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1'))) } self.assertEqual( self.httplib_object._get_subject_alt_names(cert=cert1), []) alt_names = self.httplib_object._get_subject_alt_names(cert=cert2) self.assertEqual(len(alt_names), 2) self.assertTrue('foo.alt.name' in alt_names) self.assertTrue('foo.alt.name.1' in alt_names) def test_get_common_name(self): cert = { 'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'), ), (('stateOrProvinceName', 'Delaware'), ), (('localityName', 'Wilmington'), ), (('organizationName', 'Python Software Foundation'), ), (('organizationalUnitName', 'SSL'), ), (('commonName', 'somemachine.python.org'), )) } self.assertEqual( self.httplib_object._get_common_name(cert)[0], 'somemachine.python.org') self.assertEqual(self.httplib_object._get_common_name({}), None) @patch('warnings.warn') def test_setup_verify(self, _): libcloud.security.CA_CERTS_PATH = [] # Should throw a runtime error libcloud.security.VERIFY_SSL_CERT = True expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG self.assertRaisesRegexp(RuntimeError, expected_msg, self.httplib_object._setup_verify) libcloud.security.VERIFY_SSL_CERT = False self.httplib_object._setup_verify() @patch('warnings.warn') def test_setup_ca_cert(self, _): # verify = False, _setup_ca_cert should be a no-op self.httplib_object.verify = False self.httplib_object._setup_ca_cert() self.assertEqual(self.httplib_object.ca_cert, None) # verify = True, a valid path is provided, self.ca_cert should be set to # a valid path self.httplib_object.verify = True libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)] self.httplib_object._setup_ca_cert() self.assertTrue(self.httplib_object.ca_cert is not None) # verify = True, no CA certs are available, exception should be thrown libcloud.security.CA_CERTS_PATH = [] expected_msg = libcloud.security.CA_CERTS_UNAVAILABLE_ERROR_MSG self.assertRaisesRegexp(RuntimeError, expected_msg, self.httplib_object._setup_ca_cert)
class TestHttpLibSSLTests(unittest.TestCase): def setUp(self): self.httplib_object = LibcloudHTTPSConnection('foo.bar') def test_verify_hostname(self): cert1 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),))} cert2 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),)), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1')))} self.assertFalse(self.httplib_object._verify_hostname( hostname='invalid', cert=cert1)) self.assertTrue(self.httplib_object._verify_hostname( hostname='somemachine.python.org', cert=cert1)) self.assertFalse(self.httplib_object._verify_hostname( hostname='invalid', cert=cert2)) self.assertTrue(self.httplib_object._verify_hostname( hostname='foo.alt.name.1', cert=cert2)) def test_get_subject_alt_names(self): cert1 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),))} cert2 = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),)), 'subjectAltName': ((('DNS', 'foo.alt.name')), (('DNS', 'foo.alt.name.1')))} self.assertEqual(self.httplib_object._get_subject_alt_names(cert=cert1), []) alt_names = self.httplib_object._get_subject_alt_names(cert=cert2) self.assertEqual(len(alt_names), 2) self.assertTrue('foo.alt.name' in alt_names) self.assertTrue('foo.alt.name.1' in alt_names) def test_get_common_name(self): cert = {'notAfter': 'Feb 16 16:54:50 2013 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'Delaware'),), (('localityName', 'Wilmington'),), (('organizationName', 'Python Software Foundation'),), (('organizationalUnitName', 'SSL'),), (('commonName', 'somemachine.python.org'),))} self.assertEqual(self.httplib_object._get_common_name(cert)[0], 'somemachine.python.org') self.assertEqual(self.httplib_object._get_common_name({}), None) def test_setup_verify(self): # @TODO: catch warnings libcloud.security.VERIFY_SSL_CERT = True self.httplib_object._setup_verify() libcloud.security.VERIFY_SSL_CERT = False self.httplib_object._setup_verify() def test_setup_ca_cert(self): # @TODO: catch warnings self.httplib_object.verify = False self.httplib_object._setup_ca_cert() self.assertEqual(self.httplib_object.ca_cert, None) self.httplib_object.verify = True libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)] self.httplib_object._setup_ca_cert() self.assertTrue(self.httplib_object.ca_cert is not None) libcloud.security.CA_CERTS_PATH = [] self.httplib_object._setup_ca_cert() self.assertFalse(self.httplib_object.ca_cert) self.assertFalse(self.httplib_object.verify)