def _configured_socket(address, options): """Given (host, port) and PoolOptions, return a configured socket. Can raise socket.error, ConnectionFailure, or CertificateError. Sets socket's SSL and timeout options. """ sock = _create_connection(address, options) ssl_context = options.ssl_context if ssl_context is not None: host = address[0] try: # According to RFC6066, section 3, IPv4 and IPv6 literals are # not permitted for SNI hostname. if _HAVE_SNI and not is_ip_address(host): sock = ssl_context.wrap_socket(sock, server_hostname=host) else: sock = ssl_context.wrap_socket(sock) except IOError as exc: sock.close() raise ConnectionFailure("SSL handshake failed: %s" % (str(exc),)) if ssl_context.verify_mode and options.ssl_match_hostname: try: match_hostname(sock.getpeercert(), hostname=host) except CertificateError: sock.close() raise sock.settimeout(options.socket_timeout) return sock
def _configured_socket(address, options): """Given (host, port) and PoolOptions, return a configured socket. Can raise socket.error, ConnectionFailure, or CertificateError. Sets socket's SSL and timeout options. """ sock = _create_connection(address, options) ssl_context = options.ssl_context if ssl_context is not None: host = address[0] try: # According to RFC6066, section 3, IPv4 and IPv6 literals are # not permitted for SNI hostname. # Previous to Python 3.7 wrap_socket would blindly pass # IP addresses as SNI hostname. # https://bugs.python.org/issue32185 # We have to pass hostname / ip address to wrap_socket # to use SSLContext.check_hostname. if _HAVE_SNI and (not is_ip_address(host) or _PY37PLUS): sock = ssl_context.wrap_socket(sock, server_hostname=host) else: sock = ssl_context.wrap_socket(sock) except _SSLCertificateError: sock.close() # Raise CertificateError directly like we do after match_hostname # below. raise except IOError as exc: sock.close() # We raise AutoReconnect for transient and permanent SSL handshake # failures alike. Permanent handshake failures, like protocol # mismatch, will be turned into ServerSelectionTimeoutErrors later. _raise_connection_failure(address, exc, "SSL handshake failed: ") if (ssl_context.verify_mode and not getattr(ssl_context, "check_hostname", False) and options.ssl_match_hostname): try: match_hostname(sock.getpeercert(), hostname=host) except CertificateError: sock.close() raise sock.settimeout(options.socket_timeout) return sock
def _configured_socket(address, options): """Given (host, port) and PoolOptions, return a configured socket. Can raise socket.error, ConnectionFailure, or CertificateError. Sets socket's SSL and timeout options. """ sock = _create_connection(address, options) ssl_context = options.ssl_context if ssl_context is not None: host = address[0] try: # According to RFC6066, section 3, IPv4 and IPv6 literals are # not permitted for SNI hostname. # Previous to Python 3.7 wrap_socket would blindly pass # IP addresses as SNI hostname. # https://bugs.python.org/issue32185 # We have to pass hostname / ip address to wrap_socket # to use SSLContext.check_hostname. if _HAVE_SNI and (not is_ip_address(host) or _PY37PLUS): sock = ssl_context.wrap_socket(sock, server_hostname=host) else: sock = ssl_context.wrap_socket(sock) except IOError as exc: sock.close() raise ConnectionFailure("SSL handshake failed: %s" % (str(exc), )) if (ssl_context.verify_mode and not getattr(ssl_context, "check_hostname", False) and options.ssl_match_hostname): try: match_hostname(sock.getpeercert(), hostname=host) except CertificateError: sock.close() raise sock.settimeout(options.socket_timeout) return sock