Improved MCS checks, added settings to MCS function

This commit is contained in:
Armin Novak 2022-10-10 11:31:22 +02:00 committed by akallabeth
parent b706676d1a
commit a3ec857278
3 changed files with 61 additions and 18 deletions

View File

@ -1368,7 +1368,7 @@ BOOL rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, wStream* s)
BOOL allJoined = TRUE; BOOL allJoined = TRUE;
rdpMcs* mcs = rdp->mcs; rdpMcs* mcs = rdp->mcs;
if (!mcs_recv_channel_join_request(mcs, s, &channelId)) if (!mcs_recv_channel_join_request(mcs, rdp->settings, s, &channelId))
return FALSE; return FALSE;
if (!mcs_send_channel_join_confirm(mcs, channelId)) if (!mcs_send_channel_join_confirm(mcs, channelId))

View File

@ -287,6 +287,7 @@ const char* mcs_domain_pdu_string(DomainMCSPDU pdu)
return "DomainMCSPDU_UNKNOWN"; return "DomainMCSPDU_UNKNOWN";
} }
} }
static BOOL mcs_merge_domain_parameters(DomainParameters* targetParameters, static BOOL mcs_merge_domain_parameters(DomainParameters* targetParameters,
DomainParameters* minimumParameters, DomainParameters* minimumParameters,
DomainParameters* maximumParameters, DomainParameters* maximumParameters,
@ -376,16 +377,18 @@ BOOL mcs_read_domain_mcspdu_header(wStream* s, DomainMCSPDU domainMCSPDU, UINT16
* @param length TPKT length * @param length TPKT length
*/ */
void mcs_write_domain_mcspdu_header(wStream* s, DomainMCSPDU domainMCSPDU, UINT16 length, BOOL mcs_write_domain_mcspdu_header(wStream* s, DomainMCSPDU domainMCSPDU, UINT16 length,
BYTE options) BYTE options)
{ {
WINPR_ASSERT(s); WINPR_ASSERT(s);
WINPR_ASSERT((options & ~0x03) == 0); WINPR_ASSERT((options & ~0x03) == 0);
WINPR_ASSERT((domainMCSPDU & ~0x3F) == 0); WINPR_ASSERT((domainMCSPDU & ~0x3F) == 0);
tpkt_write_header(s, length); if (!tpkt_write_header(s, length))
tpdu_write_data(s); return FALSE;
per_write_choice(s, (BYTE)((domainMCSPDU << 2) | options)); if (!tpdu_write_data(s))
return FALSE;
return per_write_choice(s, (BYTE)((domainMCSPDU << 2) | options));
} }
/** /**
@ -1153,7 +1156,8 @@ BOOL mcs_send_attach_user_confirm(rdpMcs* mcs)
* @param s stream * @param s stream
*/ */
BOOL mcs_recv_channel_join_request(rdpMcs* mcs, wStream* s, UINT16* channelId) BOOL mcs_recv_channel_join_request(rdpMcs* mcs, const rdpSettings* settings, wStream* s,
UINT16* channelId)
{ {
UINT16 length; UINT16 length;
UINT16 userId; UINT16 userId;
@ -1164,8 +1168,15 @@ BOOL mcs_recv_channel_join_request(rdpMcs* mcs, wStream* s, UINT16* channelId)
if (!mcs_read_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinRequest, &length, NULL)) if (!mcs_read_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinRequest, &length, NULL))
return FALSE; return FALSE;
if (!per_read_integer16(s, &userId, MCS_BASE_CHANNEL_ID) && (userId == mcs->userId)) if (!per_read_integer16(s, &userId, MCS_BASE_CHANNEL_ID))
return FALSE; return FALSE;
if (userId != mcs->userId)
{
if (freerdp_settings_get_bool(settings, FreeRDP_TransportDumpReplay))
mcs->userId = userId;
else
return FALSE;
}
if (!per_read_integer16(s, channelId, 0)) if (!per_read_integer16(s, channelId, 0))
return FALSE; return FALSE;
@ -1244,7 +1255,7 @@ BOOL mcs_recv_channel_join_confirm(rdpMcs* mcs, wStream* s, UINT16* channelId)
BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channelId) BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channelId)
{ {
wStream* s; wStream* s;
int status; int status = -1;
UINT16 length = 15; UINT16 length = 15;
if (!mcs) if (!mcs)
@ -1258,13 +1269,19 @@ BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channelId)
return FALSE; return FALSE;
} }
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinConfirm, length, 2); if (!mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinConfirm, length, 2))
per_write_enumerated(s, 0, MCS_Result_enum_length); /* result */ goto fail;
per_write_integer16(s, mcs->userId, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ if (!per_write_enumerated(s, 0, MCS_Result_enum_length)) /* result */
per_write_integer16(s, channelId, 0); /* requested (ChannelId) */ goto fail;
per_write_integer16(s, channelId, 0); /* channelId */ if (!per_write_integer16(s, mcs->userId, MCS_BASE_CHANNEL_ID)) /* initiator (UserId) */
goto fail;
if (!per_write_integer16(s, channelId, 0)) /* requested (ChannelId) */
goto fail;
if (!per_write_integer16(s, channelId, 0)) /* channelId */
goto fail;
Stream_SealLength(s); Stream_SealLength(s);
status = transport_write(mcs->transport, s); status = transport_write(mcs->transport, s);
fail:
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
return (status < 0) ? FALSE : TRUE; return (status < 0) ? FALSE : TRUE;
} }
@ -1381,9 +1398,6 @@ rdpMcs* mcs_new(rdpTransport* transport)
{ {
rdpMcs* mcs; rdpMcs* mcs;
if (!transport)
return NULL;
mcs = (rdpMcs*)calloc(1, sizeof(rdpMcs)); mcs = (rdpMcs*)calloc(1, sizeof(rdpMcs));
if (!mcs) if (!mcs)
@ -1421,3 +1435,29 @@ void mcs_free(rdpMcs* mcs)
free(mcs); free(mcs);
} }
} }
BOOL mcs_server_apply_to_settings(const rdpMcs* mcs, rdpSettings* settings)
{
UINT32 x;
WINPR_ASSERT(mcs);
WINPR_ASSERT(settings);
if (!freerdp_settings_set_uint32(settings, FreeRDP_ChannelCount, mcs->channelCount))
return FALSE;
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ChannelDefArray, NULL,
mcs->channelCount))
return FALSE;
for (x = 0; x < mcs->channelCount; x++)
{
const rdpMcsChannel* current = &mcs->channels[x];
CHANNEL_DEF def = { 0 };
def.options = current->options;
memcpy(def.name, current->Name, sizeof(def.name));
if (!freerdp_settings_set_pointer_array(settings, FreeRDP_ChannelDefArray, x, &def))
return FALSE;
}
return TRUE;
}

