Commit Graph

7 Commits

Author SHA1 Message Date
Vantz Stockwell
1bf225ae27 fix(rdp): send client capability instructions before CONNECT handshake
ROOT CAUSE: guacd showed "User resolution is 0x0 at 0 DPI" and
immediately killed every RDP connection.

The Guacamole protocol requires five client capability instructions
(size, audio, video, image, timezone) BETWEEN receiving 'args' and
sending 'connect'. Our handshake skipped all five and jumped straight
to CONNECT. guacd never received the display dimensions, defaulted to
0x0, and terminated the connection.

Now sends the complete handshake:
  select → (receive args) → size → audio → video → image → timezone → connect

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 06:32:36 -04:00
Vantz Stockwell
34bea52e0b fix(rdp): TCP stream buffering + error surfacing for guacd pipeline
Three bugs fixed:

1. TCP stream fragmentation — guacd→browser data pipe treated each TCP
   chunk as a complete instruction. TCP is a stream protocol; instructions
   WILL be split across chunks (especially display/image data). Added
   instruction buffer that accumulates data and only forwards complete
   instructions (terminated by ';').

2. Missing client.onerror — when guacd fails the RDP connection (NLA,
   auth, TLS), it sends a Guacamole error instruction. No handler was
   registered, so errors were silently swallowed. User saw blank canvas
   with no feedback. Now surfaces errors via console and gateway callback.

3. Missing client.onstatechange — no connection state tracking. Added
   state transition logging for diagnostics.

Also improved CONNECT handshake logging to surface connection parameters
(host, port, user, domain, security mode) without exposing passwords.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 06:17:32 -04:00
Vantz Stockwell
c062cd502d debug(rdp): enable guacd debug logging + log all guacd responses
guacd was dying silently with no error instruction sent back.
Enable -L debug -f for verbose FreeRDP diagnostics and log
first 5 guacd→browser instructions plus connection parameters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 05:53:13 -04:00
Vantz Stockwell
80463235b0 fix(rdp): VERSION echo + guacd host networking for overlay reach
- Echo VERSION_X_Y_Z args back to guacd in CONNECT handshake
- Set guacd to network_mode: host so it can reach RDP targets on
  NetBird/Tailscale overlay networks (100.64.x.x)
- App container uses host.docker.internal to reach guacd on host
- Add diagnostic logging for guacd→browser instruction relay

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 05:23:02 -04:00
Vantz Stockwell
9d3a93bea9 fix(rdp): parse guacd args response and send matching positional connect values 2026-03-14 05:05:00 -04:00
Vantz Stockwell
f124d4b7d2 fix(rdp): convert to manual ws.Server, fix URL path, fix double session 2026-03-14 02:40:37 -04:00
Vantz Stockwell
5d75869bb4 feat: RDP backend — Guacamole TCP tunnel to guacd over WebSocket
- guacamole.service.ts: raw TCP client to guacd on GUACD_HOST:GUACD_PORT.
  Performs SELECT rdp → CONNECT handshake with full RDP parameter set.
  Provides encode/decode helpers for length-prefixed Guacamole wire format.
- rdp.gateway.ts: WebSocket gateway at /ws/rdp. JWT auth via WsAuthGuard.
  Handles connect (host lookup, credential decrypt, guacd tunnel open) and
  guac (bidirectional instruction forwarding). Updates lastConnectedAt and
  creates ConnectionLog on connect (same pattern as SSH gateway).
- rdp.module.ts: imports VaultModule, ConnectionsModule, AuthModule.
- app.module.ts: registers RdpModule.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:27:09 -04:00