1
1
Fork 0
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:
Marcus Smith 2013-03-03 22:38:37 -08:00
parent 50e2662bb4
commit 72812c52ff
3 changed files with 25 additions and 3 deletions

View file

@ -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):

View file

@ -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

View file

@ -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.