void rdp_free(rdpRdp* rdp) { if (rdp) { crypto_rc4_free(rdp->rc4_decrypt_key); crypto_rc4_free(rdp->rc4_encrypt_key); crypto_des3_free(rdp->fips_encrypt); crypto_des3_free(rdp->fips_decrypt); crypto_hmac_free(rdp->fips_hmac); freerdp_settings_free(rdp->settings); freerdp_settings_free(rdp->settingsCopy); transport_free(rdp->transport); license_free(rdp->license); input_free(rdp->input); update_free(rdp->update); fastpath_free(rdp->fastpath); nego_free(rdp->nego); mcs_free(rdp->mcs); redirection_free(rdp->redirection); autodetect_free(rdp->autodetect); heartbeat_free(rdp->heartbeat); multitransport_free(rdp->multitransport); bulk_free(rdp->bulk); free(rdp); } }
void rdp_write_client_auto_reconnect_cookie(wStream* s, rdpSettings* settings) { CryptoHmac hmac; BYTE nullRandom[32]; BYTE cryptSecurityVerifier[16]; ARC_CS_PRIVATE_PACKET* autoReconnectCookie; autoReconnectCookie = settings->ClientAutoReconnectCookie; /* SecurityVerifier = HMAC(AutoReconnectRandom, ClientRandom) */ hmac = crypto_hmac_new(); ZeroMemory(nullRandom, sizeof(nullRandom)); crypto_hmac_md5_init(hmac, autoReconnectCookie->securityVerifier, 16); if (settings->ClientRandomLength > 0) crypto_hmac_update(hmac, settings->ClientRandom, settings->ClientRandomLength); else crypto_hmac_update(hmac, nullRandom, sizeof(nullRandom)); crypto_hmac_final(hmac, cryptSecurityVerifier, 16); crypto_hmac_free(hmac); Stream_Write_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ Stream_Write_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ Stream_Write_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ Stream_Write(s, cryptSecurityVerifier, 16); /* SecurityVerifier */ }
BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) { CryptoHmac hmac; BYTE ClientRandom[32]; BYTE AutoReconnectRandom[32]; ARC_SC_PRIVATE_PACKET* serverCookie; ARC_CS_PRIVATE_PACKET* clientCookie; rdpSettings* settings = rdp->settings; serverCookie = settings->ServerAutoReconnectCookie; clientCookie = settings->ClientAutoReconnectCookie; clientCookie->cbLen = 28; clientCookie->version = serverCookie->version; clientCookie->logonId = serverCookie->logonId; ZeroMemory(clientCookie->securityVerifier, 16); ZeroMemory(AutoReconnectRandom, sizeof(AutoReconnectRandom)); CopyMemory(AutoReconnectRandom, serverCookie->arcRandomBits, 16); ZeroMemory(ClientRandom, sizeof(ClientRandom)); if (settings->SelectedProtocol == PROTOCOL_RDP) CopyMemory(ClientRandom, settings->ClientRandom, settings->ClientRandomLength); hmac = crypto_hmac_new(); if (!hmac) return FALSE; /* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */ if (!crypto_hmac_md5_init(hmac, AutoReconnectRandom, 16)) return FALSE; crypto_hmac_update(hmac, ClientRandom, 32); crypto_hmac_final(hmac, clientCookie->securityVerifier, 16); crypto_hmac_free(hmac); return TRUE; }
void rdp_free(rdpRdp* rdp) { if (rdp != NULL) { crypto_rc4_free(rdp->rc4_decrypt_key); crypto_rc4_free(rdp->rc4_encrypt_key); crypto_des3_free(rdp->fips_encrypt); crypto_des3_free(rdp->fips_decrypt); crypto_hmac_free(rdp->fips_hmac); settings_free(rdp->settings); transport_free(rdp->transport); license_free(rdp->license); // input_free(rdp->input); // update_free(rdp->update); fastpath_free(rdp->fastpath); nego_free(rdp->nego); mcs_free(rdp->mcs); redirection_free(rdp->redirection); mppc_free(rdp); xfree(rdp); } }
void rdp_reset(rdpRdp* rdp) { rdpSettings* settings; settings = rdp->settings; bulk_reset(rdp->bulk); crypto_rc4_free(rdp->rc4_decrypt_key); 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; crypto_des3_free(rdp->fips_decrypt); rdp->fips_decrypt = NULL; crypto_hmac_free(rdp->fips_hmac); rdp->fips_hmac = NULL; mcs_free(rdp->mcs); nego_free(rdp->nego); license_free(rdp->license); transport_free(rdp->transport); free(settings->ServerRandom); settings->ServerRandom = NULL; free(settings->ServerCertificate); settings->ServerCertificate = NULL; free(settings->ClientAddress); settings->ClientAddress = NULL; rdp->transport = transport_new(rdp->settings); rdp->transport->rdp = rdp; rdp->license = license_new(rdp); rdp->nego = nego_new(rdp->transport); rdp->mcs = mcs_new(rdp->transport); rdp->transport->layer = TRANSPORT_LAYER_TCP; }
boolean rdp_client_redirect(rdpRdp* rdp) { rdpSettings* settings = rdp->settings; rdpRedirection* redirection = rdp->redirection; rdp_client_disconnect(rdp); /* FIXME: this is a subset of rdp_free */ crypto_rc4_free(rdp->rc4_decrypt_key); crypto_rc4_free(rdp->rc4_encrypt_key); crypto_des3_free(rdp->fips_encrypt); crypto_des3_free(rdp->fips_decrypt); crypto_hmac_free(rdp->fips_hmac); mcs_free(rdp->mcs); nego_free(rdp->nego); license_free(rdp->license); transport_free(rdp->transport); /* FIXME: this is a subset of settings_free */ freerdp_blob_free(settings->server_random); freerdp_blob_free(settings->server_certificate); xfree(settings->ip_address); rdp->transport = transport_new(settings); rdp->license = license_new(rdp); rdp->nego = nego_new(rdp->transport); rdp->mcs = mcs_new(rdp->transport); rdp->transport->layer = TRANSPORT_LAYER_TCP; settings->redirected_session_id = redirection->sessionID; if (redirection->flags & LB_LOAD_BALANCE_INFO) { nego_set_routing_token(rdp->nego, &redirection->loadBalanceInfo); } else { if (redirection->flags & LB_TARGET_NET_ADDRESS) { xfree(settings->hostname); settings->hostname = xstrdup(redirection->targetNetAddress.ascii); } else if (redirection->flags & LB_TARGET_FQDN) { xfree(settings->hostname); settings->hostname = xstrdup(redirection->targetFQDN.ascii); } else if (redirection->flags & LB_TARGET_NETBIOS_NAME) { xfree(settings->hostname); settings->hostname = xstrdup(redirection->targetNetBiosName.ascii); } } if (redirection->flags & LB_USERNAME) { xfree(settings->username); settings->username = xstrdup(redirection->username.ascii); } if (redirection->flags & LB_DOMAIN) { xfree(settings->domain); settings->domain = xstrdup(redirection->domain.ascii); } if (redirection->flags & LB_PASSWORD) { settings->password_cookie = &redirection->password_cookie; } return rdp_client_connect(rdp); }
BOOL rdp_client_redirect(rdpRdp* rdp) { rdpSettings* settings = rdp->settings; rdpRedirection* redirection = rdp->redirection; rdp_client_disconnect(rdp); /* FIXME: this is a subset of rdp_free */ crypto_rc4_free(rdp->rc4_decrypt_key); crypto_rc4_free(rdp->rc4_encrypt_key); crypto_des3_free(rdp->fips_encrypt); crypto_des3_free(rdp->fips_decrypt); crypto_hmac_free(rdp->fips_hmac); mcs_free(rdp->mcs); nego_free(rdp->nego); license_free(rdp->license); transport_free(rdp->transport); free(settings->ServerRandom); free(settings->ServerCertificate); free(settings->ClientAddress); rdp->transport = transport_new(settings); rdp->license = license_new(rdp); rdp->nego = nego_new(rdp->transport); rdp->mcs = mcs_new(rdp->transport); rdp->transport->layer = TRANSPORT_LAYER_TCP; settings->RedirectedSessionId = redirection->sessionID; if (redirection->flags & LB_LOAD_BALANCE_INFO) { nego_set_routing_token(rdp->nego, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength); } else { if (redirection->flags & LB_TARGET_NET_ADDRESS) { free(settings->ServerHostname); settings->ServerHostname = _strdup(redirection->targetNetAddress.ascii); } else if (redirection->flags & LB_TARGET_FQDN) { free(settings->ServerHostname); settings->ServerHostname = _strdup(redirection->targetFQDN.ascii); } else if (redirection->flags & LB_TARGET_NETBIOS_NAME) { free(settings->ServerHostname); settings->ServerHostname = _strdup(redirection->targetNetBiosName.ascii); } } if (redirection->flags & LB_USERNAME) { free(settings->Username); settings->Username = _strdup(redirection->username.ascii); } if (redirection->flags & LB_DOMAIN) { free(settings->Domain); settings->Domain = _strdup(redirection->domain.ascii); } if (redirection->flags & LB_PASSWORD) { settings->RedirectionPassword = redirection->PasswordCookie; settings->RedirectionPasswordLength = redirection->PasswordCookieLength; } return rdp_client_connect(rdp); }
void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings) { int clientAddressFamily; WCHAR* clientAddress = NULL; int cbClientAddress; WCHAR* clientDir = NULL; int cbClientDir; int cbAutoReconnectLen; clientAddressFamily = settings->IPv6Enabled ? ADDRESS_FAMILY_INET6 : ADDRESS_FAMILY_INET; cbClientAddress = ConvertToUnicode(CP_UTF8, 0, settings->ClientAddress, -1, &clientAddress, 0) * 2; cbClientDir = ConvertToUnicode(CP_UTF8, 0, settings->ClientDir, -1, &clientDir, 0) * 2; cbAutoReconnectLen = (int) settings->ServerAutoReconnectCookie->cbLen; Stream_Write_UINT16(s, clientAddressFamily); /* clientAddressFamily */ Stream_Write_UINT16(s, cbClientAddress + 2); /* cbClientAddress */ if (cbClientAddress > 0) Stream_Write(s, clientAddress, cbClientAddress); /* clientAddress */ Stream_Write_UINT16(s, 0); Stream_Write_UINT16(s, cbClientDir + 2); /* cbClientDir */ if (cbClientDir > 0) Stream_Write(s, clientDir, cbClientDir); /* clientDir */ Stream_Write_UINT16(s, 0); rdp_write_client_time_zone(s, settings); /* clientTimeZone */ Stream_Write_UINT32(s, 0); /* clientSessionId, should be set to 0 */ freerdp_performance_flags_make(settings); Stream_Write_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ Stream_Write_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ if (cbAutoReconnectLen > 0) { CryptoHmac hmac; ARC_SC_PRIVATE_PACKET* serverCookie; ARC_CS_PRIVATE_PACKET* clientCookie; WLog_DBG(TAG, "Sending auto reconnect"); serverCookie = settings->ServerAutoReconnectCookie; clientCookie = settings->ClientAutoReconnectCookie; clientCookie->cbLen = serverCookie->cbLen; clientCookie->version = serverCookie->version; clientCookie->logonId = serverCookie->logonId; hmac = crypto_hmac_new(); if (!hmac) { WLog_ERR(TAG, "unable to allocate hmac"); goto out_free; } crypto_hmac_md5_init(hmac, serverCookie->arcRandomBits, 16); if (settings->SelectedProtocol == PROTOCOL_RDP) { crypto_hmac_update(hmac, (BYTE*) (settings->ClientRandom), 32); } else { /* Anthony Tong's version had 16 zeroes here; I'm not sure why. * I do know that 16 did not reconnect correctly vs Win2008RDVH, * and 32 did. */ const BYTE zeros[32] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }; crypto_hmac_update(hmac, zeros, 32); } crypto_hmac_final(hmac, clientCookie->securityVerifier, 16); rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ /* mark as used */ settings->ServerAutoReconnectCookie->cbLen = 0; crypto_hmac_free(hmac); } /* reserved1 (2 bytes) */ /* reserved2 (2 bytes) */ out_free: free(clientAddress); free(clientDir); }