def test_local_dns(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks4_negotiation(sock) addr, port = next(handler) self.assertEqual(addr, "127.0.0.1") self.assertEqual(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) pm = socks.SOCKSProxyManager(proxy_url) self.addCleanup(pm.clear) response = pm.request("GET", "http://localhost") self.assertEqual(response.status, 200) self.assertEqual(response.headers["Server"], "SocksTestServer") self.assertEqual(response.data, b"")
def test_local_dns(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) self.assertIn(addr, ['127.0.0.1', '::1']) self.assertTrue(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) pm = socks.SOCKSProxyManager(proxy_url) self.addCleanup(pm.clear) response = pm.request('GET', 'http://localhost') self.assertEqual(response.status, 200) self.assertEqual(response.data, b'') self.assertEqual(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] self.assertEqual(sock.getpeername()[0], '127.0.0.1') self.assertEqual(sock.getpeername()[1], expected_port) handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) self.assertEqual(addr, '16.17.18.19') self.assertTrue(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) pm = socks.SOCKSProxyManager(proxy_url, source_address=('127.0.0.1', expected_port)) self.addCleanup(pm.clear) response = pm.request('GET', 'http://16.17.18.19') self.assertEqual(response.status, 200)
def test_correct_header_line(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) self.assertEqual(addr, b"example.com") self.assertEqual(port, 80) handler.send(True) buf = b"" while True: buf += sock.recv(65535) if buf.endswith(b"\r\n\r\n"): break self.assertTrue(buf.startswith(b"GET / HTTP/1.1")) self.assertIn(b"Host: example.com", 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 = "socks5h://%s:%s" % (self.host, self.port) pm = socks.SOCKSProxyManager(proxy_url) self.addCleanup(pm.clear) response = pm.request("GET", "http://example.com") self.assertEqual(response.status, 200)
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) self.assertEqual(addr, '16.17.18.19') self.assertTrue(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) pm = socks.SOCKSProxyManager(proxy_url, username='******') self.addCleanup(pm.clear) response = pm.request('GET', 'http://16.17.18.19') self.assertEqual(response.status, 200) self.assertEqual(response.data, b'') self.assertEqual(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) self.assertEqual(addr, b'example.com') self.assertTrue(port, 80) handler.send(True) buf = b'' while True: buf += sock.recv(65535) if buf.endswith(b'\r\n\r\n'): break self.assertTrue(buf.startswith(b'GET / HTTP/1.1')) self.assertTrue(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) pm = socks.SOCKSProxyManager(proxy_url) self.addCleanup(pm.clear) response = pm.request('GET', 'http://example.com') self.assertEqual(response.status, 200)
def test_basic_request(self): def request_handler(listener): sock = listener.accept()[0] handler = handle_socks4_negotiation(sock) 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) pm = socks.SOCKSProxyManager(proxy_url) self.addCleanup(pm.clear) response = pm.request("GET", "http://16.17.18.19") assert response.status == 200 assert response.headers["Server"] == "SocksTestServer" assert response.data == b""
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 = f"socks5://{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 = f"socks5://{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_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 = f"socks4a://{self.host}:{self.port}" with socks.SOCKSProxyManager(proxy_url) as pm: response = pm.request("GET", "http://example.com") assert response.status == 200
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 = f"socks4://{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_basic_request(self) -> None: def request_handler(listener: socket.socket) -> None: sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) assert addr == "16.17.18.19" assert port == 80 with pytest.raises(StopIteration): 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 = f"socks5://{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_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=0.001, retries=False) event.set()
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 = f"socks4a://{self.host}:{self.port}" with socks.SOCKSProxyManager(proxy_url, username="******") as pm: with pytest.raises(NewConnectionError, match="different user-ids"): pm.request("GET", "http://example.com", retries=False)
def test_connection_failure(self): event = threading.Event() def request_handler(listener): listener.close() event.set() self._start_server(request_handler) proxy_url = f"socks5h://{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_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) pm = socks.SOCKSProxyManager(proxy_url) self.addCleanup(pm.clear) event.wait() with pytest.raises(NewConnectionError): pm.request("GET", "http://example.com", retries=False)
def test_connection_timeouts(self) -> None: event = threading.Event() def request_handler(listener: socket.socket) -> None: event.wait() self._start_server(request_handler) proxy_url = f"socks5h://{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_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: try: pm.request("GET", "http://example.com", retries=False) except NewConnectionError as e: assert "different user-ids" in str(e) else: self.fail("Did not raise")
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) pm = socks.SOCKSProxyManager(proxy_url) self.addCleanup(pm.clear) self.assertRaises( ConnectTimeoutError, pm.request, 'GET', 'http://example.com', timeout=0.001, retries=False ) event.set()
def test_connection_failure(self): event = threading.Event() def request_handler(listener): listener.close() event.set() self._start_server(request_handler) proxy_url = "socks5://%s:%s" % (self.host, self.port) pm = socks.SOCKSProxyManager(proxy_url) event.wait() self.assertRaises(NewConnectionError, pm.request, 'GET', 'http://example.com', retries=False)
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 = "socks4://%s:%s" % (self.host, self.port) pm = socks.SOCKSProxyManager(proxy_url, username='******') try: pm.request('GET', 'http://example.com', retries=False) except NewConnectionError as e: self.assertTrue("different user-ids" in str(e)) else: self.fail("Did not raise")
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_basic_request(self): if not HAS_SSL: raise SkipTest("No TLS available") def request_handler(listener): sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) self.assertEqual(addr, b'localhost') self.assertTrue(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 self.assertTrue(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) pm = socks.SOCKSProxyManager(proxy_url) self.addCleanup(pm.clear) response = pm.request('GET', 'https://localhost') self.assertEqual(response.status, 200) self.assertEqual(response.data, b'') self.assertEqual(response.headers['Server'], 'SocksTestServer')
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) -> None: def request_handler(listener: socket.socket) -> None: sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) assert addr == b"localhost" assert port == 443 with pytest.raises(StopIteration): handler.send(True) # Wrap in TLS context = better_ssl.SSLContext( ssl.PROTOCOL_SSLv23) # type: ignore[misc] 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 = f"socks5h://{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_invalid_password(self, monkeypatch): _set_up_fake_getaddrinfo(monkeypatch) 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 = f"socks5h://{self.host}:{self.port}" with socks.SOCKSProxyManager(proxy_url, username="******", password="******") as pm: with pytest.raises(NewConnectionError, match="SOCKS5 authentication failed"): pm.request("GET", "http://example.com", retries=False)
def test_proxy_rejection(self, monkeypatch): _set_up_fake_getaddrinfo(monkeypatch) evt = threading.Event() def request_handler(listener): sock = listener.accept()[0] handler = handle_socks5_negotiation(sock, negotiate=False) addr, port = next(handler) handler.send(False) evt.wait() sock.close() self._start_server(request_handler) proxy_url = f"socks5h://{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) self.assertEqual(addr, b"localhost") self.assertEqual(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 self.assertTrue(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) pm = socks.SOCKSProxyManager(proxy_url, ca_certs=DEFAULT_CA) self.addCleanup(pm.clear) response = pm.request("GET", "https://localhost") self.assertEqual(response.status, 200) self.assertEqual(response.data, b"") self.assertEqual(response.headers["Server"], "SocksTestServer")
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) pm = socks.SOCKSProxyManager(proxy_url, username='******', password='******') self.addCleanup(pm.clear) try: pm.request('GET', 'http://example.com', retries=False) except NewConnectionError as e: self.assertIn("SOCKS5 authentication failed", str(e)) else: self.fail("Did not raise")
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"