Skip to content

Commit

Permalink
Merge staging/1.2.0 changes back to master.
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-jumper committed May 7, 2020
2 parents 9c37fc5 + 0bf65ce commit a0e11dc
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 7 deletions.
35 changes: 35 additions & 0 deletions src/protocols/rdp/channels/rdpdr/rdpdr-fs-messages-file-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,28 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdp_common_svc* svc,
wStream* output_stream;
char destination_path[GUAC_RDP_FS_MAX_PATH];

/* Check stream size prior to reading. */
if (Stream_GetRemainingLength(input_stream) < 6) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Set "
"Information Request (FileRenameInformation) PDU does not "
"contain the expected number of bytes. File redirection "
"may not work as expected.");
return;
}

/* Read structure */
Stream_Seek_UINT8(input_stream); /* ReplaceIfExists */
Stream_Seek_UINT8(input_stream); /* RootDirectory */
Stream_Read_UINT32(input_stream, filename_length); /* FileNameLength */

if (Stream_GetRemainingLength(input_stream) < filename_length) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Set "
"Information Request (FileRenameInformation) PDU does not "
"contain the expected number of bytes. File redirection "
"may not work as expected.");
return;
}

/* Convert name to UTF-8 */
guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), filename_length/2,
destination_path, sizeof(destination_path));
Expand Down Expand Up @@ -192,6 +209,15 @@ void guac_rdpdr_fs_process_set_allocation_info(guac_rdp_common_svc* svc,
UINT64 size;
wStream* output_stream;

/* Check to make sure the stream has at least 8 bytes (UINT64) */
if (Stream_GetRemainingLength(input_stream) < 8) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Set "
"Information Request (FileAllocationInformation) PDU does not "
"contain the expected number of bytes. File redirection "
"may not work as expected.");
return;
}

/* Read new size */
Stream_Read_UINT64(input_stream, size); /* AllocationSize */

Expand Down Expand Up @@ -244,6 +270,15 @@ void guac_rdpdr_fs_process_set_end_of_file_info(guac_rdp_common_svc* svc,
UINT64 size;
wStream* output_stream;

/* Check to make sure stream contains at least 8 bytes (UINT64) */
if (Stream_GetRemainingLength(input_stream) < 8) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Set "
"Information Request (FileEndOfFileInformation) PDU does not "
"contain the expected number of bytes. File redirection "
"may not work as expected.");
return;
}

/* Read new size */
Stream_Read_UINT64(input_stream, size); /* AllocationSize */

Expand Down
84 changes: 83 additions & 1 deletion src/protocols/rdp/channels/rdpdr/rdpdr-fs-messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ void guac_rdpdr_fs_process_create(guac_rdp_common_svc* svc,
int create_disposition, create_options, path_length;
char path[GUAC_RDP_FS_MAX_PATH];

/* Check remaining stream data prior to reading. */
if (Stream_GetRemainingLength(input_stream) < 32) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Create Drive "
"Request PDU does not contain the expected number of bytes. "
"Drive redirection may not work as expected.");
return;
}

/* Read "create" information */
Stream_Read_UINT32(input_stream, desired_access);
Stream_Seek_UINT64(input_stream); /* allocation size */
Expand All @@ -57,6 +65,14 @@ void guac_rdpdr_fs_process_create(guac_rdp_common_svc* svc,
Stream_Read_UINT32(input_stream, create_options);
Stream_Read_UINT32(input_stream, path_length);

/* Check to make sure the stream contains path_length bytes. */
if(Stream_GetRemainingLength(input_stream) < path_length) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Create Drive "
"Request PDU does not contain the expected number of bytes. "
"Drive redirection may not work as expected.");
return;
}

/* Convert path to UTF-8 */
guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path_length/2 - 1,
path, sizeof(path));
Expand Down Expand Up @@ -123,6 +139,14 @@ void guac_rdpdr_fs_process_read(guac_rdp_common_svc* svc,

wStream* output_stream;

/* Check remaining bytes before reading stream. */
if (Stream_GetRemainingLength(input_stream) < 12) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Read "
"Request PDU does not contain the expected number of bytes. "
"Drive redirection may not work as expected.");
return;
}

/* Read packet */
Stream_Read_UINT32(input_stream, length);
Stream_Read_UINT64(input_stream, offset);
Expand Down Expand Up @@ -172,6 +196,14 @@ void guac_rdpdr_fs_process_write(guac_rdp_common_svc* svc,

wStream* output_stream;

/* Check remaining length. */
if (Stream_GetRemainingLength(input_stream) < 32) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Write "
"Request PDU does not contain the expected number of bytes. "
"Drive redirection may not work as expected.");
return;
}

