libfreerdp-core: move stuff down from transport to tsg layer

This commit is contained in:
Marc-André Moreau 2015-02-11 11:57:02 -05:00
parent 46724b0c75
commit aa8b843250
7 changed files with 137 additions and 217 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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.

View File

@ -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;
client->context->metrics = metrics_new(client->context);
context->ServerMode = TRUE;
rdp = rdp_new(client->context);
context->metrics = metrics_new(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);

View File

@ -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);

View File

@ -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,91 +271,17 @@ 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);
}
if (!tsg_connect(tsg, hostname, port, timeout))
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))
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);