@@ -98,6 +98,7 @@ enum COMPLETION_TYPE
98
98
99
99
/* globals */
100
100
extern int g_rdpdr_chan_id ; /* in chansrv.c */
101
+ int g_need_user_loggedon_pdu = 0 ;
101
102
int g_is_printer_redir_supported = 0 ;
102
103
int g_is_port_redir_supported = 0 ;
103
104
int g_is_drive_redir_supported = 0 ;
@@ -370,26 +371,38 @@ devredir_data_in(struct stream *s, int chan_id, int chan_flags, int length,
370
371
case RDP_CLIENT_60_61 :
371
372
break ;
372
373
}
373
- // LK_TODO devredir_send_server_clientID_confirm();
374
374
}
375
375
break ;
376
376
377
377
case PAKID_CORE_CLIENT_NAME :
378
378
/* client is telling us its computer name; do we even care? */
379
379
380
- /* let client know login was successful */
381
- devredir_send_server_user_logged_on ();
382
- usleep ( 1000 * 100 );
383
-
384
- /* let client know our capabilities */
385
- devredir_send_server_core_cap_req ();
380
+ /* See 3.3.5.1.6 for sequencing rules */
381
+ if ( g_client_rdp_version >= RDP_CLIENT_51 )
382
+ {
383
+ /* let client know our capabilities */
384
+ devredir_send_server_core_cap_req ();
385
+ }
386
386
387
387
/* send confirm clientID */
388
388
devredir_send_server_clientID_confirm ();
389
389
break ;
390
390
391
391
case PAKID_CORE_CLIENT_CAPABILITY :
392
392
rv = devredir_proc_client_core_cap_resp (ls );
393
+ if (rv == 0 )
394
+ {
395
+ if (g_need_user_loggedon_pdu )
396
+ {
397
+ /* Tell client to announce remaining devices */
398
+ devredir_send_server_user_logged_on ();
399
+ }
400
+ else if (g_client_rdp_version >= RDP_CLIENT_51 )
401
+ {
402
+ /* See 3.3.5.1.7 */
403
+ devredir_send_server_clientID_confirm ();
404
+ }
405
+ }
393
406
break ;
394
407
395
408
case PAKID_CORE_DEVICELIST_ANNOUNCE :
@@ -734,6 +747,51 @@ devredir_send_drive_dir_request(IRP *irp, tui32 device_id,
734
747
** process data received from client **
735
748
******************************************************************************/
736
749
750
+ /**
751
+ * Process a GENERAL_CAPS_SET packet from the client
752
+ * @param s Stream. CAPABILITY_HEADER is already read
753
+ * @param cap_len Amount of data left in stream for the packet
754
+ * @return 0 for success, -1 otherwise
755
+ *
756
+ * Globals are modified by this call.
757
+ * After this call, the capability is skipped in the stream
758
+ */
759
+ static int
760
+ process_client_general_caps_set (struct stream * s , unsigned int cap_len )
761
+ {
762
+ int rv = -1 ;
763
+ char * exit_p = s -> p + cap_len ;
764
+
765
+ // Data we don't check at the start of the packet
766
+ #define PACKET_SKIP_LENGTH ( \
767
+ 4 + /* osType */ \
768
+ 4 + /* osVersion */ \
769
+ 2 + /* protocolMajorVersion */ \
770
+ 2 + /* protocolMinorVersion */ \
771
+ 4 + /* ioCode1 */ \
772
+ 4 ) /* ioCode2 */
773
+
774
+ if (cap_len < (PACKET_SKIP_LENGTH + 4 ))
775
+ {
776
+ LOG (LOG_LEVEL_ERROR ,
777
+ "[MS-RDPEFS] GENERAL_CAPS_SET: Short packet (%u bytes) encountered" ,
778
+ cap_len );
779
+ }
780
+ else
781
+ {
782
+ tui32 extended_pdu ;
783
+ xstream_seek (s , PACKET_SKIP_LENGTH );
784
+ xstream_rd_u32_le (s , extended_pdu );
785
+
786
+ g_need_user_loggedon_pdu = (extended_pdu & RDPDR_USER_LOGGEDON_PDU );
787
+ rv = 0 ;
788
+ }
789
+
790
+ s -> p = exit_p ;
791
+ return rv ;
792
+ #undef PACKET_SKIP_LENGTH
793
+ }
794
+
737
795
/**
738
796
* @brief process client's response to our core_capability_req() msg
739
797
*
@@ -780,20 +838,27 @@ devredir_proc_client_core_cap_resp(struct stream *s)
780
838
{
781
839
case CAP_GENERAL_TYPE :
782
840
LOG_DEVEL (LOG_LEVEL_DEBUG , "got CAP_GENERAL_TYPE" );
841
+ if (process_client_general_caps_set (s , cap_len ) < 0 )
842
+ {
843
+ return -1 ;
844
+ }
783
845
break ;
784
846
785
847
case CAP_PRINTER_TYPE :
786
848
LOG_DEVEL (LOG_LEVEL_DEBUG , "got CAP_PRINTER_TYPE" );
849
+ xstream_seek (s , cap_len );
787
850
g_is_printer_redir_supported = 1 ;
788
851
break ;
789
852
790
853
case CAP_PORT_TYPE :
791
854
LOG_DEVEL (LOG_LEVEL_DEBUG , "got CAP_PORT_TYPE" );
855
+ xstream_seek (s , cap_len );
792
856
g_is_port_redir_supported = 1 ;
793
857
break ;
794
858
795
859
case CAP_DRIVE_TYPE :
796
860
LOG_DEVEL (LOG_LEVEL_DEBUG , "got CAP_DRIVE_TYPE" );
861
+ xstream_seek (s , cap_len );
797
862
g_is_drive_redir_supported = 1 ;
798
863
if (cap_version == 2 )
799
864
{
@@ -803,10 +868,10 @@ devredir_proc_client_core_cap_resp(struct stream *s)
803
868
804
869
case CAP_SMARTCARD_TYPE :
805
870
LOG_DEVEL (LOG_LEVEL_DEBUG , "got CAP_SMARTCARD_TYPE" );
871
+ xstream_seek (s , cap_len );
806
872
g_is_smartcard_redir_supported = (scard_init () == 0 );
807
873
break ;
808
874
}
809
- xstream_seek (s , cap_len );
810
875
}
811
876
return 0 ;
812
877
}
0 commit comments