/* Read packet */
Stream_Read_UINT32(input_stream, length);
Stream_Read_UINT64(input_stream, offset);
Expand All @@ -181,6 +213,14 @@ void guac_rdpdr_fs_process_write(guac_rdp_common_svc* svc,
"%s: [file_id=%i] length=%i, offset=%" PRIu64,
__func__, iorequest->file_id, length, (uint64_t) offset);

/* Check to make sure stream contains at least length bytes */
if (Stream_GetRemainingLength(input_stream) < length) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Write "
"Request PDU does not contain the expected number of bytes. "
"Drive redirection may not work as expected.");
return;
}

/* Attempt write */
bytes_written = guac_rdp_fs_write((guac_rdp_fs*) device->data,
iorequest->file_id, offset, Stream_Pointer(input_stream), length);
Expand Down Expand Up @@ -244,6 +284,14 @@ void guac_rdpdr_fs_process_volume_info(guac_rdp_common_svc* svc,

int fs_information_class;

/* Check remaining length */
if (Stream_GetRemainingLength(input_stream) < 4) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Query "
"Volume Information PDU does not contain the expected number "
"of bytes. Drive redirection may not work as expected.");
return;
}

Stream_Read_UINT32(input_stream, fs_information_class);

/* Dispatch to appropriate class-specific handler */
Expand Down Expand Up @@ -282,6 +330,14 @@ void guac_rdpdr_fs_process_file_info(guac_rdp_common_svc* svc,

int fs_information_class;

/* Check remaining length */
if (Stream_GetRemainingLength(input_stream) < 4) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Query "
"Information PDU does not contain the expected number of "
"bytes. Drive redirection may not work as expected.");
return;
}

Stream_Read_UINT32(input_stream, fs_information_class);

/* Dispatch to appropriate class-specific handler */
Expand Down Expand Up @@ -328,6 +384,14 @@ void guac_rdpdr_fs_process_set_file_info(guac_rdp_common_svc* svc,
int fs_information_class;
int length;

/* Check remaining length */
if (Stream_GetRemainingLength(input_stream) < 32) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Set "
"Information PDU does not contain the expected number of "
"bytes. Drive redirection may not work as expected.");
return;
}

Stream_Read_UINT32(input_stream, fs_information_class);
Stream_Read_UINT32(input_stream, length); /* Length */
Stream_Seek(input_stream, 24); /* Padding */
Expand Down Expand Up @@ -406,6 +470,13 @@ void guac_rdpdr_fs_process_query_directory(guac_rdp_common_svc* svc,
if (file == NULL)
return;

if (Stream_GetRemainingLength(input_stream) < 9) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Query "
"Directory PDU does not contain the expected number of bytes. "
"Drive redirection may not work as expected.");
return;
}

/* Read main header */
Stream_Read_UINT32(input_stream, fs_information_class);
Stream_Read_UINT8(input_stream, initial_query);
Expand All @@ -414,8 +485,19 @@ 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 (initial_query) {

/*
* Check to make sure Stream has at least the 23 padding bytes in it
* prior to seeking.
*/
if (Stream_GetRemainingLength(input_stream) < (23 + path_length)) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Drive Query "
"Directory PDU does not contain the expected number of "
"bytes. Drive redirection may not work as expected.");
return;
}

Stream_Seek(input_stream, 23); /* Padding */

/* Convert path to UTF-8 */
guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path_length/2 - 1,
file->dir_pattern, sizeof(file->dir_pattern));
Expand Down
50 changes: 50 additions & 0 deletions src/protocols/rdp/channels/rdpdr/rdpdr-messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,14 @@ void guac_rdpdr_process_server_announce(guac_rdp_common_svc* svc,

unsigned int major, minor, client_id;

/* Stream should contain at least 8 bytes (UINT16 + UINT16 + UINT32) */
if (Stream_GetRemainingLength(input_stream) < 8) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Announce "
"Request PDU does not contain the expected number of bytes. "
"Device redirection may not work as expected.");
return;
}

