7cb2a8b618
Testing / remote-protocol-compat (0.9.5) (push) Successful in 1m4s
Testing / test (push) Successful in 1m22s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 1m7s
Package Extension / package-extension (push) Successful in 1m1s
Build & Publish Package / publish (push) Successful in 1m5s
- Split auth into focused package modules for agent keys, file keys, signing, and post-quantum transport helpers while keeping the public browser_cli.auth import surface intact. - Move transport encoding internals into a package with separate codec and binary-hoisting helpers, preserving browser_cli.transport compatibility. - Extract remote TCP auth/socket helpers and serve challenge setup out of the runtime paths to make connection handling easier to reason about. - Move the extension markdown extractor into a dedicated content/markdown folder with separate root selection, code normalization, renderer, and utils. - Centralize CLI Rich rendering helpers for tab/window tree and table output, and add rendering tests for the shared builders. - Remove local typing ignores in SDK/decorator/script plumbing and bump the package and extension version to 0.15.3.
60 lines
2.5 KiB
Python
60 lines
2.5 KiB
Python
"""TCP/TLS transport for talking to a remote ``browser-cli serve``.
|
|
|
|
This module keeps the public/private compatibility surface used by older tests
|
|
and callers, while delegating socket mechanics and auth-handshake details to
|
|
focused helper modules.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
from browser_cli.framing import async_send_frame, frame
|
|
from browser_cli.remote.auth import (
|
|
build_auth_message as _build_auth_message,
|
|
build_auth_message_async as _build_auth_message_async,
|
|
decode_pq_response as _decode_pq_response,
|
|
parse_challenge as _parse_challenge,
|
|
should_warn_no_pq as _should_warn_no_pq,
|
|
with_challenge as _with_challenge,
|
|
)
|
|
from browser_cli.remote.socket import (
|
|
async_recv_all as _async_recv_all,
|
|
async_recv_exact_bytes as _async_recv_exact,
|
|
open_async_connection as _open_async_connection,
|
|
open_socket as _open_socket,
|
|
recv_all as _recv_all,
|
|
recv_exact_bytes as _recv_exact,
|
|
split_endpoint as _split_endpoint,
|
|
)
|
|
|
|
def _send_remote(endpoint: str, msg: dict, private_key=None, *, warn_no_pq: bool | None = None) -> bytes | None:
|
|
warn = _should_warn_no_pq(msg) if warn_no_pq is None else warn_no_pq
|
|
|
|
def build_auth(sync_msg: dict, challenge: dict | None, nonce_hex: str | None, key):
|
|
from browser_cli.auth import pq_kex_client_encapsulate
|
|
return _build_auth_message(sync_msg, challenge, nonce_hex, key, pq_kex_client_encapsulate, warn_no_pq=warn)
|
|
|
|
with _open_socket(endpoint) as sock:
|
|
payload_msg, pq_shared_secret = _with_challenge(_recv_all(sock), msg, private_key, build_auth)
|
|
sock.sendall(frame(json.dumps(payload_msg).encode("utf-8")))
|
|
return _decode_pq_response(_recv_all(sock), pq_shared_secret)
|
|
|
|
async def _send_remote_async(endpoint: str, msg: dict, private_key=None, *, warn_no_pq: bool | None = None) -> bytes | None:
|
|
reader, writer = await _open_async_connection(endpoint)
|
|
try:
|
|
challenge_raw = await _async_recv_all(reader)
|
|
warn = _should_warn_no_pq(msg) if warn_no_pq is None else warn_no_pq
|
|
|
|
async def build_auth(sync_msg: dict, challenge: dict | None, nonce_hex: str | None, key):
|
|
return await _build_auth_message_async(sync_msg, challenge, nonce_hex, key, warn_no_pq=warn)
|
|
|
|
payload_msg, pq_shared_secret = await _with_challenge(challenge_raw, msg, private_key, build_auth)
|
|
await async_send_frame(writer, json.dumps(payload_msg).encode("utf-8"))
|
|
return _decode_pq_response(await _async_recv_all(reader), pq_shared_secret)
|
|
finally:
|
|
writer.close()
|
|
try:
|
|
await writer.wait_closed()
|
|
except Exception:
|
|
pass
|