[PR #89] [CLOSED] Fix #67: Force rustls for control WebSocket (avoid macOS SecureTransport -9806) #92

Closed
opened 2026-03-02 23:02:16 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/agrinman/tunnelto/pull/89
Author: @godnight10061
Created: 12/28/2025
Status: Closed

Base: masterHead: fix/issue-67-websocketerror


📝 Commits (1)

  • f046e56 Fix #67: force rustls for control websocket

📊 Changes

49 files changed (+21596 additions, -33 deletions)

View changed files

📝 Cargo.lock (+134 -29)
📝 Cargo.toml (+6 -1)
📝 tunnelto/Cargo.toml (+5 -2)
📝 tunnelto/src/main.rs (+2 -1)
tunnelto/src/ws.rs (+200 -0)
vendor/ntapi/.cargo-ok (+1 -0)
vendor/ntapi/.cargo_vcs_info.json (+6 -0)
vendor/ntapi/Cargo.toml (+40 -0)
vendor/ntapi/Cargo.toml.orig (+31 -0)
vendor/ntapi/LICENSE-APACHE (+202 -0)
vendor/ntapi/LICENSE-MIT (+17 -0)
vendor/ntapi/README.md (+17 -0)
vendor/ntapi/build.rs (+15 -0)
vendor/ntapi/src/lib.rs (+70 -0)
vendor/ntapi/src/macros.rs (+112 -0)
vendor/ntapi/src/ntapi_base.rs (+40 -0)
vendor/ntapi/src/ntdbg.rs (+239 -0)
vendor/ntapi/src/ntexapi.rs (+3013 -0)
vendor/ntapi/src/ntgdi.rs (+123 -0)
vendor/ntapi/src/ntioapi.rs (+1464 -0)

...and 29 more files

📄 Description

Fixes #67.

Problem

  • On macOS, the control WebSocket can fail during TLS with SecureTransport/native-tls (e.g. WebSocketError(Tls(Native(Error { code: -9806, message: "connection closed via error" })))), preventing the tunnel from coming up.

Solution

  • Force Rustls for the control WebSocket connection instead of relying on the default TLS connector selection.
  • Add tunnelto/src/ws.rs with connect_async_force_rustls(...) / connect_async_force_rustls_with_config(...) using Connector::Rustls and a trust store backed by webpki-roots.
  • Update tunnelto/src/main.rs (connect_to_wormhole) to use ws::connect_async_force_rustls(config.control_url.as_str()).

Tests

  • Added deterministic unit tests in tunnelto/src/ws.rs using rcgen + a local TLS WebSocket server to validate:
    • Untrusted cert fails as expected.
    • Supplying a custom root CA succeeds and yields MaybeTlsStream::Rustls.
  • Verified with cargo test --workspace.

Notes

  • Includes a minimal ntapi patch to keep Windows builds working on Rust 1.91+ (E0793 packed-field references) via [patch.crates-io] and vendor/ntapi.

Risk/compat

  • TLS backend change is limited to the control WebSocket path; protocol/wire behavior is unchanged.
  • Uses webpki-roots rather than the OS trust store by default. Environments relying on OS-installed custom roots may need a custom root config (supported by connect_async_force_rustls_with_config(...) for future wiring).

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/agrinman/tunnelto/pull/89 **Author:** [@godnight10061](https://github.com/godnight10061) **Created:** 12/28/2025 **Status:** ❌ Closed **Base:** `master` ← **Head:** `fix/issue-67-websocketerror` --- ### 📝 Commits (1) - [`f046e56`](https://github.com/agrinman/tunnelto/commit/f046e56cec8dfa0841b76d9514c67646a87c247a) Fix #67: force rustls for control websocket ### 📊 Changes **49 files changed** (+21596 additions, -33 deletions) <details> <summary>View changed files</summary> 📝 `Cargo.lock` (+134 -29) 📝 `Cargo.toml` (+6 -1) 📝 `tunnelto/Cargo.toml` (+5 -2) 📝 `tunnelto/src/main.rs` (+2 -1) ➕ `tunnelto/src/ws.rs` (+200 -0) ➕ `vendor/ntapi/.cargo-ok` (+1 -0) ➕ `vendor/ntapi/.cargo_vcs_info.json` (+6 -0) ➕ `vendor/ntapi/Cargo.toml` (+40 -0) ➕ `vendor/ntapi/Cargo.toml.orig` (+31 -0) ➕ `vendor/ntapi/LICENSE-APACHE` (+202 -0) ➕ `vendor/ntapi/LICENSE-MIT` (+17 -0) ➕ `vendor/ntapi/README.md` (+17 -0) ➕ `vendor/ntapi/build.rs` (+15 -0) ➕ `vendor/ntapi/src/lib.rs` (+70 -0) ➕ `vendor/ntapi/src/macros.rs` (+112 -0) ➕ `vendor/ntapi/src/ntapi_base.rs` (+40 -0) ➕ `vendor/ntapi/src/ntdbg.rs` (+239 -0) ➕ `vendor/ntapi/src/ntexapi.rs` (+3013 -0) ➕ `vendor/ntapi/src/ntgdi.rs` (+123 -0) ➕ `vendor/ntapi/src/ntioapi.rs` (+1464 -0) _...and 29 more files_ </details> ### 📄 Description Fixes #67. ## Problem - On macOS, the control WebSocket can fail during TLS with SecureTransport/native-tls (e.g. `WebSocketError(Tls(Native(Error { code: -9806, message: "connection closed via error" })))`), preventing the tunnel from coming up. ## Solution - Force Rustls for the control WebSocket connection instead of relying on the default TLS connector selection. - Add `tunnelto/src/ws.rs` with `connect_async_force_rustls(...)` / `connect_async_force_rustls_with_config(...)` using `Connector::Rustls` and a trust store backed by `webpki-roots`. - Update `tunnelto/src/main.rs` (`connect_to_wormhole`) to use `ws::connect_async_force_rustls(config.control_url.as_str())`. ## Tests - Added deterministic unit tests in `tunnelto/src/ws.rs` using `rcgen` + a local TLS WebSocket server to validate: - Untrusted cert fails as expected. - Supplying a custom root CA succeeds and yields `MaybeTlsStream::Rustls`. - Verified with `cargo test --workspace`. ## Notes - Includes a minimal `ntapi` patch to keep Windows builds working on Rust 1.91+ (E0793 packed-field references) via `[patch.crates-io]` and `vendor/ntapi`. ## Risk/compat - TLS backend change is limited to the control WebSocket path; protocol/wire behavior is unchanged. - Uses `webpki-roots` rather than the OS trust store by default. Environments relying on OS-installed custom roots may need a custom root config (supported by `connect_async_force_rustls_with_config(...)` for future wiring). --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-02 23:02:16 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tunnelto#92
No description provided.