diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index c586dbb58..a29499339 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -728,8 +728,12 @@ static void xf_post_disconnect(freerdp *instance) assert(NULL != xfc); assert(NULL != instance->settings); - WaitForSingleObject(xfc->mutex, INFINITE); - CloseHandle(xfc->mutex); + if (xfc->mutex) + { + WaitForSingleObject(xfc->mutex, INFINITE); + CloseHandle(xfc->mutex); + xfc->mutex = NULL; + } xf_monitors_free(xfc, instance->settings); } @@ -938,6 +942,10 @@ BOOL xf_post_connect(freerdp* instance) xf_create_window(xfc); ZeroMemory(&gcv, sizeof(gcv)); + + if (xfc->modifier_map) + XFreeModifiermap(xfc->modifier_map); + xfc->modifier_map = XGetModifierMapping(xfc->display); xfc->gc = XCreateGC(xfc->display, xfc->drawable, GCGraphicsExposures, &gcv); @@ -1389,6 +1397,15 @@ void* xf_thread(void* param) if (!status) { + if (xfc->mutex) + { + WaitForSingleObject(xfc->mutex, INFINITE); + CloseHandle(xfc->mutex); + xfc->mutex = NULL; + } + + xf_monitors_free(xfc, instance->settings); + exit_code = XF_EXIT_CONN_FAILED; ExitThread(exit_code); } @@ -1830,7 +1847,6 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context) PubSub_SubscribeParamChange(context->pubSub, (pParamChangeEventHandler) xf_ParamChangeEventHandler); PubSub_SubscribeScalingFactorChange(context->pubSub, (pScalingFactorChangeEventHandler) xf_ScalingFactorChangeEventHandler); - return 0; } diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 7205a7b67..74947fb98 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -475,7 +475,9 @@ static BOOL xf_event_MappingNotify(xfContext* xfc, XEvent* event, BOOL app) { if (event->xmapping.request == MappingModifier) { - XFreeModifiermap(xfc->modifier_map); + if (xfc->modifier_map) + XFreeModifiermap(xfc->modifier_map); + xfc->modifier_map = XGetModifierMapping(xfc->display); } diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 8b5cf0b33..e6427e190 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -38,9 +38,14 @@ void xf_kbd_init(xfContext* xfc) { xf_kbd_clear(xfc); + xfc->keyboard_layout_id = xfc->instance->settings->KeyboardLayout; xfc->keyboard_layout_id = freerdp_keyboard_init(xfc->keyboard_layout_id); xfc->instance->settings->KeyboardLayout = xfc->keyboard_layout_id; + + if (xfc->modifier_map) + XFreeModifiermap(xfc->modifier_map); + xfc->modifier_map = XGetModifierMapping(xfc->display); } diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index fc4d23bf2..e38918846 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -261,10 +261,16 @@ BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings) void xf_monitors_free(xfContext *xfc, rdpSettings *settings) { #ifdef WITH_XINERAMA - if(xfc->vscreen.monitors) + if (xfc->vscreen.monitors) + { free(xfc->vscreen.monitors); + xfc->vscreen.monitors = NULL; + } #endif - if(settings->MonitorIds) + if (settings->MonitorIds) + { free(settings->MonitorIds); + settings->MonitorIds = NULL; + } } diff --git a/include/freerdp/crypto/tls.h b/include/freerdp/crypto/tls.h index a18597308..09ff7a3a0 100644 --- a/include/freerdp/crypto/tls.h +++ b/include/freerdp/crypto/tls.h @@ -58,7 +58,6 @@ FREERDP_API BOOL tls_disconnect(rdpTls* tls); FREERDP_API int tls_read(rdpTls* tls, BYTE* data, int length); FREERDP_API int tls_write(rdpTls* tls, BYTE* data, int length); -FREERDP_API int tls_read_all(rdpTls* tls, BYTE* data, int length); FREERDP_API int tls_write_all(rdpTls* tls, BYTE* data, int length); FREERDP_API int tls_wait_read(rdpTls* tls); diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 97030a760..93b3f2a9d 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -286,22 +286,22 @@ BOOL rdp_client_redirect(rdpRdp* rdp) /* FIXME: this is a subset of rdp_free */ /* --> this should really go into rdp.c */ crypto_rc4_free(rdp->rc4_decrypt_key); - rdp->rc4_decrypt_key = NULL ; + rdp->rc4_decrypt_key = NULL; crypto_rc4_free(rdp->rc4_encrypt_key); rdp->rc4_encrypt_key = NULL; crypto_des3_free(rdp->fips_encrypt); - rdp->fips_encrypt = NULL ; + rdp->fips_encrypt = NULL; crypto_des3_free(rdp->fips_decrypt); - rdp->fips_decrypt = NULL ; + rdp->fips_decrypt = NULL; crypto_hmac_free(rdp->fips_hmac); - rdp->fips_hmac = NULL ; + rdp->fips_hmac = NULL; free(settings->ServerRandom); settings->ServerRandom = NULL ; free(settings->ServerCertificate); - settings->ServerCertificate = NULL ; + settings->ServerCertificate = NULL; free(settings->ClientAddress); - settings->ClientAddress = NULL ; + settings->ClientAddress = NULL; mppc_enc_free(rdp->mppc_enc); mppc_dec_free(rdp->mppc_dec); @@ -364,6 +364,8 @@ BOOL rdp_client_redirect(rdpRdp* rdp) return rdp_client_connect(rdp); } +static BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; + static BOOL rdp_client_establish_keys(rdpRdp* rdp) { BYTE* mod; @@ -380,10 +382,17 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) } /* encrypt client random */ - if (rdp->settings->ClientRandom) free(rdp->settings->ClientRandom); + + if (rdp->settings->ClientRandom) + free(rdp->settings->ClientRandom); + rdp->settings->ClientRandom = malloc(CLIENT_RANDOM_LENGTH); - if (rdp->settings->ClientRandom == NULL) return FALSE; + + if (!rdp->settings->ClientRandom) + return FALSE; + ZeroMemory(crypt_client_random, sizeof(crypt_client_random)); + crypto_nonce(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH); key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength; mod = rdp->settings->RdpServerCertificate->cert_info.Modulus; @@ -422,7 +431,6 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { - BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); @@ -503,7 +511,6 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { - BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 3b88012fe..671840152 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -139,18 +139,28 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings) if (Stream_GetRemainingLength(s) < cbClientAddress) return FALSE; + if (settings->ClientAddress) + { + free(settings->ClientAddress); + settings->ClientAddress = NULL; + } + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL); Stream_Seek(s, cbClientAddress); if (Stream_GetRemainingLength(s) < 2) return FALSE; + Stream_Read_UINT16(s, cbClientDir); /* cbClientDir */ if (Stream_GetRemainingLength(s) < cbClientDir) return FALSE; if (settings->ClientDir) + { free(settings->ClientDir); + settings->ClientDir = NULL; + } ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientDir / 2, &settings->ClientDir, 0, NULL, NULL); Stream_Seek(s, cbClientDir); @@ -238,10 +248,12 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings) clientCookie->logonId = serverCookie->logonId; hmac = crypto_hmac_new(); + crypto_hmac_md5_init(hmac, serverCookie->arcRandomBits, 16); + if (settings->SelectedProtocol == PROTOCOL_RDP) { - crypto_hmac_update(hmac, (BYTE *) (settings->ClientRandom), 32); + crypto_hmac_update(hmac, (BYTE*) (settings->ClientRandom), 32); } else { diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 12475aa8a..6fb547d9d 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -1669,7 +1669,11 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ return FALSE; if (glyph->aj) + { free(glyph->aj); + glyph->aj = NULL; + } + glyph->aj = (BYTE*) malloc(glyph->cb); Stream_Read(s, glyph->aj, glyph->cb); } diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c index 433731df4..4db501033 100644 --- a/libfreerdp/core/redirection.c +++ b/libfreerdp/core/redirection.c @@ -96,6 +96,7 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) if (Stream_GetRemainingLength(s) < 12) return FALSE; + Stream_Read_UINT16(s, flags); /* flags (2 bytes) */ Stream_Read_UINT16(s, length); /* length (2 bytes) */ Stream_Read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */ diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index 904865563..4b57a3354 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -79,6 +79,13 @@ void tcp_get_ip_address(rdpTcp * tcp) tcp->ip_address[sizeof(tcp->ip_address) - 1] = 0; tcp->settings->IPv6Enabled = 0; + + if (tcp->settings->ClientAddress) + { + free(tcp->settings->ClientAddress); + tcp->settings->ClientAddress = NULL; + } + tcp->settings->ClientAddress = _strdup(tcp->ip_address); } diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 3cd138273..d082844c2 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -218,7 +218,6 @@ BOOL transport_connect_tls(rdpTransport* transport) connectErrorCode = TLSCONNECTERROR; tls_free(transport->TsgTls); - transport->TsgTls = NULL; return FALSE; @@ -537,6 +536,12 @@ int transport_read(rdpTransport* transport, wStream* s) pduLength = 0; transport_status = 0; + if (!transport) + return -1; + + if (!s) + return -1; + /* first check if we have header */ streamPosition = Stream_GetPosition(s); @@ -790,6 +795,9 @@ int transport_check_fds(rdpTransport** ptransport) wStream* received; rdpTransport* transport = *ptransport; + if (!transport) + return -1; + #ifdef _WIN32 WSAResetEvent(transport->TcpIn->wsa_event); #endif @@ -881,10 +889,11 @@ int transport_check_fds(rdpTransport** ptransport) recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); if (transport == *ptransport) + { /* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */ /* so only release if still valid */ Stream_Release(received); - + } if (recv_status < 0) status = -1; @@ -1029,12 +1038,20 @@ void transport_free(rdpTransport* transport) if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); - tcp_free(transport->TcpIn); + transport->TlsIn = NULL; + transport->TlsOut = NULL; + + if (transport->TcpIn) + tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); + transport->TcpIn = NULL; + transport->TcpOut = NULL; + tsg_free(transport->tsg); + transport->tsg = NULL; CloseHandle(transport->ReadMutex); CloseHandle(transport->WriteMutex); diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 324e00acf..1b5c92ab8 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -371,9 +371,15 @@ int tls_read(rdpTls* tls, BYTE* data, int length) int error; int status; - status = tls ? SSL_read(tls->ssl, data, length) : -1; + if (!tls) + return -1; - if (tls && status <= 0) + if (!tls->ssl) + return -1; + + status = SSL_read(tls->ssl, data, length); + + if (status <= 0) { error = SSL_get_error(tls->ssl, status); @@ -412,26 +418,17 @@ int tls_read(rdpTls* tls, BYTE* data, int length) return status; } -int tls_read_all(rdpTls* tls, BYTE* data, int length) -{ - int status; - - do - { - status = tls_read(tls, data, length); - if (status == 0) - tls_wait_read(tls); - } - while (status == 0); - - return status; -} - int tls_write(rdpTls* tls, BYTE* data, int length) { int error; int status; + if (!tls) + return -1; + + if (!tls->ssl) + return -1; + status = SSL_write(tls->ssl, data, length); if (status <= 0) @@ -777,7 +774,7 @@ rdpTls* tls_new(rdpSettings* settings) tls = (rdpTls*) malloc(sizeof(rdpTls)); - if (tls != NULL) + if (tls) { ZeroMemory(tls, sizeof(rdpTls)); @@ -793,7 +790,7 @@ rdpTls* tls_new(rdpSettings* settings) void tls_free(rdpTls* tls) { - if (tls != NULL) + if (tls) { if (tls->ssl) {