freerdp: patch leaks reported by valgrind when using TS Gateway
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 11 Dec 2014 16:25:34 +0000 (11:25 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 11 Dec 2014 16:25:34 +0000 (11:25 -0500)
13 files changed:
client/common/client.c
docs/valgrind.supp
libfreerdp/core/gateway/http.c
libfreerdp/core/gateway/ncacn_http.c
libfreerdp/core/gateway/ntlm.c
libfreerdp/core/gateway/rpc.c
libfreerdp/core/gateway/rpc_bind.c
libfreerdp/core/gateway/rpc_client.c
libfreerdp/core/gateway/rts.c
libfreerdp/core/gateway/tsg.c
libfreerdp/core/settings.c
libfreerdp/core/transport.c
winpr/libwinpr/utils/collections/ListDictionary.c

index 86eed62..3c09b67 100644 (file)
@@ -112,19 +112,25 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings)
                {
                        if (settings->Username)
                        {
+                               free(settings->GatewayUsername);
                                settings->GatewayUsername = _strdup(settings->Username);
+
                                if (!settings->GatewayUsername)
                                        goto out_error;
                        }
                        if (settings->Domain)
                        {
+                               free(settings->GatewayDomain);
                                settings->GatewayDomain = _strdup(settings->Domain);
+
                                if (!settings->GatewayDomain)
                                        goto out_error;
                        }
                        if (settings->Password)
                        {
+                               free(settings->GatewayPassword);
                                settings->GatewayPassword = _strdup(settings->Password);
+
                                if (!settings->GatewayPassword)
                                        goto out_error;
                        }
index 440d92c..2ce34e8 100644 (file)
   fun:ssl3_write_pending
   fun:ssl3_write_bytes
 }
