3 Commits

Author SHA1 Message Date
Fredrik Johansson
f425e0bb8e fix: stop leaking TURN secret to browser clients
All checks were successful
Build / Build & release (push) Successful in 13m40s
WASTE_CONFIG.turnSecret was shipped in plaintext config.js and used to
compute coturn HMAC credentials client-side in browser.ts. Anyone reading
the PWA's JS could read the secret and mint unlimited long-lived TURN
credentials, turning the relay into an open proxy.

The anchor now mints short-lived (1h) credentials server-side via a new
GET /turn-credentials endpoint (-turn-secret flag), mirroring what the
daemon already does. The browser fetches credentials instead of holding
the secret. Daemon mode was unaffected (already server-side).

Docs updated to drop turnSecret from config.js examples, document the
new nginx route, and instruct anyone with an old config.js to rotate
the coturn secret since it was previously exposed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 18:48:59 +02:00
Fredrik Johansson
b87f14a361 Bring wire protocol into full YAW/2 spec compliance
Five interop issues fixed against PROTOCOL.md:

- Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex
  string) as specified in §5.1, not net_raw_bytes. Both anchor server
  and client updated to match.

- Chat wire fields renamed to spec names: text/ts (Unix ms int64)
  replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage
  matches §8 exactly; store and TUI updated accordingly.

- Direct messages now use the spec "pm" type (flat {type,mid,text,ts})
  instead of chat+to. Receiver reconstructs a ChatMessage with
  dm:<short-id> room for IPC/storage. §8 compliant.

- File transfer message types changed to spec hyphenated names:
  file-offer, file-accept, file-cancel, file-done with spec field
  names (name/size not filename/size_bytes). §9 compliant.

- DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen
  fires on OnOpen callback or immediately if the channel is already
  open when WireDataChannel is called (answerer race).

Also fixes two bugs found during testing:

- mid was missing from outgoing wire messages, causing all received
  messages to arrive with mid="" and collide on the UNIQUE DB
  constraint. mid is now included on all sent chat/pm messages; a
  random mid is generated for any received message that omits it.

- Test scripts hardened: kill -9 + active lsof polling replaces blind
  sleep for port cleanup; join_network sent before peer_field queries
  (local_peer is now network-scoped and nil until joined).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
Fredrik Johansson
3e058bee9b Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto
Replace the original raw-TCP peer connections and Blowfish/RSA-era design with
the YAW/2 protocol stack:

Transport
- internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc
  DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/
  candidate exchange rather than direct dialling.
- internal/nat: deleted — ICE subsumes everything this package was going to do.

Signaling
- cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies
  Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts
  peer-join/peer-leave events. Never sees plaintext signaling content.
- internal/anchor: new anchor client. Manages PeerConnection lifecycle,
  decides offerer by peer-id comparison, seals/opens signaling payloads with
  nacl/box, implements mesh.Anchor.

Crypto (internal/crypto)
- PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2).
- Sign/Verify: hex signatures throughout.
- Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519
  identity via Montgomery conversion (filippo.io/edwards25519), matching
  libsodium's crypto_sign_ed25519_*_to_curve25519.
- Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open
  for signaling payloads.

Wire types (internal/proto)
- ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8).
- FileChunk removed from PeerMessage — chunks go on a separate binary
  DataChannel labelled "f:<xid>"; FileDone added.
- New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString.
- PeerID.Short() now returns first 16 hex chars grouped in 4s.
- IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added;
  EvtSessionReady added (fires when DataChannel opens and hello is received).

IPC (internal/ipc)
- join_network/leave_network replace connect (direct TCP dial).
- Network joins are context-scoped: leave_network or client disconnect
  cancels the anchor connection cleanly.

README updated to reflect new project layout, getting-started commands,
IPC protocol, and roadmap state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00