53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
"""rustdesk-server — real websocket handshakes against hbbs/hbbr's ws listeners.
|
|
|
|
21118 (hbbs) and 21119 (hbbr) are the servers' websocket endpoints — the surface a real
|
|
RustDesk web client uses. A completed `101 Switching Protocols` upgrade is the app's own
|
|
protocol answering (verified live against 1.1.12 and 1.1.16 during enrollment); a bare GET
|
|
without upgrade headers gets NO response, so this can only pass against a genuinely serving
|
|
listener, never a proxy or placeholder.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import socket
|
|
import time
|
|
|
|
WS_PORTS = {21118: "hbbs", 21119: "hbbr"}
|
|
|
|
_REQ = (
|
|
b"GET / HTTP/1.1\r\n"
|
|
b"Host: rustdesk\r\n"
|
|
b"Upgrade: websocket\r\n"
|
|
b"Connection: Upgrade\r\n"
|
|
b"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
b"Sec-WebSocket-Version: 13\r\n"
|
|
b"\r\n"
|
|
)
|
|
|
|
|
|
def _handshake(port: int, timeout: float = 5.0) -> bytes:
|
|
with socket.create_connection(("127.0.0.1", port), timeout=timeout) as s:
|
|
s.sendall(_REQ)
|
|
s.settimeout(timeout)
|
|
return s.recv(200)
|
|
|
|
|
|
def test_websocket_upgrades(meta):
|
|
"""Both ws endpoints complete an HTTP->websocket upgrade with 101 (poll per §5)."""
|
|
deadline = time.time() + meta.HTTP_TIMEOUT
|
|
pending = dict(WS_PORTS)
|
|
while pending and time.time() < deadline:
|
|
for port in list(pending):
|
|
try:
|
|
data = _handshake(port)
|
|
except OSError:
|
|
data = b""
|
|
if data.startswith(b"HTTP/1.1 101"):
|
|
del pending[port]
|
|
if pending:
|
|
time.sleep(3)
|
|
assert not pending, (
|
|
f"websocket endpoints did not complete 101 upgrades: {pending} "
|
|
f"(waited {meta.HTTP_TIMEOUT}s)"
|
|
)
|