diff --git a/channels/rdpdr/client/devman.c b/channels/rdpdr/client/devman.c index 2e1666204..315339d92 100644 --- a/channels/rdpdr/client/devman.c +++ b/channels/rdpdr/client/devman.c @@ -6,6 +6,7 @@ * Copyright 2010-2012 Marc-Andre Moreau * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2016 Armin Novak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +43,9 @@ void devman_device_free(DEVICE* device) { + if (!device) + return; + IFCALL(device->Free, device); } @@ -49,6 +53,9 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr) { DEVMAN* devman; + if (!rdpdr) + return NULL; + devman = (DEVMAN*) calloc(1, sizeof(DEVMAN)); if (!devman) @@ -84,6 +91,9 @@ void devman_unregister_device(DEVMAN* devman, void* key) { DEVICE* device; + if (!devman || !key) + return; + device = (DEVICE*) ListDictionary_Remove(devman->devices, key); if (device) @@ -99,6 +109,12 @@ static UINT devman_register_device(DEVMAN* devman, DEVICE* device) { void* key = NULL; + if (!devman || !device) + return ERROR_INVALID_PARAMETER; + + if (device->type != RDPDR_DTYP_FILESYSTEM) + return CHANNEL_RC_OK; + device->id = devman->id_sequence++; key = (void*) (size_t) device->id; @@ -115,6 +131,9 @@ DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id) DEVICE* device = NULL; void* key = (void*) (size_t) id; + if (!devman) + return NULL; + device = (DEVICE*) ListDictionary_GetItemValue(devman->devices, key); return device; @@ -137,6 +156,9 @@ UINT devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device, rdpContext DEVICE_SERVICE_ENTRY_POINTS ep; PDEVICE_SERVICE_ENTRY entry = NULL; + if (!devman || !device || !rdpcontext) + return ERROR_INVALID_PARAMETER; + if (device->Type == RDPDR_DTYP_FILESYSTEM) ServiceName = DRIVE_SERVICE_NAME; else if (device->Type == RDPDR_DTYP_PRINT) diff --git a/channels/rdpdr/client/rdpdr_capabilities.c b/channels/rdpdr/client/rdpdr_capabilities.c index 26f6d529e..1198a53c9 100644 --- a/channels/rdpdr/client/rdpdr_capabilities.c +++ b/channels/rdpdr/client/rdpdr_capabilities.c @@ -128,12 +128,15 @@ static void rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s) Stream_Seek(s, capabilityLength - 4); } -void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s) +UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s) { UINT16 i; UINT16 numCapabilities; UINT16 capabilityType; + if (!rdpdr || !s) + return ERROR_INVALID_PARAMETER; + Stream_Read_UINT16(s, numCapabilities); Stream_Seek(s, 2); /* pad (2 bytes) */ @@ -167,6 +170,8 @@ void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s) break; } } + + return CHANNEL_RC_OK; } /** diff --git a/channels/rdpdr/client/rdpdr_capabilities.h b/channels/rdpdr/client/rdpdr_capabilities.h index bc2ef8b9e..d4e1ecb27 100644 --- a/channels/rdpdr/client/rdpdr_capabilities.h +++ b/channels/rdpdr/client/rdpdr_capabilities.h @@ -25,7 +25,7 @@ #include "rdpdr_main.h" -void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s); +UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s); UINT rdpdr_send_capability_response(rdpdrPlugin* rdpdr); #endif /* FREERDP_CHANNEL_RDPDR_CLIENT_CAPABILITIES_H */ diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 30bd2681d..9581ab0ae 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -81,6 +81,9 @@ static UINT rdpdr_send_device_list_remove_request(rdpdrPlugin* rdpdr, UINT32 cou UINT32 i; wStream* s; + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + s = Stream_New(NULL, 256); if (!s) { @@ -429,7 +432,7 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) BOOL dev_found = FALSE; device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]); - if (!device_ext) + if (!device_ext || !device_ext->path) continue; /* not plugable device */ @@ -592,6 +595,10 @@ out: static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr) { UINT error; + + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + if (rdpdr->hotplugThread) { if (rdpdr->stopEvent) @@ -623,6 +630,9 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr) rdpSettings* settings; UINT error = CHANNEL_RC_OK; + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + rdpdr->devman = devman_new(rdpdr); if (!rdpdr->devman) { @@ -661,13 +671,18 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr) return error; } -static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s) +static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s) { + if (!rdpdr || !s) + return ERROR_INVALID_PARAMETER; + Stream_Read_UINT16(s, rdpdr->versionMajor); Stream_Read_UINT16(s, rdpdr->versionMinor); Stream_Read_UINT32(s, rdpdr->clientID); rdpdr->sequenceId++; + + return CHANNEL_RC_OK; } /** @@ -679,6 +694,9 @@ static UINT rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr) { wStream* s; + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + s = Stream_New(NULL, 12); if (!s) { @@ -707,6 +725,9 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) WCHAR* computerNameW = NULL; size_t computerNameLenW; + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + if (!rdpdr->computerName[0]) gethostname(rdpdr->computerName, sizeof(rdpdr->computerName) - 1); @@ -733,12 +754,15 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) return rdpdr_send(rdpdr, s); } -static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s) +static UINT rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s) { UINT16 versionMajor; UINT16 versionMinor; UINT32 clientID; + if (!rdpdr || !s) + return ERROR_INVALID_PARAMETER; + Stream_Read_UINT16(s, versionMajor); Stream_Read_UINT16(s, versionMinor); Stream_Read_UINT32(s, clientID); @@ -750,9 +774,9 @@ static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s } if (clientID != rdpdr->clientID) - { rdpdr->clientID = clientID; - } + + return CHANNEL_RC_OK; } /** @@ -774,6 +798,9 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use int keyCount; ULONG_PTR* pKeys; + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + s = Stream_New(NULL, 256); if (!s) { @@ -859,6 +886,9 @@ static UINT rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s) IRP* irp; UINT error = CHANNEL_RC_OK; + if (!rdpdr || !s) + return ERROR_INVALID_PARAMETER; + irp = irp_new(rdpdr->devman, s); if (!irp) @@ -888,6 +918,9 @@ static UINT rdpdr_process_init(rdpdrPlugin* rdpdr) ULONG_PTR* pKeys; UINT error = CHANNEL_RC_OK; + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + pKeys = NULL; keyCount = ListDictionary_GetKeys(rdpdr->devman->devices, &pKeys); @@ -921,6 +954,9 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s) UINT32 status; UINT error; + if (!rdpdr || !s) + return ERROR_INVALID_PARAMETER; + Stream_Read_UINT16(s, component); /* Component (2 bytes) */ Stream_Read_UINT16(s, packetId); /* PacketId (2 bytes) */ @@ -929,7 +965,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s) switch (packetId) { case PAKID_CORE_SERVER_ANNOUNCE: - rdpdr_process_server_announce_request(rdpdr, s); + if ((error = rdpdr_process_server_announce_request(rdpdr, s))) + return error; if ((error = rdpdr_send_client_announce_reply(rdpdr))) { WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %lu", error); @@ -948,7 +985,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s) break; case PAKID_CORE_SERVER_CAPABILITY: - rdpdr_process_capability_request(rdpdr, s); + if ((error = rdpdr_process_capability_request(rdpdr, s))) + return error; if ((error = rdpdr_send_capability_response(rdpdr))) { WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %lu", error); @@ -957,7 +995,9 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s) break; case PAKID_CORE_CLIENTID_CONFIRM: - rdpdr_process_server_clientid_confirm(rdpdr, s); + if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s))) + return error; + if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE))) { WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error); @@ -1132,10 +1172,11 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s) UINT status; rdpdrPlugin* plugin = (rdpdrPlugin*) rdpdr; + if (!rdpdr || !s) + return ERROR_INVALID_PARAMETER; + if (!plugin) - { status = CHANNEL_RC_BAD_INIT_HANDLE; - } else { status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle, @@ -1162,6 +1203,9 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, { wStream* data_in; + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME)) { /* @@ -1256,6 +1300,12 @@ static void* rdpdr_virtual_channel_client_thread(void* arg) rdpdrPlugin* rdpdr = (rdpdrPlugin*) arg; UINT error; + if (!rdpdr) + { + ExitThread((DWORD) ERROR_INVALID_PARAMETER); + return NULL; + } + if ((error = rdpdr_process_connect(rdpdr))) { WLog_ERR(TAG, "rdpdr_process_connect failed with error %lu!", error); @@ -1304,6 +1354,9 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa UINT32 status; UINT error; + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + status = rdpdr->channelEntryPoints.pVirtualChannelOpen(rdpdr->InitHandle, &rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event); @@ -1345,6 +1398,9 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr) { UINT error; + if (!rdpdr) + return ERROR_INVALID_PARAMETER; + if (MessageQueue_PostQuit(rdpdr->queue, 0) && (WaitForSingleObject(rdpdr->thread, INFINITE) == WAIT_FAILED)) { error = GetLastError(); @@ -1444,7 +1500,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) rdpdrPlugin* rdpdr; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; - rdpdr = (rdpdrPlugin*) calloc(1, sizeof(rdpdrPlugin)); if (!rdpdr) @@ -1473,7 +1528,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - rc = rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle, &rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpdr_virtual_channel_init_event);