You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When an agent advertises the KDC's subnet or DNS domain, route Kerberos
traffic through the QUIC tunnel just like every other proxy path. Closes
the last gap left after the transparent routing PR (#1741).
Two paths now use the same routing pipeline as connection forwarding:
- `/jet/KdcProxy` HTTP endpoint -- the handler builds a `KdcConnector`
and forwards through it. When an agent advertises the KDC subnet, the
request goes through the agent tunnel; otherwise it falls back to a
direct TCP/UDP connection.
- RDP CredSSP/NLA -- `rdp_proxy.rs::send_network_request` previously
hard-coded `None` for the agent handle. `RdpProxy` now carries a
`KdcConnector` field that the CredSSP machinery
(`perform_credssp_as_*` -> `resolve_*_generator` -> `send_network_request`)
uses for every Kerberos sub-request. The same change reaches the
credential-injection clean path (`rd_clean_path.rs`).
`KdcConnector` (new `src/kdc_connector.rs`) bundles the three inputs the
routing pipeline needs (`session_id`, `explicit_agent_id`,
`agent_tunnel_handle`) into a single value and always defers the
routing decision to `agent_tunnel::routing::try_route`. Callers never
pre-decide "direct" vs "via tunnel": the routing pipeline does, and
its existing `explicit_agent_id` enforcement (pin without tunnel handle
must error, never silently fall back to direct) is preserved end-to-end.
Session correlation:
- RDP CredSSP callers pass the parent association's `claims.jet_aid`
as `session_id`, so KDC sub-traffic ties back to its parent RDP
session in agent-side logs.
- The HTTP `/jet/KdcProxy` handler passes the KDC token's own `jti`,
the most persistent identifier available without a parent
association. `KdcTokenClaims` now exposes `jti` through its serde
helper, matching how every other `*TokenClaims` type surfaces `jti`.
Explicit-agent routing (matches every other proxy path):
- The parent association's `jet_agent_id`, when set, is forwarded to
`try_route`. KDC traffic must route via that agent or fail -- never
silently fall back to a different agent or to direct connect. The
HTTP handler passes `None` (no parent association).
- A new UDP-via-agent guard rejects `udp://` KDC targets whenever the
routing pipeline selects an agent. Without it, an explicit
`jet_agent_id` pin could be downgraded to direct UDP, since the
agent tunnel currently carries only TCP.
Hardening (came along since they share the file):
- 64 KiB `MAX_KDC_REPLY_MESSAGE_LEN` DoS cap on the announced TCP-framed
KDC reply length, with overflow-safe length math.
- UDP scheme guard at the direct-connect branch (preserved).
Tests:
- `kdc_connector` unit tests pin the routing-decision contract:
pin-without-tunnel must error, no-pin-no-tunnel directs, pin-with-
missing-agent errors, no-match falls back to direct. The success
path and the UDP-via-agent guard both require a live `connect_via_agent`
fixture and are tracked as follow-up TODOs in the same file.
- A `pub(hidden) AgentTunnelHandle::for_testing(registry, ca_manager)`
constructor was added to the `agent-tunnel` crate so the gateway
crate's tests can build a handle without standing up a real QUIC
endpoint.
Issue: DGW-384
0 commit comments