diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index 7c1d988ca..6cc947431 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -468,7 +468,7 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits tile_bitmap = (char*) malloc(32); ZeroMemory(tile_bitmap, 32); - if (surface_bits_command->codecID == CODEC_ID_REMOTEFX) + if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX) { message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); @@ -503,7 +503,7 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits rfx_message_free(rfx_context, message); } - else if (surface_bits_command->codecID == CODEC_ID_NSCODEC) + else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC) { nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index db8414b67..7448577af 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -953,7 +953,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) xfi->rfx_context; NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) xfi->nsc_context; - if (surface_bits_command->codecID == CODEC_ID_REMOTEFX) + if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX) { message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); @@ -990,7 +990,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits XSetClipMask(xfi->display, xfi->gc, None); rfx_message_free(rfx_context, message); } - else if (surface_bits_command->codecID == CODEC_ID_NSCODEC) + else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC) { nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); @@ -1017,7 +1017,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits XSetClipMask(xfi->display, xfi->gc, None); } - else if (surface_bits_command->codecID == CODEC_ID_NONE) + else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE) { XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 024d40c2a..d43a587d1 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -135,10 +135,10 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, switch (codec_id) { - case CODEC_ID_NSCODEC: + case RDP_CODEC_ID_NSCODEC: printf("xf_Bitmap_Decompress: nsc not done\n"); break; - case CODEC_ID_REMOTEFX: + case RDP_CODEC_ID_REMOTEFX: xfi = ((xfContext*)context)->xfi; rfx_context_set_pixel_format(xfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); msg = rfx_process_message(xfi->rfx_context, data, length); @@ -163,7 +163,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, rfx_message_free(xfi->rfx_context, msg); } break; - case CODEC_ID_JPEG: + case RDP_CODEC_ID_JPEG: if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp)) { printf("xf_Bitmap_Decompress: jpeg Decompression Failed\n"); diff --git a/include/freerdp/constants.h b/include/freerdp/constants.h index eb0ba52f0..fb30c64e5 100644 --- a/include/freerdp/constants.h +++ b/include/freerdp/constants.h @@ -25,10 +25,10 @@ */ enum RDP_CODEC_ID { - CODEC_ID_NONE = 0x00, - CODEC_ID_NSCODEC = 0x01, - CODEC_ID_JPEG = 0x02, - CODEC_ID_REMOTEFX = 0x03 + RDP_CODEC_ID_NONE = 0x00, + RDP_CODEC_ID_NSCODEC = 0x01, + RDP_CODEC_ID_JPEG = 0x02, + RDP_CODEC_ID_REMOTEFX = 0x03 }; /** diff --git a/libfreerdp/cache/bitmap.c b/libfreerdp/cache/bitmap.c index 64cf7579a..2ed6bfaa3 100644 --- a/libfreerdp/cache/bitmap.c +++ b/libfreerdp/cache/bitmap.c @@ -83,7 +83,7 @@ void update_gdi_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitm bitmap->Decompress(context, bitmap, cache_bitmap->bitmapDataStream, cache_bitmap->bitmapWidth, cache_bitmap->bitmapHeight, cache_bitmap->bitmapBpp, cache_bitmap->bitmapLength, - cache_bitmap->compressed, CODEC_ID_NONE); + cache_bitmap->compressed, RDP_CODEC_ID_NONE); bitmap->New(context, bitmap); @@ -114,7 +114,7 @@ void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cach bitmap->Decompress(context, bitmap, cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight, cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength, - cache_bitmap_v2->compressed, CODEC_ID_NONE); + cache_bitmap_v2->compressed, RDP_CODEC_ID_NONE); bitmap->New(context, bitmap); @@ -192,7 +192,7 @@ void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap_update) bitmap->Decompress(context, bitmap, bitmap_data->bitmapDataStream, bitmap_data->width, bitmap_data->height, bitmap_data->bitsPerPixel, bitmap_data->bitmapLength, - bitmap_data->compressed, CODEC_ID_NONE); + bitmap_data->compressed, RDP_CODEC_ID_NONE); if (reused) bitmap->Free(context, bitmap); diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index 7e91fb945..101e92a61 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -114,14 +114,17 @@ void rdp_capability_set_finish(STREAM* s, BYTE* header, UINT16 type) * @msdn{cc240549} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_general_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_general_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT16 extraFlags; BYTE refreshRectSupport; BYTE suppressOutputSupport; + if(length < 24) + return FALSE; if (settings->ServerMode) { stream_read_UINT16(s, settings->OsMajorType); /* osMajorType (2 bytes) */ @@ -150,6 +153,7 @@ void rdp_read_general_capability_set(STREAM* s, UINT16 length, rdpSettings* sett if (suppressOutputSupport == FALSE) settings->SuppressOutput = FALSE; + return TRUE; } /** @@ -197,9 +201,10 @@ void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240554} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_bitmap_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_bitmap_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { BYTE drawingFlags; UINT16 desktopWidth; @@ -207,6 +212,8 @@ void rdp_read_bitmap_capability_set(STREAM* s, UINT16 length, rdpSettings* setti UINT16 desktopResizeFlag; UINT16 preferredBitsPerPixel; + if(length < 28) + return FALSE; stream_read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ stream_seek_UINT16(s); /* receive1BitPerPixel (2 bytes) */ stream_seek_UINT16(s); /* receive4BitsPerPixel (2 bytes) */ @@ -236,6 +243,7 @@ void rdp_read_bitmap_capability_set(STREAM* s, UINT16 length, rdpSettings* setti settings->DesktopWidth = desktopWidth; settings->DesktopHeight = desktopHeight; } + return TRUE; } /** @@ -285,15 +293,18 @@ void rdp_write_bitmap_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240556} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_order_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_order_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { int i; UINT16 orderFlags; BYTE orderSupport[32]; UINT16 orderSupportExFlags; + if(length < 88) + return FALSE; stream_seek(s, 16); /* terminalDescriptor (16 bytes) */ stream_seek_UINT32(s); /* pad4OctetsA (4 bytes) */ stream_seek_UINT16(s); /* desktopSaveXGranularity (2 bytes) */ @@ -317,6 +328,14 @@ void rdp_read_order_capability_set(STREAM* s, UINT16 length, rdpSettings* settin if (orderSupport[i] == FALSE) settings->OrderSupport[i] = FALSE; } + + /* pad4octetsB (4 bytes) */ + /* desktopSaveSize (4 bytes) */ + /* pad2octetsC (2 bytes) */ + /* pad2octetsD (2 bytes) */ + /* textANSICodePage (2 bytes) */ + /* pad2octetsE (2 bytes) */ + return TRUE; } /** @@ -379,10 +398,13 @@ void rdp_write_order_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240559} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_bitmap_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_bitmap_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 40) + return FALSE; stream_seek_UINT32(s); /* pad1 (4 bytes) */ stream_seek_UINT32(s); /* pad2 (4 bytes) */ stream_seek_UINT32(s); /* pad3 (4 bytes) */ @@ -395,6 +417,7 @@ void rdp_read_bitmap_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* stream_seek_UINT16(s); /* Cache1MaximumCellSize (2 bytes) */ stream_seek_UINT16(s); /* Cache2Entries (2 bytes) */ stream_seek_UINT16(s); /* Cache2MaximumCellSize (2 bytes) */ + return TRUE; } /** @@ -441,14 +464,18 @@ void rdp_write_bitmap_cache_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240568} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_control_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_control_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 12) + return FALSE; stream_seek_UINT16(s); /* controlFlags (2 bytes) */ stream_seek_UINT16(s); /* remoteDetachFlag (2 bytes) */ stream_seek_UINT16(s); /* controlInterest (2 bytes) */ stream_seek_UINT16(s); /* detachInterest (2 bytes) */ + return TRUE; } /** @@ -477,14 +504,18 @@ void rdp_write_control_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240569} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_window_activation_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_window_activation_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 12) + return FALSE; stream_seek_UINT16(s); /* helpKeyFlag (2 bytes) */ stream_seek_UINT16(s); /* helpKeyIndexFlag (2 bytes) */ stream_seek_UINT16(s); /* helpExtendedKeyFlag (2 bytes) */ stream_seek_UINT16(s); /* windowManagerKeyFlag (2 bytes) */ + return TRUE; } /** @@ -513,14 +544,17 @@ void rdp_write_window_activation_capability_set(STREAM* s, rdpSettings* settings * @msdn{cc240562} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_pointer_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_pointer_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT16 colorPointerFlag; UINT16 colorPointerCacheSize; UINT16 pointerCacheSize; + if(length < 10) + return FALSE; stream_read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ stream_read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ stream_read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ @@ -532,6 +566,7 @@ void rdp_read_pointer_capability_set(STREAM* s, UINT16 length, rdpSettings* sett { settings->PointerCacheSize = pointerCacheSize; } + return TRUE; } /** @@ -566,12 +601,16 @@ void rdp_write_pointer_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240570} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_share_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_share_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 8) + return FALSE; stream_seek_UINT16(s); /* nodeId (2 bytes) */ stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ + return TRUE; } /** @@ -601,12 +640,16 @@ void rdp_write_share_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc241564} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_color_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_color_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 8) + return FALSE; stream_seek_UINT16(s); /* colorTableCacheSize (2 bytes) */ stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ + return TRUE; } /** @@ -633,16 +676,20 @@ void rdp_write_color_cache_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240552} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_sound_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_sound_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT16 soundFlags; + if(length < 8) + return FALSE; stream_read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */ settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) ? TRUE : FALSE; + return TRUE; } /** @@ -672,12 +719,15 @@ void rdp_write_sound_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240563} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_input_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_input_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT16 inputFlags; + if(length < 88) + return FALSE; stream_read_UINT16(s, inputFlags); /* inputFlags (2 bytes) */ stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */ @@ -714,6 +764,7 @@ void rdp_read_input_capability_set(STREAM* s, UINT16 length, rdpSettings* settin settings->FastPathInput = FALSE; } } + return TRUE; } /** @@ -754,15 +805,17 @@ void rdp_write_input_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240571} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_font_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_font_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { if (length > 4) stream_seek_UINT16(s); /* fontSupportFlags (2 bytes) */ if (length > 6) stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ + return TRUE; } /** @@ -789,11 +842,15 @@ void rdp_write_font_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240564} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_brush_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_brush_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 8) + return FALSE; stream_seek_UINT32(s); /* brushSupportLevel (4 bytes) */ + return TRUE; } /** @@ -841,18 +898,22 @@ void rdp_write_cache_definition(STREAM* s, GLYPH_CACHE_DEFINITION* cache_definit * @msdn{cc240565} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_glyph_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_glyph_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT16 glyphSupportLevel; + if(length < 52) + return FALSE; stream_seek(s, 40); /* glyphCache (40 bytes) */ stream_seek_UINT32(s); /* fragCache (4 bytes) */ stream_read_UINT16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */ stream_seek_UINT16(s); /* pad2Octets (2 bytes) */ settings->GlyphSupportLevel = glyphSupportLevel; + return TRUE; } /** @@ -894,18 +955,22 @@ void rdp_write_glyph_cache_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240550} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_offscreen_bitmap_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_offscreen_bitmap_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT32 offscreenSupportLevel; + if(length < 12) + return FALSE; stream_read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ stream_read_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ stream_read_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ if (offscreenSupportLevel & TRUE) settings->OffscreenSupportLevel = TRUE; + return TRUE; } /** @@ -937,18 +1002,22 @@ void rdp_write_offscreen_bitmap_cache_capability_set(STREAM* s, rdpSettings* set * @msdn{cc240557} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_bitmap_cache_host_support_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_bitmap_cache_host_support_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { BYTE cacheVersion; + if(length < 8) + return FALSE; stream_read_BYTE(s, cacheVersion); /* cacheVersion (1 byte) */ stream_seek_BYTE(s); /* pad1 (1 byte) */ stream_seek_UINT16(s); /* pad2 (2 bytes) */ if (cacheVersion & BITMAP_CACHE_V2) settings->BitmapCachePersistEnabled = TRUE; + return TRUE; } /** @@ -989,10 +1058,14 @@ void rdp_write_bitmap_cache_cell_info(STREAM* s, BITMAP_CACHE_V2_CELL_INFO* cell * @msdn{cc240560} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_bitmap_cache_v2_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_bitmap_cache_v2_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 40) + return FALSE; + stream_seek_UINT16(s); /* cacheFlags (2 bytes) */ stream_seek_BYTE(s); /* pad2 (1 byte) */ stream_seek_BYTE(s); /* numCellCaches (1 byte) */ @@ -1002,6 +1075,7 @@ void rdp_read_bitmap_cache_v2_capability_set(STREAM* s, UINT16 length, rdpSettin stream_seek(s, 4); /* bitmapCache3CellInfo (4 bytes) */ stream_seek(s, 4); /* bitmapCache4CellInfo (4 bytes) */ stream_seek(s, 12); /* pad3 (12 bytes) */ + return TRUE; } /** @@ -1041,13 +1115,16 @@ void rdp_write_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240551} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_virtual_channel_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_virtual_channel_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT32 flags; UINT32 VCChunkSize; + if(length < 8) + return FALSE; stream_read_UINT32(s, flags); /* flags (4 bytes) */ if (length > 8) @@ -1057,6 +1134,7 @@ void rdp_read_virtual_channel_capability_set(STREAM* s, UINT16 length, rdpSettin if (settings->ServerMode != TRUE) settings->VirtualChannelChunkSize = VCChunkSize; + return TRUE; } /** @@ -1086,12 +1164,15 @@ void rdp_write_virtual_channel_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc241565} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_draw_nine_grid_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_draw_nine_grid_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT32 drawNineGridSupportLevel; + if(length < 12) + return FALSE; stream_read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ stream_read_UINT16(s, settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ stream_read_UINT16(s, settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ @@ -1099,6 +1180,7 @@ void rdp_read_draw_nine_grid_cache_capability_set(STREAM* s, UINT16 length, rdpS if ((drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED) || (drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED_V2)) settings->DrawNineGridEnabled = TRUE; + return TRUE; } /** @@ -1153,13 +1235,16 @@ void rdp_write_gdiplus_image_cache_properties(STREAM* s, UINT16 oiccs, UINT16 oi * @msdn{cc241566} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_draw_gdiplus_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_draw_gdiplus_cache_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT32 drawGDIPlusSupportLevel; UINT32 drawGdiplusCacheLevel; + if(length < 40) + return FALSE; stream_read_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ stream_seek_UINT32(s); /* GdipVersion (4 bytes) */ stream_read_UINT32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ @@ -1172,6 +1257,7 @@ void rdp_read_draw_gdiplus_cache_capability_set(STREAM* s, UINT16 length, rdpSet if (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) settings->DrawGdiPlusCacheEnabled = TRUE; + return TRUE; } /** @@ -1207,12 +1293,15 @@ void rdp_write_draw_gdiplus_cache_capability_set(STREAM* s, rdpSettings* setting * @msdn{cc242518} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_remote_programs_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_remote_programs_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { UINT32 railSupportLevel; + if(length < 8) + return FALSE; stream_read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ if ((railSupportLevel & RAIL_LEVEL_SUPPORTED) == 0) @@ -1223,6 +1312,7 @@ void rdp_read_remote_programs_capability_set(STREAM* s, UINT16 length, rdpSettin settings->RemoteApplicationMode = FALSE; } } + return TRUE; } /** @@ -1254,13 +1344,18 @@ void rdp_write_remote_programs_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc242564} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_window_list_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_window_list_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 11) + return FALSE; + stream_seek_UINT32(s); /* wndSupportLevel (4 bytes) */ stream_seek_BYTE(s); /* numIconCaches (1 byte) */ stream_seek_UINT16(s); /* numIconCacheEntries (2 bytes) */ + return TRUE; } /** @@ -1291,11 +1386,15 @@ void rdp_write_window_list_capability_set(STREAM* s, rdpSettings* settings) * @msdn{cc240855} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_desktop_composition_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_desktop_composition_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 6) + return FALSE; stream_seek_UINT16(s); /* compDeskSupportLevel (2 bytes) */ + return TRUE; } /** @@ -1324,11 +1423,15 @@ void rdp_write_desktop_composition_capability_set(STREAM* s, rdpSettings* settin * @msdn{cc240649} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_multifragment_update_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_multifragment_update_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 8) + return FALSE; stream_read_UINT32(s, settings->MultifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ + return TRUE; } /** @@ -1354,11 +1457,15 @@ void rdp_write_multifragment_update_capability_set(STREAM* s, rdpSettings* setti * @msdn{cc240650} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_large_pointer_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_large_pointer_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 6) + return FALSE; stream_seek_UINT16(s); /* largePointerSupportFlags (2 bytes) */ + return TRUE; } /** @@ -1387,14 +1494,18 @@ void rdp_write_large_pointer_capability_set(STREAM* s, rdpSettings* settings) * @msdn{dd871563} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_surface_commands_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_surface_commands_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 12) + return FALSE; stream_seek_UINT32(s); /* cmdFlags (4 bytes) */ stream_seek_UINT32(s); /* reserved (4 bytes) */ settings->SurfaceCommandsEnabled = TRUE; + return TRUE; } /** @@ -1426,14 +1537,19 @@ void rdp_write_surface_commands_capability_set(STREAM* s, rdpSettings* settings) * @msdn{dd891377} * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_bitmap_codecs_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_bitmap_codecs_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { BYTE bitmapCodecCount; UINT16 codecPropertiesLength; + UINT16 remainingLength; + if(length < 5) + return FALSE; stream_read_BYTE(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ + remainingLength = length - 5; if (settings->ServerMode) { @@ -1444,6 +1560,8 @@ void rdp_read_bitmap_codecs_capability_set(STREAM* s, UINT16 length, rdpSettings while (bitmapCodecCount > 0) { + if(remainingLength < 19) + return FALSE; if (settings->ServerMode && strncmp((char*) stream_get_tail(s), CODEC_GUID_REMOTEFX, 16) == 0) { stream_seek(s, 16); /* codecGUID (16 bytes) */ @@ -1463,10 +1581,16 @@ void rdp_read_bitmap_codecs_capability_set(STREAM* s, UINT16 length, rdpSettings } stream_read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ + remainingLength -= 19; + if(remainingLength < codecPropertiesLength) + return FALSE; + stream_seek(s, codecPropertiesLength); /* codecProperties */ + remainingLength -= codecPropertiesLength; bitmapCodecCount--; } + return TRUE; } /** @@ -1604,7 +1728,7 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) } else { - stream_write_BYTE(s, CODEC_ID_REMOTEFX); /* codecID */ + stream_write_BYTE(s, RDP_CODEC_ID_REMOTEFX); /* codecID */ rdp_write_rfx_client_capability_container(s, settings); } } @@ -1618,7 +1742,7 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) } else { - stream_write_BYTE(s, CODEC_ID_NSCODEC); /* codecID */ + stream_write_BYTE(s, RDP_CODEC_ID_NSCODEC); /* codecID */ rdp_write_nsc_client_capability_container(s, settings); } } @@ -1632,7 +1756,7 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) } else { - stream_write_BYTE(s, CODEC_ID_JPEG); /* codecID */ + stream_write_BYTE(s, RDP_CODEC_ID_JPEG); /* codecID */ rdp_write_jpeg_client_capability_container(s, settings); } } @@ -1643,10 +1767,14 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) * Read frame acknowledge capability set.\n * @param s stream * @param settings settings + * @return if the operation completed successfully */ -void rdp_read_frame_acknowledge_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_frame_acknowledge_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 8) + return FALSE; + if (settings->ServerMode) { stream_read_UINT32(s, settings->FrameAcknowledge); /* (4 bytes) */ @@ -1655,11 +1783,15 @@ void rdp_read_frame_acknowledge_capability_set(STREAM* s, UINT16 length, rdpSett { stream_seek_UINT32(s); /* (4 bytes) */ } + return TRUE; } -void rdp_read_bitmap_cache_v3_codec_id_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) +BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(STREAM* s, UINT16 length, rdpSettings* settings) { + if(length < 5) + return FALSE; stream_seek_BYTE(s); /* (1 byte) */ + return TRUE; } void rdp_write_bitmap_cache_v3_codec_id_capability_set(STREAM* s, rdpSettings* settings) @@ -1715,119 +1847,148 @@ BOOL rdp_read_capability_sets(STREAM* s, rdpSettings* settings, UINT16 numberCap switch (type) { case CAPSET_TYPE_GENERAL: - rdp_read_general_capability_set(s, length, settings); + if(!rdp_read_general_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_BITMAP: - rdp_read_bitmap_capability_set(s, length, settings); + if(!rdp_read_bitmap_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_ORDER: - rdp_read_order_capability_set(s, length, settings); + if(!rdp_read_order_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_BITMAP_CACHE: - rdp_read_bitmap_cache_capability_set(s, length, settings); + if(!rdp_read_bitmap_cache_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_CONTROL: - rdp_read_control_capability_set(s, length, settings); + if(!rdp_read_control_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_ACTIVATION: - rdp_read_window_activation_capability_set(s, length, settings); + if(!rdp_read_window_activation_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_POINTER: - rdp_read_pointer_capability_set(s, length, settings); + if(!rdp_read_pointer_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_SHARE: - rdp_read_share_capability_set(s, length, settings); + if(!rdp_read_share_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_COLOR_CACHE: - rdp_read_color_cache_capability_set(s, length, settings); + if(!rdp_read_color_cache_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_SOUND: - rdp_read_sound_capability_set(s, length, settings); + if(!rdp_read_sound_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_INPUT: - rdp_read_input_capability_set(s, length, settings); + if(!rdp_read_input_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_FONT: - rdp_read_font_capability_set(s, length, settings); + if(!rdp_read_font_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_BRUSH: - rdp_read_brush_capability_set(s, length, settings); + if(!rdp_read_brush_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_GLYPH_CACHE: - rdp_read_glyph_cache_capability_set(s, length, settings); + if(!rdp_read_glyph_cache_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_OFFSCREEN_CACHE: - rdp_read_offscreen_bitmap_cache_capability_set(s, length, settings); + if(!rdp_read_offscreen_bitmap_cache_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT: - rdp_read_bitmap_cache_host_support_capability_set(s, length, settings); + if(!rdp_read_bitmap_cache_host_support_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_BITMAP_CACHE_V2: - rdp_read_bitmap_cache_v2_capability_set(s, length, settings); + if(!rdp_read_bitmap_cache_v2_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_VIRTUAL_CHANNEL: - rdp_read_virtual_channel_capability_set(s, length, settings); + if(!rdp_read_virtual_channel_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_DRAW_NINE_GRID_CACHE: - rdp_read_draw_nine_grid_cache_capability_set(s, length, settings); + if(!rdp_read_draw_nine_grid_cache_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_DRAW_GDI_PLUS: - rdp_read_draw_gdiplus_cache_capability_set(s, length, settings); + if(!rdp_read_draw_gdiplus_cache_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_RAIL: - rdp_read_remote_programs_capability_set(s, length, settings); + if(!rdp_read_remote_programs_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_WINDOW: - rdp_read_window_list_capability_set(s, length, settings); + if(!rdp_read_window_list_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_COMP_DESK: - rdp_read_desktop_composition_capability_set(s, length, settings); + if(!rdp_read_desktop_composition_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE: - rdp_read_multifragment_update_capability_set(s, length, settings); + if(!rdp_read_multifragment_update_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_LARGE_POINTER: - rdp_read_large_pointer_capability_set(s, length, settings); + if(!rdp_read_large_pointer_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_SURFACE_COMMANDS: - rdp_read_surface_commands_capability_set(s, length, settings); + if(!rdp_read_surface_commands_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_BITMAP_CODECS: - rdp_read_bitmap_codecs_capability_set(s, length, settings); + if(!rdp_read_bitmap_codecs_capability_set(s, length, settings)) + return FALSE; break; case CAPSET_TYPE_FRAME_ACKNOWLEDGE: - rdp_read_frame_acknowledge_capability_set(s, length, settings); + if(!rdp_read_frame_acknowledge_capability_set(s, length, settings)) + return FALSE; break; - case 6: - rdp_read_bitmap_cache_v3_codec_id_capability_set(s, length, settings); + case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID: + if(!rdp_read_bitmap_cache_v3_codec_id_capability_set(s, length, settings)) + return FALSE; break; default: @@ -1868,7 +2029,9 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, STREAM* s) if (rdp->settings->DisableEncryption) { - rdp_read_security_header(s, &securityFlags); + if (!rdp_read_security_header(s, &securityFlags)) + return FALSE; + if (securityFlags & SEC_ENCRYPT) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) @@ -1899,9 +2062,13 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, STREAM* s) return FALSE; } + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ stream_read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ stream_read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + if (!stream_skip(lengthSourceDescriptor) || stream_get_left(s) < 4) + return FALSE; stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */ stream_read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ stream_seek(s, 2); /* pad2Octets (2 bytes) */ @@ -2003,7 +2170,8 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s) if (rdp->settings->DisableEncryption) { - rdp_read_security_header(s, &securityFlags); + if (!rdp_read_security_header(s, &securityFlags)) + return FALSE; if (securityFlags & SEC_ENCRYPT) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) @@ -2025,18 +2193,19 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s) if (pduType != PDU_TYPE_CONFIRM_ACTIVE) return FALSE; + if(stream_get_left(s) < 10) + return FALSE; stream_seek_UINT32(s); /* shareId (4 bytes) */ stream_seek_UINT16(s); /* originatorId (2 bytes) */ stream_read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ stream_read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + if(stream_get_left(s) < lengthSourceDescriptor+4) + return FALSE; stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */ stream_read_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ stream_seek(s, 2); /* pad2Octets (2 bytes) */ - if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities)) - return FALSE; - - return TRUE; + return rdp_read_capability_sets(s, rdp->settings, numberCapabilities); } void rdp_write_confirm_active(STREAM* s, rdpSettings* settings) diff --git a/libfreerdp/core/certificate.c b/libfreerdp/core/certificate.c index fa664ea10..7984faf7c 100644 --- a/libfreerdp/core/certificate.c +++ b/libfreerdp/core/certificate.c @@ -129,7 +129,7 @@ * @param cert X.509 certificate */ -void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info) +BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info) { STREAM* s; int length; @@ -141,73 +141,104 @@ void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info) s = stream_new(0); stream_attach(s, cert->data, cert->length); - ber_read_sequence_tag(s, &length); /* Certificate (SEQUENCE) */ + if(!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */ + goto error1; - ber_read_sequence_tag(s, &length); /* TBSCertificate (SEQUENCE) */ + if(!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */ + goto error1; /* Explicit Contextual Tag [0] */ - ber_read_contextual_tag(s, 0, &length, TRUE); - ber_read_integer(s, &version); /* version (INTEGER) */ + if(!ber_read_contextual_tag(s, 0, &length, TRUE)) + goto error1; + if(!ber_read_integer(s, &version)) /* version (INTEGER) */ + goto error1; version++; /* serialNumber */ - ber_read_integer(s, NULL); /* CertificateSerialNumber (INTEGER) */ + if(!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */ + goto error1; /* signature */ - ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */ + if(!ber_read_sequence_tag(s, &length) || stream_get_left(s) < length) /* AlgorithmIdentifier (SEQUENCE) */ + goto error1; stream_seek(s, length); /* issuer */ - ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */ + if(!ber_read_sequence_tag(s, &length) || stream_get_left(s) < length) /* Name (SEQUENCE) */ + goto error1; stream_seek(s, length); /* validity */ - ber_read_sequence_tag(s, &length); /* Validity (SEQUENCE) */ + if(!ber_read_sequence_tag(s, &length) || stream_get_left(s) < length) /* Validity (SEQUENCE) */ + goto error1; stream_seek(s, length); /* subject */ - ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */ + if(!ber_read_sequence_tag(s, &length) || stream_get_left(s) < length) /* Name (SEQUENCE) */ + goto error1; stream_seek(s, length); /* subjectPublicKeyInfo */ - ber_read_sequence_tag(s, &length); /* SubjectPublicKeyInfo (SEQUENCE) */ + if(!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */ + goto error1; /* subjectPublicKeyInfo::AlgorithmIdentifier */ - ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */ + if(!ber_read_sequence_tag(s, &length) || stream_get_left(s) < length) /* AlgorithmIdentifier (SEQUENCE) */ + goto error1; stream_seek(s, length); /* subjectPublicKeyInfo::subjectPublicKey */ - ber_read_bit_string(s, &length, &padding); /* BIT_STRING */ + if(!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */ + goto error1; /* RSAPublicKey (SEQUENCE) */ - ber_read_sequence_tag(s, &length); /* SEQUENCE */ + if(!ber_read_sequence_tag(s, &length)) /* SEQUENCE */ + goto error1; - ber_read_integer_length(s, &modulus_length); /* modulus (INTEGER) */ + if(!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */ + goto error1; /* skip zero padding, if any */ do { + if(stream_get_left(s) < padding) + goto error1; stream_peek_BYTE(s, padding); if (padding == 0) { + if(stream_get_left(s) < 1) + goto error1; stream_seek(s, 1); modulus_length--; } } while (padding == 0); + if(stream_get_left(s) < modulus_length) + goto error1; info->ModulusLength = modulus_length; info->Modulus = (BYTE*) malloc(info->ModulusLength); stream_read(s, info->Modulus, info->ModulusLength); - ber_read_integer_length(s, &exponent_length); /* publicExponent (INTEGER) */ + if(!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */ + goto error2; + if(stream_get_left(s) < exponent_length) + goto error2; stream_read(s, &info->exponent[4 - exponent_length], exponent_length); crypto_reverse(info->Modulus, info->ModulusLength); crypto_reverse(info->exponent, 4); stream_detach(s); stream_free(s); + return TRUE; + +error2: + free(info->Modulus); +error1: + stream_detach(s); + stream_free(s); + return FALSE; } /** @@ -259,6 +290,8 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, S UINT32 datalen; UINT32 modlen; + if(stream_get_left(s) < 20) + return FALSE; stream_read(s, magic, 4); if (memcmp(magic, "RSA1", 4) != 0) @@ -273,6 +306,8 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, S stream_read(s, certificate->cert_info.exponent, 4); modlen = keylen - 8; + if(stream_get_left(s) < modlen + 8) + return FALSE; certificate->cert_info.ModulusLength = modlen; certificate->cert_info.Modulus = malloc(certificate->cert_info.ModulusLength); stream_read(s, certificate->cert_info.Modulus, certificate->cert_info.ModulusLength); @@ -354,6 +389,9 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate BYTE* sigdata; int sigdatalen; + if(stream_get_left(s) < 12) + return FALSE; + /* -4, because we need to include dwVersion */ sigdata = stream_get_tail(s) - 4; stream_read_UINT32(s, dwSigAlgId); @@ -374,6 +412,8 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate } stream_read_UINT16(s, wPublicKeyBlobLen); + if(stream_get_left(s) < wPublicKeyBlobLen) + return FALSE; if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen)) { @@ -381,6 +421,9 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate return FALSE; } + if(stream_get_left(s) < 4) + return FALSE; + sigdatalen = stream_get_tail(s) - sigdata; stream_read_UINT16(s, wSignatureBlobType); @@ -391,6 +434,8 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate } stream_read_UINT16(s, wSignatureBlobLen); + if(stream_get_left(s) < wSignatureBlobLen) + return FALSE; if (wSignatureBlobLen != 72) { @@ -421,13 +466,19 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, DEBUG_CERTIFICATE("Server X.509 Certificate Chain"); + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, numCertBlobs); /* numCertBlobs */ certificate->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs); for (i = 0; i < (int) numCertBlobs; i++) { + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, certLength); + if(stream_get_left(s) < certLength) + return FALSE; DEBUG_CERTIFICATE("\nX.509 Certificate #%d, length:%d", i + 1, certLength); @@ -465,6 +516,7 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serv { STREAM* s; UINT32 dwVersion; + BOOL ret = TRUE; if (length < 1) { @@ -472,6 +524,9 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serv return FALSE; } + if (length < 4) + return FALSE; + s = stream_new(0); stream_attach(s, server_cert, length); @@ -480,11 +535,11 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serv switch (dwVersion & CERT_CHAIN_VERSION_MASK) { case CERT_CHAIN_VERSION_1: - certificate_read_server_proprietary_certificate(certificate, s); + ret = certificate_read_server_proprietary_certificate(certificate, s); break; case CERT_CHAIN_VERSION_2: - certificate_read_server_x509_certificate_chain(certificate, s); + ret = certificate_read_server_x509_certificate_chain(certificate, s); break; default: @@ -493,7 +548,7 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serv } free(s); - return TRUE; + return ret; } rdpRsaKey* key_new(const char* keyfile) diff --git a/libfreerdp/core/certificate.h b/libfreerdp/core/certificate.h index c92c74b76..7a178c842 100644 --- a/libfreerdp/core/certificate.h +++ b/libfreerdp/core/certificate.h @@ -42,7 +42,7 @@ #define BB_RSA_KEY_BLOB 6 #define BB_RSA_SIGNATURE_BLOB 8 -void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info); +BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info); rdpX509CertChain* certificate_new_x509_certificate_chain(UINT32 count); void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain); diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 848bfd6ed..fb1319dd6 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -162,31 +162,36 @@ static BOOL fastpath_recv_orders(rdpFastPath* fastpath, STREAM* s) return TRUE; } -static void fastpath_recv_update_common(rdpFastPath* fastpath, STREAM* s) +static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, STREAM* s) { UINT16 updateType; rdpUpdate* update = fastpath->rdp->update; rdpContext* context = update->context; + if(stream_get_left(s) < 2) + return FALSE; stream_read_UINT16(s, updateType); /* updateType (2 bytes) */ switch (updateType) { case UPDATE_TYPE_BITMAP: - update_read_bitmap(update, s, &update->bitmap_update); + if(!update_read_bitmap(update, s, &update->bitmap_update)) + return FALSE; IFCALL(update->BitmapUpdate, context, &update->bitmap_update); break; case UPDATE_TYPE_PALETTE: - update_read_palette(update, s, &update->palette_update); + if(!update_read_palette(update, s, &update->palette_update)) + return FALSE; IFCALL(update->Palette, context, &update->palette_update); break; } + return TRUE; } -static void fastpath_recv_update_synchronize(rdpFastPath* fastpath, STREAM* s) +static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, STREAM* s) { - stream_seek_UINT16(s); /* size (2 bytes), must be set to zero */ + return stream_skip(s, 2); /* size (2 bytes), MUST be set to zero */ } static BOOL fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 size, STREAM* s) @@ -209,16 +214,17 @@ static BOOL fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 case FASTPATH_UPDATETYPE_BITMAP: case FASTPATH_UPDATETYPE_PALETTE: - fastpath_recv_update_common(fastpath, s); - break; + return fastpath_recv_update_common(fastpath, s); case FASTPATH_UPDATETYPE_SYNCHRONIZE: - fastpath_recv_update_synchronize(fastpath, s); + if (!fastpath_recv_update_synchronize(fastpath, s)) + return FALSE; IFCALL(update->Synchronize, context); break; case FASTPATH_UPDATETYPE_SURFCMDS: - update_recv_surfcmds(update, size, s); + if (!update_recv_surfcmds(update, size, s)) + return FALSE; break; case FASTPATH_UPDATETYPE_PTR_NULL: @@ -232,17 +238,20 @@ static BOOL fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 break; case FASTPATH_UPDATETYPE_PTR_POSITION: - update_read_pointer_position(s, &pointer->pointer_position); + if (!update_read_pointer_position(s, &pointer->pointer_position)) + return FALSE; IFCALL(pointer->PointerPosition, context, &pointer->pointer_position); break; case FASTPATH_UPDATETYPE_COLOR: - update_read_pointer_color(s, &pointer->pointer_color); + if (!update_read_pointer_color(s, &pointer->pointer_color)) + return FALSE; IFCALL(pointer->PointerColor, context, &pointer->pointer_color); break; case FASTPATH_UPDATETYPE_CACHED: - update_read_pointer_cached(s, &pointer->pointer_cached); + if (!update_read_pointer_cached(s, &pointer->pointer_cached)) + return FALSE; IFCALL(pointer->PointerCached, context, &pointer->pointer_cached); break; diff --git a/libfreerdp/core/input.c b/libfreerdp/core/input.c index 38d9f593d..d486069fb 100644 --- a/libfreerdp/core/input.c +++ b/libfreerdp/core/input.c @@ -300,7 +300,7 @@ static BOOL input_recv_event(rdpInput* input, STREAM* s) { UINT16 messageType; - if (stream_get_left(s) < 4) + if (stream_get_left(s) < 6) return FALSE; stream_seek(s, 4); /* eventTime (4 bytes), ignored by the server */ diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index ad2f52ac5..807e1e9ec 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -81,14 +81,18 @@ static const char* const state_transitions[] = * @param bMsgType license message type * @param flags message flags * @param wMsgSize message size + * @return if the operation completed successfully */ -void license_read_preamble(STREAM* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsgSize) +BOOL license_read_preamble(STREAM* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsgSize) { /* preamble (4 bytes) */ + if(stream_get_left(s) < 4) + return FALSE; stream_read_BYTE(s, *bMsgType); /* bMsgType (1 byte) */ stream_read_BYTE(s, *flags); /* flags (1 byte) */ stream_read_UINT16(s, *wMsgSize); /* wMsgSize (2 bytes) */ + return TRUE; } /** @@ -170,6 +174,7 @@ BOOL license_send(rdpLicense* license, STREAM* s, BYTE type) * @msdn{cc240479} * @param license license module * @param s stream + * @return if the operation completed successfully */ BOOL license_recv(rdpLicense* license, STREAM* s) @@ -187,7 +192,8 @@ BOOL license_recv(rdpLicense* license, STREAM* s) return FALSE; } - rdp_read_security_header(s, &sec_flags); + if(!rdp_read_security_header(s, &sec_flags)) + return FALSE; if (!(sec_flags & SEC_LICENSE_PKT)) { stream_rewind(s, RDP_SECURITY_HEADER_LENGTH); @@ -199,7 +205,8 @@ BOOL license_recv(rdpLicense* license, STREAM* s) return TRUE; } - license_read_preamble(s, &bMsgType, &flags, &wMsgSize); /* preamble (4 bytes) */ + if(!license_read_preamble(s, &bMsgType, &flags, &wMsgSize)) /* preamble (4 bytes) */ + return FALSE; DEBUG_LICENSE("Receiving %s Packet", LICENSE_MESSAGE_STRINGS[bMsgType & 0x1F]); @@ -386,19 +393,30 @@ void license_decrypt_platform_challenge(rdpLicense* license) * @param productInfo product information */ -void license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo) +BOOL license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo) { + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */ stream_read_UINT32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */ + if(stream_get_left(s) < productInfo->cbCompanyName + 4) + return FALSE; productInfo->pbCompanyName = (BYTE*) malloc(productInfo->cbCompanyName); stream_read(s, productInfo->pbCompanyName, productInfo->cbCompanyName); stream_read_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */ + if(stream_get_left(s) < productInfo->cbProductId) + { + free(productInfo->pbCompanyName); + productInfo->pbCompanyName = NULL; + return FALSE; + } productInfo->pbProductId = (BYTE*) malloc(productInfo->cbProductId); stream_read(s, productInfo->pbProductId, productInfo->cbProductId); + return TRUE; } /** @@ -446,19 +464,24 @@ void license_free_product_info(PRODUCT_INFO* productInfo) * @param blob license binary blob */ -void license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob) +BOOL license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob) { UINT16 wBlobType; + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT16(s, wBlobType); /* wBlobType (2 bytes) */ stream_read_UINT16(s, blob->length); /* wBlobLen (2 bytes) */ + if(stream_get_left(s) < blob->length) + return FALSE; + /* * Server can choose to not send data by setting len to 0. * If so, it may not bother to set the type, so shortcut the warning */ if (blob->type != BB_ANY_BLOB && blob->length == 0) - return; + return TRUE; if (blob->type != wBlobType && blob->type != BB_ANY_BLOB) { @@ -469,6 +492,7 @@ void license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob) blob->data = (BYTE*) malloc(blob->length); stream_read(s, blob->data, blob->length); /* blobData */ + return TRUE; } /** @@ -540,11 +564,13 @@ void license_free_binary_blob(LICENSE_BLOB* blob) * @param scopeList scope list */ -void license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList) +BOOL license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList) { UINT32 i; UINT32 scopeCount; + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, scopeCount); /* ScopeCount (4 bytes) */ scopeList->count = scopeCount; @@ -554,8 +580,10 @@ void license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList) for (i = 0; i < scopeCount; i++) { scopeList->array[i].type = BB_SCOPE_BLOB; - license_read_binary_blob(s, &scopeList->array[i]); + if(!license_read_binary_blob(s, &scopeList->array[i])) + return FALSE; } + return TRUE; } /** @@ -608,9 +636,11 @@ void license_free_scope_list(SCOPE_LIST* scopeList) * @param s stream */ -void license_read_license_request_packet(rdpLicense* license, STREAM* s) +BOOL license_read_license_request_packet(rdpLicense* license, STREAM* s) { /* ServerRandom (32 bytes) */ + if(stream_get_left(s) < 32) + return FALSE; stream_read(s, license->server_random, 32); /* ProductInfo */ @@ -632,6 +662,7 @@ void license_read_license_request_packet(rdpLicense* license, STREAM* s) license_generate_keys(license); license_generate_hwid(license); license_encrypt_premaster_secret(license); + return TRUE; } /** @@ -641,10 +672,11 @@ void license_read_license_request_packet(rdpLicense* license, STREAM* s) * @param s stream */ -void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s) +BOOL license_read_platform_challenge_packet(rdpLicense* license, STREAM* s) { DEBUG_LICENSE("Receiving Platform Challenge Packet"); - + if(stream_get_left(s) < 4) + return FALSE; stream_seek(s, 4); /* ConnectFlags, Reserved (4 bytes) */ /* EncryptedPlatformChallenge */ @@ -653,9 +685,12 @@ void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s) license->encrypted_platform_challenge->type = BB_ENCRYPTED_DATA_BLOB; /* MACData (16 bytes) */ + if(stream_get_left(s) < 16) + return FALSE; stream_seek(s, 16); license_decrypt_platform_challenge(license); + return TRUE; } /** @@ -691,14 +726,17 @@ void license_read_upgrade_license_packet(rdpLicense* license, STREAM* s) * @param s stream */ -void license_read_error_alert_packet(rdpLicense* license, STREAM* s) +BOOL license_read_error_alert_packet(rdpLicense* license, STREAM* s) { UINT32 dwErrorCode; UINT32 dwStateTransition; + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT32(s, dwErrorCode); /* dwErrorCode (4 bytes) */ stream_read_UINT32(s, dwStateTransition); /* dwStateTransition (4 bytes) */ - license_read_binary_blob(s, license->error_info); /* bbErrorInfo */ + if(!license_read_binary_blob(s, license->error_info)) /* bbErrorInfo */ + return FALSE; #ifdef WITH_DEBUG_LICENSE printf("dwErrorCode: %s, dwStateTransition: %s\n", @@ -708,7 +746,7 @@ void license_read_error_alert_packet(rdpLicense* license, STREAM* s) if (dwErrorCode == STATUS_VALID_CLIENT) { license->state = LICENSE_STATE_COMPLETED; - return; + return TRUE; } switch (dwStateTransition) @@ -731,6 +769,7 @@ void license_read_error_alert_packet(rdpLicense* license, STREAM* s) default: break; } + return TRUE; } /** diff --git a/libfreerdp/core/license.h b/libfreerdp/core/license.h index 2ce31a93a..3a03cca75 100644 --- a/libfreerdp/core/license.h +++ b/libfreerdp/core/license.h @@ -168,22 +168,22 @@ void license_decrypt_platform_challenge(rdpLicense* license); PRODUCT_INFO* license_new_product_info(); void license_free_product_info(PRODUCT_INFO* productInfo); -void license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo); +BOOL license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo); LICENSE_BLOB* license_new_binary_blob(UINT16 type); void license_free_binary_blob(LICENSE_BLOB* blob); -void license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob); +BOOL license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob); void license_write_binary_blob(STREAM* s, LICENSE_BLOB* blob); SCOPE_LIST* license_new_scope_list(); void license_free_scope_list(SCOPE_LIST* scopeList); -void license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList); +BOOL license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList); -void license_read_license_request_packet(rdpLicense* license, STREAM* s); -void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s); +BOOL license_read_license_request_packet(rdpLicense* license, STREAM* s); +BOOL license_read_platform_challenge_packet(rdpLicense* license, STREAM* s); void license_read_new_license_packet(rdpLicense* license, STREAM* s); void license_read_upgrade_license_packet(rdpLicense* license, STREAM* s); -void license_read_error_alert_packet(rdpLicense* license, STREAM* s); +BOOL license_read_error_alert_packet(rdpLicense* license, STREAM* s); void license_write_new_license_request_packet(rdpLicense* license, STREAM* s); void license_send_new_license_request_packet(rdpLicense* license); diff --git a/libfreerdp/core/mcs.c b/libfreerdp/core/mcs.c index f26f1ccbc..8ca2ccf4e 100644 --- a/libfreerdp/core/mcs.c +++ b/libfreerdp/core/mcs.c @@ -195,14 +195,16 @@ BOOL mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU, U { BYTE choice; enum DomainMCSPDU MCSPDU; + UINT16 li; *length = tpkt_read_header(s); - if (tpdu_read_data(s) == 0) + if (!tpdu_read_data(s, &li)) return FALSE; MCSPDU = *domainMCSPDU; - per_read_choice(s, &choice); + if(!per_read_choice(s, &choice)) + return FALSE; *domainMCSPDU = (choice >> 2); if (*domainMCSPDU != MCSPDU) @@ -257,17 +259,16 @@ static void mcs_init_domain_parameters(DomainParameters* domainParameters, BOOL mcs_read_domain_parameters(STREAM* s, DomainParameters* domainParameters) { int length; - ber_read_sequence_tag(s, &length); - ber_read_integer(s, &(domainParameters->maxChannelIds)); - ber_read_integer(s, &(domainParameters->maxUserIds)); - ber_read_integer(s, &(domainParameters->maxTokenIds)); - ber_read_integer(s, &(domainParameters->numPriorities)); - ber_read_integer(s, &(domainParameters->minThroughput)); - ber_read_integer(s, &(domainParameters->maxHeight)); - ber_read_integer(s, &(domainParameters->maxMCSPDUsize)); - ber_read_integer(s, &(domainParameters->protocolVersion)); - - return TRUE; + return + ber_read_sequence_tag(s, &length) && + ber_read_integer(s, &(domainParameters->maxChannelIds)) && + ber_read_integer(s, &(domainParameters->maxUserIds)) && + ber_read_integer(s, &(domainParameters->maxTokenIds)) && + ber_read_integer(s, &(domainParameters->numPriorities)) && + ber_read_integer(s, &(domainParameters->minThroughput)) && + ber_read_integer(s, &(domainParameters->maxHeight)) && + ber_read_integer(s, &(domainParameters->maxMCSPDUsize)) && + ber_read_integer(s, &(domainParameters->protocolVersion)); } /** @@ -325,24 +326,25 @@ void mcs_print_domain_parameters(DomainParameters* domainParameters) BOOL mcs_recv_connect_initial(rdpMcs* mcs, STREAM* s) { + UINT16 li; int length; BOOL upwardFlag; tpkt_read_header(s); - if (tpdu_read_data(s) == 0) + if (!tpdu_read_data(s, &li)) return FALSE; if (!ber_read_application_tag(s, MCS_TYPE_CONNECT_INITIAL, &length)) return FALSE; /* callingDomainSelector (OCTET_STRING) */ - if (!ber_read_octet_string_tag(s, &length)) + if (!ber_read_octet_string_tag(s, &length) || stream_get_left(s) < length) return FALSE; stream_seek(s, length); /* calledDomainSelector (OCTET_STRING) */ - if (!ber_read_octet_string_tag(s, &length)) + if (!ber_read_octet_string_tag(s, &length) || stream_get_left(s) < length) return FALSE; stream_seek(s, length); @@ -351,15 +353,18 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, STREAM* s) return FALSE; /* targetParameters (DomainParameters) */ - mcs_read_domain_parameters(s, &mcs->targetParameters); + if(!mcs_read_domain_parameters(s, &mcs->targetParameters)) + return FALSE; /* minimumParameters (DomainParameters) */ - mcs_read_domain_parameters(s, &mcs->minimumParameters); + if(!mcs_read_domain_parameters(s, &mcs->minimumParameters)) + return FALSE; /* maximumParameters (DomainParameters) */ - mcs_read_domain_parameters(s, &mcs->maximumParameters); + if(!mcs_read_domain_parameters(s, &mcs->maximumParameters)) + return FALSE; - if (!ber_read_octet_string_tag(s, &length)) + if (!ber_read_octet_string_tag(s, &length) || stream_get_left(s) < length) return FALSE; if (!gcc_read_conference_create_request(s, mcs->transport->settings)) @@ -491,21 +496,22 @@ BOOL mcs_recv_connect_response(rdpMcs* mcs, STREAM* s) { int length; BYTE result; + UINT16 li; UINT32 calledConnectId; tpkt_read_header(s); - if (tpdu_read_data(s) == 0) + if (!tpdu_read_data(s, &li)) return FALSE; - ber_read_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, &length); - ber_read_enumerated(s, &result, MCS_Result_enum_length); - ber_read_integer(s, &calledConnectId); - - if (!mcs_read_domain_parameters(s, &(mcs->domainParameters))) + if(!ber_read_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, &length) || + !ber_read_enumerated(s, &result, MCS_Result_enum_length) || + !ber_read_integer(s, &calledConnectId) || + !mcs_read_domain_parameters(s, &(mcs->domainParameters)) || + !ber_read_octet_string_tag(s, &length)) + { return FALSE; - - ber_read_octet_string_tag(s, &length); + } if (!gcc_read_conference_create_response(s, mcs->transport->settings)) { @@ -571,10 +577,7 @@ BOOL mcs_recv_erect_domain_request(rdpMcs* mcs, STREAM* s) enum DomainMCSPDU MCSPDU; MCSPDU = DomainMCSPDU_ErectDomainRequest; - if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) - return FALSE; - - return TRUE; + return mcs_read_domain_mcspdu_header(s, &MCSPDU, &length); } /** @@ -613,10 +616,7 @@ BOOL mcs_recv_attach_user_request(rdpMcs* mcs, STREAM* s) enum DomainMCSPDU MCSPDU; MCSPDU = DomainMCSPDU_AttachUserRequest; - if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) - return FALSE; - - return TRUE; + return mcs_read_domain_mcspdu_header(s, &MCSPDU, &length); } /** @@ -652,13 +652,10 @@ BOOL mcs_recv_attach_user_confirm(rdpMcs* mcs, STREAM* s) enum DomainMCSPDU MCSPDU; MCSPDU = DomainMCSPDU_AttachUserConfirm; - if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) - return FALSE; - - per_read_enumerated(s, &result, MCS_Result_enum_length); /* result */ - per_read_integer16(s, &(mcs->user_id), MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ - - return TRUE; + return + mcs_read_domain_mcspdu_header(s, &MCSPDU, &length) && + per_read_enumerated(s, &result, MCS_Result_enum_length) && /* result */ + per_read_integer16(s, &(mcs->user_id), MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ } /** @@ -699,17 +696,11 @@ BOOL mcs_recv_channel_join_request(rdpMcs* mcs, STREAM* s, UINT16* channel_id) UINT16 user_id; MCSPDU = DomainMCSPDU_ChannelJoinRequest; - if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) - return FALSE; - - if (!per_read_integer16(s, &user_id, MCS_BASE_CHANNEL_ID)) - return FALSE; - if (user_id != mcs->user_id) - return FALSE; - if (!per_read_integer16(s, channel_id, 0)) - return FALSE; - - return TRUE; + return + mcs_read_domain_mcspdu_header(s, &MCSPDU, &length) && + per_read_integer16(s, &user_id, MCS_BASE_CHANNEL_ID) && + (user_id == mcs->user_id) && + per_read_integer16(s, channel_id, 0); } /** @@ -751,15 +742,12 @@ BOOL mcs_recv_channel_join_confirm(rdpMcs* mcs, STREAM* s, UINT16* channel_id) enum DomainMCSPDU MCSPDU; MCSPDU = DomainMCSPDU_ChannelJoinConfirm; - if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) - return FALSE; - - per_read_enumerated(s, &result, MCS_Result_enum_length); /* result */ - per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ - per_read_integer16(s, &requested, 0); /* requested (ChannelId) */ - per_read_integer16(s, channel_id, 0); /* channelId */ - - return TRUE; + return + mcs_read_domain_mcspdu_header(s, &MCSPDU, &length) && + per_read_enumerated(s, &result, MCS_Result_enum_length) && /* result */ + per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID) && /* initiator (UserId) */ + per_read_integer16(s, &requested, 0) && /* requested (ChannelId) */ + per_read_integer16(s, channel_id, 0); /* channelId */ } /** diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index 770c6da8c..31b8811ab 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -490,7 +490,8 @@ int nego_recv(rdpTransport* transport, STREAM* s, void* extra) if (length == 0) return -1; - li = tpdu_read_connection_confirm(s); + if(!tpdu_read_connection_confirm(s, &li)) + return -1; if (li > 6) { @@ -562,7 +563,8 @@ BOOL nego_read_request(rdpNego* nego, STREAM* s) BYTE type; tpkt_read_header(s); - li = tpdu_read_connection_request(s); + if(!tpdu_read_connection_request(s, &li)) + return FALSE; if (li != stream_get_left(s) + 6) { @@ -723,6 +725,13 @@ void nego_process_negotiation_response(rdpNego* nego, STREAM* s) DEBUG_NEGO("RDP_NEG_RSP"); + if (stream_get_left(s) < 7) + { + DEBUG_NEGO("RDP_INVALID_NEG_RSP"); + nego->state = NEGO_STATE_FAIL; + return; + } + stream_read_BYTE(s, nego->flags); stream_read_UINT16(s, length); stream_read_UINT32(s, nego->selected_protocol); diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 215bcb9c3..8157a24b3 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -190,7 +190,8 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s) if (channelId != MCS_GLOBAL_CHANNEL_ID) { - freerdp_channel_peer_process(client, s, channelId); + if(!freerdp_channel_peer_process(client, s, channelId)) + return -1; } else { @@ -233,7 +234,8 @@ static int peer_recv_fastpath_pdu(freerdp_peer* client, STREAM* s) if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED) { - rdp_decrypt(rdp, s, length, (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0); + if(!rdp_decrypt(rdp, s, length, (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0)) + return -1; } return fastpath_recv_inputs(fastpath, s); diff --git a/libfreerdp/core/tpdu.c b/libfreerdp/core/tpdu.c index bfbdc1066..84fa37128 100644 --- a/libfreerdp/core/tpdu.c +++ b/libfreerdp/core/tpdu.c @@ -66,11 +66,12 @@ * @return TPDU length indicator (LI) */ -BYTE tpdu_read_header(STREAM* s, BYTE* code) +BOOL tpdu_read_header(STREAM* s, BYTE* code, BYTE *li) { - BYTE li; + if(stream_get_left(s) < 3) + return FALSE; - stream_read_BYTE(s, li); /* LI */ + stream_read_BYTE(s, *li); /* LI */ stream_read_BYTE(s, *code); /* Code */ if (*code == X224_TPDU_DATA) @@ -83,10 +84,9 @@ BYTE tpdu_read_header(STREAM* s, BYTE* code) /* DST-REF (2 bytes) */ /* SRC-REF (2 bytes) */ /* Class 0 (1 byte) */ - stream_seek(s, 5); + return stream_skip(s, 5); } - - return li; + return TRUE; } /** @@ -119,20 +119,20 @@ void tpdu_write_header(STREAM* s, UINT16 length, BYTE code) * @return length indicator (LI) */ -BYTE tpdu_read_connection_request(STREAM* s) +BOOL tpdu_read_connection_request(STREAM* s, BYTE *li) { - BYTE li; BYTE code; - li = tpdu_read_header(s, &code); + if(!tpdu_read_header(s, &code, li)) + return FALSE; if (code != X224_TPDU_CONNECTION_REQUEST) { printf("Error: expected X224_TPDU_CONNECTION_REQUEST\n"); - return 0; + return FALSE; } - return li; + return TRUE; } /** @@ -152,20 +152,20 @@ void tpdu_write_connection_request(STREAM* s, UINT16 length) * @return length indicator (LI) */ -BYTE tpdu_read_connection_confirm(STREAM* s) +BOOL tpdu_read_connection_confirm(STREAM* s, BYTE *li) { - BYTE li; BYTE code; - li = tpdu_read_header(s, &code); + if(!tpdu_read_header(s, &code, li)) + return FALSE; if (code != X224_TPDU_CONNECTION_CONFIRM) { printf("Error: expected X224_TPDU_CONNECTION_CONFIRM\n"); - return 0; + return FALSE; } - return li; + return (stream_get_left(s) >= *li); } /** @@ -205,15 +205,16 @@ void tpdu_write_data(STREAM* s) * @param s stream */ -UINT16 tpdu_read_data(STREAM* s) +BOOL tpdu_read_data(STREAM* s, UINT16 *LI) { BYTE code; - UINT16 li; + BYTE li; - li = tpdu_read_header(s, &code); + if(!tpdu_read_header(s, &code, &li)) + return FALSE; if (code != X224_TPDU_DATA) - return 0; - - return li; + return FALSE; + *LI = li; + return TRUE; } diff --git a/libfreerdp/core/tpdu.h b/libfreerdp/core/tpdu.h index cf92551f0..c81fba6b8 100644 --- a/libfreerdp/core/tpdu.h +++ b/libfreerdp/core/tpdu.h @@ -41,14 +41,14 @@ enum X224_TPDU_TYPE #define TPDU_CONNECTION_CONFIRM_LENGTH (TPKT_HEADER_LENGTH + TPDU_CONNECTION_CONFIRM_HEADER_LENGTH) #define TPDU_DISCONNECT_REQUEST_LENGTH (TPKT_HEADER_LENGTH + TPDU_DISCONNECT_REQUEST_HEADER_LENGTH) -BYTE tpdu_read_header(STREAM* s, BYTE* code); +BOOL tpdu_read_header(STREAM* s, BYTE* code, BYTE *li); void tpdu_write_header(STREAM* s, UINT16 length, BYTE code); -BYTE tpdu_read_connection_request(STREAM* s); +BOOL tpdu_read_connection_request(STREAM* s, BYTE *li); void tpdu_write_connection_request(STREAM* s, UINT16 length); -BYTE tpdu_read_connection_confirm(STREAM* s); +BOOL tpdu_read_connection_confirm(STREAM* s, BYTE *li); void tpdu_write_connection_confirm(STREAM* s, UINT16 length); void tpdu_write_disconnect_request(STREAM* s, UINT16 length); -UINT16 tpdu_read_data(STREAM* s); +BOOL tpdu_read_data(STREAM* s, UINT16 *li); void tpdu_write_data(STREAM* s); #endif /* __TPDU_H */ diff --git a/libfreerdp/core/window.c b/libfreerdp/core/window.c index 60c6f4ec3..6c5b207a7 100644 --- a/libfreerdp/core/window.c +++ b/libfreerdp/core/window.c @@ -28,8 +28,10 @@ #include "window.h" -void update_read_icon_info(STREAM* s, ICON_INFO* icon_info) +BOOL update_read_icon_info(STREAM* s, ICON_INFO* icon_info) { + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT16(s, icon_info->cacheEntry); /* cacheEntry (2 bytes) */ stream_read_BYTE(s, icon_info->cacheId); /* cacheId (1 byte) */ stream_read_BYTE(s, icon_info->bpp); /* bpp (1 byte) */ @@ -37,14 +39,22 @@ void update_read_icon_info(STREAM* s, ICON_INFO* icon_info) stream_read_UINT16(s, icon_info->height); /* height (2 bytes) */ /* cbColorTable is only present when bpp is 1, 2 or 4 */ - if (icon_info->bpp == 1 || icon_info->bpp == 2 || icon_info->bpp == 4) + if (icon_info->bpp == 1 || icon_info->bpp == 2 || icon_info->bpp == 4) { + if(stream_get_left(s) < 2) + return FALSE; stream_read_UINT16(s, icon_info->cbColorTable); /* cbColorTable (2 bytes) */ - else + } else { icon_info->cbColorTable = 0; + } + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT16(s, icon_info->cbBitsMask); /* cbBitsMask (2 bytes) */ stream_read_UINT16(s, icon_info->cbBitsColor); /* cbBitsColor (2 bytes) */ + if(stream_get_left(s) < icon_info->cbBitsMask + icon_info->cbBitsColor) + return FALSE; + /* bitsMask */ if (icon_info->bitsMask == NULL) icon_info->bitsMask = (BYTE*) malloc(icon_info->cbBitsMask); @@ -65,85 +75,122 @@ void update_read_icon_info(STREAM* s, ICON_INFO* icon_info) else icon_info->bitsColor = (BYTE*) realloc(icon_info->bitsColor, icon_info->cbBitsColor); stream_read(s, icon_info->bitsColor, icon_info->cbBitsColor); + return TRUE; } -void update_read_cached_icon_info(STREAM* s, CACHED_ICON_INFO* cached_icon_info) +BOOL update_read_cached_icon_info(STREAM* s, CACHED_ICON_INFO* cached_icon_info) { + if(stream_get_left(s) < 3) + return FALSE; stream_read_UINT16(s, cached_icon_info->cacheEntry); /* cacheEntry (2 bytes) */ stream_read_BYTE(s, cached_icon_info->cacheId); /* cacheId (1 byte) */ + return TRUE; } -void update_read_notify_icon_infotip(STREAM* s, NOTIFY_ICON_INFOTIP* notify_icon_infotip) +BOOL update_read_notify_icon_infotip(STREAM* s, NOTIFY_ICON_INFOTIP* notify_icon_infotip) { + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT32(s, notify_icon_infotip->timeout); /* timeout (4 bytes) */ stream_read_UINT32(s, notify_icon_infotip->flags); /* infoFlags (4 bytes) */ - rail_read_unicode_string(s, ¬ify_icon_infotip->text); /* infoTipText */ - rail_read_unicode_string(s, ¬ify_icon_infotip->title); /* title */ + return rail_read_unicode_string(s, ¬ify_icon_infotip->text) && /* infoTipText */ + rail_read_unicode_string(s, ¬ify_icon_infotip->title); /* title */ } -void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +BOOL update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) { int i; int size; - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) { + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, window_state->ownerWindowId); /* ownerWindowId (4 bytes) */ + } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) { + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT32(s, window_state->style); /* style (4 bytes) */ stream_read_UINT32(s, window_state->extendedStyle); /* extendedStyle (4 bytes) */ } - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) { + if(stream_get_left(s) < 1) + return FALSE; stream_read_BYTE(s, window_state->showState); /* showState (1 byte) */ + } - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) - rail_read_unicode_string(s, &window_state->titleInfo); /* titleInfo */ + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) { + if(!rail_read_unicode_string(s, &window_state->titleInfo)) /* titleInfo */ + return FALSE; + } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) { + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, window_state->clientOffsetX); /* clientOffsetX (4 bytes) */ stream_read_UINT32(s, window_state->clientOffsetY); /* clientOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) { + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, window_state->clientAreaWidth); /* clientAreaWidth (4 bytes) */ stream_read_UINT32(s, window_state->clientAreaHeight); /* clientAreaHeight (4 bytes) */ } - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) { + if(stream_get_left(s) < 1) + return FALSE; stream_read_BYTE(s, window_state->RPContent); /* RPContent (1 byte) */ + } - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) { + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, window_state->rootParentHandle);/* rootParentHandle (4 bytes) */ + } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) { + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT32(s, window_state->windowOffsetX); /* windowOffsetX (4 bytes) */ stream_read_UINT32(s, window_state->windowOffsetY); /* windowOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) { + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT32(s, window_state->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */ stream_read_UINT32(s, window_state->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) { + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT32(s, window_state->windowWidth); /* windowWidth (4 bytes) */ stream_read_UINT32(s, window_state->windowHeight); /* windowHeight (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) { + if(stream_get_left(s) < 2) + return FALSE; stream_read_UINT16(s, window_state->numWindowRects); /* numWindowRects (2 bytes) */ size = sizeof(RECTANGLE_16) * window_state->numWindowRects; window_state->windowRects = (RECTANGLE_16*) malloc(size); + if(stream_get_left(s) < 8 * window_state->numWindowRects) + return FALSE; + /* windowRects */ for (i = 0; i < (int) window_state->numWindowRects; i++) { @@ -156,17 +203,24 @@ void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WIN if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) { + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, window_state->visibleOffsetX); /* visibleOffsetX (4 bytes) */ stream_read_UINT32(s, window_state->visibleOffsetY); /* visibleOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) { + if(stream_get_left(s) < 2) + return FALSE; stream_read_UINT16(s, window_state->numVisibilityRects); /* numVisibilityRects (2 bytes) */ size = sizeof(RECTANGLE_16) * window_state->numVisibilityRects; window_state->visibilityRects = (RECTANGLE_16*) malloc(size); + if(stream_get_left(s) < window_state->numVisibilityRects * 8) + return FALSE; + /* visibilityRects */ for (i = 0; i < (int) window_state->numVisibilityRects; i++) { @@ -176,19 +230,20 @@ void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WIN stream_read_UINT16(s, window_state->visibilityRects[i].bottom); /* bottom (2 bytes) */ } } + return TRUE; } -void update_read_window_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon) +BOOL update_read_window_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon) { window_icon->iconInfo = (ICON_INFO*) malloc(sizeof(ICON_INFO)); ZeroMemory(window_icon->iconInfo, sizeof(ICON_INFO)); - update_read_icon_info(s, window_icon->iconInfo); /* iconInfo (ICON_INFO) */ + return update_read_icon_info(s, window_icon->iconInfo); /* iconInfo (ICON_INFO) */ } -void update_read_window_cached_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon) +BOOL update_read_window_cached_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon) { - update_read_cached_icon_info(s, &window_cached_icon->cachedIcon); /* cachedIcon (CACHED_ICON_INFO) */ + return update_read_cached_icon_info(s, &window_cached_icon->cachedIcon); /* cachedIcon (CACHED_ICON_INFO) */ } void update_read_window_delete_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo) @@ -196,23 +251,27 @@ void update_read_window_delete_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo) /* window deletion event */ } -void update_recv_window_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo) +BOOL update_recv_window_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo) { rdpContext* context = update->context; rdpWindowUpdate* window = update->window; + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */ if (orderInfo->fieldFlags & WINDOW_ORDER_ICON) { DEBUG_WND("Window Icon Order"); - update_read_window_icon_order(s, orderInfo, &window->window_icon); + if(!update_read_window_icon_order(s, orderInfo, &window->window_icon)) + return FALSE; IFCALL(window->WindowIcon, context, orderInfo, &window->window_icon); } else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON) { DEBUG_WND("Window Cached Icon Order"); - update_read_window_cached_icon_order(s, orderInfo, &window->window_cached_icon); + if(!update_read_window_cached_icon_order(s, orderInfo, &window->window_cached_icon)) + return FALSE; IFCALL(window->WindowCachedIcon, context, orderInfo, &window->window_cached_icon); } else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED) @@ -224,34 +283,51 @@ void update_recv_window_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_IN else { DEBUG_WND("Window State Order"); - update_read_window_state_order(s, orderInfo, &window->window_state); + if(!update_read_window_state_order(s, orderInfo, &window->window_state)) + return FALSE; if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW) IFCALL(window->WindowCreate, context, orderInfo, &window->window_state); else IFCALL(window->WindowUpdate, context, orderInfo, &window->window_state); } + return TRUE; } -void update_read_notification_icon_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state) +BOOL update_read_notification_icon_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state) { - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) { + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, notify_icon_state->version); /* version (4 bytes) */ + } - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) - rail_read_unicode_string(s, ¬ify_icon_state->toolTip); /* toolTip (UNICODE_STRING) */ + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) { + if(!rail_read_unicode_string(s, ¬ify_icon_state->toolTip)) /* toolTip (UNICODE_STRING) */ + return FALSE; + } - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) - update_read_notify_icon_infotip(s, ¬ify_icon_state->infoTip); /* infoTip (NOTIFY_ICON_INFOTIP) */ + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) { + if(!update_read_notify_icon_infotip(s, ¬ify_icon_state->infoTip)) /* infoTip (NOTIFY_ICON_INFOTIP) */ + return FALSE; + } - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE) + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE) { + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, notify_icon_state->state); /* state (4 bytes) */ + } - if (orderInfo->fieldFlags & WINDOW_ORDER_ICON) - update_read_icon_info(s, ¬ify_icon_state->icon); /* icon (ICON_INFO) */ + if (orderInfo->fieldFlags & WINDOW_ORDER_ICON) { + if(!update_read_icon_info(s, ¬ify_icon_state->icon)) /* icon (ICON_INFO) */ + return FALSE; + } - if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON) - update_read_cached_icon_info(s, ¬ify_icon_state->cachedIcon); /* cachedIcon (CACHED_ICON_INFO) */ + if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON) { + if(!update_read_cached_icon_info(s, ¬ify_icon_state->cachedIcon)) /* cachedIcon (CACHED_ICON_INFO) */ + return FALSE; + } + return TRUE; } void update_read_notification_icon_delete_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo) @@ -259,11 +335,13 @@ void update_read_notification_icon_delete_order(STREAM* s, WINDOW_ORDER_INFO* or /* notification icon deletion event */ } -void update_recv_notification_icon_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo) +BOOL update_recv_notification_icon_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo) { rdpContext* context = update->context; rdpWindowUpdate* window = update->window; + if(stream_get_left(s) < 8) + return FALSE; stream_read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */ stream_read_UINT32(s, orderInfo->notifyIconId); /* notifyIconId (4 bytes) */ @@ -276,27 +354,37 @@ void update_recv_notification_icon_info_order(rdpUpdate* update, STREAM* s, WIND else { DEBUG_WND("Notification Icon State Order"); - update_read_notification_icon_state_order(s, orderInfo, &window->notify_icon_state); + if(!update_read_notification_icon_state_order(s, orderInfo, &window->notify_icon_state)) + return FALSE; if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW) IFCALL(window->NotifyIconCreate, context, orderInfo, &window->notify_icon_state); else IFCALL(window->NotifyIconUpdate, context, orderInfo, &window->notify_icon_state); } + return TRUE; } -void update_read_desktop_actively_monitored_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitored_desktop) +BOOL update_read_desktop_actively_monitored_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitored_desktop) { int i; int size; - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) { + if(stream_get_left(s) < 4) + return FALSE; stream_read_UINT32(s, monitored_desktop->activeWindowId); /* activeWindowId (4 bytes) */ + } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) { + if(stream_get_left(s) < 1) + return FALSE; stream_read_BYTE(s, monitored_desktop->numWindowIds); /* numWindowIds (1 byte) */ + if(stream_get_left(s) < 4 * monitored_desktop->numWindowIds) + return FALSE; + size = sizeof(UINT32) * monitored_desktop->numWindowIds; if (monitored_desktop->windowIds == NULL) @@ -310,6 +398,7 @@ void update_read_desktop_actively_monitored_order(STREAM* s, WINDOW_ORDER_INFO* stream_read_UINT32(s, monitored_desktop->windowIds[i]); } } + return TRUE; } void update_read_desktop_non_monitored_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo) @@ -317,7 +406,7 @@ void update_read_desktop_non_monitored_order(STREAM* s, WINDOW_ORDER_INFO* order /* non-monitored desktop notification event */ } -void update_recv_desktop_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo) +BOOL update_recv_desktop_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo) { rdpContext* context = update->context; rdpWindowUpdate* window = update->window; @@ -331,24 +420,29 @@ void update_recv_desktop_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_I else { DEBUG_WND("Actively Monitored Desktop Order"); - update_read_desktop_actively_monitored_order(s, orderInfo, &window->monitored_desktop); + if(!update_read_desktop_actively_monitored_order(s, orderInfo, &window->monitored_desktop)) + return FALSE; IFCALL(window->MonitoredDesktop, context, orderInfo, &window->monitored_desktop); } + return TRUE; } -void update_recv_altsec_window_order(rdpUpdate* update, STREAM* s) +BOOL update_recv_altsec_window_order(rdpUpdate* update, STREAM* s) { UINT16 orderSize; rdpWindowUpdate* window = update->window; + if(stream_get_left(s) < 6) + return FALSE; stream_read_UINT16(s, orderSize); /* orderSize (2 bytes) */ stream_read_UINT32(s, window->orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */ if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW) - update_recv_window_info_order(update, s, &window->orderInfo); + return update_recv_window_info_order(update, s, &window->orderInfo); else if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY) - update_recv_notification_icon_info_order(update, s, &window->orderInfo); + return update_recv_notification_icon_info_order(update, s, &window->orderInfo); else if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP) - update_recv_desktop_info_order(update, s, &window->orderInfo); + return update_recv_desktop_info_order(update, s, &window->orderInfo); + return TRUE; } diff --git a/libfreerdp/core/window.h b/libfreerdp/core/window.h index 7f173ddc2..0b9725b08 100644 --- a/libfreerdp/core/window.h +++ b/libfreerdp/core/window.h @@ -25,7 +25,7 @@ #include -void update_recv_altsec_window_order(rdpUpdate* update, STREAM* s); +BOOL update_recv_altsec_window_order(rdpUpdate* update, STREAM* s); #ifdef WITH_DEBUG_WND #define DEBUG_WND(fmt, ...) DEBUG_CLASS(WND, fmt, ## __VA_ARGS__) diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index f222899e1..37ea82319 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -708,7 +708,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co tile_bitmap = (char*) malloc(32); ZeroMemory(tile_bitmap, 32); - if (surface_bits_command->codecID == CODEC_ID_REMOTEFX) + if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX) { message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); @@ -742,7 +742,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co gdi_SetNullClipRgn(gdi->primary->hdc); rfx_message_free(rfx_context, message); } - else if (surface_bits_command->codecID == CODEC_ID_NSCODEC) + else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC) { nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); @@ -754,7 +754,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co freerdp_image_flip(nsc_context->bmpdata, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, 32); gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); } - else if (surface_bits_command->codecID == CODEC_ID_NONE) + else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE) { gdi->image->bitmap->width = surface_bits_command->width; gdi->image->bitmap->height = surface_bits_command->height; diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index d10f49d30..d30a230db 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -115,10 +115,10 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, switch (codec_id) { - case CODEC_ID_NSCODEC: + case RDP_CODEC_ID_NSCODEC: printf("gdi_Bitmap_Decompress: nsc not done\n"); break; - case CODEC_ID_REMOTEFX: + case RDP_CODEC_ID_REMOTEFX: gdi = context->gdi; rfx_context_set_pixel_format(gdi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); msg = rfx_process_message(gdi->rfx_context, data, length); @@ -143,7 +143,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, rfx_message_free(gdi->rfx_context, msg); } break; - case CODEC_ID_JPEG: + case RDP_CODEC_ID_JPEG: #ifdef WITH_JPEG if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp)) { diff --git a/winpr/libwinpr/sspi/Schannel/schannel_openssl.c b/winpr/libwinpr/sspi/Schannel/schannel_openssl.c index 3b767311c..b86eeb5ce 100644 --- a/winpr/libwinpr/sspi/Schannel/schannel_openssl.c +++ b/winpr/libwinpr/sspi/Schannel/schannel_openssl.c @@ -307,7 +307,7 @@ SECURITY_STATUS schannel_openssl_server_process_tokens(SCHANNEL_OPENSSL* context if (pBuffer->BufferType != SECBUFFER_TOKEN) return SEC_E_INVALID_TOKEN; - printf("Server input: %d\n", pBuffer->cbBuffer); + printf("Server input: %ld\n", pBuffer->cbBuffer); status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer); status = SSL_accept(context->ssl);