mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
close socket upon CertificateError
This commit is contained in:
parent
50e2662bb4
commit
72812c52ff
|
@ -12,7 +12,7 @@ import tempfile
|
|||
from pip.backwardcompat import (xmlrpclib, urllib, urllib2, httplib,
|
||||
urlparse, string_types, ssl)
|
||||
if ssl:
|
||||
from pip.backwardcompat import match_hostname
|
||||
from pip.backwardcompat import match_hostname, CertificateError
|
||||
from pip.exceptions import InstallationError, PipError, NoSSLError
|
||||
from pip.util import (splitext, rmtree, format_size, display_path,
|
||||
backup_dir, ask_path_exists, unpack_file,
|
||||
|
@ -103,7 +103,13 @@ class VerifiedHTTPSConnection(httplib.HTTPSConnection):
|
|||
cert_reqs=ssl.CERT_REQUIRED,
|
||||
ca_certs=cert_path)
|
||||
|
||||
match_hostname(self.sock.getpeercert(), self.host)
|
||||
try:
|
||||
match_hostname(self.sock.getpeercert(), self.host)
|
||||
except CertificateError:
|
||||
self.sock.shutdown(socket.SHUT_RDWR)
|
||||
self.sock.close()
|
||||
raise
|
||||
|
||||
|
||||
|
||||
class VerifiedHTTPSHandler(urllib2.HTTPSHandler):
|
||||
|
|
|
@ -491,7 +491,7 @@ class HTMLPage(object):
|
|||
elif isinstance(e, URLError):
|
||||
#ssl/certificate error
|
||||
if ssl and hasattr(e, 'reason') and (isinstance(e.reason, ssl.SSLError) or isinstance(e.reason, CertificateError)):
|
||||
desc = 'there was a problem confirming the ssl certificate %s' % e
|
||||
desc = 'There was a problem confirming the ssl certificate: %s' % e
|
||||
log_meth = logger.notify
|
||||
else:
|
||||
log_meth = logger.info
|
||||
|
|
|
@ -7,6 +7,8 @@ from tests.test_pip import assert_raises_regexp, here, reset_env, run_pip
|
|||
from nose import SkipTest
|
||||
from nose.tools import assert_raises
|
||||
from pip.backwardcompat import urllib2, ssl, URLError
|
||||
if ssl:
|
||||
from pip.backwardcompat import CertificateError
|
||||
from pip.exceptions import PipError
|
||||
|
||||
pypi_https = 'https://pypi.python.org/simple/'
|
||||
|
@ -128,6 +130,20 @@ class Tests_not_py25:
|
|||
assert_raises_regexp(ValueError, 'empty or no certificate', o.open, pypi_https)
|
||||
|
||||
|
||||
@patch('pip.download.match_hostname')
|
||||
def test_raises_certificate_error(self, mock_match_hostname):
|
||||
"""
|
||||
Test CertificateError gets raised, which implicity confirms the sock.shutdown/sock.close calls ran
|
||||
TODO: mock socket._socket.close (to explicitly confirm the close upon exception)
|
||||
"""
|
||||
def mock_matchhostname(cert, host):
|
||||
raise CertificateError()
|
||||
|
||||
mock_match_hostname.side_effect = mock_matchhostname
|
||||
opener = urlopen.get_opener(scheme='https')
|
||||
assert_raises(CertificateError, opener.open, pypi_https)
|
||||
|
||||
|
||||
def test_bad_pem_fails(self):
|
||||
"""
|
||||
Test ssl verification fails with bad pem file.
|
||||
|
|
Loading…
Reference in a new issue