def test_unwrap_existing_socket(self): """ Validates we can break up the TLS layer A full request/response is sent over TLS, and later over plain text. """ def shutdown_handler(listener): sock = listener.accept()[0] ssl_sock = self.server_context.wrap_socket(sock, server_side=True) request = consume_socket(ssl_sock) validate_request(request) ssl_sock.sendall(sample_response()) unwrapped_sock = ssl_sock.unwrap() request = consume_socket(unwrapped_sock) validate_request(request) unwrapped_sock.sendall(sample_response()) self.start_dummy_server(shutdown_handler) sock = socket.create_connection((self.host, self.port)) ssock = SSLTransport(sock, self.client_context, server_hostname="localhost") # request/response over TLS. ssock.sendall(sample_request()) response = consume_socket(ssock) validate_response(response) # request/response over plaintext after unwrap. ssock.unwrap() sock.sendall(sample_request()) response = consume_socket(sock) validate_response(response)
def socket_handler(listener): sock = listener.accept()[0] consume_socket(sock) # Close the connection, without sending any response (not even the # HTTP status line). This will trigger a `Timeout` on the client, # inside `urlopen()`. sock.close() # Expect a new request. Because we don't want to hang this thread, # we actually use select.select to confirm that a new request is # coming in: this lets us time the thread out. rlist, _, _ = select.select([listener], [], [], 5) assert rlist sock = listener.accept()[0] consume_socket(sock) # Send complete chunked response. sock.send(('HTTP/1.1 200 OK\r\n' 'Content-Type: text/plain\r\n' 'Transfer-Encoding: chunked\r\n' '\r\n' '8\r\n' '12345678\r\n' '0\r\n\r\n').encode('utf-8')) sock.close()
def socket_handler(listener): sock = listener.accept()[0] consume_socket(sock) # Close the connection, without sending any response (not even the # HTTP status line). This will trigger a `Timeout` on the client, # inside `urlopen()`. sock.close() # Expect a new request. Because we don't want to hang this thread, # we actually use select.select to confirm that a new request is # coming in: this lets us time the thread out. rlist, _, _ = select.select([listener], [], [], 5) assert rlist sock = listener.accept()[0] consume_socket(sock) # Send complete chunked response. sock.send(( 'HTTP/1.1 200 OK\r\n' 'Content-Type: text/plain\r\n' 'Transfer-Encoding: chunked\r\n' '\r\n' '8\r\n' '12345678\r\n' '0\r\n\r\n').encode('utf-8') ) sock.close()
def shutdown_handler(listener): sock = listener.accept()[0] ssl_sock = self.server_context.wrap_socket(sock, server_side=True) request = consume_socket(ssl_sock) validate_request(request) ssl_sock.sendall(sample_response()) unwrapped_sock = ssl_sock.unwrap() request = consume_socket(unwrapped_sock) validate_request(request) unwrapped_sock.sendall(sample_response())
def socket_handler(listener): sock = listener.accept()[0] with self.server_context.wrap_socket(sock, server_side=True) as ssock: request = consume_socket(ssock) validate_request(request) ssock.send(sample_response())
def test_ssl_object_attributes(self): """ Ensures common ssl attributes are exposed """ self.start_dummy_server() sock = socket.create_connection((self.host, self.port)) with SSLTransport(sock, self.client_context, server_hostname="localhost") as ssock: cipher = ssock.cipher() assert type(cipher) == tuple # No chosen protocol through ALPN or NPN. assert ssock.selected_alpn_protocol() is None assert ssock.selected_npn_protocol() is None shared_ciphers = ssock.shared_ciphers() assert type(shared_ciphers) == list assert len(shared_ciphers) > 0 assert ssock.compression() is None validate_peercert(ssock) ssock.send(sample_request()) response = consume_socket(ssock) validate_response(response)
def socket_handler(listener): for _ in range(2): sock = listener.accept()[0] request = consume_socket(sock) if b"transfer-encoding: chunked" in request.split(b"\r\n"): self.chunked_requests += 1 sock.send(b"HTTP/1.1 404 Not Found\r\n\r\n") sock.close()
def test_unbuffered_text_makefile(self): self.start_dummy_server() sock = socket.create_connection((self.host, self.port)) with SSLTransport(sock, self.client_context, server_hostname="localhost") as ssock: with pytest.raises(ValueError): ssock.makefile("r", buffering=0) ssock.send(sample_request()) response = consume_socket(ssock) validate_response(response)
def test_wrap_existing_socket(self): """ Validates a single TLS layer can be established. """ self.start_dummy_server() sock = socket.create_connection((self.host, self.port)) with SSLTransport(sock, self.client_context, server_hostname="localhost") as ssock: assert ssock.version() is not None ssock.send(sample_request()) response = consume_socket(ssock) validate_response(response)
def socket_handler(listener): for _ in range(2): sock = listener.accept()[0] request = consume_socket(sock) if b"Transfer-Encoding: chunked" in request.split(b"\r\n"): self.chunked_requests += 1 sock.send(b"HTTP/1.1 429 Too Many Requests\r\n" b"Content-Type: text/plain\r\n" b"Retry-After: 1\r\n" b"\r\n") sock.close()
def socket_handler(listener): for i in range(2): sock = listener.accept()[0] request = consume_socket(sock) if b"transfer-encoding: chunked" in request.split(b"\r\n"): self.chunked_requests += 1 if i == 0: # Bad HTTP version will trigger a connection close sock.send(b"HTTP/0.5 200 OK\r\n\r\n") else: sock.send(b"HTTP/1.1 200 OK\r\n\r\n") sock.close()
def socket_handler(listener): for i in range(2): sock = listener.accept()[0] request = consume_socket(sock) if b"Transfer-Encoding: chunked" in request.split(b"\r\n"): self.chunked_requests += 1 if i == 0: sock.send(b"HTTP/1.1 301 Moved Permanently\r\n" b"Location: /redirect\r\n\r\n") else: sock.send(b"HTTP/1.1 200 OK\r\n\r\n") sock.close()
def socket_handler(listener: socket.socket) -> None: for _ in range(2): sock = listener.accept()[0] self.socks.append(sock) request = consume_socket(sock) if b"Transfer-Encoding: chunked" in request.split(b"\r\n"): self.chunked_requests += 1 sock.send(b"HTTP/1.1 429 Too Many Requests\r\n" b"Content-Type: text/plain\r\n" b"Retry-After: 1\r\n" b"Content-Length: 0\r\n" b"Connection: close\r\n" b"\r\n")
def test_socket_object_attributes(self): """ Ensures common socket attributes are exposed """ self.start_dummy_server() sock = socket.create_connection((self.host, self.port)) with SSLTransport(sock, self.client_context, server_hostname="localhost") as ssock: assert ssock.fileno() is not None test_timeout = 10 ssock.settimeout(test_timeout) assert ssock.gettimeout() == test_timeout assert ssock.socket.gettimeout() == test_timeout ssock.send(sample_request()) response = consume_socket(ssock) validate_response(response)
def test_tls_in_tls_tunnel(self): """ Basic communication over the TLS in TLS tunnel. """ self.start_destination_server() self.start_proxy_server() sock = socket.create_connection( (self.proxy_server.host, self.proxy_server.port)) with self.client_context.wrap_socket( sock, server_hostname="localhost") as proxy_sock: with SSLTransport(proxy_sock, self.client_context, server_hostname="localhost") as destination_sock: assert destination_sock.version() is not None destination_sock.send(sample_request()) response = consume_socket(destination_sock) validate_response(response)
def test_unwrap_existing_socket(self): """ Validates we can break up the TLS layer Request is sent over TLS. response received over regular TCP. Currently disabled as its flaky on occassion. """ def shutdown_handler(listener): sock = listener.accept()[0] ssl_sock = self.server_context.wrap_socket(sock, server_side=True) request = consume_socket(ssl_sock) validate_request(request) sock = ssl_sock.unwrap() sock.send(sample_response()) self.start_dummy_server(shutdown_handler) sock = socket.create_connection((self.host, self.port)) ssock = SSLTransport(sock, self.client_context, server_hostname="localhost") ssock.send(sample_request()) ssock.unwrap() response = consume_socket(sock) validate_response(response)