[core] implement skip channel join

This commit is contained in:
akallabeth 2023-01-20 09:03:16 +01:00 committed by Martin Fleisz
parent 60424ef76f
commit 23281121bf
5 changed files with 100 additions and 53 deletions

View File

@ -952,6 +952,54 @@ end:
return ret;
}
static BOOL rdp_client_send_client_info_and_change_state(rdpRdp* rdp)
{
WINPR_ASSERT(rdp);
if (!rdp_client_establish_keys(rdp))
return FALSE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE))
return FALSE;
if (!rdp_send_client_info(rdp))
return FALSE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST))
return FALSE;
return TRUE;
}
BOOL rdp_client_skip_mcs_channel_join(rdpRdp* rdp)
{
WINPR_ASSERT(rdp);
rdpMcs* mcs = rdp->mcs;
WINPR_ASSERT(mcs);
mcs->userChannelJoined = TRUE;
mcs->globalChannelJoined = TRUE;
mcs->messageChannelJoined = TRUE;
for (UINT32 i = 0; i < mcs->channelCount; i++)
{
rdpMcsChannel* cur = &mcs->channels[i];
cur->joined = TRUE;
}
return rdp_client_send_client_info_and_change_state(rdp);
}
static BOOL rdp_client_join_channel(rdpRdp* rdp, UINT16 ChannelId)
{
WINPR_ASSERT(rdp);
rdpMcs* mcs = rdp->mcs;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
return FALSE;
if (!mcs_send_channel_join_request(mcs, ChannelId))
return FALSE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
return FALSE;
return TRUE;
}
BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
{
UINT32 i;
@ -968,12 +1016,7 @@ BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
return FALSE;
mcs->userChannelJoined = TRUE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
return FALSE;
if (!mcs_send_channel_join_request(mcs, MCS_GLOBAL_CHANNEL_ID))
return FALSE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
if (!rdp_client_join_channel(rdp, MCS_GLOBAL_CHANNEL_ID))
return FALSE;
}
else if (!mcs->globalChannelJoined)
@ -985,13 +1028,8 @@ BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
if (mcs->messageChannelId != 0)
{
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
if (!rdp_client_join_channel(rdp, mcs->messageChannelId))
return FALSE;
if (!mcs_send_channel_join_request(mcs, mcs->messageChannelId))
return FALSE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
return FALSE;
allJoined = FALSE;
}
else
@ -999,14 +1037,8 @@ BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
if (mcs->channelCount > 0)
{
const rdpMcsChannel* cur = &mcs->channels[0];
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
if (!rdp_client_join_channel(rdp, cur->ChannelId))
return FALSE;
if (!mcs_send_channel_join_request(mcs, cur->ChannelId))
return FALSE;
if (!rdp_client_transition_to_state(rdp,
CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
return FALSE;
allJoined = FALSE;
}
}
@ -1021,13 +1053,8 @@ BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
if (mcs->channelCount > 0)
{
const rdpMcsChannel* cur = &mcs->channels[0];
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
if (!rdp_client_join_channel(rdp, cur->ChannelId))
return FALSE;
if (!mcs_send_channel_join_request(mcs, cur->ChannelId))
return FALSE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
return FALSE;
allJoined = FALSE;
}
}
@ -1049,27 +1076,15 @@ BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
if (i + 1 < mcs->channelCount)
{
const rdpMcsChannel* cur = &mcs->channels[i + 1];
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
if (!rdp_client_join_channel(rdp, cur->ChannelId))
return FALSE;
if (!mcs_send_channel_join_request(mcs, cur->ChannelId))
return FALSE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
return FALSE;
allJoined = FALSE;
}
}
if (mcs->userChannelJoined && mcs->globalChannelJoined && allJoined)
{
if (!rdp_client_establish_keys(rdp))
return FALSE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE))
return FALSE;
if (!rdp_send_client_info(rdp))
return FALSE;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST))
if (!rdp_client_send_client_info_and_change_state(rdp))
return FALSE;
}
@ -1477,6 +1492,25 @@ BOOL rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, wStream* s)
return rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER);
}
static BOOL rdp_server_skip_mcs_channel_join(rdpRdp* rdp)
{
WINPR_ASSERT(rdp);
rdpMcs* mcs = rdp->mcs;
WINPR_ASSERT(mcs);
mcs->userChannelJoined = TRUE;
mcs->globalChannelJoined = TRUE;
mcs->messageChannelJoined = TRUE;
for (UINT32 i = 0; i < mcs->channelCount; i++)
{
rdpMcsChannel* cur = &mcs->channels[i];
cur->joined = TRUE;
}
return rdp_server_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE);
}
BOOL rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, wStream* s)
{
if (!mcs_recv_attach_user_request(rdp->mcs, s))
@ -1488,6 +1522,8 @@ BOOL rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, wStream* s)
if (!mcs_send_attach_user_confirm(rdp->mcs))
return FALSE;
if (freerdp_settings_get_bool(rdp->settings, FreeRDP_SupportSkipChannelJoin))
return rdp_server_skip_mcs_channel_join(rdp);
return rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST);
}

