mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
[channels,rdpdr] relax state checks for PAKID_CORE_CLIENTID_CONFIRM
This missage might be sent before PAKID_CORE_SERVER_CAPABILITY by some servers. Do accept these.
This commit is contained in:
@@ -189,7 +189,6 @@ UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
if (!rdpdr || !s)
|
if (!rdpdr || !s)
|
||||||
return CHANNEL_RC_NULL_DATA;
|
return CHANNEL_RC_NULL_DATA;
|
||||||
|
|
||||||
WINPR_ASSERT(rdpdr->state == RDPDR_CHANNEL_STATE_SERVER_CAPS);
|
|
||||||
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_CLIENT_CAPS);
|
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_CLIENT_CAPS);
|
||||||
|
|
||||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
|
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
|
||||||
|
|||||||
@@ -1681,7 +1681,9 @@ static BOOL rdpdr_check_channel_state(rdpdrPlugin* rdpdr, UINT16 packetid)
|
|||||||
RDPDR_CHANNEL_STATE_READY, RDPDR_CHANNEL_STATE_CLIENT_CAPS,
|
RDPDR_CHANNEL_STATE_READY, RDPDR_CHANNEL_STATE_CLIENT_CAPS,
|
||||||
RDPDR_CHANNEL_STATE_CLIENTID_CONFIRM, RDPDR_CHANNEL_STATE_USER_LOGGEDON);
|
RDPDR_CHANNEL_STATE_CLIENTID_CONFIRM, RDPDR_CHANNEL_STATE_USER_LOGGEDON);
|
||||||
case PAKID_CORE_CLIENTID_CONFIRM:
|
case PAKID_CORE_CLIENTID_CONFIRM:
|
||||||
return rdpdr_state_check(rdpdr, packetid, RDPDR_CHANNEL_STATE_CLIENTID_CONFIRM, 3,
|
return rdpdr_state_check(rdpdr, packetid, RDPDR_CHANNEL_STATE_CLIENTID_CONFIRM, 5,
|
||||||
|
RDPDR_CHANNEL_STATE_NAME_REQUEST,
|
||||||
|
RDPDR_CHANNEL_STATE_SERVER_CAPS,
|
||||||
RDPDR_CHANNEL_STATE_CLIENT_CAPS, RDPDR_CHANNEL_STATE_READY,
|
RDPDR_CHANNEL_STATE_CLIENT_CAPS, RDPDR_CHANNEL_STATE_READY,
|
||||||
RDPDR_CHANNEL_STATE_USER_LOGGEDON);
|
RDPDR_CHANNEL_STATE_USER_LOGGEDON);
|
||||||
case PAKID_CORE_USER_LOGGEDON:
|
case PAKID_CORE_USER_LOGGEDON:
|
||||||
@@ -1700,6 +1702,24 @@ static BOOL rdpdr_check_channel_state(rdpdrPlugin* rdpdr, UINT16 packetid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL tryAdvance(rdpdrPlugin* rdpdr)
|
||||||
|
{
|
||||||
|
if (rdpdr->haveClientId && rdpdr->haveServerCaps)
|
||||||
|
{
|
||||||
|
const UINT error = rdpdr_send_device_list_announce_request(rdpdr, FALSE);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||||
|
"rdpdr_send_device_list_announce_request failed with error %" PRIu32 "",
|
||||||
|
error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_READY))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function description
|
* Function description
|
||||||
*
|
*
|
||||||
@@ -1730,6 +1750,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
switch (packetId)
|
switch (packetId)
|
||||||
{
|
{
|
||||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||||
|
rdpdr->haveClientId = FALSE;
|
||||||
|
rdpdr->haveServerCaps = FALSE;
|
||||||
if ((error = rdpdr_process_server_announce_request(rdpdr, s)))
|
if ((error = rdpdr_process_server_announce_request(rdpdr, s)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -1763,6 +1785,12 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
"rdpdr_send_capability_response failed with error %" PRIu32 "",
|
"rdpdr_send_capability_response failed with error %" PRIu32 "",
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rdpdr->haveServerCaps = TRUE;
|
||||||
|
if (!tryAdvance(rdpdr))
|
||||||
|
error = ERROR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1770,28 +1798,31 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s)))
|
if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE)))
|
else
|
||||||
{
|
{
|
||||||
WLog_Print(
|
rdpdr->haveClientId = TRUE;
|
||||||
rdpdr->log, WLOG_ERROR,
|
if (!tryAdvance(rdpdr))
|
||||||
"rdpdr_send_device_list_announce_request failed with error %" PRIu32 "",
|
error = ERROR_INTERNAL_ERROR;
|
||||||
error);
|
|
||||||
}
|
|
||||||
else if (!rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_READY))
|
|
||||||
{
|
|
||||||
error = ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAKID_CORE_USER_LOGGEDON:
|
case PAKID_CORE_USER_LOGGEDON:
|
||||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, TRUE)))
|
if (!rdpdr->haveServerCaps)
|
||||||
|
{
|
||||||
|
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||||
|
"Wrong state %s for %s. [serverCaps=%d, clientId=%d]",
|
||||||
|
rdpdr_state_str(rdpdr->state), rdpdr_packetid_string(packetId),
|
||||||
|
rdpdr->haveServerCaps, rdpdr->haveClientId);
|
||||||
|
error = ERROR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
else if ((error = rdpdr_send_device_list_announce_request(rdpdr, TRUE)))
|
||||||
{
|
{
|
||||||
WLog_Print(
|
WLog_Print(
|
||||||
rdpdr->log, WLOG_ERROR,
|
rdpdr->log, WLOG_ERROR,
|
||||||
"rdpdr_send_device_list_announce_request failed with error %" PRIu32 "",
|
"rdpdr_send_device_list_announce_request failed with error %" PRIu32 "",
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
else if (!rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_READY))
|
else if (!tryAdvance(rdpdr))
|
||||||
{
|
{
|
||||||
error = ERROR_INTERNAL_ERROR;
|
error = ERROR_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ typedef struct
|
|||||||
wLog* log;
|
wLog* log;
|
||||||
BOOL async;
|
BOOL async;
|
||||||
BOOL capabilities[6];
|
BOOL capabilities[6];
|
||||||
|
BOOL haveClientId;
|
||||||
|
BOOL haveServerCaps;
|
||||||
} rdpdrPlugin;
|
} rdpdrPlugin;
|
||||||
|
|
||||||
BOOL rdpdr_state_advance(rdpdrPlugin* rdpdr, enum RDPDR_CHANNEL_STATE next);
|
BOOL rdpdr_state_advance(rdpdrPlugin* rdpdr, enum RDPDR_CHANNEL_STATE next);
|
||||||
|
|||||||
Reference in New Issue
Block a user