@@ -257,58 +257,59 @@ async fn process_cleanpath(
257
257
// and X224 connection request/response to IronRDP client
258
258
// - Without PCB: Gateway handles (1) X224 connection request, (2) X224 connection response,
259
259
// then leaves TLS handshake and CredSSP to IronRDP client
260
- let ( server_stream, x224_rsp) = if let Some ( pcb_string) = cleanpath_pdu. preconnection_blob {
261
- debug ! ( "Sending preconnection blob to server" ) ;
262
- let pcb = ironrdp_pdu:: pcb:: PreconnectionBlob {
263
- version : ironrdp_pdu:: pcb:: PcbVersion :: V2 ,
264
- id : 0 ,
265
- v2_payload : Some ( pcb_string) ,
266
- } ;
267
-
268
- let encoded = ironrdp_core:: encode_vec ( & pcb)
269
- . context ( "failed to encode preconnection blob" )
270
- . map_err ( CleanPathError :: BadRequest ) ?;
271
-
272
- server_stream. write_all ( & encoded) . await ?;
273
-
274
- let server_stream = crate :: tls:: connect ( selected_target. host ( ) . to_owned ( ) , server_stream)
275
- . await
276
- . map_err ( |source| CleanPathError :: TlsHandshake {
277
- source,
278
- target_server : selected_target. to_owned ( ) ,
279
- } ) ?;
280
-
281
- ( server_stream, None )
282
- } else {
283
- // Send X224 connection request
284
- let x224_req = cleanpath_pdu
285
- . x224_connection_pdu
286
- . context ( "request is missing X224 connection PDU" )
287
- . map_err ( CleanPathError :: BadRequest ) ?;
260
+ // Send preconnection blob and/or X224 connection request
261
+ match ( & cleanpath_pdu. preconnection_blob , & cleanpath_pdu. x224_connection_pdu ) {
262
+ ( None , None ) => {
263
+ return Err ( CleanPathError :: BadRequest ( anyhow:: anyhow!(
264
+ "RDCleanPath PDU is missing both preconnection blob and X224 connection PDU"
265
+ ) ) ) ;
266
+ }
267
+ ( Some ( general_pcb) , Some ( _) ) => {
268
+ server_stream. write_all ( general_pcb. as_bytes ( ) ) . await ?;
269
+ }
270
+ ( None , Some ( _) ) => { } // no preconnection blob to send
271
+ // This is considered to be the case where the preconnection blob is used for Hyper-V VMs connection
272
+ ( Some ( pcb) , None ) => {
273
+ debug ! ( "Sending preconnection blob to server" ) ;
274
+ let pcb = ironrdp_pdu:: pcb:: PreconnectionBlob {
275
+ version : ironrdp_pdu:: pcb:: PcbVersion :: V2 ,
276
+ id : 0 ,
277
+ v2_payload : Some ( pcb. clone ( ) ) ,
278
+ } ;
279
+
280
+ let encoded = ironrdp_core:: encode_vec ( & pcb)
281
+ . context ( "failed to encode preconnection blob" )
282
+ . map_err ( CleanPathError :: BadRequest ) ?;
283
+
284
+ server_stream. write_all ( & encoded) . await ?;
285
+ }
286
+ }
288
287
289
- server_stream. write_all ( x224_req. as_bytes ( ) ) . await ?;
288
+ // Send X224 connection request if present
289
+ let x224_rsp = if let Some ( x224_connection_pdu) = & cleanpath_pdu. x224_connection_pdu {
290
+ server_stream. write_all ( x224_connection_pdu. as_bytes ( ) ) . await ?;
291
+ debug ! ( "X224 connection request sent" ) ;
290
292
291
293
let x224_rsp = read_x224_response ( & mut server_stream)
292
294
. await
293
295
. with_context ( || format ! ( "read X224 response from {selected_target}" ) )
294
296
. map_err ( CleanPathError :: BadRequest ) ?;
295
297
trace ! ( "Receiving X224 response" ) ;
296
298
297
- let server_stream = crate :: tls:: connect ( selected_target. host ( ) . to_owned ( ) , server_stream)
298
- . await
299
- . map_err ( |source| CleanPathError :: TlsHandshake {
300
- source,
301
- target_server : selected_target. to_owned ( ) ,
302
- } ) ?;
303
- debug ! ( "X224 connection request sent" ) ;
304
-
305
- // Receive server X224 connection response
306
-
307
- trace ! ( "Establishing TLS connection with server" ) ;
308
-
309
- ( server_stream, Some ( x224_rsp) )
299
+ Some ( x224_rsp)
300
+ } else {
301
+ None
310
302
} ;
311
303
304
+ // Establish TLS connection
305
+ trace ! ( "Establishing TLS connection with server" ) ;
306
+ let server_stream = crate :: tls:: connect ( selected_target. host ( ) . to_owned ( ) , server_stream)
307
+ . await
308
+ . map_err ( |source| CleanPathError :: TlsHandshake {
309
+ source,
310
+ target_server : selected_target. to_owned ( ) ,
311
+ } ) ?;
312
+
312
313
return Ok ( CleanPathResult {
313
314
destination : selected_target. to_owned ( ) ,
314
315
claims,
@@ -379,8 +380,12 @@ pub async fn handle(
379
380
380
381
trace ! ( "Sending RDCleanPath response" ) ;
381
382
382
- let rdcleanpath_rsp = RDCleanPathPdu :: new_response ( server_addr. to_string ( ) , x224_rsp, x509_chain)
383
- . map_err ( |e| anyhow:: anyhow!( "couldn’t build RDCleanPath response: {e}" ) ) ?;
383
+ let rdcleanpath_rsp = RDCleanPathPdu :: new_response (
384
+ server_addr. to_string ( ) ,
385
+ x224_rsp,
386
+ x509_chain,
387
+ )
388
+ . map_err ( |e| anyhow:: anyhow!( "couldn’t build RDCleanPath response: {e}" ) ) ?;
384
389
385
390
send_clean_path_response ( & mut client_stream, & rdcleanpath_rsp) . await ?;
386
391
0 commit comments