[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:
akallabeth 2025-03-27 13:26:44 +01:00
parent 0ed1548974
commit 7939a44ce5
No known key found for this signature in database
GPG Key ID: A49454A3FC909FD5
3 changed files with 45 additions and 13 deletions

View File

@ -189,7 +189,6 @@ UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
if (!rdpdr || !s)
return CHANNEL_RC_NULL_DATA;
WINPR_ASSERT(rdpdr->state == RDPDR_CHANNEL_STATE_SERVER_CAPS);
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_CLIENT_CAPS);
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))

View File

@ -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_CLIENTID_CONFIRM, RDPDR_CHANNEL_STATE_USER_LOGGEDON);
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_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
*
@ -1730,6 +1750,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
switch (packetId)
{
case PAKID_CORE_SERVER_ANNOUNCE:
rdpdr->haveClientId = FALSE;
rdpdr->haveServerCaps = FALSE;
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 "",
error);
}
else
{
rdpdr->haveServerCaps = TRUE;
if (!tryAdvance(rdpdr))
error = ERROR_INTERNAL_ERROR;
}
break;
@ -1770,28 +1798,31 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* 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->log, WLOG_ERROR,
"rdpdr_send_device_list_announce_request failed with error %" PRIu32 "",
error);
}
else if (!rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_READY))
{
error = ERROR_INTERNAL_ERROR;
rdpdr->haveClientId = TRUE;
if (!tryAdvance(rdpdr))
error = ERROR_INTERNAL_ERROR;
}
break;
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(
rdpdr->log, WLOG_ERROR,
"rdpdr_send_device_list_announce_request failed with error %" PRIu32 "",
error);
}
else if (!rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_READY))
else if (!tryAdvance(rdpdr))
{
error = ERROR_INTERNAL_ERROR;
}

View File

@ -111,6 +111,8 @@ typedef struct
wLog* log;
BOOL async;
BOOL capabilities[6];
BOOL haveClientId;
BOOL haveServerCaps;
} rdpdrPlugin;
BOOL rdpdr_state_advance(rdpdrPlugin* rdpdr, enum RDPDR_CHANNEL_STATE next);