Compare commits

...

10 Commits

Author SHA1 Message Date
Nick Couchman
0d479fee8c [WIP] Use the right function name.. 2020-04-05 16:42:47 -04:00
Nick Couchman
f4afa306d2 [WIP] This one is not working quite right.. 2020-04-05 16:42:14 -04:00
Nick Couchman
2cec76f748 [WIP] One more length check. 2020-04-05 16:39:33 -04:00
Nick Couchman
792e23d481 [WIP] Quick stream check fixes. 2020-04-05 15:37:33 -04:00
Nick Couchman
4f1f1d71a6 [WIP] Check all streams prior to reading. 2020-04-05 15:10:42 -04:00
Nick Couchman
d26f497a9c [WIP] Add some debug, just some more. 2020-04-05 14:11:06 -04:00
Nick Couchman
7a624c4d86 [WIP] Add some debug, correctly. 2020-04-05 14:08:05 -04:00
Nick Couchman
64a463738b [WIP] Add some debug. 2020-04-05 14:06:09 -04:00
Nick Couchman
8d9d0fc097 [WIP] More tweaks to code. 2020-04-05 13:42:21 -04:00
Nick Couchman
f9986a5787 [WIP] RDP code enhancements. 2020-04-05 13:34:53 -04:00
10 changed files with 114 additions and 4 deletions

View File

@ -135,6 +135,10 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdp_common_svc* svc,
wStream* output_stream; wStream* output_stream;
char destination_path[GUAC_RDP_FS_MAX_PATH]; char destination_path[GUAC_RDP_FS_MAX_PATH];
/* Check stream size prior to reading. */
if (Stream_GetRemainingLength(input_stream) < 6)
return;
/* Read structure */ /* Read structure */
Stream_Seek_UINT8(input_stream); /* ReplaceIfExists */ Stream_Seek_UINT8(input_stream); /* ReplaceIfExists */
Stream_Seek_UINT8(input_stream); /* RootDirectory */ Stream_Seek_UINT8(input_stream); /* RootDirectory */

View File