+
+{
+   g_type_init
+   Memcheck:Leak
+   ...
+   fun:g_type_init_with_debug_flags
+}
+{
+   gobject_init_ctor
+   Memcheck:Leak
+   ...
+   fun:gobject_init_ctor
+}
+{
+   g_type_register_static
+   Memcheck:Leak
+   ...
+   fun:g_type_register_static
+}
+{
+   g_type_register_fundamental
+   Memcheck:Leak
+   ...
+   fun:g_type_register_fundamental
+}
+{
+   g_type_add_interface_static
+   Memcheck:Leak
+   ...
+   fun:g_type_add_interface_static
+}
+{
+   g_type_class_ref
+   Memcheck:Leak
+   ...
+   fun:g_type_class_ref
+}
+
+{
+  XGetDefault
+  Memcheck:Leak
+  ...
+  fun:XGetDefault
+}
index 8eb3898..7fb91d1 100644 (file)
@@ -360,17 +360,21 @@ BOOL http_response_parse_header_status_line(HttpResponse* http_response, char* s
 
 BOOL http_response_parse_header_field(HttpResponse* http_response, char* name, char* value)
 {
+       BOOL status = TRUE;
+
        if (_stricmp(name, "Content-Length") == 0)
        {
                http_response->ContentLength = atoi(value);
        }
        else if (_stricmp(name, "WWW-Authenticate") == 0)
        {
-               char* separator;
-               char* authScheme, *authValue;
+               char* separator = NULL;
+               char* authScheme = NULL;
+               char* authValue = NULL;
+
                separator = strchr(value, ' ');
 
-               if (separator != NULL)
+               if (separator)
                {
                        /* WWW-Authenticate: Basic realm=""
                         * WWW-Authenticate: NTLM base64token
@@ -397,10 +401,12 @@ BOOL http_response_parse_header_field(HttpResponse* http_response, char* name, c
                        authValue = NULL;
                }
 
-               return ListDictionary_Add(http_response->Authenticates, authScheme, authValue);
+               status = ListDictionary_Add(http_response->Authenticates, authScheme, authValue);
+
+               free(authScheme);
        }
 
-       return TRUE;
+       return status;
 }
 
 BOOL http_response_parse_header(HttpResponse* http_response)
@@ -498,6 +504,7 @@ HttpResponse* http_response_recv(rdpTls* tls)
        nbytes = 0;
        length = 10000;
        content = NULL;
+
        buffer = calloc(length, 1);
 
        if (!buffer)
@@ -637,16 +644,19 @@ static void string_free(void* obj1)
 
 HttpResponse* http_response_new()
 {
-       HttpResponse* ret = (HttpResponse*)calloc(1, sizeof(HttpResponse));
+       HttpResponse* ret = (HttpResponse*) calloc(1, sizeof(HttpResponse));
 
        if (!ret)
                return NULL;
 
        ret->Authenticates = ListDictionary_New(FALSE);
+
        ListDictionary_KeyObject(ret->Authenticates)->fnObjectEquals = strings_equals_nocase;
        ListDictionary_KeyObject(ret->Authenticates)->fnObjectFree = string_free;
+
        ListDictionary_ValueObject(ret->Authenticates)->fnObjectEquals = strings_equals_nocase;
        ListDictionary_ValueObject(ret->Authenticates)->fnObjectFree = string_free;
+
        return ret;
 }
 
@@ -665,6 +675,7 @@ void http_response_free(HttpResponse* http_response)
 
        free(http_response->lines);
        free(http_response->ReasonPhrase);
+
        ListDictionary_Free(http_response->Authenticates);
 
        if (http_response->ContentLength > 0)
index b5beff4..d06e9d2 100644 (file)
@@ -222,18 +222,20 @@ int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc)
 int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
 {
        int ntlm_token_length = 0;
-       BYTE* ntlm_token_data;
+       BYTE* ntlm_token_data = NULL;
        HttpResponse* http_response;
        rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm;
 
        http_response = http_response_recv(rpc->TlsOut);
 
        ntlm_token_data = NULL;
+
        if (http_response && ListDictionary_Contains(http_response->Authenticates, "NTLM"))
        {
-               char *token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM");
+               chartoken64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM");
                crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length);
        }
+
        ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
        ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
        
@@ -298,16 +300,18 @@ rdpNtlmHttp* ntlm_http_new()
 {
        rdpNtlmHttp* ntlm_http;
 
-       ntlm_http = (rdpNtlmHttp *)calloc(1, sizeof(rdpNtlmHttp));
+       ntlm_http = (rdpNtlmHttp*) calloc(1, sizeof(rdpNtlmHttp));
 
        if (!ntlm_http)
                return NULL;
 
        ntlm_http->ntlm = ntlm_new();
+
        if (!ntlm_http->ntlm)
                goto out_free;
 
        ntlm_http->context = http_context_new();
+
        if (!ntlm_http->context)
                goto out_free_ntlm;
 
index eeb2500..5ce2b16 100644 (file)
@@ -217,6 +217,7 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm)
        ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN;
        ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken;
        ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer);
+
        if (!ntlm->outputBuffer[0].pvBuffer)
                return FALSE;
 
@@ -295,13 +296,19 @@ void ntlm_client_uninit(rdpNtlm* ntlm)
 
 rdpNtlm* ntlm_new()
 {
-       return (rdpNtlm *)calloc(1, sizeof(rdpNtlm));
+       return (rdpNtlm*) calloc(1, sizeof(rdpNtlm));
 }
 
 void ntlm_free(rdpNtlm* ntlm)
 {
-       if (ntlm != NULL)
+       if (ntlm)
        {
+               if (ntlm->outputBuffer[0].pvBuffer)
+               {
+                       free(ntlm->outputBuffer[0].pvBuffer);
+                       ntlm->outputBuffer[0].pvBuffer = NULL;
+               }
+
                free(ntlm);
        }
 }
index 4d4c675..039fc5d 100644 (file)
@@ -519,12 +519,12 @@ RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
                return NULL;
 
        connection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
-       connection->DefaultInChannel = (RpcInChannel*)calloc(1, sizeof(RpcInChannel));
+       connection->DefaultInChannel = (RpcInChannel*) calloc(1, sizeof(RpcInChannel));
 
        if (!connection->DefaultInChannel)
                goto out_free;
 
-       connection->DefaultOutChannel = (RpcOutChannel*)calloc(1, sizeof(RpcOutChannel));
+       connection->DefaultOutChannel = (RpcOutChannel*) calloc(1, sizeof(RpcOutChannel));
 
        if (!connection->DefaultOutChannel)
                goto out_default_in;
@@ -538,13 +538,15 @@ out_free:
        return NULL;
 }
 
-void rpc_client_virtual_connection_free(RpcVirtualConnection* virtual_connection)
+void rpc_client_virtual_connection_free(RpcVirtualConnection* virtualConnection)
 {
-       if (virtual_connection != NULL)
+       if (virtualConnection)
        {
-               free(virtual_connection->DefaultInChannel);
-               free(virtual_connection->DefaultOutChannel);
-               free(virtual_connection);
+               CloseHandle(virtualConnection->DefaultInChannel->Mutex);
+               CloseHandle(virtualConnection->DefaultOutChannel->Mutex);
+               free(virtualConnection->DefaultInChannel);
+               free(virtualConnection->DefaultOutChannel);
+               free(virtualConnection);
        }
 }
 
@@ -559,6 +561,7 @@ rdpRpc* rpc_new(rdpTransport* transport)
        rpc->transport = transport;
        rpc->settings = transport->settings;
        rpc->SendSeqNum = 0;
+
        rpc->ntlm = ntlm_new();
 
        if (!rpc->ntlm)
@@ -576,6 +579,7 @@ rdpRpc* rpc_new(rdpTransport* transport)
 
        rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpIn, TSG_CHANNEL_IN);
        rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT);
+
        rpc->PipeCallId = 0;
        rpc->StubCallId = 0;
        rpc->StubFragCount = 0;
@@ -594,6 +598,7 @@ rdpRpc* rpc_new(rdpTransport* transport)
        rpc->KeepAliveInterval = 300000;
        rpc->CurrentKeepAliveInterval = rpc->KeepAliveInterval;
        rpc->CurrentKeepAliveTime = 0;
+
        rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);
 
        if (!rpc->VirtualConnection)
@@ -630,19 +635,33 @@ out_free:
 
 void rpc_free(rdpRpc* rpc)
 {
-       if (rpc != NULL)
+       if (rpc)
        {
                rpc_client_stop(rpc);
 
-               if (rpc->State >= RPC_CLIENT_STATE_CONTEXT_NEGOTIATED)
+               if (rpc->ntlm)
                {
                        ntlm_client_uninit(rpc->ntlm);
                        ntlm_free(rpc->ntlm);
+                       rpc->ntlm = NULL;
+               }
+
+               if (rpc->NtlmHttpIn)
+               {
+                       ntlm_http_free(rpc->NtlmHttpIn);
+                       rpc->NtlmHttpIn = NULL;
+               }
+
+               if (rpc->NtlmHttpOut)
+               {
+                       ntlm_http_free(rpc->NtlmHttpOut);
+                       rpc->NtlmHttpOut = NULL;
                }
 
                rpc_client_virtual_connection_free(rpc->VirtualConnection);
                ArrayList_Clear(rpc->VirtualConnectionCookieTable);
                ArrayList_Free(rpc->VirtualConnectionCookieTable);
+
                free(rpc);
        }
 }
index a2679d4..6e982e8 100644 (file)
@@ -105,7 +105,14 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
 
        DEBUG_RPC("Sending bind PDU");
 
+       if (rpc->ntlm)
+       {
+               ntlm_free(rpc->ntlm);
+               rpc->ntlm = NULL;
+       }
+
        rpc->ntlm = ntlm_new();
+
        if (!rpc->ntlm)
                return -1;
 
index 4a5544e..4213a84 100644 (file)
@@ -547,18 +547,13 @@ static void rpc_fragment_free(wStream* fragment)
 
 int rpc_client_new(rdpRpc* rpc)
 {
-       RpcClient* client = NULL;
-       client = (RpcClient*)calloc(1, sizeof(RpcClient));
-       rpc->client = client;
+       RpcClient* client;
 
-       if (!client)
-               return -1;
+       client = (RpcClient*) calloc(1, sizeof(RpcClient));
 
-       client->Thread = CreateThread(NULL, 0,
-                                                                 (LPTHREAD_START_ROUTINE) rpc_client_thread,
-                                                                 rpc, CREATE_SUSPENDED, NULL);
+       rpc->client = client;
 
-       if (!client->Thread)
+       if (!client)
                return -1;
 
        client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -615,8 +610,8 @@ int rpc_client_new(rdpRpc* rpc)
 int rpc_client_start(rdpRpc* rpc)
 {
        rpc->client->Thread = CreateThread(NULL, 0,
-                                                                          (LPTHREAD_START_ROUTINE) rpc_client_thread,
-                                                                          rpc, 0, NULL);
+               (LPTHREAD_START_ROUTINE) rpc_client_thread, rpc, 0, NULL);
+
        return 0;
 }
 
index a4d20f4..4652d6a 100644 (file)
@@ -212,6 +212,7 @@ BOOL rts_connect(rdpRpc* rpc)
        rpc_client_start(rpc);
 
        pdu = rpc_recv_dequeue_pdu(rpc);
+
        if (!pdu)
                return FALSE;
 
index cdd7d09..923f2a3 100644 (file)
@@ -1142,13 +1142,20 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port)
        RpcClientCall* call;
        rdpRpc* rpc = tsg->rpc;
        rdpSettings* settings = rpc->settings;
+
        tsg->Port = port;
+
+       free(tsg->Hostname);
+       tsg->Hostname = NULL;
        ConvertToUnicode(CP_UTF8, 0, hostname, -1, &tsg->Hostname, 0);
+
+       free(tsg->MachineName);
+       tsg->MachineName = NULL;
        ConvertToUnicode(CP_UTF8, 0, settings->ComputerName, -1, &tsg->MachineName, 0);
 
        if (!rpc_connect(rpc))
        {
-               WLog_ERR(TAG,  "rpc_connect failed!");
+               WLog_ERR(TAG, "rpc_connect failed!");
                return FALSE;
        }
 
@@ -1518,6 +1525,7 @@ BOOL tsg_set_blocking_mode(rdpTsg* tsg, BOOL blocking)
 rdpTsg* tsg_new(rdpTransport* transport)
 {
        rdpTsg* tsg;
+
        tsg = (rdpTsg*) calloc(1, sizeof(rdpTsg));
 
        if (!tsg)
@@ -1541,6 +1549,7 @@ void tsg_free(rdpTsg* tsg)
 {
        if (tsg)
        {
+               free(tsg->Hostname);
                free(tsg->MachineName);
                rpc_free(tsg->rpc);
                free(tsg);
index eabb843..8795b5f 100644 (file)
@@ -685,6 +685,10 @@ void freerdp_settings_free(rdpSettings* settings)
                free(settings->RedirectionTsvUrl);
                free(settings->RemoteAssistanceSessionId);
                free(settings->AuthenticationServiceClass);
+               free(settings->GatewayHostname);
+               free(settings->GatewayUsername);
+               free(settings->GatewayPassword);
+               free(settings->GatewayDomain);
                freerdp_target_net_addresses_free(settings);
                freerdp_device_collection_free(settings);
                freerdp_static_channel_collection_free(settings);
index fc2158a..c26686d 100644 (file)
@@ -356,6 +356,7 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
        rdpSettings* settings = transport->settings;
        instance = (freerdp*) transport->settings->instance;
        context = instance->context;
+
        tsg = tsg_new(transport);
 
        if (!tsg)
@@ -1254,9 +1255,21 @@ void transport_free(rdpTransport* transport)
 
        transport->TcpIn = NULL;
        transport->TcpOut = NULL;
-       tsg_free(transport->tsg);
-       transport->tsg = NULL;
+
+       if (transport->tsg)
+       {
+               tsg_free(transport->tsg);
+               transport->tsg = NULL;
+       }
+
+       if (transport->TsgTls)
+       {
+               tls_free(transport->TsgTls);
+               transport->TsgTls = NULL;
+       }
+
        DeleteCriticalSection(&(transport->ReadLock));
        DeleteCriticalSection(&(transport->WriteLock));
+
        free(transport);
 }
index a0690d8..c1733a4 100644 (file)
@@ -181,6 +181,7 @@ BOOL ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
                EnterCriticalSection(&listDictionary->lock);
 
        item = (wListDictionaryItem*) malloc(sizeof(wListDictionaryItem));
+
        if (!item)
                return FALSE;
 
@@ -205,6 +206,7 @@ BOOL ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
 
        if (listDictionary->synchronized)
                LeaveCriticalSection(&listDictionary->lock);
+
        return TRUE;
 }