def test_socks4_with_username(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks4_negotiation(sock, username=b"user") addr, port = next(handler) assert addr == "16.17.18.19" assert port == 80 handler.send(True) while True: buf = sock.recv(65535) if buf.endswith(b"\r\n\r\n"): break sock.sendall(b"HTTP/1.1 200 OK\r\n" b"Server: SocksTestServer\r\n" b"Content-Length: 0\r\n" b"\r\n") sock.close() self._start_server(request_handler) proxy_url = "socks4://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url, username="******") as pm: response = pm.request("GET", "http://16.17.18.19") assert response.status == 200 assert response.data == b"" assert response.headers["Server"] == "SocksTestServer"
def test_correct_header_line(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks4_negotiation(sock) addr, port = next(handler) assert addr == b"example.com" assert port == 80 handler.send(True) buf = b"" while True: buf += sock.recv(65535) if buf.endswith(b"\r\n\r\n"): break assert buf.startswith(b"GET / HTTP/1.1") assert b"Host: example.com" in buf sock.sendall(b"HTTP/1.1 200 OK\r\n" b"Server: SocksTestServer\r\n" b"Content-Length: 0\r\n" b"\r\n") sock.close() self._start_server(request_handler) proxy_url = "socks4a://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url) as pm: response = pm.request("GET", "http://example.com") assert response.status == 200
def test_local_dns(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) assert addr in ["127.0.0.1", "::1"] assert port == 80 handler.send(True) while True: buf = sock.recv(65535) if buf.endswith(b"\r\n\r\n"): break sock.sendall(b"HTTP/1.1 200 OK\r\n" b"Server: SocksTestServer\r\n" b"Content-Length: 0\r\n" b"\r\n") sock.close() self._start_server(request_handler) proxy_url = "socks5://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url) as pm: response = pm.request("GET", "http://localhost") assert response.status == 200 assert response.data == b"" assert response.headers["Server"] == "SocksTestServer"
def test_source_address_works(self): expected_port = _get_free_port(self.host) def request_handler(listener): sock = listener.accept()[0] assert sock.getpeername()[0] == "127.0.0.1" assert sock.getpeername()[1] == expected_port handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) assert addr == "16.17.18.19" assert port == 80 handler.send(True) while True: buf = sock.recv(65535) if buf.endswith(b"\r\n\r\n"): break sock.sendall(b"HTTP/1.1 200 OK\r\n" b"Server: SocksTestServer\r\n" b"Content-Length: 0\r\n" b"\r\n") sock.close() self._start_server(request_handler) proxy_url = "socks5://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url, source_address=("127.0.0.1", expected_port)) as pm: response = pm.request("GET", "http://16.17.18.19") assert response.status == 200
def test_socks_with_invalid_username(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks4_negotiation(sock, username=b"user") next(handler) self._start_server(request_handler) proxy_url = "socks4a://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url, username="******") as pm: with pytest.raises(NewConnectionError) as e: pm.request("GET", "http://example.com", retries=False) assert "different user-ids" in str(e.value)
def test_connection_failure(self): event = threading.Event() def request_handler(listener): listener.close() event.set() self._start_server(request_handler) proxy_url = "socks5h://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url) as pm: event.wait() with pytest.raises(NewConnectionError): pm.request("GET", "http://example.com", retries=False)
def test_connection_timeouts(self): event = threading.Event() def request_handler(listener): event.wait() self._start_server(request_handler) proxy_url = "socks5h://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url) as pm: with pytest.raises(ConnectTimeoutError): pm.request("GET", "http://example.com", timeout=SHORT_TIMEOUT, retries=False) event.set()
def test_socks_with_invalid_password(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=True, username=b"user", password=b"pass") next(handler) self._start_server(request_handler) proxy_url = "socks5h://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url, username="******", password="******") as pm: with pytest.raises(NewConnectionError) as e: pm.request("GET", "http://example.com", retries=False) assert "SOCKS5 authentication failed" in str(e.value)
def test_proxy_rejection(self): evt = threading.Event() def request_handler(listener): sock = listener.accept()[0] handler = handle_socks4_negotiation(sock) addr, port = next(handler) handler.send(False) evt.wait() sock.close() self._start_server(request_handler) proxy_url = "socks4a://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url) as pm: with pytest.raises(NewConnectionError): pm.request("GET", "http://example.com", retries=False) evt.set()
def test_basic_request(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) assert addr == b"localhost" assert port == 443 handler.send(True) # Wrap in TLS context = better_ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.load_cert_chain(DEFAULT_CERTS["certfile"], DEFAULT_CERTS["keyfile"]) tls = context.wrap_socket(sock, server_side=True) buf = b"" while True: buf += tls.recv(65535) if buf.endswith(b"\r\n\r\n"): break assert buf.startswith(b"GET / HTTP/1.1\r\n") tls.sendall(b"HTTP/1.1 200 OK\r\n" b"Server: SocksTestServer\r\n" b"Content-Length: 0\r\n" b"\r\n") tls.close() sock.close() self._start_server(request_handler) proxy_url = "socks5h://%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url, ca_certs=DEFAULT_CA) as pm: response = pm.request("GET", "https://localhost") assert response.status == 200 assert response.data == b"" assert response.headers["Server"] == "SocksTestServer"
def test_socks_with_auth_in_url(self): """ Test when we have auth info in url, i.e. socks5://user:pass@host:port and no username/password as params """ def request_handler(listener): sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=True, username=b"user", password=b"pass") addr, port = next(handler) assert addr == "16.17.18.19" assert port == 80 handler.send(True) while True: buf = sock.recv(65535) if buf.endswith(b"\r\n\r\n"): break sock.sendall(b"HTTP/1.1 200 OK\r\n" b"Server: SocksTestServer\r\n" b"Content-Length: 0\r\n" b"\r\n") sock.close() self._start_server(request_handler) proxy_url = "socks5://user:pass@%s:%s" % (self.host, self.port) with socks.SOCKSProxyManager(proxy_url) as pm: response = pm.request("GET", "http://16.17.18.19") assert response.status == 200 assert response.data == b"" assert response.headers["Server"] == "SocksTestServer"
def test_invalid_socks_version_is_valueerror(self): with pytest.raises(ValueError) as e: socks.SOCKSProxyManager(proxy_url="http://example.org") assert "Unable to determine SOCKS version" in e.value.args[0]