fix(remote): connect --e2ee actually bypasses the plaintext-address check - #1019
fix(remote): connect --e2ee actually bypasses the plaintext-address check#1019knaoe wants to merge 1 commit into
Conversation
…heck
cmd_connect validated the endpoint unconditionally before --e2ee was
ever consulted, so the refusal text's own claim ("connect with --e2ee
so the contents are sealed before they leave this machine") did not
hold. Skip the check when e2ee is requested, matching the documented
and advertised behavior.
Adds a control test (same address, no --e2ee, still refused) and the
positive case (with --e2ee, gets past the refusal and fails at the
network instead) to tests/test_remote.bats.
|
Found a second gate while actually driving this end to end against a real Tailscale address, so flagging before this looks more finished than it is.
So this PR as it stands fixes the I didn't attempt a fix for this one here, for the reason I gave in the PR description: Happy to take a pass at whichever shape you'd prefer, or to leave this PR scoped to just the |
|
Thanks — the On the second gate you flagged: we traced it and agree, with one addition. Since you offered: yes, please extend the fix to |
Fixes #1018.
What
cmd_connectinscripts/remote.shcalled_remote_validate_endpointunconditionally, before$e2eewas ever consulted. So the refusal text's own claim — "connect with--e2eeso the contents are sealed before they leave this machine" — didn't hold:--e2eenever actually bypassed the plaintext-address check.Fix
Skip the check when
--e2eeis set:cmd_pullandcmd_set_endpointcall the same validator unconditionally too, but that's correct as-is — neither takes an--e2eeflag, since encryption is a per-team property fixed atconnecttime.cmd_connectis the only place that parses--e2eeand then didn't act on it for this decision.I deliberately left
connectedBinding()(scripts/internal/remote-sync.mjs:579, the per-sync re-check for an already-connected binding) as-is. It has noe2eeparameter, and I wasn't confident rewiring it to accept one — and getting that wiring wrong — was worth doing without a maintainer's steer, given a connected team's binding is exactly the state a bug there could put in a broken loop. Flagged in the issue; happy to take a pass at it here if that's the right call.Tests
Added two cases to
tests/test_remote.bats, right after the existing loopback-acceptance test:--e2ee, an address outside the allowlist (http://0.0.0.0:1) is still refused with the existing message--e2ee, the same address gets past that refusal and fails at the network instead (asserted via the absence of the refusal text plus the presence ofremote.sh's ownconnect failedwrapper, not a specific curl/errno string, since the exact transport error for an unreachable address is not something I wanted to pin across platforms)0.0.0.0:1was picked over a real unreachable public address so the case stays fast and hermetic (no network dependency, no timeout to wait out) — nothing listens on port 1 there, and it resolves like loopback for an outbound connection on both Linux and macOS, while still being outside the validator's private-range allowlist.Ran locally (
bats tests/test_remote.bats tests/test_endpoint_scheme.bats tests/test_endpoint_table_node.bats): all passing, including the two new cases and the full existing suite in those files.Environment
Found this while connecting two of my own machines over Tailscale — its CGNAT range (100.64.0.0/10) isn't in the hardcoded private-range list, so a Tailscale-only pair (no shared LAN) had no working plaintext path, and
--e2ee, the documented way out, didn't do anything.