View File

@ -43,6 +43,8 @@ FREERDP_LOCAL BOOL rdp_client_disconnect(rdpRdp* rdp);
FREERDP_LOCAL BOOL rdp_client_disconnect_and_clear(rdpRdp* rdp);
FREERDP_LOCAL BOOL rdp_client_reconnect(rdpRdp* rdp);
FREERDP_LOCAL BOOL rdp_client_redirect(rdpRdp* rdp);
FREERDP_LOCAL BOOL rdp_client_skip_mcs_channel_join(rdpRdp* rdp);
FREERDP_LOCAL BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s);
FREERDP_LOCAL BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s);
FREERDP_LOCAL state_run_t rdp_client_connect_license(rdpRdp* rdp, wStream* s);

View File

@ -857,8 +857,7 @@ static UINT32 filterAndLogEarlyServerCapabilityFlags(UINT32 flags)
{
const UINT32 mask =
(RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1 | RNS_UD_SC_DYNAMIC_DST_SUPPORTED |
RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2); // TODO: Not implemented
// RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED
RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2 | RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED);
const UINT32 filtered = flags & mask;
const UINT32 unknown = flags & (~mask);
if (unknown != 0)
@ -896,8 +895,8 @@ static UINT16 filterAndLogEarlyClientCapabilityFlags(UINT32 flags)
RNS_UD_CS_SUPPORT_STATUSINFO_PDU | RNS_UD_CS_STRONG_ASYMMETRIC_KEYS |
RNS_UD_CS_VALID_CONNECTION_TYPE | RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU |
RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT | RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL |
RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE |
RNS_UD_CS_SUPPORT_HEARTBEAT_PDU); // unsupported RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN
RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE | RNS_UD_CS_SUPPORT_HEARTBEAT_PDU |
RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN);
const UINT32 filtered = flags & mask;
const UINT32 unknown = flags & ~mask;
if (unknown != 0)
@ -2033,7 +2032,7 @@ BOOL gcc_read_server_network_data(wStream* s, rdpMcs* mcs)
if (!Stream_CheckAndLogRequiredLength(TAG, s, 2ull * channelCount))
return FALSE;
for (i = 0; i < parsedChannelCount; i++)
for (UINT32 i = 0; i < parsedChannelCount; i++)
{
rdpMcsChannel* channel = &mcs->channels[i];
Stream_Read_UINT16(s, channelId); /* channelId */

View File

@ -1793,17 +1793,25 @@ static state_run_t rdp_recv_callback_int(rdpTransport* transport, wStream* s, vo
WLog_ERR(TAG, "mcs_recv_attach_user_confirm failure");
status = STATE_RUN_FAILED;
}
else if (!rdp_client_transition_to_state(rdp,
CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
status = STATE_RUN_FAILED;
else if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->userId))
else if (!freerdp_settings_get_bool(rdp->settings, FreeRDP_SupportSkipChannelJoin))
{
WLog_ERR(TAG, "mcs_send_channel_join_request failure");
status = STATE_RUN_FAILED;
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
status = STATE_RUN_FAILED;
else if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->userId))
{
WLog_ERR(TAG, "mcs_send_channel_join_request failure");
status = STATE_RUN_FAILED;
}
else if (!rdp_client_transition_to_state(
rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
status = STATE_RUN_FAILED;
}
else
{
/* SKIP_CHANNELJOIN is active, consider channels to be joined */
if (!rdp_client_skip_mcs_channel_join(rdp))
status = STATE_RUN_FAILED;
}
else if (!rdp_client_transition_to_state(rdp,
CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
status = STATE_RUN_FAILED;
break;
case CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE:

View File

@ -754,6 +754,8 @@ rdpSettings* freerdp_settings_new(DWORD flags)
goto out_fail;
}
}
if (!freerdp_settings_set_bool(settings, FreeRDP_SupportSkipChannelJoin, TRUE))
goto out_fail;
return settings;
out_fail: