diff --git a/channels/ainput/client/ainput_main.c b/channels/ainput/client/ainput_main.c index 8eeaed974..d7acd4bab 100644 --- a/channels/ainput/client/ainput_main.c +++ b/channels/ainput/client/ainput_main.c @@ -86,13 +86,13 @@ static UINT ainput_on_data_received(IWTSVirtualChannelCallback* pChannelCallback ainput = (AINPUT_PLUGIN*)callback->plugin; WINPR_ASSERT(ainput); - if (Stream_GetRemainingLength(data) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, data, 2)) return ERROR_NO_DATA; Stream_Read_UINT16(data, type); switch (type) { case MSG_AINPUT_VERSION: - if (Stream_GetRemainingLength(data) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, data, 8)) return ERROR_NO_DATA; Stream_Read_UINT32(data, ainput->MajorVersion); Stream_Read_UINT32(data, ainput->MinorVersion); diff --git a/channels/ainput/server/ainput_main.c b/channels/ainput/server/ainput_main.c index fbdee53e9..8f7ad2c3b 100644 --- a/channels/ainput/server/ainput_main.c +++ b/channels/ainput/server/ainput_main.c @@ -173,7 +173,7 @@ static UINT ainput_server_recv_mouse_event(ainput_server* ainput, wStream* s) WINPR_ASSERT(ainput); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 24) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 24)) return ERROR_NO_DATA; Stream_Read_UINT64(s, time); diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 060cec982..69d118060 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -137,7 +137,7 @@ static UINT audin_process_version(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c const UINT32 ClientVersion = 0x01; UINT32 ServerVersion; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, ServerVersion); @@ -195,7 +195,7 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c UINT32 NumFormats; UINT32 cbSizeFormatsPacket; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, NumFormats); @@ -469,7 +469,7 @@ static UINT audin_process_open(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* call UINT32 FramesPerPacket; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, FramesPerPacket); @@ -513,7 +513,7 @@ static UINT audin_process_format_change(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLB UINT32 NewFormat; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, NewFormat); diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 73d762aad..1a5040030 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -174,7 +174,7 @@ static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* return ERROR_INTERNAL_ERROR; } - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, version); /* version (4 bytes) */ @@ -223,7 +223,7 @@ static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT32 WINPR_ASSERT(cliprdr); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ @@ -232,13 +232,14 @@ static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT32 for (index = 0; index < cCapabilitiesSets; index++) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */ Stream_Read_UINT16(s, lengthCapability); /* lengthCapability (2 bytes) */ - if ((lengthCapability < 4) || (Stream_GetRemainingLength(s) < (lengthCapability - 4U))) + if ((lengthCapability < 4) || + (!Stream_CheckAndLogRequiredLength(TAG, s, lengthCapability - 4U))) return ERROR_INVALID_DATA; switch (capabilitySetType) @@ -386,11 +387,8 @@ static UINT cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UI WLog_Print(cliprdr->log, WLOG_DEBUG, "LockClipData"); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough remaining data"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } lockClipboardData.msgType = CB_LOCK_CLIPDATA; lockClipboardData.msgFlags = flags; @@ -452,14 +450,14 @@ static UINT cliprdr_order_recv(LPVOID userdata, wStream* s) WINPR_ASSERT(cliprdr); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, msgType); /* msgType (2 bytes) */ Stream_Read_UINT16(s, msgFlags); /* msgFlags (2 bytes) */ Stream_Read_UINT32(s, dataLen); /* dataLen (4 bytes) */ - if (Stream_GetRemainingLength(s) < dataLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, dataLen)) return ERROR_INVALID_DATA; #ifdef WITH_DEBUG_CLIPRDR diff --git a/channels/cliprdr/cliprdr_common.c b/channels/cliprdr/cliprdr_common.c index 2a9e93d2d..d8f08c0cc 100644 --- a/channels/cliprdr/cliprdr_common.c +++ b/channels/cliprdr/cliprdr_common.c @@ -322,11 +322,8 @@ wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList, } UINT cliprdr_read_unlock_clipdata(wStream* s, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough remaining data"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */ return CHANNEL_RC_OK; @@ -334,11 +331,8 @@ UINT cliprdr_read_unlock_clipdata(wStream* s, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unl UINT cliprdr_read_format_data_request(wStream* s, CLIPRDR_FORMAT_DATA_REQUEST* request) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, request->requestedFormatId); /* requestedFormatId (4 bytes) */ return CHANNEL_RC_OK; @@ -348,11 +342,8 @@ UINT cliprdr_read_format_data_response(wStream* s, CLIPRDR_FORMAT_DATA_RESPONSE* { response->requestedFormatData = NULL; - if (Stream_GetRemainingLength(s) < response->dataLen) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, response->dataLen)) return ERROR_INVALID_DATA; - } if (response->dataLen) response->requestedFormatData = Stream_Pointer(s); @@ -362,11 +353,8 @@ UINT cliprdr_read_format_data_response(wStream* s, CLIPRDR_FORMAT_DATA_RESPONSE* UINT cliprdr_read_file_contents_request(wStream* s, CLIPRDR_FILE_CONTENTS_REQUEST* request) { - if (Stream_GetRemainingLength(s) < 24) - { - WLog_ERR(TAG, "not enough remaining data"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 24)) return ERROR_INVALID_DATA; - } request->haveClipDataId = FALSE; Stream_Read_UINT32(s, request->streamId); /* streamId (4 bytes) */ @@ -390,11 +378,8 @@ UINT cliprdr_read_file_contents_request(wStream* s, CLIPRDR_FILE_CONTENTS_REQUES UINT cliprdr_read_file_contents_response(wStream* s, CLIPRDR_FILE_CONTENTS_RESPONSE* response) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough remaining data"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, response->streamId); /* streamId (4 bytes) */ response->requestedData = Stream_Pointer(s); /* requestedFileContentsData */ diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index 113806a67..eb63c2f0b 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -430,7 +430,7 @@ cliprdr_server_file_contents_response(CliprdrServerContext* context, static UINT cliprdr_server_receive_general_capability(CliprdrServerContext* context, wStream* s, CLIPRDR_GENERAL_CAPABILITY_SET* cap_set) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, cap_set->version); /* version (4 bytes) */ @@ -477,7 +477,7 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w WINPR_UNUSED(header); WLog_DBG(TAG, "CliprdrClientCapabilities"); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilities.cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ @@ -486,7 +486,7 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w for (index = 0; index < capabilities.cCapabilitiesSets; index++) { void* tmp = NULL; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) goto out; Stream_Read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */ Stream_Read_UINT16(s, capabilitySetLength); /* capabilitySetLength (2 bytes) */ @@ -555,13 +555,8 @@ static UINT cliprdr_server_receive_temporary_directory(CliprdrServerContext* con WINPR_UNUSED(header); - slength = Stream_GetRemainingLength(s); - if (slength / sizeof(WCHAR) < 260) - { - WLog_ERR(TAG, "Stream_GetRemainingLength returned %" PRIuz " but should at least be 520", - slength); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 260 * sizeof(WCHAR))) return CHANNEL_RC_NO_MEMORY; - } wszTempDir = (WCHAR*)Stream_Pointer(s); @@ -662,11 +657,8 @@ static UINT cliprdr_server_receive_lock_clipdata(CliprdrServerContext* context, UINT error = CHANNEL_RC_OK; WLog_DBG(TAG, "CliprdrClientLockClipData"); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } lockClipboardData.msgType = CB_LOCK_CLIPDATA; lockClipboardData.msgFlags = header->msgFlags; diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c index f6d11baa7..138ea9fd7 100644 --- a/channels/disp/client/disp_main.c +++ b/channels/disp/client/disp_main.c @@ -187,11 +187,8 @@ static UINT disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, context = (DispClientContext*)disp->iface.pInterface; WINPR_ASSERT(context); - if (Stream_GetRemainingLength(s) < 12) - { - WLog_ERR(TAG, "not enough remaining data"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */ Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorA); /* MaxMonitorAreaFactorA (4 bytes) */ @@ -217,11 +214,8 @@ static UINT disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s) WINPR_ASSERT(callback); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "not enough remaining data"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } if ((error = disp_read_header(s, &header))) { diff --git a/channels/disp/disp_common.c b/channels/disp/disp_common.c index dba0e9a37..9387691ea 100644 --- a/channels/disp/disp_common.c +++ b/channels/disp/disp_common.c @@ -34,11 +34,8 @@ */ UINT disp_read_header(wStream* s, DISPLAY_CONTROL_HEADER* header) { - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "header parsing failed: not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, header->type); Stream_Read_UINT32(s, header->length); diff --git a/channels/disp/server/disp_main.c b/channels/disp/server/disp_main.c index a9413d76d..408dd8aa7 100644 --- a/channels/disp/server/disp_main.c +++ b/channels/disp/server/disp_main.c @@ -133,11 +133,8 @@ static UINT disp_recv_display_control_monitor_layout_pdu(wStream* s, DispServerC WINPR_ASSERT(s); WINPR_ASSERT(context); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.MonitorLayoutSize); /* MonitorLayoutSize (4 bytes) */ @@ -157,11 +154,9 @@ static UINT disp_recv_display_control_monitor_layout_pdu(wStream* s, DispServerC return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) / DISPLAY_CONTROL_MONITOR_LAYOUT_SIZE < pdu.NumMonitors) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength( + TAG, s, pdu.NumMonitors * 1ull * DISPLAY_CONTROL_MONITOR_LAYOUT_SIZE)) return ERROR_INVALID_DATA; - } pdu.Monitors = (DISPLAY_CONTROL_MONITOR_LAYOUT*)calloc(pdu.NumMonitors, sizeof(DISPLAY_CONTROL_MONITOR_LAYOUT)); diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 5409effd6..26d0d8b07 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -952,7 +952,7 @@ static UINT drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, i if (!drdynvc) return CHANNEL_RC_BAD_INIT_HANDLE; - if (Stream_GetRemainingLength(s) < 3) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3)) return ERROR_INVALID_DATA; WLog_Print(drdynvc->log, WLOG_TRACE, "capability_request Sp=%d cbChId=%d", Sp, cbChId); @@ -964,7 +964,7 @@ static UINT drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, i */ if ((drdynvc->version == 2) || (drdynvc->version == 3)) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, drdynvc->PriorityCharge0); @@ -1054,7 +1054,7 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int c drdynvc->state = DRDYNVC_STATE_READY; } - if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, drdynvc_cblen_to_bytes(cbChId))) return ERROR_INVALID_DATA; ChannelId = drdynvc_read_variable_uint(s, cbChId); @@ -1131,7 +1131,8 @@ static UINT drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChI UINT32 Length; UINT32 ChannelId; - if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId) + drdynvc_cblen_to_bytes(Sp)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, drdynvc_cblen_to_bytes(cbChId) + drdynvc_cblen_to_bytes(Sp))) return ERROR_INVALID_DATA; ChannelId = drdynvc_read_variable_uint(s, cbChId); @@ -1162,7 +1163,7 @@ static UINT drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, wSt UINT32 ChannelId; UINT status; - if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, drdynvc_cblen_to_bytes(cbChId))) return ERROR_INVALID_DATA; ChannelId = drdynvc_read_variable_uint(s, cbChId); @@ -1187,7 +1188,7 @@ static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cb UINT error; UINT32 ChannelId; - if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, drdynvc_cblen_to_bytes(cbChId))) return ERROR_INVALID_DATA; ChannelId = drdynvc_read_variable_uint(s, cbChId); @@ -1214,7 +1215,7 @@ static UINT drdynvc_order_recv(drdynvcPlugin* drdynvc, wStream* s, UINT32 Thread int Sp; int cbChId; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return ERROR_INVALID_DATA; Stream_Read_UINT8(s, value); diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c index ab047625a..0d5b54373 100644 --- a/channels/drive/client/drive_file.c +++ b/channels/drive/client/drive_file.c @@ -577,7 +577,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN switch (FsInformationClass) { case FileBasicInformation: - if (Stream_GetRemainingLength(input) < 36) + if (!Stream_CheckAndLogRequiredLength(TAG, input, 36)) return FALSE; /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */ @@ -641,7 +641,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN /* http://msdn.microsoft.com/en-us/library/cc232067.aspx */ case FileAllocationInformation: - if (Stream_GetRemainingLength(input) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, input, 8)) return FALSE; /* http://msdn.microsoft.com/en-us/library/cc232076.aspx */ @@ -683,7 +683,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN if (Length) { - if (Stream_GetRemainingLength(input) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, input, 1)) return FALSE; Stream_Read_UINT8(input, delete_pending); @@ -707,7 +707,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN break; case FileRenameInformation: - if (Stream_GetRemainingLength(input) < 6) + if (!Stream_CheckAndLogRequiredLength(TAG, input, 6)) return FALSE; /* http://msdn.microsoft.com/en-us/library/cc232085.aspx */ @@ -715,7 +715,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN Stream_Seek_UINT8(input); /* RootDirectory */ Stream_Read_UINT32(input, FileNameLength); - if (Stream_GetRemainingLength(input) < FileNameLength) + if (!Stream_CheckAndLogRequiredLength(TAG, input, FileNameLength)) return FALSE; fullpath = drive_file_combine_fullpath(file->basepath, (WCHAR*)Stream_Pointer(input), diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index d3e2a4029..0b9ea694e 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -165,7 +165,7 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp) if (!drive || !irp || !irp->devman || !irp->Complete) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(irp->input) < 6 * 4 + 8) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 6 * 4 + 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, DesiredAccess); @@ -176,7 +176,7 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp) Stream_Read_UINT32(irp->input, CreateOptions); Stream_Read_UINT32(irp->input, PathLength); - if (Stream_GetRemainingLength(irp->input) < PathLength) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, PathLength)) return ERROR_INVALID_DATA; path = (const WCHAR*)Stream_Pointer(irp->input); @@ -274,7 +274,7 @@ static UINT drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp) if (!drive || !irp || !irp->output || !irp->Complete) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(irp->input) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 12)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, Length); @@ -333,7 +333,7 @@ static UINT drive_process_irp_write(DRIVE_DEVICE* drive, IRP* irp) if (!drive || !irp || !irp->input || !irp->output || !irp->Complete) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(irp->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 32)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, Length); @@ -378,7 +378,7 @@ static UINT drive_process_irp_query_information(DRIVE_DEVICE* drive, IRP* irp) if (!drive || !irp || !irp->Complete) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(irp->input) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, FsInformationClass); @@ -410,7 +410,7 @@ static UINT drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp) if (!drive || !irp || !irp->Complete || !irp->input || !irp->output) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(irp->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 32)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, FsInformationClass); @@ -458,7 +458,7 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* output = irp->output; - if (Stream_GetRemainingLength(irp->input) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, FsInformationClass); @@ -594,7 +594,7 @@ static UINT drive_process_irp_silent_ignore(DRIVE_DEVICE* drive, IRP* irp) if (!drive || !irp || !irp->output || !irp->Complete) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(irp->input) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, FsInformationClass); @@ -618,7 +618,7 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp) if (!drive || !irp || !irp->Complete) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(irp->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 32)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, FsInformationClass); diff --git a/channels/encomsp/client/encomsp_main.c b/channels/encomsp/client/encomsp_main.c index b09bbd7c6..d84122bf5 100644 --- a/channels/encomsp/client/encomsp_main.c +++ b/channels/encomsp/client/encomsp_main.c @@ -52,11 +52,8 @@ struct encomsp_plugin */ static UINT encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) { - if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, ENCOMSP_ORDER_HEADER_SIZE)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ @@ -84,11 +81,8 @@ static UINT encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) { ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING)); - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */ @@ -98,11 +92,8 @@ static UINT encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) / sizeof(WCHAR) < str->cchString) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(WCHAR) * str->cchString)) return ERROR_INVALID_DATA; - } Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ return CHANNEL_RC_OK; @@ -169,11 +160,8 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, beg = pos - ENCOMSP_ORDER_HEADER_SIZE; CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return ERROR_INVALID_DATA; - } Stream_Read_UINT8(s, pdu.Flags); /* Flags (1 byte) */ end = Stream_GetPosition(s); @@ -186,11 +174,8 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -220,11 +205,8 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream if (!context) return ERROR_INVALID_HANDLE; - if (Stream_GetRemainingLength(s) < 6) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return ERROR_INVALID_DATA; - } pos = Stream_GetPosition(s); if (pos < ENCOMSP_ORDER_HEADER_SIZE) @@ -251,11 +233,8 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -291,11 +270,8 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream beg = pos - ENCOMSP_ORDER_HEADER_SIZE; CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.AppId); /* AppId (4 bytes) */ end = Stream_GetPosition(s); @@ -308,11 +284,8 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -348,11 +321,8 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, beg = pos - ENCOMSP_ORDER_HEADER_SIZE; CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - if (Stream_GetRemainingLength(s) < 10) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 10)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ Stream_Read_UINT32(s, pdu.AppId); /* AppId (4 bytes) */ @@ -374,11 +344,8 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -414,11 +381,8 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, beg = pos - ENCOMSP_ORDER_HEADER_SIZE; CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.WndId); /* WndId (4 bytes) */ end = Stream_GetPosition(s); @@ -431,11 +395,8 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -471,11 +432,8 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, beg = pos - ENCOMSP_ORDER_HEADER_SIZE; CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.WndId); /* WndId (4 bytes) */ end = Stream_GetPosition(s); @@ -488,11 +446,8 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -528,11 +483,8 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream beg = pos - ENCOMSP_ORDER_HEADER_SIZE; CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - if (Stream_GetRemainingLength(s) < 10) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 10)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ Stream_Read_UINT32(s, pdu.GroupId); /* GroupId (4 bytes) */ @@ -554,11 +506,8 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -588,11 +537,8 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream if (!context) return ERROR_INVALID_HANDLE; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; - } beg = (Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); @@ -610,11 +556,8 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -650,11 +593,8 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc beg = pos - ENCOMSP_ORDER_HEADER_SIZE; CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - if (Stream_GetRemainingLength(s) < 6) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ @@ -668,11 +608,8 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -754,11 +691,8 @@ static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStr if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -803,11 +737,8 @@ static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wSt if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } diff --git a/channels/encomsp/server/encomsp_main.c b/channels/encomsp/server/encomsp_main.c index d7b51265b..3caf0aa82 100644 --- a/channels/encomsp/server/encomsp_main.c +++ b/channels/encomsp/server/encomsp_main.c @@ -38,7 +38,7 @@ */ static UINT encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) { - if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE) + if (!Stream_CheckAndLogRequiredLength(TAG, s, ENCOMSP_ORDER_HEADER_SIZE)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ @@ -59,7 +59,7 @@ static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) { ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING)); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return -1; Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */ @@ -67,7 +67,7 @@ static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) if (str->cchString > 1024) return -1; - if (Stream_GetRemainingLength(s) < (str->cchString * 2)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, (str->cchString * 2ull))) return -1; Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ @@ -91,11 +91,8 @@ static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerConte beg = ((int)Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - if (Stream_GetRemainingLength(s) < 6) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ @@ -109,11 +106,8 @@ static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerConte if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - } Stream_SetPosition(s, (beg + header->Length)); } @@ -166,7 +160,6 @@ static UINT encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s default: WLog_ERR(TAG, "header.Type unknown %" PRIu16 "!", header.Type); return ERROR_INVALID_DATA; - break; } } diff --git a/channels/geometry/client/geometry_main.c b/channels/geometry/client/geometry_main.c index c9675551a..f713882c5 100644 --- a/channels/geometry/client/geometry_main.c +++ b/channels/geometry/client/geometry_main.c @@ -188,15 +188,12 @@ static UINT geometry_recv_pdu(GEOMETRY_CHANNEL_CALLBACK* callback, wStream* s) geometry = (GEOMETRY_PLUGIN*)callback->plugin; context = (GeometryClientContext*)geometry->iface.pInterface; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough remaining data"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, length); /* Length (4 bytes) */ - if (length < 73 || Stream_GetRemainingLength(s) < (length - 4)) + if (length < 73 || !Stream_CheckAndLogRequiredLength(TAG, s, (length - 4))) { WLog_ERR(TAG, "invalid packet length"); return ERROR_INVALID_DATA; @@ -269,11 +266,8 @@ static UINT geometry_recv_pdu(GEOMETRY_CHANNEL_CALLBACK* callback, wStream* s) Stream_Read_UINT32(s, geometryType); Stream_Read_UINT32(s, cbGeometryBuffer); - if (Stream_GetRemainingLength(s) < cbGeometryBuffer) - { - WLog_ERR(TAG, "invalid packet length"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, cbGeometryBuffer)) return ERROR_INVALID_DATA; - } if (cbGeometryBuffer) { diff --git a/channels/gfxredir/gfxredir_common.c b/channels/gfxredir/gfxredir_common.c index 672dad423..552d7d261 100644 --- a/channels/gfxredir/gfxredir_common.c +++ b/channels/gfxredir/gfxredir_common.c @@ -34,11 +34,8 @@ */ UINT gfxredir_read_header(wStream* s, GFXREDIR_HEADER* header) { - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "header parsing failed: not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, header->cmdId); Stream_Read_UINT32(s, header->length); diff --git a/channels/gfxredir/server/gfxredir_main.c b/channels/gfxredir/server/gfxredir_main.c index 7b27661f5..f661a9c12 100644 --- a/channels/gfxredir/server/gfxredir_main.c +++ b/channels/gfxredir/server/gfxredir_main.c @@ -47,11 +47,8 @@ static UINT gfxredir_recv_legacy_caps_pdu(wStream* s, GfxRedirServerContext* con UINT32 error = CHANNEL_RC_OK; GFXREDIR_LEGACY_CAPS_PDU pdu; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.version); /* version (2 bytes) */ @@ -72,11 +69,8 @@ static UINT gfxredir_recv_caps_advertise_pdu(wStream* s, UINT32 length, UINT32 error = CHANNEL_RC_OK; GFXREDIR_CAPS_ADVERTISE_PDU pdu; - if (Stream_GetRemainingLength(s) < length) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return ERROR_INVALID_DATA; - } pdu.length = length; Stream_GetPointer(s, pdu.caps); @@ -105,11 +99,8 @@ static UINT gfxredir_recv_present_buffer_ack_pdu(wStream* s, GfxRedirServerConte UINT32 error = CHANNEL_RC_OK; GFXREDIR_PRESENT_BUFFER_ACK_PDU pdu; - if (Stream_GetRemainingLength(s) < 16) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return ERROR_INVALID_DATA; - } Stream_Read_UINT64(s, pdu.windowId); /* windowId (8 bytes) */ Stream_Read_UINT64(s, pdu.presentId); /* presentId (8 bytes) */ diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index 6ebbcc3e7..a0a0fdf91 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -87,7 +87,7 @@ static UINT parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) return ERROR_INVALID_DATA; /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ /* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */ - if (Stream_GetRemainingLength(irp->input) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, PathLength); ptr = (WCHAR*)Stream_Pointer(irp->input); @@ -153,7 +153,7 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp) UINT64 Offset; ssize_t status; BYTE* buffer = NULL; - if (Stream_GetRemainingLength(irp->input) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 12)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, Length); Stream_Read_UINT64(irp->input, Offset); @@ -208,7 +208,7 @@ static UINT parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) UINT64 Offset; ssize_t status; void* ptr; - if (Stream_GetRemainingLength(irp->input) > 12) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 12)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, Length); diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index 1d76f1f47..8f3cb77ba 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -481,7 +481,7 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) UINT error = CHANNEL_RC_OK; void* ptr; - if (Stream_GetRemainingLength(irp->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 32)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, Length); Stream_Read_UINT64(irp->input, Offset); @@ -650,7 +650,7 @@ static UINT printer_custom_component(DEVICE* device, UINT16 component, UINT16 pa if (component != RDPDR_CTYP_PRN) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, eventID); @@ -667,7 +667,7 @@ static UINT printer_custom_component(DEVICE* device, UINT16 component, UINT16 pa const WCHAR *PnPName, *DriverName, *PrinterName; const BYTE* CachedPrinterConfigData; - if (Stream_GetRemainingLength(s) < 24) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 24)) return ERROR_INVALID_DATA; Stream_Read(s, PortDosName, sizeof(PortDosName)); @@ -676,25 +676,25 @@ static UINT printer_custom_component(DEVICE* device, UINT16 component, UINT16 pa Stream_Read_UINT32(s, PrintNameLen); Stream_Read_UINT32(s, CacheFieldsLen); - if (Stream_GetRemainingLength(s) < PnPNameLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, PnPNameLen)) return ERROR_INVALID_DATA; PnPName = (const WCHAR*)Stream_Pointer(s); Stream_Seek(s, PnPNameLen); - if (Stream_GetRemainingLength(s) < DriverNameLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, DriverNameLen)) return ERROR_INVALID_DATA; DriverName = (const WCHAR*)Stream_Pointer(s); Stream_Seek(s, DriverNameLen); - if (Stream_GetRemainingLength(s) < PrintNameLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, PrintNameLen)) return ERROR_INVALID_DATA; PrinterName = (const WCHAR*)Stream_Pointer(s); Stream_Seek(s, PrintNameLen); - if (Stream_GetRemainingLength(s) < CacheFieldsLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, CacheFieldsLen)) return ERROR_INVALID_DATA; CachedPrinterConfigData = Stream_Pointer(s); @@ -714,19 +714,19 @@ static UINT printer_custom_component(DEVICE* device, UINT16 component, UINT16 pa const WCHAR* PrinterName; const BYTE* ConfigData; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, PrinterNameLen); Stream_Read_UINT32(s, ConfigDataLen); - if (Stream_GetRemainingLength(s) < PrinterNameLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, PrinterNameLen)) return ERROR_INVALID_DATA; PrinterName = (const WCHAR*)Stream_Pointer(s); Stream_Seek(s, PrinterNameLen); - if (Stream_GetRemainingLength(s) < ConfigDataLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, ConfigDataLen)) return ERROR_INVALID_DATA; ConfigData = Stream_Pointer(s); @@ -743,12 +743,12 @@ static UINT printer_custom_component(DEVICE* device, UINT16 component, UINT16 pa UINT32 PrinterNameLen; const WCHAR* PrinterName; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, PrinterNameLen); - if (Stream_GetRemainingLength(s) < PrinterNameLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, PrinterNameLen)) return ERROR_INVALID_DATA; PrinterName = (const WCHAR*)Stream_Pointer(s); @@ -763,19 +763,19 @@ static UINT printer_custom_component(DEVICE* device, UINT16 component, UINT16 pa const WCHAR* OldPrinterName; const WCHAR* NewPrinterName; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, OldPrinterNameLen); Stream_Read_UINT32(s, NewPrinterNameLen); - if (Stream_GetRemainingLength(s) < OldPrinterNameLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, OldPrinterNameLen)) return ERROR_INVALID_DATA; OldPrinterName = (const WCHAR*)Stream_Pointer(s); Stream_Seek(s, OldPrinterNameLen); - if (Stream_GetRemainingLength(s) < NewPrinterNameLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, NewPrinterNameLen)) return ERROR_INVALID_DATA; NewPrinterName = (const WCHAR*)Stream_Pointer(s); @@ -798,7 +798,7 @@ static UINT printer_custom_component(DEVICE* device, UINT16 component, UINT16 pa { UINT32 flags; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, flags); diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index 50a0cc834..f2eb95a09 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -61,11 +61,8 @@ static UINT rail_read_server_exec_result_order(wStream* s, RAIL_EXEC_RESULT_ORDE if (!s || !execResult) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < RAIL_EXEC_RESULT_ORDER_LENGTH) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_EXEC_RESULT_ORDER_LENGTH)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, execResult->flags); /* flags (2 bytes) */ Stream_Read_UINT16(s, execResult->execResult); /* execResult (2 bytes) */ @@ -86,11 +83,8 @@ static UINT rail_read_server_minmaxinfo_order(wStream* s, RAIL_MINMAXINFO_ORDER* if (!s || !minmaxinfo) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < RAIL_MINMAXINFO_ORDER_LENGTH) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_MINMAXINFO_ORDER_LENGTH)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, minmaxinfo->windowId); /* windowId (4 bytes) */ Stream_Read_INT16(s, minmaxinfo->maxWidth); /* maxWidth (2 bytes) */ @@ -117,11 +111,8 @@ static UINT rail_read_server_localmovesize_order(wStream* s, if (!s || !localMoveSize) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < RAIL_LOCALMOVESIZE_ORDER_LENGTH) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_LOCALMOVESIZE_ORDER_LENGTH)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, localMoveSize->windowId); /* windowId (4 bytes) */ Stream_Read_UINT16(s, isMoveSizeStart); /* isMoveSizeStart (2 bytes) */ @@ -143,11 +134,8 @@ static UINT rail_read_server_get_appid_resp_order(wStream* s, if (!s || !getAppidResp) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < RAIL_GET_APPID_RESP_ORDER_LENGTH) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_GET_APPID_RESP_ORDER_LENGTH)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, getAppidResp->windowId); /* windowId (4 bytes) */ Stream_Read_UTF16_String( @@ -166,11 +154,8 @@ static UINT rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* la if (!s || !langbarInfo) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < RAIL_LANGBAR_INFO_ORDER_LENGTH) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_LANGBAR_INFO_ORDER_LENGTH)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, langbarInfo->languageBarStatus); /* languageBarStatus (4 bytes) */ return CHANNEL_RC_OK; @@ -651,11 +636,8 @@ static UINT rail_read_taskbar_info_order(wStream* s, RAIL_TASKBAR_INFO_ORDER* ta if (!s || !taskbarInfo) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < RAIL_TASKBAR_INFO_ORDER_LENGTH) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_TASKBAR_INFO_ORDER_LENGTH)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, taskbarInfo->TaskbarMessage); Stream_Read_UINT32(s, taskbarInfo->WindowIdTab); @@ -699,11 +681,8 @@ static UINT rail_read_zorder_sync_order(wStream* s, RAIL_ZORDER_SYNC* zorder) if (!s || !zorder) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < RAIL_Z_ORDER_SYNC_ORDER_LENGTH) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_Z_ORDER_SYNC_ORDER_LENGTH)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, zorder->windowIdMarker); return CHANNEL_RC_OK; @@ -742,11 +721,8 @@ static UINT rail_read_cloak_order(wStream* s, RAIL_CLOAK* cloak) { BYTE cloaked; - if (Stream_GetRemainingLength(s) < RAIL_CLOAK_ORDER_LENGTH) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_CLOAK_ORDER_LENGTH)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, cloak->windowId); /* WindowId (4 bytes) */ Stream_Read_UINT8(s, cloaked); /* Cloaked (1 byte) */ @@ -792,11 +768,8 @@ static UINT rail_read_power_display_request_order(wStream* s, RAIL_POWER_DISPLAY if (!s || !power) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < RAIL_POWER_DISPLAY_REQUEST_ORDER_LENGTH) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_POWER_DISPLAY_REQUEST_ORDER_LENGTH)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, active); power->active = active != 0; @@ -840,11 +813,8 @@ static UINT rail_read_get_application_id_extended_response_order(wStream* s, if (!s || !id) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, id->windowID); @@ -854,11 +824,8 @@ static UINT rail_read_get_application_id_extended_response_order(wStream* s, if (_wcsnlen(id->applicationID, ARRAYSIZE(id->applicationID)) >= ARRAYSIZE(id->applicationID)) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, id->processId); diff --git a/channels/rail/rail_common.c b/channels/rail/rail_common.c index 2ce7c21da..bfacdd2d4 100644 --- a/channels/rail/rail_common.c +++ b/channels/rail/rail_common.c @@ -96,7 +96,7 @@ UINT rail_read_pdu_header(wStream* s, UINT16* orderType, UINT16* orderLength) if (!s || !orderType || !orderLength) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, *orderType); /* orderType (2 bytes) */ @@ -129,7 +129,7 @@ wStream* rail_pdu_init(size_t length) */ UINT rail_read_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ @@ -148,7 +148,7 @@ void rail_write_handshake_order(wStream* s, const RAIL_HANDSHAKE_ORDER* handshak */ UINT rail_read_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, handshakeEx->buildNumber); /* buildNumber (4 bytes) */ @@ -221,7 +221,7 @@ static UINT rail_read_high_contrast(wStream* s, RAIL_HIGH_CONTRAST* highContrast if (!s || !highContrast) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, highContrast->flags); /* flags (4 bytes) */ @@ -263,7 +263,7 @@ static UINT rail_read_filterkeys(wStream* s, TS_FILTERKEYS* filterKeys) if (!s || !filterKeys) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, filterKeys->Flags); @@ -308,11 +308,8 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex if (!s || !sysparam) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 5) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, sysparam->param); /* systemParam (4 bytes) */ @@ -348,11 +345,8 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex case SPI_SET_WORK_AREA: sysparam->params |= SPI_MASK_SET_WORK_AREA; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, sysparam->workArea.left); /* left (2 bytes) */ Stream_Read_UINT16(s, sysparam->workArea.top); /* top (2 bytes) */ @@ -363,11 +357,8 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex case SPI_DISPLAY_CHANGE: sysparam->params |= SPI_MASK_DISPLAY_CHANGE; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, sysparam->displayChange.left); /* left (2 bytes) */ Stream_Read_UINT16(s, sysparam->displayChange.top); /* top (2 bytes) */ @@ -378,11 +369,8 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex case SPI_TASKBAR_POS: sysparam->params |= SPI_MASK_TASKBAR_POS; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, sysparam->taskbarPos.left); /* left (2 bytes) */ Stream_Read_UINT16(s, sysparam->taskbarPos.top); /* top (2 bytes) */ @@ -392,11 +380,8 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex case SPI_SET_HIGH_CONTRAST: sysparam->params |= SPI_MASK_SET_HIGH_CONTRAST; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } error = rail_read_high_contrast(s, &sysparam->highContrast); break; @@ -407,11 +392,8 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex if (!extendedSpiSupported) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, sysparam->caretWidth); @@ -426,11 +408,8 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex if (!extendedSpiSupported) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, sysparam->stickyKeys); break; @@ -441,11 +420,8 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex if (!extendedSpiSupported) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, sysparam->toggleKeys); break; @@ -456,11 +432,8 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex if (!extendedSpiSupported) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 20) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return ERROR_INVALID_DATA; - } error = rail_read_filterkeys(s, &sysparam->filterKeys); break; diff --git a/channels/rail/server/rail_main.c b/channels/rail/server/rail_main.c index db389282c..6dec0b85a 100644 --- a/channels/rail/server/rail_main.c +++ b/channels/rail/server/rail_main.c @@ -636,7 +636,7 @@ static UINT rail_send_server_get_appid_resp_ex(RailServerContext* context, */ static UINT rail_read_client_status_order(wStream* s, RAIL_CLIENT_STATUS_ORDER* clientStatus) { - if (Stream_GetRemainingLength(s) < RAIL_CLIENT_STATUS_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_CLIENT_STATUS_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, clientStatus->flags); /* Flags (4 bytes) */ @@ -653,7 +653,7 @@ static UINT rail_read_exec_order(wStream* s, RAIL_EXEC_ORDER* exec) RAIL_EXEC_ORDER order = { 0 }; UINT16 exeLen, workLen, argLen; - if (Stream_GetRemainingLength(s) < RAIL_EXEC_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_EXEC_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, exec->flags); /* Flags (2 bytes) */ @@ -661,7 +661,7 @@ static UINT rail_read_exec_order(wStream* s, RAIL_EXEC_ORDER* exec) Stream_Read_UINT16(s, workLen); /* WorkingDirLength (2 bytes) */ Stream_Read_UINT16(s, argLen); /* ArgumentsLength (2 bytes) */ - if (Stream_GetRemainingLength(s) < (size_t)exeLen + workLen + argLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)exeLen + workLen + argLen)) return ERROR_INVALID_DATA; { @@ -714,7 +714,7 @@ static UINT rail_read_activate_order(wStream* s, RAIL_ACTIVATE_ORDER* activate) { BYTE enabled; - if (Stream_GetRemainingLength(s) < RAIL_ACTIVATE_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_ACTIVATE_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, activate->windowId); /* WindowId (4 bytes) */ @@ -730,7 +730,7 @@ static UINT rail_read_activate_order(wStream* s, RAIL_ACTIVATE_ORDER* activate) */ static UINT rail_read_sysmenu_order(wStream* s, RAIL_SYSMENU_ORDER* sysmenu) { - if (Stream_GetRemainingLength(s) < RAIL_SYSMENU_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_SYSMENU_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, sysmenu->windowId); /* WindowId (4 bytes) */ @@ -746,7 +746,7 @@ static UINT rail_read_sysmenu_order(wStream* s, RAIL_SYSMENU_ORDER* sysmenu) */ static UINT rail_read_syscommand_order(wStream* s, RAIL_SYSCOMMAND_ORDER* syscommand) { - if (Stream_GetRemainingLength(s) < RAIL_SYSCOMMAND_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_SYSCOMMAND_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, syscommand->windowId); /* WindowId (4 bytes) */ @@ -761,7 +761,7 @@ static UINT rail_read_syscommand_order(wStream* s, RAIL_SYSCOMMAND_ORDER* syscom */ static UINT rail_read_notify_event_order(wStream* s, RAIL_NOTIFY_EVENT_ORDER* notifyEvent) { - if (Stream_GetRemainingLength(s) < RAIL_NOTIFY_EVENT_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_NOTIFY_EVENT_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, notifyEvent->windowId); /* WindowId (4 bytes) */ @@ -777,7 +777,7 @@ static UINT rail_read_notify_event_order(wStream* s, RAIL_NOTIFY_EVENT_ORDER* no */ static UINT rail_read_get_appid_req_order(wStream* s, RAIL_GET_APPID_REQ_ORDER* getAppidReq) { - if (Stream_GetRemainingLength(s) < RAIL_GET_APPID_REQ_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_GET_APPID_REQ_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, getAppidReq->windowId); /* WindowId (4 bytes) */ @@ -791,7 +791,7 @@ static UINT rail_read_get_appid_req_order(wStream* s, RAIL_GET_APPID_REQ_ORDER* */ static UINT rail_read_window_move_order(wStream* s, RAIL_WINDOW_MOVE_ORDER* windowMove) { - if (Stream_GetRemainingLength(s) < RAIL_WINDOW_MOVE_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_WINDOW_MOVE_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, windowMove->windowId); /* WindowId (4 bytes) */ @@ -809,7 +809,7 @@ static UINT rail_read_window_move_order(wStream* s, RAIL_WINDOW_MOVE_ORDER* wind */ static UINT rail_read_snap_arange_order(wStream* s, RAIL_SNAP_ARRANGE* snapArrange) { - if (Stream_GetRemainingLength(s) < RAIL_SNAP_ARRANGE_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_SNAP_ARRANGE_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, snapArrange->windowId); /* WindowId (4 bytes) */ @@ -827,7 +827,7 @@ static UINT rail_read_snap_arange_order(wStream* s, RAIL_SNAP_ARRANGE* snapArran */ static UINT rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbarInfo) { - if (Stream_GetRemainingLength(s) < RAIL_LANGBAR_INFO_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_LANGBAR_INFO_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, langbarInfo->languageBarStatus); /* LanguageBarStatus (4 bytes) */ @@ -842,7 +842,7 @@ static UINT rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* la static UINT rail_read_language_ime_info_order(wStream* s, RAIL_LANGUAGEIME_INFO_ORDER* languageImeInfo) { - if (Stream_GetRemainingLength(s) < RAIL_LANGUAGEIME_INFO_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_LANGUAGEIME_INFO_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, languageImeInfo->ProfileType); /* ProfileType (4 bytes) */ @@ -864,7 +864,7 @@ static UINT rail_read_language_ime_info_order(wStream* s, static UINT rail_read_compartment_info_order(wStream* s, RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo) { - if (Stream_GetRemainingLength(s) < RAIL_COMPARTMENT_INFO_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_COMPARTMENT_INFO_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, compartmentInfo->ImeState); /* ImeState (4 bytes) */ @@ -883,7 +883,7 @@ static UINT rail_read_cloak_order(wStream* s, RAIL_CLOAK* cloak) { BYTE cloaked; - if (Stream_GetRemainingLength(s) < RAIL_CLOAK_ORDER_LENGTH) + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_CLOAK_ORDER_LENGTH)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, cloak->windowId); /* WindowId (4 bytes) */ diff --git a/channels/rdpdr/client/irp.c b/channels/rdpdr/client/irp.c index cc4af361d..ce45ff5b9 100644 --- a/channels/rdpdr/client/irp.c +++ b/channels/rdpdr/client/irp.c @@ -83,7 +83,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error) DEVICE* device; UINT32 DeviceId; - if (Stream_GetRemainingLength(s) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) { if (error) *error = ERROR_INVALID_DATA; diff --git a/channels/rdpdr/client/rdpdr_capabilities.c b/channels/rdpdr/client/rdpdr_capabilities.c index 4c45a8a54..6c93cd81e 100644 --- a/channels/rdpdr/client/rdpdr_capabilities.c +++ b/channels/rdpdr/client/rdpdr_capabilities.c @@ -67,7 +67,7 @@ static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s) UINT16 capabilityLength; WINPR_UNUSED(rdpdr); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilityLength); @@ -75,7 +75,7 @@ static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s) if (capabilityLength < 4) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < capabilityLength - 4U) + if (!Stream_CheckAndLogRequiredLength(TAG, s, capabilityLength - 4U)) return ERROR_INVALID_DATA; Stream_Seek(s, capabilityLength - 4U); @@ -95,7 +95,7 @@ static UINT rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s) UINT16 capabilityLength; WINPR_UNUSED(rdpdr); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilityLength); @@ -103,7 +103,7 @@ static UINT rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s) if (capabilityLength < 4) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < capabilityLength - 4U) + if (!Stream_CheckAndLogRequiredLength(TAG, s, capabilityLength - 4U)) return ERROR_INVALID_DATA; Stream_Seek(s, capabilityLength - 4U); @@ -123,7 +123,7 @@ static UINT rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s) UINT16 capabilityLength; WINPR_UNUSED(rdpdr); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilityLength); @@ -131,7 +131,7 @@ static UINT rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s) if (capabilityLength < 4U) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < capabilityLength - 4U) + if (!Stream_CheckAndLogRequiredLength(TAG, s, capabilityLength - 4U)) return ERROR_INVALID_DATA; Stream_Seek(s, capabilityLength - 4U); @@ -151,7 +151,7 @@ static UINT rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s) UINT16 capabilityLength; WINPR_UNUSED(rdpdr); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilityLength); @@ -159,7 +159,7 @@ static UINT rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s) if (capabilityLength < 4) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < capabilityLength - 4U) + if (!Stream_CheckAndLogRequiredLength(TAG, s, capabilityLength - 4U)) return ERROR_INVALID_DATA; Stream_Seek(s, capabilityLength - 4U); @@ -179,7 +179,7 @@ static UINT rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s) UINT16 capabilityLength; WINPR_UNUSED(rdpdr); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilityLength); @@ -187,7 +187,7 @@ static UINT rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s) if (capabilityLength < 4) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < capabilityLength - 4U) + if (!Stream_CheckAndLogRequiredLength(TAG, s, capabilityLength - 4U)) return ERROR_INVALID_DATA; Stream_Seek(s, capabilityLength - 4U); @@ -204,7 +204,7 @@ UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s) if (!rdpdr || !s) return CHANNEL_RC_NULL_DATA; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, numCapabilities); @@ -212,7 +212,7 @@ UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s) for (i = 0; i < numCapabilities; i++) { - if (Stream_GetRemainingLength(s) < sizeof(UINT16)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(UINT16))) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilityType); diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index fab04b9a9..6ff242cc7 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -1122,7 +1122,7 @@ static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s WINPR_ASSERT(rdpdr); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, rdpdr->versionMajor); @@ -1209,7 +1209,7 @@ static UINT rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s WINPR_ASSERT(rdpdr); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, versionMajor); diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index 8e35100be..2c732dd91 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -119,11 +119,8 @@ static UINT rdpdr_server_receive_announce_response(RdpdrServerContext* context, WINPR_UNUSED(header); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, VersionMajor); /* VersionMajor (2 bytes) */ Stream_Read_UINT16(s, VersionMinor); /* VersionMinor (2 bytes) */ @@ -149,11 +146,8 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context WINPR_UNUSED(header); - if (Stream_GetRemainingLength(s) < 12) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, UnicodeFlag); /* UnicodeFlag (4 bytes) */ Stream_Seek_UINT32(s); /* CodePage (4 bytes), MUST be set to zero */ @@ -184,11 +178,8 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context } } - if (Stream_GetRemainingLength(s) < ComputerNameLen) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, ComputerNameLen)) return ERROR_INVALID_DATA; - } /* ComputerName must be null terminated, check if it really is */ @@ -237,11 +228,8 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context */ static UINT rdpdr_server_read_capability_set_header(wStream* s, RDPDR_CAPABILITY_HEADER* header) { - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, header->CapabilityType); /* CapabilityType (2 bytes) */ Stream_Read_UINT16(s, header->CapabilityLength); /* CapabilityLength (2 bytes) */ @@ -283,11 +271,8 @@ static UINT rdpdr_server_read_general_capability_set(RdpdrServerContext* context UINT16 VersionMinor; UINT32 SpecialTypeDeviceCap; - if (Stream_GetRemainingLength(s) < 32) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 32)) return ERROR_INVALID_DATA; - } Stream_Seek_UINT32(s); /* osType (4 bytes), ignored on receipt */ Stream_Seek_UINT32(s); /* osVersion (4 bytes), unused and must be set to zero */ @@ -325,11 +310,8 @@ static UINT rdpdr_server_read_general_capability_set(RdpdrServerContext* context if (header->Version == GENERAL_CAPABILITY_VERSION_02) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */ } @@ -666,11 +648,8 @@ static UINT rdpdr_server_receive_core_capability_response(RdpdrServerContext* co WINPR_UNUSED(header); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, numCapabilities); /* numCapabilities (2 bytes) */ Stream_Seek_UINT16(s); /* Padding (2 bytes) */ @@ -805,11 +784,8 @@ static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext WINPR_UNUSED(header); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */ WLog_DBG(TAG, "DeviceCount: %" PRIu32 "", DeviceCount); @@ -818,22 +794,16 @@ static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext { ZeroMemory(PreferredDosName, sizeof(PreferredDosName)); - if (Stream_GetRemainingLength(s) < 20) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, DeviceType); /* DeviceType (4 bytes) */ Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */ Stream_Read(s, PreferredDosName, 8); /* PreferredDosName (8 bytes) */ Stream_Read_UINT32(s, DeviceDataLength); /* DeviceDataLength (4 bytes) */ - if (Stream_GetRemainingLength(s) < DeviceDataLength) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, DeviceDataLength)) return ERROR_INVALID_DATA; - } WLog_DBG(TAG, "Device %d Name: %s Id: 0x%08" PRIX32 " DataLength: %" PRIu32 "", i, PreferredDosName, DeviceId, DeviceDataLength); @@ -898,22 +868,16 @@ static UINT rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* WINPR_UNUSED(header); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */ WLog_DBG(TAG, "DeviceCount: %" PRIu32 "", DeviceCount); for (i = 0; i < DeviceCount; i++) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */ WLog_DBG(TAG, "Device %d Id: 0x%08" PRIX32 "", i, DeviceId); @@ -978,11 +942,8 @@ static UINT rdpdr_server_receive_device_io_completion(RdpdrServerContext* contex WINPR_UNUSED(header); - if (Stream_GetRemainingLength(s) < 12) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, deviceId); Stream_Read_UINT32(s, completionId); @@ -1375,11 +1336,8 @@ static UINT rdpdr_server_read_file_directory_information(wStream* s, UINT32 fileNameLength; ZeroMemory(fdi, sizeof(FILE_DIRECTORY_INFORMATION)); - if (Stream_GetRemainingLength(s) < 64) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 64)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, fdi->NextEntryOffset); /* NextEntryOffset (4 bytes) */ Stream_Read_UINT32(s, fdi->FileIndex); /* FileIndex (4 bytes) */ @@ -1392,11 +1350,8 @@ static UINT rdpdr_server_read_file_directory_information(wStream* s, Stream_Read_UINT32(s, fdi->FileAttributes); /* FileAttributes (4 bytes) */ Stream_Read_UINT32(s, fileNameLength); /* FileNameLength (4 bytes) */ - if (Stream_GetRemainingLength(s) < fileNameLength) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, fileNameLength)) return ERROR_INVALID_DATA; - } WINPR_ASSERT(fileNameLength / 2U <= INT_MAX); WINPR_ASSERT(sizeof(fdi->FileName) < INT_MAX); @@ -1697,11 +1652,8 @@ static UINT rdpdr_server_drive_create_directory_callback1(RdpdrServerContext* co return CHANNEL_RC_OK; } - if (Stream_GetRemainingLength(s) < 5) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ @@ -1810,11 +1762,8 @@ static UINT rdpdr_server_drive_delete_directory_callback1(RdpdrServerContext* co return CHANNEL_RC_OK; } - if (Stream_GetRemainingLength(s) < 5) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ @@ -1893,11 +1842,8 @@ static UINT rdpdr_server_drive_query_directory_callback2(RdpdrServerContext* con ", ioStatus=0x%" PRIx32 "", deviceId, completionId, ioStatus); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, length); /* Length (4 bytes) */ @@ -1913,11 +1859,8 @@ static UINT rdpdr_server_drive_query_directory_callback2(RdpdrServerContext* con } else { - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return ERROR_INVALID_DATA; - } Stream_Seek(s, 1); /* Padding (1 byte) */ } @@ -1977,11 +1920,8 @@ static UINT rdpdr_server_drive_query_directory_callback1(RdpdrServerContext* con return CHANNEL_RC_OK; } - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, fileId); /* Setup the IRP. */ @@ -2060,11 +2000,8 @@ static UINT rdpdr_server_drive_open_file_callback(RdpdrServerContext* context, w ", ioStatus=0x%" PRIx32 "", deviceId, completionId, ioStatus); - if (Stream_GetRemainingLength(s) < 5) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ @@ -2133,19 +2070,13 @@ static UINT rdpdr_server_drive_read_file_callback(RdpdrServerContext* context, w ", ioStatus=0x%" PRIx32 "", deviceId, completionId, ioStatus); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, length); /* Length (4 bytes) */ - if (Stream_GetRemainingLength(s) < length) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return ERROR_INVALID_DATA; - } if (length > 0) { @@ -2215,20 +2146,14 @@ static UINT rdpdr_server_drive_write_file_callback(RdpdrServerContext* context, ", ioStatus=0x%" PRIx32 "", deviceId, completionId, ioStatus); - if (Stream_GetRemainingLength(s) < 5) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, length); /* Length (4 bytes) */ Stream_Seek(s, 1); /* Padding (1 byte) */ - if (Stream_GetRemainingLength(s) < length) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return ERROR_INVALID_DATA; - } /* Invoke the write file completion routine. */ context->OnDriveWriteFileComplete(context, irp->CallbackData, ioStatus, length); @@ -2384,11 +2309,8 @@ static UINT rdpdr_server_drive_delete_file_callback1(RdpdrServerContext* context return CHANNEL_RC_OK; } - if (Stream_GetRemainingLength(s) < 5) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ @@ -2486,11 +2408,8 @@ static UINT rdpdr_server_drive_rename_file_callback2(RdpdrServerContext* context ", ioStatus=0x%" PRIx32 "", deviceId, completionId, ioStatus); - if (Stream_GetRemainingLength(s) < 5) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, length); /* Length (4 bytes) */ Stream_Seek(s, 1); /* Padding (1 byte) */ @@ -2538,11 +2457,8 @@ static UINT rdpdr_server_drive_rename_file_callback1(RdpdrServerContext* context return CHANNEL_RC_OK; } - if (Stream_GetRemainingLength(s) < 5) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index f25cfa3f3..36c1c6027 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -725,18 +725,17 @@ static UINT rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s rdpei = (RDPEI_PLUGIN*)callback->plugin; - size = Stream_GetRemainingLength(s); - if (size < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, protocolVersion); /* protocolVersion (4 bytes) */ if (protocolVersion >= RDPINPUT_PROTOCOL_V300) { - if (size < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; } - if (size >= 9) + if (Stream_GetRemainingLength(s) >= 4) Stream_Read_UINT32(s, features); if (rdpei->version > protocolVersion) @@ -815,7 +814,7 @@ static UINT rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) UINT error; if (!s) return ERROR_INTERNAL_ERROR; - if (Stream_GetRemainingLength(s) < 6) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, eventId); /* eventId (2 bytes) */ diff --git a/channels/rdpei/rdpei_common.c b/channels/rdpei/rdpei_common.c index 5345fc90f..c4a388c91 100644 --- a/channels/rdpei/rdpei_common.c +++ b/channels/rdpei/rdpei_common.c @@ -25,18 +25,22 @@ #include "rdpei_common.h" +#include + +#define TAG FREERDP_TAG("channels.rdpei.common") + BOOL rdpei_read_2byte_unsigned(wStream* s, UINT16* value) { BYTE byte; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); if (byte & 0x80) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; *value = (byte & 0x7F) << 8; @@ -82,7 +86,7 @@ BOOL rdpei_read_2byte_signed(wStream* s, INT16* value) BYTE byte; BOOL negative; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -93,7 +97,7 @@ BOOL rdpei_read_2byte_signed(wStream* s, INT16* value) if (byte & 0x80) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -152,14 +156,14 @@ BOOL rdpei_read_4byte_unsigned(wStream* s, UINT32* value) BYTE byte; BYTE count; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); count = (byte & 0xC0) >> 6; - if (Stream_GetRemainingLength(s) < count) + if (!Stream_CheckAndLogRequiredLength(TAG, s, count)) return FALSE; switch (count) @@ -251,7 +255,7 @@ BOOL rdpei_read_4byte_signed(wStream* s, INT32* value) BYTE count; BOOL negative; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -259,7 +263,7 @@ BOOL rdpei_read_4byte_signed(wStream* s, INT32* value) count = (byte & 0xC0) >> 6; negative = (byte & 0x20); - if (Stream_GetRemainingLength(s) < count) + if (!Stream_CheckAndLogRequiredLength(TAG, s, count)) return FALSE; switch (count) @@ -377,14 +381,14 @@ BOOL rdpei_read_8byte_unsigned(wStream* s, UINT64* value) UINT64 byte; BYTE count; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); count = (byte & 0xE0) >> 5; - if (Stream_GetRemainingLength(s) < count) + if (!Stream_CheckAndLogRequiredLength(TAG, s, count)) return FALSE; switch (count) diff --git a/channels/rdpei/server/rdpei_main.c b/channels/rdpei/server/rdpei_main.c index 16c555d69..ba1490dd8 100644 --- a/channels/rdpei/server/rdpei_main.c +++ b/channels/rdpei/server/rdpei_main.c @@ -168,11 +168,8 @@ HANDLE rdpei_server_get_event_handle(RdpeiServerContext* context) static UINT read_cs_ready_message(RdpeiServerContext* context, wStream* s) { UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 10) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 10)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, context->protocolFlags); Stream_Read_UINT32(s, context->clientVersion); @@ -206,11 +203,8 @@ static UINT read_touch_contact_data(RdpeiServerContext* context, wStream* s, RDPINPUT_CONTACT_DATA* contactData) { WINPR_UNUSED(context); - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return ERROR_INVALID_DATA; - } Stream_Read_UINT8(s, contactData->contactId); if (!rdpei_read_2byte_unsigned(s, &contactData->fieldsPresent) || @@ -255,11 +249,8 @@ static UINT read_pen_contact(RdpeiServerContext* context, wStream* s, RDPINPUT_PEN_CONTACT* contactData) { WINPR_UNUSED(context); - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return ERROR_INVALID_DATA; - } Stream_Read_UINT8(s, contactData->deviceId); if (!rdpei_read_2byte_unsigned(s, &contactData->fieldsPresent) || @@ -470,11 +461,8 @@ static UINT read_dismiss_hovering_contact(RdpeiServerContext* context, wStream* BYTE contactId; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return ERROR_INVALID_DATA; - } Stream_Read_UINT8(s, contactId); diff --git a/channels/rdpgfx/client/rdpgfx_codec.c b/channels/rdpgfx/client/rdpgfx_codec.c index 5bfa38503..28976b65d 100644 --- a/channels/rdpgfx/client/rdpgfx_codec.c +++ b/channels/rdpgfx/client/rdpgfx_codec.c @@ -46,19 +46,13 @@ static UINT rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H2 meta->regionRects = NULL; meta->quantQualityVals = NULL; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) goto error_out; - } Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */ - if (Stream_GetRemainingLength(s) / 8 < meta->numRegionRects) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ull * meta->numRegionRects)) goto error_out; - } meta->regionRects = (RECTANGLE_16*)calloc(meta->numRegionRects, sizeof(RECTANGLE_16)); @@ -97,9 +91,8 @@ static UINT rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H2 index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom); } - if (Stream_GetRemainingLength(s) / 2 < meta->numRegionRects) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2ull * meta->numRegionRects)) { - WLog_ERR(TAG, "not enough data!"); error = ERROR_INVALID_DATA; goto error_out; } @@ -189,7 +182,7 @@ static UINT rdpgfx_decode_AVC444(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd return CHANNEL_RC_NO_MEMORY; } - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) { error = ERROR_INVALID_DATA; goto fail; @@ -220,7 +213,7 @@ static UINT rdpgfx_decode_AVC444(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd { tmp = h264.cbAvc420EncodedBitstream1 - pos2 + pos1; - if (Stream_GetRemainingLength(s) < tmp) + if (!Stream_CheckAndLogRequiredLength(TAG, s, tmp)) { error = ERROR_INVALID_DATA; goto fail; diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index 52e49eb32..28db70fc2 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -339,11 +339,8 @@ static UINT rdpgfx_recv_caps_confirm_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStr RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; pdu.capsSet = &capsSet; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, capsSet.version); /* version (4 bytes) */ Stream_Read_UINT32(s, capsSet.length); /* capsDataLength (4 bytes) */ @@ -550,21 +547,15 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS UINT error = CHANNEL_RC_OK; GraphicsResetEventArgs graphicsReset; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.width); /* width (4 bytes) */ Stream_Read_UINT32(s, pdu.height); /* height (4 bytes) */ Stream_Read_UINT32(s, pdu.monitorCount); /* monitorCount (4 bytes) */ - if (Stream_GetRemainingLength(s) / 20 < pdu.monitorCount) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20ull * pdu.monitorCount)) return ERROR_INVALID_DATA; - } pdu.monitorDefArray = (MONITOR_DEF*)calloc(pdu.monitorCount, sizeof(MONITOR_DEF)); @@ -586,9 +577,8 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS pad = 340 - (RDPGFX_HEADER_SIZE + 12 + (pdu.monitorCount * 20)); - if (Stream_GetRemainingLength(s) < (size_t)pad) + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)pad)) { - WLog_Print(gfx->log, WLOG_ERROR, "Stream_GetRemainingLength failed!"); free(pdu.monitorDefArray); return CHANNEL_RC_NO_MEMORY; } @@ -637,11 +627,8 @@ static UINT rdpgfx_recv_evict_cache_entry_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */ WLog_Print(gfx->log, WLOG_DEBUG, "RecvEvictCacheEntryPdu: cacheSlot: %" PRIu16 "", @@ -672,19 +659,13 @@ static UINT rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.importedEntriesCount); /* cacheSlot (2 bytes) */ - if (Stream_GetRemainingLength(s) / 2 < pdu.importedEntriesCount) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2ull * pdu.importedEntriesCount)) return ERROR_INVALID_DATA; - } pdu.cacheSlots = (UINT16*)calloc(pdu.importedEntriesCount, sizeof(UINT16)); @@ -727,11 +708,8 @@ static UINT rdpgfx_recv_create_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 7) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 7)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.width); /* width (2 bytes) */ @@ -766,11 +744,8 @@ static UINT rdpgfx_recv_delete_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ DEBUG_RDPGFX(gfx->log, "RecvDeleteSurfacePdu: surfaceId: %" PRIu16 "", pdu.surfaceId); @@ -799,11 +774,8 @@ static UINT rdpgfx_recv_start_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStre RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < RDPGFX_START_FRAME_PDU_SIZE) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RDPGFX_START_FRAME_PDU_SIZE)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */ Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ @@ -837,11 +809,8 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < RDPGFX_END_FRAME_PDU_SIZE) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RDPGFX_END_FRAME_PDU_SIZE)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ DEBUG_RDPGFX(gfx->log, "RecvEndFramePdu: frameId: %" PRIu32 "", pdu.frameId); @@ -934,11 +903,8 @@ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*)callback->plugin; UINT error; - if (Stream_GetRemainingLength(s) < RDPGFX_WIRE_TO_SURFACE_PDU_1_SIZE) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RDPGFX_WIRE_TO_SURFACE_PDU_1_SIZE)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ @@ -952,11 +918,8 @@ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ - if (pdu.bitmapDataLength > Stream_GetRemainingLength(s)) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, pdu.bitmapDataLength)) return ERROR_INVALID_DATA; - } pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); @@ -1029,11 +992,8 @@ static UINT rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < RDPGFX_WIRE_TO_SURFACE_PDU_2_SIZE) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, RDPGFX_WIRE_TO_SURFACE_PDU_2_SIZE)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ @@ -1101,11 +1061,8 @@ static UINT rdpgfx_recv_delete_encoding_context_pdu(RDPGFX_CHANNEL_CALLBACK* cal RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 6) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT32(s, pdu.codecContextId); /* codecContextId (4 bytes) */ @@ -1140,11 +1097,8 @@ static UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStrea RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ @@ -1157,11 +1111,8 @@ static UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStrea Stream_Read_UINT16(s, pdu.fillRectCount); /* fillRectCount (2 bytes) */ - if (Stream_GetRemainingLength(s) / 8 < pdu.fillRectCount) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ull * pdu.fillRectCount)) return ERROR_INVALID_DATA; - } pdu.fillRects = (RECTANGLE_16*)calloc(pdu.fillRectCount, sizeof(RECTANGLE_16)); @@ -1213,11 +1164,8 @@ static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error; - if (Stream_GetRemainingLength(s) < 14) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 14)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceIdSrc); /* surfaceIdSrc (2 bytes) */ Stream_Read_UINT16(s, pdu.surfaceIdDest); /* surfaceIdDest (2 bytes) */ @@ -1231,11 +1179,8 @@ static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ - if (Stream_GetRemainingLength(s) / 4ULL < pdu.destPtsCount) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4ULL * pdu.destPtsCount)) return ERROR_INVALID_DATA; - } pdu.destPts = (RDPGFX_POINT16*)calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); @@ -1290,11 +1235,8 @@ static UINT rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error; - if (Stream_GetRemainingLength(s) < 20) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT64(s, pdu.cacheKey); /* cacheKey (8 bytes) */ @@ -1340,21 +1282,15 @@ static UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 6) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */ Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ - if (Stream_GetRemainingLength(s) / 4 < pdu.destPtsCount) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4ull * pdu.destPtsCount)) return ERROR_INVALID_DATA; - } pdu.destPts = (RDPGFX_POINT16*)calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); @@ -1407,11 +1343,8 @@ static UINT rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK* callb RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.reserved); /* reserved (2 bytes) */ @@ -1442,11 +1375,8 @@ static UINT rdpgfx_recv_map_surface_to_scaled_output_pdu(RDPGFX_CHANNEL_CALLBACK RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 20) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.reserved); /* reserved (2 bytes) */ @@ -1484,11 +1414,8 @@ static UINT rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callb RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 18) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 18)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT64(s, pdu.windowId); /* windowId (8 bytes) */ @@ -1519,11 +1446,8 @@ static UINT rdpgfx_recv_map_surface_to_scaled_window_pdu(RDPGFX_CHANNEL_CALLBACK RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 26) - { - WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 26)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT64(s, pdu.windowId); /* windowId (8 bytes) */ diff --git a/channels/rdpgfx/rdpgfx_common.c b/channels/rdpgfx/rdpgfx_common.c index 1b0fdaee9..7da26a45a 100644 --- a/channels/rdpgfx/rdpgfx_common.c +++ b/channels/rdpgfx/rdpgfx_common.c @@ -112,21 +112,20 @@ UINT rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header) WINPR_ASSERT(s); WINPR_ASSERT(header); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "calloc failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return CHANNEL_RC_NO_MEMORY; - } Stream_Read_UINT16(s, header->cmdId); /* cmdId (2 bytes) */ Stream_Read_UINT16(s, header->flags); /* flags (2 bytes) */ Stream_Read_UINT32(s, header->pduLength); /* pduLength (4 bytes) */ - if ((header->pduLength < 8) || (Stream_GetRemainingLength(s) < (header->pduLength - 8))) + if (header->pduLength < 8) { WLog_ERR(TAG, "header->pduLength %u less than 8!", header->pduLength); return ERROR_INVALID_DATA; } + if (!Stream_CheckAndLogRequiredLength(TAG, s, (header->pduLength - 8))) + return ERROR_INVALID_DATA; return CHANNEL_RC_OK; } @@ -159,11 +158,8 @@ UINT rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16) WINPR_ASSERT(s); WINPR_ASSERT(pt16); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pt16->x); /* x (2 bytes) */ Stream_Read_UINT16(s, pt16->y); /* y (2 bytes) */ @@ -198,11 +194,8 @@ UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16) WINPR_ASSERT(s); WINPR_ASSERT(rect16); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, rect16->left); /* left (2 bytes) */ Stream_Read_UINT16(s, rect16->top); /* top (2 bytes) */ @@ -245,11 +238,8 @@ UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32) WINPR_ASSERT(s); WINPR_ASSERT(color32); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT8(s, color32->B); /* B (1 byte) */ Stream_Read_UINT8(s, color32->G); /* G (1 byte) */ diff --git a/channels/rdpgfx/server/rdpgfx_main.c b/channels/rdpgfx/server/rdpgfx_main.c index d590e49ec..2e9ede26f 100644 --- a/channels/rdpgfx/server/rdpgfx_main.c +++ b/channels/rdpgfx/server/rdpgfx_main.c @@ -1098,11 +1098,8 @@ static UINT rdpgfx_recv_frame_acknowledge_pdu(RdpgfxServerContext* context, wStr RDPGFX_FRAME_ACKNOWLEDGE_PDU pdu; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.queueDepth); /* queueDepth (4 bytes) */ Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ @@ -1131,11 +1128,8 @@ static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wSt RDPGFX_CACHE_ENTRY_METADATA* cacheEntries; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; - } /* cacheEntriesCount (2 bytes) */ Stream_Read_UINT16(s, pdu.cacheEntriesCount); @@ -1147,11 +1141,8 @@ static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wSt return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) / 12 < pdu.cacheEntriesCount) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12ull * pdu.cacheEntriesCount)) return ERROR_INVALID_DATA; - } if (pdu.cacheEntriesCount > 0) { @@ -1199,11 +1190,8 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream if (!context) return ERROR_BAD_ARGUMENTS; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */ if (pdu.capsSetCount > 0) @@ -1219,7 +1207,7 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream { RDPGFX_CAPSET* capsSet = &(pdu.capsSets[index]); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) goto fail; Stream_Read_UINT32(s, capsSet->version); /* version (4 bytes) */ @@ -1227,7 +1215,7 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream if (capsSet->length >= 4) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) goto fail; Stream_Peek_UINT32(s, capsSet->flags); /* capsData (4 bytes) */ @@ -1258,11 +1246,8 @@ static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context, RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU pdu; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_ERR(TAG, "not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */ diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 81870d758..42eeb96c0 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -276,7 +276,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* rdpsnd->NumberOfServerFormats = 0; rdpsnd->ServerFormats = NULL; - if (Stream_GetRemainingLength(s) < 30) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 30)) return ERROR_BAD_LENGTH; /* http://msdn.microsoft.com/en-us/library/cc240956.aspx */ @@ -290,7 +290,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* Stream_Seek_UINT8(s); /* bPad */ rdpsnd->NumberOfServerFormats = wNumberOfFormats; - if (Stream_GetRemainingLength(s) / 14 < wNumberOfFormats) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 14ull * wNumberOfFormats)) return ERROR_BAD_LENGTH; rdpsnd->ServerFormats = audio_formats_new(wNumberOfFormats); @@ -366,7 +366,7 @@ static UINT rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s) WINPR_ASSERT(rdpsnd); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_BAD_LENGTH; Stream_Read_UINT16(s, wTimeStamp); @@ -441,7 +441,7 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B WINPR_ASSERT(rdpsnd); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_BAD_LENGTH; rdpsnd->wArrivalTime = GetTickCount64(); @@ -591,7 +591,7 @@ static UINT rdpsnd_treat_wave(rdpsndPlugin* rdpsnd, wStream* s, size_t size) UINT64 diffMS, ts; UINT latency = 0; - if (Stream_GetRemainingLength(s) < size) + if (!Stream_CheckAndLogRequiredLength(TAG, s, size)) return ERROR_BAD_LENGTH; if (rdpsnd->wCurrentFormatNo >= rdpsnd->NumberOfClientFormats) @@ -651,7 +651,7 @@ static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) * to be filled with the first four bytes of the audio sample data sent as * part of the preceding Wave Info PDU. */ - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; CopyMemory(Stream_Buffer(s), rdpsnd->waveData, 4); @@ -664,7 +664,7 @@ static UINT rdpsnd_recv_wave2_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 BodyS AUDIO_FORMAT* format; UINT32 dwAudioTimeStamp; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_BAD_LENGTH; Stream_Read_UINT16(s, rdpsnd->wTimeStamp); @@ -710,7 +710,7 @@ static UINT rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s) BOOL rc = FALSE; UINT32 dwVolume; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_BAD_LENGTH; Stream_Read_UINT32(s, dwVolume); @@ -745,7 +745,7 @@ static UINT rdpsnd_recv_pdu(rdpsndPlugin* rdpsnd, wStream* s) goto out; } - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) { status = ERROR_BAD_LENGTH; goto out; diff --git a/channels/rdpsnd/server/rdpsnd_main.c b/channels/rdpsnd/server/rdpsnd_main.c index e06292969..a9d9aa1c1 100644 --- a/channels/rdpsnd/server/rdpsnd_main.c +++ b/channels/rdpsnd/server/rdpsnd_main.c @@ -91,11 +91,8 @@ static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, wStream BYTE confirmBlockNum; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, timestamp); Stream_Read_UINT8(s, confirmBlockNum); @@ -117,11 +114,8 @@ static UINT rdpsnd_server_recv_quality_mode(RdpsndServerContext* context, wStrea { UINT16 quality; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT16(s, quality); Stream_Seek_UINT16(s); // reserved @@ -142,11 +136,8 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) BYTE lastblock; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 20) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, flags); /* dwFlags */ Stream_Read_UINT32(s, vol); /* dwVolume */ @@ -158,11 +149,8 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) Stream_Seek_UINT8(s); /* bPad */ /* this check is only a guess as cbSize can influence the size of a format record */ - if (Stream_GetRemainingLength(s) / 18 < context->num_client_formats) - { - WLog_ERR(TAG, "not enough data in stream!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 18ull * context->num_client_formats)) return ERROR_INVALID_DATA; - } if (!context->num_client_formats) { @@ -180,7 +168,7 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) for (i = 0; i < context->num_client_formats; i++) { - if (Stream_GetRemainingLength(s) < 18) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 18)) { WLog_ERR(TAG, "not enough data in stream!"); error = ERROR_INVALID_DATA; diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c index e7a930fc2..facd3af6e 100644 --- a/channels/remdesk/client/remdesk_main.c +++ b/channels/remdesk/client/remdesk_main.c @@ -76,7 +76,7 @@ static UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) WINPR_ASSERT(remdesk); WINPR_ASSERT(remdesk->rdpcontext); - settings = remdesk->rdpcontext; + settings = remdesk->rdpcontext->settings; WINPR_ASSERT(settings); if (remdesk->ExpertBlob) @@ -142,11 +142,8 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head WINPR_ASSERT(s); WINPR_ASSERT(header); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */ Stream_Read_UINT32(s, header->DataLength); /* DataLen (4 bytes) */ @@ -163,11 +160,8 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) < ChannelNameLen) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, ChannelNameLen)) return ERROR_INVALID_DATA; - } ZeroMemory(header->ChannelName, sizeof(header->ChannelName)); pChannelName = (char*)header->ChannelName; @@ -272,11 +266,8 @@ static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s WINPR_ASSERT(s); WINPR_ASSERT(header); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */ Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */ @@ -341,11 +332,8 @@ static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, WINPR_ASSERT(header); WINPR_ASSERT(pResult); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, result); /* result (4 bytes) */ *pResult = result; @@ -380,7 +368,7 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) pdu.expertBlob = remdesk->ExpertBlob; WINPR_ASSERT(remdesk->rdpcontext); - settings = remdesk->rdpcontext; + settings = remdesk->rdpcontext->settings; WINPR_ASSERT(settings); pdu.raConnectionString = settings->RemoteAssistanceRCTicket; @@ -446,7 +434,7 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) WINPR_ASSERT(remdesk); WINPR_ASSERT(remdesk->rdpcontext); - settings = remdesk->rdpcontext; + settings = remdesk->rdpcontext->settings; WINPR_ASSERT(settings); pdu.raConnectionString = settings->RemoteAssistanceRCTicket; @@ -590,11 +578,8 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA WINPR_ASSERT(s); WINPR_ASSERT(header); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Not enough data!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, msgType); /* msgType (4 bytes) */ diff --git a/channels/remdesk/server/remdesk_main.c b/channels/remdesk/server/remdesk_main.c index c37e526c1..4a475faaf 100644 --- a/channels/remdesk/server/remdesk_main.c +++ b/channels/remdesk/server/remdesk_main.c @@ -52,11 +52,8 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head UINT32 ChannelNameLen; char* pChannelName = NULL; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return CHANNEL_RC_NO_MEMORY; - } Stream_Read_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */ Stream_Read_UINT32(s, header->DataLength); /* DataLen (4 bytes) */ @@ -73,11 +70,8 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) < ChannelNameLen) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, ChannelNameLen)) return ERROR_INVALID_DATA; - } ZeroMemory(header->ChannelName, sizeof(header->ChannelName)); pChannelName = (char*)header->ChannelName; @@ -251,12 +245,8 @@ static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wSt UINT32 versionMajor; UINT32 versionMinor; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "REMOTEDESKTOP_CTL_VERSIONINFO_PACKET missing data, got %" PRIuz, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */ Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */ @@ -410,11 +400,8 @@ static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, REMDESK_CTL_VERIFY_PASSWORD_PDU pdu; UINT error; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - } pdu.expertBlob = NULL; expertBlobW = (WCHAR*)Stream_Pointer(s); @@ -447,11 +434,8 @@ static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, UINT error = CHANNEL_RC_OK; UINT32 msgType = 0; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; - } Stream_Read_UINT32(s, msgType); /* msgType (4 bytes) */ WLog_INFO(TAG, "msgType: %" PRIu32 "", msgType); diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index 3d489e147..52cfa6782 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -126,7 +126,7 @@ static UINT serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) DWORD CreateDisposition; UINT32 PathLength; - if (Stream_GetRemainingLength(irp->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 32)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, DesiredAccess); /* DesiredAccess (4 bytes) */ @@ -202,7 +202,7 @@ error_handle: static UINT serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) { - if (Stream_GetRemainingLength(irp->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 32)) return ERROR_INVALID_DATA; Stream_Seek(irp->input, 32); /* Padding (32 bytes) */ @@ -236,7 +236,7 @@ static UINT serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp) BYTE* buffer = NULL; DWORD nbRead = 0; - if (Stream_GetRemainingLength(irp->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 32)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, Length); /* Length (4 bytes) */ @@ -297,7 +297,7 @@ static UINT serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp) void* ptr; DWORD nbWritten = 0; - if (Stream_GetRemainingLength(irp->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 32)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, Length); /* Length (4 bytes) */ @@ -351,7 +351,7 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) BYTE* OutputBuffer = NULL; DWORD BytesReturned = 0; - if (Stream_GetRemainingLength(irp->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 32)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, OutputBufferLength); /* OutputBufferLength (4 bytes) */ @@ -359,7 +359,7 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) Stream_Read_UINT32(irp->input, IoControlCode); /* IoControlCode (4 bytes) */ Stream_Seek(irp->input, 20); /* Padding (20 bytes) */ - if (Stream_GetRemainingLength(irp->input) < InputBufferLength) + if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, InputBufferLength)) return ERROR_INVALID_DATA; OutputBuffer = (BYTE*)calloc(OutputBufferLength, sizeof(BYTE)); diff --git a/channels/tsmf/client/tsmf_codec.c b/channels/tsmf/client/tsmf_codec.c index 991bb080c..0ad183873 100644 --- a/channels/tsmf/client/tsmf_codec.c +++ b/channels/tsmf/client/tsmf_codec.c @@ -273,7 +273,7 @@ static UINT32 tsmf_codec_parse_BITMAPINFOHEADER(TS_AM_MEDIA_TYPE* mediatype, wSt UINT32 biWidth; UINT32 biHeight; - if (Stream_GetRemainingLength(s) < 40) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 40)) return 0; Stream_Read_UINT32(s, biSize); Stream_Read_UINT32(s, biWidth); @@ -287,7 +287,10 @@ static UINT32 tsmf_codec_parse_BITMAPINFOHEADER(TS_AM_MEDIA_TYPE* mediatype, wSt mediatype->Height = biHeight; /* Assume there will be no color table for video? */ - if ((biSize < 40) || (Stream_GetRemainingLength(s) < (biSize - 40))) + if (biSize < 40) + return 0; + + if (!Stream_CheckAndLogRequiredLength(TAG, s, (biSize - 40))) return 0; if (bypass && biSize > 40) @@ -302,7 +305,7 @@ static UINT32 tsmf_codec_parse_VIDEOINFOHEADER2(TS_AM_MEDIA_TYPE* mediatype, wSt UINT64 AvgTimePerFrame; /* VIDEOINFOHEADER2.rcSource, RECT(LONG left, LONG top, LONG right, LONG bottom) */ - if (Stream_GetRemainingLength(s) < 72) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 72)) return 0; Stream_Seek_UINT32(s); @@ -339,7 +342,7 @@ static UINT32 tsmf_codec_parse_VIDEOINFOHEADER(TS_AM_MEDIA_TYPE* mediatype, wStr */ UINT64 AvgTimePerFrame; - if (Stream_GetRemainingLength(s) < 48) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 48)) return 0; /* VIDEOINFOHEADER.rcSource, RECT(LONG left, LONG top, LONG right, LONG bottom) */ @@ -368,7 +371,7 @@ static BOOL tsmf_read_format_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s, UINT3 { case TSMF_FORMAT_TYPE_MFVIDEOFORMAT: /* http://msdn.microsoft.com/en-us/library/aa473808.aspx */ - if (Stream_GetRemainingLength(s) < 176) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 176)) return FALSE; Stream_Seek(s, 8); /* dwSize and ? */ @@ -391,7 +394,7 @@ static BOOL tsmf_read_format_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s, UINT3 case TSMF_FORMAT_TYPE_WAVEFORMATEX: /* http://msdn.microsoft.com/en-us/library/dd757720.aspx */ - if (Stream_GetRemainingLength(s) < 18) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 18)) return FALSE; Stream_Seek_UINT16(s); @@ -406,7 +409,7 @@ static BOOL tsmf_read_format_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s, UINT3 if (mediatype->ExtraDataSize > 0) { - if (Stream_GetRemainingLength(s) < mediatype->ExtraDataSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, mediatype->ExtraDataSize)) return FALSE; mediatype->ExtraData = Stream_Pointer(s); } @@ -425,7 +428,7 @@ static BOOL tsmf_read_format_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s, UINT3 if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; - if (Stream_GetRemainingLength(s) < mediatype->ExtraDataSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, mediatype->ExtraDataSize)) return FALSE; mediatype->ExtraData = Stream_Pointer(s); } @@ -444,7 +447,7 @@ static BOOL tsmf_read_format_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s, UINT3 if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; - if (Stream_GetRemainingLength(s) < mediatype->ExtraDataSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, mediatype->ExtraDataSize)) return FALSE; mediatype->ExtraData = Stream_Pointer(s); } @@ -462,7 +465,7 @@ static BOOL tsmf_read_format_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s, UINT3 if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; - if (Stream_GetRemainingLength(s) < mediatype->ExtraDataSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, mediatype->ExtraDataSize)) return FALSE; mediatype->ExtraData = Stream_Pointer(s); } @@ -485,7 +488,7 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) /* MajorType */ DEBUG_TSMF("MediaMajorType:"); - if (Stream_GetRemainingLength(s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return FALSE; tsmf_print_guid(Stream_Pointer(s)); @@ -504,7 +507,7 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) /* SubType */ DEBUG_TSMF("MediaSubType:"); - if (Stream_GetRemainingLength(s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return FALSE; tsmf_print_guid(Stream_Pointer(s)); @@ -522,13 +525,13 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) Stream_Seek(s, 16); /* bFixedSizeSamples, bTemporalCompression, SampleSize */ - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return FALSE; Stream_Seek(s, 12); /* FormatType */ DEBUG_TSMF("FormatType:"); - if (Stream_GetRemainingLength(s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return FALSE; tsmf_print_guid(Stream_Pointer(s)); @@ -546,7 +549,7 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) Stream_Seek(s, 16); /* cbFormat */ - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, cbFormat); DEBUG_TSMF("cbFormat %" PRIu32 "", cbFormat); diff --git a/channels/tsmf/client/tsmf_ifman.c b/channels/tsmf/client/tsmf_ifman.c index 8e2836efa..fe3aac0eb 100644 --- a/channels/tsmf/client/tsmf_ifman.c +++ b/channels/tsmf/client/tsmf_ifman.c @@ -46,7 +46,7 @@ UINT tsmf_ifman_rim_exchange_capability_request(TSMF_IFMAN* ifman) { UINT32 CapabilityValue; - if (Stream_GetRemainingLength(ifman->input) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(ifman->input, CapabilityValue); @@ -81,20 +81,20 @@ UINT tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman) Stream_Copy(ifman->input, ifman->output, ifman->input_size); Stream_SetPosition(ifman->output, pos); - if (Stream_GetRemainingLength(ifman->output) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(ifman->output, numHostCapabilities); for (i = 0; i < numHostCapabilities; i++) { - if (Stream_GetRemainingLength(ifman->output) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(ifman->output, CapabilityType); Stream_Read_UINT32(ifman->output, cbCapabilityLength); - if (Stream_GetRemainingLength(ifman->output) < cbCapabilityLength) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, cbCapabilityLength)) return ERROR_INVALID_DATA; pos = Stream_GetPosition(ifman->output); @@ -102,7 +102,7 @@ UINT tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman) switch (CapabilityType) { case 1: /* Protocol version request */ - if (Stream_GetRemainingLength(ifman->output) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(ifman->output, v); @@ -110,7 +110,7 @@ UINT tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman) break; case 2: /* Supported platform */ - if (Stream_GetRemainingLength(ifman->output) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, 4)) return ERROR_INVALID_DATA; Stream_Peek_UINT32(ifman->output, v); @@ -144,7 +144,7 @@ UINT tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman) UINT32 PlatformCookie; UINT32 FormatSupported = 1; - if (Stream_GetRemainingLength(ifman->input) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 12)) return ERROR_INVALID_DATA; Stream_Read_UINT32(ifman->input, PlatformCookie); @@ -179,7 +179,7 @@ UINT tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman) TSMF_PRESENTATION* presentation; DEBUG_TSMF(""); - if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -215,7 +215,7 @@ UINT tsmf_ifman_add_stream(TSMF_IFMAN* ifman, rdpContext* rdpcontext) TSMF_PRESENTATION* presentation; DEBUG_TSMF(""); - if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE + 8)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -282,7 +282,7 @@ UINT tsmf_ifman_remove_stream(TSMF_IFMAN* ifman) TSMF_PRESENTATION* presentation; DEBUG_TSMF(""); - if (Stream_GetRemainingLength(ifman->input) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 20)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -329,7 +329,7 @@ UINT tsmf_ifman_set_source_video_rect(TSMF_IFMAN* ifman) TSMF_PRESENTATION* presentation; DEBUG_TSMF(""); - if (Stream_GetRemainingLength(ifman->input) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 32)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -363,7 +363,7 @@ UINT tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman) TSMF_PRESENTATION* presentation; DEBUG_TSMF(""); - if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -396,7 +396,7 @@ UINT tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman) UINT32 muted; DEBUG_TSMF("on stream volume"); - if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE + 8)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -430,7 +430,7 @@ UINT tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman) TSMF_PRESENTATION* presentation; DEBUG_TSMF("on channel volume"); - if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE + 8)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -482,7 +482,7 @@ UINT tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman) int i; size_t pos; - if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 32) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE + 32)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -576,7 +576,7 @@ UINT tsmf_ifman_on_sample(TSMF_IFMAN* ifman) UINT32 cbData; UINT error; - if (Stream_GetRemainingLength(ifman->input) < 60) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 60)) return ERROR_INVALID_DATA; Stream_Seek(ifman->input, 16); @@ -589,7 +589,7 @@ UINT tsmf_ifman_on_sample(TSMF_IFMAN* ifman) Stream_Read_UINT32(ifman->input, SampleExtensions); Stream_Read_UINT32(ifman->input, cbData); - if (Stream_GetRemainingLength(ifman->input) < cbData) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, cbData)) return ERROR_INVALID_DATA; DEBUG_TSMF("MessageId %" PRIu32 " StreamId %" PRIu32 " SampleStartTime %" PRIu64 @@ -642,7 +642,7 @@ UINT tsmf_ifman_on_flush(TSMF_IFMAN* ifman) TSMF_PRESENTATION* presentation; TSMF_STREAM* stream; - if (Stream_GetRemainingLength(ifman->input) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 20)) return ERROR_INVALID_DATA; Stream_Seek(ifman->input, 16); @@ -684,7 +684,7 @@ UINT tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman) TSMF_STREAM* stream = NULL; TSMF_PRESENTATION* presentation; - if (Stream_GetRemainingLength(ifman->input) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 20)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -715,7 +715,7 @@ UINT tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman) TSMF_PRESENTATION* presentation; DEBUG_TSMF(""); - if (Stream_GetRemainingLength(ifman->input) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 16)) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); diff --git a/channels/tsmf/client/tsmf_main.c b/channels/tsmf/client/tsmf_main.c index 18e638f8a..27677d4a1 100644 --- a/channels/tsmf/client/tsmf_main.c +++ b/channels/tsmf/client/tsmf_main.c @@ -138,11 +138,8 @@ static UINT tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 cbSize = Stream_GetRemainingLength(data); /* 2.2.1 Shared Message Header (SHARED_MSG_HEADER) */ - if (cbSize < 12) - { - WLog_ERR(TAG, "invalid size. cbSize=%" PRIu32 "", cbSize); + if (!Stream_CheckAndLogRequiredLength(TAG, data, 12)) return ERROR_INVALID_DATA; - } input = data; output = Stream_New(NULL, 256); @@ -198,7 +195,7 @@ static UINT tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, switch (FunctionId) { case SET_CHANNEL_PARAMS: - if (Stream_GetRemainingLength(input) < GUID_SIZE + 4) + if (!Stream_CheckAndLogRequiredLength(TAG, input, GUID_SIZE + 4)) { error = ERROR_INVALID_DATA; goto out; diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c index cc06a5e24..a4f7e6cc5 100644 --- a/channels/urbdrc/client/data_transfer.c +++ b/channels/urbdrc/client/data_transfer.c @@ -161,7 +161,7 @@ static UINT urbdrc_process_cancel_request(IUDEVICE* pdev, wStream* s, IUDEVMAN* urbdrc = (URBDRC_PLUGIN*)udevman->plugin; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, CancelId); @@ -186,7 +186,7 @@ static UINT urbdrc_process_retract_device_request(IUDEVICE* pdev, wStream* s, IU if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, Reason); /** Reason */ @@ -228,7 +228,7 @@ static UINT urbdrc_process_io_control(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* c if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, IoControlCode); @@ -236,7 +236,7 @@ static UINT urbdrc_process_io_control(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* c if (!Stream_SafeSeek(s, InputBufferSize)) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 8ULL) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ULL)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, OutputBufferSize); @@ -314,7 +314,7 @@ static UINT urbdrc_process_internal_io_control(IUDEVICE* pdev, URBDRC_CHANNEL_CA if (!pdev || !callback || !s || !udevman) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, IoControlCode); @@ -322,7 +322,7 @@ static UINT urbdrc_process_internal_io_control(IUDEVICE* pdev, URBDRC_CHANNEL_CA if (!Stream_SafeSeek(s, InputBufferSize)) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 8ULL) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ULL)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, OutputBufferSize); Stream_Read_UINT32(s, RequestId); @@ -353,7 +353,7 @@ static UINT urbdrc_process_query_device_text(IUDEVICE* pdev, URBDRC_CHANNEL_CALL if (!pdev || !callback || !s || !udevman) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, TextType); @@ -426,7 +426,7 @@ static UINT urb_select_configuration(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* ca return ERROR_INVALID_PARAMETER; } - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev)); @@ -544,14 +544,14 @@ static UINT urb_select_interface(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callba return ERROR_INVALID_PARAMETER; } - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev)); Stream_Read_UINT32(s, ConfigurationHandle); MsInterface = msusb_msinterface_read(s); - if ((Stream_GetRemainingLength(s) < 4) || !MsInterface) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) || !MsInterface) { msusb_msinterface_free(MsInterface); return ERROR_INVALID_DATA; @@ -626,7 +626,7 @@ static UINT urb_control_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callba if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev)); @@ -638,7 +638,7 @@ static UINT urb_control_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callba switch (External) { case URB_CONTROL_TRANSFER_EXTERNAL: - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, Timeout); /** TransferFlags */ @@ -649,7 +649,7 @@ static UINT urb_control_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callba } /** SetupPacket 8 bytes */ - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; Stream_Read_UINT8(s, bmRequestType); @@ -716,7 +716,7 @@ static UINT urb_bulk_or_interrupt_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBA if (!pdev || !callback || !s || !udevman) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, PipeHandle); @@ -792,7 +792,7 @@ static UINT urb_isoch_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callback if (!pdev || !callback || !udevman) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, PipeHandle); @@ -802,7 +802,7 @@ static UINT urb_isoch_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callback Stream_Read_UINT32(s, NumberOfPackets); /** NumberOfPackets */ Stream_Read_UINT32(s, ErrorCount); /** ErrorCount */ - if (Stream_GetRemainingLength(s) < NumberOfPackets * 12ULL + 4ULL) + if (!Stream_CheckAndLogRequiredLength(TAG, s, NumberOfPackets * 12ULL + 4ULL)) return ERROR_INVALID_DATA; packetDescriptorData = Stream_Pointer(s); @@ -840,7 +840,7 @@ static UINT urb_control_descriptor_request(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBA if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev)); @@ -852,7 +852,7 @@ static UINT urb_control_descriptor_request(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBA return ERROR_INVALID_DATA; if (transferDir == USBD_TRANSFER_DIRECTION_OUT) { - if (Stream_GetRemainingLength(s) < OutputBufferSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize)) return ERROR_INVALID_DATA; } @@ -927,7 +927,7 @@ static UINT urb_control_get_status_request(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBA return ERROR_INVALID_PARAMETER; } - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev)); @@ -980,7 +980,7 @@ static UINT urb_control_vendor_or_class_request(IUDEVICE* pdev, URBDRC_CHANNEL_C if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return ERROR_INVALID_DATA; InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev)); @@ -996,7 +996,7 @@ static UINT urb_control_vendor_or_class_request(IUDEVICE* pdev, URBDRC_CHANNEL_C if (transferDir == USBD_TRANSFER_DIRECTION_OUT) { - if (Stream_GetRemainingLength(s) < OutputBufferSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize)) return ERROR_INVALID_DATA; } @@ -1063,7 +1063,7 @@ static UINT urb_os_feature_descriptor_request(IUDEVICE* pdev, URBDRC_CHANNEL_CAL if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; /* 2.2.9.15 TS_URB_OS_FEATURE_DESCRIPTOR_REQUEST */ @@ -1080,7 +1080,7 @@ static UINT urb_os_feature_descriptor_request(IUDEVICE* pdev, URBDRC_CHANNEL_CAL switch (transferDir) { case USBD_TRANSFER_DIRECTION_OUT: - if (Stream_GetRemainingLength(s) < OutputBufferSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize)) return ERROR_INVALID_DATA; break; @@ -1147,7 +1147,7 @@ static UINT urb_pipe_request(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callback, if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; if (transferDir == 0) @@ -1224,7 +1224,7 @@ static UINT urb_get_current_frame_number(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; if (transferDir == 0) @@ -1294,7 +1294,7 @@ static UINT urb_control_get_configuration_request(IUDEVICE* pdev, URBDRC_CHANNEL return ERROR_INVALID_PARAMETER; } - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, OutputBufferSize); @@ -1343,7 +1343,7 @@ static UINT urb_control_get_interface_request(IUDEVICE* pdev, URBDRC_CHANNEL_CAL if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; if (transferDir == 0) @@ -1401,7 +1401,7 @@ static UINT urb_control_feature_request(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev)); @@ -1413,7 +1413,7 @@ static UINT urb_control_feature_request(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* switch (transferDir) { case USBD_TRANSFER_DIRECTION_OUT: - if (Stream_GetRemainingLength(s) < OutputBufferSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize)) return ERROR_INVALID_DATA; break; @@ -1493,7 +1493,7 @@ static UINT urbdrc_process_transfer_request(IUDEVICE* pdev, URBDRC_CHANNEL_CALLB if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, CbTsUrb); /** CbTsUrb */ @@ -1775,14 +1775,11 @@ UINT urbdrc_process_udev_data_transfer(URBDRC_CHANNEL_CALLBACK* callback, URBDRC UINT32 FunctionId; IUDEVICE* pdev; UINT error = ERROR_INTERNAL_ERROR; - size_t len; if (!urbdrc || !data || !callback || !udevman) goto fail; - len = Stream_GetRemainingLength(data); - - if (len < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, data, 8)) goto fail; Stream_Rewind_UINT32(data); diff --git a/channels/urbdrc/client/urbdrc_main.c b/channels/urbdrc/client/urbdrc_main.c index 4c0844cb3..0d69f09cf 100644 --- a/channels/urbdrc/client/urbdrc_main.c +++ b/channels/urbdrc/client/urbdrc_main.c @@ -143,7 +143,7 @@ static UINT urbdrc_process_capability_request(URBDRC_CHANNEL_CALLBACK* callback, if (!callback || !s) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, Version); @@ -186,7 +186,7 @@ static UINT urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, wSt urbdrc = (URBDRC_PLUGIN*)callback->plugin; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, MajorVersion); @@ -385,7 +385,7 @@ static UINT urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback, wStr if (!data) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(data) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, data, 8)) return ERROR_INVALID_DATA; Stream_Rewind_UINT32(data); @@ -520,7 +520,7 @@ static UINT urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callbac if (!urbdrc) return ERROR_INVALID_PARAMETER; - if (Stream_GetRemainingLength(data) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, data, 8)) return ERROR_INVALID_DATA; Stream_Rewind(data, 4); @@ -576,7 +576,7 @@ static UINT urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback udevman = (IUDEVMAN*)urbdrc->udevman; - if (Stream_GetRemainingLength(data) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, data, 12)) return ERROR_INVALID_DATA; urbdrc_dump_message(urbdrc->log, FALSE, FALSE, data); diff --git a/channels/video/client/video_main.c b/channels/video/client/video_main.c index 422b3538a..25302d278 100644 --- a/channels/video/client/video_main.c +++ b/channels/video/client/video_main.c @@ -528,11 +528,8 @@ static UINT video_read_tsmm_presentation_req(VideoClientContext* context, wStrea WINPR_ASSERT(context); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 60) - { - WLog_ERR(TAG, "not enough bytes for a TSMM_PRESENTATION_REQUEST"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 60)) return ERROR_INVALID_DATA; - } Stream_Read_UINT8(s, req.PresentationId); Stream_Read_UINT8(s, req.Version); @@ -552,11 +549,8 @@ static UINT video_read_tsmm_presentation_req(VideoClientContext* context, wStrea Stream_Read_UINT32(s, req.cbExtra); - if (Stream_GetRemainingLength(s) < req.cbExtra) - { - WLog_ERR(TAG, "not enough bytes for cbExtra of TSMM_PRESENTATION_REQUEST"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, req.cbExtra)) return ERROR_INVALID_DATA; - } req.pExtraData = Stream_Pointer(s); @@ -593,15 +587,17 @@ static UINT video_control_on_data_received(IWTSVirtualChannelCallback* pChannelC context = (VideoClientContext*)video->wtsPlugin.pInterface; WINPR_ASSERT(context); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, cbSize); - if (cbSize < 8 || Stream_GetRemainingLength(s) < (cbSize - 4)) + if (cbSize < 8) { - WLog_ERR(TAG, "invalid cbSize"); + WLog_ERR(TAG, "invalid cbSize %" PRIu32 ", expected 8", cbSize); return ERROR_INVALID_DATA; } + if (!Stream_CheckAndLogRequiredLength(TAG, s, cbSize - 4)) + return ERROR_INVALID_DATA; Stream_Read_UINT32(s, packetType); switch (packetType) @@ -940,16 +936,19 @@ static UINT video_data_on_data_received(IWTSVirtualChannelCallback* pChannelCall video = (VIDEO_PLUGIN*)callback->plugin; context = (VideoClientContext*)video->wtsPlugin.pInterface; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, cbSize); - if (cbSize < 8 || Stream_GetRemainingLength(s) < (cbSize - 4)) + if (cbSize < 8) { - WLog_ERR(TAG, "invalid cbSize"); + WLog_ERR(TAG, "invalid cbSize %" PRIu32 ", expected >= 8", cbSize); return ERROR_INVALID_DATA; } + if (!Stream_CheckAndLogRequiredLength(TAG, s, cbSize - 4)) + return ERROR_INVALID_DATA; + Stream_Read_UINT32(s, packetType); if (packetType != TSMM_PACKET_TYPE_VIDEO_DATA) { @@ -957,11 +956,8 @@ static UINT video_data_on_data_received(IWTSVirtualChannelCallback* pChannelCall return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) < 32) - { - WLog_ERR(TAG, "not enough bytes for a TSMM_VIDEO_DATA"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 32)) return ERROR_INVALID_DATA; - } Stream_Read_UINT8(s, data.PresentationId); Stream_Read_UINT8(s, data.Version); diff --git a/client/Android/Studio/freeRDPCore/src/main/cpp/android_freerdp.c b/client/Android/Studio/freeRDPCore/src/main/cpp/android_freerdp.c index 9c1176feb..cdedbe42b 100644 --- a/client/Android/Studio/freeRDPCore/src/main/cpp/android_freerdp.c +++ b/client/Android/Studio/freeRDPCore/src/main/cpp/android_freerdp.c @@ -433,7 +433,7 @@ static int android_freerdp_run(freerdp* instance) inputEvent = android_get_handle(instance); - while (!freerdp_shall_disconnect(instance)) + while (!freerdp_shall_disconnect_context(instance->context)) { DWORD tmp; count = 0; @@ -469,7 +469,7 @@ static int android_freerdp_run(freerdp* instance) break; } - if (freerdp_shall_disconnect(instance)) + if (freerdp_shall_disconnect_context(instance->context)) break; if (android_check_handle(instance) != TRUE) @@ -774,7 +774,7 @@ Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1disconnect(JNIEnv* env return JNI_FALSE; } - if (!freerdp_abort_connect(inst)) + if (!freerdp_abort_connect_context(inst->context)) return JNI_FALSE; return JNI_TRUE; diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index d04455aaa..3d4fb8c1f 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -155,7 +155,7 @@ DWORD WINAPI mac_client_thread(void *param) nCountBase = nCount; - while (!freerdp_shall_disconnect(instance)) + while (!freerdp_shall_disconnect_context(instance->context)) { nCount = nCountBase; { diff --git a/client/Sample/tf_freerdp.c b/client/Sample/tf_freerdp.c index fbf596b4c..425685ef1 100644 --- a/client/Sample/tf_freerdp.c +++ b/client/Sample/tf_freerdp.c @@ -242,7 +242,7 @@ static DWORD WINAPI tf_client_thread_proc(LPVOID arg) if (instance->context->settings->AuthenticationOnly) { result = freerdp_get_last_error(instance->context); - freerdp_abort_connect(instance); + freerdp_abort_connect_context(instance->context); WLog_ERR(TAG, "Authentication only, exit status 0x%08" PRIx32 "", result); goto disconnect; } @@ -254,7 +254,7 @@ static DWORD WINAPI tf_client_thread_proc(LPVOID arg) return result; } - while (!freerdp_shall_disconnect(instance)) + while (!freerdp_shall_disconnect_context(instance->context)) { nCount = freerdp_get_event_handles(instance->context, handles, ARRAYSIZE(handles)); diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 540c16f11..e286fc4be 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -488,7 +488,7 @@ static int wlfreerdp_run(freerdp* instance) goto disconnect; } - while (!freerdp_shall_disconnect(instance)) + while (!freerdp_shall_disconnect_context(instance->context)) { DWORD count = 0; handles[count++] = timer; diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index 515ef2902..47d8152c9 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -1057,7 +1057,7 @@ static DWORD WINAPI wf_client_thread(LPVOID lpParam) } } - if (freerdp_shall_disconnect(instance)) + if (freerdp_shall_disconnect_context(instance->context)) break; quit_msg = FALSE; diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 0b82a99cf..2dbf625fe 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1617,7 +1617,7 @@ static DWORD WINAPI xf_client_thread(LPVOID param) } inputEvent = xfc->x11event; - while (!freerdp_shall_disconnect(instance)) + while (!freerdp_shall_disconnect_context(instance->context)) { nCount = 0; handles[nCount++] = timer; @@ -1733,7 +1733,7 @@ static void xf_TerminateEventHandler(void* context, const TerminateEventArgs* e) { rdpContext* ctx = (rdpContext*)context; WINPR_UNUSED(e); - freerdp_abort_connect(ctx->instance); + freerdp_abort_connect_context(ctx); } #ifdef WITH_XRENDER diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 7af7c71e4..2945e57c3 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -414,11 +414,8 @@ static CLIPRDR_FORMAT* xf_cliprdr_parse_server_format_list(BYTE* data, size_t le goto error; } - if (Stream_GetRemainingLength(s) < sizeof(UINT32)) - { - WLog_ERR(TAG, "too short serialized format list"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(UINT32))) goto error; - } Stream_Read_UINT32(s, *numFormats); @@ -439,11 +436,8 @@ static CLIPRDR_FORMAT* xf_cliprdr_parse_server_format_list(BYTE* data, size_t le const char* formatName = NULL; size_t formatNameLength = 0; - if (Stream_GetRemainingLength(s) < sizeof(UINT32)) - { - WLog_ERR(TAG, "unexpected end of serialized format list"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(UINT32))) goto error; - } Stream_Read_UINT32(s, formats[i].formatId); formatName = (const char*)Stream_Pointer(s); @@ -1799,11 +1793,8 @@ static xfCliprdrFuseInode* xf_cliprdr_fuse_create_root_node() static BOOL xf_cliprdr_fuse_check_stream(wStream* s, size_t count) { UINT32 nrDescriptors; - if (Stream_GetRemainingLength(s) < sizeof(UINT32)) - { - WLog_ERR(TAG, "too short serialized format list"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(UINT32))) return FALSE; - } Stream_Read_UINT32(s, nrDescriptors); if (count != nrDescriptors) diff --git a/client/X11/xf_floatbar.c b/client/X11/xf_floatbar.c index af12791a3..b9b787b3f 100644 --- a/client/X11/xf_floatbar.c +++ b/client/X11/xf_floatbar.c @@ -100,7 +100,7 @@ static BOOL xf_floatbar_button_onclick_close(xfFloatbar* floatbar) if (!floatbar) return FALSE; - return freerdp_abort_connect(floatbar->xfc->common.context.instance); + return freerdp_abort_connect_context(&floatbar->xfc->common.context); } static BOOL xf_floatbar_button_onclick_minimize(xfFloatbar* floatbar) diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index afd5daf25..e2792d95a 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -811,7 +811,7 @@ static UINT xf_rail_server_execute_result(RailClientContext* context, { WLog_ERR(TAG, "RAIL exec error: execResult=%s NtError=0x%X\n", error_code_names[execResult->execResult], execResult->rawResult); - freerdp_abort_connect(xfc->common.context.instance); + freerdp_abort_connect_context(&xfc->common.context); } else { diff --git a/client/common/client.c b/client/common/client.c index 1eb877c5e..b4989a7cf 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -951,7 +951,7 @@ int freerdp_client_common_stop(rdpContext* context) rdpClientContext* cctx = (rdpClientContext*)context; WINPR_ASSERT(cctx); - freerdp_abort_connect(cctx->context.instance); + freerdp_abort_connect_context(&cctx->context); if (cctx->thread) { diff --git a/client/iOS/FreeRDP/ios_freerdp.m b/client/iOS/FreeRDP/ios_freerdp.m index 711880b75..c68ada068 100644 --- a/client/iOS/FreeRDP/ios_freerdp.m +++ b/client/iOS/FreeRDP/ios_freerdp.m @@ -266,7 +266,7 @@ int ios_run_freerdp(freerdp *instance) memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); - while (!freerdp_shall_disconnect(instance)) + while (!freerdp_shall_disconnect_context(instance->context)) { rcount = wcount = 0; pool = [[NSAutoreleasePool alloc] init]; diff --git a/include/freerdp/crypto/per.h b/include/freerdp/crypto/per.h index d6067a4be..087a17fe2 100644 --- a/include/freerdp/crypto/per.h +++ b/include/freerdp/crypto/per.h @@ -51,7 +51,7 @@ extern "C" UINT16 min); FREERDP_API BOOL per_write_octet_string(wStream* s, const BYTE* oct_str, UINT16 length, UINT16 min); - FREERDP_API BOOL per_read_numeric_string(wStream* s, int min); + FREERDP_API BOOL per_read_numeric_string(wStream* s, UINT16 min); FREERDP_API BOOL per_write_numeric_string(wStream* s, const BYTE* num_str, UINT16 length, UINT16 min); diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index c3c6f4808..a5d364eb7 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -302,7 +302,7 @@ extern "C" ALIGN64 rdpMetrics* metrics; /* 41 */ ALIGN64 rdpCodecs* codecs; /* 42 */ ALIGN64 rdpAutoDetect* autodetect; /* 43 owned by rdpRdp */ - ALIGN64 HANDLE abortEvent; /* 44 */ + UINT64 paddingC1[45 - 44]; /* 44 */ ALIGN64 int disconnectUltimatum; /* 45 */ UINT64 paddingC[64 - 46]; /* 46 */ @@ -505,8 +505,16 @@ settings but before rdp_client_connect() to have it executed after the FREERDP_API void freerdp_context_free(freerdp* instance); FREERDP_API BOOL freerdp_connect(freerdp* instance); - FREERDP_API BOOL freerdp_abort_connect(freerdp* instance); - FREERDP_API BOOL freerdp_shall_disconnect(freerdp* instance); + + WINPR_DEPRECATED_VAR("use freerdp_abort_connect_context instead", + FREERDP_API BOOL freerdp_abort_connect(freerdp* instance)); + + FREERDP_API BOOL freerdp_abort_connect_context(rdpContext* context); + + WINPR_DEPRECATED_VAR("use freerdp_shall_disconnect_context instead", + FREERDP_API BOOL freerdp_shall_disconnect(freerdp* instance)); + + FREERDP_API BOOL freerdp_shall_disconnect_context(rdpContext* context); FREERDP_API BOOL freerdp_disconnect(freerdp* instance); FREERDP_API BOOL freerdp_disconnect_before_reconnect(freerdp* instance); diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 2ef6a1227..3a3ba2302 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -563,6 +563,8 @@ typedef struct #define FreeRDP_MonitorLocalShiftX (395) #define FreeRDP_MonitorLocalShiftY (396) #define FreeRDP_HasMonitorAttributes (397) +#define FreeRDP_MonitorFlags (398) +#define FreeRDP_MonitorAttributeFlags (399) #define FreeRDP_MultitransportFlags (512) #define FreeRDP_SupportMultitransport (513) #define FreeRDP_AlternateShell (640) @@ -588,6 +590,7 @@ typedef struct #define FreeRDP_IPv6Enabled (768) #define FreeRDP_ClientAddress (769) #define FreeRDP_ClientDir (770) +#define FreeRDP_ClientSessionId (771) #define FreeRDP_AutoReconnectionEnabled (832) #define FreeRDP_AutoReconnectMaxRetries (833) #define FreeRDP_ClientAutoReconnectCookie (834) @@ -1005,7 +1008,9 @@ struct rdp_settings ALIGN64 UINT32 MonitorLocalShiftX; /*395 */ ALIGN64 UINT32 MonitorLocalShiftY; /* 396 */ ALIGN64 BOOL HasMonitorAttributes; /* 397 */ - UINT64 padding0448[448 - 398]; /* 398 */ + ALIGN64 UINT32 MonitorFlags; /* 398 */ + ALIGN64 UINT32 MonitorAttributeFlags; /* 399 */ + UINT64 padding0448[448 - 400]; /* 400 */ /* Client Message Channel Data */ UINT64 padding0512[512 - 448]; /* 448 */ @@ -1050,7 +1055,8 @@ struct rdp_settings ALIGN64 BOOL IPv6Enabled; /* 768 */ ALIGN64 char* ClientAddress; /* 769 */ ALIGN64 char* ClientDir; /* 770 */ - UINT64 padding0832[832 - 771]; /* 771 */ + ALIGN64 UINT32 ClientSessionId; /* */ + UINT64 padding0832[832 - 772]; /* 772 */ /* Client Info (Auto Reconnection) */ ALIGN64 BOOL AutoReconnectionEnabled; /* 832 */ diff --git a/libfreerdp/codec/audio.c b/libfreerdp/codec/audio.c index b2904469a..81824e956 100644 --- a/libfreerdp/codec/audio.c +++ b/libfreerdp/codec/audio.c @@ -149,7 +149,7 @@ BOOL audio_format_read(wStream* s, AUDIO_FORMAT* format) if (!s || !format) return FALSE; - if (Stream_GetRemainingLength(s) < 18) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 18)) return FALSE; Stream_Read_UINT16(s, format->wFormatTag); @@ -160,7 +160,7 @@ BOOL audio_format_read(wStream* s, AUDIO_FORMAT* format) Stream_Read_UINT16(s, format->wBitsPerSample); Stream_Read_UINT16(s, format->cbSize); - if (Stream_GetRemainingLength(s) < format->cbSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, format->cbSize)) return FALSE; format->data = NULL; diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c index 68dadf60b..8cc2b1ba2 100644 --- a/libfreerdp/codec/clear.c +++ b/libfreerdp/codec/clear.c @@ -103,12 +103,8 @@ static BOOL clear_decompress_nscodec(NSC_CONTEXT* nsc, UINT32 width, UINT32 heig { BOOL rc; - if (Stream_GetRemainingLength(s) < bitmapDataByteCount) - { - WLog_ERR(TAG, "stream short %" PRIuz " [%" PRIu32 " expected]", - Stream_GetRemainingLength(s), bitmapDataByteCount); + if (!Stream_CheckAndLogRequiredLength(TAG, s, bitmapDataByteCount)) return FALSE; - } rc = nsc_process_message(nsc, 32, width, height, Stream_Pointer(s), bitmapDataByteCount, pDstData, DstFormat, nDstStep, nXDstRel, nYDstRel, width, height, @@ -135,14 +131,10 @@ static BOOL clear_decompress_subcode_rlex(wStream* s, UINT32 bitmapDataByteCount BYTE paletteCount; UINT32 palette[128] = { 0 }; - if (Stream_GetRemainingLength(s) < bitmapDataByteCount) - { - WLog_ERR(TAG, "stream short %" PRIuz " [%" PRIu32 " expected]", - Stream_GetRemainingLength(s), bitmapDataByteCount); + if (!Stream_CheckAndLogRequiredLength(TAG, s, bitmapDataByteCount)) return FALSE; - } - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, paletteCount); bitmapDataOffset = 1 + (paletteCount * 3); @@ -153,7 +145,7 @@ static BOOL clear_decompress_subcode_rlex(wStream* s, UINT32 bitmapDataByteCount return FALSE; } - if (Stream_GetRemainingLength(s) / 3 < paletteCount) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3ull * paletteCount)) return FALSE; for (i = 0; i < paletteCount; i++) @@ -175,11 +167,8 @@ static BOOL clear_decompress_subcode_rlex(wStream* s, UINT32 bitmapDataByteCount UINT32 color; UINT32 runLengthFactor; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "stream short %" PRIuz " [2 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } Stream_Read_UINT8(s, tmp); Stream_Read_UINT8(s, runLengthFactor); @@ -190,23 +179,16 @@ static BOOL clear_decompress_subcode_rlex(wStream* s, UINT32 bitmapDataByteCount if (runLengthFactor >= 0xFF) { - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "stream short %" PRIuz " [2 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } Stream_Read_UINT16(s, runLengthFactor); bitmapDataOffset += 2; if (runLengthFactor >= 0xFFFF) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "stream short %" PRIuz " [4 expected]", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Read_UINT32(s, runLengthFactor); bitmapDataOffset += 4; @@ -346,12 +328,8 @@ static BOOL clear_decompress_residual_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 pixelIndex; UINT32 pixelCount; - if (Stream_GetRemainingLength(s) < residualByteCount) - { - WLog_ERR(TAG, "stream short %" PRIuz " [%" PRIu32 " expected]", - Stream_GetRemainingLength(s), residualByteCount); + if (!Stream_CheckAndLogRequiredLength(TAG, s, residualByteCount)) return FALSE; - } suboffset = 0; pixelIndex = 0; @@ -368,11 +346,8 @@ static BOOL clear_decompress_residual_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 runLengthFactor; UINT32 color; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "stream short %" PRIuz " [4 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Read_UINT8(s, b); Stream_Read_UINT8(s, g); @@ -383,23 +358,16 @@ static BOOL clear_decompress_residual_data(CLEAR_CONTEXT* clear, wStream* s, if (runLengthFactor >= 0xFF) { - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "stream short %" PRIuz " [2 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } Stream_Read_UINT16(s, runLengthFactor); suboffset += 2; if (runLengthFactor >= 0xFFFF) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "stream short %" PRIuz " [4 expected]", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Read_UINT32(s, runLengthFactor); suboffset += 4; @@ -451,12 +419,8 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* clear, wStream* s, BYTE subcodecId; UINT32 suboffset; - if (Stream_GetRemainingLength(s) < subcodecByteCount) - { - WLog_ERR(TAG, "stream short %" PRIuz " [%" PRIu32 " expected]", - Stream_GetRemainingLength(s), subcodecByteCount); + if (!Stream_CheckAndLogRequiredLength(TAG, s, subcodecByteCount)) return FALSE; - } suboffset = 0; @@ -465,11 +429,8 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 nXDstRel; UINT32 nYDstRel; - if (Stream_GetRemainingLength(s) < 13) - { - WLog_ERR(TAG, "stream short %" PRIuz " [13 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 13)) return FALSE; - } Stream_Read_UINT16(s, xStart); Stream_Read_UINT16(s, yStart); @@ -479,12 +440,8 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* clear, wStream* s, Stream_Read_UINT8(s, subcodecId); suboffset += 13; - if (Stream_GetRemainingLength(s) < bitmapDataByteCount) - { - WLog_ERR(TAG, "stream short %" PRIuz " [%" PRIu32 " expected]", - Stream_GetRemainingLength(s), bitmapDataByteCount); + if (!Stream_CheckAndLogRequiredLength(TAG, s, bitmapDataByteCount)) return FALSE; - } nXDstRel = nXDst + xStart; nYDstRel = nYDst + yStart; @@ -595,11 +552,8 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 UINT32 nXDstRel; UINT32 nYDstRel; - if (Stream_GetRemainingLength(s) < bandsByteCount) - { - WLog_ERR(TAG, "stream short %" PRIuz " [11 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, bandsByteCount)) return FALSE; - } suboffset = 0; @@ -618,11 +572,8 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 UINT32 vBarPixelCount; UINT32 vBarShortPixelCount = 0; - if (Stream_GetRemainingLength(s) < 11) - { - WLog_ERR(TAG, "stream short %" PRIuz " [11 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 11)) return FALSE; - } Stream_Read_UINT16(s, xStart); Stream_Read_UINT16(s, xEnd); @@ -656,11 +607,8 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 BOOL vBarUpdate = FALSE; const BYTE* cpSrcPixel; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "stream short %" PRIuz " [2 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } Stream_Read_UINT16(s, vBarHeader); suboffset += 2; @@ -683,12 +631,8 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 return FALSE; } - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "stream short %" PRIuz " [1 expected]", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, vBarYOn); suboffset += 1; @@ -714,12 +658,8 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 return FALSE; } - if (Stream_GetRemainingLength(s) / 3 < vBarShortPixelCount) - { - WLog_ERR(TAG, "stream short %" PRIuz " [%" PRIu32 " expected]", - Stream_GetRemainingLength(s), (vBarShortPixelCount * 3)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3ull * vBarShortPixelCount)) return FALSE; - } if (clear->ShortVBarStorageCursor >= CLEARCODEC_VBAR_SHORT_SIZE) { @@ -920,11 +860,8 @@ static BOOL clear_decompress_glyph_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 return FALSE; } - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "stream short %" PRIuz " [2 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } Stream_Read_UINT16(s, glyphIndex); @@ -1041,11 +978,8 @@ INT32 clear_decompress(CLEAR_CONTEXT* clear, const BYTE* pSrcData, UINT32 SrcSiz if (!s) return -2005; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "stream short %" PRIuz " [2 expected]", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) goto fail; - } if (!updateContextFormat(clear, DstFormat)) goto fail; @@ -1082,14 +1016,13 @@ INT32 clear_decompress(CLEAR_CONTEXT* clear, const BYTE* pSrcData, UINT32 SrcSiz } /* Read composition payload header parameters */ - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) { const UINT32 mask = (CLEARCODEC_FLAG_GLYPH_HIT | CLEARCODEC_FLAG_GLYPH_INDEX); if ((glyphFlags & mask) == mask) goto finish; - WLog_ERR(TAG, "stream short %" PRIuz " [12 expected]", Stream_GetRemainingLength(s)); goto fail; } diff --git a/libfreerdp/codec/nsc.c b/libfreerdp/codec/nsc.c index a461f96b5..0cb5a872f 100644 --- a/libfreerdp/codec/nsc.c +++ b/libfreerdp/codec/nsc.c @@ -36,6 +36,9 @@ #include "nsc_sse2.h" +#include +#define TAG FREERDP_TAG("codec.nsc") + #ifndef NSC_INIT_SIMD #define NSC_INIT_SIMD(_nsc_context) \ do \ @@ -219,7 +222,7 @@ static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s) { int i; - if (Stream_GetRemainingLength(s) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return FALSE; for (i = 0; i < 4; i++) diff --git a/libfreerdp/codec/nsc_encode.c b/libfreerdp/codec/nsc_encode.c index 25e43add8..25ac90678 100644 --- a/libfreerdp/codec/nsc_encode.c +++ b/libfreerdp/codec/nsc_encode.c @@ -523,6 +523,7 @@ BOOL nsc_decompose_message(NSC_CONTEXT* context, wStream* s, BYTE* bmpdata, UINT UINT32 flip) { size_t size = Stream_GetRemainingLength(s); + if (size > UINT32_MAX) return FALSE; diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c index 28ee13757..f124277e7 100644 --- a/libfreerdp/codec/progressive.c +++ b/libfreerdp/codec/progressive.c @@ -1505,12 +1505,8 @@ static INLINE BOOL progressive_tile_read_upgrade(PROGRESSIVE_CONTEXT* progressiv RFX_PROGRESSIVE_TILE tile = { 0 }; const size_t expect = 20; - if (Stream_GetRemainingLength(s) < expect) - { - WLog_Print(progressive->log, WLOG_ERROR, "Expected %" PRIuz " bytes, got %" PRIuz, expect, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, expect)) return FALSE; - } tile.blockType = blockType; tile.blockLen = blockLen; @@ -1587,12 +1583,8 @@ static INLINE BOOL progressive_tile_read(PROGRESSIVE_CONTEXT* progressive, BOOL RFX_PROGRESSIVE_TILE tile = { 0 }; size_t expect = simple ? 16 : 17; - if (Stream_GetRemainingLength(s) < expect) - { - WLog_Print(progressive->log, WLOG_ERROR, "Expected %" PRIuz " bytes, got %" PRIuz, expect, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, expect)) return FALSE; - } tile.blockType = blockType; tile.blockLen = blockLen; @@ -1696,19 +1688,13 @@ static INLINE int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, wS PROGRESSIVE_TILE_PROCESS_WORK_PARAM* params = NULL; UINT16 close_cnt = 0; - if (Stream_GetRemainingLength(s) < region->tileDataSize) - { - WLog_Print(progressive->log, WLOG_ERROR, "Short block %" PRIuz ", expected %" PRIu32, - Stream_GetRemainingLength(s), region->tileDataSize); + if (!Stream_CheckAndLogRequiredLength(TAG, s, region->tileDataSize)) return -1; - } while ((Stream_GetRemainingLength(s) >= 6) && (region->tileDataSize > (Stream_GetPosition(s) - start))) { - size_t rem; const size_t pos = Stream_GetPosition(s); - rem = Stream_GetRemainingLength(s); Stream_Read_UINT16(s, blockType); Stream_Read_UINT32(s, blockLen); @@ -1716,14 +1702,15 @@ static INLINE int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, wS WLog_Print(progressive->log, WLOG_DEBUG, "%s", progressive_get_block_type_string(blockType)); - if (rem < blockLen) + if (blockLen < 6) { - WLog_Print(progressive->log, WLOG_ERROR, "Expected %" PRIu32 " remaining %" PRIuz, - blockLen, rem); + WLog_Print(progressive->log, WLOG_ERROR, "Expected >= %" PRIu32 " remaining %" PRIuz, 6, + blockLen); return -1003; } + if (!Stream_CheckAndLogRequiredLength(TAG, s, blockLen - 6)) + return -1003; - rem = Stream_GetRemainingLength(s); switch (blockType) { case PROGRESSIVE_WBT_TILE_SIMPLE: @@ -1749,7 +1736,7 @@ static INLINE int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, wS return -1039; } - rem = Stream_GetPosition(s); + size_t rem = Stream_GetPosition(s); if ((rem - pos) != blockLen) { WLog_Print(progressive->log, WLOG_ERROR, @@ -2030,13 +2017,8 @@ static INLINE INT32 progressive_wb_sync(PROGRESSIVE_CONTEXT* progressive, wStrea return -1005; } - if (Stream_GetRemainingLength(s) < 6) - { - WLog_Print(progressive->log, WLOG_ERROR, - "ProgressiveSync short %" PRIuz ", expected %" PRIuz, - Stream_GetRemainingLength(s), 6); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return -1004; - } WLog_Print(progressive->log, WLOG_DEBUG, "ProgressiveSync"); @@ -2082,13 +2064,8 @@ static INLINE INT32 progressive_wb_frame_begin(PROGRESSIVE_CONTEXT* progressive, return -1005; } - if (Stream_GetRemainingLength(s) < 6) - { - WLog_Print(progressive->log, WLOG_ERROR, - "ProgressiveFrameBegin short %" PRIuz ", expected %" PRIuz, - Stream_GetRemainingLength(s), 6); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return -1007; - } Stream_Read_UINT32(s, frameBegin.frameIndex); Stream_Read_UINT16(s, frameBegin.regionCount); @@ -2168,13 +2145,8 @@ static INLINE int progressive_wb_context(PROGRESSIVE_CONTEXT* progressive, wStre return -1005; } - if (Stream_GetRemainingLength(s) < 4) - { - WLog_Print(progressive->log, WLOG_ERROR, - "ProgressiveContext short %" PRIuz ", expected %" PRIuz, - Stream_GetRemainingLength(s), 4); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return -1009; - } Stream_Read_UINT8(s, context->ctxId); Stream_Read_UINT16(s, context->tileSize); @@ -2210,13 +2182,8 @@ static INLINE INT32 progressive_wb_read_region_header(PROGRESSIVE_CONTEXT* progr size_t len; memset(region, 0, sizeof(PROGRESSIVE_BLOCK_REGION)); - if (Stream_GetRemainingLength(s) < 12) - { - WLog_Print(progressive->log, WLOG_ERROR, - "ProgressiveRegion short %" PRIuz ", expected %" PRIuz, - Stream_GetRemainingLength(s), 12); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return -1011; - } region->blockType = blockType; region->blockLen = blockLen; @@ -2252,7 +2219,7 @@ static INLINE INT32 progressive_wb_read_region_header(PROGRESSIVE_CONTEXT* progr } len = Stream_GetRemainingLength(s); - if (len / 8 < region->numRects) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ull * region->numRects)) { WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion data short for region->rects"); return -1015; @@ -2469,23 +2436,25 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD progressive->state = 0; /* Set state to not initialized */ while (Stream_GetRemainingLength(s) >= 6) { - size_t rem, st, e; + size_t st, e; st = Stream_GetPosition(s); - rem = Stream_GetRemainingLength(s); Stream_Read_UINT16(s, blockType); Stream_Read_UINT32(s, blockLen); - if (rem < blockLen) + if (blockLen < 6) + { + WLog_WARN(TAG, "Invalid blockLen %" PRIu32 ", expected >= 6", blockLen); + rc = -1003; + goto fail; + } + if (!Stream_CheckAndLogRequiredLength(TAG, s, blockLen - 6)) { - WLog_Print(progressive->log, WLOG_ERROR, "Short block %" PRIuz ", expected %" PRIu32, - rem, blockLen); rc = -1003; goto fail; } - rem = Stream_GetRemainingLength(s); switch (blockType) { case PROGRESSIVE_WBT_SYNC: diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 1afac7b23..3fa66eb09 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -435,11 +435,8 @@ static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* s) context->decodedHeaderBlocks &= ~RFX_DECODED_SYNC; /* RFX_SYNC */ - if (Stream_GetRemainingLength(s) < 6) - { - WLog_ERR(TAG, "RfxSync packet too small"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; - } Stream_Read_UINT32(s, magic); /* magic (4 bytes), 0xCACCACCA */ if (magic != WF_MAGIC) @@ -465,11 +462,8 @@ static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s) BYTE numCodecs; context->decodedHeaderBlocks &= ~RFX_DECODED_VERSIONS; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "%s: packet too small for reading codec versions", __FUNCTION__); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Read_UINT8(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */ Stream_Read_UINT8(s, context->codec_id); /* codecId (1 byte), must be set to 0x01 */ @@ -507,11 +501,8 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s) BYTE numChannels; context->decodedHeaderBlocks &= ~RFX_DECODED_CHANNELS; - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "RfxMessageChannels packet too small"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, numChannels); /* numChannels (1 byte), must bet set to 0x01 */ @@ -524,12 +515,8 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s) return FALSE; } - if (Stream_GetRemainingLength(s) / 5 < numChannels) - { - WLog_ERR(TAG, "RfxMessageChannels packet too small for numChannels=%" PRIu8 "", - numChannels); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5ull * numChannels)) return FALSE; - } /* RFX_CHANNELT */ Stream_Read_UINT8(s, channelId); /* channelId (1 byte), must be set to 0x00 */ @@ -566,11 +553,8 @@ static BOOL rfx_process_message_context(RFX_CONTEXT* context, wStream* s) UINT16 properties; context->decodedHeaderBlocks &= ~RFX_DECODED_CONTEXT; - if (Stream_GetRemainingLength(s) < 5) - { - WLog_ERR(TAG, "RfxMessageContext packet too small"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return FALSE; - } Stream_Read_UINT8(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */ Stream_Read_UINT16(s, tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */ @@ -625,11 +609,8 @@ static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* m *pExpectedBlockType = WBT_REGION; - if (Stream_GetRemainingLength(s) < 6) - { - WLog_ERR(TAG, "RfxMessageFrameBegin packet too small"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; - } Stream_Read_UINT32( s, frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */ @@ -670,11 +651,8 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag *pExpectedBlockType = WBT_EXTENSION; - if (Stream_GetRemainingLength(s) < 3) - { - WLog_ERR(TAG, "%s: packet too small (regionFlags/numRects)", __FUNCTION__); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3)) return FALSE; - } Stream_Seek_UINT8(s); /* regionFlags (1 byte) */ Stream_Read_UINT16(s, message->numRects); /* numRects (2 bytes) */ @@ -700,12 +678,8 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag return TRUE; } - if (Stream_GetRemainingLength(s) / 8 < message->numRects) - { - WLog_ERR(TAG, "%s: packet too small for num_rects=%" PRIu16 "", __FUNCTION__, - message->numRects); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ull * message->numRects)) return FALSE; - } tmpRects = realloc(message->rects, message->numRects * sizeof(RFX_RECT)); if (!tmpRects) @@ -726,11 +700,8 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag rect->y, rect->width, rect->height); } - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "%s: packet too small (regionType/numTileSets)", __FUNCTION__); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Read_UINT16(s, regionType); /*regionType (2 bytes): MUST be set to CBT_REGION (0xCAC1)*/ Stream_Read_UINT16(s, numTileSets); /*numTilesets (2 bytes): MUST be set to 0x0001.*/ @@ -788,11 +759,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa *pExpectedBlockType = WBT_FRAME_END; - if (Stream_GetRemainingLength(s) < 14) - { - WLog_ERR(TAG, "RfxMessageTileSet packet too small"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 14)) return FALSE; - } Stream_Read_UINT16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */ if (subtype != CBT_TILESET) @@ -827,12 +795,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa quants = context->quants = (UINT32*)pmem; /* quantVals */ - if (Stream_GetRemainingLength(s) / 5 < context->numQuant) - { - WLog_ERR(TAG, "RfxMessageTileSet packet too small for num_quants=%" PRIu8 "", - context->numQuant); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5ull * context->numQuant)) return FALSE; - } for (i = 0; i < context->numQuant; i++) { @@ -916,7 +880,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa message->tiles[i] = tile; /* RFX_TILE */ - if (Stream_GetRemainingLength(s) < 6) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) { WLog_ERR(TAG, "RfxMessageTileSet packet too small to read tile %d/%" PRIu16 "", i, message->numTiles); @@ -934,7 +898,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa rc = FALSE; break; } - if ((blockLen < 6 + 13) || (Stream_GetRemainingLength(sub) < blockLen - 6)) + if ((blockLen < 6 + 13) || (!Stream_CheckAndLogRequiredLength(TAG, sub, blockLen - 6))) { WLog_ERR(TAG, "RfxMessageTileSet not enough bytes to read tile %d/%" PRIu16 @@ -1073,11 +1037,8 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length, return FALSE; } - if (Stream_GetRemainingLength(s) < blockLen - 6) - { - WLog_ERR(TAG, "%s: packet too small for blocklen=%" PRIu32 "", __FUNCTION__, blockLen); + if (!Stream_CheckAndLogRequiredLength(TAG, s, blockLen - 6)) return FALSE; - } if (blockType > WBT_CONTEXT && context->decodedHeaderBlocks != RFX_DECODED_HEADERS) { @@ -1091,11 +1052,8 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length, UINT8 codecId; UINT8 channelId; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "extraBlockLen too small(%" PRIuz ")", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } extraBlockLen = 2; Stream_Read_UINT8(s, codecId); /* codecId (1 byte) must be set to 0x01 */ diff --git a/libfreerdp/codec/zgfx.c b/libfreerdp/codec/zgfx.c index 5d0099a2f..c08d32c0d 100644 --- a/libfreerdp/codec/zgfx.c +++ b/libfreerdp/codec/zgfx.c @@ -232,7 +232,7 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t cbSegment = segmentSize - 1; - if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize < 1) || + if (!Stream_CheckAndLogRequiredLength(TAG, stream, segmentSize) || (segmentSize < 1) || (segmentSize > UINT32_MAX)) return FALSE; @@ -371,7 +371,7 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY if (!stream) return -1; - if (Stream_GetRemainingLength(stream) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, stream, 1)) goto fail; Stream_Read_UINT8(stream, descriptor); /* descriptor (1 byte) */ @@ -401,13 +401,13 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY BYTE* pConcatenated; size_t used = 0; - if (Stream_GetRemainingLength(stream) < 6) + if (!Stream_CheckAndLogRequiredLength(TAG, stream, 6)) goto fail; Stream_Read_UINT16(stream, segmentCount); /* segmentCount (2 bytes) */ Stream_Read_UINT32(stream, uncompressedSize); /* uncompressedSize (4 bytes) */ - if (Stream_GetRemainingLength(stream) / sizeof(UINT32) < segmentCount) + if (!Stream_CheckAndLogRequiredLength(TAG, stream, sizeof(UINT32) * segmentCount)) goto fail; pConcatenated = (BYTE*)malloc(uncompressedSize); @@ -420,7 +420,7 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY for (segmentNumber = 0; segmentNumber < segmentCount; segmentNumber++) { - if (Stream_GetRemainingLength(stream) < sizeof(UINT32)) + if (!Stream_CheckAndLogRequiredLength(TAG, stream, sizeof(UINT32))) goto fail; Stream_Read_UINT32(stream, segmentSize); /* segmentSize (4 bytes) */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 357864471..223f680c7 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -26,6 +26,7 @@ #include #include +#include #include "../core/settings.h" #include "../core/certificate.h" @@ -781,6 +782,7 @@ void freerdp_dynamic_channel_collection_free(rdpSettings* settings) { UINT32 i; + WINPR_ASSERT(settings); for (i = 0; i < freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount); i++) { freerdp_addin_argv_free(settings->DynamicChannelArray[i]); @@ -796,6 +798,8 @@ void freerdp_target_net_addresses_free(rdpSettings* settings) { UINT32 index; + WINPR_ASSERT(settings); + for (index = 0; index < settings->TargetNetAddressCount; index++) free(settings->TargetNetAddresses[index]); @@ -1159,7 +1163,19 @@ BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, size_t id, const vo { case FreeRDP_RdpServerCertificate: certificate_free(settings->RdpServerCertificate); - settings->RdpServerCertificate = (rdpCertificate*)cnv.v; + + if (len > 1) + { + WLog_ERR(TAG, "FreeRDP_RdpServerCertificate::len must be 0 or 1"); + return FALSE; + } + settings->RdpServerCertificate = cnv.v; + if (!settings->RdpServerCertificate && (len > 0)) + { + settings->RdpServerCertificate = certificate_new(); + if (!settings->RdpServerCertificate) + return FALSE; + } return TRUE; case FreeRDP_RdpServerRsaKey: key_free(settings->RdpServerRsaKey); @@ -1210,12 +1226,20 @@ BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, size_t id, const vo sizeof(CHANNEL_DEF))) return FALSE; return freerdp_settings_set_uint32(settings, FreeRDP_ChannelCount, len); - case FreeRDP_ClientAutoReconnectCookie: - case FreeRDP_ServerAutoReconnectCookie: case FreeRDP_MonitorDefArray: + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, + sizeof(rdpMonitor)); + case FreeRDP_ClientAutoReconnectCookie: + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, + sizeof(ARC_CS_PRIVATE_PACKET)); + case FreeRDP_ServerAutoReconnectCookie: + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, + sizeof(ARC_SC_PRIVATE_PACKET)); + case FreeRDP_ClientTimeZone: + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, + sizeof(TIME_ZONE_INFORMATION)); case FreeRDP_ReceivedCapabilities: case FreeRDP_OrderSupport: - case FreeRDP_ClientTimeZone: case FreeRDP_BitmapCacheV2CellInfo: case FreeRDP_GlyphCache: case FreeRDP_FragCache: @@ -1345,6 +1369,11 @@ BOOL freerdp_settings_set_pointer_array(rdpSettings* settings, size_t id, size_t return FALSE; settings->ChannelDefArray[offset] = *(const CHANNEL_DEF*)data; return TRUE; + case FreeRDP_MonitorDefArray: + if (offset > freerdp_settings_get_uint32(settings, FreeRDP_MonitorDefArraySize)) + return FALSE; + settings->MonitorDefArray[offset] = *(const rdpMonitor*)data; + return TRUE; default: WLog_WARN(TAG, "Invalid id %" PRIuz " for %s", id, __FUNCTION__); return FALSE; diff --git a/libfreerdp/common/settings_getters.c b/libfreerdp/common/settings_getters.c index 3b5228ec7..d8bd42c91 100644 --- a/libfreerdp/common/settings_getters.c +++ b/libfreerdp/common/settings_getters.c @@ -1393,6 +1393,9 @@ UINT32 freerdp_settings_get_uint32(const rdpSettings* settings, size_t id) case FreeRDP_ClientRandomLength: return settings->ClientRandomLength; + case FreeRDP_ClientSessionId: + return settings->ClientSessionId; + case FreeRDP_ClusterInfoFlags: return settings->ClusterInfoFlags; @@ -1525,12 +1528,18 @@ UINT32 freerdp_settings_get_uint32(const rdpSettings* settings, size_t id) case FreeRDP_MaxTimeInCheckLoop: return settings->MaxTimeInCheckLoop; + case FreeRDP_MonitorAttributeFlags: + return settings->MonitorAttributeFlags; + case FreeRDP_MonitorCount: return settings->MonitorCount; case FreeRDP_MonitorDefArraySize: return settings->MonitorDefArraySize; + case FreeRDP_MonitorFlags: + return settings->MonitorFlags; + case FreeRDP_MonitorLocalShiftX: return settings->MonitorLocalShiftX; @@ -1770,6 +1779,10 @@ BOOL freerdp_settings_set_uint32(rdpSettings* settings, size_t id, UINT32 val) settings->ClientRandomLength = cnv.c; break; + case FreeRDP_ClientSessionId: + settings->ClientSessionId = cnv.c; + break; + case FreeRDP_ClusterInfoFlags: settings->ClusterInfoFlags = cnv.c; break; @@ -1946,6 +1959,10 @@ BOOL freerdp_settings_set_uint32(rdpSettings* settings, size_t id, UINT32 val) settings->MaxTimeInCheckLoop = cnv.c; break; + case FreeRDP_MonitorAttributeFlags: + settings->MonitorAttributeFlags = cnv.c; + break; + case FreeRDP_MonitorCount: settings->MonitorCount = cnv.c; break; @@ -1954,6 +1971,10 @@ BOOL freerdp_settings_set_uint32(rdpSettings* settings, size_t id, UINT32 val) settings->MonitorDefArraySize = cnv.c; break; + case FreeRDP_MonitorFlags: + settings->MonitorFlags = cnv.c; + break; + case FreeRDP_MonitorLocalShiftX: settings->MonitorLocalShiftX = cnv.c; break; diff --git a/libfreerdp/common/settings_str.c b/libfreerdp/common/settings_str.c index b5f3b3527..f238a1743 100644 --- a/libfreerdp/common/settings_str.c +++ b/libfreerdp/common/settings_str.c @@ -200,6 +200,7 @@ static const struct settings_str_entry settings_map[] = { { FreeRDP_ChannelDefArraySize, 3, "FreeRDP_ChannelDefArraySize" }, { FreeRDP_ClientBuild, 3, "FreeRDP_ClientBuild" }, { FreeRDP_ClientRandomLength, 3, "FreeRDP_ClientRandomLength" }, + { FreeRDP_ClientSessionId, 3, "FreeRDP_ClientSessionId" }, { FreeRDP_ClusterInfoFlags, 3, "FreeRDP_ClusterInfoFlags" }, { FreeRDP_ColorDepth, 3, "FreeRDP_ColorDepth" }, { FreeRDP_CompDeskSupportLevel, 3, "FreeRDP_CompDeskSupportLevel" }, @@ -244,8 +245,10 @@ static const struct settings_str_entry settings_map[] = { { FreeRDP_LargePointerFlag, 3, "FreeRDP_LargePointerFlag" }, { FreeRDP_LoadBalanceInfoLength, 3, "FreeRDP_LoadBalanceInfoLength" }, { FreeRDP_MaxTimeInCheckLoop, 3, "FreeRDP_MaxTimeInCheckLoop" }, + { FreeRDP_MonitorAttributeFlags, 3, "FreeRDP_MonitorAttributeFlags" }, { FreeRDP_MonitorCount, 3, "FreeRDP_MonitorCount" }, { FreeRDP_MonitorDefArraySize, 3, "FreeRDP_MonitorDefArraySize" }, + { FreeRDP_MonitorFlags, 3, "FreeRDP_MonitorFlags" }, { FreeRDP_MonitorLocalShiftX, 3, "FreeRDP_MonitorLocalShiftX" }, { FreeRDP_MonitorLocalShiftY, 3, "FreeRDP_MonitorLocalShiftY" }, { FreeRDP_MultifragMaxRequestSize, 3, "FreeRDP_MultifragMaxRequestSize" }, diff --git a/libfreerdp/core/activation.c b/libfreerdp/core/activation.c index 162c6d8f9..2a8bb5b3b 100644 --- a/libfreerdp/core/activation.c +++ b/libfreerdp/core/activation.c @@ -102,13 +102,16 @@ BOOL rdp_recv_client_synchronize_pdu(rdpRdp* rdp, wStream* s) rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, messageType); /* messageType (2 bytes) */ if (messageType != SYNCMSGTYPE_SYNC) + { + WLog_WARN(TAG, "client synchronize PDU message type invalid, got %" PRIu16, messageType); return FALSE; + } /* targetUser (2 bytes) */ Stream_Seek_UINT16(s); @@ -137,7 +140,7 @@ static BOOL rdp_recv_control_pdu(wStream* s, UINT16* action) WINPR_ASSERT(s); WINPR_ASSERT(action); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT16(s, *action); /* action (2 bytes) */ @@ -300,8 +303,12 @@ BOOL rdp_recv_client_persistent_key_list_pdu(wStream* s) WINPR_ASSERT(s); /* 2.2.1.17.1 Persistent Key List PDU Data (TS_BITMAPCACHE_PERSISTENT_LIST_PDU) */ - if (Stream_GetRemainingLength(s) < 21) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 21)) + { + WLog_ERR(TAG, "short TS_BITMAPCACHE_PERSISTENT_LIST_PDU, need 21 bytes, got %" PRIuz, + Stream_GetRemainingLength(s)); return FALSE; + } /* Read numEntriesCacheX for variable length data in PDU */ for (x = 0; x < 5; x++) { @@ -335,9 +342,20 @@ BOOL rdp_recv_client_persistent_key_list_pdu(wStream* s) /* Skip padding */ if (!Stream_SafeSeek(s, 3)) + { + WLog_ERR(TAG, "short TS_BITMAPCACHE_PERSISTENT_LIST_PDU, need 3 bytes, got %" PRIuz, + Stream_GetRemainingLength(s)); return FALSE; + } /* Skip actual entries sent by client */ - return Stream_SafeSeek(s, count * sizeof(UINT64)); + if (!Stream_SafeSeek(s, count * sizeof(UINT64))) + { + WLog_ERR(TAG, + "short TS_BITMAPCACHE_PERSISTENT_LIST_PDU, need %" PRIuz " bytes, got %" PRIuz, + count * sizeof(UINT64), Stream_GetRemainingLength(s)); + return FALSE; + } + return TRUE; } static BOOL rdp_write_client_font_list_pdu(wStream* s, UINT16 flags) @@ -385,8 +403,9 @@ BOOL rdp_recv_server_font_map_pdu(rdpRdp* rdp, wStream* s) WINPR_ASSERT(rdp); WINPR_ASSERT(s); + WLog_WARN(TAG, "Invalid PDU received: FONT_MAP only allowed client -> server"); rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU; - return TRUE; + return FALSE; } BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s) @@ -449,17 +468,17 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s) { do { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) break; Stream_Read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) break; Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ - if (Stream_GetRemainingLength(s) < lengthSourceDescriptor) + if (!Stream_CheckAndLogRequiredLength(TAG, s, lengthSourceDescriptor)) break; Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */ @@ -475,7 +494,7 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s) return FALSE; WINPR_ASSERT(rdp->context); - if (freerdp_shall_disconnect(rdp->context->instance)) + if (freerdp_shall_disconnect_context(rdp->context)) return TRUE; if (rdp_get_state(rdp) == CONNECTION_STATE_ACTIVE) diff --git a/libfreerdp/core/autodetect.c b/libfreerdp/core/autodetect.c index bd09fd0e2..bcb194c2c 100644 --- a/libfreerdp/core/autodetect.c +++ b/libfreerdp/core/autodetect.c @@ -441,7 +441,7 @@ static BOOL autodetect_recv_bandwidth_measure_payload(rdpRdp* rdp, wStream* s, if (autodetectReqPdu->headerLength != 0x08) return FALSE; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(AUTODETECT_TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, payloadLength); /* payloadLength (2 bytes) */ @@ -465,7 +465,7 @@ static BOOL autodetect_recv_bandwidth_measure_stop(rdpRdp* rdp, wStream* s, if (autodetectReqPdu->headerLength != 0x08) return FALSE; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(AUTODETECT_TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, payloadLength); /* payloadLength (2 bytes) */ @@ -509,7 +509,7 @@ static BOOL autodetect_recv_bandwidth_measure_results(rdpRdp* rdp, wStream* s, return FALSE; WLog_VRB(AUTODETECT_TAG, "received Bandwidth Measure Results PDU"); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(AUTODETECT_TAG, s, 8)) return -1; Stream_Read_UINT32(s, rdp->autodetect->bandwidthMeasureTimeDelta); /* timeDelta (4 bytes) */ Stream_Read_UINT32(s, rdp->autodetect->bandwidthMeasureByteCount); /* byteCount (4 bytes) */ @@ -537,7 +537,8 @@ static BOOL autodetect_recv_netchar_result(rdpRdp* rdp, wStream* s, case RDP_NETCHAR_RESULTS_0x0840: /* baseRTT and averageRTT fields are present (bandwidth field is not) */ - if ((autodetectReqPdu->headerLength != 0x0E) || (Stream_GetRemainingLength(s) < 8)) + if ((autodetectReqPdu->headerLength != 0x0E) || + (!Stream_CheckAndLogRequiredLength(AUTODETECT_TAG, s, 8))) return FALSE; Stream_Read_UINT32(s, rdp->autodetect->netCharBaseRTT); /* baseRTT (4 bytes) */ @@ -547,7 +548,8 @@ static BOOL autodetect_recv_netchar_result(rdpRdp* rdp, wStream* s, case RDP_NETCHAR_RESULTS_0x0880: /* bandwidth and averageRTT fields are present (baseRTT field is not) */ - if ((autodetectReqPdu->headerLength != 0x0E) || (Stream_GetRemainingLength(s) < 8)) + if ((autodetectReqPdu->headerLength != 0x0E) || + (!Stream_CheckAndLogRequiredLength(AUTODETECT_TAG, s, 8))) return FALSE; Stream_Read_UINT32(s, rdp->autodetect->netCharBandwidth); /* bandwidth (4 bytes) */ @@ -557,7 +559,8 @@ static BOOL autodetect_recv_netchar_result(rdpRdp* rdp, wStream* s, case RDP_NETCHAR_RESULTS_0x08C0: /* baseRTT, bandwidth, and averageRTT fields are present */ - if ((autodetectReqPdu->headerLength != 0x12) || (Stream_GetRemainingLength(s) < 12)) + if ((autodetectReqPdu->headerLength != 0x12) || + (!Stream_CheckAndLogRequiredLength(AUTODETECT_TAG, s, 12))) return FALSE; Stream_Read_UINT32(s, rdp->autodetect->netCharBaseRTT); /* baseRTT (4 bytes) */ @@ -581,7 +584,7 @@ int rdp_recv_autodetect_request_packet(rdpRdp* rdp, wStream* s) AUTODETECT_REQ_PDU autodetectReqPdu; BOOL success = FALSE; - if (Stream_GetRemainingLength(s) < 6) + if (!Stream_CheckAndLogRequiredLength(AUTODETECT_TAG, s, 6)) return -1; Stream_Read_UINT8(s, autodetectReqPdu.headerLength); /* headerLength (1 byte) */ @@ -658,7 +661,7 @@ int rdp_recv_autodetect_response_packet(rdpRdp* rdp, wStream* s) AUTODETECT_RSP_PDU autodetectRspPdu; BOOL success = FALSE; - if (Stream_GetRemainingLength(s) < 6) + if (!Stream_CheckAndLogRequiredLength(AUTODETECT_TAG, s, 6)) return -1; Stream_Read_UINT8(s, autodetectRspPdu.headerLength); /* headerLength (1 byte) */ diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index 3bb2f37fb..10cc99e37 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -107,8 +107,13 @@ static const GUID CODEC_GUID_JPEG = { static BOOL rdp_read_capability_set_header(wStream* s, UINT16* length, UINT16* type) { - if (Stream_GetRemainingLength(s) < 4) + WINPR_ASSERT(s); + WINPR_ASSERT(length); + WINPR_ASSERT(type); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; + Stream_Read_UINT16(s, *type); /* capabilitySetType */ Stream_Read_UINT16(s, *length); /* lengthCapability */ if (*length < 4) @@ -118,6 +123,9 @@ static BOOL rdp_read_capability_set_header(wStream* s, UINT16* length, UINT16* t static void rdp_write_capability_set_header(wStream* s, UINT16 length, UINT16 type) { + WINPR_ASSERT(s); + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 4); + Stream_Write_UINT16(s, type); /* capabilitySetType */ Stream_Write_UINT16(s, length); /* lengthCapability */ } @@ -157,7 +165,7 @@ static BOOL rdp_read_general_capability_set(wStream* s, rdpSettings* settings) BYTE refreshRectSupport; BYTE suppressOutputSupport; - if (Stream_GetRemainingLength(s) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return FALSE; if (settings->ServerMode) @@ -278,7 +286,7 @@ static BOOL rdp_print_general_capability_set(wStream* s) BYTE refreshRectSupport; BYTE suppressOutputSupport; - if (Stream_GetRemainingLength(s) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20) return FALSE; WLog_VRB(TAG, "GeneralCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); @@ -324,7 +332,7 @@ static BOOL rdp_read_bitmap_capability_set(wStream* s, rdpSettings* settings) UINT16 desktopResizeFlag; UINT16 preferredBitsPerPixel; - if (Stream_GetRemainingLength(s) < 24) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 24)) return FALSE; Stream_Read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ @@ -452,7 +460,7 @@ static BOOL rdp_print_bitmap_capability_set(wStream* s) UINT16 pad2OctetsB; WLog_VRB(TAG, "BitmapCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 24) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 24) return FALSE; Stream_Read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ @@ -502,7 +510,7 @@ static BOOL rdp_read_order_capability_set(wStream* s, rdpSettings* settings) BOOL BitmapCacheV3Enabled = FALSE; BOOL FrameMarkerCommandEnabled = FALSE; - if (Stream_GetRemainingLength(s) < 84) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 84)) return FALSE; Stream_Seek(s, 16); /* terminalDescriptor (16 bytes) */ @@ -630,7 +638,7 @@ static BOOL rdp_print_order_capability_set(wStream* s) UINT16 pad2OctetsE; WLog_VRB(TAG, "OrderCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 84) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 84) return FALSE; Stream_Read(s, terminalDescriptor, 16); /* terminalDescriptor (16 bytes) */ @@ -714,7 +722,7 @@ static BOOL rdp_print_order_capability_set(wStream* s) static BOOL rdp_read_bitmap_cache_capability_set(wStream* s, rdpSettings* settings) { WINPR_UNUSED(settings); - if (Stream_GetRemainingLength(s) < 36) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 36)) return FALSE; Stream_Seek_UINT32(s); /* pad1 (4 bytes) */ @@ -791,7 +799,7 @@ static BOOL rdp_print_bitmap_cache_capability_set(wStream* s) UINT16 Cache2MaximumCellSize; WLog_VRB(TAG, "BitmapCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 36) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 36) return FALSE; Stream_Read_UINT32(s, pad1); /* pad1 (4 bytes) */ @@ -833,7 +841,7 @@ static BOOL rdp_print_bitmap_cache_capability_set(wStream* s) static BOOL rdp_read_control_capability_set(wStream* s, rdpSettings* settings) { WINPR_UNUSED(settings); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Seek_UINT16(s); /* controlFlags (2 bytes) */ @@ -877,7 +885,7 @@ static BOOL rdp_print_control_capability_set(wStream* s) UINT16 detachInterest; WLog_VRB(TAG, "ControlCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8) return FALSE; Stream_Read_UINT16(s, controlFlags); /* controlFlags (2 bytes) */ @@ -903,7 +911,7 @@ static BOOL rdp_print_control_capability_set(wStream* s) static BOOL rdp_read_window_activation_capability_set(wStream* s, rdpSettings* settings) { WINPR_UNUSED(settings); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Seek_UINT16(s); /* helpKeyFlag (2 bytes) */ @@ -948,7 +956,7 @@ static BOOL rdp_print_window_activation_capability_set(wStream* s) WLog_VRB(TAG, "WindowActivationCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8) return FALSE; Stream_Read_UINT16(s, helpKeyFlag); /* helpKeyFlag (2 bytes) */ @@ -977,7 +985,7 @@ static BOOL rdp_read_pointer_capability_set(wStream* s, rdpSettings* settings) UINT16 colorPointerCacheSize; UINT16 pointerCacheSize; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ @@ -1041,7 +1049,7 @@ static BOOL rdp_print_pointer_capability_set(wStream* s) UINT16 colorPointerCacheSize; UINT16 pointerCacheSize; - if (Stream_GetRemainingLength(s) < 6) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6) return FALSE; WLog_VRB(TAG, "PointerCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); @@ -1066,7 +1074,7 @@ static BOOL rdp_print_pointer_capability_set(wStream* s) static BOOL rdp_read_share_capability_set(wStream* s, rdpSettings* settings) { WINPR_UNUSED(settings); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Seek_UINT16(s); /* nodeId (2 bytes) */ @@ -1105,7 +1113,7 @@ static BOOL rdp_print_share_capability_set(wStream* s) UINT16 pad2Octets; WLog_VRB(TAG, "ShareCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) return FALSE; Stream_Read_UINT16(s, nodeId); /* nodeId (2 bytes) */ @@ -1127,7 +1135,7 @@ static BOOL rdp_print_share_capability_set(wStream* s) static BOOL rdp_read_color_cache_capability_set(wStream* s, rdpSettings* settings) { WINPR_UNUSED(settings); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Seek_UINT16(s); /* colorTableCacheSize (2 bytes) */ @@ -1165,7 +1173,7 @@ static BOOL rdp_print_color_cache_capability_set(wStream* s) UINT16 pad2Octets; WLog_VRB(TAG, "ColorCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) return FALSE; Stream_Read_UINT16(s, colorTableCacheSize); /* colorTableCacheSize (2 bytes) */ @@ -1188,7 +1196,7 @@ static BOOL rdp_read_sound_capability_set(wStream* s, rdpSettings* settings) { UINT16 soundFlags; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ @@ -1228,7 +1236,7 @@ static BOOL rdp_print_sound_capability_set(wStream* s) UINT16 pad2OctetsA; WLog_VRB(TAG, "SoundCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) return FALSE; Stream_Read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ @@ -1251,7 +1259,7 @@ static BOOL rdp_read_input_capability_set(wStream* s, rdpSettings* settings) { UINT16 inputFlags; - if (Stream_GetRemainingLength(s) < 84) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 84)) return FALSE; Stream_Read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ @@ -1361,7 +1369,7 @@ static BOOL rdp_print_input_capability_set(wStream* s) UINT32 keyboardFunctionKey; WLog_VRB(TAG, "InputCapabilitySet (length %" PRIuz ")", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 84) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 84) return FALSE; Stream_Read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ @@ -1484,7 +1492,7 @@ static BOOL rdp_print_brush_capability_set(wStream* s) UINT32 brushSupportLevel; WLog_VRB(TAG, "BrushCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) return FALSE; Stream_Read_UINT32(s, brushSupportLevel); /* brushSupportLevel (4 bytes) */ @@ -1527,7 +1535,7 @@ static void rdp_write_cache_definition(wStream* s, GLYPH_CACHE_DEFINITION* cache static BOOL rdp_read_glyph_cache_capability_set(wStream* s, rdpSettings* settings) { - if (Stream_GetRemainingLength(s) < 48) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 48)) return FALSE; /* glyphCache (40 bytes) */ @@ -1592,7 +1600,7 @@ static BOOL rdp_print_glyph_cache_capability_set(wStream* s) UINT16 pad2Octets; WLog_VRB(TAG, "GlyphCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 48) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 48) return FALSE; /* glyphCache (40 bytes) */ @@ -1649,7 +1657,7 @@ static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wStream* s, rdpSettin { UINT32 offscreenSupportLevel; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ @@ -1703,7 +1711,7 @@ static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wStream* s) WLog_VRB(TAG, "OffscreenBitmapCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8) return FALSE; Stream_Read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ @@ -1728,7 +1736,7 @@ static BOOL rdp_read_bitmap_cache_host_support_capability_set(wStream* s, rdpSet { BYTE cacheVersion; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT8(s, cacheVersion); /* cacheVersion (1 byte) */ @@ -1775,7 +1783,7 @@ static BOOL rdp_print_bitmap_cache_host_support_capability_set(wStream* s) WLog_VRB(TAG, "BitmapCacheHostSupportCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) return FALSE; Stream_Read_UINT8(s, cacheVersion); /* cacheVersion (1 byte) */ @@ -1822,7 +1830,7 @@ static void rdp_write_bitmap_cache_cell_info(wStream* s, BITMAP_CACHE_V2_CELL_IN static BOOL rdp_read_bitmap_cache_v2_capability_set(wStream* s, rdpSettings* settings) { WINPR_UNUSED(settings); - if (Stream_GetRemainingLength(s) < 36) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 36)) return FALSE; Stream_Seek_UINT16(s); /* cacheFlags (2 bytes) */ @@ -1886,7 +1894,7 @@ static BOOL rdp_print_bitmap_cache_v2_capability_set(wStream* s) BITMAP_CACHE_V2_CELL_INFO bitmapCacheV2CellInfo[5]; WLog_VRB(TAG, "BitmapCacheV2CapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 36) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 36) return FALSE; Stream_Read_UINT16(s, cacheFlags); /* cacheFlags (2 bytes) */ @@ -1933,7 +1941,7 @@ static BOOL rdp_read_virtual_channel_capability_set(wStream* s, rdpSettings* set UINT32 flags; UINT32 VCChunkSize; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, flags); /* flags (4 bytes) */ @@ -1980,7 +1988,7 @@ static BOOL rdp_print_virtual_channel_capability_set(wStream* s) UINT32 VCChunkSize; WLog_VRB(TAG, "VirtualChannelCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) return FALSE; Stream_Read_UINT32(s, flags); /* flags (4 bytes) */ @@ -2008,7 +2016,7 @@ static BOOL rdp_read_draw_nine_grid_cache_capability_set(wStream* s, rdpSettings { UINT32 drawNineGridSupportLevel; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ @@ -2086,7 +2094,7 @@ static BOOL rdp_print_draw_nine_grid_cache_capability_set(wStream* s) WLog_VRB(TAG, "DrawNineGridCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8) return FALSE; Stream_Read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ @@ -2109,7 +2117,7 @@ static BOOL rdp_read_draw_gdiplus_cache_capability_set(wStream* s, rdpSettings* UINT32 drawGDIPlusSupportLevel; UINT32 drawGdiplusCacheLevel; - if (Stream_GetRemainingLength(s) < 36) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 36)) return FALSE; Stream_Read_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ @@ -2170,7 +2178,7 @@ static BOOL rdp_print_draw_gdiplus_cache_capability_set(wStream* s) WLog_VRB(TAG, "DrawGdiPlusCacheCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 36) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 36) return FALSE; Stream_Read_UINT32(s, drawGdiPlusSupportLevel); /* drawGdiPlusSupportLevel (4 bytes) */ @@ -2195,7 +2203,7 @@ static BOOL rdp_read_remote_programs_capability_set(wStream* s, rdpSettings* set { UINT32 railSupportLevel; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ @@ -2264,7 +2272,7 @@ static BOOL rdp_print_remote_programs_capability_set(wStream* s) UINT32 railSupportLevel; WLog_VRB(TAG, "RemoteProgramsCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) return FALSE; Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ @@ -2283,7 +2291,7 @@ static BOOL rdp_print_remote_programs_capability_set(wStream* s) static BOOL rdp_read_window_list_capability_set(wStream* s, rdpSettings* settings) { - if (Stream_GetRemainingLength(s) < 7) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 7)) return FALSE; Stream_Read_UINT32(s, settings->RemoteWndSupportLevel); /* wndSupportLevel (4 bytes) */ @@ -2325,7 +2333,7 @@ static BOOL rdp_print_window_list_capability_set(wStream* s) UINT16 numIconCacheEntries; WLog_VRB(TAG, "WindowListCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 7) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 7) return FALSE; Stream_Read_UINT32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */ @@ -2349,7 +2357,7 @@ static BOOL rdp_print_window_list_capability_set(wStream* s) static BOOL rdp_read_desktop_composition_capability_set(wStream* s, rdpSettings* settings) { WINPR_UNUSED(settings); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Seek_UINT16(s); /* compDeskSupportLevel (2 bytes) */ @@ -2387,7 +2395,7 @@ static BOOL rdp_print_desktop_composition_capability_set(wStream* s) WLog_VRB(TAG, "DesktopCompositionCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2) return FALSE; Stream_Read_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ @@ -2408,7 +2416,7 @@ static BOOL rdp_read_multifragment_update_capability_set(wStream* s, rdpSettings { UINT32 multifragMaxRequestSize; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, multifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ @@ -2513,7 +2521,7 @@ static BOOL rdp_print_multifragment_update_capability_set(wStream* s) WLog_VRB(TAG, "MultifragmentUpdateCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) return FALSE; Stream_Read_UINT32(s, maxRequestSize); /* maxRequestSize (4 bytes) */ @@ -2534,7 +2542,7 @@ static BOOL rdp_read_large_pointer_capability_set(wStream* s, rdpSettings* setti { UINT16 largePointerSupportFlags; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ @@ -2580,7 +2588,7 @@ static BOOL rdp_print_large_pointer_capability_set(wStream* s) UINT16 largePointerSupportFlags; WLog_VRB(TAG, "LargePointerCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2) return FALSE; Stream_Read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ @@ -2601,7 +2609,7 @@ static BOOL rdp_read_surface_commands_capability_set(wStream* s, rdpSettings* se { UINT32 cmdFlags; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */ @@ -2647,7 +2655,7 @@ static BOOL rdp_print_surface_commands_capability_set(wStream* s) WLog_VRB(TAG, "SurfaceCommandsCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8) return FALSE; Stream_Read_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */ @@ -2691,7 +2699,7 @@ static char* rdp_get_bitmap_codec_guid_name(const GUID* guid) static BOOL rdp_read_bitmap_codec_guid(wStream* s, GUID* guid) { BYTE g[16]; - if (Stream_GetRemainingLength(s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return FALSE; Stream_Read(s, g, 16); guid->Data1 = ((UINT32)g[3] << 24U) | ((UINT32)g[2] << 16U) | (g[1] << 8U) | g[0]; @@ -2750,7 +2758,7 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, rdpSettings* setti BOOL guidRemoteFx = FALSE; BOOL guidRemoteFxImage = FALSE; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ @@ -2763,7 +2771,7 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, rdpSettings* setti if (!rdp_read_bitmap_codec_guid(s, &codecGuid)) /* codecGuid (16 bytes) */ return FALSE; - if (Stream_GetRemainingLength(s) < 3) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3)) return FALSE; Stream_Read_UINT8(s, codecId); /* codecId (1 byte) */ Stream_Read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ @@ -2781,7 +2789,7 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, rdpSettings* setti UINT32 captureFlags; guidRemoteFx = TRUE; settings->RemoteFxCodecId = codecId; - if (Stream_GetRemainingLength(sub) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, sub, 12)) return FALSE; Stream_Read_UINT32(sub, rfxPropsLength); /* length (4 bytes) */ Stream_Read_UINT32(sub, captureFlags); /* captureFlags (4 bytes) */ @@ -2799,7 +2807,7 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, rdpSettings* setti UINT16 numIcaps; UINT16 icapLen; /* TS_RFX_CAPS */ - if (Stream_GetRemainingLength(sub) < 21) + if (!Stream_CheckAndLogRequiredLength(TAG, sub, 21)) return FALSE; Stream_Read_UINT16(sub, blockType); /* blockType (2 bytes) */ Stream_Read_UINT32(sub, blockLen); /* blockLen (4 bytes) */ @@ -2840,7 +2848,7 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, rdpSettings* setti BYTE transformBits; BYTE entropyBits; /* TS_RFX_ICAP */ - if (Stream_GetRemainingLength(sub) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, sub, 8)) return FALSE; Stream_Read_UINT16(sub, version); /* version (2 bytes) */ Stream_Read_UINT16(sub, tileSize); /* tileSize (2 bytes) */ @@ -2886,7 +2894,7 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, rdpSettings* setti BYTE fAllowDynamicFidelity; guidNSCodec = TRUE; settings->NSCodecId = codecId; - if (Stream_GetRemainingLength(sub) < 3) + if (!Stream_CheckAndLogRequiredLength(TAG, sub, 3)) return FALSE; Stream_Read_UINT8(sub, fAllowDynamicFidelity); /* fAllowDynamicFidelity (1 byte) */ Stream_Read_UINT8(sub, fAllowSubsampling); /* fAllowSubsampling (1 byte) */ @@ -3212,7 +3220,7 @@ static BOOL rdp_print_bitmap_codecs_capability_set(wStream* s) WLog_VRB(TAG, "BitmapCodecsCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1) return FALSE; Stream_Read_UINT8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ @@ -3222,7 +3230,7 @@ static BOOL rdp_print_bitmap_codecs_capability_set(wStream* s) { if (!rdp_read_bitmap_codec_guid(s, &codecGuid)) /* codecGuid (16 bytes) */ return FALSE; - if (Stream_GetRemainingLength(s) < 3) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3) return FALSE; Stream_Read_UINT8(s, codecId); /* codecId (1 byte) */ WLog_VRB(TAG, "\tcodecGuid: 0x"); @@ -3250,7 +3258,7 @@ static BOOL rdp_print_bitmap_codecs_capability_set(wStream* s) static BOOL rdp_read_frame_acknowledge_capability_set(wStream* s, rdpSettings* settings) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; if (settings->ServerMode) @@ -3292,7 +3300,7 @@ static BOOL rdp_print_frame_acknowledge_capability_set(wStream* s) WLog_VRB(TAG, "FrameAcknowledgeCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) return FALSE; Stream_Read_UINT32(s, frameAcknowledge); /* frameAcknowledge (4 bytes) */ @@ -3306,7 +3314,7 @@ static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wStream* s, rdpSett BYTE bitmapCacheV3CodecId; WINPR_UNUSED(settings); - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */ @@ -3337,7 +3345,7 @@ static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wStream* s) WLog_VRB(TAG, "BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz "):", Stream_GetRemainingLength(s)); - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1) return FALSE; Stream_Read_UINT8(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */ @@ -3357,7 +3365,7 @@ BOOL rdp_print_capability_sets(wStream* s, size_t start, BOOL receiving) Stream_SetPosition(s, start); if (receiving) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) goto fail; } else @@ -3593,7 +3601,7 @@ static BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 t #ifdef WITH_DEBUG_CAPABILITIES const size_t capstart = Stream_GetPosition(s); #endif - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ @@ -3878,7 +3886,7 @@ BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId, UIN if (!rdp_read_header(rdp, s, length, pChannelId)) return FALSE; - if (freerdp_shall_disconnect(rdp->context->instance)) + if (freerdp_shall_disconnect_context(rdp->context)) return TRUE; if (rdp->settings->UseRdpSecurityLayer) @@ -3926,7 +3934,7 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) if (!rdp_recv_get_active_header(rdp, s, &channelId, &length)) return FALSE; - if (freerdp_shall_disconnect(rdp->context->instance)) + if (freerdp_shall_disconnect_context(rdp->context)) return TRUE; if (!rdp_read_share_control_header(s, NULL, NULL, &pduType, &pduSource)) @@ -3958,7 +3966,7 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) rdp->settings->PduSource = pduSource; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ @@ -3966,7 +3974,7 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) Stream_Read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ if (!Stream_SafeSeek(s, lengthSourceDescriptor) || - Stream_GetRemainingLength(s) < 4) /* sourceDescriptor */ + !Stream_CheckAndLogRequiredLength(TAG, s, 4)) /* sourceDescriptor */ return FALSE; /* capabilitySets */ @@ -4081,7 +4089,7 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s, UINT16 pduLength) settings = rdp->settings; - if (Stream_GetRemainingLength(s) < 10) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 10)) return FALSE; Stream_Seek_UINT32(s); /* shareId (4 bytes) */ @@ -4089,7 +4097,7 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s, UINT16 pduLength) Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ Stream_Read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ - if (Stream_GetRemainingLength(s) < lengthSourceDescriptor + 4U) + if (!Stream_CheckAndLogRequiredLength(TAG, s, lengthSourceDescriptor + 4U)) return FALSE; Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor */ diff --git a/libfreerdp/core/certificate.c b/libfreerdp/core/certificate.c index a43158f30..83cef6dd7 100644 --- a/libfreerdp/core/certificate.c +++ b/libfreerdp/core/certificate.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -259,7 +260,7 @@ static BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* in /* skip zero padding, if any */ do { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) goto error1; Stream_Peek_UINT8(s, padding); @@ -278,7 +279,7 @@ static BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* in if (modulus_length > UINT32_MAX) goto error1; - if ((Stream_GetRemainingLength(s)) < modulus_length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, modulus_length)) goto error1; info->ModulusLength = (UINT32)modulus_length; @@ -295,7 +296,7 @@ static BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* in error++; - if (((Stream_GetRemainingLength(s)) < exponent_length) || (exponent_length > 4)) + if ((!Stream_CheckAndLogRequiredLength(TAG, s, exponent_length)) || (exponent_length > 4)) goto error2; Stream_Read(s, &info->exponent[4 - exponent_length], exponent_length); @@ -370,7 +371,10 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w UINT32 datalen; BYTE* tmp; - if (Stream_GetRemainingLength(s) < 20) + WINPR_ASSERT(certificate); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return FALSE; Stream_Read(s, magic, 4); @@ -386,7 +390,7 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w Stream_Read_UINT32(s, datalen); Stream_Read(s, certificate->cert_info.exponent, 4); - if ((keylen <= 8) || (Stream_GetRemainingLength(s) < keylen)) + if ((keylen <= 8) || (!Stream_CheckAndLogRequiredLength(TAG, s, keylen))) return FALSE; certificate->cert_info.ModulusLength = keylen - 8; @@ -401,6 +405,39 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w return TRUE; } +static BOOL certificate_write_server_public_key(const rdpCertificate* certificate, wStream* s) +{ + const char magic[4] = "RSA1"; + const UINT16 wPublicKeyBlobType = BB_RSA_KEY_BLOB; + UINT16 wPublicKeyBlobLen = 0; + UINT32 keylen, bitlen, datalen; + + WINPR_ASSERT(certificate); + WINPR_ASSERT(s); + + /* [MS-RDPBCGR] 2.2.1.4.3.1.1.1 RSA Public Key (RSA_PUBLIC_KEY) */ + wPublicKeyBlobLen = sizeof(magic) + 12 + sizeof(certificate->cert_info.exponent) + + certificate->cert_info.ModulusLength + 8; + bitlen = certificate->cert_info.ModulusLength * 8; + keylen = (bitlen / 8) + 8; + datalen = bitlen / 8 - 1; + + if (!Stream_EnsureRemainingCapacity(s, 4 + wPublicKeyBlobLen)) + return FALSE; + + Stream_Write_UINT16(s, wPublicKeyBlobType); + Stream_Write_UINT16(s, wPublicKeyBlobLen); + Stream_Write(s, magic, sizeof(magic)); + Stream_Write_UINT32(s, keylen); + Stream_Write_UINT32(s, bitlen); + Stream_Write_UINT32(s, datalen); + + Stream_Write(s, certificate->cert_info.exponent, sizeof(certificate->cert_info.exponent)); + Stream_Write(s, certificate->cert_info.Modulus, certificate->cert_info.ModulusLength); + Stream_Zero(s, 8); /* 8 bytes of zero padding */ + return TRUE; +} + static BOOL certificate_process_server_public_signature(rdpCertificate* certificate, const BYTE* sigdata, size_t sigdatalen, wStream* s, UINT32 siglen) @@ -490,6 +527,27 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific return TRUE; } +static BOOL certificate_write_server_public_signature(const rdpCertificate* certificate, wStream* s) +{ + const UINT16 wSignatureBlobType = BB_RSA_SIGNATURE_BLOB; + UINT16 wSignatureBlobLen = 72; + char signature[72] = { 0 }; + + WINPR_ASSERT(certificate); + WINPR_ASSERT(s); + + if (!Stream_EnsureRemainingCapacity(s, 4 + wSignatureBlobLen)) + return FALSE; + + Stream_Write_UINT16(s, wSignatureBlobType); + Stream_Write_UINT16(s, wSignatureBlobLen); + + WLog_WARN(TAG, "[%s] TODO: Calcualte proper signature", __FUNCTION__); + + Stream_Write(s, signature, wSignatureBlobLen); + return TRUE; +} + /** * Read a Server Proprietary Certificate.\n * @param certificate certificate module @@ -507,7 +565,7 @@ static BOOL certificate_read_server_proprietary_certificate(rdpCertificate* cert BYTE* sigdata; size_t sigdatalen; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return FALSE; /* -4, because we need to include dwVersion */ @@ -534,11 +592,8 @@ static BOOL certificate_read_server_proprietary_certificate(rdpCertificate* cert Stream_Read_UINT16(s, wPublicKeyBlobLen); - if (Stream_GetRemainingLength(s) < wPublicKeyBlobLen) - { - WLog_ERR(TAG, "not enough bytes for public key(len=%" PRIu16 ")", wPublicKeyBlobLen); + if (!Stream_CheckAndLogRequiredLength(TAG, s, wPublicKeyBlobLen)) return FALSE; - } if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen)) { @@ -546,7 +601,7 @@ static BOOL certificate_read_server_proprietary_certificate(rdpCertificate* cert return FALSE; } - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; sigdatalen = Stream_Pointer(s) - sigdata; @@ -560,11 +615,8 @@ static BOOL certificate_read_server_proprietary_certificate(rdpCertificate* cert Stream_Read_UINT16(s, wSignatureBlobLen); - if (Stream_GetRemainingLength(s) < wSignatureBlobLen) - { - WLog_ERR(TAG, "not enough bytes for signature(len=%" PRIu16 ")", wSignatureBlobLen); + if (!Stream_CheckAndLogRequiredLength(TAG, s, wSignatureBlobLen)) return FALSE; - } if (wSignatureBlobLen != 72) { @@ -578,6 +630,29 @@ static BOOL certificate_read_server_proprietary_certificate(rdpCertificate* cert WLog_ERR(TAG, "unable to parse server public signature"); return FALSE; } + return TRUE; +} + +static BOOL certificate_write_server_proprietary_certificate(const rdpCertificate* certificate, + wStream* s) +{ + const UINT32 dwSigAlgId = SIGNATURE_ALG_RSA; + const UINT32 dwKeyAlgId = KEY_EXCHANGE_ALG_RSA; + + WINPR_ASSERT(certificate); + WINPR_ASSERT(s); + + if (!Stream_EnsureRemainingCapacity(s, 8)) + return FALSE; + + Stream_Write_UINT32(s, dwSigAlgId); + Stream_Write_UINT32(s, dwKeyAlgId); + + if (!certificate_write_server_public_key(certificate, s)) + return FALSE; + + if (!certificate_write_server_public_signature(certificate, s)) + return FALSE; return TRUE; } @@ -596,7 +671,7 @@ static BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certi UINT32 numCertBlobs; DEBUG_CERTIFICATE("Server X.509 Certificate Chain"); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, numCertBlobs); /* numCertBlobs */ @@ -607,12 +682,12 @@ static BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certi for (i = 0; i < numCertBlobs; i++) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, certLength); - if (Stream_GetRemainingLength(s) < certLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, certLength)) return FALSE; DEBUG_CERTIFICATE("X.509 Certificate #%d, length:%" PRIu32 "", i + 1, certLength); @@ -656,6 +731,36 @@ static BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certi return TRUE; } +static BOOL certificate_write_server_x509_certificate_chain(const rdpCertificate* certificate, + wStream* s) +{ + UINT32 i; + UINT32 numCertBlobs = 0; + + WINPR_ASSERT(certificate); + WINPR_ASSERT(s); + + if (certificate->x509_cert_chain) + numCertBlobs = certificate->x509_cert_chain->count; + + if (!Stream_EnsureRemainingCapacity(s, 4)) + return FALSE; + Stream_Write_UINT32(s, numCertBlobs); /* numCertBlobs */ + + for (i = 0; i < numCertBlobs; i++) + { + const rdpCertBlob* cert = &certificate->x509_cert_chain->array[i]; + + if (!Stream_EnsureRemainingCapacity(s, 4 + cert->length)) + return FALSE; + + Stream_Write_UINT32(s, cert->length); + Stream_Write(s, cert->data, cert->length); + } + + return TRUE; +} + /** * Read a Server Certificate.\n * @param certificate certificate module @@ -702,6 +807,37 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, const BYTE return ret; } +BOOL certificate_write_server_certificate(rdpCertificate* certificate, UINT32 dwVersion, wStream* s) +{ + BOOL ret; + + WINPR_ASSERT(certificate); + WINPR_ASSERT(s); + + if (!Stream_EnsureRemainingCapacity(s, 4)) + return FALSE; + Stream_Write_UINT32(s, dwVersion); /* dwVersion (4 bytes) */ + + switch (dwVersion & CERT_CHAIN_VERSION_MASK) + { + case CERT_CHAIN_VERSION_1: + ret = certificate_write_server_proprietary_certificate(certificate, s); + break; + + case CERT_CHAIN_VERSION_2: + ret = certificate_write_server_x509_certificate_chain(certificate, s); + break; + + default: + WLog_ERR(TAG, "invalid certificate chain version:%" PRIu32 "", + dwVersion & CERT_CHAIN_VERSION_MASK); + ret = FALSE; + break; + } + + return ret; +} + rdpRsaKey* key_new_from_content(const char* keycontent, const char* keyfile) { BIO* bio = NULL; diff --git a/libfreerdp/core/certificate.h b/libfreerdp/core/certificate.h index 29a83a256..e5aae89ae 100644 --- a/libfreerdp/core/certificate.h +++ b/libfreerdp/core/certificate.h @@ -47,6 +47,8 @@ FREERDP_LOCAL BOOL certificate_read_server_certificate(rdpCertificate* certificate, const BYTE* server_cert, size_t length); +FREERDP_LOCAL BOOL certificate_write_server_certificate(rdpCertificate* certificate, + UINT32 dwVersion, wStream* s); FREERDP_LOCAL rdpCertificate* certificate_clone(rdpCertificate* certificate); diff --git a/libfreerdp/core/channels.c b/libfreerdp/core/channels.c index de805a574..38487067a 100644 --- a/libfreerdp/core/channels.c +++ b/libfreerdp/core/channels.c @@ -117,7 +117,7 @@ BOOL freerdp_channel_process(freerdp* instance, wStream* s, UINT16 channelId, si } packetLength -= 8; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; /* [MS-RDPBCGR] 3.1.5.2.2 Processing of Virtual Channel PDU @@ -134,7 +134,7 @@ BOOL freerdp_channel_process(freerdp* instance, wStream* s, UINT16 channelId, si chunkLength); return FALSE; } - if (length < chunkLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) { WLog_ERR(TAG, "Expected %" PRIu32 " bytes, but have %" PRIdz, length, chunkLength); return FALSE; @@ -156,7 +156,10 @@ BOOL freerdp_channel_peer_process(freerdp_peer* client, wStream* s, UINT16 chann UINT32 flags; size_t chunkLength; - if (Stream_GetRemainingLength(s) < 8) + WINPR_ASSERT(client); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, length); @@ -199,7 +202,13 @@ BOOL freerdp_channel_peer_process(freerdp_peer* client, wStream* s, UINT16 chann if (!rc) return FALSE; } - return Stream_SafeSeek(s, chunkLength); + if (!Stream_SafeSeek(s, chunkLength)) + { + WLog_WARN(TAG, "Short PDU, need %" PRIuz " bytes, got %" PRIuz, chunkLength, + Stream_GetRemainingLength(s)); + return FALSE; + } + return TRUE; } static const WtsApiFunctionTable FreeRDP_WtsApiFunctionTable = { diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 4669f5673..00bd1e947 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -374,6 +374,7 @@ BOOL rdp_client_connect(rdpRdp* rdp) if (rdp_get_state(rdp) != CONNECTION_STATE_NLA) { + rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CONNECT); if (!mcs_client_begin(rdp->mcs)) return FALSE; } @@ -443,7 +444,7 @@ BOOL rdp_client_disconnect_and_clear(rdpRdp* rdp) context->LastError = FREERDP_ERROR_SUCCESS; clearChannelError(context); - return utils_reset_abort(context); + return utils_reset_abort(rdp); } static BOOL rdp_client_reconnect_channels(rdpRdp* rdp, BOOL redirect) @@ -792,13 +793,13 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) rdp->do_crypt_license = (sec_flags & SEC_LICENSE_ENCRYPT_SC) != 0 ? TRUE : FALSE; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, rand_len); /* rand_len already includes 8 bytes of padding */ - if (Stream_GetRemainingLength(s) < rand_len) + if (!Stream_CheckAndLogRequiredLength(TAG, s, rand_len)) return FALSE; key_len = rdp->settings->RdpServerRsaKey->ModulusLength; @@ -1086,8 +1087,7 @@ int rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s) return rc; } - WINPR_ASSERT(rdp->context); - if (freerdp_shall_disconnect(rdp->context->instance)) + if (freerdp_shall_disconnect_context(rdp->context)) return 0; if (!rdp_send_confirm_active(rdp)) diff --git a/libfreerdp/core/display.c b/libfreerdp/core/display.c index d8a0c5371..5eb5fdbf6 100644 --- a/libfreerdp/core/display.c +++ b/libfreerdp/core/display.c @@ -23,19 +23,20 @@ static BOOL display_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, const MONITOR_DEF* monitorDefArray) { UINT32 index; - const MONITOR_DEF* monitor; if (!Stream_EnsureRemainingCapacity(s, 4 + (monitorCount * 20))) return FALSE; Stream_Write_UINT32(s, monitorCount); /* monitorCount (4 bytes) */ - for (index = 0, monitor = monitorDefArray; index < monitorCount; index++, monitor++) + for (index = 0; index < monitorCount; index++) { - Stream_Write_UINT32(s, monitor->left); /* left (4 bytes) */ - Stream_Write_UINT32(s, monitor->top); /* top (4 bytes) */ - Stream_Write_UINT32(s, monitor->right); /* right (4 bytes) */ - Stream_Write_UINT32(s, monitor->bottom); /* bottom (4 bytes) */ + const MONITOR_DEF* monitor = &monitorDefArray[index]; + + Stream_Write_INT32(s, monitor->left); /* left (4 bytes) */ + Stream_Write_INT32(s, monitor->top); /* top (4 bytes) */ + Stream_Write_INT32(s, monitor->right); /* right (4 bytes) */ + Stream_Write_INT32(s, monitor->bottom); /* bottom (4 bytes) */ Stream_Write_UINT32(s, monitor->flags); /* flags (4 bytes) */ } diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 6df9ab6df..4cea2816b 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -97,7 +97,7 @@ static BOOL fastpath_read_update_header(wStream* s, BYTE* updateCode, BYTE* frag if (!s || !updateCode || !fragmentation || !compression) return FALSE; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, updateHeader); @@ -206,7 +206,7 @@ BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, wStream* s, UINT16* length) if (!s || !length) return FALSE; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, header); @@ -243,11 +243,8 @@ static BOOL fastpath_recv_orders(rdpFastPath* fastpath, wStream* s) return FALSE; } - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "Stream short"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } Stream_Read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */ @@ -282,7 +279,7 @@ static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s) defaultReturn = freerdp_settings_get_bool(context->settings, FreeRDP_DeactivateClientDecoding); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */ @@ -510,7 +507,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (compression == FASTPATH_OUTPUT_COMPRESSION_USED) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return -1; Stream_Read_UINT8(s, compressionFlags); @@ -518,16 +515,13 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) else compressionFlags = 0; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return -1; Stream_Read_UINT16(s, size); - if (Stream_GetRemainingLength(s) < size) - { - WLog_ERR(TAG, "Stream_GetRemainingLength() < size"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, size)) return -1; - } bulkStatus = bulk_decompress(rdp->bulk, Stream_Pointer(s), size, &pDstData, &DstSize, compressionFlags); @@ -658,10 +652,11 @@ static BOOL fastpath_read_input_event_header(wStream* s, BYTE* eventFlags, BYTE* { BYTE eventHeader; - if (!s || !eventFlags || !eventCode) - return FALSE; + WINPR_ASSERT(s); + WINPR_ASSERT(eventFlags); + WINPR_ASSERT(eventCode); - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, eventHeader); /* eventHeader (1 byte) */ @@ -674,16 +669,17 @@ static BOOL fastpath_recv_input_event_scancode(rdpFastPath* fastpath, wStream* s { rdpInput* input; UINT16 flags; - UINT8 code; + UINT16 code; + WINPR_ASSERT(fastpath); + WINPR_ASSERT(fastpath->rdp); + WINPR_ASSERT(fastpath->rdp->input); + WINPR_ASSERT(s); - if (!fastpath || !fastpath->rdp || !fastpath->rdp->input || !s) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; input = fastpath->rdp->input; - if (Stream_GetRemainingLength(s) < 1) - return FALSE; - Stream_Read_UINT8(s, code); /* keyCode (1 byte) */ flags = 0; @@ -707,15 +703,16 @@ static BOOL fastpath_recv_input_event_mouse(rdpFastPath* fastpath, wStream* s, B UINT16 pointerFlags; UINT16 xPos; UINT16 yPos; + WINPR_ASSERT(fastpath); + WINPR_ASSERT(fastpath->rdp); + WINPR_ASSERT(fastpath->rdp->input); + WINPR_ASSERT(s); - if (!fastpath || !fastpath->rdp || !fastpath->rdp->input || !s) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; input = fastpath->rdp->input; - if (Stream_GetRemainingLength(s) < 6) - return FALSE; - Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */ Stream_Read_UINT16(s, xPos); /* xPos (2 bytes) */ Stream_Read_UINT16(s, yPos); /* yPos (2 bytes) */ @@ -729,14 +726,16 @@ static BOOL fastpath_recv_input_event_mousex(rdpFastPath* fastpath, wStream* s, UINT16 xPos; UINT16 yPos; - if (!fastpath || !fastpath->rdp || !fastpath->rdp->input || !s) + WINPR_ASSERT(fastpath); + WINPR_ASSERT(fastpath->rdp); + WINPR_ASSERT(fastpath->rdp->input); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; input = fastpath->rdp->input; - if (Stream_GetRemainingLength(s) < 6) - return FALSE; - Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */ Stream_Read_UINT16(s, xPos); /* xPos (2 bytes) */ Stream_Read_UINT16(s, yPos); /* yPos (2 bytes) */ @@ -747,8 +746,10 @@ static BOOL fastpath_recv_input_event_sync(rdpFastPath* fastpath, wStream* s, BY { rdpInput* input; - if (!fastpath || !fastpath->rdp || !fastpath->rdp->input || !s) - return FALSE; + WINPR_ASSERT(fastpath); + WINPR_ASSERT(fastpath->rdp); + WINPR_ASSERT(fastpath->rdp->input); + WINPR_ASSERT(s); input = fastpath->rdp->input; return IFCALLRESULT(TRUE, input->SynchronizeEvent, input, eventFlags); @@ -759,10 +760,10 @@ static BOOL fastpath_recv_input_event_unicode(rdpFastPath* fastpath, wStream* s, UINT16 unicodeCode; UINT16 flags; - if (!fastpath || !s) - return FALSE; + WINPR_ASSERT(fastpath); + WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, unicodeCode); /* unicodeCode (2 bytes) */ @@ -785,8 +786,8 @@ static BOOL fastpath_recv_input_event(rdpFastPath* fastpath, wStream* s) BYTE eventFlags; BYTE eventCode; - if (!fastpath || !s) - return FALSE; + WINPR_ASSERT(fastpath); + WINPR_ASSERT(s); if (!fastpath_read_input_event_header(s, &eventFlags, &eventCode)) return FALSE; @@ -835,8 +836,8 @@ int fastpath_recv_inputs(rdpFastPath* fastpath, wStream* s) { BYTE i; - if (!fastpath || !s) - return -1; + WINPR_ASSERT(fastpath); + WINPR_ASSERT(s); if (fastpath->numberEvents == 0) { @@ -844,7 +845,7 @@ int fastpath_recv_inputs(rdpFastPath* fastpath, wStream* s) * If numberEvents is not provided in fpInputHeader, it will be provided * as one additional byte here. */ - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return -1; Stream_Read_UINT8(s, fastpath->numberEvents); /* eventHeader (1 byte) */ @@ -920,12 +921,13 @@ wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE ev BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, size_t iNumEvents) { - int state; + CONNECTION_STATE state; BOOL rc = FALSE; rdpRdp* rdp; - UINT16 length; + size_t length; BYTE eventHeader; + WINPR_ASSERT(iNumEvents > 0); if (!s) return FALSE; diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index a26333567..9c4ba2f5c 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -85,7 +85,7 @@ BOOL freerdp_connect(freerdp* instance) instance->ConnectionCallbackState = CLIENT_STATE_INITIAL; freerdp_set_last_error_log(instance->context, FREERDP_ERROR_SUCCESS); clearChannelError(instance->context); - if (!utils_reset_abort(instance->context)) + if (!utils_reset_abort(instance->context->rdp)) return FALSE; rdp = instance->context->rdp; @@ -238,11 +238,20 @@ freerdp_connect_finally: BOOL freerdp_abort_connect(freerdp* instance) { - if (!instance || !instance->context) + if (!instance) return FALSE; - freerdp_set_last_error_if_not(instance->context, FREERDP_ERROR_CONNECT_CANCELLED); - return utils_abort_connect(instance->context); + return freerdp_abort_connect_context(instance->context); +} + +BOOL freerdp_abort_connect_context(rdpContext* context) +{ + if (!context) + return FALSE; + + freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_CANCELLED); + + return utils_abort_connect(context->rdp); } #if defined(WITH_FREERDP_DEPRECATED) @@ -309,7 +318,7 @@ DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count { events[nCount++] = freerdp_channels_get_event_handle(context->instance); events[nCount++] = getChannelErrorEventHandle(context); - events[nCount++] = context->abortEvent; + events[nCount++] = utils_get_abort_event(context->rdp); } else return 0; @@ -473,8 +482,8 @@ BOOL freerdp_disconnect(freerdp* instance) if (!instance || !instance->context) return FALSE; - utils_abort_connect(instance->context); rdp = instance->context->rdp; + utils_abort_connect(rdp); if (!rdp_client_disconnect(rdp)) rc = FALSE; @@ -519,20 +528,25 @@ BOOL freerdp_reconnect(freerdp* instance) rdp = instance->context->rdp; - if (!utils_reset_abort(instance->context)) + if (!utils_reset_abort(instance->context->rdp)) return FALSE; return rdp_client_reconnect(rdp); } BOOL freerdp_shall_disconnect(freerdp* instance) { - if (!instance || !instance->context) + if (!instance) return FALSE; - if (WaitForSingleObject(instance->context->abortEvent, 0) != WAIT_OBJECT_0) + return freerdp_shall_disconnect_context(instance->context); +} + +BOOL freerdp_shall_disconnect_context(rdpContext* context) +{ + if (!context) return FALSE; - return TRUE; + return utils_abort_event_is_set(context->rdp); } BOOL freerdp_focus_required(freerdp* instance) @@ -682,10 +696,6 @@ BOOL freerdp_context_new_ex(freerdp* instance, rdpSettings* settings) } update_register_client_callbacks(rdp->update); - instance->context->abortEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - if (!instance->context->abortEvent) - goto fail; if (!(context->channels = freerdp_channels_new(instance))) goto fail; @@ -694,7 +704,7 @@ BOOL freerdp_context_new_ex(freerdp* instance, rdpSettings* settings) if (!context->dump) goto fail; - IFCALLRET(instance->ContextNew, ret, instance, instance->context); + IFCALLRET(instance->ContextNew, ret, instance, context); if (ret) return TRUE; @@ -745,10 +755,6 @@ void freerdp_context_free(freerdp* instance) free(ctx->errorDescription); ctx->errorDescription = NULL; - if (ctx->abortEvent) - CloseHandle(ctx->abortEvent); - ctx->abortEvent = NULL; - freerdp_channels_free(ctx->channels); ctx->channels = NULL; diff --git a/libfreerdp/core/gateway/rdg.c b/libfreerdp/core/gateway/rdg.c index 9eec6210b..8bd860b93 100644 --- a/libfreerdp/core/gateway/rdg.c +++ b/libfreerdp/core/gateway/rdg.c @@ -311,7 +311,7 @@ static BOOL rdg_read_http_unicode_string(wStream* s, const WCHAR** string, UINT1 size_t rem = Stream_GetRemainingLength(s); /* Read length of the string */ - if (rem < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) { WLog_ERR(TAG, "[%s]: Could not read stream length, only have % " PRIuz " bytes", rem); return FALSE; @@ -1262,12 +1262,8 @@ static BOOL rdg_process_handshake_response(rdpRdg* rdg, wStream* s) return FALSE; } - if (Stream_GetRemainingLength(s) < 10) - { - WLog_ERR(TAG, "[%s] Short packet %" PRIuz ", expected 10", __FUNCTION__, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 10)) return FALSE; - } Stream_Read_UINT32(s, errorCode); Stream_Read_UINT8(s, verMajor); @@ -1306,12 +1302,8 @@ static BOOL rdg_process_tunnel_response_optional(rdpRdg* rdg, wStream* s, UINT16 if (fieldsPresent & HTTP_TUNNEL_RESPONSE_FIELD_CAPS) { UINT32 caps; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "[%s] Short capsFlags, got %" PRIuz ", expected 4", __FUNCTION__, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Read_UINT32(s, caps); WLog_DBG(TAG, "capabilities=%s", capabilities_enum_to_string(caps)); @@ -1370,12 +1362,8 @@ static BOOL rdg_process_tunnel_response(rdpRdg* rdg, wStream* s) return FALSE; } - if (Stream_GetRemainingLength(s) < 10) - { - WLog_ERR(TAG, "[%s] Short packet %" PRIuz ", expected 10", __FUNCTION__, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 10)) return FALSE; - } Stream_Read_UINT16(s, serverVersion); Stream_Read_UINT32(s, errorCode); @@ -1410,12 +1398,8 @@ static BOOL rdg_process_tunnel_authorization_response(rdpRdg* rdg, wStream* s) return FALSE; } - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "[%s] Short packet %" PRIuz ", expected 8", __FUNCTION__, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; - } Stream_Read_UINT32(s, errorCode); Stream_Read_UINT16(s, fieldsPresent); @@ -1446,12 +1430,8 @@ static BOOL rdg_process_channel_response(rdpRdg* rdg, wStream* s) return FALSE; } - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "[%s] Short packet %" PRIuz ", expected 8", __FUNCTION__, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; - } Stream_Read_UINT32(s, errorCode); Stream_Read_UINT16(s, fieldsPresent); @@ -1479,12 +1459,8 @@ static BOOL rdg_process_packet(rdpRdg* rdg, wStream* s) UINT32 packetLength; Stream_SetPosition(s, 0); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "[%s] Short packet %" PRIuz ", expected 8", __FUNCTION__, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; - } Stream_Read_UINT16(s, type); Stream_Seek_UINT16(s); /* reserved */ @@ -2059,7 +2035,7 @@ static BOOL rdg_process_close_packet(rdpRdg* rdg, wStream* s) UINT32 packetSize = 12; /* Read error code */ - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, errorCode); diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 66f55f177..cfb7091ed 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -361,7 +361,7 @@ static int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) Stream_SetPosition(fragment, StubOffset); Stream_Read_UINT32(fragment, rpc->result); - utils_abort_connect(context); + utils_abort_connect(context->rdp); tsg_set_state(tsg, TSG_STATE_TUNNEL_CLOSE_PENDING); EventArgsInit(&e, "freerdp"); e.code = 0; diff --git a/libfreerdp/core/gateway/rts.c b/libfreerdp/core/gateway/rts.c index e6c3fdccf..9a47df74c 100644 --- a/libfreerdp/core/gateway/rts.c +++ b/libfreerdp/core/gateway/rts.c @@ -179,11 +179,10 @@ static BOOL rts_write_common_pdu_header(wStream* s, const rpcconn_common_hdr_t* BOOL rts_read_common_pdu_header(wStream* s, rpcconn_common_hdr_t* header) { - size_t left; WINPR_ASSERT(s); WINPR_ASSERT(header); - if (Stream_GetRemainingLength(s) < sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT8(s, header->rpc_vers); @@ -198,8 +197,8 @@ BOOL rts_read_common_pdu_header(wStream* s, rpcconn_common_hdr_t* header) if (header->frag_length < sizeof(rpcconn_common_hdr_t)) return FALSE; - left = Stream_GetRemainingLength(s); - if (left < header->frag_length - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, + header->frag_length - sizeof(rpcconn_common_hdr_t))) return FALSE; return TRUE; @@ -222,7 +221,7 @@ static BOOL rts_read_auth_verifier_no_checks(wStream* s, auth_verifier_co_t* aut const size_t expected = header->frag_length - header->auth_length - 8; Stream_SetPosition(s, expected); - if (Stream_GetRemainingLength(s) < sizeof(auth_verifier_co_t)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(auth_verifier_co_t))) return FALSE; Stream_Read_UINT8(s, auth->auth_type); @@ -370,7 +369,7 @@ static BOOL rts_read_version(wStream* s, p_rt_version_t* version) WINPR_ASSERT(s); WINPR_ASSERT(version); - if (Stream_GetRemainingLength(s) < 2 * sizeof(UINT8)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2 * sizeof(UINT8))) return FALSE; Stream_Read_UINT8(s, version->major); Stream_Read_UINT8(s, version->minor); @@ -392,7 +391,7 @@ static BOOL rts_read_supported_versions(wStream* s, p_rt_versions_supported_t* v WINPR_ASSERT(s); WINPR_ASSERT(versions); - if (Stream_GetRemainingLength(s) < sizeof(UINT8)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(UINT8))) return FALSE; Stream_Read_UINT8(s, versions->n_protocols); /* count */ @@ -423,7 +422,7 @@ static BOOL rts_read_port_any(wStream* s, port_any_t* port) WINPR_ASSERT(s); WINPR_ASSERT(port); - if (Stream_GetRemainingLength(s) < sizeof(UINT16)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(UINT16))) return FALSE; Stream_Read_UINT16(s, port->length); @@ -449,7 +448,7 @@ static BOOL rts_read_uuid(wStream* s, p_uuid_t* uuid) WINPR_ASSERT(s); WINPR_ASSERT(uuid); - if (Stream_GetRemainingLength(s) < sizeof(p_uuid_t)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(p_uuid_t))) return FALSE; Stream_Read_UINT32(s, uuid->time_low); @@ -496,7 +495,7 @@ static BOOL rts_read_syntax_id(wStream* s, p_syntax_id_t* syntax_id) if (!rts_read_uuid(s, &syntax_id->if_uuid)) return FALSE; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, syntax_id->if_version); @@ -538,7 +537,7 @@ static BOOL rts_read_context_elem(wStream* s, p_cont_elem_t* element) WINPR_ASSERT(s); WINPR_ASSERT(element); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, element->p_cont_id); @@ -595,7 +594,7 @@ static BOOL rts_read_context_list(wStream* s, p_cont_list_t* list) WINPR_ASSERT(s); WINPR_ASSERT(list); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT8(s, list->n_context_elem); /* number of items */ Stream_Read_UINT8(s, list->reserved); /* alignment pad, m.b.z. */ @@ -662,7 +661,7 @@ static BOOL rts_read_result(wStream* s, p_result_t* result) WINPR_ASSERT(s); WINPR_ASSERT(result); - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, result->result); Stream_Read_UINT16(s, result->reason); @@ -683,7 +682,7 @@ static BOOL rts_read_result_list(wStream* s, p_result_list_t* list) WINPR_ASSERT(s); WINPR_ASSERT(list); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT8(s, list->n_results); /* count */ Stream_Read_UINT8(s, list->reserved); /* alignment pad, m.b.z. */ @@ -734,8 +733,8 @@ static BOOL rts_read_pdu_alter_context(wStream* s, rpcconn_alter_context_hdr_t* WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < - sizeof(rpcconn_alter_context_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_alter_context_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT16(s, ctx->max_xmit_frag); @@ -757,8 +756,8 @@ static BOOL rts_read_pdu_alter_context_response(wStream* s, WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < - sizeof(rpcconn_alter_context_response_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_alter_context_response_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT16(s, ctx->max_xmit_frag); Stream_Read_UINT16(s, ctx->max_recv_frag); @@ -794,7 +793,8 @@ static BOOL rts_read_pdu_bind(wStream* s, rpcconn_bind_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < sizeof(rpcconn_bind_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_bind_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT16(s, ctx->max_xmit_frag); Stream_Read_UINT16(s, ctx->max_recv_frag); @@ -822,8 +822,8 @@ static BOOL rts_read_pdu_bind_ack(wStream* s, rpcconn_bind_ack_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < - sizeof(rpcconn_bind_ack_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_bind_ack_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT16(s, ctx->max_xmit_frag); Stream_Read_UINT16(s, ctx->max_recv_frag); @@ -855,8 +855,8 @@ static BOOL rts_read_pdu_bind_nak(wStream* s, rpcconn_bind_nak_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < - sizeof(rpcconn_bind_nak_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_bind_nak_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT16(s, ctx->provider_reject_reason); return rts_read_supported_versions(s, &ctx->versions); @@ -875,8 +875,8 @@ static BOOL rts_read_pdu_auth3(wStream* s, rpcconn_rpc_auth_3_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < - sizeof(rpcconn_rpc_auth_3_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_rpc_auth_3_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT16(s, ctx->max_xmit_frag); Stream_Read_UINT16(s, ctx->max_recv_frag); @@ -896,7 +896,8 @@ static BOOL rts_read_pdu_fault(wStream* s, rpcconn_fault_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < sizeof(rpcconn_fault_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_fault_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT32(s, ctx->alloc_hint); Stream_Read_UINT16(s, ctx->p_cont_id); @@ -919,7 +920,8 @@ static BOOL rts_read_pdu_cancel_ack(wStream* s, rpcconn_cancel_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < sizeof(rpcconn_cancel_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_cancel_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; return rts_read_auth_verifier(s, &ctx->auth_verifier, &ctx->header); } @@ -936,8 +938,8 @@ static BOOL rts_read_pdu_orphaned(wStream* s, rpcconn_orphaned_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < - sizeof(rpcconn_orphaned_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_orphaned_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; return rts_read_auth_verifier(s, &ctx->auth_verifier, &ctx->header); } @@ -954,7 +956,8 @@ static BOOL rts_read_pdu_request(wStream* s, rpcconn_request_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < sizeof(rpcconn_request_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_request_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT32(s, ctx->alloc_hint); Stream_Read_UINT16(s, ctx->p_cont_id); @@ -977,8 +980,8 @@ static BOOL rts_read_pdu_response(wStream* s, rpcconn_response_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < - sizeof(rpcconn_response_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength( + TAG, s, sizeof(rpcconn_response_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT32(s, ctx->alloc_hint); Stream_Read_UINT16(s, ctx->p_cont_id); @@ -1004,7 +1007,8 @@ static BOOL rts_read_pdu_rts(wStream* s, rpcconn_rts_hdr_t* ctx) WINPR_ASSERT(s); WINPR_ASSERT(ctx); - if (Stream_GetRemainingLength(s) < sizeof(rpcconn_rts_hdr_t) - sizeof(rpcconn_common_hdr_t)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, + sizeof(rpcconn_rts_hdr_t) - sizeof(rpcconn_common_hdr_t))) return FALSE; Stream_Read_UINT16(s, ctx->Flags); @@ -1173,7 +1177,7 @@ static int rts_receive_window_size_command_read(rdpRpc* rpc, wStream* buffer, WINPR_ASSERT(rpc); WINPR_ASSERT(buffer); - if (Stream_GetRemainingLength(buffer) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, buffer, 4)) return -1; Stream_Read_UINT32(buffer, val); if (ReceiveWindowSize) @@ -1203,7 +1207,7 @@ static int rts_flow_control_ack_command_read(rdpRpc* rpc, wStream* buffer, UINT3 WINPR_ASSERT(buffer); /* Ack (24 bytes) */ - if (Stream_GetRemainingLength(buffer) < 24) + if (!Stream_CheckAndLogRequiredLength(TAG, buffer, 24)) return -1; Stream_Read_UINT32(buffer, val); @@ -1244,7 +1248,7 @@ static BOOL rts_connection_timeout_command_read(rdpRpc* rpc, wStream* buffer, WINPR_ASSERT(rpc); WINPR_ASSERT(buffer); - if (Stream_GetRemainingLength(buffer) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, buffer, 4)) return FALSE; Stream_Read_UINT32(buffer, val); @@ -1339,7 +1343,7 @@ static BOOL rts_padding_command_read(wStream* s, size_t* length) UINT32 ConformanceCount; WINPR_ASSERT(s); WINPR_ASSERT(length); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, ConformanceCount); /* ConformanceCount (4 bytes) */ *length = ConformanceCount + 4; @@ -1353,7 +1357,7 @@ static BOOL rts_client_address_command_read(wStream* s, size_t* length) WINPR_ASSERT(s); WINPR_ASSERT(length); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, AddressType); /* AddressType (4 bytes) */ @@ -1391,7 +1395,7 @@ static int rts_destination_command_read(rdpRpc* rpc, wStream* buffer, UINT32* De WINPR_ASSERT(rpc); WINPR_ASSERT(buffer); - if (Stream_GetRemainingLength(buffer) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, buffer, 4)) return -1; Stream_Read_UINT32(buffer, val); if (Destination) @@ -1849,7 +1853,7 @@ BOOL rts_command_length(UINT32 CommandType, wStream* s, size_t* length) } CommandLength += padding; - if (Stream_GetRemainingLength(s) < CommandLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, CommandLength)) return FALSE; if (length) diff --git a/libfreerdp/core/gateway/rts_signature.c b/libfreerdp/core/gateway/rts_signature.c index d60f85bc8..855fefb51 100644 --- a/libfreerdp/core/gateway/rts_signature.c +++ b/libfreerdp/core/gateway/rts_signature.c @@ -327,7 +327,7 @@ BOOL rts_extract_pdu_signature(RtsPduSignature* signature, wStream* src, UINT32 CommandType; size_t CommandLength; - if (Stream_GetRemainingLength(&tmp) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, &tmp, 4)) goto fail; Stream_Read_UINT32(&tmp, CommandType); /* CommandType (4 bytes) */ diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 037408cd2..1dbb7ad3d 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -1045,7 +1045,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, if (!packet) return FALSE; - if (Stream_GetRemainingLength(pdu->s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 12)) goto fail; Stream_Seek_UINT32(pdu->s); /* PacketPtr (4 bytes) */ @@ -1064,7 +1064,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, packet->tsgPacket.packetCapsResponse = packetCapsResponse; - if (Stream_GetRemainingLength(pdu->s) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 32)) goto fail; Stream_Seek_UINT32(pdu->s); /* PacketQuarResponsePtr (4 bytes) */ @@ -1080,7 +1080,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, if ((Pointer == 0x0002000C) || (Pointer == 0x00020008)) { - if (Stream_GetRemainingLength(pdu->s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 16)) goto fail; Stream_Seek_UINT32(pdu->s); /* MsgId (4 bytes) */ @@ -1091,7 +1091,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, if (packetCapsResponse->pktQuarEncResponse.certChainLen > 0) { - if (Stream_GetRemainingLength(pdu->s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 16)) goto fail; Stream_Read_UINT32(pdu->s, Pointer); /* MsgPtr (4 bytes): 0x00020014 */ @@ -1113,7 +1113,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, } else { - if (Stream_GetRemainingLength(pdu->s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 4)) goto fail; Stream_Read_UINT32(pdu->s, Pointer); /* Ptr (4 bytes) */ @@ -1126,7 +1126,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, packetCapsResponse->pktQuarEncResponse.versionCaps = versionCaps; - if (Stream_GetRemainingLength(pdu->s) < 18) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 18)) goto fail; Stream_Read_UINT16(pdu->s, versionCaps->tsgHeader.ComponentId); /* ComponentId (2 bytes) */ @@ -1157,7 +1157,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, versionCaps->tsgCaps = tsgCaps; - if (Stream_GetRemainingLength(pdu->s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 16)) goto fail; Stream_Seek_UINT32(pdu->s); /* MaxCount (4 bytes) */ @@ -1180,7 +1180,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, { case TSG_ASYNC_MESSAGE_CONSENT_MESSAGE: case TSG_ASYNC_MESSAGE_SERVICE_MESSAGE: - if (Stream_GetRemainingLength(pdu->s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 16)) goto fail; Stream_Read_INT32(pdu->s, packetStringMessage.isDisplayMandatory); @@ -1190,7 +1190,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, if (Pointer) { - if (Stream_GetRemainingLength(pdu->s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 12)) goto fail; Stream_Seek_UINT32(pdu->s); /* MaxCount (4 bytes) */ @@ -1206,12 +1206,8 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, } packetStringMessage.msgBuffer = (WCHAR*)Stream_Pointer(pdu->s); - if (Stream_GetRemainingLength(pdu->s) < packetStringMessage.msgBytes) - { - WLog_ERR(TAG, "Unable to read message (%" PRIu32 " remaining %" PRId32 ")", - packetStringMessage.msgBytes, Stream_GetRemainingLength(pdu->s)); + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, packetStringMessage.msgBytes)) goto fail; - } if (context->instance) { @@ -1234,7 +1230,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, if (!tsg_stream_align(pdu->s, 8)) goto fail; - if (Stream_GetRemainingLength(pdu->s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 8)) goto fail; Stream_Seek_UINT64(pdu->s); /* TunnelContext (8 bytes) */ @@ -1250,7 +1246,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, goto fail; /* TunnelContext (20 bytes) */ - if (Stream_GetRemainingLength(pdu->s) < 24) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 24)) goto fail; Stream_Read_UINT32(pdu->s, tunnelContext->ContextType); /* ContextType (4 bytes) */ @@ -1269,7 +1265,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, packet->tsgPacket.packetQuarEncResponse = packetQuarEncResponse; - if (Stream_GetRemainingLength(pdu->s) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 32)) goto fail; Stream_Seek_UINT32(pdu->s); /* PacketQuarResponsePtr (4 bytes) */ @@ -1281,7 +1277,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, if (packetQuarEncResponse->certChainLen > 0) { - if (Stream_GetRemainingLength(pdu->s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 16)) goto fail; Stream_Read_UINT32(pdu->s, Pointer); /* Ptr (4 bytes): 0x0002000C */ @@ -1303,7 +1299,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, } else { - if (Stream_GetRemainingLength(pdu->s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 4)) goto fail; Stream_Read_UINT32(pdu->s, Pointer); /* Ptr (4 bytes): 0x00020008 */ @@ -1316,7 +1312,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, packetQuarEncResponse->versionCaps = versionCaps; - if (Stream_GetRemainingLength(pdu->s) < 18) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 18)) goto fail; Stream_Read_UINT16(pdu->s, versionCaps->tsgHeader.ComponentId); /* ComponentId (2 bytes) */ @@ -1340,7 +1336,7 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, if (!tsg_stream_align(pdu->s, 4)) goto fail; - if (Stream_GetRemainingLength(pdu->s) < 36) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 36)) goto fail; /* Not sure exactly what this is */ @@ -1448,7 +1444,7 @@ static BOOL TsProxyAuthorizeTunnelReadResponse(RPC_PDU* pdu) if (!packet) return FALSE; - if (Stream_GetRemainingLength(pdu->s) < 68) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 68)) goto fail; Stream_Seek_UINT32(pdu->s); /* PacketPtr (4 bytes) */ @@ -1519,7 +1515,7 @@ static BOOL TsProxyAuthorizeTunnelReadResponse(RPC_PDU* pdu) goto fail; } - if (Stream_GetRemainingLength(pdu->s) < SizeValue) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, SizeValue)) goto fail; if (SizeValue == 4) @@ -1579,7 +1575,7 @@ static BOOL TsProxyReadPacketSTringMessage(rdpTsg* tsg, wStream* s, TSG_PACKET_S if (!tsg || !s || !msg) return FALSE; - if (Stream_GetRemainingLength(s) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 32)) return FALSE; Stream_Read_UINT32(s, Pointer); /* ConsentMessagePtr (4 bytes) */ @@ -1594,7 +1590,7 @@ static BOOL TsProxyReadPacketSTringMessage(rdpTsg* tsg, wStream* s, TSG_PACKET_S if (msg->msgBytes < ActualCount * 2) return FALSE; - if (Stream_GetRemainingLength(s) < msg->msgBytes) + if (!Stream_CheckAndLogRequiredLength(TAG, s, msg->msgBytes)) return FALSE; msg->msgBuffer = (WCHAR*)Stream_Pointer(s); @@ -1626,7 +1622,7 @@ static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (!pdu) return FALSE; - if (Stream_GetRemainingLength(pdu->s) < 28) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 28)) goto fail; Stream_Seek_UINT32(pdu->s); /* PacketPtr (4 bytes) */ @@ -1702,7 +1698,7 @@ static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) break; case TSG_ASYNC_MESSAGE_REAUTH: - if (Stream_GetRemainingLength(pdu->s) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 20)) goto fail; Stream_Read_UINT32(pdu->s, Pointer); /* ReauthMessagePtr (4 bytes) */ @@ -1783,7 +1779,7 @@ static BOOL TsProxyCreateChannelReadResponse(RPC_PDU* pdu, CONTEXT_HANDLE* chann if (!pdu) return FALSE; - if (Stream_GetRemainingLength(pdu->s) < 28) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 28)) goto fail; /* ChannelContext (20 bytes) */ @@ -1831,7 +1827,7 @@ static BOOL TsProxyCloseChannelReadResponse(RPC_PDU* pdu, CONTEXT_HANDLE* contex if (!pdu) return FALSE; - if (Stream_GetRemainingLength(pdu->s) < 24) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 24)) goto fail; /* ChannelContext (20 bytes) */ @@ -1878,7 +1874,7 @@ static BOOL TsProxyCloseTunnelReadResponse(RPC_PDU* pdu, CONTEXT_HANDLE* context if (!pdu || !context) return FALSE; - if (Stream_GetRemainingLength(pdu->s) < 24) + if (!Stream_CheckAndLogRequiredLength(TAG, pdu->s, 24)) goto fail; /* TunnelContext (20 bytes) */ diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 5c886177d..72b106499 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -250,7 +250,7 @@ BOOL gcc_read_conference_create_request(wStream* s, rdpMcs* mcs) if (!per_read_length(s, &length)) return FALSE; - if (Stream_GetRemainingLength(s) < length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; if (!gcc_read_client_data_blocks(s, mcs, length)) @@ -411,7 +411,7 @@ BOOL gcc_read_client_data_blocks(wStream* s, rdpMcs* mcs, UINT16 length) if (!gcc_read_user_data_header(s, &type, &blockLength)) return FALSE; - if (Stream_GetRemainingLength(s) < (size_t)(blockLength - 4)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(blockLength - 4))) return FALSE; switch (type) @@ -652,13 +652,13 @@ BOOL gcc_write_server_data_blocks(wStream* s, rdpMcs* mcs) BOOL gcc_read_user_data_header(wStream* s, UINT16* type, UINT16* length) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, *type); /* type */ Stream_Read_UINT16(s, *length); /* length */ - if ((*length < 4) || (Stream_GetRemainingLength(s) < (size_t)(*length - 4))) + if ((*length < 4) || (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(*length - 4)))) return FALSE; return TRUE; @@ -1089,7 +1089,7 @@ BOOL gcc_read_server_core_data(wStream* s, rdpMcs* mcs) settings = context->settings; WINPR_ASSERT(settings); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, serverVersion); /* version */ @@ -1232,7 +1232,7 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) settings = context->settings; WINPR_ASSERT(settings); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, serverEncryptionMethod); /* encryptionMethod */ @@ -1329,7 +1329,7 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) return TRUE; } - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, settings->ServerRandomLength); /* serverRandomLen */ @@ -1338,7 +1338,7 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) if ((settings->ServerRandomLength == 0) || (settings->ServerCertificateLength == 0)) return FALSE; - if (Stream_GetRemainingLength(s) < settings->ServerRandomLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, settings->ServerRandomLength)) return FALSE; /* serverRandom */ @@ -1348,7 +1348,7 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength); - if (Stream_GetRemainingLength(s) < settings->ServerCertificateLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, settings->ServerCertificateLength)) goto fail; /* serverCertificate */ @@ -1358,10 +1358,6 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength); - if (!freerdp_settings_set_pointer_len(settings, FreeRDP_RdpServerCertificate, certificate_new(), - sizeof(rdpCertificate))) - goto fail; - data = settings->ServerCertificate; length = settings->ServerCertificateLength; @@ -1729,7 +1725,7 @@ BOOL gcc_read_server_network_data(wStream* s, rdpMcs* mcs) UINT16 channelCount; UINT16 parsedChannelCount; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, MCSChannelId); /* MCSChannelId */ @@ -1747,7 +1743,7 @@ BOOL gcc_read_server_network_data(wStream* s, rdpMcs* mcs) parsedChannelCount = mcs->channelCount; } - if (Stream_GetRemainingLength(s) / 2 < channelCount) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2ull * channelCount)) return FALSE; for (i = 0; i < parsedChannelCount; i++) @@ -2149,7 +2145,7 @@ BOOL gcc_read_server_message_channel_data(wStream* s, rdpMcs* mcs) { UINT16 MCSChannelId; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, MCSChannelId); /* MCSChannelId */ @@ -2219,7 +2215,7 @@ BOOL gcc_read_server_multitransport_channel_data(wStream* s, rdpMcs* mcs) { UINT32 flags; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, flags); /* flags */ diff --git a/libfreerdp/core/heartbeat.c b/libfreerdp/core/heartbeat.c index 8c1341084..d2662a55f 100644 --- a/libfreerdp/core/heartbeat.c +++ b/libfreerdp/core/heartbeat.c @@ -35,7 +35,7 @@ int rdp_recv_heartbeat_packet(rdpRdp* rdp, wStream* s) WINPR_ASSERT(rdp->context); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(AUTODETECT_TAG, s, 4)) return -1; Stream_Read_UINT8(s, reserved); /* reserved (1 byte) */ diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 4e8a90256..81fe1456a 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -79,7 +79,7 @@ static BOOL rdp_read_info_null_string(UINT32 flags, wStream* s, size_t cbLen, CH const BOOL unicode = flags & INFO_UNICODE; const size_t nullSize = unicode ? sizeof(WCHAR) : sizeof(CHAR); - if (Stream_GetRemainingLength(s) < (size_t)(cbLen)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(cbLen))) return FALSE; if (cbLen > 0) @@ -194,7 +194,7 @@ static BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s, logon rdpSettings* settings = rdp->settings; autoReconnectCookie = settings->ServerAutoReconnectCookie; - if (Stream_GetRemainingLength(s) < 28) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 28)) return FALSE; Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ @@ -245,7 +245,7 @@ static BOOL rdp_read_client_auto_reconnect_cookie(rdpRdp* rdp, wStream* s) rdpSettings* settings = rdp->settings; autoReconnectCookie = settings->ClientAutoReconnectCookie; - if (Stream_GetRemainingLength(s) < 28) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 28)) return FALSE; Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ @@ -298,7 +298,7 @@ static BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) UINT16 cbAutoReconnectLen; rdpSettings* settings = rdp->settings; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily (2 bytes) */ @@ -320,14 +320,11 @@ static BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) settings->IPv6Enabled = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? TRUE : FALSE); - if (Stream_GetRemainingLength(s) < cbClientAddress) - return FALSE; - if (!rdp_read_info_null_string(INFO_UNICODE, s, cbClientAddress, &settings->ClientAddress, (settings->RdpVersion < RDP_VERSION_10_0) ? 64 : 80)) return FALSE; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, cbClientDir); /* cbClientDir (2 bytes) */ @@ -350,25 +347,24 @@ static BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) /* optional: clientTimeZone (172 bytes) */ if (Stream_GetRemainingLength(s) == 0) - return TRUE; + goto end; if (!rdp_read_client_time_zone(s, settings)) return FALSE; /* optional: clientSessionId (4 bytes), should be set to 0 */ if (Stream_GetRemainingLength(s) == 0) - return TRUE; - - if (Stream_GetRemainingLength(s) < 4) + goto end; + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - Stream_Seek_UINT32(s); + Stream_Read_UINT32(s, settings->ClientSessionId); /* optional: performanceFlags (4 bytes) */ if (Stream_GetRemainingLength(s) == 0) - return TRUE; + goto end; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, settings->PerformanceFlags); @@ -376,9 +372,9 @@ static BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) /* optional: cbAutoReconnectLen (2 bytes) */ if (Stream_GetRemainingLength(s) == 0) - return TRUE; + goto end; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, cbAutoReconnectLen); @@ -386,14 +382,56 @@ static BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) /* optional: autoReconnectCookie (28 bytes) */ /* must be present if cbAutoReconnectLen is > 0 */ if (cbAutoReconnectLen > 0) - return rdp_read_client_auto_reconnect_cookie(rdp, s); + { + if (!rdp_read_client_auto_reconnect_cookie(rdp, s)) + return FALSE; + } - /* TODO */ - /* reserved1 (2 bytes) */ - /* reserved2 (2 bytes) */ - /* cbDynamicDSTTimeZoneKeyName (2 bytes) */ - /* dynamicDSTTimeZoneKeyName (variable) */ - /* dynamicDaylightTimeDisabled (2 bytes) */ + /* skip reserved1 and reserved2 fields */ + if (Stream_GetRemainingLength(s) == 0) + goto end; + + if (!Stream_SafeSeek(s, 2)) + return FALSE; + + if (Stream_GetRemainingLength(s) == 0) + goto end; + + if (!Stream_SafeSeek(s, 2)) + return FALSE; + + if (Stream_GetRemainingLength(s) == 0) + goto end; + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) + return FALSE; + { + UINT16 cbDynamicDSTTimeZoneKeyName; + + Stream_Read_UINT16(s, cbDynamicDSTTimeZoneKeyName); + + if (!rdp_read_info_null_string(INFO_UNICODE, s, cbDynamicDSTTimeZoneKeyName, + &settings->DynamicDSTTimeZoneKeyName, 254)) + return FALSE; + + if (Stream_GetRemainingLength(s) == 0) + goto end; + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) + return FALSE; + Stream_Read_UINT16(s, settings->DynamicDaylightTimeDisabled); + if (settings->DynamicDaylightTimeDisabled > 1) + { + WLog_WARN(TAG, + "[MS-RDPBCGR] 2.2.1.11.1.1.1 Extended Info Packet " + "(TS_EXTENDED_INFO_PACKET)::dynamicDaylightTimeDisabled value %" PRIu16 + " not allowed in [0,1]", + settings->DynamicDaylightTimeDisabled); + return FALSE; + } + } + +end: return TRUE; } @@ -447,7 +485,8 @@ static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s) if (!rdp_write_client_time_zone(s, settings)) /* clientTimeZone (172 bytes) */ goto fail; - Stream_Write_UINT32(s, 0); /* clientSessionId (4 bytes), should be set to 0 */ + Stream_Write_UINT32( + s, settings->ClientSessionId); /* clientSessionId (4 bytes), should be set to 0 */ freerdp_performance_flags_make(settings); Stream_Write_UINT32(s, settings->PerformanceFlags); /* performanceFlags (4 bytes) */ Stream_Write_UINT16(s, cbAutoReconnectCookie); /* cbAutoReconnectCookie (2 bytes) */ @@ -460,6 +499,28 @@ static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s) Stream_Write_UINT16(s, 0); /* reserved1 (2 bytes) */ Stream_Write_UINT16(s, 0); /* reserved2 (2 bytes) */ } + + if (settings->EarlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE) + { + int rc; + WCHAR DynamicDSTTimeZoneKeyName[254] = { 0 }; + LPWSTR ptr = DynamicDSTTimeZoneKeyName; + + if (!Stream_EnsureRemainingCapacity(s, 10 + sizeof(DynamicDSTTimeZoneKeyName))) + goto fail; + + /* skip reserved1 and reserved2 fields */ + Stream_Seek(s, 4); + + rc = ConvertToUnicode(CP_UTF8, 0, settings->DynamicDSTTimeZoneKeyName, -1, &ptr, + ARRAYSIZE(DynamicDSTTimeZoneKeyName)); + if (rc < 0) + goto fail; + Stream_Write_UINT16(s, (UINT16)rc); + Stream_Write_UTF16_String(s, ptr, (size_t)rc); + Stream_Write_UINT16(s, settings->DynamicDaylightTimeDisabled ? 0x01 : 0x00); + } + ret = TRUE; fail: free(clientAddress); @@ -480,7 +541,7 @@ static BOOL rdp_read_info_string(UINT32 flags, wStream* s, size_t cbLenNonNull, const BOOL unicode = flags & INFO_UNICODE; const size_t nullSize = unicode ? sizeof(WCHAR) : sizeof(CHAR); - if (Stream_GetRemainingLength(s) < (size_t)(cbLenNonNull + nullSize)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(cbLenNonNull + nullSize))) return FALSE; if (cbLenNonNull > 0) @@ -548,7 +609,7 @@ static BOOL rdp_read_info_packet(rdpRdp* rdp, wStream* s, UINT16 tpktlength) UINT32 CompressionLevel; rdpSettings* settings = rdp->settings; - if (Stream_GetRemainingLength(s) < 18) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 18)) return FALSE; Stream_Read_UINT32(s, settings->KeyboardCodePage); /* CodePage (4 bytes ) */ @@ -930,7 +991,7 @@ static BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s, logon_info* info) WINPR_UNUSED(rdp); ZeroMemory(info, sizeof(*info)); - if (Stream_GetRemainingLength(s) < 576) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 576)) return FALSE; Stream_Read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */ @@ -1017,12 +1078,8 @@ static BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info* info) WINPR_UNUSED(rdp); ZeroMemory(info, sizeof(*info)); - if (Stream_GetRemainingLength(s) < logonInfoV2TotalSize) - { - WLog_WARN(TAG, "short LogonInfoV2, expected %" PRIuz " bytes, got %" PRIuz, - logonInfoV2TotalSize, Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, logonInfoV2TotalSize)) return FALSE; - } Stream_Read_UINT16(s, Version); /* Version (2 bytes) */ if (Version != SAVE_SESSION_PDU_VERSION_ONE) @@ -1075,11 +1132,8 @@ static BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info* info) goto fail; } - if (Stream_GetRemainingLength(s) < (size_t)cbDomain) - { - WLog_ERR(TAG, "insufficient remaining stream length"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)cbDomain)) goto fail; - } memcpy(domain, Stream_Pointer(s), cbDomain); Stream_Seek(s, cbDomain); /* domain */ @@ -1113,11 +1167,8 @@ static BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info* info) goto fail; } - if (Stream_GetRemainingLength(s) < (size_t)cbUserName) - { - WLog_ERR(TAG, "insufficient remaining stream length"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)cbUserName)) goto fail; - } memcpy(user, Stream_Pointer(s), cbUserName); Stream_Seek(s, cbUserName); /* userName */ @@ -1149,7 +1200,7 @@ fail: static BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, wStream* s) { WINPR_UNUSED(rdp); - if (Stream_GetRemainingLength(s) < 576) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 576)) return FALSE; Stream_Seek(s, 576); /* pad (576 bytes) */ @@ -1171,12 +1222,8 @@ static BOOL rdp_recv_logon_error_info(rdpRdp* rdp, wStream* s, logon_info_ex* in instance = rdp->context->instance; WINPR_ASSERT(instance); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_WARN(TAG, "received short logon error info, need 8 bytes, got %" PRIuz, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; - } Stream_Read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */ Stream_Read_UINT32(s, errorNotificationData); /* errorNotificationData (4 bytes) */ @@ -1198,7 +1245,7 @@ static BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s, logon_info_ex* WINPR_ASSERT(s); WINPR_ASSERT(info); - if (Stream_GetRemainingLength(s) < 6) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) { WLog_WARN(TAG, "received short logon info extended, need 6 bytes, got %" PRIuz, Stream_GetRemainingLength(s)); @@ -1208,7 +1255,7 @@ static BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s, logon_info_ex* Stream_Read_UINT16(s, Length); /* Length (2 bytes) */ Stream_Read_UINT32(s, fieldsPresent); /* fieldsPresent (4 bytes) */ - if ((Length < 6) || (Stream_GetRemainingLength(s) < (Length - 6U))) + if ((Length < 6) || (!Stream_CheckAndLogRequiredLength(TAG, s, (Length - 6U)))) { WLog_WARN(TAG, "received short logon info extended, need %" PRIu16 " - 6 bytes, got %" PRIuz, @@ -1222,13 +1269,13 @@ static BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s, logon_info_ex* if (fieldsPresent & LOGON_EX_AUTORECONNECTCOOKIE) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; info->haveCookie = TRUE; Stream_Read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */ - if (Stream_GetRemainingLength(s) < cbFieldData) + if (!Stream_CheckAndLogRequiredLength(TAG, s, cbFieldData)) return FALSE; if (!rdp_read_server_auto_reconnect_cookie(rdp, s, info)) @@ -1239,19 +1286,19 @@ static BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s, logon_info_ex* { info->haveErrorInfo = TRUE; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */ - if (Stream_GetRemainingLength(s) < cbFieldData) + if (!Stream_CheckAndLogRequiredLength(TAG, s, cbFieldData)) return FALSE; if (!rdp_recv_logon_error_info(rdp, s, info)) return FALSE; } - if (Stream_GetRemainingLength(s) < 570) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 570)) return FALSE; Stream_Seek(s, 570); /* pad (570 bytes) */ @@ -1267,7 +1314,7 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s) rdpContext* context = rdp->context; rdpUpdate* update = rdp->context->update; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, infoType); /* infoType (4 bytes) */ diff --git a/libfreerdp/core/input.c b/libfreerdp/core/input.c index 90f1ba321..290677302 100644 --- a/libfreerdp/core/input.c +++ b/libfreerdp/core/input.c @@ -38,14 +38,20 @@ #define INPUT_EVENT_MOUSE 0x8001 #define INPUT_EVENT_MOUSEX 0x8002 +#define RDP_CLIENT_INPUT_PDU_HEADER_LENGTH 4 + static void rdp_write_client_input_pdu_header(wStream* s, UINT16 number) { + WINPR_ASSERT(s); + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 4); Stream_Write_UINT16(s, number); /* numberEvents (2 bytes) */ Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ } static void rdp_write_input_event_header(wStream* s, UINT32 time, UINT16 type) { + WINPR_ASSERT(s); + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 6); Stream_Write_UINT32(s, time); /* eventTime (4 bytes) */ Stream_Write_UINT16(s, type); /* messageType (2 bytes) */ } @@ -65,13 +71,13 @@ static wStream* rdp_client_input_pdu_init(rdpRdp* rdp, UINT16 type) static BOOL rdp_send_client_input_pdu(rdpRdp* rdp, wStream* s) { - WINPR_ASSERT(rdp); - WINPR_ASSERT(rdp->mcs); return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_INPUT, rdp->mcs->userId); } static void input_write_synchronize_event(wStream* s, UINT32 flags) { + WINPR_ASSERT(s); + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 6); Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ Stream_Write_UINT32(s, flags); /* toggleFlags (4 bytes) */ } @@ -203,8 +209,12 @@ static BOOL input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT1 wStream* s; rdpRdp* rdp; - if (!input || !input->context) - return FALSE; + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); + WINPR_ASSERT(input->context->settings); + + rdp = input->context->rdp; + WINPR_ASSERT(rdp); if (!input->context->settings->HasExtendedMouseEvent) { @@ -215,7 +225,6 @@ static BOOL input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT1 return TRUE; } - rdp = input->context->rdp; s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSEX); if (!s) @@ -270,10 +279,12 @@ static BOOL input_send_fastpath_synchronize_event(rdpInput* input, UINT32 flags) wStream* s; rdpRdp* rdp; - if (!input || !input->context) - return FALSE; + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); rdp = input->context->rdp; + WINPR_ASSERT(rdp); + /* The FastPath Synchronization eventFlags has identical values as SlowPath */ s = fastpath_input_pdu_init(rdp->fastpath, (BYTE)flags, FASTPATH_INPUT_EVENT_SYNC); @@ -289,10 +300,12 @@ static BOOL input_send_fastpath_keyboard_event(rdpInput* input, UINT16 flags, UI BYTE eventFlags = 0; rdpRdp* rdp; - if (!input || !input->context) - return FALSE; + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); rdp = input->context->rdp; + WINPR_ASSERT(rdp); + eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0; eventFlags |= (flags & KBD_FLAGS_EXTENDED) ? FASTPATH_INPUT_KBDFLAGS_EXTENDED : 0; eventFlags |= (flags & KBD_FLAGS_EXTENDED1) ? FASTPATH_INPUT_KBDFLAGS_PREFIX_E1 : 0; @@ -312,8 +325,12 @@ static BOOL input_send_fastpath_unicode_keyboard_event(rdpInput* input, UINT16 f BYTE eventFlags = 0; rdpRdp* rdp; - if (!input || !input->context) - return FALSE; + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); + WINPR_ASSERT(input->context->settings); + + rdp = input->context->rdp; + WINPR_ASSERT(rdp); if (!input->context->settings->UnicodeInput) { @@ -321,7 +338,6 @@ static BOOL input_send_fastpath_unicode_keyboard_event(rdpInput* input, UINT16 f return FALSE; } - rdp = input->context->rdp; eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0; s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_UNICODE); @@ -337,10 +353,12 @@ static BOOL input_send_fastpath_mouse_event(rdpInput* input, UINT16 flags, UINT1 wStream* s; rdpRdp* rdp; - if (!input || !input->context || !input->context->settings) - return FALSE; + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); + WINPR_ASSERT(input->context->settings); rdp = input->context->rdp; + WINPR_ASSERT(rdp); if (!input->context->settings->HasHorizontalWheel) { @@ -369,8 +387,11 @@ static BOOL input_send_fastpath_extended_mouse_event(rdpInput* input, UINT16 fla wStream* s; rdpRdp* rdp; - if (!input || !input->context) - return FALSE; + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); + + rdp = input->context->rdp; + WINPR_ASSERT(rdp); if (!input->context->settings->HasExtendedMouseEvent) { @@ -381,7 +402,6 @@ static BOOL input_send_fastpath_extended_mouse_event(rdpInput* input, UINT16 fla return TRUE; } - rdp = input->context->rdp; s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSEX); if (!s) @@ -397,10 +417,12 @@ static BOOL input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleSta BYTE eventFlags = 0; rdpRdp* rdp; - if (!input || !input->context) - return FALSE; + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); rdp = input->context->rdp; + WINPR_ASSERT(rdp); + s = fastpath_input_pdu_init_header(rdp->fastpath); if (!s) @@ -431,10 +453,12 @@ static BOOL input_send_fastpath_keyboard_pause_event(rdpInput* input) const BYTE keyUpEvent = (FASTPATH_INPUT_EVENT_SCANCODE << 5) | FASTPATH_INPUT_KBDFLAGS_RELEASE; rdpRdp* rdp; - if (!input || !input->context) - return FALSE; + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); rdp = input->context->rdp; + WINPR_ASSERT(rdp); + s = fastpath_input_pdu_init_header(rdp->fastpath); if (!s) @@ -459,7 +483,10 @@ static BOOL input_recv_sync_event(rdpInput* input, wStream* s) { UINT32 toggleFlags; - if (Stream_GetRemainingLength(s) < 6) + WINPR_ASSERT(input); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ @@ -471,7 +498,10 @@ static BOOL input_recv_keyboard_event(rdpInput* input, wStream* s) { UINT16 keyboardFlags, keyCode; - if (Stream_GetRemainingLength(s) < 6) + WINPR_ASSERT(input); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; Stream_Read_UINT16(s, keyboardFlags); /* keyboardFlags (2 bytes) */ @@ -510,7 +540,10 @@ static BOOL input_recv_unicode_keyboard_event(rdpInput* input, wStream* s) { UINT16 keyboardFlags, unicodeCode; - if (Stream_GetRemainingLength(s) < 6) + WINPR_ASSERT(input); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; Stream_Read_UINT16(s, keyboardFlags); /* keyboardFlags (2 bytes) */ @@ -531,7 +564,10 @@ static BOOL input_recv_mouse_event(rdpInput* input, wStream* s) { UINT16 pointerFlags, xPos, yPos; - if (Stream_GetRemainingLength(s) < 6) + WINPR_ASSERT(input); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */ @@ -544,7 +580,10 @@ static BOOL input_recv_extended_mouse_event(rdpInput* input, wStream* s) { UINT16 pointerFlags, xPos, yPos; - if (Stream_GetRemainingLength(s) < 6) + WINPR_ASSERT(input); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */ @@ -557,7 +596,10 @@ static BOOL input_recv_event(rdpInput* input, wStream* s) { UINT16 messageType; - if (Stream_GetRemainingLength(s) < 6) + WINPR_ASSERT(input); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; Stream_Seek(s, 4); /* eventTime (4 bytes), ignored by the server */ @@ -609,17 +651,17 @@ BOOL input_recv(rdpInput* input, wStream* s) { UINT16 i, numberEvents; - if (!input || !s) - return FALSE; + WINPR_ASSERT(input); + WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, numberEvents); /* numberEvents (2 bytes) */ Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ /* Each input event uses 6 exactly bytes. */ - if (Stream_GetRemainingLength(s) / 6 < numberEvents) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6ull * numberEvents)) return FALSE; for (i = 0; i < numberEvents; i++) @@ -634,6 +676,7 @@ BOOL input_recv(rdpInput* input, wStream* s) BOOL input_register_client_callbacks(rdpInput* input) { rdpSettings* settings; + rdp_input_internal* in = input_cast(input); if (!input->context) return FALSE; diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index 865cb96ac..e0dd49c41 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -334,7 +334,7 @@ error_path: static BOOL license_read_preamble(wStream* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsgSize) { /* preamble (4 bytes) */ - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT8(s, *bMsgType); /* bMsgType (1 byte) */ @@ -779,7 +779,7 @@ static BOOL license_decrypt_and_check_MAC(rdpLicense* license, const BYTE* input BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */ @@ -789,7 +789,7 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo) if ((productInfo->cbCompanyName < 2) || (productInfo->cbCompanyName % 2 != 0)) return FALSE; - if (Stream_GetRemainingLength(s) < productInfo->cbCompanyName) + if (!Stream_CheckAndLogRequiredLength(TAG, s, productInfo->cbCompanyName)) return FALSE; productInfo->pbProductId = NULL; @@ -798,7 +798,7 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo) return FALSE; Stream_Read(s, productInfo->pbCompanyName, productInfo->cbCompanyName); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) goto out_fail; Stream_Read_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */ @@ -806,7 +806,7 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo) if ((productInfo->cbProductId < 2) || (productInfo->cbProductId % 2 != 0)) goto out_fail; - if (Stream_GetRemainingLength(s) < productInfo->cbProductId) + if (!Stream_CheckAndLogRequiredLength(TAG, s, productInfo->cbProductId)) goto out_fail; productInfo->pbProductId = (BYTE*)malloc(productInfo->cbProductId); @@ -870,13 +870,13 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob) { UINT16 wBlobType; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, wBlobType); /* wBlobType (2 bytes) */ Stream_Read_UINT16(s, blob->length); /* wBlobLen (2 bytes) */ - if (Stream_GetRemainingLength(s) < blob->length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, blob->length)) return FALSE; /* @@ -988,12 +988,13 @@ BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList) UINT32 i; UINT32 scopeCount; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, scopeCount); /* ScopeCount (4 bytes) */ - if (scopeCount > Stream_GetRemainingLength(s) / 4) /* every blob is at least 4 bytes */ + if (!Stream_CheckAndLogRequiredLength(TAG, s, + 4ull * scopeCount)) /* every blob is at least 4 bytes */ return FALSE; scopeList->count = scopeCount; @@ -1104,7 +1105,7 @@ error: BOOL license_read_license_request_packet(rdpLicense* license, wStream* s) { /* ServerRandom (32 bytes) */ - if (Stream_GetRemainingLength(s) < 32) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 32)) return FALSE; Stream_Read(s, license->ServerRandom, 32); @@ -1157,7 +1158,7 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s) DEBUG_LICENSE("Receiving Platform Challenge Packet"); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, ConnectFlags); /* ConnectFlags, Reserved (4 bytes) */ @@ -1169,7 +1170,7 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s) license->EncryptedPlatformChallenge->type = BB_ENCRYPTED_DATA_BLOB; /* MACData (16 bytes) */ - if (Stream_GetRemainingLength(s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return FALSE; Stream_Read(s, macData, 16); @@ -1197,7 +1198,7 @@ static BOOL license_read_encrypted_blob(const rdpLicense* license, wStream* s, L UINT16 wBlobType, wBlobLen; BYTE* encryptedData; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, wBlobType); @@ -1210,7 +1211,7 @@ static BOOL license_read_encrypted_blob(const rdpLicense* license, wStream* s, L Stream_Read_UINT16(s, wBlobLen); - if (Stream_GetRemainingLength(s) < wBlobLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, wBlobLen)) return FALSE; encryptedData = Stream_Pointer(s); @@ -1246,7 +1247,7 @@ BOOL license_read_new_or_upgrade_license_packet(rdpLicense* license, wStream* s) goto out_free_blob; /* compute MAC and check it */ - if (Stream_GetRemainingLength(s) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) goto out_free_blob; if (!security_mac_data(license->MacSaltKey, calBlob->data, calBlob->length, computedMac)) @@ -1265,7 +1266,7 @@ BOOL license_read_new_or_upgrade_license_packet(rdpLicense* license, wStream* s) if (!licenseStream) goto out_free_blob; - if (Stream_GetRemainingLength(licenseStream) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, licenseStream, 8)) goto out_free_stream; Stream_Read_UINT16(licenseStream, os_minor); @@ -1273,7 +1274,7 @@ BOOL license_read_new_or_upgrade_license_packet(rdpLicense* license, wStream* s) /* Scope */ Stream_Read_UINT32(licenseStream, cbScope); - if (Stream_GetRemainingLength(licenseStream) < cbScope) + if (!Stream_CheckAndLogRequiredLength(TAG, licenseStream, cbScope)) goto out_free_stream; #ifdef WITH_DEBUG_LICENSE WLog_DBG(TAG, "Scope:"); @@ -1282,10 +1283,10 @@ BOOL license_read_new_or_upgrade_license_packet(rdpLicense* license, wStream* s) Stream_Seek(licenseStream, cbScope); /* CompanyName */ - if (Stream_GetRemainingLength(licenseStream) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, licenseStream, 4)) goto out_free_stream; Stream_Read_UINT32(licenseStream, cbCompanyName); - if (Stream_GetRemainingLength(licenseStream) < cbCompanyName) + if (!Stream_CheckAndLogRequiredLength(TAG, licenseStream, cbCompanyName)) goto out_free_stream; #ifdef WITH_DEBUG_LICENSE WLog_DBG(TAG, "Company name:"); @@ -1294,10 +1295,10 @@ BOOL license_read_new_or_upgrade_license_packet(rdpLicense* license, wStream* s) Stream_Seek(licenseStream, cbCompanyName); /* productId */ - if (Stream_GetRemainingLength(licenseStream) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, licenseStream, 4)) goto out_free_stream; Stream_Read_UINT32(licenseStream, cbProductId); - if (Stream_GetRemainingLength(licenseStream) < cbProductId) + if (!Stream_CheckAndLogRequiredLength(TAG, licenseStream, cbProductId)) goto out_free_stream; #ifdef WITH_DEBUG_LICENSE WLog_DBG(TAG, "Product id:"); @@ -1306,10 +1307,10 @@ BOOL license_read_new_or_upgrade_license_packet(rdpLicense* license, wStream* s) Stream_Seek(licenseStream, cbProductId); /* licenseInfo */ - if (Stream_GetRemainingLength(licenseStream) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, licenseStream, 4)) goto out_free_stream; Stream_Read_UINT32(licenseStream, cbLicenseInfo); - if (Stream_GetRemainingLength(licenseStream) < cbLicenseInfo) + if (!Stream_CheckAndLogRequiredLength(TAG, licenseStream, cbLicenseInfo)) goto out_free_stream; license->state = LICENSE_STATE_COMPLETED; @@ -1338,7 +1339,7 @@ BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s) UINT32 dwErrorCode; UINT32 dwStateTransition; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, dwErrorCode); /* dwErrorCode (4 bytes) */ diff --git a/libfreerdp/core/mcs.c b/libfreerdp/core/mcs.c index 9cb9a5bdd..89e315087 100644 --- a/libfreerdp/core/mcs.c +++ b/libfreerdp/core/mcs.c @@ -24,6 +24,7 @@ #include #include +#include #include #include "gcc.h" @@ -341,8 +342,9 @@ BOOL mcs_read_domain_mcspdu_header(wStream* s, DomainMCSPDU domainMCSPDU, UINT16 if (actual) *actual = DomainMCSPDU_invalid; - if (!s || !domainMCSPDU || !length) - return FALSE; + WINPR_ASSERT(s); + WINPR_ASSERT(domainMCSPDU); + WINPR_ASSERT(length); if (!tpkt_read_header(s, length)) return FALSE; @@ -377,6 +379,10 @@ BOOL mcs_read_domain_mcspdu_header(wStream* s, DomainMCSPDU domainMCSPDU, UINT16 void mcs_write_domain_mcspdu_header(wStream* s, DomainMCSPDU domainMCSPDU, UINT16 length, BYTE options) { + WINPR_ASSERT(s); + WINPR_ASSERT((options & ~0x03) == 0); + WINPR_ASSERT((domainMCSPDU & ~0x3F) == 0); + tpkt_write_header(s, length); tpdu_write_data(s); per_write_choice(s, (BYTE)((domainMCSPDU << 2) | options)); @@ -629,8 +635,8 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s) BOOL upwardFlag; UINT16 tlength; - if (!mcs || !s) - return FALSE; + WINPR_ASSERT(mcs); + WINPR_ASSERT(s); if (!tpkt_read_header(s, &tlength)) return FALSE; @@ -642,13 +648,15 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s) return FALSE; /* callingDomainSelector (OCTET_STRING) */ - if (!ber_read_octet_string_tag(s, &length) || (Stream_GetRemainingLength(s)) < length) + if (!ber_read_octet_string_tag(s, &length) || + (!Stream_CheckAndLogRequiredLength(TAG, s, length))) return FALSE; Stream_Seek(s, length); /* calledDomainSelector (OCTET_STRING) */ - if (!ber_read_octet_string_tag(s, &length) || (Stream_GetRemainingLength(s)) < length) + if (!ber_read_octet_string_tag(s, &length) || + (!Stream_CheckAndLogRequiredLength(TAG, s, length))) return FALSE; Stream_Seek(s, length); @@ -669,7 +677,8 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s) if (!mcs_read_domain_parameters(s, &mcs->maximumParameters)) return FALSE; - if (!ber_read_octet_string_tag(s, &length) || (Stream_GetRemainingLength(s)) < length) + if (!ber_read_octet_string_tag(s, &length) || + (!Stream_CheckAndLogRequiredLength(TAG, s, length))) return FALSE; if (!gcc_read_conference_create_request(s, mcs)) @@ -985,8 +994,8 @@ BOOL mcs_recv_erect_domain_request(rdpMcs* mcs, wStream* s) UINT32 subHeight; UINT32 subInterval; - if (!mcs || !s) - return FALSE; + WINPR_ASSERT(mcs); + WINPR_ASSERT(s); if (!mcs_read_domain_mcspdu_header(s, DomainMCSPDU_ErectDomainRequest, &length, NULL)) return FALSE; @@ -1269,8 +1278,9 @@ BOOL mcs_recv_disconnect_provider_ultimatum(rdpMcs* mcs, wStream* s, int* reason { BYTE b1, b2; - if (!mcs || !s || !reason) - return FALSE; + WINPR_ASSERT(mcs); + WINPR_ASSERT(s); + WINPR_ASSERT(reason); /* * http://msdn.microsoft.com/en-us/library/cc240872.aspx: @@ -1299,7 +1309,7 @@ BOOL mcs_recv_disconnect_provider_ultimatum(rdpMcs* mcs, wStream* s, int* reason * 0 - padding */ - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Rewind_UINT8(s); @@ -1320,8 +1330,7 @@ BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs) int status; UINT16 length = 9; - if (!mcs) - return FALSE; + WINPR_ASSERT(mcs); s = Stream_New(NULL, length); @@ -1351,7 +1360,6 @@ BOOL mcs_client_begin(rdpMcs* mcs) return FALSE; /* First transition state, we need this to trigger session recording */ - rdp_client_transition_to_state(context->rdp, CONNECTION_STATE_MCS_CONNECT); if (!mcs_send_connect_initial(mcs)) { freerdp_set_last_error_if_not(context, FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR); diff --git a/libfreerdp/core/mcs.h b/libfreerdp/core/mcs.h index e0df8a958..9b9a5ba14 100644 --- a/libfreerdp/core/mcs.h +++ b/libfreerdp/core/mcs.h @@ -136,6 +136,8 @@ struct rdp_mcs UINT16 baseChannelId; UINT16 messageChannelId; + UINT32 flags; + DomainParameters domainParameters; DomainParameters targetParameters; DomainParameters minimumParameters; diff --git a/libfreerdp/core/multitransport.c b/libfreerdp/core/multitransport.c index 7613a2473..e96c47dd3 100644 --- a/libfreerdp/core/multitransport.c +++ b/libfreerdp/core/multitransport.c @@ -21,6 +21,10 @@ #include "multitransport.h" +#include + +#define TAG FREERDP_TAG("core.multitransport") + int rdp_recv_multitransport_packet(rdpRdp* rdp, wStream* s) { UINT32 requestId; @@ -28,7 +32,7 @@ int rdp_recv_multitransport_packet(rdpRdp* rdp, wStream* s) UINT16 reserved; BYTE securityCookie[16]; - if (Stream_GetRemainingLength(s) < 24) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 24)) return -1; Stream_Read_UINT32(s, requestId); /* requestId (4 bytes) */ diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index 194362a83..06c579d84 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -24,6 +24,7 @@ #include #include +#include #include @@ -982,7 +983,7 @@ static BOOL nego_process_correlation_info(rdpNego* nego, wStream* s) UINT16 length; BYTE correlationId[16] = { 0 }; - if (Stream_GetRemainingLength(s) < 36) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 36)) { WLog_ERR(TAG, "RDP_NEG_REQ::flags CORRELATION_INFO_PRESENT but data is missing"); return FALSE; @@ -1047,7 +1048,7 @@ BOOL nego_process_negotiation_request(rdpNego* nego, wStream* s) WINPR_ASSERT(nego); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 7) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 7)) return FALSE; Stream_Read_UINT8(s, flags); if ((flags & ~(RESTRICTED_ADMIN_MODE_REQUIRED | REDIRECTED_AUTHENTICATION_MODE_REQUIRED | @@ -1130,9 +1131,8 @@ BOOL nego_process_negotiation_response(rdpNego* nego, wStream* s) WINPR_ASSERT(nego); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 7) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 7)) { - WLog_ERR(TAG, "RDP_NEG_RSP short data %" PRIuz, Stream_GetRemainingLength(s)); nego_set_state(nego, NEGO_STATE_FAIL); return FALSE; } @@ -1168,11 +1168,9 @@ BOOL nego_process_negotiation_failure(rdpNego* nego, wStream* s) WINPR_ASSERT(s); WLog_DBG(TAG, "RDP_NEG_FAILURE"); - if (Stream_GetRemainingLength(s) < 7) - { - WLog_ERR(TAG, "RDP_NEG_FAILURE short data %" PRIuz, Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 7)) return FALSE; - } + Stream_Read_UINT8(s, flags); if (flags != 0) { diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 260454b01..366d894b3 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -202,7 +202,7 @@ static BOOL nla_decode_to_buffer(wStream* s, SecBuffer* buffer) if (!s || !buffer) return FALSE; if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ - Stream_GetRemainingLength(s) < length) + !Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; rc = nla_sec_buffer_alloc_from_data(buffer, Stream_Pointer(s), 0, length); diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 27080bc10..413254099 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -511,7 +511,7 @@ static INLINE BOOL update_read_coord(wStream* s, INT32* coord, BOOL delta) if (delta) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_INT8(s, lsi8); @@ -519,7 +519,7 @@ static INLINE BOOL update_read_coord(wStream* s, INT32* coord, BOOL delta) } else { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_INT16(s, lsi16); @@ -537,7 +537,7 @@ static INLINE BOOL update_read_color(wStream* s, UINT32* color) { BYTE byte; - if (Stream_GetRemainingLength(s) < 3) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3)) return FALSE; *color = 0; @@ -564,7 +564,7 @@ static INLINE BOOL update_read_colorref(wStream* s, UINT32* color) { BYTE byte; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; *color = 0; @@ -595,14 +595,14 @@ static INLINE BOOL update_read_2byte_unsigned(wStream* s, UINT32* value) { BYTE byte; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); if (byte & 0x80) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; *value = (byte & 0x7F) << 8; @@ -643,7 +643,7 @@ static INLINE BOOL update_read_2byte_signed(wStream* s, INT32* value) BYTE byte; BOOL negative; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -652,7 +652,7 @@ static INLINE BOOL update_read_2byte_signed(wStream* s, INT32* value) if (byte & 0x80) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -706,13 +706,13 @@ static INLINE BOOL update_read_4byte_unsigned(wStream* s, UINT32* value) BYTE byte; BYTE count; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); count = (byte & 0xC0) >> 6; - if (Stream_GetRemainingLength(s) < count) + if (!Stream_CheckAndLogRequiredLength(TAG, s, count)) return FALSE; switch (count) @@ -795,11 +795,8 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value) { BYTE byte; - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 1"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, byte); @@ -810,11 +807,8 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value) if (byte & 0x80) { - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 1"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, byte); *value = (*value << 8) | byte; @@ -846,7 +840,7 @@ static INLINE BOOL update_read_brush(wStream* s, rdpBrush* brush, BYTE fieldFlag { if (fieldFlags & ORDER_FIELD_01) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, brush->x); @@ -854,7 +848,7 @@ static INLINE BOOL update_read_brush(wStream* s, rdpBrush* brush, BYTE fieldFlag if (fieldFlags & ORDER_FIELD_02) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, brush->y); @@ -862,7 +856,7 @@ static INLINE BOOL update_read_brush(wStream* s, rdpBrush* brush, BYTE fieldFlag if (fieldFlags & ORDER_FIELD_03) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, brush->style); @@ -870,7 +864,7 @@ static INLINE BOOL update_read_brush(wStream* s, rdpBrush* brush, BYTE fieldFlag if (fieldFlags & ORDER_FIELD_04) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, brush->hatch); @@ -889,7 +883,7 @@ static INLINE BOOL update_read_brush(wStream* s, rdpBrush* brush, BYTE fieldFlag if (fieldFlags & ORDER_FIELD_05) { - if (Stream_GetRemainingLength(s) < 7) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 7)) return FALSE; brush->data = (BYTE*)brush->p8x8; @@ -969,7 +963,7 @@ static INLINE BOOL update_read_delta_rects(wStream* s, DELTA_RECT* rectangles, U zeroBitsSize = ((number + 1) / 2); - if (Stream_GetRemainingLength(s) < zeroBitsSize) + if (!Stream_CheckAndLogRequiredLength(TAG, s, zeroBitsSize)) return FALSE; Stream_GetPointer(s, zeroBits); @@ -1027,11 +1021,8 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, UIN BYTE* zeroBits; UINT32 zeroBitsSize = ((number + 3) / 4); - if (Stream_GetRemainingLength(s) < zeroBitsSize) - { - WLog_ERR(TAG, "Stream_GetRemainingLength(s) < %" PRIu32 "", zeroBitsSize); + if (!Stream_CheckAndLogRequiredLength(TAG, s, zeroBitsSize)) return FALSE; - } Stream_GetPointer(s, zeroBits); Stream_Seek(s, zeroBitsSize); @@ -1072,7 +1063,7 @@ static INLINE BOOL read_order_field_byte(const ORDER_INFO* orderInfo, wStream* s { if (!order_field_flag_is_set(orderInfo, number)) return TRUE; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, *target); return TRUE; @@ -1083,7 +1074,7 @@ static INLINE BOOL read_order_field_2bytes(const ORDER_INFO* orderInfo, wStream* { if (!order_field_flag_is_set(orderInfo, number)) return TRUE; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT8(s, *target1); Stream_Read_UINT8(s, *target2); @@ -1096,7 +1087,7 @@ static INLINE BOOL read_order_field_uint16(const ORDER_INFO* orderInfo, wStream* if (!order_field_flag_is_set(orderInfo, number)) return TRUE; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, *target); @@ -1109,7 +1100,7 @@ static INLINE BOOL read_order_field_int16(const ORDER_INFO* orderInfo, wStream* if (!order_field_flag_is_set(orderInfo, number)) return TRUE; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_INT16(s, *target); @@ -1121,7 +1112,7 @@ static INLINE BOOL read_order_field_uint32(const ORDER_INFO* orderInfo, wStream* { if (!order_field_flag_is_set(orderInfo, number)) return TRUE; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, *target); @@ -1154,7 +1145,7 @@ static INLINE BOOL read_order_field_color(const ORDER_INFO* orderInfo, wStream* } static INLINE BOOL FIELD_SKIP_BUFFER16(wStream* s, UINT32 TARGET_LEN) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, TARGET_LEN); @@ -1309,7 +1300,7 @@ static BOOL update_read_opaque_rect_order(wStream* s, const ORDER_INFO* orderInf if ((orderInfo->fieldFlags & ORDER_FIELD_05) != 0) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -1318,7 +1309,7 @@ static BOOL update_read_opaque_rect_order(wStream* s, const ORDER_INFO* orderInf if ((orderInfo->fieldFlags & ORDER_FIELD_06) != 0) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -1327,7 +1318,7 @@ static BOOL update_read_opaque_rect_order(wStream* s, const ORDER_INFO* orderInf if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -1401,7 +1392,7 @@ static BOOL update_read_multi_dstblt_order(wStream* s, const ORDER_INFO* orderIn if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, multi_dstblt->cbData); @@ -1431,7 +1422,7 @@ static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderIn if ((orderInfo->fieldFlags & ORDER_FIELD_14) != 0) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, multi_patblt->cbData); @@ -1458,7 +1449,7 @@ static BOOL update_read_multi_scrblt_order(wStream* s, const ORDER_INFO* orderIn if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, multi_scrblt->cbData); @@ -1480,7 +1471,7 @@ static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* or if ((orderInfo->fieldFlags & ORDER_FIELD_05) != 0) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -1489,7 +1480,7 @@ static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* or if ((orderInfo->fieldFlags & ORDER_FIELD_06) != 0) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -1498,7 +1489,7 @@ static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* or if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -1510,7 +1501,7 @@ static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* or if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, multi_opaque_rect->cbData); @@ -1534,7 +1525,7 @@ static BOOL update_read_multi_draw_nine_grid_order(wStream* s, const ORDER_INFO* if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, multi_draw_nine_grid->cbData); @@ -1617,11 +1608,8 @@ static BOOL update_read_polyline_order(wStream* s, const ORDER_INFO* orderInfo, if (new_num == 0) return FALSE; - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 1"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, polyline->cbData); new_points = (DELTA_POINT*)realloc(polyline->points, sizeof(DELTA_POINT) * new_num); @@ -1756,12 +1744,12 @@ static BOOL update_read_glyph_index_order(wStream* s, const ORDER_INFO* orderInf if ((orderInfo->fieldFlags & ORDER_FIELD_22) != 0) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, glyph_index->cbData); - if (Stream_GetRemainingLength(s) < glyph_index->cbData) + if (!Stream_CheckAndLogRequiredLength(TAG, s, glyph_index->cbData)) return FALSE; CopyMemory(glyph_index->data, Stream_Pointer(s), glyph_index->cbData); @@ -1853,12 +1841,12 @@ static BOOL update_read_fast_index_order(wStream* s, const ORDER_INFO* orderInfo if ((orderInfo->fieldFlags & ORDER_FIELD_15) != 0) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, fast_index->cbData); - if (Stream_GetRemainingLength(s) < fast_index->cbData) + if (!Stream_CheckAndLogRequiredLength(TAG, s, fast_index->cbData)) return FALSE; CopyMemory(fast_index->data, Stream_Pointer(s), fast_index->cbData); @@ -1896,7 +1884,7 @@ static BOOL update_read_fast_glyph_order(wStream* s, const ORDER_INFO* orderInfo const BYTE* src; wStream subbuffer; wStream* sub; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, fastGlyph->cbData); @@ -1965,7 +1953,7 @@ static BOOL update_read_polygon_sc_order(wStream* s, const ORDER_INFO* orderInfo if (num == 0) return FALSE; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, polygon_sc->cbData); @@ -2007,7 +1995,7 @@ static BOOL update_read_polygon_cb_order(wStream* s, const ORDER_INFO* orderInfo if (num == 0) return FALSE; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, polygon_cb->cbData); @@ -2071,7 +2059,7 @@ static CACHE_BITMAP_ORDER* update_read_cache_bitmap_order(rdpUpdate* update, wSt if (!cache_bitmap) goto fail; - if (Stream_GetRemainingLength(s) < 9) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 9)) goto fail; Stream_Read_UINT8(s, cache_bitmap->cacheId); /* cacheId (1 byte) */ @@ -2095,7 +2083,7 @@ static CACHE_BITMAP_ORDER* update_read_cache_bitmap_order(rdpUpdate* update, wSt { BYTE* bitmapComprHdr = (BYTE*)&(cache_bitmap->bitmapComprHdr); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) goto fail; Stream_Read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */ @@ -2106,7 +2094,7 @@ static CACHE_BITMAP_ORDER* update_read_cache_bitmap_order(rdpUpdate* update, wSt if (cache_bitmap->bitmapLength == 0) goto fail; - if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, cache_bitmap->bitmapLength)) goto fail; cache_bitmap->bitmapDataStream = malloc(cache_bitmap->bitmapLength); @@ -2196,7 +2184,7 @@ static CACHE_BITMAP_V2_ORDER* update_read_cache_bitmap_v2_order(rdpUpdate* updat if (cache_bitmap_v2->flags & CBR2_PERSISTENT_KEY_PRESENT) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) goto fail; Stream_Read_UINT32(s, cache_bitmap_v2->key1); /* key1 (4 bytes) */ @@ -2228,7 +2216,7 @@ static CACHE_BITMAP_V2_ORDER* update_read_cache_bitmap_v2_order(rdpUpdate* updat { if (!(cache_bitmap_v2->flags & CBR2_NO_BITMAP_COMPRESSION_HDR)) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) goto fail; Stream_Read_UINT16( @@ -2245,7 +2233,7 @@ static CACHE_BITMAP_V2_ORDER* update_read_cache_bitmap_v2_order(rdpUpdate* updat if (cache_bitmap_v2->bitmapLength == 0) goto fail; - if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, cache_bitmap_v2->bitmapLength)) goto fail; if (cache_bitmap_v2->bitmapLength == 0) @@ -2371,7 +2359,7 @@ static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* updat if (!rc) goto fail; - if (Stream_GetRemainingLength(s) < 21) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 21)) goto fail; Stream_Read_UINT16(s, cache_bitmap_v3->cacheIndex); /* cacheIndex (2 bytes) */ @@ -2393,7 +2381,7 @@ static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* updat Stream_Read_UINT16(s, bitmapData->height); /* height (2 bytes) */ Stream_Read_UINT32(s, new_len); /* length (4 bytes) */ - if ((new_len == 0) || (Stream_GetRemainingLength(s) < new_len)) + if ((new_len == 0) || (!Stream_CheckAndLogRequiredLength(TAG, s, new_len))) goto fail; new_data = (BYTE*)realloc(bitmapData->data, new_len); @@ -2457,7 +2445,7 @@ static CACHE_COLOR_TABLE_ORDER* update_read_cache_color_table_order(rdpUpdate* u if (!cache_color_table) goto fail; - if (Stream_GetRemainingLength(s) < 3) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3)) goto fail; Stream_Read_UINT8(s, cache_color_table->cacheIndex); /* cacheIndex (1 byte) */ @@ -2469,7 +2457,7 @@ static CACHE_COLOR_TABLE_ORDER* update_read_cache_color_table_order(rdpUpdate* u goto fail; } - if (Stream_GetRemainingLength(s) / 4 < cache_color_table->numberColors) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4ull * cache_color_table->numberColors)) goto fail; colorTable = (UINT32*)&cache_color_table->colorTable; @@ -2527,7 +2515,7 @@ static CACHE_GLYPH_ORDER* update_read_cache_glyph_order(rdpUpdate* update, wStre if (!cache_glyph_order || !update || !s) goto fail; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) goto fail; Stream_Read_UINT8(s, cache_glyph_order->cacheId); /* cacheId (1 byte) */ @@ -2537,7 +2525,7 @@ static CACHE_GLYPH_ORDER* update_read_cache_glyph_order(rdpUpdate* update, wStre { GLYPH_DATA* glyph = &cache_glyph_order->glyphData[i]; - if (Stream_GetRemainingLength(s) < 10) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 10)) goto fail; Stream_Read_UINT16(s, glyph->cacheIndex); @@ -2548,7 +2536,7 @@ static CACHE_GLYPH_ORDER* update_read_cache_glyph_order(rdpUpdate* update, wStre glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; - if (Stream_GetRemainingLength(s) < glyph->cb) + if (!Stream_CheckAndLogRequiredLength(TAG, s, glyph->cb)) goto fail; glyph->aj = (BYTE*)malloc(glyph->cb); @@ -2566,7 +2554,7 @@ static CACHE_GLYPH_ORDER* update_read_cache_glyph_order(rdpUpdate* update, wStre if (!cache_glyph_order->unicodeCharacters) goto fail; - if (Stream_GetRemainingLength(s) < sizeof(WCHAR) * cache_glyph_order->cGlyphs) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(WCHAR) * cache_glyph_order->cGlyphs)) goto fail; Stream_Read_UTF16_String(s, cache_glyph_order->unicodeCharacters, @@ -2640,7 +2628,7 @@ static CACHE_GLYPH_V2_ORDER* update_read_cache_glyph_v2_order(rdpUpdate* update, { GLYPH_DATA_V2* glyph = &cache_glyph_v2->glyphData[i]; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) goto fail; Stream_Read_UINT8(s, glyph->cacheIndex); @@ -2655,7 +2643,7 @@ static CACHE_GLYPH_V2_ORDER* update_read_cache_glyph_v2_order(rdpUpdate* update, glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; - if (Stream_GetRemainingLength(s) < glyph->cb) + if (!Stream_CheckAndLogRequiredLength(TAG, s, glyph->cb)) goto fail; glyph->aj = (BYTE*)malloc(glyph->cb); @@ -2673,7 +2661,7 @@ static CACHE_GLYPH_V2_ORDER* update_read_cache_glyph_v2_order(rdpUpdate* update, if (!cache_glyph_v2->unicodeCharacters) goto fail; - if (Stream_GetRemainingLength(s) < sizeof(WCHAR) * cache_glyph_v2->cGlyphs) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(WCHAR) * cache_glyph_v2->cGlyphs)) goto fail; Stream_Read_UTF16_String(s, cache_glyph_v2->unicodeCharacters, cache_glyph_v2->cGlyphs); @@ -2738,7 +2726,7 @@ static BOOL update_decompress_brush(wStream* s, BYTE* output, size_t outSize, BY const BYTE* palette = Stream_Pointer(s) + 16; const size_t bytesPerPixel = ((bpp + 1) / 8); - if (Stream_GetRemainingLength(s) < 16ULL + bytesPerPixel * 4ULL) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16ULL + bytesPerPixel * 4ULL)) return FALSE; for (y = 7; y >= 0; y--) @@ -2780,7 +2768,7 @@ static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStre if (!cache_brush) goto fail; - if (Stream_GetRemainingLength(s) < 6) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) goto fail; Stream_Read_UINT8(s, cache_brush->index); /* cacheEntry (1 byte) */ @@ -2808,7 +2796,7 @@ static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStre goto fail; } - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) goto fail; /* rows are encoded in reverse order */ @@ -2838,7 +2826,7 @@ static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStre /* uncompressed brush */ UINT32 scanline = (cache_brush->bpp / 8) * 8; - if (Stream_GetRemainingLength(s) / 8 < scanline) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ull * scanline)) goto fail; for (i = 7; i >= 0; i--) @@ -2938,7 +2926,7 @@ update_read_create_offscreen_bitmap_order(wStream* s, BOOL deleteListPresent; OFFSCREEN_DELETE_LIST* deleteList; - if (Stream_GetRemainingLength(s) < 6) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; Stream_Read_UINT16(s, flags); /* flags (2 bytes) */ @@ -2959,7 +2947,7 @@ update_read_create_offscreen_bitmap_order(wStream* s, { UINT32 i; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, deleteList->cIndices); @@ -2976,7 +2964,7 @@ update_read_create_offscreen_bitmap_order(wStream* s, deleteList->indices = new_indices; } - if (Stream_GetRemainingLength(s) / 2 < deleteList->cIndices) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2ull * deleteList->cIndices)) return FALSE; for (i = 0; i < deleteList->cIndices; i++) @@ -3042,7 +3030,7 @@ BOOL update_write_create_offscreen_bitmap_order( } static BOOL update_read_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, switch_surface->bitmapId); /* bitmapId (2 bytes) */ @@ -3068,7 +3056,7 @@ update_read_create_nine_grid_bitmap_order(wStream* s, { NINE_GRID_BITMAP_INFO* nineGridInfo; - if (Stream_GetRemainingLength(s) < 19) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 19)) return FALSE; Stream_Read_UINT8(s, create_nine_grid_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */ @@ -3091,7 +3079,7 @@ update_read_create_nine_grid_bitmap_order(wStream* s, } static BOOL update_read_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, frame_marker->action); /* action (4 bytes) */ @@ -3100,7 +3088,7 @@ static BOOL update_read_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame static BOOL update_read_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first) { - if (Stream_GetRemainingLength(s) < 10) // 8 + 2 at least + if (!Stream_CheckAndLogRequiredLength(TAG, s, 10)) // 8 + 2 at least return FALSE; Stream_Read_UINT8(s, stream_bitmap_first->bitmapFlags); /* bitmapFlags (1 byte) */ @@ -3118,14 +3106,14 @@ static BOOL update_read_stream_bitmap_first_order(wStream* s, if (stream_bitmap_first->bitmapFlags & STREAM_BITMAP_V2) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, stream_bitmap_first->bitmapSize); /* bitmapSize (4 bytes) */ } else { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, stream_bitmap_first->bitmapSize); /* bitmapSize (2 bytes) */ @@ -3138,7 +3126,7 @@ static BOOL update_read_stream_bitmap_first_order(wStream* s, static BOOL update_read_stream_bitmap_next_order(wStream* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next) { - if (Stream_GetRemainingLength(s) < 5) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return FALSE; Stream_Read_UINT8(s, stream_bitmap_next->bitmapFlags); /* bitmapFlags (1 byte) */ @@ -3150,7 +3138,7 @@ static BOOL update_read_stream_bitmap_next_order(wStream* s, static BOOL update_read_draw_gdiplus_first_order(wStream* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first) { - if (Stream_GetRemainingLength(s) < 11) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 11)) return FALSE; Stream_Seek_UINT8(s); /* pad1Octet (1 byte) */ @@ -3162,7 +3150,7 @@ static BOOL update_read_draw_gdiplus_first_order(wStream* s, static BOOL update_read_draw_gdiplus_next_order(wStream* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next) { - if (Stream_GetRemainingLength(s) < 3) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3)) return FALSE; Stream_Seek_UINT8(s); /* pad1Octet (1 byte) */ @@ -3171,7 +3159,7 @@ static BOOL update_read_draw_gdiplus_next_order(wStream* s, } static BOOL update_read_draw_gdiplus_end_order(wStream* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end) { - if (Stream_GetRemainingLength(s) < 11) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 11)) return FALSE; Stream_Seek_UINT8(s); /* pad1Octet (1 byte) */ @@ -3184,7 +3172,7 @@ static BOOL update_read_draw_gdiplus_cache_first_order(wStream* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first) { - if (Stream_GetRemainingLength(s) < 11) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 11)) return FALSE; Stream_Read_UINT8(s, draw_gdiplus_cache_first->flags); /* flags (1 byte) */ @@ -3198,7 +3186,7 @@ static BOOL update_read_draw_gdiplus_cache_next_order(wStream* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next) { - if (Stream_GetRemainingLength(s) < 7) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 7)) return FALSE; Stream_Read_UINT8(s, draw_gdiplus_cache_next->flags); /* flags (1 byte) */ @@ -3211,7 +3199,7 @@ static BOOL update_read_draw_gdiplus_cache_end_order(wStream* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end) { - if (Stream_GetRemainingLength(s) < 11) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 11)) return FALSE; Stream_Read_UINT8(s, draw_gdiplus_cache_end->flags); /* flags (1 byte) */ @@ -3237,7 +3225,7 @@ static BOOL update_read_field_flags(wStream* s, UINT32* fieldFlags, BYTE flags, fieldBytes = 0; } - if (Stream_GetRemainingLength(s) < fieldBytes) + if (!Stream_CheckAndLogRequiredLength(TAG, s, fieldBytes)) return FALSE; *fieldFlags = 0; @@ -3286,7 +3274,7 @@ static BOOL update_read_bounds(wStream* s, rdpBounds* bounds) { BYTE flags; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, flags); /* field flags */ @@ -3527,11 +3515,8 @@ static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags) if (flags & ORDER_TYPE_CHANGE) { - if (Stream_GetRemainingLength(s) < 1) - { - WLog_Print(up->log, WLOG_ERROR, "Stream_GetRemainingLength(s) < 1"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, orderInfo->orderType); /* orderType (1 byte) */ } @@ -3787,7 +3772,7 @@ static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags) static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) { BOOL rc = FALSE; - size_t start, end, pos, diff, rem; + size_t start, end, pos, diff; BYTE orderType; UINT16 extraFlags; INT16 orderLength; @@ -3801,12 +3786,8 @@ static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flag defaultReturn = freerdp_settings_get_bool(settings, FreeRDP_DeactivateClientDecoding); - rem = Stream_GetRemainingLength(s); - if (rem < 5) - { - WLog_Print(up->log, WLOG_ERROR, "Stream_GetRemainingLength(s) < 5"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return FALSE; - } Stream_Read_INT16(s, orderLength); /* orderLength (2 bytes signed) */ Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ @@ -3824,19 +3805,20 @@ static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flag * According to [MS-RDPEGDI] 2.2.2.2.1.2.1.1 the order length must be increased by 13 bytes * including the header. As we already read the header 7 left */ - rem = Stream_GetRemainingLength(s); /* orderLength might be negative without the adjusted header data. * Account for that here so all further checks operate on the correct value. */ orderLengthFull = orderLength + 7; - if ((orderLengthFull < 0) || (rem < (size_t)orderLengthFull)) + if (orderLengthFull < 0) { - WLog_Print(up->log, WLOG_ERROR, "Stream_GetRemainingLength(s) %" PRIuz " < %" PRId32, rem, - orderLengthFull); + WLog_Print(up->log, WLOG_ERROR, "orderLength %" PRIu16 " must be >= 7", orderLength); return FALSE; } + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)orderLengthFull)) + return FALSE; + if (!check_secondary_order_supported(up->log, settings, orderType, name)) return FALSE; @@ -4156,11 +4138,8 @@ BOOL update_recv_order(rdpUpdate* update, wStream* s) BYTE controlFlags; rdp_update_internal* up = update_cast(update); - if (Stream_GetRemainingLength(s) < 1) - { - WLog_Print(up->log, WLOG_ERROR, "Stream_GetRemainingLength(s) < 1"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, controlFlags); /* controlFlags (1 byte) */ diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 3f73822d0..b847686e6 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -382,7 +382,7 @@ static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s, UINT16 totalLen return FALSE; case DATA_PDU_TYPE_FRAME_ACKNOWLEDGE: - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, client->ack_frame_id); @@ -434,7 +434,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) return -1; rdp->inPackets++; - if (freerdp_shall_disconnect(rdp->context->instance)) + if (freerdp_shall_disconnect_context(rdp->context)) return 0; if (settings->UseRdpSecurityLayer) @@ -445,10 +445,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) if (securityFlags & SEC_ENCRYPT) { if (!rdp_decrypt(rdp, s, &length, securityFlags)) - { - WLog_ERR(TAG, "rdp_decrypt failed"); return -1; - } } } @@ -479,11 +476,15 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) case PDU_TYPE_FLOW_STOP: case PDU_TYPE_FLOW_TEST: if (!Stream_SafeSeek(s, remain)) + { + WLog_WARN(TAG, "Short PDU, need %" PRIuz " bytes, got %" PRIuz, remain, + Stream_GetRemainingLength(s)); return -1; + } break; default: - WLog_ERR(TAG, "Client sent pduType %" PRIu16 "", pduType); + WLog_ERR(TAG, "Client sent unknown pduType %" PRIu16 "", pduType); return -1; } } @@ -511,7 +512,6 @@ static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s) rdpRdp* rdp; UINT16 length; BOOL rc; - size_t rem; rdpFastPath* fastpath; WINPR_ASSERT(s); @@ -526,12 +526,13 @@ static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s) rc = fastpath_read_header_rdp(fastpath, s, &length); - rem = Stream_GetRemainingLength(s); - if (!rc || (length == 0) || (length > rem)) + if (!rc || (length == 0)) { WLog_ERR(TAG, "incorrect FastPath PDU header length %" PRIu16 "", length); return -1; } + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) + return -1; if (fastpath_get_encryption_flags(fastpath) & FASTPATH_OUTPUT_ENCRYPTED) { @@ -1075,9 +1076,6 @@ BOOL freerdp_peer_context_new_ex(freerdp_peer* client, const rdpSettings* settin context->update = rdp->update; context->settings = rdp->settings; context->autodetect = rdp->autodetect; - context->update->context = context; - context->input->context = context; - context->autodetect->context = context; update_register_server_callbacks(rdp->update); autodetect_register_server_callbacks(rdp->autodetect); diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 0a3a7c450..bf81d7e06 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -21,6 +21,8 @@ #include #include +#include +#include #include "rdp.h" @@ -123,8 +125,16 @@ static BOOL rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UI BOOL rdp_read_security_header(wStream* s, UINT16* flags, UINT16* length) { + WINPR_ASSERT(s); + WINPR_ASSERT(flags); + /* Basic Security Header */ - if ((Stream_GetRemainingLength(s) < 4) || (length && (*length < 4))) + if ((length && (*length < 4))) + { + WLog_WARN(TAG, "invalid security header length, have %" PRIu16 ", must be >= 4", *length); + return FALSE; + } + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, *flags); /* flags */ @@ -143,18 +153,30 @@ BOOL rdp_read_security_header(wStream* s, UINT16* flags, UINT16* length) * @param flags security flags */ -void rdp_write_security_header(wStream* s, UINT16 flags) +BOOL rdp_write_security_header(wStream* s, UINT16 flags) { + WINPR_ASSERT(s); + + if (Stream_GetRemainingCapacity(s) < 4) + return FALSE; + /* Basic Security Header */ Stream_Write_UINT16(s, flags); /* flags */ Stream_Write_UINT16(s, 0); /* flagsHi (unused) */ + return TRUE; } BOOL rdp_read_share_control_header(wStream* s, UINT16* tpktLength, UINT16* remainingLength, UINT16* type, UINT16* channel_id) { UINT16 len; - if (Stream_GetRemainingLength(s) < 2) + UINT16 tmp; + + WINPR_ASSERT(s); + WINPR_ASSERT(type); + WINPR_ASSERT(channel_id); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; /* Share Control Header */ @@ -174,15 +196,19 @@ BOOL rdp_read_share_control_header(wStream* s, UINT16* tpktLength, UINT16* remai return TRUE; } - if ((len < 4U) || ((len - 2U) > Stream_GetRemainingLength(s))) + if (len < 4U) + { + WLog_ERR(TAG, "Invalid share control header, length is %" PRIu16 ", must be >4", len); return FALSE; + } + if (!Stream_CheckAndLogRequiredLength(TAG, s, len - 2)) + return FALSE; if (tpktLength) *tpktLength = len; - Stream_Read_UINT16(s, *type); /* pduType */ - *type &= 0x0F; /* type is in the 4 least significant bits */ - + Stream_Read_UINT16(s, tmp); /* pduType */ + *type = tmp & 0x0F; /* type is in the 4 least significant bits */ if (len > 5) { Stream_Read_UINT16(s, *channel_id); /* pduSource */ @@ -201,6 +227,8 @@ BOOL rdp_read_share_control_header(wStream* s, UINT16* tpktLength, UINT16* remai BOOL rdp_write_share_control_header(wStream* s, UINT16 length, UINT16 type, UINT16 channel_id) { + WINPR_ASSERT(s); + if (length < RDP_PACKET_HEADER_MAX_LENGTH) return FALSE; if (Stream_GetRemainingCapacity(s) < 6) @@ -216,7 +244,9 @@ BOOL rdp_write_share_control_header(wStream* s, UINT16 length, UINT16 type, UINT BOOL rdp_read_share_data_header(wStream* s, UINT16* length, BYTE* type, UINT32* shareId, BYTE* compressedType, UINT16* compressedLength) { - if (Stream_GetRemainingLength(s) < 12) + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return FALSE; /* Share Data Header */ @@ -234,6 +264,9 @@ BOOL rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UINT32 sh { const size_t headerLen = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SHARE_CONTROL_HEADER_LENGTH + RDP_SHARE_DATA_HEADER_LENGTH; + + WINPR_ASSERT(s); + if (length < headerLen) return FALSE; length -= headerLen; @@ -253,8 +286,8 @@ BOOL rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UINT32 sh static BOOL rdp_security_stream_init(rdpRdp* rdp, wStream* s, BOOL sec_header) { - if (!rdp || !s) - return FALSE; + WINPR_ASSERT(rdp); + WINPR_ASSERT(s); if (rdp->do_crypt) { @@ -339,11 +372,15 @@ fail: BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo) { + WINPR_ASSERT(rdp); + rdp->errorInfo = errorInfo; if (rdp->errorInfo != ERRINFO_SUCCESS) { rdpContext* context = rdp->context; + WINPR_ASSERT(context); + rdp_print_errinfo(rdp->errorInfo); if (context) @@ -362,7 +399,7 @@ BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo) WLog_ERR(TAG, "%s missing context=%p", __FUNCTION__, context); /* Ensure the connection is terminated */ - utils_abort_connect(context); + utils_abort_connect(rdp); } else { @@ -374,7 +411,11 @@ BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo) wStream* rdp_message_channel_pdu_init(rdpRdp* rdp) { - wStream* s = transport_send_stream_init(rdp->transport, 4096); + wStream* s; + + WINPR_ASSERT(rdp); + + s = transport_send_stream_init(rdp->transport, 4096); if (!s) return NULL; @@ -411,9 +452,7 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId) WINPR_ASSERT(rdp); WINPR_ASSERT(rdp->settings); - WINPR_ASSERT(rdp->context); WINPR_ASSERT(s); - MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication; @@ -428,7 +467,7 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId) { if (code == X224_TPDU_DISCONNECT_REQUEST) { - utils_abort_connect(rdp->context); + utils_abort_connect(rdp); return TRUE; } @@ -460,12 +499,8 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId) return FALSE; } - if ((*length - 8U) > Stream_GetRemainingLength(s)) - { - WLog_WARN(TAG, "TPDU invalid length, got %" PRIuz ", expected %" PRIu16, - Stream_GetRemainingLength(s), *length - 8); + if (!Stream_CheckAndLogRequiredLength(TAG, s, *length - 8)) return FALSE; - } if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum) { @@ -495,19 +530,15 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId) } WLog_DBG(TAG, "DisconnectProviderUltimatum: reason: %d", reason); - utils_abort_connect(context); + utils_abort_connect(rdp); EventArgsInit(&e, "freerdp"); e.code = 0; PubSub_OnTerminate(context->pubSub, context, &e); return TRUE; } - if (Stream_GetRemainingLength(s) < 5) - { - WLog_WARN(TAG, "TPDU packet short length, got %" PRIuz ", expected at least 5", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 5)) return FALSE; - } if (!per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID)) /* initiator (UserId) */ return FALSE; @@ -520,12 +551,8 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId) if (!per_read_length(s, length)) /* userData (OCTET_STRING) */ return FALSE; - if (*length > Stream_GetRemainingLength(s)) - { - WLog_WARN(TAG, "TPDU invalid length, got %" PRIuz ", expected %" PRIu16, - Stream_GetRemainingLength(s), *length); + if (!Stream_CheckAndLogRequiredLength(TAG, s, *length)) return FALSE; - } return TRUE; } @@ -542,6 +569,11 @@ void rdp_write_header(rdpRdp* rdp, wStream* s, UINT16 length, UINT16 channelId) { int body_length; DomainMCSPDU MCSPDU; + + WINPR_ASSERT(rdp); + WINPR_ASSERT(rdp->settings); + WINPR_ASSERT(s); + MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataIndication : DomainMCSPDU_SendDataRequest; @@ -823,7 +855,7 @@ static BOOL rdp_recv_server_set_keyboard_indicators_pdu(rdpRdp* rdp, wStream* s) WINPR_ASSERT(context); WINPR_ASSERT(context->update); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, unitId); /* unitId (2 bytes) */ @@ -840,7 +872,7 @@ static BOOL rdp_recv_server_set_keyboard_ime_status_pdu(rdpRdp* rdp, wStream* s) if (!rdp || !rdp->input) return FALSE; - if (Stream_GetRemainingLength(s) < 10) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 10)) return FALSE; Stream_Read_UINT16(s, unitId); /* unitId (2 bytes) */ @@ -854,7 +886,7 @@ static BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s) { UINT32 errorInfo; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, errorInfo); /* errorInfo (4 bytes) */ @@ -865,7 +897,7 @@ static BOOL rdp_recv_server_auto_reconnect_status_pdu(rdpRdp* rdp, wStream* s) { UINT32 arcStatus; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, arcStatus); /* arcStatus (4 bytes) */ @@ -877,7 +909,7 @@ static BOOL rdp_recv_server_status_info_pdu(rdpRdp* rdp, wStream* s) { UINT32 statusCode; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, statusCode); /* statusCode (4 bytes) */ @@ -896,12 +928,12 @@ static BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s) MONITOR_DEF* monitorDefArray; BOOL ret = TRUE; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, monitorCount); /* monitorCount (4 bytes) */ - if ((Stream_GetRemainingLength(s) / 20) < monitorCount) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20ull * monitorCount)) return FALSE; monitorDefArray = (MONITOR_DEF*)calloc(monitorCount, sizeof(MONITOR_DEF)); @@ -947,7 +979,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) const BYTE* pDstData = NULL; UINT16 SrcSize = compressedLength - 18; - if ((compressedLength < 18) || (Stream_GetRemainingLength(s) < SrcSize)) + if ((compressedLength < 18) || (!Stream_CheckAndLogRequiredLength(TAG, s, SrcSize))) { WLog_ERR(TAG, "bulk_decompress: not enough bytes for compressedLength %" PRIu16 "", compressedLength); @@ -1139,6 +1171,9 @@ out_fail: int rdp_recv_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 securityFlags) { + WINPR_ASSERT(rdp); + WINPR_ASSERT(s); + if (securityFlags & SEC_AUTODETECT_REQ) { /* Server Auto-Detect Request PDU */ @@ -1204,9 +1239,12 @@ BOOL rdp_read_flow_control_pdu(wStream* s, UINT16* type, UINT16* channel_id) * Switched the order of these two fields to match this observation. */ UINT8 pduType; - if (!type) - return FALSE; - if (Stream_GetRemainingLength(s) < 6) + + WINPR_ASSERT(s); + WINPR_ASSERT(type); + WINPR_ASSERT(channel_id); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; Stream_Read_UINT8(s, pduType); /* pduTypeFlow */ *type = pduType; @@ -1231,8 +1269,10 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, UINT16* pLength, UINT16 securityFlags) BOOL status; INT32 length; - if (!rdp || !s || !pLength) - return FALSE; + WINPR_ASSERT(rdp); + WINPR_ASSERT(rdp->settings); + WINPR_ASSERT(s); + WINPR_ASSERT(pLength); length = *pLength; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) @@ -1242,7 +1282,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, UINT16* pLength, UINT16 securityFlags) BYTE* sig; INT64 padLength; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return FALSE; Stream_Read_UINT16(s, len); /* 0x10 */ @@ -1254,7 +1294,10 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, UINT16* pLength, UINT16 securityFlags) padLength = length - pad; if ((length <= 0) || (padLength <= 0) || (padLength > UINT16_MAX)) + { + WLog_ERR(TAG, "FATAL: invalid pad length %" PRId32, padLength); return FALSE; + } if (!security_fips_decrypt(Stream_Pointer(s), length, rdp)) { @@ -1273,14 +1316,17 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, UINT16* pLength, UINT16 securityFlags) return TRUE; } - if (Stream_GetRemainingLength(s) < sizeof(wmac)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(wmac))) return FALSE; Stream_Read(s, wmac, sizeof(wmac)); length -= sizeof(wmac); if (length <= 0) + { + WLog_ERR(TAG, "FATAL: invalid length field"); return FALSE; + } if (!security_decrypt(Stream_Pointer(s), length, rdp)) return FALSE; @@ -1363,7 +1409,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) if (!rdp_read_header(rdp, s, &length, &channelId)) return -1; - if (freerdp_shall_disconnect(instance)) + if (freerdp_shall_disconnect_context(rdp->context)) return 0; if (rdp->autodetect->bandwidthMeasureStarted) @@ -1502,7 +1548,7 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s) return -1; } - if ((length == 0) || (length > Stream_GetRemainingLength(s))) + if ((length == 0) || (!Stream_CheckAndLogRequiredLength(TAG, s, length))) { WLog_ERR(TAG, "incorrect FastPath PDU header length %" PRIu16 "", length); return -1; @@ -1614,6 +1660,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) nla_free(rdp->nla); rdp->nla = NULL; + rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CONNECT); if (!mcs_client_begin(rdp->mcs)) { WLog_ERR(TAG, "%s: %s - mcs_client_begin() fail", __FUNCTION__, @@ -1925,6 +1972,9 @@ rdpRdp* rdp_new(rdpContext* context) if (!rdp->bulk) goto fail; + rdp->abortEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!rdp->abortEvent) + goto fail; return rdp; fail: @@ -2019,7 +2069,7 @@ BOOL rdp_reset(rdpRdp* rdp) goto fail; rdp->errorInfo = 0; - rdp->deactivation_reactivation = 0; + rdp->deactivation_reactivation = FALSE; rdp->finalize_sc_pdus = 0; rc = TRUE; @@ -2051,6 +2101,8 @@ void rdp_free(rdpRdp* rdp) multitransport_free(rdp->multitransport); bulk_free(rdp->bulk); free(rdp->io); + if (rdp->abortEvent) + CloseHandle(rdp->abortEvent); free(rdp); } } diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index 1083828ce..0f195e9a2 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -96,31 +96,34 @@ #define FINALIZE_SC_COMPLETE 0x0F /* Data PDU Types */ -#define DATA_PDU_TYPE_UPDATE 0x02 -#define DATA_PDU_TYPE_CONTROL 0x14 -#define DATA_PDU_TYPE_POINTER 0x1B -#define DATA_PDU_TYPE_INPUT 0x1C -#define DATA_PDU_TYPE_SYNCHRONIZE 0x1F -#define DATA_PDU_TYPE_REFRESH_RECT 0x21 -#define DATA_PDU_TYPE_PLAY_SOUND 0x22 -#define DATA_PDU_TYPE_SUPPRESS_OUTPUT 0x23 -#define DATA_PDU_TYPE_SHUTDOWN_REQUEST 0x24 -#define DATA_PDU_TYPE_SHUTDOWN_DENIED 0x25 -#define DATA_PDU_TYPE_SAVE_SESSION_INFO 0x26 -#define DATA_PDU_TYPE_FONT_LIST 0x27 -#define DATA_PDU_TYPE_FONT_MAP 0x28 -#define DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS 0x29 -#define DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST 0x2B -#define DATA_PDU_TYPE_BITMAP_CACHE_ERROR 0x2C -#define DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS 0x2D -#define DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR 0x2E -#define DATA_PDU_TYPE_SET_ERROR_INFO 0x2F -#define DATA_PDU_TYPE_DRAW_NINEGRID_ERROR 0x30 -#define DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR 0x31 -#define DATA_PDU_TYPE_ARC_STATUS 0x32 -#define DATA_PDU_TYPE_STATUS_INFO 0x36 -#define DATA_PDU_TYPE_MONITOR_LAYOUT 0x37 -#define DATA_PDU_TYPE_FRAME_ACKNOWLEDGE 0x38 +typedef enum +{ + DATA_PDU_TYPE_UPDATE = 0x02, + DATA_PDU_TYPE_CONTROL = 0x14, + DATA_PDU_TYPE_POINTER = 0x1B, + DATA_PDU_TYPE_INPUT = 0x1C, + DATA_PDU_TYPE_SYNCHRONIZE = 0x1F, + DATA_PDU_TYPE_REFRESH_RECT = 0x21, + DATA_PDU_TYPE_PLAY_SOUND = 0x22, + DATA_PDU_TYPE_SUPPRESS_OUTPUT = 0x23, + DATA_PDU_TYPE_SHUTDOWN_REQUEST = 0x24, + DATA_PDU_TYPE_SHUTDOWN_DENIED = 0x25, + DATA_PDU_TYPE_SAVE_SESSION_INFO = 0x26, + DATA_PDU_TYPE_FONT_LIST = 0x27, + DATA_PDU_TYPE_FONT_MAP = 0x28, + DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS = 0x29, + DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST = 0x2B, + DATA_PDU_TYPE_BITMAP_CACHE_ERROR = 0x2C, + DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS = 0x2D, + DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR = 0x2E, + DATA_PDU_TYPE_SET_ERROR_INFO = 0x2F, + DATA_PDU_TYPE_DRAW_NINEGRID_ERROR = 0x30, + DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR = 0x31, + DATA_PDU_TYPE_ARC_STATUS = 0x32, + DATA_PDU_TYPE_STATUS_INFO = 0x36, + DATA_PDU_TYPE_MONITOR_LAYOUT = 0x37, + DATA_PDU_TYPE_FRAME_ACKNOWLEDGE = 0x38 +} rdpPduType; /* Stream Identifiers */ #define STREAM_UNDEFINED 0x00 @@ -179,10 +182,11 @@ struct rdp_rdp CRITICAL_SECTION critical; rdpTransportIo* io; void* ioContext; + HANDLE abortEvent; }; FREERDP_LOCAL BOOL rdp_read_security_header(wStream* s, UINT16* flags, UINT16* length); -FREERDP_LOCAL void rdp_write_security_header(wStream* s, UINT16 flags); +FREERDP_LOCAL BOOL rdp_write_security_header(wStream* s, UINT16 flags); FREERDP_LOCAL BOOL rdp_read_share_control_header(wStream* s, UINT16* tpktLength, UINT16* remainingLength, UINT16* type, diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c index a449d6c45..2a39ac23b 100644 --- a/libfreerdp/core/redirection.c +++ b/libfreerdp/core/redirection.c @@ -98,11 +98,8 @@ static BOOL rdp_redirection_read_unicode_string(wStream* s, char** str, size_t m UINT32 length; WCHAR* wstr = NULL; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "rdp_redirection_read_string failure: cannot read length"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Read_UINT32(s, length); @@ -114,7 +111,7 @@ static BOOL rdp_redirection_read_unicode_string(wStream* s, char** str, size_t m return FALSE; } - if (Stream_GetRemainingLength(s) < length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) { WLog_ERR(TAG, "rdp_redirection_read_string failure: insufficient stream length (%" PRIu32 @@ -233,7 +230,7 @@ static BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) UINT16 length; rdpRedirection* redirection = rdp->redirection; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return -1; Stream_Read_UINT16(s, flags); /* flags (2 bytes) */ @@ -272,12 +269,12 @@ static BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) * 0010 34 30 32 36 34 33 32 2e 31 35 36 32 39 2e 30 30 4026432.15629.00 * 0020 30 30 0d 0a 00.. */ - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return -1; Stream_Read_UINT32(s, redirection->LoadBalanceInfoLength); - if (Stream_GetRemainingLength(s) < redirection->LoadBalanceInfoLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, redirection->LoadBalanceInfoLength)) return -1; redirection->LoadBalanceInfo = (BYTE*)malloc(redirection->LoadBalanceInfoLength); @@ -330,7 +327,7 @@ static BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) * Notwithstanding the above, we'll allocated an additional zero WCHAR at the * end of the buffer which won't get counted in PasswordLength. */ - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return -1; Stream_Read_UINT32(s, redirection->PasswordLength); @@ -340,7 +337,7 @@ static BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) * password cookie format (see previous comment). */ - if (Stream_GetRemainingLength(s) < redirection->PasswordLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, redirection->PasswordLength)) return -1; if (redirection->PasswordLength > LB_PASSWORD_MAX_LENGTH) @@ -376,12 +373,12 @@ static BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) if (redirection->flags & LB_CLIENT_TSV_URL) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return -1; Stream_Read_UINT32(s, redirection->TsvUrlLength); - if (Stream_GetRemainingLength(s) < redirection->TsvUrlLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, redirection->TsvUrlLength)) return -1; redirection->TsvUrl = (BYTE*)malloc(redirection->TsvUrlLength); @@ -400,7 +397,7 @@ static BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) UINT32 count; UINT32 targetNetAddressesLength; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return -1; Stream_Read_UINT32(s, targetNetAddressesLength); diff --git a/libfreerdp/core/security.c b/libfreerdp/core/security.c index c83f038a2..54a70ecbb 100644 --- a/libfreerdp/core/security.c +++ b/libfreerdp/core/security.c @@ -331,6 +331,11 @@ BOOL security_mac_signature(rdpRdp* rdp, const BYTE* data, UINT32 length, BYTE* BYTE md5_digest[WINPR_MD5_DIGEST_LENGTH]; BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH]; BOOL result = FALSE; + + WINPR_ASSERT(rdp); + WINPR_ASSERT(data || (length == 0)); + WINPR_ASSERT(output); + security_UINT32_le(length_le, length); /* length must be little-endian */ /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ @@ -377,6 +382,8 @@ BOOL security_mac_signature(rdpRdp* rdp, const BYTE* data, UINT32 length, BYTE* memcpy(output, md5_digest, 8); result = TRUE; out: + if (!result) + WLog_WARN(TAG, "security mac generation failed"); winpr_Digest_Free(sha1); winpr_Digest_Free(md5); return result; @@ -393,6 +400,10 @@ BOOL security_salted_mac_signature(rdpRdp* rdp, const BYTE* data, UINT32 length, BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH]; BOOL result = FALSE; + WINPR_ASSERT(rdp); + WINPR_ASSERT(data || (length == 0)); + WINPR_ASSERT(output); + EnterCriticalSection(&rdp->critical); security_UINT32_le(length_le, length); /* length must be little-endian */ @@ -456,6 +467,8 @@ BOOL security_salted_mac_signature(rdpRdp* rdp, const BYTE* data, UINT32 length, memcpy(output, md5_digest, 8); result = TRUE; out: + if (!result) + WLog_WARN(TAG, "security mac signature generation failed"); LeaveCriticalSection(&rdp->critical); winpr_Digest_Free(sha1); winpr_Digest_Free(md5); @@ -745,6 +758,10 @@ fail: BOOL security_decrypt(BYTE* data, size_t length, rdpRdp* rdp) { BOOL rc = FALSE; + + WINPR_ASSERT(data || (length == 0)); + WINPR_ASSERT(rdp); + EnterCriticalSection(&rdp->critical); if (rdp->rc4_decrypt_key == NULL) goto fail; @@ -770,6 +787,8 @@ BOOL security_decrypt(BYTE* data, size_t length, rdpRdp* rdp) rdp->decrypt_checksum_use_count++; rc = TRUE; fail: + if (!rc) + WLog_WARN(TAG, "Failed to decrypt security"); LeaveCriticalSection(&rdp->critical); return rc; } diff --git a/libfreerdp/core/server.c b/libfreerdp/core/server.c index 74f087bac..fd23885d8 100644 --- a/libfreerdp/core/server.c +++ b/libfreerdp/core/server.c @@ -126,21 +126,21 @@ static int wts_read_variable_uint(wStream* s, int cbLen, UINT32* val) switch (cbLen) { case 0: - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return 0; Stream_Read_UINT8(s, *val); return 1; case 1: - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return 0; Stream_Read_UINT16(s, *val); return 2; case 2: - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return 0; Stream_Read_UINT32(s, *val); diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 1a08e75c2..149723beb 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -418,6 +418,9 @@ rdpSettings* freerdp_settings_new(DWORD flags) if (!settings_get_computer_name(settings)) goto out_fail; + if (!freerdp_settings_set_pointer_len(settings, FreeRDP_RdpServerCertificate, NULL, 1)) + goto out_fail; + settings->ReceivedCapabilities = calloc(1, 32); if (!settings->ReceivedCapabilities) @@ -574,13 +577,13 @@ rdpSettings* freerdp_settings_new(DWORD flags) { ARC_CS_PRIVATE_PACKET cookie = { 0 }; if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ClientAutoReconnectCookie, &cookie, - sizeof(cookie))) + 1)) goto out_fail; } { ARC_SC_PRIVATE_PACKET cookie = { 0 }; if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ServerAutoReconnectCookie, &cookie, - sizeof(cookie))) + 1)) goto out_fail; } @@ -834,13 +837,11 @@ static BOOL freerdp_settings_int_buffer_copy(rdpSettings* _settings, const rdpSe if (!freerdp_settings_set_pointer_len( _settings, FreeRDP_ClientAutoReconnectCookie, - freerdp_settings_get_pointer(settings, FreeRDP_ClientAutoReconnectCookie), - sizeof(ARC_CS_PRIVATE_PACKET))) + freerdp_settings_get_pointer(settings, FreeRDP_ClientAutoReconnectCookie), 1)) goto out_fail; if (!freerdp_settings_set_pointer_len( _settings, FreeRDP_ServerAutoReconnectCookie, - freerdp_settings_get_pointer(settings, FreeRDP_ServerAutoReconnectCookie), - sizeof(ARC_SC_PRIVATE_PACKET))) + freerdp_settings_get_pointer(settings, FreeRDP_ServerAutoReconnectCookie), 1)) goto out_fail; _settings->ClientTimeZone = (LPTIME_ZONE_INFORMATION)malloc(sizeof(TIME_ZONE_INFORMATION)); diff --git a/libfreerdp/core/surface.c b/libfreerdp/core/surface.c index dffa7d526..b17f80110 100644 --- a/libfreerdp/core/surface.c +++ b/libfreerdp/core/surface.c @@ -34,12 +34,8 @@ static BOOL update_recv_surfcmd_bitmap_header_ex(wStream* s, TS_COMPRESSED_BITMA if (!s || !header) return FALSE; - if (Stream_GetRemainingLength(s) < 24) - { - WLog_ERR(TAG, "got %" PRIuz ", expected %" PRIuz " bytes", Stream_GetRemainingLength(s), - 24); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 24)) return FALSE; - } Stream_Read_UINT32(s, header->highUniqueId); Stream_Read_UINT32(s, header->lowUniqueId); @@ -53,12 +49,8 @@ static BOOL update_recv_surfcmd_bitmap_ex(wStream* s, TS_BITMAP_DATA_EX* bmp) if (!s || !bmp) return FALSE; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_ERR(TAG, "got %" PRIuz ", expected %" PRIuz " bytes", Stream_GetRemainingLength(s), - 12); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return FALSE; - } Stream_Read_UINT8(s, bmp->bpp); Stream_Read_UINT8(s, bmp->flags); @@ -135,11 +127,8 @@ static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT BOOL rc = FALSE; SURFACE_BITS_COMMAND cmd = { 0 }; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "got %" PRIuz ", expected %" PRIuz " bytes", Stream_GetRemainingLength(s), 8); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) goto fail; - } cmd.cmdType = cmdType; Stream_Read_UINT16(s, cmd.destLeft); @@ -171,14 +160,11 @@ static BOOL update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s) WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "got %" PRIuz ", expected %" PRIuz " bytes", Stream_GetRemainingLength(s), 6); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } Stream_Read_UINT16(s, marker.frameAction); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) WLog_WARN(TAG, "[SERVER-BUG]: got %" PRIuz ", expected %" PRIuz " bytes. [MS-RDPBCGR] 2.2.9.2.3 Frame Marker Command (TS_FRAME_MARKER) is " diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index 011a8efae..2f36b251b 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -29,6 +29,7 @@ #include #include "rdp.h" +#include "utils.h" #if !defined(_WIN32) @@ -817,7 +818,7 @@ static BOOL freerdp_tcp_connect_timeout(rdpContext* context, int sockfd, struct goto fail; } - handles[count++] = context->abortEvent; + handles[count++] = utils_get_abort_event(context->rdp); status = _connect(sockfd, addr, addrlen); if (status < 0) @@ -1232,7 +1233,7 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons } } - if (WaitForSingleObject(context->abortEvent, 0) == WAIT_OBJECT_0) + if (WaitForSingleObject(utils_get_abort_event(context->rdp), 0) == WAIT_OBJECT_0) { close(sockfd); return -1; diff --git a/libfreerdp/core/test/TestConnect.c b/libfreerdp/core/test/TestConnect.c index cb75bf7c0..aa6c3e95b 100644 --- a/libfreerdp/core/test/TestConnect.c +++ b/libfreerdp/core/test/TestConnect.c @@ -132,10 +132,9 @@ static int testAbort(int port) WaitForSingleObject(s_sync, INFINITE); Sleep(100); /* Wait until freerdp_connect has been called */ - freerdp_abort_connect(instance); - status = WaitForSingleObject(instance->context->abortEvent, 0); + freerdp_abort_connect_context(instance->context); - if (status != WAIT_OBJECT_0) + if (!freerdp_shall_disconnect_context(instance->context)) { CloseHandle(s_sync); CloseHandle(thread); diff --git a/libfreerdp/core/test/settings_property_lists.h b/libfreerdp/core/test/settings_property_lists.h index 1b768538c..aedfc2cc2 100644 --- a/libfreerdp/core/test/settings_property_lists.h +++ b/libfreerdp/core/test/settings_property_lists.h @@ -197,6 +197,7 @@ static const size_t uint32_list_indices[] = { FreeRDP_ChannelDefArraySize, FreeRDP_ClientBuild, FreeRDP_ClientRandomLength, + FreeRDP_ClientSessionId, FreeRDP_ClusterInfoFlags, FreeRDP_ColorDepth, FreeRDP_CompDeskSupportLevel, @@ -241,8 +242,10 @@ static const size_t uint32_list_indices[] = { FreeRDP_LargePointerFlag, FreeRDP_LoadBalanceInfoLength, FreeRDP_MaxTimeInCheckLoop, + FreeRDP_MonitorAttributeFlags, FreeRDP_MonitorCount, FreeRDP_MonitorDefArraySize, + FreeRDP_MonitorFlags, FreeRDP_MonitorLocalShiftX, FreeRDP_MonitorLocalShiftY, FreeRDP_MultifragMaxRequestSize, diff --git a/libfreerdp/core/timezone.c b/libfreerdp/core/timezone.c index 57dd0dab6..6e796cf46 100644 --- a/libfreerdp/core/timezone.c +++ b/libfreerdp/core/timezone.c @@ -24,6 +24,9 @@ #include "timezone.h" +#include +#define TAG FREERDP_TAG("core.timezone") + static void rdp_read_system_time(wStream* s, SYSTEMTIME* system_time); static void rdp_write_system_time(wStream* s, SYSTEMTIME* system_time); @@ -84,7 +87,7 @@ BOOL rdp_read_client_time_zone(wStream* s, rdpSettings* settings) if (!s || !settings) return FALSE; - if (Stream_GetRemainingLength(s) < 172) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 172)) return FALSE; tz = settings->ClientTimeZone; diff --git a/libfreerdp/core/tpdu.c b/libfreerdp/core/tpdu.c index 7bc3518ff..d29ac8456 100644 --- a/libfreerdp/core/tpdu.c +++ b/libfreerdp/core/tpdu.c @@ -74,12 +74,8 @@ static void tpdu_write_header(wStream* s, UINT16 length, BYTE code); BOOL tpdu_read_header(wStream* s, BYTE* code, BYTE* li, UINT16 tpktlength) { - if (Stream_GetRemainingLength(s) < 3) - { - WLog_WARN(TAG, "tpdu invalid data, got %" PRIuz ", require at least 3 more", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3)) return FALSE; - } Stream_Read_UINT8(s, *li); /* LI */ Stream_Read_UINT8(s, *code); /* Code */ @@ -100,7 +96,12 @@ BOOL tpdu_read_header(wStream* s, BYTE* code, BYTE* li, UINT16 tpktlength) /* DST-REF (2 bytes) */ /* SRC-REF (2 bytes) */ /* Class 0 (1 byte) */ - return Stream_SafeSeek(s, 5); + if (!Stream_SafeSeek(s, 5)) + { + WLog_WARN(TAG, "tpdu invalid data, got %" PRIuz ", require at least 5 more", + Stream_GetRemainingLength(s)); + return FALSE; + } } return TRUE; @@ -195,7 +196,9 @@ BOOL tpdu_read_connection_confirm(wStream* s, BYTE* li, UINT16 tpktlength) */ bytes_read = (Stream_GetPosition(s) - position) - 1; - return (Stream_GetRemainingLength(s) >= (size_t)(*li - bytes_read)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(*li - bytes_read))) + return FALSE; + return TRUE; } /** diff --git a/libfreerdp/core/tpdu.h b/libfreerdp/core/tpdu.h index ea629e758..daccbeff9 100644 --- a/libfreerdp/core/tpdu.h +++ b/libfreerdp/core/tpdu.h @@ -23,6 +23,8 @@ #include #include +#include "tpkt.h" + enum X224_TPDU_TYPE { X224_TPDU_CONNECTION_REQUEST = 0xE0, diff --git a/libfreerdp/core/tpkt.c b/libfreerdp/core/tpkt.c index 409791239..e36c7f330 100644 --- a/libfreerdp/core/tpkt.c +++ b/libfreerdp/core/tpkt.c @@ -69,6 +69,8 @@ BOOL tpkt_verify_header(wStream* s) { BYTE version; + WINPR_ASSERT(s); + Stream_Peek_UINT8(s, version); if (version == 3) @@ -88,25 +90,16 @@ BOOL tpkt_read_header(wStream* s, UINT16* length) { BYTE version; - if (Stream_GetRemainingLength(s) < 1) - { - WLog_WARN(TAG, "tpkt invalid data, got %" PRIuz ", require at least 1 more", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Peek_UINT8(s, version); if (version == 3) { - size_t slen; UINT16 len; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "tpkt invalid data, got %" PRIuz ", require at least 4 more", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Seek(s, 2); Stream_Read_UINT16_BE(s, len); @@ -118,10 +111,9 @@ BOOL tpkt_read_header(wStream* s, UINT16* length) return FALSE; } - slen = Stream_GetRemainingLength(s) + 4; - if (len > slen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, len - 4)) { - WLog_ERR(TAG, "TPKT header length %" PRIu16 ", but only received %" PRIdz, len, slen); + WLog_ERR(TAG, "TPKT header length %" PRIu16 ", but received less", len); return FALSE; } *length = len; diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 56c284f13..4d6467bd8 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -589,7 +589,7 @@ static SSIZE_T transport_read_layer(rdpTransport* transport, BYTE* data, size_t int r = (int)((tr > INT_MAX) ? INT_MAX : tr); int status = BIO_read(transport->frontBio, data + read, r); - if (freerdp_shall_disconnect(context->instance)) + if (freerdp_shall_disconnect_context(context)) return -1; if (status <= 0) @@ -1122,7 +1122,7 @@ int transport_check_fds(rdpTransport* transport) while (now < dueDate) { WINPR_ASSERT(context); - if (freerdp_shall_disconnect(context->instance)) + if (freerdp_shall_disconnect_context(context)) { return -1; } diff --git a/libfreerdp/core/tscredentials.c b/libfreerdp/core/tscredentials.c index c871c72b2..de1ccebd6 100644 --- a/libfreerdp/core/tscredentials.c +++ b/libfreerdp/core/tscredentials.c @@ -1,9 +1,10 @@ /* ============================================================================================================ * this file has been generated using - * tools/asn_parser_generator.py --input=libfreerdp/core/credssp.asn1 --output-kind=impls --output=libfreerdp/core/tscredentials.c + * tools/asn_parser_generator.py --input=libfreerdp/core/credssp.asn1 --output-kind=impls + * --output=libfreerdp/core/tscredentials.c * - * /!\ If you want to modify this file you'd probably better change asn_parser_generator.py or the corresponding ASN1 - * definition file + * /!\ If you want to modify this file you'd probably better change asn_parser_generator.py or the + * corresponding ASN1 definition file * * ============================================================================================================ */ @@ -13,7 +14,12 @@ #include "tscredentials.h" -size_t ber_sizeof_nla_TSCredentials_content(const TSCredentials_t* item) { +#include + +#define TAG FREERDP_TAG("core.tscredentials") + +size_t ber_sizeof_nla_TSCredentials_content(const TSCredentials_t* item) +{ size_t ret = 0; /* [0] credType (INTEGER)*/ @@ -25,17 +31,19 @@ size_t ber_sizeof_nla_TSCredentials_content(const TSCredentials_t* item) { return ret; } -size_t ber_sizeof_nla_TSCredentials(const TSCredentials_t* item) +size_t ber_sizeof_nla_TSCredentials(const TSCredentials_t* item) { - size_t ret = ber_sizeof_nla_TSCredentials_content(item); - return ber_sizeof_sequence(ret); + size_t ret = ber_sizeof_nla_TSCredentials_content(item); + return ber_sizeof_sequence(ret); } -size_t ber_sizeof_contextual_nla_TSCredentials(const TSCredentials_t* item) { +size_t ber_sizeof_contextual_nla_TSCredentials(const TSCredentials_t* item) +{ size_t innerSz = ber_sizeof_nla_TSCredentials(item); return ber_sizeof_contextual_tag(innerSz) + innerSz; } -void nla_TSCredentials_free(TSCredentials_t** pitem) { +void nla_TSCredentials_free(TSCredentials_t** pitem) +{ TSCredentials_t* item; WINPR_ASSERT(pitem); @@ -48,82 +56,85 @@ void nla_TSCredentials_free(TSCredentials_t** pitem) { *pitem = NULL; } -size_t ber_write_nla_TSCredentials(wStream *s, const TSCredentials_t* item) +size_t ber_write_nla_TSCredentials(wStream* s, const TSCredentials_t* item) { - size_t content_size = ber_sizeof_nla_TSCredentials_content(item); - size_t ret = 0; - - ret = ber_write_sequence_tag(s, content_size); - /* [0] credType (INTEGER) */ - if (!ber_write_contextual_integer(s, 0, item->credType)) - return 0; + size_t content_size = ber_sizeof_nla_TSCredentials_content(item); + size_t ret = 0; - /* [1] credentials (OCTET STRING) */ - if (!ber_write_contextual_octet_string(s, 1, item->credentials, item->credentialsLen)) - return 0; + ret = ber_write_sequence_tag(s, content_size); + /* [0] credType (INTEGER) */ + if (!ber_write_contextual_integer(s, 0, item->credType)) + return 0; - return ret + content_size; + /* [1] credentials (OCTET STRING) */ + if (!ber_write_contextual_octet_string(s, 1, item->credentials, item->credentialsLen)) + return 0; + + return ret + content_size; } -size_t ber_write_contextual_nla_TSCredentials(wStream *s, BYTE tag, const TSCredentials_t* item) +size_t ber_write_contextual_nla_TSCredentials(wStream* s, BYTE tag, const TSCredentials_t* item) { - size_t ret; - size_t inner = ber_sizeof_nla_TSCredentials(item); - - ret = ber_write_contextual_tag(s, tag, inner, TRUE); - ber_write_nla_TSCredentials(s, item); - return ret + inner; + size_t ret; + size_t inner = ber_sizeof_nla_TSCredentials(item); + + ret = ber_write_contextual_tag(s, tag, inner, TRUE); + ber_write_nla_TSCredentials(s, item); + return ret + inner; } -BOOL ber_read_nla_TSCredentials(wStream *s, TSCredentials_t** pret) { - wStream seqstream; - size_t seqLength; - size_t inner_size; - wStream fieldStream; - TSCredentials_t* item; - BOOL ret; +BOOL ber_read_nla_TSCredentials(wStream* s, TSCredentials_t** pret) +{ + wStream seqstream; + size_t seqLength; + size_t inner_size; + wStream fieldStream; + TSCredentials_t* item; + BOOL ret; - if (!ber_read_sequence_tag(s, &seqLength) || Stream_GetRemainingLength(s) < seqLength) - return FALSE; - Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - - item = calloc(1, sizeof(*item)); - if (!item) - return FALSE; - - /* [0] credType (INTEGER) */ - ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); - if (!ret) - goto out_fail_credType; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + if (!ber_read_sequence_tag(s, &seqLength) || + !Stream_CheckAndLogRequiredLength(TAG, s, seqLength)) + return FALSE; + Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - ret = ber_read_integer(&fieldStream, &item->credType); - if (!ret) - goto out_fail_credType; + item = calloc(1, sizeof(*item)); + if (!item) + return FALSE; - /* [1] credentials (OCTET STRING) */ - ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); - if (!ret) - goto out_fail_credentials; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + /* [0] credType (INTEGER) */ + ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); + if (!ret) + goto out_fail_credType; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_octet_string(&fieldStream, &item->credentials, &item->credentialsLen); - if (!ret) - goto out_fail_credentials; + ret = ber_read_integer(&fieldStream, &item->credType); + if (!ret) + goto out_fail_credType; - *pret = item; - return TRUE; + /* [1] credentials (OCTET STRING) */ + ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); + if (!ret) + goto out_fail_credentials; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); + + ret = ber_read_octet_string(&fieldStream, &item->credentials, &item->credentialsLen); + if (!ret) + goto out_fail_credentials; + + *pret = item; + return TRUE; out_fail_credentials: - + out_fail_credType: - free(item); - return FALSE; + free(item); + return FALSE; } -size_t ber_sizeof_nla_TSPasswordCreds_content(const TSPasswordCreds_t* item) { +size_t ber_sizeof_nla_TSPasswordCreds_content(const TSPasswordCreds_t* item) +{ size_t ret = 0; /* [0] domainName (OCTET STRING)*/ @@ -138,17 +149,19 @@ size_t ber_sizeof_nla_TSPasswordCreds_content(const TSPasswordCreds_t* item) { return ret; } -size_t ber_sizeof_nla_TSPasswordCreds(const TSPasswordCreds_t* item) +size_t ber_sizeof_nla_TSPasswordCreds(const TSPasswordCreds_t* item) { - size_t ret = ber_sizeof_nla_TSPasswordCreds_content(item); - return ber_sizeof_sequence(ret); + size_t ret = ber_sizeof_nla_TSPasswordCreds_content(item); + return ber_sizeof_sequence(ret); } -size_t ber_sizeof_contextual_nla_TSPasswordCreds(const TSPasswordCreds_t* item) { +size_t ber_sizeof_contextual_nla_TSPasswordCreds(const TSPasswordCreds_t* item) +{ size_t innerSz = ber_sizeof_nla_TSPasswordCreds(item); return ber_sizeof_contextual_tag(innerSz) + innerSz; } -void nla_TSPasswordCreds_free(TSPasswordCreds_t** pitem) { +void nla_TSPasswordCreds_free(TSPasswordCreds_t** pitem) +{ TSPasswordCreds_t* item; WINPR_ASSERT(pitem); @@ -163,138 +176,147 @@ void nla_TSPasswordCreds_free(TSPasswordCreds_t** pitem) { *pitem = NULL; } -size_t ber_write_nla_TSPasswordCreds(wStream *s, const TSPasswordCreds_t* item) +size_t ber_write_nla_TSPasswordCreds(wStream* s, const TSPasswordCreds_t* item) { - size_t content_size = ber_sizeof_nla_TSPasswordCreds_content(item); - size_t ret = 0; - - ret = ber_write_sequence_tag(s, content_size); - /* [0] domainName (OCTET STRING) */ - if (!ber_write_contextual_octet_string(s, 0, item->domainName, item->domainNameLen)) - return 0; + size_t content_size = ber_sizeof_nla_TSPasswordCreds_content(item); + size_t ret = 0; - /* [1] userName (OCTET STRING) */ - if (!ber_write_contextual_octet_string(s, 1, item->userName, item->userNameLen)) - return 0; + ret = ber_write_sequence_tag(s, content_size); + /* [0] domainName (OCTET STRING) */ + if (!ber_write_contextual_octet_string(s, 0, item->domainName, item->domainNameLen)) + return 0; - /* [2] password (OCTET STRING) */ - if (!ber_write_contextual_octet_string(s, 2, item->password, item->passwordLen)) - return 0; + /* [1] userName (OCTET STRING) */ + if (!ber_write_contextual_octet_string(s, 1, item->userName, item->userNameLen)) + return 0; - return ret + content_size; + /* [2] password (OCTET STRING) */ + if (!ber_write_contextual_octet_string(s, 2, item->password, item->passwordLen)) + return 0; + + return ret + content_size; } -size_t ber_write_contextual_nla_TSPasswordCreds(wStream *s, BYTE tag, const TSPasswordCreds_t* item) +size_t ber_write_contextual_nla_TSPasswordCreds(wStream* s, BYTE tag, const TSPasswordCreds_t* item) { - size_t ret; - size_t inner = ber_sizeof_nla_TSPasswordCreds(item); - - ret = ber_write_contextual_tag(s, tag, inner, TRUE); - ber_write_nla_TSPasswordCreds(s, item); - return ret + inner; + size_t ret; + size_t inner = ber_sizeof_nla_TSPasswordCreds(item); + + ret = ber_write_contextual_tag(s, tag, inner, TRUE); + ber_write_nla_TSPasswordCreds(s, item); + return ret + inner; } -BOOL ber_read_nla_TSPasswordCreds(wStream *s, TSPasswordCreds_t** pret) { - wStream seqstream; - size_t seqLength; - size_t inner_size; - wStream fieldStream; - TSPasswordCreds_t* item; - BOOL ret; +BOOL ber_read_nla_TSPasswordCreds(wStream* s, TSPasswordCreds_t** pret) +{ + wStream seqstream; + size_t seqLength; + size_t inner_size; + wStream fieldStream; + TSPasswordCreds_t* item; + BOOL ret; - if (!ber_read_sequence_tag(s, &seqLength) || Stream_GetRemainingLength(s) < seqLength) - return FALSE; - Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - - item = calloc(1, sizeof(*item)); - if (!item) - return FALSE; - - /* [0] domainName (OCTET STRING) */ - ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); - if (!ret) - goto out_fail_domainName; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + if (!ber_read_sequence_tag(s, &seqLength) || + !Stream_CheckAndLogRequiredLength(TAG, s, seqLength)) + return FALSE; + Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - ret = ber_read_octet_string(&fieldStream, &item->domainName, &item->domainNameLen); - if (!ret) - goto out_fail_domainName; + item = calloc(1, sizeof(*item)); + if (!item) + return FALSE; - /* [1] userName (OCTET STRING) */ - ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); - if (!ret) - goto out_fail_userName; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + /* [0] domainName (OCTET STRING) */ + ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); + if (!ret) + goto out_fail_domainName; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_octet_string(&fieldStream, &item->userName, &item->userNameLen); - if (!ret) - goto out_fail_userName; + ret = ber_read_octet_string(&fieldStream, &item->domainName, &item->domainNameLen); + if (!ret) + goto out_fail_domainName; - /* [2] password (OCTET STRING) */ - ret = ber_read_contextual_tag(&seqstream, 2, &inner_size, TRUE); - if (!ret) - goto out_fail_password; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + /* [1] userName (OCTET STRING) */ + ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); + if (!ret) + goto out_fail_userName; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_octet_string(&fieldStream, &item->password, &item->passwordLen); - if (!ret) - goto out_fail_password; + ret = ber_read_octet_string(&fieldStream, &item->userName, &item->userNameLen); + if (!ret) + goto out_fail_userName; - *pret = item; - return TRUE; + /* [2] password (OCTET STRING) */ + ret = ber_read_contextual_tag(&seqstream, 2, &inner_size, TRUE); + if (!ret) + goto out_fail_password; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); + + ret = ber_read_octet_string(&fieldStream, &item->password, &item->passwordLen); + if (!ret) + goto out_fail_password; + + *pret = item; + return TRUE; out_fail_password: free(item->userName); out_fail_userName: free(item->domainName); out_fail_domainName: - free(item); - return FALSE; + free(item); + return FALSE; } -size_t ber_sizeof_nla_TSCspDataDetail_content(const TSCspDataDetail_t* item) { +size_t ber_sizeof_nla_TSCspDataDetail_content(const TSCspDataDetail_t* item) +{ size_t ret = 0; /* [0] keySpec (INTEGER)*/ ret += ber_sizeof_contextual_integer(item->keySpec); /* [1] cardName (OCTET STRING) OPTIONAL*/ - if (item->cardName) { + if (item->cardName) + { ret += ber_sizeof_contextual_octet_string(strlen(item->cardName) * 2); } /* [2] readerName (OCTET STRING) OPTIONAL*/ - if (item->readerName) { + if (item->readerName) + { ret += ber_sizeof_contextual_octet_string(strlen(item->readerName) * 2); } /* [3] containerName (OCTET STRING) OPTIONAL*/ - if (item->containerName) { + if (item->containerName) + { ret += ber_sizeof_contextual_octet_string(strlen(item->containerName) * 2); } /* [4] cspName (OCTET STRING) OPTIONAL*/ - if (item->cspName) { + if (item->cspName) + { ret += ber_sizeof_contextual_octet_string(strlen(item->cspName) * 2); } return ret; } -size_t ber_sizeof_nla_TSCspDataDetail(const TSCspDataDetail_t* item) +size_t ber_sizeof_nla_TSCspDataDetail(const TSCspDataDetail_t* item) { - size_t ret = ber_sizeof_nla_TSCspDataDetail_content(item); - return ber_sizeof_sequence(ret); + size_t ret = ber_sizeof_nla_TSCspDataDetail_content(item); + return ber_sizeof_sequence(ret); } -size_t ber_sizeof_contextual_nla_TSCspDataDetail(const TSCspDataDetail_t* item) { +size_t ber_sizeof_contextual_nla_TSCspDataDetail(const TSCspDataDetail_t* item) +{ size_t innerSz = ber_sizeof_nla_TSCspDataDetail(item); return ber_sizeof_contextual_tag(innerSz) + innerSz; } -void nla_TSCspDataDetail_free(TSCspDataDetail_t** pitem) { +void nla_TSCspDataDetail_free(TSCspDataDetail_t** pitem) +{ TSCspDataDetail_t* item; WINPR_ASSERT(pitem); @@ -310,122 +332,132 @@ void nla_TSCspDataDetail_free(TSCspDataDetail_t** pitem) { *pitem = NULL; } -size_t ber_write_nla_TSCspDataDetail(wStream *s, const TSCspDataDetail_t* item) +size_t ber_write_nla_TSCspDataDetail(wStream* s, const TSCspDataDetail_t* item) { - size_t content_size = ber_sizeof_nla_TSCspDataDetail_content(item); - size_t ret = 0; - - ret = ber_write_sequence_tag(s, content_size); - /* [0] keySpec (INTEGER) */ - if (!ber_write_contextual_integer(s, 0, item->keySpec)) - return 0; + size_t content_size = ber_sizeof_nla_TSCspDataDetail_content(item); + size_t ret = 0; - /* [1] cardName (OCTET STRING) OPTIONAL */ - if (item->cardName) { - if (!ber_write_contextual_char_to_unicode_octet_string(s, 1, item->cardName)) - return 0; - } + ret = ber_write_sequence_tag(s, content_size); + /* [0] keySpec (INTEGER) */ + if (!ber_write_contextual_integer(s, 0, item->keySpec)) + return 0; - /* [2] readerName (OCTET STRING) OPTIONAL */ - if (item->readerName) { - if (!ber_write_contextual_char_to_unicode_octet_string(s, 2, item->readerName)) - return 0; - } + /* [1] cardName (OCTET STRING) OPTIONAL */ + if (item->cardName) + { + if (!ber_write_contextual_char_to_unicode_octet_string(s, 1, item->cardName)) + return 0; + } - /* [3] containerName (OCTET STRING) OPTIONAL */ - if (item->containerName) { - if (!ber_write_contextual_char_to_unicode_octet_string(s, 3, item->containerName)) - return 0; - } + /* [2] readerName (OCTET STRING) OPTIONAL */ + if (item->readerName) + { + if (!ber_write_contextual_char_to_unicode_octet_string(s, 2, item->readerName)) + return 0; + } - /* [4] cspName (OCTET STRING) OPTIONAL */ - if (item->cspName) { - if (!ber_write_contextual_char_to_unicode_octet_string(s, 4, item->cspName)) - return 0; - } + /* [3] containerName (OCTET STRING) OPTIONAL */ + if (item->containerName) + { + if (!ber_write_contextual_char_to_unicode_octet_string(s, 3, item->containerName)) + return 0; + } - return ret + content_size; + /* [4] cspName (OCTET STRING) OPTIONAL */ + if (item->cspName) + { + if (!ber_write_contextual_char_to_unicode_octet_string(s, 4, item->cspName)) + return 0; + } + + return ret + content_size; } -size_t ber_write_contextual_nla_TSCspDataDetail(wStream *s, BYTE tag, const TSCspDataDetail_t* item) +size_t ber_write_contextual_nla_TSCspDataDetail(wStream* s, BYTE tag, const TSCspDataDetail_t* item) { - size_t ret; - size_t inner = ber_sizeof_nla_TSCspDataDetail(item); - - ret = ber_write_contextual_tag(s, tag, inner, TRUE); - ber_write_nla_TSCspDataDetail(s, item); - return ret + inner; + size_t ret; + size_t inner = ber_sizeof_nla_TSCspDataDetail(item); + + ret = ber_write_contextual_tag(s, tag, inner, TRUE); + ber_write_nla_TSCspDataDetail(s, item); + return ret + inner; } -BOOL ber_read_nla_TSCspDataDetail(wStream *s, TSCspDataDetail_t** pret) { - wStream seqstream; - size_t seqLength; - size_t inner_size; - wStream fieldStream; - TSCspDataDetail_t* item; - BOOL ret; +BOOL ber_read_nla_TSCspDataDetail(wStream* s, TSCspDataDetail_t** pret) +{ + wStream seqstream; + size_t seqLength; + size_t inner_size; + wStream fieldStream; + TSCspDataDetail_t* item; + BOOL ret; - if (!ber_read_sequence_tag(s, &seqLength) || Stream_GetRemainingLength(s) < seqLength) - return FALSE; - Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - - item = calloc(1, sizeof(*item)); - if (!item) - return FALSE; - - /* [0] keySpec (INTEGER) */ - ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); - if (!ret) - goto out_fail_keySpec; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + if (!ber_read_sequence_tag(s, &seqLength) || + !Stream_CheckAndLogRequiredLength(TAG, s, seqLength)) + return FALSE; + Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - ret = ber_read_integer(&fieldStream, &item->keySpec); - if (!ret) - goto out_fail_keySpec; + item = calloc(1, sizeof(*item)); + if (!item) + return FALSE; - /* [1] cardName (OCTET STRING) OPTIONAL */ - ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); - if (ret) { - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + /* [0] keySpec (INTEGER) */ + ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); + if (!ret) + goto out_fail_keySpec; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->cardName); - if (!ret) - goto out_fail_cardName; - } - /* [2] readerName (OCTET STRING) OPTIONAL */ - ret = ber_read_contextual_tag(&seqstream, 2, &inner_size, TRUE); - if (ret) { - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + ret = ber_read_integer(&fieldStream, &item->keySpec); + if (!ret) + goto out_fail_keySpec; - ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->readerName); - if (!ret) - goto out_fail_readerName; - } - /* [3] containerName (OCTET STRING) OPTIONAL */ - ret = ber_read_contextual_tag(&seqstream, 3, &inner_size, TRUE); - if (ret) { - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + /* [1] cardName (OCTET STRING) OPTIONAL */ + ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); + if (ret) + { + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->containerName); - if (!ret) - goto out_fail_containerName; - } - /* [4] cspName (OCTET STRING) OPTIONAL */ - ret = ber_read_contextual_tag(&seqstream, 4, &inner_size, TRUE); - if (ret) { - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->cardName); + if (!ret) + goto out_fail_cardName; + } + /* [2] readerName (OCTET STRING) OPTIONAL */ + ret = ber_read_contextual_tag(&seqstream, 2, &inner_size, TRUE); + if (ret) + { + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->cspName); - if (!ret) - goto out_fail_cspName; - } - *pret = item; - return TRUE; + ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->readerName); + if (!ret) + goto out_fail_readerName; + } + /* [3] containerName (OCTET STRING) OPTIONAL */ + ret = ber_read_contextual_tag(&seqstream, 3, &inner_size, TRUE); + if (ret) + { + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); + + ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->containerName); + if (!ret) + goto out_fail_containerName; + } + /* [4] cspName (OCTET STRING) OPTIONAL */ + ret = ber_read_contextual_tag(&seqstream, 4, &inner_size, TRUE); + if (ret) + { + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); + + ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->cspName); + if (!ret) + goto out_fail_cspName; + } + *pret = item; + return TRUE; out_fail_cspName: free(item->containerName); @@ -434,13 +466,14 @@ out_fail_containerName: out_fail_readerName: free(item->cardName); out_fail_cardName: - + out_fail_keySpec: - free(item); - return FALSE; + free(item); + return FALSE; } -size_t ber_sizeof_nla_TSSmartCardCreds_content(const TSSmartCardCreds_t* item) { +size_t ber_sizeof_nla_TSSmartCardCreds_content(const TSSmartCardCreds_t* item) +{ size_t ret = 0; /* [0] pin (OCTET STRING)*/ @@ -450,29 +483,33 @@ size_t ber_sizeof_nla_TSSmartCardCreds_content(const TSSmartCardCreds_t* item) { ret += ber_sizeof_contextual_nla_TSCspDataDetail(item->cspData); /* [2] userHint (OCTET STRING) OPTIONAL*/ - if (item->userHint) { + if (item->userHint) + { ret += ber_sizeof_contextual_octet_string(strlen(item->userHint) * 2); } /* [3] domainHint (OCTET STRING) OPTIONAL*/ - if (item->domainHint) { + if (item->domainHint) + { ret += ber_sizeof_contextual_octet_string(strlen(item->domainHint) * 2); } return ret; } -size_t ber_sizeof_nla_TSSmartCardCreds(const TSSmartCardCreds_t* item) +size_t ber_sizeof_nla_TSSmartCardCreds(const TSSmartCardCreds_t* item) { - size_t ret = ber_sizeof_nla_TSSmartCardCreds_content(item); - return ber_sizeof_sequence(ret); + size_t ret = ber_sizeof_nla_TSSmartCardCreds_content(item); + return ber_sizeof_sequence(ret); } -size_t ber_sizeof_contextual_nla_TSSmartCardCreds(const TSSmartCardCreds_t* item) { +size_t ber_sizeof_contextual_nla_TSSmartCardCreds(const TSSmartCardCreds_t* item) +{ size_t innerSz = ber_sizeof_nla_TSSmartCardCreds(item); return ber_sizeof_contextual_tag(innerSz) + innerSz; } -void nla_TSSmartCardCreds_free(TSSmartCardCreds_t** pitem) { +void nla_TSSmartCardCreds_free(TSSmartCardCreds_t** pitem) +{ TSSmartCardCreds_t* item; WINPR_ASSERT(pitem); @@ -488,105 +525,112 @@ void nla_TSSmartCardCreds_free(TSSmartCardCreds_t** pitem) { *pitem = NULL; } -size_t ber_write_nla_TSSmartCardCreds(wStream *s, const TSSmartCardCreds_t* item) +size_t ber_write_nla_TSSmartCardCreds(wStream* s, const TSSmartCardCreds_t* item) { - size_t content_size = ber_sizeof_nla_TSSmartCardCreds_content(item); - size_t ret = 0; - - ret = ber_write_sequence_tag(s, content_size); - /* [0] pin (OCTET STRING) */ - if (!ber_write_contextual_char_to_unicode_octet_string(s, 0, item->pin)) - return 0; + size_t content_size = ber_sizeof_nla_TSSmartCardCreds_content(item); + size_t ret = 0; - /* [1] cspData (TSCspDataDetail) */ - if (!ber_write_contextual_nla_TSCspDataDetail(s, 1, item->cspData)) - return 0; + ret = ber_write_sequence_tag(s, content_size); + /* [0] pin (OCTET STRING) */ + if (!ber_write_contextual_char_to_unicode_octet_string(s, 0, item->pin)) + return 0; - /* [2] userHint (OCTET STRING) OPTIONAL */ - if (item->userHint) { - if (!ber_write_contextual_char_to_unicode_octet_string(s, 2, item->userHint)) - return 0; - } + /* [1] cspData (TSCspDataDetail) */ + if (!ber_write_contextual_nla_TSCspDataDetail(s, 1, item->cspData)) + return 0; - /* [3] domainHint (OCTET STRING) OPTIONAL */ - if (item->domainHint) { - if (!ber_write_contextual_char_to_unicode_octet_string(s, 3, item->domainHint)) - return 0; - } + /* [2] userHint (OCTET STRING) OPTIONAL */ + if (item->userHint) + { + if (!ber_write_contextual_char_to_unicode_octet_string(s, 2, item->userHint)) + return 0; + } - return ret + content_size; + /* [3] domainHint (OCTET STRING) OPTIONAL */ + if (item->domainHint) + { + if (!ber_write_contextual_char_to_unicode_octet_string(s, 3, item->domainHint)) + return 0; + } + + return ret + content_size; } -size_t ber_write_contextual_nla_TSSmartCardCreds(wStream *s, BYTE tag, const TSSmartCardCreds_t* item) +size_t ber_write_contextual_nla_TSSmartCardCreds(wStream* s, BYTE tag, + const TSSmartCardCreds_t* item) { - size_t ret; - size_t inner = ber_sizeof_nla_TSSmartCardCreds(item); - - ret = ber_write_contextual_tag(s, tag, inner, TRUE); - ber_write_nla_TSSmartCardCreds(s, item); - return ret + inner; + size_t ret; + size_t inner = ber_sizeof_nla_TSSmartCardCreds(item); + + ret = ber_write_contextual_tag(s, tag, inner, TRUE); + ber_write_nla_TSSmartCardCreds(s, item); + return ret + inner; } -BOOL ber_read_nla_TSSmartCardCreds(wStream *s, TSSmartCardCreds_t** pret) { - wStream seqstream; - size_t seqLength; - size_t inner_size; - wStream fieldStream; - TSSmartCardCreds_t* item; - BOOL ret; +BOOL ber_read_nla_TSSmartCardCreds(wStream* s, TSSmartCardCreds_t** pret) +{ + wStream seqstream; + size_t seqLength; + size_t inner_size; + wStream fieldStream; + TSSmartCardCreds_t* item; + BOOL ret; - if (!ber_read_sequence_tag(s, &seqLength) || Stream_GetRemainingLength(s) < seqLength) - return FALSE; - Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - - item = calloc(1, sizeof(*item)); - if (!item) - return FALSE; - - /* [0] pin (OCTET STRING) */ - ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); - if (!ret) - goto out_fail_pin; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + if (!ber_read_sequence_tag(s, &seqLength) || + !Stream_CheckAndLogRequiredLength(TAG, s, seqLength)) + return FALSE; + Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->pin); - if (!ret) - goto out_fail_pin; + item = calloc(1, sizeof(*item)); + if (!item) + return FALSE; - /* [1] cspData (TSCspDataDetail) */ - ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); - if (!ret) - goto out_fail_cspData; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + /* [0] pin (OCTET STRING) */ + ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); + if (!ret) + goto out_fail_pin; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_nla_TSCspDataDetail(&fieldStream, &item->cspData); - if (!ret) - goto out_fail_cspData; + ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->pin); + if (!ret) + goto out_fail_pin; - /* [2] userHint (OCTET STRING) OPTIONAL */ - ret = ber_read_contextual_tag(&seqstream, 2, &inner_size, TRUE); - if (ret) { - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + /* [1] cspData (TSCspDataDetail) */ + ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); + if (!ret) + goto out_fail_cspData; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->userHint); - if (!ret) - goto out_fail_userHint; - } - /* [3] domainHint (OCTET STRING) OPTIONAL */ - ret = ber_read_contextual_tag(&seqstream, 3, &inner_size, TRUE); - if (ret) { - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + ret = ber_read_nla_TSCspDataDetail(&fieldStream, &item->cspData); + if (!ret) + goto out_fail_cspData; - ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->domainHint); - if (!ret) - goto out_fail_domainHint; - } - *pret = item; - return TRUE; + /* [2] userHint (OCTET STRING) OPTIONAL */ + ret = ber_read_contextual_tag(&seqstream, 2, &inner_size, TRUE); + if (ret) + { + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); + + ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->userHint); + if (!ret) + goto out_fail_userHint; + } + /* [3] domainHint (OCTET STRING) OPTIONAL */ + ret = ber_read_contextual_tag(&seqstream, 3, &inner_size, TRUE); + if (ret) + { + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); + + ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->domainHint); + if (!ret) + goto out_fail_domainHint; + } + *pret = item; + return TRUE; out_fail_domainHint: free(item->userHint); @@ -595,11 +639,12 @@ out_fail_userHint: out_fail_cspData: free(item->pin); out_fail_pin: - free(item); - return FALSE; + free(item); + return FALSE; } -size_t ber_sizeof_nla_TSRemoteGuardPackageCred_content(const TSRemoteGuardPackageCred_t* item) { +size_t ber_sizeof_nla_TSRemoteGuardPackageCred_content(const TSRemoteGuardPackageCred_t* item) +{ size_t ret = 0; /* [0] packageName (OCTET STRING)*/ @@ -611,17 +656,19 @@ size_t ber_sizeof_nla_TSRemoteGuardPackageCred_content(const TSRemoteGuardPackag return ret; } -size_t ber_sizeof_nla_TSRemoteGuardPackageCred(const TSRemoteGuardPackageCred_t* item) +size_t ber_sizeof_nla_TSRemoteGuardPackageCred(const TSRemoteGuardPackageCred_t* item) { - size_t ret = ber_sizeof_nla_TSRemoteGuardPackageCred_content(item); - return ber_sizeof_sequence(ret); + size_t ret = ber_sizeof_nla_TSRemoteGuardPackageCred_content(item); + return ber_sizeof_sequence(ret); } -size_t ber_sizeof_contextual_nla_TSRemoteGuardPackageCred(const TSRemoteGuardPackageCred_t* item) { +size_t ber_sizeof_contextual_nla_TSRemoteGuardPackageCred(const TSRemoteGuardPackageCred_t* item) +{ size_t innerSz = ber_sizeof_nla_TSRemoteGuardPackageCred(item); return ber_sizeof_contextual_tag(innerSz) + innerSz; } -void nla_TSRemoteGuardPackageCred_free(TSRemoteGuardPackageCred_t** pitem) { +void nla_TSRemoteGuardPackageCred_free(TSRemoteGuardPackageCred_t** pitem) +{ TSRemoteGuardPackageCred_t* item; WINPR_ASSERT(pitem); @@ -635,195 +682,209 @@ void nla_TSRemoteGuardPackageCred_free(TSRemoteGuardPackageCred_t** pitem) { *pitem = NULL; } -size_t ber_write_nla_TSRemoteGuardPackageCred(wStream *s, const TSRemoteGuardPackageCred_t* item) +size_t ber_write_nla_TSRemoteGuardPackageCred(wStream* s, const TSRemoteGuardPackageCred_t* item) { - size_t content_size = ber_sizeof_nla_TSRemoteGuardPackageCred_content(item); - size_t ret = 0; - - ret = ber_write_sequence_tag(s, content_size); - /* [0] packageName (OCTET STRING) */ - if (!ber_write_contextual_octet_string(s, 0, item->packageName, item->packageNameLen)) - return 0; + size_t content_size = ber_sizeof_nla_TSRemoteGuardPackageCred_content(item); + size_t ret = 0; - /* [1] credBuffer (OCTET STRING) */ - if (!ber_write_contextual_octet_string(s, 1, item->credBuffer, item->credBufferLen)) - return 0; + ret = ber_write_sequence_tag(s, content_size); + /* [0] packageName (OCTET STRING) */ + if (!ber_write_contextual_octet_string(s, 0, item->packageName, item->packageNameLen)) + return 0; - return ret + content_size; + /* [1] credBuffer (OCTET STRING) */ + if (!ber_write_contextual_octet_string(s, 1, item->credBuffer, item->credBufferLen)) + return 0; + + return ret + content_size; } -size_t ber_write_contextual_nla_TSRemoteGuardPackageCred(wStream *s, BYTE tag, const TSRemoteGuardPackageCred_t* item) +size_t ber_write_contextual_nla_TSRemoteGuardPackageCred(wStream* s, BYTE tag, + const TSRemoteGuardPackageCred_t* item) { - size_t ret; - size_t inner = ber_sizeof_nla_TSRemoteGuardPackageCred(item); - - ret = ber_write_contextual_tag(s, tag, inner, TRUE); - ber_write_nla_TSRemoteGuardPackageCred(s, item); - return ret + inner; + size_t ret; + size_t inner = ber_sizeof_nla_TSRemoteGuardPackageCred(item); + + ret = ber_write_contextual_tag(s, tag, inner, TRUE); + ber_write_nla_TSRemoteGuardPackageCred(s, item); + return ret + inner; } -BOOL ber_read_nla_TSRemoteGuardPackageCred(wStream *s, TSRemoteGuardPackageCred_t** pret) { - wStream seqstream; - size_t seqLength; - size_t inner_size; - wStream fieldStream; - TSRemoteGuardPackageCred_t* item; - BOOL ret; +BOOL ber_read_nla_TSRemoteGuardPackageCred(wStream* s, TSRemoteGuardPackageCred_t** pret) +{ + wStream seqstream; + size_t seqLength; + size_t inner_size; + wStream fieldStream; + TSRemoteGuardPackageCred_t* item; + BOOL ret; - if (!ber_read_sequence_tag(s, &seqLength) || Stream_GetRemainingLength(s) < seqLength) - return FALSE; - Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - - item = calloc(1, sizeof(*item)); - if (!item) - return FALSE; - - /* [0] packageName (OCTET STRING) */ - ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); - if (!ret) - goto out_fail_packageName; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + if (!ber_read_sequence_tag(s, &seqLength) || + !Stream_CheckAndLogRequiredLength(TAG, s, seqLength)) + return FALSE; + Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - ret = ber_read_octet_string(&fieldStream, &item->packageName, &item->packageNameLen); - if (!ret) - goto out_fail_packageName; + item = calloc(1, sizeof(*item)); + if (!item) + return FALSE; - /* [1] credBuffer (OCTET STRING) */ - ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); - if (!ret) - goto out_fail_credBuffer; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + /* [0] packageName (OCTET STRING) */ + ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); + if (!ret) + goto out_fail_packageName; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_octet_string(&fieldStream, &item->credBuffer, &item->credBufferLen); - if (!ret) - goto out_fail_credBuffer; + ret = ber_read_octet_string(&fieldStream, &item->packageName, &item->packageNameLen); + if (!ret) + goto out_fail_packageName; - *pret = item; - return TRUE; + /* [1] credBuffer (OCTET STRING) */ + ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); + if (!ret) + goto out_fail_credBuffer; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); + + ret = ber_read_octet_string(&fieldStream, &item->credBuffer, &item->credBufferLen); + if (!ret) + goto out_fail_credBuffer; + + *pret = item; + return TRUE; out_fail_credBuffer: free(item->packageName); out_fail_packageName: - free(item); - return FALSE; + free(item); + return FALSE; } -size_t ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(const TSRemoteGuardPackageCred_t* item, size_t nitems) +size_t ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(const TSRemoteGuardPackageCred_t* item, + size_t nitems) { - size_t i, ret = 0; - for (i = 0; i < nitems; i++, item++) - ret += ber_sizeof_nla_TSRemoteGuardPackageCred(item); - - return ber_sizeof_sequence(ret); + size_t i, ret = 0; + for (i = 0; i < nitems; i++, item++) + ret += ber_sizeof_nla_TSRemoteGuardPackageCred(item); + + return ber_sizeof_sequence(ret); } -size_t ber_sizeof_nla_TSRemoteGuardPackageCred_array(const TSRemoteGuardPackageCred_t* item, size_t nitems) +size_t ber_sizeof_nla_TSRemoteGuardPackageCred_array(const TSRemoteGuardPackageCred_t* item, + size_t nitems) { - return ber_sizeof_sequence( ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(item, nitems) ); + return ber_sizeof_sequence(ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(item, nitems)); } -size_t ber_sizeof_contextual_nla_TSRemoteGuardPackageCred_array(const TSRemoteGuardPackageCred_t* item, size_t nitems) +size_t +ber_sizeof_contextual_nla_TSRemoteGuardPackageCred_array(const TSRemoteGuardPackageCred_t* item, + size_t nitems) { - size_t inner = ber_sizeof_nla_TSRemoteGuardPackageCred_array(item, nitems); - return ber_sizeof_contextual_tag(inner) + inner; -} - -size_t ber_write_nla_TSRemoteGuardPackageCred_array(wStream* s, const TSRemoteGuardPackageCred_t* item, size_t nitems) -{ - size_t i, r, ret; - size_t inner_len = ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(item, nitems); - - ret = ber_write_sequence_tag(s, inner_len); - - for (i = 0; i < nitems; i++, item++) - { - r = ber_write_nla_TSRemoteGuardPackageCred(s, item); - if (!r) - return 0; - ret += r; - } - - return ret; + size_t inner = ber_sizeof_nla_TSRemoteGuardPackageCred_array(item, nitems); + return ber_sizeof_contextual_tag(inner) + inner; } -size_t ber_write_contextual_nla_TSRemoteGuardPackageCred_array(wStream* s, BYTE tag, const TSRemoteGuardPackageCred_t* item, size_t nitems) +size_t ber_write_nla_TSRemoteGuardPackageCred_array(wStream* s, + const TSRemoteGuardPackageCred_t* item, + size_t nitems) { - size_t ret; - size_t inner = ber_sizeof_nla_TSRemoteGuardPackageCred_array(item, nitems); - - ret = ber_write_contextual_tag(s, tag, inner, TRUE); - ber_write_nla_TSRemoteGuardPackageCred_array(s, item, nitems); - return ret + inner; + size_t i, r, ret; + size_t inner_len = ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(item, nitems); + + ret = ber_write_sequence_tag(s, inner_len); + + for (i = 0; i < nitems; i++, item++) + { + r = ber_write_nla_TSRemoteGuardPackageCred(s, item); + if (!r) + return 0; + ret += r; + } + + return ret; } - - -BOOL ber_read_nla_TSRemoteGuardPackageCred_array(wStream* s, TSRemoteGuardPackageCred_t** pitems, size_t* nitems) +size_t ber_write_contextual_nla_TSRemoteGuardPackageCred_array( + wStream* s, BYTE tag, const TSRemoteGuardPackageCred_t* item, size_t nitems) { - size_t subLen; - wStream subStream; - TSRemoteGuardPackageCred_t* retItems = NULL; - size_t ret = 0; - - if (!ber_read_sequence_tag(s, &subLen) || Stream_GetRemainingLength(s) < subLen) - return FALSE; - - Stream_StaticInit(&subStream, Stream_Pointer(s), subLen); - while (Stream_GetRemainingLength(&subStream)) - { - TSRemoteGuardPackageCred_t *item; - TSRemoteGuardPackageCred_t* tmpRet; - - if (!ber_read_nla_TSRemoteGuardPackageCred(&subStream, &item)) - { - free(retItems); - return FALSE; - } - - tmpRet = realloc(retItems, (ret+1) * sizeof(TSRemoteGuardPackageCred_t)); - if (!tmpRet) - { - free(retItems); - return FALSE; - } - - memcpy(&retItems[ret], item, sizeof(*item)); - free(item); - ret++; - } - - *pitems = retItems; - *nitems = ret; - return TRUE; + size_t ret; + size_t inner = ber_sizeof_nla_TSRemoteGuardPackageCred_array(item, nitems); + + ret = ber_write_contextual_tag(s, tag, inner, TRUE); + ber_write_nla_TSRemoteGuardPackageCred_array(s, item, nitems); + return ret + inner; } -size_t ber_sizeof_nla_TSRemoteGuardCreds_content(const TSRemoteGuardCreds_t* item) { +BOOL ber_read_nla_TSRemoteGuardPackageCred_array(wStream* s, TSRemoteGuardPackageCred_t** pitems, + size_t* nitems) +{ + size_t subLen; + wStream subStream; + TSRemoteGuardPackageCred_t* retItems = NULL; + size_t ret = 0; + + if (!ber_read_sequence_tag(s, &subLen) || !Stream_CheckAndLogRequiredLength(TAG, s, subLen)) + return FALSE; + + Stream_StaticInit(&subStream, Stream_Pointer(s), subLen); + while (Stream_GetRemainingLength(&subStream)) + { + TSRemoteGuardPackageCred_t* item; + TSRemoteGuardPackageCred_t* tmpRet; + + if (!ber_read_nla_TSRemoteGuardPackageCred(&subStream, &item)) + { + free(retItems); + return FALSE; + } + + tmpRet = realloc(retItems, (ret + 1) * sizeof(TSRemoteGuardPackageCred_t)); + if (!tmpRet) + { + free(retItems); + return FALSE; + } + + memcpy(&retItems[ret], item, sizeof(*item)); + free(item); + ret++; + } + + *pitems = retItems; + *nitems = ret; + return TRUE; +} + +size_t ber_sizeof_nla_TSRemoteGuardCreds_content(const TSRemoteGuardCreds_t* item) +{ size_t ret = 0; /* [0] logonCred (TSRemoteGuardPackageCred)*/ ret += ber_sizeof_contextual_nla_TSRemoteGuardPackageCred(item->logonCred); /* [1] supplementalCreds (SEQUENCE OF) OPTIONAL*/ - if (item->supplementalCreds) { - ret += ber_sizeof_contextual_nla_TSRemoteGuardPackageCred_array(item->supplementalCreds, item->supplementalCredsItems); + if (item->supplementalCreds) + { + ret += ber_sizeof_contextual_nla_TSRemoteGuardPackageCred_array( + item->supplementalCreds, item->supplementalCredsItems); } return ret; } -size_t ber_sizeof_nla_TSRemoteGuardCreds(const TSRemoteGuardCreds_t* item) +size_t ber_sizeof_nla_TSRemoteGuardCreds(const TSRemoteGuardCreds_t* item) { - size_t ret = ber_sizeof_nla_TSRemoteGuardCreds_content(item); - return ber_sizeof_sequence(ret); + size_t ret = ber_sizeof_nla_TSRemoteGuardCreds_content(item); + return ber_sizeof_sequence(ret); } -size_t ber_sizeof_contextual_nla_TSRemoteGuardCreds(const TSRemoteGuardCreds_t* item) { +size_t ber_sizeof_contextual_nla_TSRemoteGuardCreds(const TSRemoteGuardCreds_t* item) +{ size_t innerSz = ber_sizeof_nla_TSRemoteGuardCreds(item); return ber_sizeof_contextual_tag(innerSz) + innerSz; } -void nla_TSRemoteGuardCreds_free(TSRemoteGuardCreds_t** pitem) { +void nla_TSRemoteGuardCreds_free(TSRemoteGuardCreds_t** pitem) +{ TSRemoteGuardCreds_t* item; WINPR_ASSERT(pitem); @@ -836,79 +897,85 @@ void nla_TSRemoteGuardCreds_free(TSRemoteGuardCreds_t** pitem) { *pitem = NULL; } -size_t ber_write_nla_TSRemoteGuardCreds(wStream *s, const TSRemoteGuardCreds_t* item) +size_t ber_write_nla_TSRemoteGuardCreds(wStream* s, const TSRemoteGuardCreds_t* item) { - size_t content_size = ber_sizeof_nla_TSRemoteGuardCreds_content(item); - size_t ret = 0; - - ret = ber_write_sequence_tag(s, content_size); - /* [0] logonCred (TSRemoteGuardPackageCred) */ - if (!ber_write_contextual_nla_TSRemoteGuardPackageCred(s, 0, item->logonCred)) - return 0; + size_t content_size = ber_sizeof_nla_TSRemoteGuardCreds_content(item); + size_t ret = 0; - /* [1] supplementalCreds (SEQUENCE OF) OPTIONAL */ - if (item->supplementalCreds) { - if (!ber_write_contextual_nla_TSRemoteGuardPackageCred_array(s, 1, item->supplementalCreds, item->supplementalCredsItems)) - return 0; - } + ret = ber_write_sequence_tag(s, content_size); + /* [0] logonCred (TSRemoteGuardPackageCred) */ + if (!ber_write_contextual_nla_TSRemoteGuardPackageCred(s, 0, item->logonCred)) + return 0; - return ret + content_size; + /* [1] supplementalCreds (SEQUENCE OF) OPTIONAL */ + if (item->supplementalCreds) + { + if (!ber_write_contextual_nla_TSRemoteGuardPackageCred_array(s, 1, item->supplementalCreds, + item->supplementalCredsItems)) + return 0; + } + + return ret + content_size; } -size_t ber_write_contextual_nla_TSRemoteGuardCreds(wStream *s, BYTE tag, const TSRemoteGuardCreds_t* item) +size_t ber_write_contextual_nla_TSRemoteGuardCreds(wStream* s, BYTE tag, + const TSRemoteGuardCreds_t* item) { - size_t ret; - size_t inner = ber_sizeof_nla_TSRemoteGuardCreds(item); - - ret = ber_write_contextual_tag(s, tag, inner, TRUE); - ber_write_nla_TSRemoteGuardCreds(s, item); - return ret + inner; + size_t ret; + size_t inner = ber_sizeof_nla_TSRemoteGuardCreds(item); + + ret = ber_write_contextual_tag(s, tag, inner, TRUE); + ber_write_nla_TSRemoteGuardCreds(s, item); + return ret + inner; } -BOOL ber_read_nla_TSRemoteGuardCreds(wStream *s, TSRemoteGuardCreds_t** pret) { - wStream seqstream; - size_t seqLength; - size_t inner_size; - wStream fieldStream; - TSRemoteGuardCreds_t* item; - BOOL ret; +BOOL ber_read_nla_TSRemoteGuardCreds(wStream* s, TSRemoteGuardCreds_t** pret) +{ + wStream seqstream; + size_t seqLength; + size_t inner_size; + wStream fieldStream; + TSRemoteGuardCreds_t* item; + BOOL ret; - if (!ber_read_sequence_tag(s, &seqLength) || Stream_GetRemainingLength(s) < seqLength) - return FALSE; - Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - - item = calloc(1, sizeof(*item)); - if (!item) - return FALSE; - - /* [0] logonCred (TSRemoteGuardPackageCred) */ - ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); - if (!ret) - goto out_fail_logonCred; - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + if (!ber_read_sequence_tag(s, &seqLength) || + !Stream_CheckAndLogRequiredLength(TAG, s, seqLength)) + return FALSE; + Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - ret = ber_read_nla_TSRemoteGuardPackageCred(&fieldStream, &item->logonCred); - if (!ret) - goto out_fail_logonCred; + item = calloc(1, sizeof(*item)); + if (!item) + return FALSE; - /* [1] supplementalCreds (SEQUENCE OF) OPTIONAL */ - ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); - if (ret) { - Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); - Stream_Seek(&seqstream, inner_size); + /* [0] logonCred (TSRemoteGuardPackageCred) */ + ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE); + if (!ret) + goto out_fail_logonCred; + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); - ret = ber_read_nla_TSRemoteGuardPackageCred_array(&fieldStream, &item->supplementalCreds, &item->supplementalCredsItems); - if (!ret) - goto out_fail_supplementalCreds; - } - *pret = item; - return TRUE; + ret = ber_read_nla_TSRemoteGuardPackageCred(&fieldStream, &item->logonCred); + if (!ret) + goto out_fail_logonCred; + + /* [1] supplementalCreds (SEQUENCE OF) OPTIONAL */ + ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE); + if (ret) + { + Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size); + Stream_Seek(&seqstream, inner_size); + + ret = ber_read_nla_TSRemoteGuardPackageCred_array(&fieldStream, &item->supplementalCreds, + &item->supplementalCredsItems); + if (!ret) + goto out_fail_supplementalCreds; + } + *pret = item; + return TRUE; out_fail_supplementalCreds: nla_TSRemoteGuardPackageCred_free(&item->logonCred); out_fail_logonCred: - free(item); - return FALSE; + free(item); + return FALSE; } - diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 9d06b2875..20a177fd5 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -57,11 +57,8 @@ static BOOL update_recv_orders(rdpUpdate* update, wStream* s) { UINT16 numberOrders; - if (Stream_GetRemainingLength(s) < 6) - { - WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 6"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; - } Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */ Stream_Read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */ @@ -84,7 +81,7 @@ static BOOL update_recv_orders(rdpUpdate* update, wStream* s) static BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* bitmapData) { WINPR_UNUSED(update); - if (Stream_GetRemainingLength(s) < 18) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 18)) return FALSE; Stream_Read_UINT16(s, bitmapData->destLeft); @@ -108,7 +105,7 @@ static BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* { if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR)) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT16(s, @@ -126,7 +123,7 @@ static BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* else bitmapData->compressed = FALSE; - if (Stream_GetRemainingLength(s) < bitmapData->bitmapLength) + if (!Stream_CheckAndLogRequiredLength(TAG, s, bitmapData->bitmapLength)) return FALSE; if (bitmapData->bitmapLength > 0) @@ -207,7 +204,7 @@ BITMAP_UPDATE* update_read_bitmap_update(rdpUpdate* update, wStream* s) if (!bitmapUpdate) goto fail; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) goto fail; Stream_Read_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */ @@ -261,7 +258,7 @@ PALETTE_UPDATE* update_read_palette(rdpUpdate* update, wStream* s) if (!palette_update) goto fail; - if (Stream_GetRemainingLength(s) < 6) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) goto fail; Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ @@ -270,7 +267,7 @@ PALETTE_UPDATE* update_read_palette(rdpUpdate* update, wStream* s) if (palette_update->number > 256) palette_update->number = 256; - if (Stream_GetRemainingLength(s) / 3 < palette_update->number) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3ull * palette_update->number)) goto fail; /* paletteEntries */ @@ -300,7 +297,7 @@ static BOOL update_read_synchronize(rdpUpdate* update, wStream* s) static BOOL update_read_play_sound(wStream* s, PLAY_SOUND_UPDATE* play_sound) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, play_sound->duration); /* duration (4 bytes) */ @@ -325,7 +322,7 @@ POINTER_POSITION_UPDATE* update_read_pointer_position(rdpUpdate* update, wStream if (!pointer_position) goto fail; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) goto fail; Stream_Read_UINT16(s, pointer_position->xPos); /* xPos (2 bytes) */ @@ -343,7 +340,7 @@ POINTER_SYSTEM_UPDATE* update_read_pointer_system(rdpUpdate* update, wStream* s) if (!pointer_system) goto fail; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) goto fail; Stream_Read_UINT32(s, pointer_system->type); /* systemPointerType (4 bytes) */ @@ -366,7 +363,7 @@ static BOOL _update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer if (!pointer_color) goto fail; - if (Stream_GetRemainingLength(s) < 14) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 14)) goto fail; Stream_Read_UINT16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */ @@ -415,7 +412,7 @@ static BOOL _update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer * * In fact instead of 24-bpp, the bpp parameter is given by the containing packet. */ - if (Stream_GetRemainingLength(s) < pointer_color->lengthXorMask) + if (!Stream_CheckAndLogRequiredLength(TAG, s, pointer_color->lengthXorMask)) goto fail; scanlineSize = (7 + xorBpp * pointer_color->width) / 8; @@ -449,7 +446,7 @@ static BOOL _update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer * consume 2 bytes (7 pixels per scan-line multiplied by 1 bpp, rounded up to the next even * number of bytes). */ - if (Stream_GetRemainingLength(s) < pointer_color->lengthAndMask) + if (!Stream_CheckAndLogRequiredLength(TAG, s, pointer_color->lengthAndMask)) goto fail; scanlineSize = ((7 + pointer_color->width) / 8); @@ -504,7 +501,7 @@ static BOOL _update_read_pointer_large(wStream* s, POINTER_LARGE_UPDATE* pointer if (!pointer) goto fail; - if (Stream_GetRemainingLength(s) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) goto fail; Stream_Read_UINT16(s, pointer->xorBpp); @@ -540,7 +537,7 @@ static BOOL _update_read_pointer_large(wStream* s, POINTER_LARGE_UPDATE* pointer * * In fact instead of 24-bpp, the bpp parameter is given by the containing packet. */ - if (Stream_GetRemainingLength(s) < pointer->lengthXorMask) + if (!Stream_CheckAndLogRequiredLength(TAG, s, pointer->lengthXorMask)) goto fail; scanlineSize = (7 + pointer->xorBpp * pointer->width) / 8; @@ -574,7 +571,7 @@ static BOOL _update_read_pointer_large(wStream* s, POINTER_LARGE_UPDATE* pointer * consume 2 bytes (7 pixels per scan-line multiplied by 1 bpp, rounded up to the next even * number of bytes). */ - if (Stream_GetRemainingLength(s) < pointer->lengthAndMask) + if (!Stream_CheckAndLogRequiredLength(TAG, s, pointer->lengthAndMask)) goto fail; scanlineSize = ((7 + pointer->width) / 8); @@ -627,7 +624,7 @@ POINTER_NEW_UPDATE* update_read_pointer_new(rdpUpdate* update, wStream* s) if (!pointer_new) goto fail; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) goto fail; Stream_Read_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ @@ -655,7 +652,7 @@ POINTER_CACHED_UPDATE* update_read_pointer_cached(rdpUpdate* update, wStream* s) if (!pointer) goto fail; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) goto fail; Stream_Read_UINT16(s, pointer->cacheIndex); /* cacheIndex (2 bytes) */ @@ -672,7 +669,7 @@ BOOL update_recv_pointer(rdpUpdate* update, wStream* s) rdpContext* context = update->context; rdpPointerUpdate* pointer = update->pointer; - if (Stream_GetRemainingLength(s) < 2 + 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2 + 2)) return FALSE; Stream_Read_UINT16(s, messageType); /* messageType (2 bytes) */ @@ -766,11 +763,8 @@ BOOL update_recv(rdpUpdate* update, wStream* s) rdp_update_internal* up = update_cast(update); rdpContext* context = update->context; - if (Stream_GetRemainingLength(s) < 2) - { - WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 2"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */ WLog_Print(up->log, WLOG_TRACE, "%s Update Data PDU", update_type_to_string(updateType)); @@ -2218,19 +2212,22 @@ BOOL update_read_refresh_rect(rdpUpdate* update, wStream* s) RECTANGLE_16* areas; rdp_update_internal* up = update_cast(update); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT8(s, numberOfAreas); Stream_Seek(s, 3); /* pad3Octects */ - if (Stream_GetRemainingLength(s) / 8 < numberOfAreas) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ull * numberOfAreas)) return FALSE; areas = (RECTANGLE_16*)calloc(numberOfAreas, sizeof(RECTANGLE_16)); if (!areas) + { + WLog_WARN(TAG, "[OOM] refresh rect"); return FALSE; + } for (index = 0; index < numberOfAreas; index++) { @@ -2256,7 +2253,10 @@ BOOL update_read_suppress_output(rdpUpdate* update, wStream* s) RECTANGLE_16 rect = { 0 }; BYTE allowDisplayUpdates; - if (Stream_GetRemainingLength(s) < 4) + WINPR_ASSERT(up); + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT8(s, allowDisplayUpdates); @@ -2264,8 +2264,9 @@ BOOL update_read_suppress_output(rdpUpdate* update, wStream* s) if (allowDisplayUpdates > 0) { - if (Stream_GetRemainingLength(s) < sizeof(RECTANGLE_16)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(RECTANGLE_16))) return FALSE; + Stream_Read_UINT16(s, rect.left); Stream_Read_UINT16(s, rect.top); Stream_Read_UINT16(s, rect.right); diff --git a/libfreerdp/core/utils.c b/libfreerdp/core/utils.c index ab1846b84..637a53cac 100644 --- a/libfreerdp/core/utils.c +++ b/libfreerdp/core/utils.c @@ -29,6 +29,8 @@ #include "utils.h" +#include "../core/rdp.h" + BOOL utils_str_copy(const char* value, char** dst) { WINPR_ASSERT(dst); @@ -54,7 +56,7 @@ auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason settings = instance->context->settings; - if (freerdp_shall_disconnect(instance)) + if (freerdp_shall_disconnect_context(instance->context)) return AUTH_FAILED; if (!settings->GatewayPassword || !settings->GatewayUsername || @@ -96,7 +98,7 @@ auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL o settings = instance->context->settings; - if (freerdp_shall_disconnect(instance)) + if (freerdp_shall_disconnect_context(instance->context)) return AUTH_FAILED; /* Ask for auth data if no or an empty username was specified or no password was given */ @@ -184,15 +186,30 @@ BOOL utils_str_is_empty(const char* str) return FALSE; } -BOOL utils_abort_connect(rdpContext* context) +BOOL utils_abort_connect(rdpRdp* rdp) { - WINPR_ASSERT(context); + WINPR_ASSERT(rdp); - return SetEvent(context->abortEvent); + return SetEvent(rdp->abortEvent); } -BOOL utils_reset_abort(rdpContext* context) +BOOL utils_reset_abort(rdpRdp* rdp) { - WINPR_ASSERT(context); - return ResetEvent(context->abortEvent); + WINPR_ASSERT(rdp); + + return ResetEvent(rdp->abortEvent); +} + +HANDLE utils_get_abort_event(rdpRdp* rdp) +{ + WINPR_ASSERT(rdp); + return rdp->abortEvent; +} + +BOOL utils_abort_event_is_set(rdpRdp* rdp) +{ + DWORD status; + WINPR_ASSERT(rdp); + status = WaitForSingleObject(rdp->abortEvent, 0); + return status == WAIT_OBJECT_0; } diff --git a/libfreerdp/core/utils.h b/libfreerdp/core/utils.h index 3892d74a3..7e538c36b 100644 --- a/libfreerdp/core/utils.h +++ b/libfreerdp/core/utils.h @@ -35,8 +35,10 @@ typedef enum auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason); auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL override); -BOOL utils_reset_abort(rdpContext* context); -BOOL utils_abort_connect(rdpContext* context); +HANDLE utils_get_abort_event(rdpRdp* rdp); +BOOL utils_abort_event_is_set(rdpRdp* rdp); +BOOL utils_reset_abort(rdpRdp* rdp); +BOOL utils_abort_connect(rdpRdp* rdp); BOOL utils_sync_credentials(rdpSettings* settings, BOOL toGateway); BOOL utils_str_is_empty(const char* str); diff --git a/libfreerdp/core/window.c b/libfreerdp/core/window.c index 3f80dd85d..ddca3bf34 100644 --- a/libfreerdp/core/window.c +++ b/libfreerdp/core/window.c @@ -36,12 +36,12 @@ BOOL rail_read_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string) UINT16 new_len; BYTE* new_str; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, new_len); /* cbString (2 bytes) */ - if (Stream_GetRemainingLength(s) < new_len) + if (!Stream_CheckAndLogRequiredLength(TAG, s, new_len)) return FALSE; if (!new_len) @@ -96,7 +96,7 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) { BYTE* newBitMask = NULL; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT16(s, iconInfo->cacheEntry); /* cacheEntry (2 bytes) */ @@ -118,7 +118,7 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) case 1: case 4: case 8: - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, iconInfo->cbColorTable); /* cbColorTable (2 bytes) */ @@ -129,7 +129,7 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) break; } - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT16(s, iconInfo->cbBitsMask); /* cbBitsMask (2 bytes) */ @@ -148,7 +148,7 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) } iconInfo->bitsMask = newBitMask; - if (Stream_GetRemainingLength(s) < iconInfo->cbBitsMask) + if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsMask)) return FALSE; Stream_Read(s, iconInfo->bitsMask, iconInfo->cbBitsMask); } @@ -182,7 +182,7 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) if (iconInfo->colorTable) { - if (Stream_GetRemainingLength(s) < iconInfo->cbColorTable) + if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbColorTable)) return FALSE; Stream_Read(s, iconInfo->colorTable, iconInfo->cbColorTable); } @@ -200,7 +200,7 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) } iconInfo->bitsColor = newBitMask; - if (Stream_GetRemainingLength(s) < iconInfo->cbBitsColor) + if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsColor)) return FALSE; Stream_Read(s, iconInfo->bitsColor, iconInfo->cbBitsColor); } @@ -215,7 +215,7 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) static BOOL update_read_cached_icon_info(wStream* s, CACHED_ICON_INFO* cachedIconInfo) { - if (Stream_GetRemainingLength(s) < 3) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 3)) return FALSE; Stream_Read_UINT16(s, cachedIconInfo->cacheEntry); /* cacheEntry (2 bytes) */ @@ -225,7 +225,7 @@ static BOOL update_read_cached_icon_info(wStream* s, CACHED_ICON_INFO* cachedIco static BOOL update_read_notify_icon_infotip(wStream* s, NOTIFY_ICON_INFOTIP* notifyIconInfoTip) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, notifyIconInfoTip->timeout); /* timeout (4 bytes) */ @@ -243,7 +243,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, windowState->ownerWindowId); /* ownerWindowId (4 bytes) */ @@ -251,7 +251,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, windowState->style); /* style (4 bytes) */ @@ -260,7 +260,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, windowState->showState); /* showState (1 byte) */ @@ -274,7 +274,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_INT32(s, windowState->clientOffsetX); /* clientOffsetX (4 bytes) */ @@ -283,7 +283,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, windowState->clientAreaWidth); /* clientAreaWidth (4 bytes) */ @@ -292,7 +292,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, windowState->resizeMarginLeft); @@ -301,7 +301,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, windowState->resizeMarginTop); @@ -310,7 +310,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, windowState->RPContent); /* RPContent (1 byte) */ @@ -318,7 +318,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, windowState->rootParentHandle); /* rootParentHandle (4 bytes) */ @@ -326,7 +326,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_INT32(s, windowState->windowOffsetX); /* windowOffsetX (4 bytes) */ @@ -335,7 +335,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_INT32(s, windowState->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */ @@ -344,7 +344,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, windowState->windowWidth); /* windowWidth (4 bytes) */ @@ -353,7 +353,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, windowState->numWindowRects); /* numWindowRects (2 bytes) */ @@ -372,7 +372,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI windowState->windowRects = newRect; - if (Stream_GetRemainingLength(s) / 8 < windowState->numWindowRects) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ull * windowState->numWindowRects)) return FALSE; /* windowRects */ @@ -388,7 +388,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) { - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, windowState->visibleOffsetX); /* visibleOffsetX (4 bytes) */ @@ -397,7 +397,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT16(s, windowState->numVisibilityRects); /* numVisibilityRects (2 bytes) */ @@ -416,7 +416,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI windowState->visibilityRects = newRect; - if (Stream_GetRemainingLength(s) / 8 < windowState->numVisibilityRects) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ull * windowState->numVisibilityRects)) return FALSE; /* visibilityRects */ @@ -444,7 +444,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, windowState->TaskbarButton); @@ -452,7 +452,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, windowState->EnforceServerZOrder); @@ -460,7 +460,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, windowState->AppBarState); @@ -468,7 +468,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, windowState->AppBarEdge); @@ -713,7 +713,7 @@ static BOOL update_recv_window_info_order(rdpUpdate* update, wStream* s, WINPR_ASSERT(window); WINPR_ASSERT(orderInfo); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */ @@ -790,7 +790,7 @@ static BOOL update_read_notification_icon_state_order(wStream* s, WINDOW_ORDER_I { if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, notify_icon_state->version); /* version (4 bytes) */ @@ -812,7 +812,7 @@ static BOOL update_read_notification_icon_state_order(wStream* s, WINDOW_ORDER_I if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, notify_icon_state->state); /* state (4 bytes) */ @@ -852,7 +852,7 @@ static BOOL update_recv_notification_icon_info_order(rdpUpdate* update, wStream* WINPR_ASSERT(context); WINPR_ASSERT(window); - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */ @@ -897,7 +897,7 @@ static BOOL update_read_desktop_actively_monitored_order(wStream* s, WINDOW_ORDE if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, monitored_desktop->activeWindowId); /* activeWindowId (4 bytes) */ @@ -907,12 +907,12 @@ static BOOL update_read_desktop_actively_monitored_order(wStream* s, WINDOW_ORDE { UINT32* newid; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, monitored_desktop->numWindowIds); /* numWindowIds (1 byte) */ - if (Stream_GetRemainingLength(s) / 4 < monitored_desktop->numWindowIds) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4ull * monitored_desktop->numWindowIds)) return FALSE; if (monitored_desktop->numWindowIds > 0) @@ -1031,11 +1031,8 @@ BOOL update_recv_altsec_window_order(rdpUpdate* update, wStream* s) remaining = Stream_GetRemainingLength(s); - if (remaining < 6) - { - WLog_Print(up->log, WLOG_ERROR, "Stream short"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 6)) return FALSE; - } Stream_Read_UINT16(s, orderSize); /* orderSize (2 bytes) */ Stream_Read_UINT32(s, orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */ diff --git a/libfreerdp/crypto/ber.c b/libfreerdp/crypto/ber.c index cec3d84ac..6382cad32 100644 --- a/libfreerdp/crypto/ber.c +++ b/libfreerdp/crypto/ber.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -32,7 +33,10 @@ BOOL ber_read_length(wStream* s, size_t* length) { BYTE byte; - if (Stream_GetRemainingLength(s) < 1) + WINPR_ASSERT(s); + WINPR_ASSERT(length); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); @@ -41,7 +45,7 @@ BOOL ber_read_length(wStream* s, size_t* length) { byte &= ~(0x80); - if (Stream_GetRemainingLength(s) < byte) + if (!Stream_CheckAndLogRequiredLength(TAG, s, byte)) return FALSE; if (byte == 1) @@ -67,8 +71,11 @@ BOOL ber_read_length(wStream* s, size_t* length) size_t ber_write_length(wStream* s, size_t length) { + WINPR_ASSERT(s); + if (length > 0xFF) { + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 3); Stream_Write_UINT8(s, 0x80 ^ 2); Stream_Write_UINT16_BE(s, length); return 3; @@ -76,11 +83,13 @@ size_t ber_write_length(wStream* s, size_t length) if (length > 0x7F) { + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 2); Stream_Write_UINT8(s, 0x80 ^ 1); Stream_Write_UINT8(s, length); return 2; } + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 1); Stream_Write_UINT8(s, length); return 1; } @@ -106,14 +115,20 @@ size_t _ber_sizeof_length(size_t length) BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc) { BYTE byte; + const BYTE expect = (BER_CLASS_UNIV | BER_PC(pc) | (BER_TAG_MASK & tag)); - if (Stream_GetRemainingLength(s) < 1) + WINPR_ASSERT(s); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); - if (byte != (BER_CLASS_UNIV | BER_PC(pc) | (BER_TAG_MASK & tag))) + if (byte != expect) + { + WLog_WARN(TAG, "invalid tag, got 0x%02" PRIx8 ", expected 0x%02" PRIx8, byte, expect); return FALSE; + } return TRUE; } @@ -127,6 +142,7 @@ BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc) size_t ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc) { + WINPR_ASSERT(s); Stream_Write_UINT8(s, (BER_CLASS_UNIV | BER_PC(pc)) | (BER_TAG_MASK & tag)); return 1; } @@ -142,35 +158,48 @@ BOOL ber_read_application_tag(wStream* s, BYTE tag, size_t* length) { BYTE byte; + WINPR_ASSERT(s); + WINPR_ASSERT(length); + if (tag > 30) { - if (Stream_GetRemainingLength(s) < 1) + const BYTE expect = ((BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; Stream_Read_UINT8(s, byte); - if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK)) - return FALSE; - - if (Stream_GetRemainingLength(s) < 1) + if (byte != expect) + { + WLog_WARN(TAG, "invalid tag, got 0x%02" PRIx8 ", expected 0x%02" PRIx8, byte, expect); return FALSE; + } Stream_Read_UINT8(s, byte); if (byte != tag) + { + WLog_WARN(TAG, "invalid tag, got 0x%02" PRIx8 ", expected 0x%02" PRIx8, byte, tag); return FALSE; + } return ber_read_length(s, length); } else { - if (Stream_GetRemainingLength(s) < 1) + const BYTE expect = ((BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag)); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); - if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag))) + if (byte != expect) + { + WLog_WARN(TAG, "invalid tag, got 0x%02" PRIx8 ", expected 0x%02" PRIx8, byte, expect); return FALSE; + } return ber_read_length(s, length); } @@ -187,14 +216,18 @@ BOOL ber_read_application_tag(wStream* s, BYTE tag, size_t* length) void ber_write_application_tag(wStream* s, BYTE tag, size_t length) { + WINPR_ASSERT(s); + if (tag > 30) { + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 2); Stream_Write_UINT8(s, (BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK); Stream_Write_UINT8(s, tag); ber_write_length(s, length); } else { + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 1); Stream_Write_UINT8(s, (BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag)); ber_write_length(s, length); } @@ -202,15 +235,24 @@ void ber_write_application_tag(wStream* s, BYTE tag, size_t length) BOOL ber_read_contextual_tag(wStream* s, BYTE tag, size_t* length, BOOL pc) { + const BYTE expect = ((BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); BYTE byte; + WINPR_ASSERT(s); + WINPR_ASSERT(length); + if (Stream_GetRemainingLength(s) < 1) + { + WLog_VRB(TAG, "short data, got %" PRIuz ", expected %" PRIuz, Stream_GetRemainingLength(s), + 1); return FALSE; + } Stream_Read_UINT8(s, byte); - if (byte != ((BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag))) + if (byte != expect) { + WLog_VRB(TAG, "invalid tag, got 0x%02" PRIx8 ", expected 0x%02" PRIx8, byte, expect); Stream_Rewind(s, 1); return FALSE; } @@ -220,6 +262,8 @@ BOOL ber_read_contextual_tag(wStream* s, BYTE tag, size_t* length, BOOL pc) size_t ber_write_contextual_tag(wStream* s, BYTE tag, size_t length, BOOL pc) { + WINPR_ASSERT(s); + WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 1); Stream_Write_UINT8(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); return 1 + ber_write_length(s, length); } @@ -231,15 +275,19 @@ size_t ber_sizeof_contextual_tag(size_t length) BOOL ber_read_sequence_tag(wStream* s, size_t* length) { + const BYTE expect = ((BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_SEQUENCE_OF)); BYTE byte; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, byte); - if (byte != ((BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_SEQUENCE_OF))) + if (byte != expect) + { + WLog_WARN(TAG, "invalid tag, got 0x%02" PRIx8 ", expected 0x%02" PRIx8, byte, expect); return FALSE; + } return ber_read_length(s, length); } @@ -270,17 +318,27 @@ BOOL ber_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) { size_t length; + WINPR_ASSERT(enumerated); + if (!ber_read_universal_tag(s, BER_TAG_ENUMERATED, FALSE) || !ber_read_length(s, &length)) return FALSE; - if (length != 1 || Stream_GetRemainingLength(s) < 1) + if (length != 1) + { + WLog_WARN(TAG, "short data, got %" PRIuz ", expected %" PRIuz, length, 1); + return FALSE; + } + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, *enumerated); /* check that enumerated value falls within expected range */ if (*enumerated + 1 > count) + { + WLog_WARN(TAG, "invalid data, expected %" PRIu8 " < %" PRIu8, *enumerated, count); return FALSE; + } return TRUE; } @@ -297,7 +355,7 @@ BOOL ber_read_bit_string(wStream* s, size_t* length, BYTE* padding) if (!ber_read_universal_tag(s, BER_TAG_BIT_STRING, FALSE) || !ber_read_length(s, length)) return FALSE; - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, *padding); @@ -314,6 +372,8 @@ BOOL ber_read_bit_string(wStream* s, size_t* length, BYTE* padding) size_t ber_write_octet_string(wStream* s, const BYTE* oct_str, size_t length) { size_t size = 0; + + WINPR_ASSERT(oct_str || (length == 0)); size += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); size += ber_write_length(s, length); Stream_Write(s, oct_str, length); @@ -338,6 +398,7 @@ size_t ber_write_contextual_octet_string(wStream* s, BYTE tag, const BYTE* oct_s size_t ber_write_char_to_unicode_octet_string(wStream* s, const char* str) { + WINPR_ASSERT(str); size_t size = 0; size_t length = strlen(str) + 1; size += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); @@ -349,7 +410,8 @@ size_t ber_write_char_to_unicode_octet_string(wStream* s, const char* str) size_t ber_write_contextual_unicode_octet_string(wStream* s, BYTE tag, LPWSTR str) { - size_t len = _wcslen(str) * 2; + WINPR_ASSERT(str); + size_t len = _wcslen(str) * sizeof(WCHAR); size_t inner_len = ber_sizeof_octet_string(len); size_t ret; @@ -363,8 +425,7 @@ size_t ber_write_contextual_char_to_unicode_octet_string(wStream* s, BYTE tag, c size_t len = strlen(str); size_t inner_len = ber_sizeof_octet_string(len * 2); - if (Stream_GetRemainingCapacity(s) < ber_sizeof_contextual_tag(inner_len) + inner_len) - return 0; + WINPR_ASSERT(Stream_GetRemainingCapacity(s) < ber_sizeof_contextual_tag(inner_len) + inner_len); ret = ber_write_contextual_tag(s, tag, inner_len, TRUE); ret += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); @@ -384,7 +445,7 @@ BOOL ber_read_unicode_octet_string(wStream* s, LPWSTR* str) if (!ber_read_octet_string_tag(s, &length)) return FALSE; - if (Stream_GetRemainingLength(s) < length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; ret = calloc(1, length + 2); @@ -406,7 +467,7 @@ BOOL ber_read_char_from_unicode_octet_string(wStream* s, char** str) if (!ber_read_octet_string_tag(s, &length)) return FALSE; - if (Stream_GetRemainingLength(s) < length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; outLen = (length / 2) + 1; @@ -429,7 +490,14 @@ BOOL ber_read_octet_string_tag(wStream* s, size_t* length) BOOL ber_read_octet_string(wStream* s, BYTE** content, size_t* length) { BYTE* ret; - if (!ber_read_octet_string_tag(s, length) || Stream_GetRemainingLength(s) < *length) + + WINPR_ASSERT(s); + WINPR_ASSERT(content); + WINPR_ASSERT(length); + + if (!ber_read_octet_string_tag(s, length)) + return FALSE; + if (!Stream_CheckAndLogRequiredLength(TAG, s, *length)) return FALSE; ret = malloc(*length); @@ -473,7 +541,12 @@ BOOL ber_read_BOOL(wStream* s, BOOL* value) if (!ber_read_universal_tag(s, BER_TAG_BOOLEAN, FALSE) || !ber_read_length(s, &length)) return FALSE; - if (length != 1 || Stream_GetRemainingLength(s) < 1) + if (length != 1) + { + WLog_WARN(TAG, "short data, got %" PRIuz ", expected %" PRIuz, length, 1); + return FALSE; + } + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, v); @@ -498,8 +571,13 @@ BOOL ber_read_integer(wStream* s, UINT32* value) { size_t length; - if (!ber_read_universal_tag(s, BER_TAG_INTEGER, FALSE) || !ber_read_length(s, &length) || - (Stream_GetRemainingLength(s) < length)) + WINPR_ASSERT(s); + + if (!ber_read_universal_tag(s, BER_TAG_INTEGER, FALSE)) + return FALSE; + if (!ber_read_length(s, &length)) + return FALSE; + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; if (value == NULL) @@ -549,10 +627,13 @@ BOOL ber_read_integer(wStream* s, UINT32* value) size_t ber_write_integer(wStream* s, UINT32 value) { + WINPR_ASSERT(s); + if (value < 0x80) { ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); ber_write_length(s, 1); + Stream_Write_UINT8(s, value); return 3; } @@ -560,6 +641,7 @@ size_t ber_write_integer(wStream* s, UINT32 value) { ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); ber_write_length(s, 2); + Stream_Write_UINT16_BE(s, value); return 4; } @@ -567,6 +649,7 @@ size_t ber_write_integer(wStream* s, UINT32 value) { ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); ber_write_length(s, 3); + Stream_Write_UINT8(s, (value >> 16)); Stream_Write_UINT16_BE(s, (value & 0xFFFF)); return 5; @@ -575,6 +658,7 @@ size_t ber_write_integer(wStream* s, UINT32 value) { ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); ber_write_length(s, 4); + Stream_Write_UINT32_BE(s, value); return 6; } @@ -583,6 +667,7 @@ size_t ber_write_integer(wStream* s, UINT32 value) /* treat as signed integer i.e. NT/HRESULT error codes */ ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); ber_write_length(s, 4); + Stream_Write_UINT32_BE(s, value); return 6; } @@ -593,8 +678,10 @@ size_t ber_write_integer(wStream* s, UINT32 value) size_t ber_write_contextual_integer(wStream* s, BYTE tag, UINT32 value) { size_t len = ber_sizeof_integer(value); - if (!Stream_EnsureRemainingCapacity(s, len + 5)) - return 0; + + WINPR_ASSERT(s); + + WINPR_ASSERT(Stream_EnsureRemainingCapacity(s, len + 5)); len += ber_write_contextual_tag(s, tag, len, TRUE); ber_write_integer(s, value); diff --git a/libfreerdp/crypto/per.c b/libfreerdp/crypto/per.c index 3275a57b6..b11ce5cf0 100644 --- a/libfreerdp/crypto/per.c +++ b/libfreerdp/crypto/per.c @@ -17,12 +17,15 @@ * limitations under the License. */ -#include +#include +#include +#include #include #include #define TAG FREERDP_TAG("crypto.per") + /** * Read PER length. * @param s stream @@ -34,23 +37,15 @@ BOOL per_read_length(wStream* s, UINT16* length) { BYTE byte; - if (Stream_GetRemainingLength(s) < 1) - { - WLog_WARN(TAG, "PER length invalid data, got %" PRIuz ", require at least 1 more", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, byte); if (byte & 0x80) { - if (Stream_GetRemainingLength(s) < 1) - { - WLog_WARN(TAG, "PER length invalid data, got %" PRIuz ", require at least 1 more", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } byte &= ~(0x80); *length = (byte << 8); @@ -97,12 +92,8 @@ BOOL per_write_length(wStream* s, UINT16 length) BOOL per_read_choice(wStream* s, BYTE* choice) { - if (Stream_GetRemainingLength(s) < 1) - { - WLog_WARN(TAG, "PER choice invalid data, got %" PRIuz ", require at least 1 more", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, *choice); return TRUE; @@ -131,9 +122,10 @@ BOOL per_write_choice(wStream* s, BYTE choice) BOOL per_read_selection(wStream* s, BYTE* selection) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; + WINPR_ASSERT(selection); Stream_Read_UINT8(s, *selection); return TRUE; } @@ -161,9 +153,10 @@ BOOL per_write_selection(wStream* s, BYTE selection) BOOL per_read_number_of_sets(wStream* s, BYTE* number) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; + WINPR_ASSERT(number); Stream_Read_UINT8(s, *number); return TRUE; } @@ -190,7 +183,7 @@ BOOL per_write_number_of_sets(wStream* s, BYTE number) BOOL per_read_padding(wStream* s, UINT16 length) { - if ((Stream_GetRemainingLength(s)) < length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; Stream_Seek(s, length); @@ -222,10 +215,12 @@ BOOL per_read_integer(wStream* s, UINT32* integer) { UINT16 length; + WINPR_ASSERT(integer); + if (!per_read_length(s, &length)) return FALSE; - if (Stream_GetRemainingLength(s) < length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; if (length == 0) @@ -285,12 +280,8 @@ BOOL per_write_integer(wStream* s, UINT32 integer) BOOL per_read_integer16(wStream* s, UINT16* integer, UINT16 min) { - if (Stream_GetRemainingLength(s) < 2) - { - WLog_WARN(TAG, "PER uint16 invalid data, got %" PRIuz ", require at least 2", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return FALSE; - } Stream_Read_UINT16_BE(s, *integer); @@ -331,14 +322,18 @@ BOOL per_write_integer16(wStream* s, UINT16 integer, UINT16 min) BOOL per_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; + WINPR_ASSERT(enumerated); Stream_Read_UINT8(s, *enumerated); /* check that enumerated value falls within expected range */ if (*enumerated + 1 > count) + { + WLog_WARN(TAG, "PER invalid data, expected %" PRIu8 " < %" PRIu8, *enumerated, count); return FALSE; + } return TRUE; } @@ -359,6 +354,24 @@ BOOL per_write_enumerated(wStream* s, BYTE enumerated, BYTE count) return TRUE; } +static BOOL per_check_oid_and_log_mismatch(const BYTE* got, const BYTE* expect, size_t length) +{ + if (memcmp(got, expect, length) == 0) + { + return TRUE; + } + else + { + char* got_str = winpr_BinToHexString(got, length, TRUE); + char* expect_str = winpr_BinToHexString(expect, length, TRUE); + + WLog_WARN(TAG, "PER OID mismatch, got %s, expected %s", got_str, expect_str); + free(got_str); + free(expect_str); + return FALSE; + } +} + /** * Read PER OBJECT_IDENTIFIER (OID). * @param s stream @@ -371,15 +384,18 @@ BOOL per_read_object_identifier(wStream* s, const BYTE oid[6]) { BYTE t12; UINT16 length; - BYTE a_oid[6]; + BYTE a_oid[6] = { 0 }; if (!per_read_length(s, &length)) return FALSE; if (length != 5) + { + WLog_WARN(TAG, "PER length, got %" PRIu16 ", expected 5", length); return FALSE; + } - if (Stream_GetRemainingLength(s) < length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; Stream_Read_UINT8(s, t12); /* first two tuples */ @@ -391,15 +407,7 @@ BOOL per_read_object_identifier(wStream* s, const BYTE oid[6]) Stream_Read_UINT8(s, a_oid[4]); /* tuple 5 */ Stream_Read_UINT8(s, a_oid[5]); /* tuple 6 */ - if ((a_oid[0] == oid[0]) && (a_oid[1] == oid[1]) && (a_oid[2] == oid[2]) && - (a_oid[3] == oid[3]) && (a_oid[4] == oid[4]) && (a_oid[5] == oid[5])) - { - return TRUE; - } - else - { - return FALSE; - } + return per_check_oid_and_log_mismatch(a_oid, oid, sizeof(a_oid)); } /** @@ -449,7 +457,6 @@ static void per_write_string(wStream* s, BYTE* str, int length) BOOL per_read_octet_string(wStream* s, const BYTE* oct_str, UINT16 length, UINT16 min) { - UINT16 i; UINT16 mlength; BYTE* a_oct_str; @@ -459,19 +466,13 @@ BOOL per_read_octet_string(wStream* s, const BYTE* oct_str, UINT16 length, UINT1 if (mlength + min != length) return FALSE; - if ((Stream_GetRemainingLength(s)) < length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; a_oct_str = Stream_Pointer(s); Stream_Seek(s, length); - for (i = 0; i < length; i++) - { - if (a_oct_str[i] != oct_str[i]) - return FALSE; - } - - return TRUE; + return per_check_oid_and_log_mismatch(a_oct_str, oct_str, length); } /** @@ -507,9 +508,9 @@ BOOL per_write_octet_string(wStream* s, const BYTE* oct_str, UINT16 length, UINT * @param min minimum string length */ -BOOL per_read_numeric_string(wStream* s, int min) +BOOL per_read_numeric_string(wStream* s, UINT16 min) { - int length; + size_t length; UINT16 mlength; if (!per_read_length(s, &mlength)) @@ -517,7 +518,7 @@ BOOL per_read_numeric_string(wStream* s, int min) length = (mlength + min + 1) / 2; - if (((int)Stream_GetRemainingLength(s)) < length) + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; Stream_Seek(s, length); diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 6bdf4f8a5..e2742d149 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -1295,7 +1295,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, const char* hostname, U instance = (freerdp*)tls->settings->instance; WINPR_ASSERT(instance); - if (freerdp_shall_disconnect(instance)) + if (freerdp_shall_disconnect_context(instance->context)) return -1; if (!tls_extract_pem(cert, &pemCert, &length)) diff --git a/libfreerdp/emu/scard/smartcard_virtual_gids.c b/libfreerdp/emu/scard/smartcard_virtual_gids.c index 047475673..1e3dcebbf 100644 --- a/libfreerdp/emu/scard/smartcard_virtual_gids.c +++ b/libfreerdp/emu/scard/smartcard_virtual_gids.c @@ -357,11 +357,8 @@ static BOOL vgids_ef_read_do(vgidsEF* ef, UINT16 doID, BYTE** data, DWORD* dataS if ((len & 0x80)) { BYTE lenSize = len & 0x7F; - if (Stream_GetRemainingLength(ef->data) < lenSize) - { - WLog_ERR(TAG, "Remaining length is smaller than constructed tag length"); + if (!Stream_CheckAndLogRequiredLength(TAG, ef->data, lenSize)) return FALSE; - } switch (lenSize) { @@ -379,11 +376,8 @@ static BOOL vgids_ef_read_do(vgidsEF* ef, UINT16 doID, BYTE** data, DWORD* dataS else doSize = len; - if (Stream_GetRemainingLength(ef->data) < doSize) - { - WLog_ERR(TAG, "Unexpected end for DO %04" PRIx16, nextDOID); + if (Stream_CheckAndLogRequiredLength(TAG, ef->data, doSize)) return FALSE; - } if (nextDOID == doID) { @@ -577,11 +571,8 @@ static BOOL vgids_prepare_keymap(vgidsContext* context, BYTE** outData, DWORD* o static BOOL vgids_parse_apdu_header(wStream* s, BYTE* cla, BYTE* ins, BYTE* p1, BYTE* p2, BYTE* lc, BYTE* le) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "APDU header with less than 5 bytes"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } /* Read and verify APDU data */ if (cla) @@ -604,25 +595,19 @@ static BOOL vgids_parse_apdu_header(wStream* s, BYTE* cla, BYTE* ins, BYTE* p1, /* If LC is requested - check remaining length and read as well */ if (lc) { - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; Stream_Read_UINT8(s, *lc); - if (Stream_GetRemainingLength(s) < *lc) - { - WLog_ERR(TAG, "The LC byte is greater than the remaining command data"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, *lc)) return FALSE; - } } /* read LE */ if (le) { - if (Stream_GetRemainingLength(s) < 1) - { - WLog_ERR(TAG, "Missing LE byte"); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; - } Stream_Read_UINT8(s, *le); } @@ -960,7 +945,7 @@ static BOOL vgids_ins_getdata(vgidsContext* context, wStream* s, BYTE** response break; } - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) { status = ISO_STATUS_INVALIDLC; break; @@ -1080,7 +1065,7 @@ static BOOL vgids_perform_digital_signature(vgidsContext* context) { /* skip digest info and calculate message size */ Stream_Seek(context->commandData, digest->infoSize); - if (Stream_GetRemainingLength(context->commandData) <= 1) + if (!Stream_CheckAndLogRequiredLength(TAG, context->commandData, 2)) goto sign_failed; msgSize = Stream_GetRemainingLength(context->commandData); @@ -1295,7 +1280,7 @@ static BOOL vgids_ins_getresponse(vgidsContext* context, wStream* s, BYTE** resp /* Get response continues data transfer after a previous get data command */ /* Check if there is any data to transfer left */ - if (!context->responseData || Stream_GetRemainingLength(context->responseData) < 1) + if (!context->responseData || !Stream_CheckAndLogRequiredLength(TAG, context->responseData, 1)) { status = ISO_STATUS_COMMANDNOTALLOWED; goto create_response; @@ -1371,14 +1356,14 @@ static BOOL vgids_ins_verify(vgidsContext* context, wStream* s, BYTE** response, } /* Read and verify LC */ - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) { status = ISO_STATUS_INVALIDLC; goto create_response; } Stream_Read_UINT8(s, lc); - if (Stream_GetRemainingLength(s) < lc || lc > VGIDS_MAX_PIN_SIZE) + if (!Stream_CheckAndLogRequiredLength(TAG, s, lc) || (lc > VGIDS_MAX_PIN_SIZE)) { status = ISO_STATUS_INVALIDLC; goto create_response; diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c index b1583d76e..a9f4b865f 100644 --- a/libfreerdp/gdi/gfx.c +++ b/libfreerdp/gdi/gfx.c @@ -783,7 +783,7 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context, s = Stream_StaticConstInit(&buffer, cmd->data, cmd->length); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; surface = (gdiGfxSurface*)context->GetSurfaceData(context, cmd->surfaceId); @@ -808,7 +808,7 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context, { UINT32 x, y; - if (Stream_GetRemainingLength(s) < cmd->height * cmd->width * 1ULL) + if (!Stream_CheckAndLogRequiredLength(TAG, s, cmd->height * cmd->width * 1ULL)) return ERROR_INVALID_DATA; for (y = cmd->top; y < cmd->top + cmd->height; y++) @@ -842,7 +842,7 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context, UINT32 count; BYTE a; - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; Stream_Read_UINT8(s, a); @@ -850,14 +850,14 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context, if (count >= 0xFF) { - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, count); if (count >= 0xFFFF) { - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, count); diff --git a/libfreerdp/utils/cliprdr_utils.c b/libfreerdp/utils/cliprdr_utils.c index 4c71f28bf..eaba15bbd 100644 --- a/libfreerdp/utils/cliprdr_utils.c +++ b/libfreerdp/utils/cliprdr_utils.c @@ -74,21 +74,16 @@ UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length, if (!s) return ERROR_NOT_ENOUGH_MEMORY; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) { - WLog_ERR(TAG, "invalid packed file list"); - result = ERROR_INCORRECT_SIZE; goto out; } Stream_Read_UINT32(s, count); /* cItems (4 bytes) */ - if (Stream_GetRemainingLength(s) / CLIPRDR_FILEDESCRIPTOR_SIZE < count) + if (!Stream_CheckAndLogRequiredLength(TAG, s, CLIPRDR_FILEDESCRIPTOR_SIZE * count * 1ull)) { - WLog_ERR(TAG, "packed file list is too short: expected %" PRIuz ", have %" PRIuz, - ((size_t)count) * CLIPRDR_FILEDESCRIPTOR_SIZE, Stream_GetRemainingLength(s)); - result = ERROR_INCORRECT_SIZE; goto out; } diff --git a/libfreerdp/utils/smartcard_operations.c b/libfreerdp/utils/smartcard_operations.c index f88448388..9871beda7 100644 --- a/libfreerdp/utils/smartcard_operations.c +++ b/libfreerdp/utils/smartcard_operations.c @@ -419,11 +419,8 @@ static LONG smartcard_AccessStartedEvent_Decode(wStream* s, SMARTCARD_OPERATION* WINPR_ASSERT(s); WINPR_ASSERT(operation); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "AccessStartedEvent is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return SCARD_F_INTERNAL_ERROR; - } Stream_Read_INT32(s, operation->call.lng.LongValue); /* Unused (4 bytes) */ @@ -561,12 +558,8 @@ LONG smartcard_irp_device_control_decode(wStream* s, UINT32 CompletionId, UINT32 /* Device Control Request */ - if (Stream_GetRemainingLength(s) < 32) - { - WLog_WARN(TAG, "Device Control Request is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 32)) return SCARD_F_INTERNAL_ERROR; - } Stream_Read_UINT32(s, outputBufferLength); /* OutputBufferLength (4 bytes) */ Stream_Read_UINT32(s, inputBufferLength); /* InputBufferLength (4 bytes) */ diff --git a/libfreerdp/utils/smartcard_pack.c b/libfreerdp/utils/smartcard_pack.c index 616eecafb..103b4ee57 100644 --- a/libfreerdp/utils/smartcard_pack.c +++ b/libfreerdp/utils/smartcard_pack.c @@ -74,7 +74,7 @@ static BOOL smartcard_ndr_pointer_read_(wStream* s, UINT32* index, UINT32* ptr, WINPR_UNUSED(file); if (!s) return FALSE; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; Stream_Read_UINT32(s, ndrPtr); /* mszGroupsNdrPtr (4 bytes) */ @@ -114,12 +114,8 @@ static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t eleme break; } - if (Stream_GetRemainingLength(s) < required) - { - WLog_ERR(TAG, "Short data while trying to read NDR pointer, expected 4, got %" PRIu32, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, required)) return STATUS_BUFFER_TOO_SMALL; - } switch (type) { @@ -163,14 +159,9 @@ static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t eleme if (len > SIZE_MAX / 2) return STATUS_BUFFER_TOO_SMALL; - if (Stream_GetRemainingLength(s) / elementSize < len) - { - WLog_ERR(TAG, - "Short data while trying to read data from NDR pointer, expected %" PRIu32 - ", got %" PRIu32, - len, Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, len * elementSize * 1ull)) return STATUS_BUFFER_TOO_SMALL; - } + len *= elementSize; r = calloc(len + 1, sizeof(CHAR)); @@ -1486,11 +1477,8 @@ LONG smartcard_unpack_common_type_header(wStream* s) UINT8 endianness; UINT16 commonHeaderLength; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_WARN(TAG, "CommonTypeHeader is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return STATUS_BUFFER_TOO_SMALL; - } /* Process CommonTypeHeader */ Stream_Read_UINT8(s, version); /* Version (1 byte) */ @@ -1539,11 +1527,8 @@ LONG smartcard_unpack_private_type_header(wStream* s) UINT32 filler; UINT32 objectBufferLength; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_WARN(TAG, "PrivateTypeHeader is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */ Stream_Read_UINT32(s, filler); /* Filler (4 bytes), should be 0x00000000 */ @@ -1554,14 +1539,8 @@ LONG smartcard_unpack_private_type_header(wStream* s) return STATUS_INVALID_PARAMETER; } - if (objectBufferLength != Stream_GetRemainingLength(s)) - { - WLog_WARN(TAG, - "PrivateTypeHeader ObjectBufferLength mismatch: Actual: %" PRIu32 - ", Expected: %" PRIuz "", - objectBufferLength, Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, objectBufferLength)) return STATUS_INVALID_PARAMETER; - } return SCARD_S_SUCCESS; } @@ -1672,20 +1651,13 @@ LONG smartcard_unpack_redir_scard_context_(wStream* s, REDIR_SCARDCONTEXT* conte ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT)); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, context->cbContext); /* cbContext (4 bytes) */ - if (Stream_GetRemainingLength(s) < context->cbContext) - { - WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: Actual: %" PRIuz ", Expected: %" PRIu32 "", - Stream_GetRemainingLength(s), context->cbContext); + if (!Stream_CheckAndLogRequiredLength(TAG, s, context->cbContext)) return STATUS_BUFFER_TOO_SMALL; - } if ((context->cbContext != 0) && (context->cbContext != 4) && (context->cbContext != 8)) { @@ -1707,12 +1679,8 @@ LONG smartcard_unpack_redir_scard_context_(wStream* s, REDIR_SCARDCONTEXT* conte return STATUS_INVALID_PARAMETER; } - if (context->cbContext > Stream_GetRemainingLength(s)) - { - WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too long: Actual: %" PRIuz ", Expected: %" PRIu32 "", - Stream_GetRemainingLength(s), context->cbContext); + if (!Stream_CheckAndLogRequiredLength(TAG, s, context->cbContext)) return STATUS_INVALID_PARAMETER; - } return SCARD_S_SUCCESS; } @@ -1740,12 +1708,8 @@ LONG smartcard_unpack_redir_scard_context_ref(wStream* s, REDIR_SCARDCONTEXT* co if (context->cbContext == 0) return SCARD_S_SUCCESS; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: Actual: %" PRIuz ", Expected: 4", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, length); /* Length (4 bytes) */ @@ -1762,12 +1726,8 @@ LONG smartcard_unpack_redir_scard_context_ref(wStream* s, REDIR_SCARDCONTEXT* co return STATUS_INVALID_PARAMETER; } - if (Stream_GetRemainingLength(s) < context->cbContext) - { - WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: Actual: %" PRIuz ", Expected: %" PRIu32 "", - Stream_GetRemainingLength(s), context->cbContext); + if (!Stream_CheckAndLogRequiredLength(TAG, s, context->cbContext)) return STATUS_BUFFER_TOO_SMALL; - } if (context->cbContext) Stream_Read(s, &(context->pbContext), context->cbContext); @@ -1795,20 +1755,13 @@ LONG smartcard_unpack_redir_scard_handle_(wStream* s, REDIR_SCARDHANDLE* handle, { ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE)); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "SCARDHANDLE is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, handle->cbHandle); /* Length (4 bytes) */ - if ((Stream_GetRemainingLength(s) < handle->cbHandle) || (!handle->cbHandle)) - { - WLog_WARN(TAG, "SCARDHANDLE is too short: Actual: %" PRIuz ", Expected: %" PRIu32 "", - Stream_GetRemainingLength(s), handle->cbHandle); + if (!Stream_CheckAndLogRequiredLength(TAG, s, handle->cbHandle)) return STATUS_BUFFER_TOO_SMALL; - } if (!smartcard_ndr_pointer_read_(s, index, NULL, file, function, line)) return ERROR_INVALID_DATA; @@ -1835,12 +1788,8 @@ LONG smartcard_unpack_redir_scard_handle_ref(wStream* s, REDIR_SCARDHANDLE* hand { UINT32 length; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "REDIR_SCARDHANDLE is too short: Actual: %" PRIuz ", Expected: 4", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, length); /* Length (4 bytes) */ @@ -1857,12 +1806,8 @@ LONG smartcard_unpack_redir_scard_handle_ref(wStream* s, REDIR_SCARDHANDLE* hand return STATUS_INVALID_PARAMETER; } - if ((Stream_GetRemainingLength(s) < handle->cbHandle) || (!handle->cbHandle)) - { - WLog_WARN(TAG, "REDIR_SCARDHANDLE is too short: Actual: %" PRIuz ", Expected: %" PRIu32 "", - Stream_GetRemainingLength(s), handle->cbHandle); + if (!Stream_CheckAndLogRequiredLength(TAG, s, handle->cbHandle)) return STATUS_BUFFER_TOO_SMALL; - } if (handle->cbHandle) Stream_Read(s, &(handle->pbHandle), handle->cbHandle); @@ -1883,12 +1828,8 @@ LONG smartcard_pack_redir_scard_handle_ref(wStream* s, const REDIR_SCARDHANDLE* LONG smartcard_unpack_establish_context_call(wStream* s, EstablishContext_Call* call) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "EstablishContext_Call is too short: Actual: %" PRIuz ", Expected: 4", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->dwScope); /* dwScope (4 bytes) */ smartcard_trace_establish_context_call(call); @@ -1936,11 +1877,8 @@ LONG smartcard_unpack_list_reader_groups_call(wStream* s, ListReaderGroups_Call* if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_WARN(TAG, "ListReaderGroups_Call is too short: %" PRIdz, Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_INT32(s, call->fmszGroupsIsNULL); /* fmszGroupsIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cchGroups); /* cchGroups (4 bytes) */ @@ -1990,11 +1928,8 @@ LONG smartcard_unpack_list_readers_call(wStream* s, ListReaders_Call* call, BOOL if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 16) - { - WLog_WARN(TAG, "ListReaders_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->cBytes); /* cBytes (4 bytes) */ if (!smartcard_ndr_pointer_read(s, &index, &mszGroupsNdrPtr)) @@ -2050,11 +1985,8 @@ static LONG smartcard_unpack_connect_common(wStream* s, Connect_Common_Call* com if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_WARN(TAG, "Connect_Common is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, common->dwShareMode); /* dwShareMode (4 bytes) */ Stream_Read_UINT32(s, common->dwPreferredProtocols); /* dwPreferredProtocols (4 bytes) */ @@ -2154,11 +2086,8 @@ LONG smartcard_unpack_reconnect_call(wStream* s, Reconnect_Call* call) if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "Reconnect_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->dwShareMode); /* dwShareMode (4 bytes) */ Stream_Read_UINT32(s, call->dwPreferredProtocols); /* dwPreferredProtocols (4 bytes) */ @@ -2203,12 +2132,8 @@ LONG smartcard_unpack_hcard_and_disposition_call(wStream* s, HCardAndDisposition if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "HCardAndDisposition_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->dwDisposition); /* dwDisposition (4 bytes) */ @@ -2264,7 +2189,7 @@ static LONG smartcard_unpack_reader_state_a(wStream* s, LPSCARD_READERSTATEA* pp LPSCARD_READERSTATEA rgReaderStates; BOOL* states; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return status; Stream_Read_UINT32(s, len); @@ -2284,12 +2209,8 @@ static LONG smartcard_unpack_reader_state_a(wStream* s, LPSCARD_READERSTATEA* pp UINT32 ptr = UINT32_MAX; LPSCARD_READERSTATEA readerState = &rgReaderStates[index]; - if (Stream_GetRemainingLength(s) < 52) - { - WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 52)) goto fail; - } if (!smartcard_ndr_pointer_read(s, ptrIndex, &ptr)) { @@ -2341,7 +2262,7 @@ static LONG smartcard_unpack_reader_state_w(wStream* s, LPSCARD_READERSTATEW* pp LPSCARD_READERSTATEW rgReaderStates; BOOL* states; - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return status; Stream_Read_UINT32(s, len); @@ -2363,12 +2284,8 @@ static LONG smartcard_unpack_reader_state_w(wStream* s, LPSCARD_READERSTATEW* pp UINT32 ptr = UINT32_MAX; LPSCARD_READERSTATEW readerState = &rgReaderStates[index]; - if (Stream_GetRemainingLength(s) < 52) - { - WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 52)) goto fail; - } if (!smartcard_ndr_pointer_read(s, ptrIndex, &ptr)) { @@ -2428,12 +2345,8 @@ LONG smartcard_unpack_get_status_change_a_call(wStream* s, GetStatusChangeA_Call if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->dwTimeOut); /* dwTimeOut (4 bytes) */ Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */ @@ -2466,12 +2379,8 @@ LONG smartcard_unpack_get_status_change_w_call(wStream* s, GetStatusChangeW_Call if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->dwTimeOut); /* dwTimeOut (4 bytes) */ Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */ @@ -2530,11 +2439,8 @@ LONG smartcard_unpack_state_call(wStream* s, State_Call* call) if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_WARN(TAG, "State_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_INT32(s, call->fpbAtrIsNULL); /* fpbAtrIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cbAtrLen); /* cbAtrLen (4 bytes) */ @@ -2583,11 +2489,8 @@ LONG smartcard_unpack_status_call(wStream* s, Status_Call* call, BOOL unicode) if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "Status_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_INT32(s, call->fmszReaderNamesIsNULL); /* fmszReaderNamesIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cchReaderLen); /* cchReaderLen (4 bytes) */ @@ -2648,11 +2551,8 @@ LONG smartcard_unpack_get_attrib_call(wStream* s, GetAttrib_Call* call) if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "GetAttrib_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->dwAttrId); /* dwAttrId (4 bytes) */ Stream_Read_INT32(s, call->fpbAttrIsNULL); /* fpbAttrIsNULL (4 bytes) */ @@ -2716,11 +2616,8 @@ LONG smartcard_unpack_control_call(wStream* s, Control_Call* call) if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 20) - { - WLog_WARN(TAG, "Control_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->dwControlCode); /* dwControlCode (4 bytes) */ Stream_Read_UINT32(s, call->cbInBufferSize); /* cbInBufferSize (4 bytes) */ @@ -2794,12 +2691,8 @@ LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call) if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 32) - { - WLog_WARN(TAG, "Transmit_Call is too short: Actual: %" PRIuz ", Expected: 32", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 32)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, ioSendPci.dwProtocol); /* dwProtocol (4 bytes) */ Stream_Read_UINT32(s, ioSendPci.cbExtraBytes); /* cbExtraBytes (4 bytes) */ @@ -2849,23 +2742,13 @@ LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call) if (pbExtraBytesNdrPtr) { // TODO: Use unified pointer reading - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "Transmit_Call is too short: %" PRIuz " (ioSendPci.pbExtraBytes)", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, length); /* Length (4 bytes) */ - if (Stream_GetRemainingLength(s) < ioSendPci.cbExtraBytes) - { - WLog_WARN(TAG, - "Transmit_Call is too short: Actual: %" PRIuz ", Expected: %" PRIu32 - " (ioSendPci.cbExtraBytes)", - Stream_GetRemainingLength(s), ioSendPci.cbExtraBytes); + if (!Stream_CheckAndLogRequiredLength(TAG, s, ioSendPci.cbExtraBytes)) return STATUS_BUFFER_TOO_SMALL; - } ioSendPci.pbExtraBytes = Stream_Pointer(s); call->pioSendPci = @@ -2906,12 +2789,8 @@ LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call) if (pioRecvPciNdrPtr) { - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "Transmit_Call is too short: Actual: %" PRIuz ", Expected: 12", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, ioRecvPci.dwProtocol); /* dwProtocol (4 bytes) */ Stream_Read_UINT32(s, ioRecvPci.cbExtraBytes); /* cbExtraBytes (4 bytes) */ @@ -2930,12 +2809,8 @@ LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call) if (pbExtraBytesNdrPtr) { // TODO: Unify ndr pointer reading - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "Transmit_Call is too short: %" PRIuz " (ioRecvPci.pbExtraBytes)", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, length); /* Length (4 bytes) */ @@ -2957,14 +2832,8 @@ LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call) return STATUS_INVALID_PARAMETER; } - if (Stream_GetRemainingLength(s) < ioRecvPci.cbExtraBytes) - { - WLog_WARN(TAG, - "Transmit_Call is too short: Actual: %" PRIuz ", Expected: %" PRIu32 - " (ioRecvPci.cbExtraBytes)", - Stream_GetRemainingLength(s), ioRecvPci.cbExtraBytes); + if (!Stream_CheckAndLogRequiredLength(TAG, s, ioRecvPci.cbExtraBytes)) return STATUS_BUFFER_TOO_SMALL; - } ioRecvPci.pbExtraBytes = Stream_Pointer(s); call->pioRecvPci = @@ -3061,12 +2930,8 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(wStream* s, LocateCardsByATRA_C if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 16) - { - WLog_WARN(TAG, "LocateCardsByATRA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->cAtrs); if (!smartcard_ndr_pointer_read(s, &index, &rgAtrMasksNdrPtr)) @@ -3183,11 +3048,9 @@ LONG smartcard_unpack_locate_cards_a_call(wStream* s, LocateCardsA_Call* call) if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 16) - { - WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return STATUS_BUFFER_TOO_SMALL; - } + Stream_Read_UINT32(s, call->cBytes); if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr)) return ERROR_INVALID_DATA; @@ -3223,11 +3086,9 @@ LONG smartcard_unpack_locate_cards_w_call(wStream* s, LocateCardsW_Call* call) if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 16) - { - WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return STATUS_BUFFER_TOO_SMALL; - } + Stream_Read_UINT32(s, call->cBytes); if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr)) return ERROR_INVALID_DATA; @@ -3266,7 +3127,7 @@ LONG smartcard_unpack_set_attrib_call(wStream* s, SetAttrib_Call* call) if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return STATUS_BUFFER_TOO_SMALL; Stream_Read_UINT32(s, call->dwAttrId); Stream_Read_UINT32(s, call->cbAttrLen); @@ -3304,12 +3165,8 @@ LONG smartcard_unpack_locate_cards_by_atr_w_call(wStream* s, LocateCardsByATRW_C if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 16) - { - WLog_WARN(TAG, "LocateCardsByATRW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return STATUS_BUFFER_TOO_SMALL; - } Stream_Read_UINT32(s, call->cAtrs); if (!smartcard_ndr_pointer_read(s, &index, &rgAtrMasksNdrPtr)) @@ -3366,7 +3223,7 @@ LONG smartcard_unpack_read_cache_a_call(wStream* s, ReadCacheA_Call* call) if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr)) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return STATUS_BUFFER_TOO_SMALL; Stream_Read_UINT32(s, call->Common.FreshnessCounter); Stream_Read_INT32(s, call->Common.fPbDataIsNULL); @@ -3411,7 +3268,7 @@ LONG smartcard_unpack_read_cache_w_call(wStream* s, ReadCacheW_Call* call) if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr)) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return STATUS_BUFFER_TOO_SMALL; Stream_Read_UINT32(s, call->Common.FreshnessCounter); Stream_Read_INT32(s, call->Common.fPbDataIsNULL); @@ -3457,7 +3314,7 @@ LONG smartcard_unpack_write_cache_a_call(wStream* s, WriteCacheA_Call* call) if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr)) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return STATUS_BUFFER_TOO_SMALL; Stream_Read_UINT32(s, call->Common.FreshnessCounter); @@ -3516,7 +3373,7 @@ LONG smartcard_unpack_write_cache_w_call(wStream* s, WriteCacheW_Call* call) if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr)) return ERROR_INVALID_DATA; - if (Stream_GetRemainingLength(s) < 8) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return STATUS_BUFFER_TOO_SMALL; Stream_Read_UINT32(s, call->Common.FreshnessCounter); Stream_Read_UINT32(s, call->Common.cbDataLen); diff --git a/server/proxy/channels/pf_channel_drdynvc.c b/server/proxy/channels/pf_channel_drdynvc.c index c2e914c82..aa09e2db1 100644 --- a/server/proxy/channels/pf_channel_drdynvc.c +++ b/server/proxy/channels/pf_channel_drdynvc.c @@ -58,17 +58,17 @@ static DynvcReadResult dynvc_read_varInt(wStream* s, size_t len, UINT64* varInt, switch (len) { case 0x00: - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return last ? DYNCVC_READ_ERROR : DYNCVC_READ_INCOMPLETE; Stream_Read_UINT8(s, *varInt); break; case 0x01: - if (Stream_GetRemainingLength(s) < 2) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return last ? DYNCVC_READ_ERROR : DYNCVC_READ_INCOMPLETE; Stream_Read_UINT16(s, *varInt); break; case 0x02: - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return last ? DYNCVC_READ_ERROR : DYNCVC_READ_INCOMPLETE; Stream_Read_UINT32(s, *varInt); break; @@ -107,7 +107,7 @@ static PfChannelResult DynvcTrackerPeekFn(ChannelStateTracker* tracker, BOOL fir const char* direction = isBackData ? "B->F" : "F->B"; s = Stream_StaticConstInit(&sbuffer, Stream_Buffer(tracker->currentPacket), Stream_GetPosition(tracker->currentPacket)); - if (Stream_GetRemainingLength(s) < 1) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return PF_CHANNEL_RESULT_ERROR; Stream_Read_UINT8(s, byte0); @@ -243,7 +243,7 @@ static PfChannelResult DynvcTrackerPeekFn(ChannelStateTracker* tracker, BOOL fir } /* CREATE_REQUEST_PDU response */ - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return PF_CHANNEL_RESULT_ERROR; Stream_Read_UINT32(s, creationStatus); diff --git a/server/proxy/channels/pf_channel_rdpdr.c b/server/proxy/channels/pf_channel_rdpdr.c index 92aaf3871..19ecfe36b 100644 --- a/server/proxy/channels/pf_channel_rdpdr.c +++ b/server/proxy/channels/pf_channel_rdpdr.c @@ -207,7 +207,7 @@ static BOOL rdpdr_process_server_header(wStream* s, UINT16 component, UINT16 Pac UINT16 rpacketid, rcomponent; WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) { WLog_WARN(TAG, "RDPDR_HEADER[%s | %s]: expected length 4, got %" PRIuz, rdpdr_component_string(component), rdpdr_packetid_string(PacketId), @@ -232,7 +232,7 @@ static BOOL rdpdr_process_server_header(wStream* s, UINT16 component, UINT16 Pac return FALSE; } - if (Stream_GetRemainingLength(s) < expect) + if (!Stream_CheckAndLogRequiredLength(TAG, s, expect)) { WLog_WARN(TAG, "RDPDR_HEADER[%s | %s] not enought data, expected %" PRIuz ", " @@ -412,7 +412,7 @@ static UINT rdpdr_process_client_name_request(pf_channel_server_context* rdpdr, Stream_Read_UINT32(s, codePage); WINPR_UNUSED(codePage); /* Field is ignored */ Stream_Read_UINT32(s, rdpdr->common.computerNameLen); - if (Stream_GetRemainingLength(s) < rdpdr->common.computerNameLen) + if (!Stream_CheckAndLogRequiredLength(TAG, s, rdpdr->common.computerNameLen)) { WLog_WARN(TAG, "[%s | %s]: missing data, got " PRIu32 ", expected %" PRIu32, rdpdr_component_string(RDPDR_CTYP_CORE), @@ -479,12 +479,9 @@ static UINT rdpdr_ignore_capset_(wStream* s, size_t capabilityLength, const char return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) < capabilityLength - 4U) - { - WLog_ERR(TAG, "[%s] missing capability data, got %" PRIuz ", expected %" PRIu16, fkt, - Stream_GetRemainingLength(s), capabilityLength - 4); + if (!Stream_CheckAndLogRequiredLengthEx(TAG, WLOG_ERROR, s, capabilityLength - 4U, + "%s::capabilityLength", fkt)) return ERROR_INVALID_DATA; - } Stream_Seek(s, capabilityLength - 4U); return CHANNEL_RC_OK; @@ -544,7 +541,7 @@ static UINT rdpdr_process_server_core_capability_request(pf_channel_client_conte UINT16 capabilityType; UINT16 capabilityLength; - if (Stream_GetRemainingLength(s) < 2 * sizeof(UINT16)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2 * sizeof(UINT16))) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilityType); @@ -700,7 +697,7 @@ static UINT rdpdr_process_client_capability_response(pf_channel_server_context* UINT16 capabilityType; UINT16 capabilityLength; - if (Stream_GetRemainingLength(s) < 2 * sizeof(UINT16)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2 * sizeof(UINT16))) { WLog_WARN(TAG, "[%s | %s] invalid capability length 0x" PRIu16 ", expected at least %" PRIuz, @@ -854,12 +851,8 @@ rdpdr_process_server_capability_request_or_clientid_confirm(pf_channel_client_co return FALSE; } - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "[%s]: expected length >= 4, got %" PRIuz, __FUNCTION__, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Read_UINT16(s, component); if (rcomponent != component) @@ -1018,7 +1011,7 @@ static BOOL filter_smartcard_io_requests(pf_channel_client_context* rdpdr, wStre WINPR_ASSERT(rdpdr); WINPR_ASSERT(pPacketid); - if (Stream_GetRemainingLength(s) < 4) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; pos = Stream_GetPosition(s); @@ -1328,7 +1321,7 @@ static BOOL filter_smartcard_device_list_remove(pf_channel_server_context* rdpdr size_t pos; UINT32 x, count; - if (Stream_GetRemainingLength(s) < sizeof(UINT32)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(UINT32))) return TRUE; pos = Stream_GetPosition(s); Stream_Read_UINT32(s, count); @@ -1336,7 +1329,7 @@ static BOOL filter_smartcard_device_list_remove(pf_channel_server_context* rdpdr if (count == 0) return TRUE; - if (Stream_GetRemainingLength(s) < count * sizeof(UINT32)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, count * sizeof(UINT32))) return TRUE; for (x = 0; x < count; x++) @@ -1379,7 +1372,7 @@ static BOOL filter_smartcard_device_list_announce(pf_channel_server_context* rdp size_t pos; UINT32 x, count; - if (Stream_GetRemainingLength(s) < sizeof(UINT32)) + if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(UINT32))) return TRUE; pos = Stream_GetPosition(s); Stream_Read_UINT32(s, count); @@ -1394,7 +1387,7 @@ static BOOL filter_smartcard_device_list_announce(pf_channel_server_context* rdp char PreferredDosName[8]; UINT32 DeviceDataLength; BYTE* dst = Stream_Pointer(s); - if (Stream_GetRemainingLength(s) < 20) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return TRUE; Stream_Read_UINT32(s, DeviceType); Stream_Read_UINT32(s, DeviceId); @@ -1427,7 +1420,7 @@ static BOOL filter_smartcard_device_list_announce_request(pf_channel_server_cont size_t pos; UINT16 component, packetid; - if (Stream_GetRemainingLength(s) < 12) + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return FALSE; pos = Stream_GetPosition(s); diff --git a/server/proxy/channels/pf_channel_smartcard.c b/server/proxy/channels/pf_channel_smartcard.c index 329748fca..e0b758850 100644 --- a/server/proxy/channels/pf_channel_smartcard.c +++ b/server/proxy/channels/pf_channel_smartcard.c @@ -81,7 +81,7 @@ static BOOL pf_channel_client_write_iostatus(wStream* out, const SMARTCARD_OPERA WINPR_ASSERT(out); pos = Stream_GetPosition(out); - if (Stream_Length(out) < 16) + if (!Stream_CheckAndLogRequiredLength(TAG, out, 16)) return FALSE; Stream_SetPosition(out, 0); @@ -178,12 +178,8 @@ BOOL pf_channel_smartcard_client_handle(pClientContext* pc, wStream* s, wStream* e.send_fkt = send_fkt; /* Skip IRP header */ - if (Stream_GetRemainingLength(s) < 20) - { - WLog_WARN(TAG, "[%s] Invalid IRP received, expected 20 bytes, have %" PRIuz, - SCARD_SVC_CHANNEL_NAME, Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 20)) return FALSE; - } else { UINT32 DeviceId; diff --git a/server/proxy/pf_client.c b/server/proxy/pf_client.c index 30c58adc1..c52a5ae5a 100644 --- a/server/proxy/pf_client.c +++ b/server/proxy/pf_client.c @@ -769,7 +769,7 @@ static DWORD WINAPI pf_client_thread_proc(pClientContext* pc) } handles[nCount++] = Queue_Event(pc->cached_server_channel_data); - while (!freerdp_shall_disconnect(instance)) + while (!freerdp_shall_disconnect_context(instance->context)) { UINT32 tmp = freerdp_get_event_handles(instance->context, &handles[nCount], ARRAYSIZE(handles) - nCount); @@ -793,7 +793,7 @@ static DWORD WINAPI pf_client_thread_proc(pClientContext* pc) if (status == WAIT_OBJECT_0) break; - if (freerdp_shall_disconnect(instance)) + if (freerdp_shall_disconnect_context(instance->context)) break; if (proxy_data_shall_disconnect(pdata)) @@ -971,7 +971,7 @@ static int pf_client_client_stop(rdpContext* context) PROXY_LOG_DBG(TAG, pc, "aborting client connection"); proxy_data_abort_connect(pdata); - freerdp_abort_connect(context->instance); + freerdp_abort_connect_context(context); return 0; } diff --git a/server/proxy/pf_context.c b/server/proxy/pf_context.c index 0aaf97119..2847e6c3f 100644 --- a/server/proxy/pf_context.c +++ b/server/proxy/pf_context.c @@ -232,8 +232,7 @@ BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src) * it must be freed before setting it to NULL to avoid a memory leak! */ - if (!freerdp_settings_set_pointer_len(dst, FreeRDP_RdpServerRsaKey, NULL, - sizeof(rdpRsaKey))) + if (!freerdp_settings_set_pointer_len(dst, FreeRDP_RdpServerRsaKey, NULL, 1)) goto out_fail; } @@ -355,7 +354,7 @@ void proxy_data_abort_connect(proxyData* pdata) WINPR_ASSERT(pdata->abort_event); SetEvent(pdata->abort_event); if (pdata->pc) - freerdp_abort_connect(pdata->pc->context.instance); + freerdp_abort_connect_context(&pdata->pc->context); } BOOL proxy_data_shall_disconnect(proxyData* pdata) diff --git a/server/shadow/Win/win_rdp.c b/server/shadow/Win/win_rdp.c index f26f511aa..6ffe9b0ba 100644 --- a/server/shadow/Win/win_rdp.c +++ b/server/shadow/Win/win_rdp.c @@ -217,7 +217,7 @@ static DWORD WINAPI shw_client_thread(LPVOID arg) break; } - if (freerdp_shall_disconnect(instance)) + if (freerdp_shall_disconnect_context(instance->context)) { break; } diff --git a/tools/asn_parser_generator.py b/tools/asn_parser_generator.py old mode 100644 new mode 100755 index fe882b1fa..2a2b83166 --- a/tools/asn_parser_generator.py +++ b/tools/asn_parser_generator.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import sys import getopt import os.path @@ -27,13 +29,13 @@ class AsnField(object): self.cleanupFunc = None self.freeFunc = None self.options = [] - + if asnType.upper() in ['OCTET STRING', 'INTEGER']: - self.asnTypePointer = self.asnType - + self.asnTypePointer = self.asnType + def __str__(self): - return "{0} [{1}] {2}{3}".format(self.name, self.seqIndex, self.asnType, self.optional and " OPTIONAL" or "") - + return "{0} [{1}] {2}{3}".format(self.name, self.seqIndex, self.asnType, self.optional and " OPTIONAL" or "") + class AsnSequence(object): ''' ''' @@ -52,7 +54,7 @@ class AsnParser(object): KNOWN_OPTIONS = (FIELD_OPTION, 'prefix', ) STATE_ROOT, STATE_IN_ITEM, STATE_IN_OPTIONS = range(0, 3) - + def __init__(self): self.state = AsnParser.STATE_ROOT self.defs = {} @@ -69,58 +71,58 @@ class AsnParser(object): CHAR_TO_UNICODE: 'strlen(item->{fieldName}) * 2', } } - - + + def parse(self, content): for l in content.split("\n"): if l.startswith('#'): continue - + tokens = compressTokens(l.lstrip().rstrip().split(' ')) - + if self.state == AsnParser.STATE_ROOT: if not len(tokens): continue - + if tokens[0] == "%options" and tokens[1] == "{": self.state = AsnParser.STATE_IN_OPTIONS continue - + if tokens[1] != "::=": continue - + if tokens[2] != "SEQUENCE": raise Exception("ERROR: not handling non sequence items for now") - + self.currentName = tokens[0] self.currentItem = AsnSequence(tokens[0]) self.state = AsnParser.STATE_IN_ITEM - + elif self.state == AsnParser.STATE_IN_ITEM: if tokens[0] == '}': self.defs[self.currentName] = self.currentItem self.state = AsnParser.STATE_ROOT continue - + optional = tokens[-1] in ["OPTIONAL", "OPTIONAL,"] fieldIndex = int(tokens[1][1:-1]) - + if optional: typeTokens = tokens[2:-1] else: typeTokens = tokens[2:] - asnType = " ".join(typeTokens) + asnType = " ".join(typeTokens) if asnType[-1] == ',': asnType = asnType[0:-1] - + subType = None if asnType.startswith("SEQUENCE OF"): subType = typeTokens[-1] - asnType = "SEQUENCE OF" - + asnType = "SEQUENCE OF" + self.currentItem.fields.append(AsnField(tokens[0], fieldIndex, optional, asnType, subType)) - + elif self.state == AsnParser.STATE_IN_OPTIONS: if not len(tokens) or l.startswith("#"): continue @@ -128,46 +130,46 @@ class AsnParser(object): if tokens[0] == "}": self.state == AsnParser.STATE_ROOT continue - + option = tokens[0] if option not in AsnParser.KNOWN_OPTIONS: raise Exception("unknown option '{0}'".format(option)) - + if option == FIELD_OPTION: target = tokens[1] objName, fieldName = target.split(".", 2) - + obj = self.defs.get(objName, None) if not obj: raise Exception("object type {0} unknown".format(objName)) - + found = False for field in obj.fields: if field.name == fieldName: found = True break if not found: - raise Exception("object {0} has no field {1}".format(objName, fieldName)) - + raise Exception("object {0} has no field {1}".format(objName, fieldName)) + if tokens[2] not in KNOWN_FIELD_OPTIONS: raise Exception("unknown field option {0}".format(objName, tokens[2])) - + field.options.append(tokens[2]) - + elif option == "prefix": self.options['prefix'] = tokens[1] - - - + + + # try to resolve custom types in fields for typeDef in self.defs.values(): for field in typeDef.fields: if field.asnTypePointer is None: field.asnTypePointer = self.defs.get(field.asnType, None) - + if field.asnType == "SEQUENCE OF": - self.emitArraycode.append(field.subType) - + self.emitArraycode.append(field.subType) + # adjust AsnField fields for typeDef in self.defs.values(): for field in typeDef.fields: @@ -185,47 +187,47 @@ class AsnParser(object): elif UNICODE in field.options: fieldType = "WCHAR" field.outputType = "WCHAR" - field.writeFunc = "ber_write_contextual_unicode_octet_string(s, {fieldIndex}, item->{fieldName})" + field.writeFunc = "ber_write_contextual_unicode_octet_string(s, {fieldIndex}, item->{fieldName})" field.lenFunc = "ber_sizeof_contextual_octet_string(" + self.options['octetStringLen'][fieldType] + ")" field.readFunc = "ber_read_unicode_octet_string({stream}, &item->{fieldName})" else: - field.writeFunc = "ber_write_contextual_octet_string(s, {fieldIndex}, item->{fieldName}, item->{fieldName}Len)" + field.writeFunc = "ber_write_contextual_octet_string(s, {fieldIndex}, item->{fieldName}, item->{fieldName}Len)" field.lenFunc = "ber_sizeof_contextual_octet_string(item->{fieldName}Len)" field.readFunc = "ber_read_octet_string({stream}, &item->{fieldName}, &item->{fieldName}Len)" field.cleanupFunc = "free(item->{fieldName});" - - + + elif field.asnType == "INTEGER": field.lenFunc = "ber_sizeof_contextual_integer(item->{fieldName})" field.writeFunc = "ber_write_contextual_integer(s, {fieldIndex}, item->{fieldName})" field.readFunc = "ber_read_integer({stream}, &item->{fieldName})" field.cleanupFunc = "" - + elif field.asnType == "SEQUENCE OF": field.lenFunc = "ber_sizeof_contextual_{prefix}{fieldSubType}_array(item->{fieldName}, item->{fieldName}Items)" field.writeFunc = "ber_write_contextual_{prefix}{fieldSubType}_array(s, {fieldIndex}, item->{fieldName}, item->{fieldName}Items)" field.readFunc = "ber_read_{prefix}{fieldSubType}_array({stream}, &item->{fieldName}, &item->{fieldName}Items)" field.cleanupFunc = "" - + else: field.lenFunc = "ber_sizeof_contextual_{prefix}{fieldType}(item->{fieldName})" field.writeFunc = "ber_write_contextual_{prefix}{fieldType}(s, {fieldIndex}, item->{fieldName})" field.readFunc = "ber_read_{prefix}{fieldType}({stream}, &item->{fieldName})" field.cleanupFunc = "{prefix}{fieldType}_free(&item->{fieldName});" - + return True - - + + def emitStructDefs(self): ret = '' - for defName, seq in self.defs.items(): + for defName, seq in self.defs.items(): h = { 'prefix': self.options['prefix'], 'defName': defName } - + ret += 'typedef struct {\n' for field in seq.fields: if field.asnType == "INTEGER": ret += "\tUINT32 {fieldName};\n".format(fieldName=field.name) - + elif field.asnType == "OCTET STRING": fieldType = field.outputType if CHAR_TO_UNICODE in field.options: @@ -235,24 +237,24 @@ class AsnParser(object): else: fieldType = 'BYTE' ret += "\tsize_t {fieldName}Len;\n".format(fieldName=field.name, fieldType=fieldType) - + ret += "\t{fieldType}* {fieldName};\n".format(fieldName=field.name, fieldType=fieldType) - + elif field.asnType == "SEQUENCE OF": ret += "\tsize_t {fieldName}Items;\n".format(fieldName=field.name, fieldType=field.subType) ret += "\t{fieldType}_t* {fieldName};\n".format(fieldName=field.name, fieldType=field.subType) else: ret += "\t{typeName}_t* {fieldName};\n".format(fieldName=field.name, typeName=field.asnType) ret += '}} {defName}_t;\n\n'.format(**h) - + return ret - - + + def emitPrototypes(self): ret = '' - for defName, seq in self.defs.items(): + for defName, seq in self.defs.items(): h = { 'prefix': self.options['prefix'], 'defName': defName } - + ret += "size_t ber_sizeof_{prefix}{defName}_content(const {defName}_t* item);\n".format(**h) ret += "size_t ber_sizeof_{prefix}{defName}(const {defName}_t* item);\n".format(**h) ret += "size_t ber_sizeof_contextual_{prefix}{defName}(const {defName}_t* item);\n".format(**h) @@ -260,48 +262,48 @@ class AsnParser(object): ret += "size_t ber_write_{prefix}{defName}(wStream *s, const {defName}_t* item);\n".format(**h) ret += "size_t ber_write_contextual_{prefix}{defName}(wStream *s, BYTE tag, const {defName}_t* item);\n".format(**h) ret += 'BOOL ber_read_{prefix}{defName}(wStream *s, {defName}_t** pret);\n'.format(**h) - + if defName in self.emitArraycode: - ret += "size_t ber_sizeof_{prefix}{defName}_array_content(const {defName}_t* item, size_t nitems);\n".format(**h) - ret += "size_t ber_sizeof_{prefix}{defName}_array(const {defName}_t* item, size_t nitems);\n".format(**h) - ret += "size_t ber_sizeof_contextual_{prefix}{defName}_array(const {defName}_t* item, size_t nitems);\n".format(**h) + ret += "size_t ber_sizeof_{prefix}{defName}_array_content(const {defName}_t* item, size_t nitems);\n".format(**h) + ret += "size_t ber_sizeof_{prefix}{defName}_array(const {defName}_t* item, size_t nitems);\n".format(**h) + ret += "size_t ber_sizeof_contextual_{prefix}{defName}_array(const {defName}_t* item, size_t nitems);\n".format(**h) ret += "size_t ber_write_{prefix}{defName}_array(wStream* s, const {defName}_t* item, size_t nitems);\n".format(**h) ret += "size_t ber_write_contextual_{prefix}{defName}_array(wStream* s, BYTE tag, const {defName}_t* item, size_t nitems);\n".format(**h) ret += "BOOL ber_read_{prefix}{defName}_array(wStream* s, {defName}_t** item, size_t* nitems);\n".format(**h) ret += '\n' - + return ret - - + + def emitImpl(self): ret = '' - for defName, seq in self.defs.items(): + for defName, seq in self.defs.items(): h = { 'prefix': self.options['prefix'], 'defName': defName } - - # ================= ber_sizeof_ ========================================= + + # ================= ber_sizeof_ ========================================= ret += "size_t ber_sizeof_{prefix}{defName}_content(const {defName}_t* item) {{\n".format(**h) ret += "\tsize_t ret = 0;\n\n" - + for field in seq.fields: h2 = {'fieldName': field.name, 'fieldIndex': field.seqIndex, 'fieldType':field.asnType, 'fieldSubType': field.subType } shift = '\t' - - ret += shift + "/* [{fieldIndex}] {fieldName} ({fieldType}){optional}*/\n".format(**h2, optional=field.optional and " OPTIONAL" or "") + + ret += shift + "/* [{fieldIndex}] {fieldName} ({fieldType}){optional}*/\n".format(**h2, optional=field.optional and " OPTIONAL" or "") if field.optional: ret += shift + "if (item->{fieldName}) {{\n".format(fieldName=field.name) - shift = '\t\t' - + shift = '\t\t' + ret += shift + "ret += " + field.lenFunc.format(**h2, **h) + ";\n" - + if field.optional: ret += "\t}\n" ret += '\n' - + ret += '\treturn ret;\n' ret += '}\n\n' - ret += '''size_t ber_sizeof_{prefix}{defName}(const {defName}_t* item) + ret += '''size_t ber_sizeof_{prefix}{defName}(const {defName}_t* item) {{ size_t ret = ber_sizeof_{prefix}{defName}_content(item); return ber_sizeof_sequence(ret); @@ -314,14 +316,14 @@ class AsnParser(object): ret += "}\n\n" - # ================= free_ ========================================= + # ================= free_ ========================================= ret += "void {prefix}{defName}_free({defName}_t** pitem) {{\n".format(**h) ret += "\t{defName}_t* item;\n\n".format(**h) ret += "\tWINPR_ASSERT(pitem);\n" ret += "\titem = *pitem;\n" ret += "\tif (!item)\n" ret += "\t\treturn;\n\n" - + for field in seq.fields: if field.cleanupFunc: h2 = { 'fieldName': field.name, 'fieldIndex': field.seqIndex, 'fieldType':field.asnType } @@ -329,29 +331,29 @@ class AsnParser(object): ret += "\tfree(item);\n" ret += "\t*pitem = NULL;\n" ret += "}\n\n" - - # ================= ber_write_ ========================================= - ret += '''size_t ber_write_{prefix}{defName}(wStream *s, const {defName}_t* item) + + # ================= ber_write_ ========================================= + ret += '''size_t ber_write_{prefix}{defName}(wStream *s, const {defName}_t* item) {{ size_t content_size = ber_sizeof_{prefix}{defName}_content(item); size_t ret = 0; - + ret = ber_write_sequence_tag(s, content_size); '''.format(**h) - + for field in seq.fields: h2 = { 'fieldName': field.name, 'fieldIndex': field.seqIndex, 'fieldType':field.asnType, 'fieldSubType': field.subType } shift = " " - - ret += shift + "/* [{fieldIndex}] {fieldName} ({fieldType}){optional} */\n".format(**h2, optional=field.optional and " OPTIONAL" or "") + + ret += shift + "/* [{fieldIndex}] {fieldName} ({fieldType}){optional} */\n".format(**h2, optional=field.optional and " OPTIONAL" or "") if field.optional: ret += shift + "if (item->{fieldName}) {{\n" .format(**h2) shift += ' ' - + ret += shift + "if (!" + field.writeFunc.format(**h2, **h) + ")\n" ret += shift + ' return 0;\n' - + if field.optional: ret += " }\n" ret += "\n" @@ -363,16 +365,16 @@ class AsnParser(object): {{ size_t ret; size_t inner = ber_sizeof_{prefix}{defName}(item); - + ret = ber_write_contextual_tag(s, tag, inner, TRUE); ber_write_{prefix}{defName}(s, item); - return ret + inner; + return ret + inner; }} '''.format(**h) - # ================= ber_read_ ========================================= + # ================= ber_read_ ========================================= ret += '''BOOL ber_read_{prefix}{defName}(wStream *s, {defName}_t** pret) {{ wStream seqstream; size_t seqLength; @@ -381,71 +383,71 @@ class AsnParser(object): {defName}_t* item; BOOL ret; - if (!ber_read_sequence_tag(s, &seqLength) || Stream_GetRemainingLength(s) < seqLength) + if (!ber_read_sequence_tag(s, &seqLength) || !Stream_CheckAndLogRequiredLength(TAG,s, seqLength)) return FALSE; Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength); - + item = calloc(1, sizeof(*item)); if (!item) return FALSE; - + '''.format(**h) shiftLevel = 1 shift = ' ' * 4 * shiftLevel - + cleanupLabels = [] for field in seq.fields: - h2 = { 'fieldName': field.name, 'fieldIndex': field.seqIndex, 'fieldType':field.asnType, + h2 = { 'fieldName': field.name, 'fieldIndex': field.seqIndex, 'fieldType':field.asnType, 'stream': '&fieldStream', 'fieldSubType': field.subType } - + cleanupLabels.insert(0, "\t" + field.cleanupFunc.format(**h2, **h)) cleanupLabels.insert(1, "out_fail_{fieldName}:".format(**h2, **h)) - - ret += shift + "/* [{fieldIndex}] {fieldName} ({fieldType}){optional} */\n".format(**h2, optional=field.optional and " OPTIONAL" or "") - ret += shift + 'ret = ber_read_contextual_tag(&seqstream, {fieldIndex}, &inner_size, TRUE);\n'.format(**h2) - if not field.optional: + ret += shift + "/* [{fieldIndex}] {fieldName} ({fieldType}){optional} */\n".format(**h2, optional=field.optional and " OPTIONAL" or "") + ret += shift + 'ret = ber_read_contextual_tag(&seqstream, {fieldIndex}, &inner_size, TRUE);\n'.format(**h2) + + if not field.optional: ret += shift + "if (!ret) \n" ret += shift + '\tgoto out_fail_{fieldName};\n'.format(**h2) else: ret += shift + "if (ret) { \n" shiftLevel += 1 shift = ' ' * 4 * shiftLevel - - ret += shift + "Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);\n" + + ret += shift + "Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);\n" ret += shift + "Stream_Seek(&seqstream, inner_size);\n" ret += '\n' ret += shift + "ret = " + field.readFunc.format(**h2, **h) + ";\n" ret += shift + "if (!ret)\n" ret += shift + '\tgoto out_fail_{fieldName};\n'.format(**h2) - + if field.optional: shiftLevel -= 1 - shift = ' ' * 4 * shiftLevel + shift = ' ' * 4 * shiftLevel ret += shift + '}' - + ret += '\n' - - ret += shift + "*pret = item;\n" - ret += shift + "return TRUE;\n" + + ret += shift + "*pret = item;\n" + ret += shift + "return TRUE;\n" ret += '\n' - cleanupLabels = cleanupLabels[1:] + cleanupLabels = cleanupLabels[1:] ret += "\n".join(cleanupLabels) - + ret += '\n' - ret += shift + 'free(item);\n' - ret += shift + 'return FALSE;\n' + ret += shift + 'free(item);\n' + ret += shift + 'return FALSE;\n' ret += '}\n\n' - # ====================== code for handling arrays ==================================== + # ====================== code for handling arrays ==================================== if defName in self.emitArraycode: ret += '''size_t ber_sizeof_{prefix}{defName}_array_content(const {defName}_t* item, size_t nitems) {{ size_t i, ret = 0; for (i = 0; i < nitems; i++, item++) ret += ber_sizeof_{prefix}{defName}(item); - + return ber_sizeof_sequence(ret); }} @@ -457,35 +459,35 @@ size_t ber_sizeof_{prefix}{defName}_array(const {defName}_t* item, size_t nitems size_t ber_sizeof_contextual_{prefix}{defName}_array(const {defName}_t* item, size_t nitems) {{ size_t inner = ber_sizeof_{prefix}{defName}_array(item, nitems); - return ber_sizeof_contextual_tag(inner) + inner; -}} + return ber_sizeof_contextual_tag(inner) + inner; +}} size_t ber_write_{prefix}{defName}_array(wStream* s, const {defName}_t* item, size_t nitems) {{ size_t i, r, ret; size_t inner_len = ber_sizeof_{prefix}{defName}_array_content(item, nitems); - + ret = ber_write_sequence_tag(s, inner_len); - + for (i = 0; i < nitems; i++, item++) {{ r = ber_write_{prefix}{defName}(s, item); if (!r) return 0; - ret += r; + ret += r; }} - - return ret; + + return ret; }} size_t ber_write_contextual_{prefix}{defName}_array(wStream* s, BYTE tag, const {defName}_t* item, size_t nitems) {{ size_t ret; size_t inner = ber_sizeof_{prefix}{defName}_array(item, nitems); - + ret = ber_write_contextual_tag(s, tag, inner, TRUE); ber_write_{prefix}{defName}_array(s, item, nitems); - return ret + inner; + return ret + inner; }} @@ -496,34 +498,34 @@ BOOL ber_read_{prefix}{defName}_array(wStream* s, {defName}_t** pitems, size_t* wStream subStream; {defName}_t* retItems = NULL; size_t ret = 0; - - if (!ber_read_sequence_tag(s, &subLen) || Stream_GetRemainingLength(s) < subLen) + + if (!ber_read_sequence_tag(s, &subLen) || !Stream_CheckAndLogRequiredLength(TAG,s, subLen)) return FALSE; - + Stream_StaticInit(&subStream, Stream_Pointer(s), subLen); - while (Stream_GetRemainingLength(&subStream)) + while (Stream_GetRemainingLength(&subStream)) {{ {defName}_t *item; {defName}_t* tmpRet; - + if (!ber_read_{prefix}{defName}(&subStream, &item)) {{ free(retItems); return FALSE; }} - + tmpRet = realloc(retItems, (ret+1) * sizeof({defName}_t)); - if (!tmpRet) + if (!tmpRet) {{ free(retItems); return FALSE; }} - + memcpy(&retItems[ret], item, sizeof(*item)); free(item); ret++; }} - + *pitems = retItems; *nitems = ret; return TRUE; @@ -531,22 +533,22 @@ BOOL ber_read_{prefix}{defName}_array(wStream* s, {defName}_t** pitems, size_t* '''.format(**h) - + return ret if __name__ == '__main__': opts, extraArgs = getopt.getopt(sys.argv[1:], "hi:o:t:", ['input=', 'output=', 'output-kind=', 'help']) - + ALLOWED_OUTPUTS = ('headers', 'impls',) - + inputStream = sys.stdin outputStream = sys.stdout outputs = ALLOWED_OUTPUTS inputHeaderName = "ASN1_HEADER_H" - headerFileName = "tscredentials.h" - + headerName = "tscredentials" + for option, value in opts: if option in ('-h', '--help',): print("usage: {0} [-i|--input]= [-o|--output]=") @@ -555,42 +557,42 @@ if __name__ == '__main__': print("\t[-t|--output-kind] [header|impl]: the kind of output") elif option in ('-o', '--output',): outputStream = open(value, "w") - + # libfreerdp/core/credssp.c => credssp.h - headerFileName = '.'.join( [os.path.splitext(os.path.basename(value))[0], 'h' ]) + headerName = os.path.splitext(os.path.basename(value))[0] elif option in ('-i', '--input',): inputStream = open(value, "r") - + # libfreerdp/core/credssp.asn1 => LIBFREERDP_CORE_CREDSSP_ASN1_H - inputHeaderName = os.path.normpath(value).replace(os.path.sep, '_').replace('.', '_').upper() + '_H' - - elif option in ('-t', '--output-kind',): + inputHeaderName = os.path.normpath(value).replace(os.path.sep, '_').replace('.', '_').upper() + '_H' + + elif option in ('-t', '--output-kind',): if value not in ALLOWED_OUTPUTS: raise Exception("unknown output kind '{0}'".format(value)) outputs = value else: raise Exception("unknown option {0}".format(option)) - + input = inputStream.read() - + parser = AsnParser() parser.parse(input) - + h = {'programName': os.path.basename(sys.argv[0]), 'cmdLine': ' '.join(sys.argv), 'programPath': sys.argv[0], - 'inputHeaderName': inputHeaderName, 'headerFileName': headerFileName } - + 'inputHeaderName': inputHeaderName, 'headerName': headerName } + outputStream.write('''/* ============================================================================================================ * this file has been generated using * {cmdLine} * - * /!\\ If you want to modify this file you'd probably better change {programName} or the corresponding ASN1 + * /!\\ If you want to modify this file you'd probably better change {programName} or the corresponding ASN1 * definition file * * ============================================================================================================ */ '''.format(**h)) - - if outputs == 'headers': + + if outputs == 'headers': outputStream.write('''#ifndef {inputHeaderName} #define {inputHeaderName} @@ -600,13 +602,17 @@ if __name__ == '__main__': outputStream.write(parser.emitStructDefs()) outputStream.write(parser.emitPrototypes()) outputStream.write('#endif /* {inputHeaderName} */\n'.format(**h)) - + elif outputs == "impls": outputStream.write(''' #include #include -#include "{headerFileName}" +#include "{headerName}.h" + +#include + +#define TAG FREERDP_TAG("core.{headerName}") '''.format(**h)) outputStream.write(parser.emitImpl()) diff --git a/winpr/include/winpr/stream.h b/winpr/include/winpr/stream.h index db2e6ad40..e8ae97ccc 100644 --- a/winpr/include/winpr/stream.h +++ b/winpr/include/winpr/stream.h @@ -61,6 +61,19 @@ extern "C" WINPR_API wStream* Stream_StaticInit(wStream* s, BYTE* buffer, size_t size); WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer); +#define Stream_CheckAndLogRequiredLength(tag, s, len) \ + Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, len, "%s(%s:%" PRIuz ")", __FUNCTION__, \ + __FILE__, __LINE__) + WINPR_API BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s, + UINT64 len, const char* fmt, ...); + WINPR_API BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s, + UINT64 len, const char* fmt, va_list args); + WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s, + UINT64 len, const char* fmt, ...); + WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s, + UINT64 len, const char* fmt, + va_list args); + static INLINE void Stream_Seek(wStream* s, size_t _offset) { WINPR_ASSERT(s); @@ -81,21 +94,27 @@ extern "C" s->pointer = s->buffer; } -#define _stream_read_n8(_t, _s, _v, _p) \ - do \ - { \ - WINPR_ASSERT(_s); \ - WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 1); \ - (_v) = (_t)(*(_s)->pointer); \ - if (_p) \ - Stream_Seek(_s, sizeof(_t)); \ +#define _stream_read_n8(_t, _s, _v, _p) \ + do \ + { \ + WINPR_ASSERT(_s); \ + if (_p) \ + { \ + WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 1); \ + } \ + (_v) = (_t)(*(_s)->pointer); \ + if (_p) \ + Stream_Seek(_s, sizeof(_t)); \ } while (0) #define _stream_read_n16_le(_t, _s, _v, _p) \ do \ { \ WINPR_ASSERT(_s); \ - WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 2); \ + if (_p) \ + { \ + WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 2); \ + } \ (_v) = (_t)((*(_s)->pointer) + (((UINT16)(*((_s)->pointer + 1))) << 8)); \ if (_p) \ Stream_Seek(_s, sizeof(_t)); \ @@ -105,7 +124,10 @@ extern "C" do \ { \ WINPR_ASSERT(_s); \ - WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 2); \ + if (_p) \ + { \ + WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 2); \ + } \ (_v) = (_t)((((UINT16)(*(_s)->pointer)) << 8) + (UINT16)(*((_s)->pointer + 1))); \ if (_p) \ Stream_Seek(_s, sizeof(_t)); \ @@ -115,7 +137,10 @@ extern "C" do \ { \ WINPR_ASSERT(_s); \ - WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 4); \ + if (_p) \ + { \ + WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 4); \ + } \ (_v) = (_t)((UINT32)(*(_s)->pointer) + (((UINT32)(*((_s)->pointer + 1))) << 8) + \ (((UINT32)(*((_s)->pointer + 2))) << 16) + \ ((((UINT32) * ((_s)->pointer + 3))) << 24)); \ @@ -127,7 +152,10 @@ extern "C" do \ { \ WINPR_ASSERT(_s); \ - WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 4); \ + if (_p) \ + { \ + WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 4); \ + } \ (_v) = (_t)(((((UINT32) * ((_s)->pointer))) << 24) + \ (((UINT32)(*((_s)->pointer + 1))) << 16) + \ (((UINT32)(*((_s)->pointer + 2))) << 8) + (((UINT32)(*((_s)->pointer + 3))))); \ @@ -139,7 +167,10 @@ extern "C" do \ { \ WINPR_ASSERT(_s); \ - WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 8); \ + if (_p) \ + { \ + WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 8); \ + } \ (_v) = (_t)((UINT64)(*(_s)->pointer) + (((UINT64)(*((_s)->pointer + 1))) << 8) + \ (((UINT64)(*((_s)->pointer + 2))) << 16) + \ (((UINT64)(*((_s)->pointer + 3))) << 24) + \ @@ -155,7 +186,10 @@ extern "C" do \ { \ WINPR_ASSERT(_s); \ - WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 8); \ + if (_p) \ + { \ + WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 8); \ + } \ (_v) = \ (_t)((((UINT64)(*((_s)->pointer))) << 56) + (((UINT64)(*((_s)->pointer + 1))) << 48) + \ (((UINT64)(*((_s)->pointer + 2))) << 40) + \ @@ -279,6 +313,7 @@ extern "C" static INLINE void Stream_Write_UINT32_BE(wStream* _s, UINT32 _v) { + WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4); Stream_Write_UINT16_BE(_s, ((_v) >> 16 & 0xFFFF)); Stream_Write_UINT16_BE(_s, ((_v)&0xFFFF)); } diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c index 967e5d292..b97478b95 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -78,12 +78,8 @@ BOOL ntlm_read_version_info(wStream* s, NTLM_VERSION_INFO* versionInfo) WINPR_ASSERT(s); WINPR_ASSERT(versionInfo); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "NTLM_VERSION_INFO short header %" PRIuz ", expected %" PRIuz, - Stream_GetRemainingLength(s), 8); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; - } Stream_Read_UINT8(s, versionInfo->ProductMajorVersion); /* ProductMajorVersion (1 byte) */ Stream_Read_UINT8(s, versionInfo->ProductMinorVersion); /* ProductMinorVersion (1 byte) */ @@ -145,12 +141,8 @@ static BOOL ntlm_read_ntlm_v2_client_challenge(wStream* s, NTLMv2_CLIENT_CHALLEN WINPR_ASSERT(s); WINPR_ASSERT(challenge); - if (Stream_GetRemainingLength(s) < 28) - { - WLog_ERR(TAG, "NTLMv2_CLIENT_CHALLENGE expected 28bytes, got %" PRIuz "bytes", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 28)) return FALSE; - } Stream_Read_UINT8(s, challenge->RespType); Stream_Read_UINT8(s, challenge->HiRespType); @@ -203,13 +195,10 @@ static BOOL ntlm_write_ntlm_v2_client_challenge(wStream* s, Stream_Write(s, challenge->ClientChallenge, 8); Stream_Write_UINT32(s, challenge->Reserved3); length = ntlm_av_pair_list_length(challenge->AvPairs, challenge->cbAvPairs); - if (Stream_GetRemainingCapacity(s) < length) - { - WLog_ERR(TAG, - "NTLMv2_CLIENT_CHALLENGE::AvPairs expected %" PRIu32 "bytes, have %" PRIuz "bytes", - length, Stream_GetRemainingCapacity(s)); + + if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) return FALSE; - } + Stream_Write(s, challenge->AvPairs, length); return TRUE; } @@ -219,13 +208,9 @@ BOOL ntlm_read_ntlm_v2_response(wStream* s, NTLMv2_RESPONSE* response) WINPR_ASSERT(s); WINPR_ASSERT(response); - if (Stream_GetRemainingLength(s) < 16) - { - WLog_ERR(TAG, "NTLMv2_RESPONSE expected 16bytes, have %" PRIuz "bytes", - Stream_GetRemainingLength(s)); - + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) return FALSE; - } + Stream_Read(s, response->Response, 16); return ntlm_read_ntlm_v2_client_challenge(s, &(response->Challenge)); } diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_message.c b/winpr/libwinpr/sspi/NTLM/ntlm_message.c index 027ec2929..2a961d505 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_message.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_message.c @@ -244,12 +244,8 @@ static BOOL ntlm_read_message_header(wStream* s, NTLM_MESSAGE_HEADER* header, UI WINPR_ASSERT(s); WINPR_ASSERT(header); - if (Stream_GetRemainingLength(s) < 12) - { - WLog_ERR(TAG, "Short NTLM_MESSAGE_HEADER::header %" PRIuz ", expected 12", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) return FALSE; - } Stream_Read(s, header->Signature, 8); Stream_Read_UINT32(s, header->MessageType); @@ -303,12 +299,8 @@ static BOOL ntlm_read_message_fields(wStream* s, NTLM_MESSAGE_FIELDS* fields) WINPR_ASSERT(s); WINPR_ASSERT(fields); - if (Stream_GetRemainingLength(s) < 8) - { - WLog_ERR(TAG, "Short NTLM_MESSAGE_FIELDS::header %" PRIuz ", expected %" PRIuz, - Stream_GetRemainingLength(s), 8); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return FALSE; - } ntlm_free_message_fields_buffer(fields); @@ -424,12 +416,8 @@ static BOOL ntlm_read_negotiate_flags(wStream* s, UINT32* flags, UINT32 required WINPR_ASSERT(flags); WINPR_ASSERT(name); - if (Stream_GetRemainingLength(s) < 4) - { - WLog_ERR(TAG, "%s::NegotiateFlags expected 4bytes, have %" PRIuz "bytes", name, - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) return FALSE; - } Stream_Read_UINT32(s, NegotiateFlags); /* NegotiateFlags (4 bytes) */ @@ -475,14 +463,8 @@ static BOOL ntlm_read_message_integrity_check(wStream* s, size_t* offset, BYTE* *offset = Stream_GetPosition(s); - if (Stream_GetRemainingLength(s) < size) - { - WLog_ERR(TAG, - "%s::MessageIntegrityCheckOffset expected %" PRIuz "bytes, got " - "%" PRIuz "byets", - name, size, Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, size)) return FALSE; - } Stream_Read(s, data, size); return TRUE; @@ -724,13 +706,8 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf context->NegotiateFlags = message->NegotiateFlags; - if (Stream_GetRemainingLength(s) < 16) - { - WLog_ERR(TAG, - "NTLM_CHALLENGE_MESSAGE::ServerChallenge expected 16bytes, got %" PRIuz "bytes", - Stream_GetRemainingLength(s)); + if (!Stream_CheckAndLogRequiredLength(TAG, s, 16)) goto fail; - } Stream_Read(s, message->ServerChallenge, 8); /* ServerChallenge (8 bytes) */ CopyMemory(context->ServerChallenge, message->ServerChallenge, 8); diff --git a/winpr/libwinpr/utils/image.c b/winpr/libwinpr/utils/image.c index 78f76880a..4cb2e57c2 100644 --- a/winpr/libwinpr/utils/image.c +++ b/winpr/libwinpr/utils/image.c @@ -49,7 +49,7 @@ static BOOL writeBitmapFileHeader(wStream* s, const WINPR_BITMAP_FILE_HEADER* bf static BOOL readBitmapFileHeader(wStream* s, WINPR_BITMAP_FILE_HEADER* bf) { - if (!s || !bf || (Stream_GetRemainingLength(s) < sizeof(WINPR_BITMAP_FILE_HEADER))) + if (!s || !bf || (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(WINPR_BITMAP_FILE_HEADER)))) return FALSE; Stream_Read_UINT8(s, bf->bfType[0]); @@ -82,7 +82,7 @@ static BOOL writeBitmapInfoHeader(wStream* s, const WINPR_BITMAP_INFO_HEADER* bi static BOOL readBitmapInfoHeader(wStream* s, WINPR_BITMAP_INFO_HEADER* bi) { - if (!s || !bi || (Stream_GetRemainingLength(s) < sizeof(WINPR_BITMAP_INFO_HEADER))) + if (!s || !bi || (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(WINPR_BITMAP_INFO_HEADER)))) return FALSE; Stream_Read_UINT32(s, bi->biSize); diff --git a/winpr/libwinpr/utils/stream.c b/winpr/libwinpr/utils/stream.c index 02a8d950d..a4ad721fe 100644 --- a/winpr/libwinpr/utils/stream.c +++ b/winpr/libwinpr/utils/stream.c @@ -314,3 +314,68 @@ BOOL Stream_Read_UTF16_String(wStream* s, WCHAR* dst, size_t length) return TRUE; } + +BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s, UINT64 len, + const char* fmt, ...) +{ + const size_t actual = Stream_GetRemainingLength(s); + + if (actual < len) + { + va_list args; + + va_start(args, fmt); + Stream_CheckAndLogRequiredLengthExVa(tag, level, s, len, fmt, args); + va_end(args); + + return FALSE; + } + return TRUE; +} + +BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s, UINT64 len, + const char* fmt, va_list args) +{ + const size_t actual = Stream_GetRemainingLength(s); + + if (actual < len) + return Stream_CheckAndLogRequiredLengthWLogExVa(WLog_Get(tag), level, s, len, fmt, args); + return TRUE; +} + +BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s, UINT64 len, + const char* fmt, ...) +{ + const size_t actual = Stream_GetRemainingLength(s); + + if (actual < len) + { + va_list args; + + va_start(args, fmt); + Stream_CheckAndLogRequiredLengthWLogExVa(log, level, s, len, fmt, args); + va_end(args); + + return FALSE; + } + return TRUE; +} + +BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s, UINT64 len, + const char* fmt, va_list args) +{ + const size_t actual = Stream_GetRemainingLength(s); + + if (actual < len) + { + char prefix[1024] = { 0 }; + + vsnprintf(prefix, sizeof(prefix), fmt, args); + + WLog_Print(log, level, "[%s] invalid length, got %" PRIuz ", require at least %" PRIu64, + prefix, actual, len); + winpr_log_backtrace_ex(log, level, 20); + return FALSE; + } + return TRUE; +}