libfreerdp-core: fix leak and use after free in tsg ListDictionary usage

This commit is contained in:
Marc-André Moreau 2014-12-11 17:08:22 -05:00
parent d8e10ac04a
commit cc2321d359
5 changed files with 33 additions and 33 deletions

View File

@ -402,8 +402,6 @@ BOOL http_response_parse_header_field(HttpResponse* http_response, char* name, c
} }
status = ListDictionary_Add(http_response->Authenticates, authScheme, authValue); status = ListDictionary_Add(http_response->Authenticates, authScheme, authValue);
free(authScheme);
} }
return status; return status;
@ -571,7 +569,7 @@ HttpResponse* http_response_recv(rdpTls* tls)
if (count) if (count)
{ {
http_response->lines = (char**)calloc(http_response->count, sizeof(char*)); http_response->lines = (char**) calloc(http_response->count, sizeof(char*));
if (!http_response->lines) if (!http_response->lines)
goto out_error; goto out_error;
@ -598,7 +596,7 @@ HttpResponse* http_response_recv(rdpTls* tls)
if (http_response->bodyLen > 0) if (http_response->bodyLen > 0)
{ {
http_response->BodyContent = (BYTE*)malloc(http_response->bodyLen); http_response->BodyContent = (BYTE*) malloc(http_response->bodyLen);
if (!http_response->BodyContent) if (!http_response->BodyContent)
goto out_error; goto out_error;

View File

@ -92,18 +92,21 @@ int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc)
int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc) int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc)
{ {
char* token64;
int ntlm_token_length = 0; int ntlm_token_length = 0;
BYTE* ntlm_token_data = NULL; BYTE* ntlm_token_data = NULL;
HttpResponse* http_response; HttpResponse* http_response;
rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm; rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm;
http_response = http_response_recv(rpc->TlsIn); http_response = http_response_recv(rpc->TlsIn);
if (!http_response) if (!http_response)
return -1; return -1;
if (ListDictionary_Contains(http_response->Authenticates, "NTLM")) if (ListDictionary_Contains(http_response->Authenticates, "NTLM"))
{ {
char *token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM"); token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM");
if (!token64) if (!token64)
goto out; goto out;
@ -135,7 +138,7 @@ int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel)
if (instance->GatewayAuthenticate) if (instance->GatewayAuthenticate)
{ {
BOOL proceed = instance->GatewayAuthenticate(instance, &settings->GatewayUsername, BOOL proceed = instance->GatewayAuthenticate(instance, &settings->GatewayUsername,
&settings->GatewayPassword, &settings->GatewayDomain); &settings->GatewayPassword, &settings->GatewayDomain);
if (!proceed) if (!proceed)
{ {
@ -170,8 +173,8 @@ int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel)
BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc) BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc)
{ {
rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm;
BOOL success = FALSE; BOOL success = FALSE;
rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm;
if (rpc_ncacn_http_ntlm_init(rpc, TSG_CHANNEL_IN) == 1) if (rpc_ncacn_http_ntlm_init(rpc, TSG_CHANNEL_IN) == 1)
{ {
@ -221,6 +224,7 @@ 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)
{ {
char* token64;
int ntlm_token_length = 0; int ntlm_token_length = 0;
BYTE* ntlm_token_data = NULL; BYTE* ntlm_token_data = NULL;
HttpResponse* http_response; HttpResponse* http_response;
@ -228,11 +232,12 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
http_response = http_response_recv(rpc->TlsOut); http_response = http_response_recv(rpc->TlsOut);
ntlm_token_data = NULL; if (!http_response)
return -1;
if (http_response && ListDictionary_Contains(http_response->Authenticates, "NTLM")) if (ListDictionary_Contains(http_response->Authenticates, "NTLM"))
{ {
char* token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM"); 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);
} }
@ -240,6 +245,7 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
ntlm->inputBuffer[0].cbBuffer = ntlm_token_length; ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
http_response_free(http_response); http_response_free(http_response);
return 0; return 0;
} }
@ -287,11 +293,11 @@ void rpc_ntlm_http_init_channel(rdpRpc* rpc, rdpNtlmHttp* ntlm_http, TSG_CHANNEL
if (channel == TSG_CHANNEL_IN) if (channel == TSG_CHANNEL_IN)
{ {
http_context_set_pragma(ntlm_http->context, "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729"); http_context_set_pragma(ntlm_http->context, "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729");
} }
else if (channel == TSG_CHANNEL_OUT) else if (channel == TSG_CHANNEL_OUT)
{ {
http_context_set_pragma(ntlm_http->context, "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, " http_context_set_pragma(ntlm_http->context, "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, "
"SessionId=fbd9c34f-397d-471d-a109-1b08cc554624"); "SessionId=fbd9c34f-397d-471d-a109-1b08cc554624");
} }
} }

View File

@ -65,6 +65,8 @@ BOOL rts_connect(rdpRpc* rpc)
RPC_PDU* pdu; RPC_PDU* pdu;
rpcconn_rts_hdr_t* rts; rpcconn_rts_hdr_t* rts;
HttpResponse* http_response; HttpResponse* http_response;
freerdp* instance = (freerdp*) rpc->settings->instance;
rdpContext* context = instance->context;
/** /**
* Connection Opening * Connection Opening
@ -90,7 +92,7 @@ BOOL rts_connect(rdpRpc* rpc)
*/ */
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_INITIAL; rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
DEBUG_RTS("VIRTUAL_CONNECTION_STATE_INITIAL"); WLog_DBG(TAG, "VIRTUAL_CONNECTION_STATE_INITIAL");
rpc->client->SynchronousSend = TRUE; rpc->client->SynchronousSend = TRUE;
rpc->client->SynchronousReceive = TRUE; rpc->client->SynchronousReceive = TRUE;
@ -120,7 +122,7 @@ BOOL rts_connect(rdpRpc* rpc)
} }
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT; rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT;
DEBUG_RTS("VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT"); WLog_DBG(TAG, "VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT");
/** /**
* Receive OUT Channel Response * Receive OUT Channel Response
@ -170,9 +172,9 @@ BOOL rts_connect(rdpRpc* rpc)
connectErrorCode = AUTHENTICATIONERROR; connectErrorCode = AUTHENTICATIONERROR;
} }
if (!freerdp_get_last_error(((freerdp*)(rpc->settings->instance))->context)) if (!freerdp_get_last_error(context))
{ {
freerdp_set_last_error(((freerdp*)(rpc->settings->instance))->context, FREERDP_ERROR_AUTHENTICATION_FAILED); freerdp_set_last_error(context, FREERDP_ERROR_AUTHENTICATION_FAILED);
} }
} }
@ -191,7 +193,7 @@ BOOL rts_connect(rdpRpc* rpc)
http_response_free(http_response); http_response_free(http_response);
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_A3W; rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_A3W;
DEBUG_RTS("VIRTUAL_CONNECTION_STATE_WAIT_A3W"); WLog_DBG(TAG, "VIRTUAL_CONNECTION_STATE_WAIT_A3W");
/** /**
* Receive CONN_A3 RTS PDU * Receive CONN_A3 RTS PDU
@ -229,7 +231,7 @@ BOOL rts_connect(rdpRpc* rpc)
rpc_client_receive_pool_return(rpc, pdu); rpc_client_receive_pool_return(rpc, pdu);
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_C2; rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_C2;
DEBUG_RTS("VIRTUAL_CONNECTION_STATE_WAIT_C2"); WLog_DBG(TAG, "VIRTUAL_CONNECTION_STATE_WAIT_C2");
/** /**
* Receive CONN_C2 RTS PDU * Receive CONN_C2 RTS PDU
@ -269,7 +271,7 @@ BOOL rts_connect(rdpRpc* rpc)
rpc_client_receive_pool_return(rpc, pdu); rpc_client_receive_pool_return(rpc, pdu);
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_OPENED; rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_OPENED;
DEBUG_RTS("VIRTUAL_CONNECTION_STATE_OPENED"); WLog_DBG(TAG, "VIRTUAL_CONNECTION_STATE_OPENED");
rpc->client->SynchronousSend = TRUE; rpc->client->SynchronousSend = TRUE;
rpc->client->SynchronousReceive = TRUE; rpc->client->SynchronousReceive = TRUE;
@ -720,7 +722,7 @@ int rts_recv_CONN_A3_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
rts_connection_timeout_command_read(rpc, &buffer[24], length - 24, &ConnectionTimeout); rts_connection_timeout_command_read(rpc, &buffer[24], length - 24, &ConnectionTimeout);
DEBUG_RTS("ConnectionTimeout: %d", ConnectionTimeout); WLog_DBG(TAG, "ConnectionTimeout: %d", ConnectionTimeout);
rpc->VirtualConnection->DefaultInChannel->PingOriginator.ConnectionTimeout = ConnectionTimeout; rpc->VirtualConnection->DefaultInChannel->PingOriginator.ConnectionTimeout = ConnectionTimeout;
@ -787,8 +789,8 @@ int rts_recv_CONN_C2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
offset += rts_receive_window_size_command_read(rpc, &buffer[offset], length - offset, &ReceiveWindowSize) + 4; offset += rts_receive_window_size_command_read(rpc, &buffer[offset], length - offset, &ReceiveWindowSize) + 4;
offset += rts_connection_timeout_command_read(rpc, &buffer[offset], length - offset, &ConnectionTimeout) + 4; offset += rts_connection_timeout_command_read(rpc, &buffer[offset], length - offset, &ConnectionTimeout) + 4;
DEBUG_RTS("ConnectionTimeout: %d", ConnectionTimeout); WLog_DBG(TAG, "ConnectionTimeout: %d", ConnectionTimeout);
DEBUG_RTS("ReceiveWindowSize: %d", ReceiveWindowSize); WLog_DBG(TAG, "ReceiveWindowSize: %d", ReceiveWindowSize);
/* TODO: verify if this is the correct protocol variable */ /* TODO: verify if this is the correct protocol variable */
rpc->VirtualConnection->DefaultInChannel->PingOriginator.ConnectionTimeout = ConnectionTimeout; rpc->VirtualConnection->DefaultInChannel->PingOriginator.ConnectionTimeout = ConnectionTimeout;

View File

@ -143,15 +143,4 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length);
#include "rts_signature.h" #include "rts_signature.h"
#ifdef WITH_DEBUG_TSG
#define WITH_DEBUG_RTS
#endif
#define RTS_TAG FREERDP_TAG("core.gateway.rts")
#ifdef WITH_DEBUG_RTS
#define DEBUG_RTS(fmt, ...) WLog_DBG(RTS_TAG, fmt, ## __VA_ARGS__)
#else
#define DEBUG_RTS(fmt, ...) do { } while (0)
#endif
#endif /* FREERDP_CORE_RTS_H */ #endif /* FREERDP_CORE_RTS_H */

View File

@ -229,8 +229,13 @@ void ListDictionary_Clear(wListDictionary* listDictionary)
while (item) while (item)
{ {
nextItem = item->next; nextItem = item->next;
if (listDictionary->objectKey.fnObjectFree)
listDictionary->objectKey.fnObjectFree(item->key);
if (listDictionary->objectValue.fnObjectFree) if (listDictionary->objectValue.fnObjectFree)
listDictionary->objectValue.fnObjectFree(item->value); listDictionary->objectValue.fnObjectFree(item->value);
free(item); free(item);
item = nextItem; item = nextItem;
} }