View File

@ -158,6 +158,8 @@ struct rdp_mcs
#define MCS_TYPE_CONNECT_RESPONSE 0x66 #define MCS_TYPE_CONNECT_RESPONSE 0x66
const char* mcs_domain_pdu_string(DomainMCSPDU pdu); const char* mcs_domain_pdu_string(DomainMCSPDU pdu);
BOOL mcs_server_apply_to_settings(const rdpMcs* msc, rdpSettings* settings);
FREERDP_LOCAL BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s); FREERDP_LOCAL BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s);
FREERDP_LOCAL BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s); FREERDP_LOCAL BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s);
FREERDP_LOCAL BOOL mcs_send_connect_response(rdpMcs* mcs); FREERDP_LOCAL BOOL mcs_send_connect_response(rdpMcs* mcs);
@ -167,14 +169,15 @@ FREERDP_LOCAL BOOL mcs_recv_attach_user_request(rdpMcs* mcs, wStream* s);
FREERDP_LOCAL BOOL mcs_send_attach_user_request(rdpMcs* mcs); FREERDP_LOCAL BOOL mcs_send_attach_user_request(rdpMcs* mcs);
FREERDP_LOCAL BOOL mcs_recv_attach_user_confirm(rdpMcs* mcs, wStream* s); FREERDP_LOCAL BOOL mcs_recv_attach_user_confirm(rdpMcs* mcs, wStream* s);
FREERDP_LOCAL BOOL mcs_send_attach_user_confirm(rdpMcs* mcs); FREERDP_LOCAL BOOL mcs_send_attach_user_confirm(rdpMcs* mcs);
FREERDP_LOCAL BOOL mcs_recv_channel_join_request(rdpMcs* mcs, wStream* s, UINT16* channelId); FREERDP_LOCAL BOOL mcs_recv_channel_join_request(rdpMcs* mcs, const rdpSettings* settings,
wStream* s, UINT16* channelId);
FREERDP_LOCAL BOOL mcs_send_channel_join_request(rdpMcs* mcs, UINT16 channelId); FREERDP_LOCAL BOOL mcs_send_channel_join_request(rdpMcs* mcs, UINT16 channelId);
FREERDP_LOCAL BOOL mcs_recv_channel_join_confirm(rdpMcs* mcs, wStream* s, UINT16* channelId); FREERDP_LOCAL BOOL mcs_recv_channel_join_confirm(rdpMcs* mcs, wStream* s, UINT16* channelId);
FREERDP_LOCAL BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channelId); FREERDP_LOCAL BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channelId);
FREERDP_LOCAL BOOL mcs_recv_disconnect_provider_ultimatum(rdpMcs* mcs, wStream* s, int* reason); FREERDP_LOCAL BOOL mcs_recv_disconnect_provider_ultimatum(rdpMcs* mcs, wStream* s, int* reason);
FREERDP_LOCAL BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs); FREERDP_LOCAL BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs);
FREERDP_LOCAL void mcs_write_domain_mcspdu_header(wStream* s, DomainMCSPDU domainMCSPDU, FREERDP_LOCAL BOOL mcs_write_domain_mcspdu_header(wStream* s, DomainMCSPDU domainMCSPDU,
UINT16 length, BYTE options); UINT16 length, BYTE options);
FREERDP_LOCAL BOOL mcs_client_begin(rdpMcs* mcs); FREERDP_LOCAL BOOL mcs_client_begin(rdpMcs* mcs);