feat(server): send the Server Auto-Reconnect Cookie during logon#1405
feat(server): send the Server Auto-Reconnect Cookie during logon#1405clintcan wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds optional support in ironrdp-server for sending a Server Auto-Reconnect Cookie (MS-RDPBCGR 2.2.4.3 ARC_SC_PRIVATE_PACKET) to the client via a Save Session Info PDU immediately after activation, enabling clients (notably mstsc) to perform the automatic reconnection sequence after an ungraceful disconnect.
Changes:
- Add
auto_reconnect_cookieconfiguration (builder + runtime setter) toRdpServer. - Send
SaveSessionInfoPdu(LogonExtended + AUTO_RECONNECT_COOKIE)once per connection after activation, guarded to avoid re-sending on Deactivation–Reactivation. - Wire the new builder option through
RdpServerBuilder::build().
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| crates/ironrdp-server/src/server.rs | Stores an optional cookie and emits the Save Session Info PDU once per connection after activation. |
| crates/ironrdp-server/src/builder.rs | Adds a builder option to provision the cookie and applies it during build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// Most callers should configure this at construction time via the builder's | ||
| /// [`with_auto_reconnect_cookie`](RdpServerBuilder::with_auto_reconnect_cookie); | ||
| /// this setter exists for dynamic post-construction reconfiguration. |
| /// disconnected. `None` (the default) sends nothing. Configure via | ||
| /// [`RdpServerBuilder::with_auto_reconnect_cookie`] or | ||
| /// [`Self::set_auto_reconnect_cookie`]. | ||
| /// | ||
| /// [`RdpServerBuilder::with_auto_reconnect_cookie`]: crate::RdpServerBuilder::with_auto_reconnect_cookie |
Add an optional Server Auto-Reconnect Cookie (MS-RDPBCGR 2.2.4.3 ARC_SC_PRIVATE_PACKET). When set, `RdpServer` sends a Save Session Info PDU carrying it once per connection, right after activation. A client only enters its automatic reconnection sequence (MS-RDPBCGR 1.3.1.5) on an *ungraceful* disconnect if it was handed this cookie during logon; without it a dropped connection simply reports as disconnected (mstsc will not auto-reconnect at all). This lets a server that intentionally drops a connection and expects the client back — e.g. a recovery path — have the reconnect happen automatically instead of requiring a manual reconnect. Configure via `RdpServerBuilder::with_auto_reconnect_cookie` or the runtime `RdpServer::set_auto_reconnect_cookie` setter, mirroring the existing credential_validator pattern. A per-connection guard sends the cookie exactly once (after the first activation), not again on a Deactivation-Reactivation. All the PDU types already exist in ironrdp-pdu (`rdp::session_info`); only the server-side send is new. Additive: the default is `None` (send nothing), so existing servers are unaffected. The returning ARC_CS_PRIVATE_PACKET is intentionally not validated here — documented in the setter.
e8b37d5 to
491acac
Compare
…erBuilder Copilot review: the doc links to RdpServerBuilder::with_auto_reconnect_cookie don't resolve because RdpServerBuilder is a private-module type not re-exported from the crate root. Link the reachable RdpServer::builder and name the builder method in code formatting instead, so the intra-doc links resolve.
|
Addressed the Copilot review in Root cause aside, in case it's of interest: |
What
Adds an optional Server Auto-Reconnect Cookie (MS-RDPBCGR 2.2.4.3
ARC_SC_PRIVATE_PACKET) toironrdp-server. When set,RdpServersends a Save Session Info PDU (LogonExtended+AUTO_RECONNECT_COOKIE) carrying it once per connection, right after activation (Confirm Active processed, encoder built), on the IO channel.Why
A client only enters its automatic reconnection sequence (MS-RDPBCGR 1.3.1.5) on an ungraceful disconnect if it was handed this cookie during logon. Without it, a dropped connection just reports as disconnected — mstsc in particular won't auto-reconnect at all. Today
ironrdp-servernever sends the cookie, so there's no way for a server to opt into that behavior.The concrete use case: a server that intentionally drops a connection and expects the client to come straight back — e.g. a recovery path that cycles the session — currently forces the user to reconnect by hand. With the cookie provisioned, the client re-establishes on its own (re-authenticating via NLA/CredSSP from cached credentials). It's also just standard behavior a real RDP server provides.
API
Mirrors the existing
credential_validatorpattern exactly — a builder method plus a runtime setter:ServerAutoReconnect(already public inironrdp-pdu::rdp::session_info) carries alogon_idand a 16-byterandom_bits(generate from a CSPRNG). A per-connection guard (auto_reconnect_sent, reset inrun_connection_with) sends it exactly once — not again on a Deactivation-Reactivation.Scope / additive
None(send nothing); existing servers are byte-for-byte unaffected.ironrdp-pdu(rdp::session_info::{SaveSessionInfoPdu, LogonInfoExtended, LogonExFlags, ServerAutoReconnect, InfoType, InfoData}) — this is purely wiring the server-side send.encode_share_data_pduhelper.Design point for review — the returning cookie
This PR implements the send side only: it enables the client's automatic reconnection. It does not validate the
ARC_CS_PRIVATE_PACKETthe client sends back on reconnect (MS-RDPBCGR 2.2.4.4). For a server that re-authenticates every connection by other means (NLA/CredSSP) that's sufficient and safe, and it's documented as such on the setter. If you'd prefer the crate to also offer validation of the returning cookie (so it can be an authentication factor — the server would store issued(logon_id, random_bits)and verify the client'sSecurityData/ARC_CSon the next connect), I'm happy to do that as a follow-up, or fold it in here — it's a larger, stateful feature so I kept this PR to the send path. Let me know which you'd prefer.Built +
clippy --features egfx -D warningsclean; tests compile.