libfreerdp-core: fix leak and use after free in tsg ListDictionary usage
This commit is contained in:
parent
d8e10ac04a
commit
cc2321d359
@ -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;
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user