Repository: urllib3/urllib3

Issue:
assert_hostname=False seems to be ignored in 1.10
I have some code that is relying on assert_hostname=False to work.
I upgrade urllib3 to version 1.10 and the code fails with SSLError: hostname 'remote-host' doesn't match 'localhost'

I haven't looked through the code to try to determine why this happens.

Did anyone else notice this? If so, what is the fix.

Essentially I am creating a connection pool like this:

``` python
import urllib3

http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',
                           ca_certs="cert.pem",
                           assert_hostname=False)
try:
    r = http.request('GET', 'https://remote-host:4443/')
    print("Certificate verification NO HOSTNAME successful")

except urllib3.exceptions.SSLError as e:
    print ("SSL Error:", e)
    return -1

return 0
```



Discussion:
One quick question:
1. Does this pass _right now_ with an older version of urllib3?

Which platform are you using? It works for me.

I am trying with Linux, python2.6 (to have no SNI) and this code:

``` py
import urllib3

http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', assert_hostname=False,
                           ca_certs='/etc/ssl/certs/ca-certificates.crt')

try:
    r = http.request('GET', 'https://sni.velox.ch')
    print(r.data)
    print("Certificate verification NO HOSTNAME successful")

except urllib3.exceptions.SSLError as e:
    print("SSL Error:", e)
```

@Lukasa : I downgraded urllib3 using `easy_install3 urllib3==1.9.1` and the code passed.

@t-8ch : I was running this under Linux, python3.4.0.
What happens with your code if you put `assert_hostname=True`? Does it fail in that case?

@alecz20 `assert_hostname=True` is not a valid parameter

Could you try: `assert_hostname='localhost'`
(It also seems, that conceptually you may want to use `assert_fingerprint`)


Resolving patch:
diff --git a/urllib3/util/ssl_.py b/urllib3/util/ssl_.py
--- a/urllib3/util/ssl_.py
+++ b/urllib3/util/ssl_.py
@@ -211,7 +211,9 @@ def create_urllib3_context(ssl_version=None, cert_reqs=ssl.CERT_REQUIRED,
 
     context.verify_mode = cert_reqs
     if getattr(context, 'check_hostname', None) is not None:  # Platform-specific: Python 3.2
-        context.check_hostname = (context.verify_mode == ssl.CERT_REQUIRED)
+        # We do our own verification, including fingerprints and alternative
+        # hostnames. So disable it here
+        context.check_hostname = False
     return context
 
 


Test patch:
diff --git a/test/with_dummyserver/test_https.py b/test/with_dummyserver/test_https.py
--- a/test/with_dummyserver/test_https.py
+++ b/test/with_dummyserver/test_https.py
@@ -240,6 +240,15 @@ def test_verify_none_and_good_fingerprint(self):
                                         '7A:F2:8A:D7:1E:07:33:67:DE'
         https_pool.request('GET', '/')
 
+    def test_good_fingerprint_and_hostname_mismatch(self):
+        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
+                                         cert_reqs='CERT_REQUIRED',
+                                         ca_certs=DEFAULT_CA)
+
+        https_pool.assert_fingerprint = 'CC:45:6A:90:82:F7FF:C0:8218:8e:' \
+                                        '7A:F2:8A:D7:1E:07:33:67:DE'
+        https_pool.request('GET', '/')
+
     @requires_network
     def test_https_timeout(self):
         timeout = Timeout(connect=0.001)