freerdp: patch leaks reported by valgrind when using TS Gateway

This commit is contained in:
Marc-André Moreau
2014-12-11 11:25:34 -05:00
parent b579ad3cec
commit d8e10ac04a
13 changed files with 156 additions and 34 deletions

View File

@@ -112,19 +112,25 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings)
{ {
if (settings->Username) if (settings->Username)
{ {
free(settings->GatewayUsername);
settings->GatewayUsername = _strdup(settings->Username); settings->GatewayUsername = _strdup(settings->Username);
if (!settings->GatewayUsername) if (!settings->GatewayUsername)
goto out_error; goto out_error;
} }
if (settings->Domain) if (settings->Domain)
{ {
free(settings->GatewayDomain);
settings->GatewayDomain = _strdup(settings->Domain); settings->GatewayDomain = _strdup(settings->Domain);
if (!settings->GatewayDomain) if (!settings->GatewayDomain)
goto out_error; goto out_error;
} }
if (settings->Password) if (settings->Password)
{ {
free(settings->GatewayPassword);
settings->GatewayPassword = _strdup(settings->Password); settings->GatewayPassword = _strdup(settings->Password);
if (!settings->GatewayPassword) if (!settings->GatewayPassword)
goto out_error; goto out_error;
} }

View File

@@ -81,3 +81,47 @@
fun:ssl3_write_pending fun:ssl3_write_pending
fun:ssl3_write_bytes 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
}

View 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 http_response_parse_header_field(HttpResponse* http_response, char* name, char* value)
{ {
BOOL status = TRUE;
if (_stricmp(name, "Content-Length") == 0) if (_stricmp(name, "Content-Length") == 0)
{ {
http_response->ContentLength = atoi(value); http_response->ContentLength = atoi(value);
} }
else if (_stricmp(name, "WWW-Authenticate") == 0) else if (_stricmp(name, "WWW-Authenticate") == 0)
{ {
char* separator; char* separator = NULL;
char* authScheme, *authValue; char* authScheme = NULL;
char* authValue = NULL;
separator = strchr(value, ' '); separator = strchr(value, ' ');
if (separator != NULL) if (separator)
{ {
/* WWW-Authenticate: Basic realm="" /* WWW-Authenticate: Basic realm=""
* WWW-Authenticate: NTLM base64token * WWW-Authenticate: NTLM base64token
@@ -397,10 +401,12 @@ BOOL http_response_parse_header_field(HttpResponse* http_response, char* name, c
authValue = NULL; 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) BOOL http_response_parse_header(HttpResponse* http_response)
@@ -498,6 +504,7 @@ HttpResponse* http_response_recv(rdpTls* tls)
nbytes = 0; nbytes = 0;
length = 10000; length = 10000;
content = NULL; content = NULL;
buffer = calloc(length, 1); buffer = calloc(length, 1);
if (!buffer) if (!buffer)
@@ -637,16 +644,19 @@ static void string_free(void* obj1)
HttpResponse* http_response_new() HttpResponse* http_response_new()
{ {
HttpResponse* ret = (HttpResponse*)calloc(1, sizeof(HttpResponse)); HttpResponse* ret = (HttpResponse*) calloc(1, sizeof(HttpResponse));
if (!ret) if (!ret)
return NULL; return NULL;
ret->Authenticates = ListDictionary_New(FALSE); ret->Authenticates = ListDictionary_New(FALSE);
ListDictionary_KeyObject(ret->Authenticates)->fnObjectEquals = strings_equals_nocase; ListDictionary_KeyObject(ret->Authenticates)->fnObjectEquals = strings_equals_nocase;
ListDictionary_KeyObject(ret->Authenticates)->fnObjectFree = string_free; ListDictionary_KeyObject(ret->Authenticates)->fnObjectFree = string_free;
ListDictionary_ValueObject(ret->Authenticates)->fnObjectEquals = strings_equals_nocase; ListDictionary_ValueObject(ret->Authenticates)->fnObjectEquals = strings_equals_nocase;
ListDictionary_ValueObject(ret->Authenticates)->fnObjectFree = string_free; ListDictionary_ValueObject(ret->Authenticates)->fnObjectFree = string_free;
return ret; return ret;
} }
@@ -665,6 +675,7 @@ void http_response_free(HttpResponse* http_response)
free(http_response->lines); free(http_response->lines);
free(http_response->ReasonPhrase); free(http_response->ReasonPhrase);
ListDictionary_Free(http_response->Authenticates); ListDictionary_Free(http_response->Authenticates);
if (http_response->ContentLength > 0) if (http_response->ContentLength > 0)

View 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 rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
{ {
int ntlm_token_length = 0; int ntlm_token_length = 0;
BYTE* ntlm_token_data; BYTE* ntlm_token_data = NULL;
HttpResponse* http_response; HttpResponse* http_response;
rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm; rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm;
http_response = http_response_recv(rpc->TlsOut); http_response = http_response_recv(rpc->TlsOut);
ntlm_token_data = NULL; ntlm_token_data = NULL;
if (http_response && ListDictionary_Contains(http_response->Authenticates, "NTLM")) if (http_response && ListDictionary_Contains(http_response->Authenticates, "NTLM"))
{ {
char *token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM"); char* token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM");
crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length); crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length);
} }
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data; ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
ntlm->inputBuffer[0].cbBuffer = ntlm_token_length; ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
@@ -298,16 +300,18 @@ rdpNtlmHttp* ntlm_http_new()
{ {
rdpNtlmHttp* ntlm_http; rdpNtlmHttp* ntlm_http;
ntlm_http = (rdpNtlmHttp *)calloc(1, sizeof(rdpNtlmHttp)); ntlm_http = (rdpNtlmHttp*) calloc(1, sizeof(rdpNtlmHttp));
if (!ntlm_http) if (!ntlm_http)
return NULL; return NULL;
ntlm_http->ntlm = ntlm_new(); ntlm_http->ntlm = ntlm_new();
if (!ntlm_http->ntlm) if (!ntlm_http->ntlm)
goto out_free; goto out_free;
ntlm_http->context = http_context_new(); ntlm_http->context = http_context_new();
if (!ntlm_http->context) if (!ntlm_http->context)
goto out_free_ntlm; goto out_free_ntlm;

View File

@@ -217,6 +217,7 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm)
ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN; ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN;
ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken; ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken;
ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer); ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer);
if (!ntlm->outputBuffer[0].pvBuffer) if (!ntlm->outputBuffer[0].pvBuffer)
return FALSE; return FALSE;
@@ -295,13 +296,19 @@ void ntlm_client_uninit(rdpNtlm* ntlm)
rdpNtlm* ntlm_new() rdpNtlm* ntlm_new()
{ {
return (rdpNtlm *)calloc(1, sizeof(rdpNtlm)); return (rdpNtlm*) calloc(1, sizeof(rdpNtlm));
} }
void ntlm_free(rdpNtlm* ntlm) 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); free(ntlm);
} }
} }

View File

@@ -519,12 +519,12 @@ RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
return NULL; return NULL;
connection->State = VIRTUAL_CONNECTION_STATE_INITIAL; connection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
connection->DefaultInChannel = (RpcInChannel*)calloc(1, sizeof(RpcInChannel)); connection->DefaultInChannel = (RpcInChannel*) calloc(1, sizeof(RpcInChannel));
if (!connection->DefaultInChannel) if (!connection->DefaultInChannel)
goto out_free; goto out_free;
connection->DefaultOutChannel = (RpcOutChannel*)calloc(1, sizeof(RpcOutChannel)); connection->DefaultOutChannel = (RpcOutChannel*) calloc(1, sizeof(RpcOutChannel));
if (!connection->DefaultOutChannel) if (!connection->DefaultOutChannel)
goto out_default_in; goto out_default_in;
@@ -538,13 +538,15 @@ out_free:
return NULL; 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); CloseHandle(virtualConnection->DefaultInChannel->Mutex);
free(virtual_connection->DefaultOutChannel); CloseHandle(virtualConnection->DefaultOutChannel->Mutex);
free(virtual_connection); free(virtualConnection->DefaultInChannel);
free(virtualConnection->DefaultOutChannel);
free(virtualConnection);
} }
} }
@@ -559,6 +561,7 @@ rdpRpc* rpc_new(rdpTransport* transport)
rpc->transport = transport; rpc->transport = transport;
rpc->settings = transport->settings; rpc->settings = transport->settings;
rpc->SendSeqNum = 0; rpc->SendSeqNum = 0;
rpc->ntlm = ntlm_new(); rpc->ntlm = ntlm_new();
if (!rpc->ntlm) 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->NtlmHttpIn, TSG_CHANNEL_IN);
rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT); rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT);
rpc->PipeCallId = 0; rpc->PipeCallId = 0;
rpc->StubCallId = 0; rpc->StubCallId = 0;
rpc->StubFragCount = 0; rpc->StubFragCount = 0;
@@ -594,6 +598,7 @@ rdpRpc* rpc_new(rdpTransport* transport)
rpc->KeepAliveInterval = 300000; rpc->KeepAliveInterval = 300000;
rpc->CurrentKeepAliveInterval = rpc->KeepAliveInterval; rpc->CurrentKeepAliveInterval = rpc->KeepAliveInterval;
rpc->CurrentKeepAliveTime = 0; rpc->CurrentKeepAliveTime = 0;
rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc); rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);
if (!rpc->VirtualConnection) if (!rpc->VirtualConnection)
@@ -630,19 +635,33 @@ out_free:
void rpc_free(rdpRpc* rpc) void rpc_free(rdpRpc* rpc)
{ {
if (rpc != NULL) if (rpc)
{ {
rpc_client_stop(rpc); rpc_client_stop(rpc);
if (rpc->State >= RPC_CLIENT_STATE_CONTEXT_NEGOTIATED) if (rpc->ntlm)
{ {
ntlm_client_uninit(rpc->ntlm); ntlm_client_uninit(rpc->ntlm);
ntlm_free(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); rpc_client_virtual_connection_free(rpc->VirtualConnection);
ArrayList_Clear(rpc->VirtualConnectionCookieTable); ArrayList_Clear(rpc->VirtualConnectionCookieTable);
ArrayList_Free(rpc->VirtualConnectionCookieTable); ArrayList_Free(rpc->VirtualConnectionCookieTable);
free(rpc); free(rpc);
} }
} }

View File

@@ -105,7 +105,14 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
DEBUG_RPC("Sending bind PDU"); DEBUG_RPC("Sending bind PDU");
if (rpc->ntlm)
{
ntlm_free(rpc->ntlm);
rpc->ntlm = NULL;
}
rpc->ntlm = ntlm_new(); rpc->ntlm = ntlm_new();
if (!rpc->ntlm) if (!rpc->ntlm)
return -1; return -1;

View File

@@ -547,20 +547,15 @@ static void rpc_fragment_free(wStream* fragment)
int rpc_client_new(rdpRpc* rpc) int rpc_client_new(rdpRpc* rpc)
{ {
RpcClient* client = NULL; RpcClient* client;
client = (RpcClient*)calloc(1, sizeof(RpcClient));
client = (RpcClient*) calloc(1, sizeof(RpcClient));
rpc->client = client; rpc->client = client;
if (!client) if (!client)
return -1; return -1;
client->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) rpc_client_thread,
rpc, CREATE_SUSPENDED, NULL);
if (!client->Thread)
return -1;
client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!client->StopEvent) if (!client->StopEvent)
@@ -615,8 +610,8 @@ int rpc_client_new(rdpRpc* rpc)
int rpc_client_start(rdpRpc* rpc) int rpc_client_start(rdpRpc* rpc)
{ {
rpc->client->Thread = CreateThread(NULL, 0, rpc->client->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) rpc_client_thread, (LPTHREAD_START_ROUTINE) rpc_client_thread, rpc, 0, NULL);
rpc, 0, NULL);
return 0; return 0;
} }

View File

@@ -212,6 +212,7 @@ BOOL rts_connect(rdpRpc* rpc)
rpc_client_start(rpc); rpc_client_start(rpc);
pdu = rpc_recv_dequeue_pdu(rpc); pdu = rpc_recv_dequeue_pdu(rpc);
if (!pdu) if (!pdu)
return FALSE; return FALSE;

View File

@@ -1142,13 +1142,20 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port)
RpcClientCall* call; RpcClientCall* call;
rdpRpc* rpc = tsg->rpc; rdpRpc* rpc = tsg->rpc;
rdpSettings* settings = rpc->settings; rdpSettings* settings = rpc->settings;
tsg->Port = port; tsg->Port = port;
free(tsg->Hostname);
tsg->Hostname = NULL;
ConvertToUnicode(CP_UTF8, 0, hostname, -1, &tsg->Hostname, 0); 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); ConvertToUnicode(CP_UTF8, 0, settings->ComputerName, -1, &tsg->MachineName, 0);
if (!rpc_connect(rpc)) if (!rpc_connect(rpc))
{ {
WLog_ERR(TAG, "rpc_connect failed!"); WLog_ERR(TAG, "rpc_connect failed!");
return FALSE; return FALSE;
} }
@@ -1518,6 +1525,7 @@ BOOL tsg_set_blocking_mode(rdpTsg* tsg, BOOL blocking)
rdpTsg* tsg_new(rdpTransport* transport) rdpTsg* tsg_new(rdpTransport* transport)
{ {
rdpTsg* tsg; rdpTsg* tsg;
tsg = (rdpTsg*) calloc(1, sizeof(rdpTsg)); tsg = (rdpTsg*) calloc(1, sizeof(rdpTsg));
if (!tsg) if (!tsg)
@@ -1541,6 +1549,7 @@ void tsg_free(rdpTsg* tsg)
{ {
if (tsg) if (tsg)
{ {
free(tsg->Hostname);
free(tsg->MachineName); free(tsg->MachineName);
rpc_free(tsg->rpc); rpc_free(tsg->rpc);
free(tsg); free(tsg);

View File

@@ -685,6 +685,10 @@ void freerdp_settings_free(rdpSettings* settings)
free(settings->RedirectionTsvUrl); free(settings->RedirectionTsvUrl);
free(settings->RemoteAssistanceSessionId); free(settings->RemoteAssistanceSessionId);
free(settings->AuthenticationServiceClass); free(settings->AuthenticationServiceClass);
free(settings->GatewayHostname);
free(settings->GatewayUsername);
free(settings->GatewayPassword);
free(settings->GatewayDomain);
freerdp_target_net_addresses_free(settings); freerdp_target_net_addresses_free(settings);
freerdp_device_collection_free(settings); freerdp_device_collection_free(settings);
freerdp_static_channel_collection_free(settings); freerdp_static_channel_collection_free(settings);

View File

@@ -356,6 +356,7 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
rdpSettings* settings = transport->settings; rdpSettings* settings = transport->settings;
instance = (freerdp*) transport->settings->instance; instance = (freerdp*) transport->settings->instance;
context = instance->context; context = instance->context;
tsg = tsg_new(transport); tsg = tsg_new(transport);
if (!tsg) if (!tsg)
@@ -1254,9 +1255,21 @@ void transport_free(rdpTransport* transport)
transport->TcpIn = NULL; transport->TcpIn = NULL;
transport->TcpOut = 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->ReadLock));
DeleteCriticalSection(&(transport->WriteLock)); DeleteCriticalSection(&(transport->WriteLock));
free(transport); free(transport);
} }

View File

@@ -181,6 +181,7 @@ BOOL ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
EnterCriticalSection(&listDictionary->lock); EnterCriticalSection(&listDictionary->lock);
item = (wListDictionaryItem*) malloc(sizeof(wListDictionaryItem)); item = (wListDictionaryItem*) malloc(sizeof(wListDictionaryItem));
if (!item) if (!item)
return FALSE; return FALSE;
@@ -205,6 +206,7 @@ BOOL ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
if (listDictionary->synchronized) if (listDictionary->synchronized)
LeaveCriticalSection(&listDictionary->lock); LeaveCriticalSection(&listDictionary->lock);
return TRUE; return TRUE;
} }