Skip to content

Commit 05a3361

Browse files
committed
Fix message ordering in devredir
1 parent ee32878 commit 05a3361

File tree

2 files changed

+78
-8
lines changed

2 files changed

+78
-8
lines changed

common/ms-rdpefs.h

+5
Original file line numberDiff line numberDiff line change
@@ -119,5 +119,10 @@ enum IRP_MN
119119
IRP_MN_NOTIFY_CHANGE_DIRECTORY = 0x00000002
120120
};
121121

122+
/*
123+
* General Capability Set (2.2.2.7.1)
124+
*/
125+
/* extendedPDU fields */
126+
#define RDPDR_USER_LOGGEDON_PDU 0x00000004
122127

123128
#endif /* MS_RDPEFS_H */

sesman/chansrv/devredir.c

+73-8
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ enum COMPLETION_TYPE
9898

9999
/* globals */
100100
extern int g_rdpdr_chan_id; /* in chansrv.c */
101+
int g_need_user_loggedon_pdu = 0;
101102
int g_is_printer_redir_supported = 0;
102103
int g_is_port_redir_supported = 0;
103104
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,
370371
case RDP_CLIENT_60_61:
371372
break;
372373
}
373-
// LK_TODO devredir_send_server_clientID_confirm();
374374
}
375375
break;
376376

377377
case PAKID_CORE_CLIENT_NAME:
378378
/* client is telling us its computer name; do we even care? */
379379

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+
}
386386

387387
/* send confirm clientID */
388388
devredir_send_server_clientID_confirm();
389389
break;
390390

391391
case PAKID_CORE_CLIENT_CAPABILITY:
392392
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+
}
393406
break;
394407

395408
case PAKID_CORE_DEVICELIST_ANNOUNCE:
@@ -734,6 +747,51 @@ devredir_send_drive_dir_request(IRP *irp, tui32 device_id,
734747
** process data received from client **
735748
******************************************************************************/
736749

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+
737795
/**
738796
* @brief process client's response to our core_capability_req() msg
739797
*
@@ -780,20 +838,27 @@ devredir_proc_client_core_cap_resp(struct stream *s)
780838
{
781839
case CAP_GENERAL_TYPE:
782840
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+
}
783845
break;
784846

785847
case CAP_PRINTER_TYPE:
786848
LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_PRINTER_TYPE");
849+
xstream_seek(s, cap_len);
787850
g_is_printer_redir_supported = 1;
788851
break;
789852

790853
case CAP_PORT_TYPE:
791854
LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_PORT_TYPE");
855+
xstream_seek(s, cap_len);
792856
g_is_port_redir_supported = 1;
793857
break;
794858

795859
case CAP_DRIVE_TYPE:
796860
LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_DRIVE_TYPE");
861+
xstream_seek(s, cap_len);
797862
g_is_drive_redir_supported = 1;
798863
if (cap_version == 2)
799864
{
@@ -803,10 +868,10 @@ devredir_proc_client_core_cap_resp(struct stream *s)
803868

804869
case CAP_SMARTCARD_TYPE:
805870
LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_SMARTCARD_TYPE");
871+
xstream_seek(s, cap_len);
806872
g_is_smartcard_redir_supported = (scard_init() == 0);
807873
break;
808874
}
809-
xstream_seek(s, cap_len);
810875
}
811876
return 0;
812877
}

0 commit comments

Comments
 (0)