From aa8b8432503abd0219801e09af17a99f75582ae1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 11 Feb 2015 11:57:02 -0500 Subject: [PATCH] libfreerdp-core: move stuff down from transport to tsg layer --- libfreerdp/core/gateway/tsg.c | 85 ++++++++++++++++++++- libfreerdp/core/gateway/tsg.h | 2 +- libfreerdp/core/license.c | 23 +++--- libfreerdp/core/nla.c | 4 +- libfreerdp/core/peer.c | 30 ++++---- libfreerdp/core/tcp.c | 37 +-------- libfreerdp/core/transport.c | 173 +++++------------------------------------- 7 files changed, 137 insertions(+), 217 deletions(-) diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 9b17663..bb45fd5 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -1410,16 +1410,93 @@ int tsg_check(rdpTsg* tsg) return status; } -BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) +BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port, int timeout) { + int tls_status; HANDLE events[2]; rdpRpc* rpc = tsg->rpc; rdpSettings* settings = rpc->settings; + rdpTransport* transport = rpc->transport; + rdpContext* context = rpc->context; + + transport->layer = TRANSPORT_LAYER_TSG; + transport->SplitInputOutput = TRUE; + + transport->TcpIn = freerdp_tcp_new(settings); + transport->TcpOut = freerdp_tcp_new(settings); + + if (!freerdp_tcp_connect(transport->TcpIn, settings->GatewayHostname, settings->GatewayPort, timeout) || + !freerdp_tcp_set_blocking_mode(transport->TcpIn, FALSE)) + return FALSE; + + if (!freerdp_tcp_connect(transport->TcpOut, settings->GatewayHostname, settings->GatewayPort, timeout) || + !freerdp_tcp_set_blocking_mode(transport->TcpOut, FALSE)) + return FALSE; + + tsg->transport = transport; + transport->tsg = tsg; + + transport->SplitInputOutput = TRUE; + + transport->TlsIn = tls_new(settings); + + if (!transport->TlsIn) + return FALSE; + + transport->TlsOut = tls_new(settings); + + if (!transport->TlsOut) + return FALSE; + + /* put a decent default value for gateway port */ + if (!settings->GatewayPort) + settings->GatewayPort = 443; + + transport->TlsIn->hostname = transport->TlsOut->hostname = settings->GatewayHostname; + transport->TlsIn->port = transport->TlsOut->port = settings->GatewayPort; + + transport->TlsIn->isGatewayTransport = TRUE; + tls_status = tls_connect(transport->TlsIn, transport->TcpIn->bufferedBio); + + if (tls_status < 1) + { + if (tls_status < 0) + { + if (!freerdp_get_last_error(context)) + freerdp_set_last_error(context, FREERDP_ERROR_TLS_CONNECT_FAILED); + } + else + { + if (!freerdp_get_last_error(context)) + freerdp_set_last_error(context, FREERDP_ERROR_CONNECT_CANCELLED); + } + + return FALSE; + } + + transport->TlsOut->isGatewayTransport = TRUE; + tls_status = tls_connect(transport->TlsOut, transport->TcpOut->bufferedBio); + + if (tls_status < 1) + { + if (tls_status < 0) + { + if (!freerdp_get_last_error(context)) + freerdp_set_last_error(context, FREERDP_ERROR_TLS_CONNECT_FAILED); + } + else + { + if (!freerdp_get_last_error(context)) + freerdp_set_last_error(context, FREERDP_ERROR_CONNECT_CANCELLED); + } + + return FALSE; + } tsg->Port = port; - rpc->TlsIn = rpc->transport->TlsIn; - rpc->TlsOut = rpc->transport->TlsOut; + rpc->TlsIn = transport->TlsIn; + rpc->TlsOut = transport->TlsOut; free(tsg->Hostname); tsg->Hostname = NULL; @@ -1456,6 +1533,8 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) tsg->bio = BIO_new(BIO_s_tsg()); tsg->bio->ptr = tsg; + transport->frontBio = tsg->bio; + return TRUE; } diff --git a/libfreerdp/core/gateway/tsg.h b/libfreerdp/core/gateway/tsg.h index ea732e0..cc8f38f 100644 --- a/libfreerdp/core/gateway/tsg.h +++ b/libfreerdp/core/gateway/tsg.h @@ -306,7 +306,7 @@ DWORD TsProxySendToServer(handle_t IDL_handle, BYTE pRpcMessage[], UINT32 count, int tsg_transition_to_state(rdpTsg* tsg, TSG_STATE state); -BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port); +BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port, int timeout); BOOL tsg_disconnect(rdpTsg* tsg); int tsg_write(rdpTsg* tsg, BYTE* data, UINT32 length); diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index 82b5f0e..93b2116 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -372,9 +372,11 @@ void license_generate_keys(rdpLicense* license) void license_generate_hwid(rdpLicense* license) { CryptoMd5 md5; - BYTE* mac_address; + BYTE macAddress[6]; + + ZeroMemory(macAddress, sizeof(macAddress)); ZeroMemory(license->HardwareId, HWID_LENGTH); - mac_address = license->rdp->transport->TcpIn->mac_address; + md5 = crypto_md5_init(); if (!md5) @@ -383,7 +385,7 @@ void license_generate_hwid(rdpLicense* license) return; } - crypto_md5_update(md5, mac_address, 6); + crypto_md5_update(md5, macAddress, sizeof(macAddress)); crypto_md5_final(md5, &license->HardwareId[HWID_PLATFORM_ID_LENGTH]); } @@ -392,12 +394,12 @@ void license_get_server_rsa_public_key(rdpLicense* license) BYTE* Exponent; BYTE* Modulus; int ModulusLength; + rdpSettings* settings = license->rdp->settings; if (license->ServerCertificate->length < 1) { certificate_read_server_certificate(license->certificate, - license->rdp->settings->ServerCertificate, - license->rdp->settings->ServerCertificateLength); + settings->ServerCertificate, settings->ServerCertificateLength); } Exponent = license->certificate->cert_info.exponent; @@ -406,7 +408,7 @@ void license_get_server_rsa_public_key(rdpLicense* license) CopyMemory(license->Exponent, Exponent, 4); license->ModulusLength = ModulusLength; license->Modulus = (BYTE*) malloc(ModulusLength); - memcpy(license->Modulus, Modulus, ModulusLength); + CopyMemory(license->Modulus, Modulus, ModulusLength); } void license_encrypt_premaster_secret(rdpLicense* license) @@ -419,14 +421,14 @@ void license_encrypt_premaster_secret(rdpLicense* license) WLog_DBG(TAG, "Exponent:"); winpr_HexDump(TAG, WLOG_DEBUG, license->Exponent, 4); #endif - EncryptedPremasterSecret = (BYTE*) malloc(license->ModulusLength); - ZeroMemory(EncryptedPremasterSecret, license->ModulusLength); + EncryptedPremasterSecret = (BYTE*) calloc(1, license->ModulusLength); + license->EncryptedPremasterSecret->type = BB_RANDOM_BLOB; license->EncryptedPremasterSecret->length = PREMASTER_SECRET_LENGTH; #ifndef LICENSE_NULL_PREMASTER_SECRET license->EncryptedPremasterSecret->length = crypto_rsa_public_encrypt(license->PremasterSecret, PREMASTER_SECRET_LENGTH, - license->ModulusLength, license->Modulus, license->Exponent, EncryptedPremasterSecret); + license->ModulusLength, license->Modulus, license->Exponent, EncryptedPremasterSecret); #endif license->EncryptedPremasterSecret->data = EncryptedPremasterSecret; } @@ -434,8 +436,10 @@ void license_encrypt_premaster_secret(rdpLicense* license) void license_decrypt_platform_challenge(rdpLicense* license) { CryptoRc4 rc4; + license->PlatformChallenge->data = (BYTE*) malloc(license->EncryptedPlatformChallenge->length); license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length; + rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); if (!rc4) @@ -447,6 +451,7 @@ void license_decrypt_platform_challenge(rdpLicense* license) crypto_rc4(rc4, license->EncryptedPlatformChallenge->length, license->EncryptedPlatformChallenge->data, license->PlatformChallenge->data); + crypto_rc4_free(rc4); } diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 1829208..35ffc6c 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -148,7 +148,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) if (instance->Authenticate) { BOOL proceed = instance->Authenticate(instance, - &settings->Username, &settings->Password, &settings->Domain); + &settings->Username, &settings->Password, &settings->Domain); if (!proceed) { @@ -174,7 +174,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) free(identity->Password); identity->PasswordLength = ConvertToUnicode(CP_UTF8, 0, - settings->PasswordHash, -1, &identity->Password, 0) - 1; + settings->PasswordHash, -1, &identity->Password, 0) - 1; /** * Multiply password hash length by 64 to obtain a length exceeding * the maximum (256) and use it this for hash identification in WinPR. diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 55b6180..5ba2630 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -607,30 +607,34 @@ static int freerdp_peer_drain_output_buffer(freerdp_peer* peer) void freerdp_peer_context_new(freerdp_peer* client) { rdpRdp* rdp; + rdpContext* context; - client->context = (rdpContext*) calloc(1, client->ContextSize); + context = client->context = (rdpContext*) calloc(1, client->ContextSize); - client->context->ServerMode = TRUE; + if (!context) + return; + + context->ServerMode = TRUE; - client->context->metrics = metrics_new(client->context); + context->metrics = metrics_new(context); - rdp = rdp_new(client->context); + rdp = rdp_new(context); client->input = rdp->input; client->update = rdp->update; client->settings = rdp->settings; client->autodetect = rdp->autodetect; - client->context->rdp = rdp; - client->context->peer = client; - client->context->input = client->input; - client->context->update = client->update; - client->context->settings = client->settings; - client->context->autodetect = client->autodetect; + context->rdp = rdp; + context->peer = client; + context->input = client->input; + context->update = client->update; + context->settings = client->settings; + context->autodetect = client->autodetect; - client->update->context = client->context; - client->input->context = client->context; - client->autodetect->context = client->context; + client->update->context = context; + client->input->context = context; + client->autodetect->context = context; update_register_server_callbacks(client->update); autodetect_register_server_callbacks(client->autodetect); diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index 5dca531..3d4343f 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -612,39 +612,7 @@ void freerdp_tcp_get_ip_address(rdpTcp* tcp) tcp->settings->ClientAddress = _strdup(tcp->ip_address); } -void freerdp_tcp_get_mac_address(rdpTcp* tcp) -{ -#ifdef LINUX - BYTE* mac; - struct ifreq if_req; - struct if_nameindex* ni; - - ni = if_nameindex(); - mac = tcp->mac_address; - - while (ni->if_name != NULL) - { - if (strcmp(ni->if_name, "lo") != 0) - break; - - ni++; - } - - strncpy(if_req.ifr_name, ni->if_name, IF_NAMESIZE); - - if (ioctl(tcp->sockfd, SIOCGIFHWADDR, &if_req) != 0) - { - WLog_ERR(TAG, "failed to obtain MAC address"); - return; - } - - memmove((void*) mac, (void*) &if_req.ifr_ifru.ifru_hwaddr.sa_data[0], 6); -#endif - /* WLog_ERR(TAG, "MAC: %02X:%02X:%02X:%02X:%02X:%02X", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); */ -} - -int uds_connect(const char* path) +int freerdp_uds_connect(const char* path) { #ifndef _WIN32 int status; @@ -960,7 +928,7 @@ BOOL freerdp_tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeou if (tcp->ipcSocket) { - tcp->sockfd = uds_connect(hostname); + tcp->sockfd = freerdp_uds_connect(hostname); if (tcp->sockfd < 0) return FALSE; @@ -1079,7 +1047,6 @@ BOOL freerdp_tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeou BIO_get_event(tcp->socketBio, &tcp->event); freerdp_tcp_get_ip_address(tcp); - freerdp_tcp_get_mac_address(tcp); option_value = 1; option_len = sizeof(option_value); diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index a999dea..3764415 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -71,7 +71,6 @@ void transport_attach(rdpTransport* transport, int sockfd) { freerdp_tcp_attach(transport->TcpIn, sockfd); transport->SplitInputOutput = FALSE; - transport->TcpOut = transport->TcpIn; transport->frontBio = transport->TcpIn->bufferedBio; } @@ -151,14 +150,11 @@ BOOL transport_connect_rdp(rdpTransport* transport) BOOL transport_connect_tls(rdpTransport* transport) { - rdpSettings* settings = transport->settings; - rdpTls* targetTls; - BIO* targetBio; int tls_status; - freerdp* instance; - rdpContext* context; - instance = (freerdp*) transport->settings->instance; - context = instance->context; + BIO* targetBio = NULL; + rdpTls* targetTls = NULL; + rdpContext* context = transport->context; + rdpSettings* settings = transport->settings; if (transport->layer == TRANSPORT_LAYER_TSG) { @@ -169,12 +165,7 @@ BOOL transport_connect_tls(rdpTransport* transport) } else { - if (!transport->TlsIn) - transport->TlsIn = tls_new(settings); - - if (!transport->TlsOut) - transport->TlsOut = transport->TlsIn; - + transport->TlsIn = tls_new(settings); targetTls = transport->TlsIn; targetBio = transport->TcpIn->bufferedBio; transport->layer = TRANSPORT_LAYER_TLS; @@ -280,92 +271,18 @@ BOOL transport_connect_nla(rdpTransport* transport) return TRUE; } -BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16 port) +BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16 port, int timeout) { rdpTsg* tsg; - int tls_status; - freerdp* instance; - rdpContext* context; - rdpSettings* settings = transport->settings; - - instance = (freerdp*) transport->settings->instance; - context = instance->context; tsg = tsg_new(transport); if (!tsg) return FALSE; - tsg->transport = transport; - transport->tsg = tsg; - transport->SplitInputOutput = TRUE; - - if (!transport->TlsIn) - { - transport->TlsIn = tls_new(settings); - - if (!transport->TlsIn) - return FALSE; - } - - if (!transport->TlsOut) - { - transport->TlsOut = tls_new(settings); - - if (!transport->TlsOut) - return FALSE; - } - - /* put a decent default value for gateway port */ - if (!settings->GatewayPort) - settings->GatewayPort = 443; - - transport->TlsIn->hostname = transport->TlsOut->hostname = settings->GatewayHostname; - transport->TlsIn->port = transport->TlsOut->port = settings->GatewayPort; - - transport->TlsIn->isGatewayTransport = TRUE; - tls_status = tls_connect(transport->TlsIn, transport->TcpIn->bufferedBio); - - if (tls_status < 1) - { - if (tls_status < 0) - { - if (!freerdp_get_last_error(context)) - freerdp_set_last_error(context, FREERDP_ERROR_TLS_CONNECT_FAILED); - } - else - { - if (!freerdp_get_last_error(context)) - freerdp_set_last_error(context, FREERDP_ERROR_CONNECT_CANCELLED); - } - - return FALSE; - } - - transport->TlsOut->isGatewayTransport = TRUE; - tls_status = tls_connect(transport->TlsOut, transport->TcpOut->bufferedBio); - - if (tls_status < 1) - { - if (tls_status < 0) - { - if (!freerdp_get_last_error(context)) - freerdp_set_last_error(context, FREERDP_ERROR_TLS_CONNECT_FAILED); - } - else - { - if (!freerdp_get_last_error(context)) - freerdp_set_last_error(context, FREERDP_ERROR_CONNECT_CANCELLED); - } - - return FALSE; - } - - if (!tsg_connect(tsg, hostname, port)) + if (!tsg_connect(tsg, hostname, port, timeout)) return FALSE; - transport->frontBio = tsg->bio; - return TRUE; } @@ -373,32 +290,22 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por { BOOL status = FALSE; rdpSettings* settings = transport->settings; + transport->async = settings->AsyncTransport; if (transport->GatewayEnabled) { - transport->layer = TRANSPORT_LAYER_TSG; - transport->SplitInputOutput = TRUE; - transport->TcpOut = freerdp_tcp_new(settings); - - if (!freerdp_tcp_connect(transport->TcpIn, settings->GatewayHostname, settings->GatewayPort, timeout) || - !freerdp_tcp_set_blocking_mode(transport->TcpIn, FALSE)) - return FALSE; - - if (!freerdp_tcp_connect(transport->TcpOut, settings->GatewayHostname, settings->GatewayPort, timeout) || - !freerdp_tcp_set_blocking_mode(transport->TcpOut, FALSE)) - return FALSE; - - if (!transport_tsg_connect(transport, hostname, port)) + if (!transport_tsg_connect(transport, hostname, port, timeout)) return FALSE; status = TRUE; } else { + transport->TcpIn = freerdp_tcp_new(settings); + status = freerdp_tcp_connect(transport->TcpIn, hostname, port, timeout); transport->SplitInputOutput = FALSE; - transport->TcpOut = transport->TcpIn; transport->frontBio = transport->TcpIn->bufferedBio; } @@ -426,9 +333,6 @@ BOOL transport_accept_tls(rdpTransport* transport) if (!transport->TlsIn) transport->TlsIn = tls_new(transport->settings); - if (!transport->TlsOut) - transport->TlsOut = transport->TlsIn; - transport->layer = TRANSPORT_LAYER_TLS; if (!tls_accept(transport->TlsIn, transport->TcpIn->bufferedBio, transport->settings->CertificateFile, transport->settings->PrivateKeyFile)) @@ -448,9 +352,6 @@ BOOL transport_accept_nla(rdpTransport* transport) if (!transport->TlsIn) transport->TlsIn = tls_new(transport->settings); - if (!transport->TlsOut) - transport->TlsOut = transport->TlsIn; - transport->layer = TRANSPORT_LAYER_TLS; if (!tls_accept(transport->TlsIn, transport->TcpIn->bufferedBio, settings->CertificateFile, settings->PrivateKeyFile)) @@ -797,7 +698,7 @@ int transport_write(rdpTransport* transport, wStream* s) if (transport->blocking || transport->settings->WaitForOutputBufferFlush) { /* blocking transport, we must ensure the write buffer is really empty */ - rdpTcp* out = transport->TcpOut; + rdpTcp* out = transport->SplitInputOutput ? transport->TcpOut : transport->TcpIn; while (out->writeBlocked) { @@ -835,27 +736,15 @@ int transport_write(rdpTransport* transport, wStream* s) void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount) { void* pfd; + #ifdef _WIN32 rfds[*rcount] = transport->TcpIn->event; (*rcount)++; - - if (transport->SplitInputOutput) - { - rfds[*rcount] = transport->TcpOut->event; - (*rcount)++; - } - #else rfds[*rcount] = (void*)(long)(transport->TcpIn->sockfd); (*rcount)++; - - if (transport->SplitInputOutput) - { - rfds[*rcount] = (void*)(long)(transport->TcpOut->sockfd); - (*rcount)++; - } - #endif + pfd = GetEventWaitObject(transport->ReceiveEvent); if (pfd) @@ -884,13 +773,6 @@ DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events) events[nCount] = freerdp_tcp_get_event_handle(transport->TcpIn); nCount++; - if (transport->SplitInputOutput) - { - if (events) - events[nCount] = freerdp_tcp_get_event_handle(transport->TcpOut); - nCount++; - } - if (transport->ReceiveEvent) { if (events) @@ -920,7 +802,7 @@ BOOL tranport_is_write_blocked(rdpTransport* transport) int tranport_drain_output_buffer(rdpTransport* transport) { - BOOL ret = FALSE; + BOOL status = FALSE; /* First try to send some accumulated bytes in the send buffer */ if (transport->TcpIn->writeBlocked) @@ -928,7 +810,7 @@ int tranport_drain_output_buffer(rdpTransport* transport) if (!transport_bio_buffered_drain(transport->TcpIn->bufferedBio)) return -1; - ret |= transport->TcpIn->writeBlocked; + status |= transport->TcpIn->writeBlocked; } if (transport->SplitInputOutput && transport->TcpOut && transport->TcpOut->writeBlocked) @@ -936,10 +818,10 @@ int tranport_drain_output_buffer(rdpTransport* transport) if (!transport_bio_buffered_drain(transport->TcpOut->bufferedBio)) return -1; - ret |= transport->TcpOut->writeBlocked; + status |= transport->TcpOut->writeBlocked; } - return ret; + return status; } int transport_check_fds(rdpTransport* transport) @@ -951,9 +833,6 @@ int transport_check_fds(rdpTransport* transport) if (!transport) return -1; -#ifdef _WIN32 - WSAResetEvent(transport->TcpIn->event); -#endif ResetEvent(transport->ReceiveEvent); /** @@ -1009,12 +888,7 @@ BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking) transport->blocking = blocking; - if (transport->SplitInputOutput) - { - status &= freerdp_tcp_set_blocking_mode(transport->TcpIn, blocking); - status &= freerdp_tcp_set_blocking_mode(transport->TcpOut, blocking); - } - else + if (!transport->SplitInputOutput) { status &= freerdp_tcp_set_blocking_mode(transport->TcpIn, blocking); } @@ -1102,11 +976,6 @@ rdpTransport* transport_new(rdpContext* context) transport->context = context; transport->settings = context->settings; - transport->TcpIn = freerdp_tcp_new(context->settings); - - if (!transport->TcpIn) - goto out_free; - /* a small 0.1ms delay when transport is blocking. */ transport->SleepInterval = 100; transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE); @@ -1153,7 +1022,6 @@ out_free_receivepool: StreamPool_Free(transport->ReceivePool); out_free_tcpin: freerdp_tcp_free(transport->TcpIn); -out_free: free(transport); return NULL; } @@ -1165,9 +1033,6 @@ void transport_free(rdpTransport* transport) transport_disconnect(transport); - if (transport->TcpIn) - freerdp_tcp_free(transport->TcpIn); - if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); -- 2.7.4