mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 08:54:38 +09:00
check stream sizes when reading ClientInfoPDU
This commit is contained in:
@@ -49,15 +49,18 @@ static const char* const INFO_TYPE_LOGON_STRINGS[] =
|
||||
* @param settings settings
|
||||
*/
|
||||
|
||||
void rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings)
|
||||
BOOL rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings)
|
||||
{
|
||||
ARC_SC_PRIVATE_PACKET* autoReconnectCookie;
|
||||
autoReconnectCookie = settings->ServerAutoReconnectCookie;
|
||||
|
||||
if(stream_get_left(s) < 4+4+4+16)
|
||||
return FALSE;
|
||||
stream_read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
|
||||
stream_read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */
|
||||
stream_read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
|
||||
stream_read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,6 +118,8 @@ BOOL rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings)
|
||||
UINT16 cbClientDir;
|
||||
UINT16 cbAutoReconnectLen;
|
||||
|
||||
if(stream_get_left(s) < 4)
|
||||
return FALSE;
|
||||
stream_read_UINT16(s, clientAddressFamily); /* clientAddressFamily */
|
||||
stream_read_UINT16(s, cbClientAddress); /* cbClientAddress */
|
||||
|
||||
@@ -126,6 +131,8 @@ BOOL rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings)
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL);
|
||||
stream_seek(s, cbClientAddress);
|
||||
|
||||
if(stream_get_left(s) < 2)
|
||||
return FALSE;
|
||||
stream_read_UINT16(s, cbClientDir); /* cbClientDir */
|
||||
|
||||
if (stream_get_left(s) < cbClientDir)
|
||||
@@ -140,6 +147,8 @@ BOOL rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings)
|
||||
if (!rdp_read_client_time_zone(s, settings))
|
||||
return FALSE;
|
||||
|
||||
if(stream_get_left(s) < 10)
|
||||
return FALSE;
|
||||
stream_seek_UINT32(s); /* clientSessionId, should be set to 0 */
|
||||
stream_read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */
|
||||
|
||||
@@ -225,6 +234,9 @@ BOOL rdp_read_info_packet(STREAM* s, rdpSettings* settings)
|
||||
UINT16 cbAlternateShell;
|
||||
UINT16 cbWorkingDir;
|
||||
|
||||
if(stream_get_left(s) < 18) // invalid packet
|
||||
return FALSE;
|
||||
|
||||
stream_seek_UINT32(s); /* CodePage */
|
||||
stream_read_UINT32(s, flags); /* flags */
|
||||
|
||||
@@ -468,53 +480,71 @@ BOOL rdp_send_client_info(rdpRdp* rdp)
|
||||
return rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
|
||||
}
|
||||
|
||||
void rdp_recv_logon_info_v1(rdpRdp* rdp, STREAM* s)
|
||||
BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
UINT32 cbDomain;
|
||||
UINT32 cbUserName;
|
||||
|
||||
if(stream_get_left(s) < 4+52+4+512+4)
|
||||
return FALSE;
|
||||
stream_read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */
|
||||
stream_seek(s, 52); /* domain (52 bytes) */
|
||||
stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */
|
||||
stream_seek(s, 512); /* userName (512 bytes) */
|
||||
stream_seek_UINT32(s); /* sessionId (4 bytes) */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void rdp_recv_logon_info_v2(rdpRdp* rdp, STREAM* s)
|
||||
BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
UINT32 cbDomain;
|
||||
UINT32 cbUserName;
|
||||
|
||||
if(stream_get_left(s) < 2+4+4+4+4+558)
|
||||
return FALSE;
|
||||
stream_seek_UINT16(s); /* version (2 bytes) */
|
||||
stream_seek_UINT32(s); /* size (4 bytes) */
|
||||
stream_seek_UINT32(s); /* sessionId (4 bytes) */
|
||||
stream_read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */
|
||||
stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */
|
||||
stream_seek(s, 558); /* pad */
|
||||
|
||||
if(stream_get_left(s) < cbDomain+cbUserName)
|
||||
return FALSE;
|
||||
stream_seek(s, cbDomain); /* domain */
|
||||
stream_seek(s, cbUserName); /* userName */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void rdp_recv_logon_plain_notify(rdpRdp* rdp, STREAM* s)
|
||||
BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if(stream_get_left(s) < 576)
|
||||
return FALSE;
|
||||
stream_seek(s, 576); /* pad */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void rdp_recv_logon_error_info(rdpRdp* rdp, STREAM* s)
|
||||
BOOL rdp_recv_logon_error_info(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
UINT32 errorNotificationType;
|
||||
UINT32 errorNotificationData;
|
||||
|
||||
if(stream_get_left(s) < 4)
|
||||
return FALSE;
|
||||
stream_read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */
|
||||
stream_read_UINT32(s, errorNotificationData); /* errorNotificationData (4 bytes) */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s)
|
||||
BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
UINT32 cbFieldData;
|
||||
UINT32 fieldsPresent;
|
||||
UINT16 Length;
|
||||
|
||||
if(stream_get_left(s) < 6)
|
||||
return FALSE;
|
||||
|
||||
stream_read_UINT16(s, Length); /* The total size in bytes of this structure */
|
||||
stream_read_UINT32(s, fieldsPresent); /* fieldsPresent (4 bytes) */
|
||||
|
||||
@@ -522,23 +552,34 @@ void rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s)
|
||||
|
||||
if (fieldsPresent & LOGON_EX_AUTORECONNECTCOOKIE)
|
||||
{
|
||||
if(stream_get_left(s) < 4)
|
||||
return FALSE;
|
||||
stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */
|
||||
rdp_read_server_auto_reconnect_cookie(s, rdp->settings);
|
||||
if(rdp_read_server_auto_reconnect_cookie(s, rdp->settings) == FALSE)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (fieldsPresent & LOGON_EX_LOGONERRORS)
|
||||
{
|
||||
if(stream_get_left(s) < 4)
|
||||
return FALSE;
|
||||
stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */
|
||||
rdp_recv_logon_error_info(rdp, s);
|
||||
if(rdp_recv_logon_error_info(rdp, s) == FALSE)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(stream_get_left(s) < 570)
|
||||
return FALSE;
|
||||
stream_seek(s, 570); /* pad */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
UINT32 infoType;
|
||||
|
||||
if(stream_get_left(s) < 4)
|
||||
return FALSE;
|
||||
stream_read_UINT32(s, infoType); /* infoType (4 bytes) */
|
||||
|
||||
//printf("%s\n", INFO_TYPE_LOGON_STRINGS[infoType]);
|
||||
@@ -546,20 +587,16 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s)
|
||||
switch (infoType)
|
||||
{
|
||||
case INFO_TYPE_LOGON:
|
||||
rdp_recv_logon_info_v1(rdp, s);
|
||||
break;
|
||||
return rdp_recv_logon_info_v1(rdp, s);
|
||||
|
||||
case INFO_TYPE_LOGON_LONG:
|
||||
rdp_recv_logon_info_v2(rdp, s);
|
||||
break;
|
||||
return rdp_recv_logon_info_v2(rdp, s);
|
||||
|
||||
case INFO_TYPE_LOGON_PLAIN_NOTIFY:
|
||||
rdp_recv_logon_plain_notify(rdp, s);
|
||||
break;
|
||||
return rdp_recv_logon_plain_notify(rdp, s);
|
||||
|
||||
case INFO_TYPE_LOGON_EXTENDED_INF:
|
||||
rdp_recv_logon_info_extended(rdp, s);
|
||||
break;
|
||||
return rdp_recv_logon_info_extended(rdp, s);
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -75,7 +75,7 @@ void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time);
|
||||
void rdp_get_client_time_zone(STREAM* s, rdpSettings* settings);
|
||||
BOOL rdp_read_client_time_zone(STREAM* s, rdpSettings* settings);
|
||||
void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings);
|
||||
void rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
|
||||
BOOL rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
|
||||
BOOL rdp_read_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
|
||||
void rdp_write_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
|
||||
void rdp_write_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
|
||||
|
||||
Reference in New Issue
Block a user