diff --git a/lib/srv/desktop/rdp/rdpclient/client.go b/lib/srv/desktop/rdp/rdpclient/client.go index 99d0cdb0930bd..4f9c1a4f368eb 100644 --- a/lib/srv/desktop/rdp/rdpclient/client.go +++ b/lib/srv/desktop/rdp/rdpclient/client.go @@ -291,6 +291,12 @@ func (c *Client) startRustRDP(ctx context.Context) error { return trace.Wrap(err) } + // [username] need only be valid for the duration of + // C.client_run. It is copied on the Rust side and + // thus can be freed here. + username := C.CString(c.username) + defer C.free(unsafe.Pointer(username)) + // [addr] need only be valid for the duration of // C.client_run. It is copied on the Rust side and // thus can be freed here. @@ -328,6 +334,7 @@ func (c *Client) startRustRDP(ctx context.Context) error { C.CGOConnectParams{ ad: C.bool(c.cfg.AD), nla: C.bool(c.cfg.NLA), + go_username: username, go_addr: addr, go_computer_name: computerName, go_kdc_addr: kdcAddr, diff --git a/lib/srv/desktop/rdp/rdpclient/src/client.rs b/lib/srv/desktop/rdp/rdpclient/src/client.rs index d4e010c8e1fa9..3dae0fc453b59 100644 --- a/lib/srv/desktop/rdp/rdpclient/src/client.rs +++ b/lib/srv/desktop/rdp/rdpclient/src/client.rs @@ -44,6 +44,7 @@ use ironrdp_pdu::input::fast_path::{ }; use ironrdp_pdu::input::mouse::PointerFlags; use ironrdp_pdu::input::{InputEventError, MousePdu}; +use ironrdp_pdu::nego::NegoRequestData; use ironrdp_pdu::rdp::capability_sets::MajorPlatformType; use ironrdp_pdu::rdp::client_info::PerformanceFlags; use ironrdp_pdu::rdp::RdpError; @@ -1442,8 +1443,11 @@ fn create_config(params: &ConnectParams, pin: String) -> Config { platform: MajorPlatformType::UNSPECIFIED, no_server_pointer: false, autologon: true, - request_data: None, pointer_software_rendering: false, + // Send the username in the request cookie, which is sent in the initial connection request. + // The RDP server ignores this value, but load balancers sitting in front of the server + // can use it to implement persistence. + request_data: Some(NegoRequestData::cookie(params.username.clone())), performance_flags: PerformanceFlags::default() | PerformanceFlags::DISABLE_CURSOR_SHADOW // this is required for pointer to work correctly in Windows 2019 | if !params.show_desktop_wallpaper { @@ -1457,6 +1461,7 @@ fn create_config(params: &ConnectParams, pin: String) -> Config { #[derive(Debug)] pub struct ConnectParams { + pub username: String, pub addr: String, pub kdc_addr: Option, pub computer_name: Option, diff --git a/lib/srv/desktop/rdp/rdpclient/src/lib.rs b/lib/srv/desktop/rdp/rdpclient/src/lib.rs index 2a7bb6b8cd60d..01a7332fff27a 100644 --- a/lib/srv/desktop/rdp/rdpclient/src/lib.rs +++ b/lib/srv/desktop/rdp/rdpclient/src/lib.rs @@ -88,6 +88,7 @@ pub unsafe extern "C" fn free_string(ptr: *mut c_char) { pub unsafe extern "C" fn client_run(cgo_handle: CgoHandle, params: CGOConnectParams) -> CGOResult { trace!("client_run"); // Convert from C to Rust types. + let username = from_c_string(params.go_username); let addr = from_c_string(params.go_addr); let cert_der = from_go_array(params.cert_der, params.cert_der_len); let key_der = from_go_array(params.key_der, params.key_der_len); @@ -107,6 +108,7 @@ pub unsafe extern "C" fn client_run(cgo_handle: CgoHandle, params: CGOConnectPar ConnectParams { ad: params.ad, nla: params.nla, + username, addr, computer_name, cert_der, @@ -476,6 +478,7 @@ pub unsafe extern "C" fn client_write_screen_resize( pub struct CGOConnectParams { ad: bool, nla: bool, + go_username: *const c_char, go_addr: *const c_char, go_domain: *const c_char, go_kdc_addr: *const c_char,