@ -48,6 +48,10 @@ void guac_rdpdr_fs_process_create(guac_rdp_common_svc* svc,
int create_disposition, create_options, path_length; int create_disposition, create_options, path_length;
char path[GUAC_RDP_FS_MAX_PATH]; char path[GUAC_RDP_FS_MAX_PATH];
/* Check remaining stream data prior to reading. */
if (Stream_GetRemainingLength(input_stream) < 32)
return;
/* Read "create" information */ /* Read "create" information */
Stream_Read_UINT32(input_stream, desired_access); Stream_Read_UINT32(input_stream, desired_access);
Stream_Seek_UINT64(input_stream); /* allocation size */ Stream_Seek_UINT64(input_stream); /* allocation size */
@ -123,6 +127,10 @@ void guac_rdpdr_fs_process_read(guac_rdp_common_svc* svc,
wStream* output_stream; wStream* output_stream;
/* Check remaining bytes before reading stream. */
if (Stream_GetRemainingLength(input_stream) < 12)
return;
/* Read packet */ /* Read packet */
Stream_Read_UINT32(input_stream, length); Stream_Read_UINT32(input_stream, length);
Stream_Read_UINT64(input_stream, offset); Stream_Read_UINT64(input_stream, offset);
@ -172,6 +180,10 @@ void guac_rdpdr_fs_process_write(guac_rdp_common_svc* svc,
wStream* output_stream; wStream* output_stream;
/* Check remaining length. */
if (Stream_GetRemainingLength(input_stream) < 32)
return;
/* Read packet */ /* Read packet */
Stream_Read_UINT32(input_stream, length); Stream_Read_UINT32(input_stream, length);
Stream_Read_UINT64(input_stream, offset); Stream_Read_UINT64(input_stream, offset);
@ -244,6 +256,10 @@ void guac_rdpdr_fs_process_volume_info(guac_rdp_common_svc* svc,
int fs_information_class; int fs_information_class;
/* Check remaining length */
if (Stream_GetRemainingLength(input_stream) < 4)
return;
Stream_Read_UINT32(input_stream, fs_information_class); Stream_Read_UINT32(input_stream, fs_information_class);
/* Dispatch to appropriate class-specific handler */ /* Dispatch to appropriate class-specific handler */
@ -282,6 +298,10 @@ void guac_rdpdr_fs_process_file_info(guac_rdp_common_svc* svc,
int fs_information_class; int fs_information_class;
/* Check remaining length */
if (Stream_GetRemainingLength(input_stream) < 4)
return;
Stream_Read_UINT32(input_stream, fs_information_class); Stream_Read_UINT32(input_stream, fs_information_class);
/* Dispatch to appropriate class-specific handler */ /* Dispatch to appropriate class-specific handler */
@ -328,6 +348,10 @@ void guac_rdpdr_fs_process_set_file_info(guac_rdp_common_svc* svc,
int fs_information_class; int fs_information_class;
int length; int length;
/* Check remaining length */
if (Stream_GetRemainingLength(input_stream) < 32)
return;
Stream_Read_UINT32(input_stream, fs_information_class); Stream_Read_UINT32(input_stream, fs_information_class);
Stream_Read_UINT32(input_stream, length); /* Length */ Stream_Read_UINT32(input_stream, length); /* Length */
Stream_Seek(input_stream, 24); /* Padding */ Stream_Seek(input_stream, 24); /* Padding */
@ -406,6 +430,9 @@ void guac_rdpdr_fs_process_query_directory(guac_rdp_common_svc* svc,
if (file == NULL) if (file == NULL)
return; return;
if (Stream_GetRemainingLength(input_stream) < 9)
return;
/* Read main header */ /* Read main header */
Stream_Read_UINT32(input_stream, fs_information_class); Stream_Read_UINT32(input_stream, fs_information_class);
Stream_Read_UINT8(input_stream, initial_query); Stream_Read_UINT8(input_stream, initial_query);
@ -414,6 +441,9 @@ void guac_rdpdr_fs_process_query_directory(guac_rdp_common_svc* svc,
/* If this is the first query, the path is included after padding */ /* If this is the first query, the path is included after padding */
if (initial_query) { if (initial_query) {
if (Stream_GetRemainingLength(input_stream) < 23)
return;
Stream_Seek(input_stream, 23); /* Padding */ Stream_Seek(input_stream, 23); /* Padding */
/* Convert path to UTF-8 */ /* Convert path to UTF-8 */

View File

@ -212,6 +212,9 @@ void guac_rdpdr_process_server_announce(guac_rdp_common_svc* svc,
unsigned int major, minor, client_id; unsigned int major, minor, client_id;
if (Stream_GetRemainingLength(input_stream) < 8)
return;
Stream_Read_UINT16(input_stream, major); Stream_Read_UINT16(input_stream, major);
Stream_Read_UINT16(input_stream, minor); Stream_Read_UINT16(input_stream, minor);
Stream_Read_UINT32(input_stream, client_id); Stream_Read_UINT32(input_stream, client_id);
@ -243,6 +246,9 @@ void guac_rdpdr_process_device_reply(guac_rdp_common_svc* svc,
unsigned int device_id, ntstatus; unsigned int device_id, ntstatus;
int severity, c, n, facility, code; int severity, c, n, facility, code;
if (Stream_GetRemainingLength(input_stream) < 8)
return;
Stream_Read_UINT32(input_stream, device_id); Stream_Read_UINT32(input_stream, device_id);
Stream_Read_UINT32(input_stream, ntstatus); Stream_Read_UINT32(input_stream, ntstatus);
@ -278,6 +284,9 @@ void guac_rdpdr_process_device_iorequest(guac_rdp_common_svc* svc,
guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data; guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data;
guac_rdpdr_iorequest iorequest; guac_rdpdr_iorequest iorequest;
if (Stream_GetRemainingLength(input_stream) < 20)
return;
/* Read header */ /* Read header */
Stream_Read_UINT32(input_stream, iorequest.device_id); Stream_Read_UINT32(input_stream, iorequest.device_id);
Stream_Read_UINT32(input_stream, iorequest.file_id); Stream_Read_UINT32(input_stream, iorequest.file_id);
@ -306,6 +315,9 @@ void guac_rdpdr_process_server_capability(guac_rdp_common_svc* svc,
int count; int count;
int i; int i;
if (Stream_GetRemainingLength(input_stream) < 4)
return;
/* Read header */ /* Read header */
Stream_Read_UINT16(input_stream, count); Stream_Read_UINT16(input_stream, count);
Stream_Seek(input_stream, 2); Stream_Seek(input_stream, 2);
@ -316,9 +328,15 @@ void guac_rdpdr_process_server_capability(guac_rdp_common_svc* svc,
int type; int type;
int length; int length;
if (Stream_GetRemainingLength(input_stream) < 4)
break;
Stream_Read_UINT16(input_stream, type); Stream_Read_UINT16(input_stream, type);
Stream_Read_UINT16(input_stream, length); Stream_Read_UINT16(input_stream, length);
if (Stream_GetRemainingLength(input_stream) < (length - 4))
break;
/* Ignore all for now */ /* Ignore all for now */
guac_client_log(svc->client, GUAC_LOG_DEBUG, "Ignoring server capability set type=0x%04x, length=%i", type, length); guac_client_log(svc->client, GUAC_LOG_DEBUG, "Ignoring server capability set type=0x%04x, length=%i", type, length);
Stream_Seek(input_stream, length - 4); Stream_Seek(input_stream, length - 4);

View File

@ -67,6 +67,9 @@ void guac_rdpdr_process_print_job_write(guac_rdp_common_svc* svc,
int length; int length;
int status; int status;
if (Stream_GetRemainingLength(input_stream) < 32)
return;
/* Read buffer of print data */ /* Read buffer of print data */
Stream_Read_UINT32(input_stream, length); Stream_Read_UINT32(input_stream, length);
Stream_Seek(input_stream, 8); /* Offset */ Stream_Seek(input_stream, 8); /* Offset */

View File

@ -38,6 +38,9 @@ void guac_rdpdr_process_receive(guac_rdp_common_svc* svc,
int component; int component;
int packet_id; int packet_id;
if (Stream_GetRemainingLength(input_stream) < 4)
return;
/* Read header */ /* Read header */
Stream_Read_UINT16(input_stream, component); Stream_Read_UINT16(input_stream, component);
Stream_Read_UINT16(input_stream, packet_id); Stream_Read_UINT16(input_stream, packet_id);

View File

@ -50,6 +50,9 @@ void guac_rdpsnd_formats_handler(guac_rdp_common_svc* svc,
/* Reset own format count */ /* Reset own format count */
rdpsnd->format_count = 0; rdpsnd->format_count = 0;
if (Stream_GetRemainingLength(input_stream) < 20)
return;
/* Format header */ /* Format header */
Stream_Seek(input_stream, 14); Stream_Seek(input_stream, 14);
Stream_Read_UINT16(input_stream, server_format_count); Stream_Read_UINT16(input_stream, server_format_count);
@ -96,6 +99,9 @@ void guac_rdpsnd_formats_handler(guac_rdp_common_svc* svc,
/* Remember position in stream */ /* Remember position in stream */
Stream_GetPointer(input_stream, format_start); Stream_GetPointer(input_stream, format_start);
if (Stream_GetRemainingLength(input_stream) < 18)
return;
/* Read format */ /* Read format */
Stream_Read_UINT16(input_stream, format_tag); Stream_Read_UINT16(input_stream, format_tag);
Stream_Read_UINT16(input_stream, channels); Stream_Read_UINT16(input_stream, channels);
@ -106,6 +112,10 @@ void guac_rdpsnd_formats_handler(guac_rdp_common_svc* svc,
/* Skip past extra data */ /* Skip past extra data */
Stream_Read_UINT16(input_stream, body_size); Stream_Read_UINT16(input_stream, body_size);
if (Stream_GetRemainingLength(input_stream) < body_size)
return;
Stream_Seek(input_stream, body_size); Stream_Seek(input_stream, body_size);
/* If PCM, accept */ /* If PCM, accept */
@ -205,6 +215,9 @@ void guac_rdpsnd_training_handler(guac_rdp_common_svc* svc,
guac_rdpsnd* rdpsnd = (guac_rdpsnd*) svc->data; guac_rdpsnd* rdpsnd = (guac_rdpsnd*) svc->data;
if (Stream_GetRemainingLength(input_stream) < 4)
return;
/* Read timestamp and data size */ /* Read timestamp and data size */
Stream_Read_UINT16(input_stream, rdpsnd->server_timestamp); Stream_Read_UINT16(input_stream, rdpsnd->server_timestamp);
Stream_Read_UINT16(input_stream, data_size); Stream_Read_UINT16(input_stream, data_size);
@ -232,6 +245,9 @@ void guac_rdpsnd_wave_info_handler(guac_rdp_common_svc* svc,
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
guac_audio_stream* audio = rdp_client->audio; guac_audio_stream* audio = rdp_client->audio;
if (Stream_GetRemainingLength(input_stream) < 12)
return;
/* Read wave information */ /* Read wave information */
Stream_Read_UINT16(input_stream, rdpsnd->server_timestamp); Stream_Read_UINT16(input_stream, rdpsnd->server_timestamp);
Stream_Read_UINT16(input_stream, format); Stream_Read_UINT16(input_stream, format);

View File

@ -35,11 +35,23 @@ void guac_rdpsnd_process_receive(guac_rdp_common_svc* svc,
guac_rdpsnd* rdpsnd = (guac_rdpsnd*) svc->data; guac_rdpsnd* rdpsnd = (guac_rdpsnd*) svc->data;
guac_rdpsnd_pdu_header header; guac_rdpsnd_pdu_header header;
/* Check that we at least have a header. */
if (Stream_GetRemainingLength(input_stream) < 4)
return;
/* Read RDPSND PDU header */ /* Read RDPSND PDU header */
Stream_Read_UINT8(input_stream, header.message_type); Stream_Read_UINT8(input_stream, header.message_type);
Stream_Seek_UINT8(input_stream); Stream_Seek_UINT8(input_stream);
Stream_Read_UINT16(input_stream, header.body_size); Stream_Read_UINT16(input_stream, header.body_size);
if (Stream_GetRemainingLength(input_stream) < header.body_size) {
guac_client_log(svc->client, GUAC_LOG_DEBUG, "Not enough bytes in stream."
" Remaining: %d, Body size: %d",
Stream_GetRemainingLength(input_stream),
header.body_size);
return;
}
/* /*
* If next PDU is SNDWAVE (due to receiving WaveInfo PDU previously), * If next PDU is SNDWAVE (due to receiving WaveInfo PDU previously),
* ignore the header and parse as a Wave PDU. * ignore the header and parse as a Wave PDU.

View File

@ -116,6 +116,10 @@ static VOID guac_rdp_common_svc_handle_open_event(LPVOID user_param,
svc->_input_stream = Stream_New(NULL, total_length); svc->_input_stream = Stream_New(NULL, total_length);
} }
/* leave if we don't have a stream. */
if (svc->_input_stream == NULL)
return;
/* Add chunk to buffer only if sufficient space remains */ /* Add chunk to buffer only if sufficient space remains */
if (Stream_EnsureRemainingCapacity(svc->_input_stream, data_length)) if (Stream_EnsureRemainingCapacity(svc->_input_stream, data_length))
Stream_Write(svc->_input_stream, data, data_length); Stream_Write(svc->_input_stream, data, data_length);
@ -137,6 +141,7 @@ static VOID guac_rdp_common_svc_handle_open_event(LPVOID user_param,
svc->_receive_handler(svc, svc->_input_stream); svc->_receive_handler(svc, svc->_input_stream);
Stream_Free(svc->_input_stream, TRUE); Stream_Free(svc->_input_stream, TRUE);
svc->_input_stream = NULL;
} }

View File

@ -39,6 +39,9 @@
static void guac_rdp_ai_read_format(wStream* stream, static void guac_rdp_ai_read_format(wStream* stream,
guac_rdp_ai_format* format) { guac_rdp_ai_format* format) {
if (Stream_GetRemainingLength(stream) < 18)
return;
/* Read audio format into structure */ /* Read audio format into structure */
Stream_Read_UINT16(stream, format->tag); /* wFormatTag */ Stream_Read_UINT16(stream, format->tag); /* wFormatTag */
Stream_Read_UINT16(stream, format->channels); /* nChannels */ Stream_Read_UINT16(stream, format->channels); /* nChannels */
@ -49,7 +52,8 @@ static void guac_rdp_ai_read_format(wStream* stream,
Stream_Read_UINT16(stream, format->data_size); /* cbSize */ Stream_Read_UINT16(stream, format->data_size); /* cbSize */
/* Read arbitrary data block (if applicable) */ /* Read arbitrary data block (if applicable) */
if (format->data_size != 0) { if (format->data_size != 0
&& Stream_GetRemainingLength(stream) >= format->data_size) {
format->data = Stream_Pointer(stream); /* data */ format->data = Stream_Pointer(stream); /* data */
Stream_Seek(stream, format->data_size); Stream_Seek(stream, format->data_size);
} }
@ -232,6 +236,12 @@ static void guac_rdp_ai_send_formatchange(IWTSVirtualChannel* channel,
void guac_rdp_ai_process_version(guac_client* client, void guac_rdp_ai_process_version(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) { IWTSVirtualChannel* channel, wStream* stream) {
if (Stream_GetRemainingLength(stream) < 4) {
guac_client_log(client, GUAC_LOG_WARNING,
"Invalid value provided for AUDIO_INPUT version.");
return;
}
UINT32 version; UINT32 version;
Stream_Read_UINT32(stream, version); Stream_Read_UINT32(stream, version);
@ -258,10 +268,13 @@ void guac_rdp_ai_process_formats(guac_client* client,
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
guac_rdp_audio_buffer* audio_buffer = rdp_client->audio_input; guac_rdp_audio_buffer* audio_buffer = rdp_client->audio_input;
if (Stream_GetRemainingLength(stream) < 8)
return;
UINT32 num_formats; UINT32 num_formats;
Stream_Read_UINT32(stream, num_formats); /* NumFormats */ Stream_Read_UINT32(stream, num_formats); /* NumFormats */
Stream_Seek_UINT32(stream); /* cbSizeFormatsPacket (MUST BE IGNORED) */ Stream_Seek_UINT32(stream); /* cbSizeFormatsPacket (MUST BE IGNORED) */
UINT32 index; UINT32 index;
for (index = 0; index < num_formats; index++) { for (index = 0; index < num_formats; index++) {
@ -306,6 +319,9 @@ void guac_rdp_ai_process_open(guac_client* client,
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
guac_rdp_audio_buffer* audio_buffer = rdp_client->audio_input; guac_rdp_audio_buffer* audio_buffer = rdp_client->audio_input;
if (Stream_GetRemainingLength(stream) < 8)
return;
UINT32 packet_frames; UINT32 packet_frames;
UINT32 initial_format; UINT32 initial_format;

View File

@ -52,10 +52,13 @@
static void guac_rdp_ai_handle_data(guac_client* client, static void guac_rdp_ai_handle_data(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) { IWTSVirtualChannel* channel, wStream* stream) {
if (Stream_GetRemainingLength(stream) < 1)
return;
/* Read message ID from received PDU */ /* Read message ID from received PDU */
BYTE message_id; BYTE message_id;
Stream_Read_UINT8(stream, message_id); Stream_Read_UINT8(stream, message_id);
/* Invoke appropriate message processor based on ID */ /* Invoke appropriate message processor based on ID */
switch (message_id) { switch (message_id) {