Stream_Read_UINT16(input_stream, major);
Stream_Read_UINT16(input_stream, minor);
Stream_Read_UINT32(input_stream, client_id);
Expand Down Expand Up @@ -243,6 +251,14 @@ void guac_rdpdr_process_device_reply(guac_rdp_common_svc* svc,
unsigned int device_id, ntstatus;
int severity, c, n, facility, code;

/* Stream should contain at least 8 bytes (UINT32 + UINT32 ) */
if (Stream_GetRemainingLength(input_stream) < 8) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Device Announce"
"Response PDU does not contain the expected number of bytes."
"Device redirection may not work as expected.");
return;
}

Stream_Read_UINT32(input_stream, device_id);
Stream_Read_UINT32(input_stream, ntstatus);

Expand Down Expand Up @@ -278,6 +294,14 @@ void guac_rdpdr_process_device_iorequest(guac_rdp_common_svc* svc,
guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data;
guac_rdpdr_iorequest iorequest;

/* Check to make sure the Stream contains at least 20 bytes (5 x UINT32 ). */
if (Stream_GetRemainingLength(input_stream) < 20) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Device I/O Request PDU "
"does not contain the expected number of bytes. Device "
"redirection may not work as expected.");
return;
}

/* Read header */
Stream_Read_UINT32(input_stream, iorequest.device_id);
Stream_Read_UINT32(input_stream, iorequest.file_id);
Expand Down Expand Up @@ -306,6 +330,14 @@ void guac_rdpdr_process_server_capability(guac_rdp_common_svc* svc,
int count;
int i;

/* Check to make sure the Stream has at least 4 bytes (UINT16 + 2) */
if (Stream_GetRemainingLength(input_stream) < 4) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Core Capability "
"Request PDU does not contain the expected number of bytes."
"Device redirection may not work as expected.");
return;
}

/* Read header */
Stream_Read_UINT16(input_stream, count);
Stream_Seek(input_stream, 2);
Expand All @@ -316,9 +348,27 @@ void guac_rdpdr_process_server_capability(guac_rdp_common_svc* svc,
int type;
int length;

/* Make sure Stream has at least 4 bytes (UINT16 + UINT16) */
if (Stream_GetRemainingLength(input_stream) < 4) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Core "
"Capability Request PDU does not contain the expected "
"number of bytes. Device redirection may not work as "
"expected.");
break;
}

Stream_Read_UINT16(input_stream, type);
Stream_Read_UINT16(input_stream, length);

/* Make sure Stream has required length remaining for Seek below. */
if (Stream_GetRemainingLength(input_stream) < (length - 4)) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Core "
"Capability Request PDU does not contain the expected "
"number of bytes. Device redirection may not work as "
"expected.");
break;
}

/* Ignore all for now */
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);
Expand Down
16 changes: 16 additions & 0 deletions src/protocols/rdp/channels/rdpdr/rdpdr-printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,28 @@ void guac_rdpdr_process_print_job_write(guac_rdp_common_svc* svc,
int length;
int status;

/* Verify that Stream contains at least 32 bytes (UINT32 + 8 + 20) */
if (Stream_GetRemainingLength(input_stream) < 32) {
guac_client_log(client, GUAC_LOG_WARNING, "Print job write stream does "
"not contain the expected number of bytes. Printer redirection "
"may not work as expected.");
return;
}

/* Read buffer of print data */
Stream_Read_UINT32(input_stream, length);
Stream_Seek(input_stream, 8); /* Offset */
Stream_Seek(input_stream, 20); /* Padding */
buffer = Stream_Pointer(input_stream);

/* Verify the stream has at least length number of bytes remaining. */
if (Stream_GetRemainingLength(input_stream) < length) {
guac_client_log(client, GUAC_LOG_WARNING, "Print job write stream does "
"not contain the expected number of bytes. Printer redirection "
"may not work as expected.");
return;
}

/* Write data only if job exists, translating status for RDP */
if (job != NULL && (length = guac_rdp_print_job_write(job,
buffer, length)) >= 0) {
Expand Down
11 changes: 11 additions & 0 deletions src/protocols/rdp/channels/rdpdr/rdpdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ void guac_rdpdr_process_receive(guac_rdp_common_svc* svc,
int component;
int packet_id;

/*
* Check that device redirection stream contains at least 4 bytes
* (UINT16 + UINT16).
*/
if (Stream_GetRemainingLength(input_stream) < 4) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Device redirection "
"channel PDU header does not contain the expected number of "
"bytes. Device redirection may not function as expected.");
return;
}

/* Read header */
Stream_Read_UINT16(input_stream, component);
Stream_Read_UINT16(input_stream, packet_id);
Expand Down
Loading

0 comments on commit a0e11dc

Please sign in to comment.