Skip to content

fix(ios): allow plaintext ws:// for LAN/Tailscale hosts; prefer password over bootstrap token (#47887)#2350

Open
BingqingLyu wants to merge 1 commit into
mainfrom
fork-pr-65185-fix-47887-ios-lan-connect-tls
Open

fix(ios): allow plaintext ws:// for LAN/Tailscale hosts; prefer password over bootstrap token (#47887)#2350
BingqingLyu wants to merge 1 commit into
mainfrom
fork-pr-65185-fix-47887-ios-lan-connect-tls

Conversation

@BingqingLyu

@BingqingLyu BingqingLyu commented Apr 28, 2026

Copy link
Copy Markdown
Owner

Summary

Four related bugs caused iOS LAN gateway onboarding to fail. This PR addresses two of them in the iOS/shared Swift layer (bugs 1 and 4 from the issue report); bugs 2 and 3 affect the TypeScript gateway side and are tracked separately.

Bug 1: ws:// silently upgraded to wss:// for LAN hosts

GatewayConnectionController.shouldRequireTLS returned true for any host that wasn't loopback, including:

  • RFC-1918 addresses: 192.168.x.x, 10.x.x.x, 172.16-31.x.x
  • Link-local: 169.254.x.x
  • mDNS names: *.local
  • Tailscale: *.ts.net, CG-NAT 100.64.x.x

Gateways on these networks commonly run without TLS (the documented default for LAN), so the forced upgrade caused connection hangs before auth even started.

Fix: Add isLocalNetworkHost() that correctly identifies these address families. shouldRequireTLS now returns false for local-network hosts when useTLS is explicitly false.

Bug 4: bootstrapToken used even when explicit password is present

Mixed auth payloads (both bootstrapToken and password) always chose the bootstrap path. When the bootstrap token was already consumed (single-use), subsequent connection attempts got AUTH_BOOTSTRAP_TOKEN_INVALID while a valid password was available.

Fix: Suppress authBootstrapToken whenever explicitPassword != nil, making password take precedence.

Files changed

  • apps/ios/Sources/Gateway/GatewayConnectionController.swift

    • shouldRequireTLS: exclude local-network hosts
    • isLocalNetworkHost(): new static helper
    • _test_isLocalNetworkHost(): test hook
  • apps/shared/OpenClawKit/Sources/OpenClawKit/GatewayChannel.swift

    • Suppress authBootstrapToken when explicitPassword != nil

Tests

9 new tests in GatewayConnectionSecurityTests:

  • RFC-1918 range detection (10.x, 172.16-31.x, 192.168.x)
  • .local mDNS names
  • Tailscale .ts.net names
  • Public hostnames correctly excluded
  • resolveManualUseTLS behaviour for LAN hosts, public hosts, and explicit useTLS=true

Build verified: xcodebuild BUILD SUCCEEDED for generic/platform=iOS.

Fixes openclaw#47887

…ord over bootstrap token (openclaw#47887)

Four related bugs caused iOS LAN gateway onboarding to fail:

1. ws:// silently upgraded to wss:// for all non-loopback hosts
   GatewayConnectionController.shouldRequireTLS returned true for any
   non-loopback host, including RFC-1918 addresses (192.168.x.x,
   10.x.x.x, 172.16-31.x.x), link-local (169.254.x.x), .local mDNS
   names, and Tailscale .ts.net addresses. Gateways on these networks
   commonly run without TLS, so the forced upgrade broke plain-LAN
   onboarding entirely.

   Fix: add isLocalNetworkHost() that returns true for RFC-1918,
   link-local, CG-NAT/Tailscale (100.64/10), .local, and .ts.net.
   shouldRequireTLS now returns false for these hosts when useTLS=false.

4. bootstrapToken used even when explicit password is present
   Mixed auth payloads (both bootstrapToken and password) were using
   the bootstrap path, causing AUTH_BOOTSTRAP_TOKEN_INVALID errors
   when a stale bootstrap token was already consumed.

   Fix: suppress authBootstrapToken whenever explicitPassword != nil,
   making password take precedence as intended.

Bugs 2 and 3 (double-socket bootstrap consumption, setup-code generator
emitting bootstrap-only payloads) are addressed on the gateway/TypeScript
side in separate commits.

Tests: 9 new tests in GatewayConnectionSecurityTests covering LAN host
detection (RFC-1918, .local, .ts.net, public hosts) and TLS override
behavior.
@BingqingLyu BingqingLyu added the independent-review Non-trivial PR with no function-level conflict with other open PRs label May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

independent-review Non-trivial PR with no function-level conflict with other open PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: iOS LAN gateway connects are forced to wss, and bootstrap-only setup codes fail onboarding

1 participant