コード例 #1
0
ファイル: connection.c プロジェクト: artemh/FreeRDP
int rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s)
{
	BYTE* mark;
	UINT16 width;
	UINT16 height;

	width = rdp->settings->DesktopWidth;
	height = rdp->settings->DesktopHeight;

	Stream_GetPointer(s, mark);

	if (!rdp_recv_demand_active(rdp, s))
	{
		UINT16 channelId;

		Stream_SetPointer(s, mark);
		rdp_recv_get_active_header(rdp, s, &channelId);

		/* Was Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
		 * but the headers aren't always that length,
		 * so that could result in a bad offset.
		 */

		return rdp_recv_out_of_sequence_pdu(rdp, s);
	}

	if (freerdp_shall_disconnect(rdp->instance))
		return 0;

	if (!rdp_send_confirm_active(rdp))
		return -1;

	if (!input_register_client_callbacks(rdp->input))
	{
		WLog_ERR(TAG, "error registering client callbacks");
		return -1;
	}

	/**
	 * The server may request a different desktop size during Deactivation-Reactivation sequence.
	 * In this case, the UI should be informed and do actual window resizing at this point.
	 */
	if (width != rdp->settings->DesktopWidth || height != rdp->settings->DesktopHeight)
	{
		BOOL status = TRUE;

		IFCALLRET(rdp->update->DesktopResize, status, rdp->update->context);

		if (!status)
		{
			WLog_ERR(TAG, "client desktop resize callback failed");
			return -1;
		}
	}

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION);

	return rdp_client_connect_finalize(rdp);
}
コード例 #2
0
ファイル: connection.c プロジェクト: AhmadKabakibi/FreeRDP
BOOL rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, wStream* s)
{
	if (!mcs_recv_attach_user_confirm(rdp->mcs, s))
		return FALSE;

	if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->userId))
		return FALSE;

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN);

	return TRUE;
}
コード例 #3
0
ファイル: connection.c プロジェクト: jat255/FreeRDP
BOOL rdp_client_disconnect(rdpRdp* rdp)
{
	BOOL status;

	status = nego_disconnect(rdp->nego);

	rdp_reset(rdp);

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_INITIAL);

	return status;
}
コード例 #4
0
ファイル: activation.c プロジェクト: FreeRDP/FreeRDP
BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
{
	UINT16 lengthSourceDescriptor;

	if (rdp->state == CONNECTION_STATE_ACTIVE)
		rdp->deactivation_reactivation = TRUE;
	else
		rdp->deactivation_reactivation = FALSE;

	/*
	 * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
	 * the following fields.
	 */
	if (Stream_GetRemainingLength(s) > 0)
	{
		do
		{
			if (Stream_GetRemainingLength(s) < 4)
				break;

			Stream_Read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */

			if (Stream_GetRemainingLength(s) < 2)
				break;

			Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */

			if (Stream_GetRemainingLength(s) < lengthSourceDescriptor)
				break;

			Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */
		}
		while (0);
	}

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);

	while (rdp->state != CONNECTION_STATE_ACTIVE)
	{
		if (rdp_check_fds(rdp) < 0)
			return FALSE;

		if (freerdp_shall_disconnect(rdp->instance))
			break;

		SwitchToThread();
	}

	return TRUE;
}
コード例 #5
0
ファイル: connection.c プロジェクト: orosam/FreeRDP
BOOL rdp_client_disconnect(rdpRdp* rdp)
{
	BOOL rc;

	if (rdp->settingsCopy)
	{
		freerdp_settings_free(rdp->settingsCopy);
		rdp->settingsCopy = NULL;
	}

	rc = nego_disconnect(rdp->nego);
	rdp_reset(rdp);
	rdp_client_transition_to_state(rdp, CONNECTION_STATE_INITIAL);
	return rc;
}
コード例 #6
0
ファイル: connection.c プロジェクト: AhmadKabakibi/FreeRDP
BOOL rdp_client_connect_mcs_connect_response(rdpRdp* rdp, wStream* s)
{
	if (!mcs_recv_connect_response(rdp->mcs, s))
	{
		fprintf(stderr, "rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed\n");
		return FALSE;
	}

	if (!mcs_send_erect_domain_request(rdp->mcs))
		return FALSE;

	if (!mcs_send_attach_user_request(rdp->mcs))
		return FALSE;

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER);

	return TRUE;
}
コード例 #7
0
ファイル: transport.c プロジェクト: bceverly/FreeRDP
BOOL transport_connect_nla(rdpTransport* transport)
{
	rdpContext* context = transport->context;
	rdpSettings* settings = context->settings;
	freerdp* instance = context->instance;
	rdpRdp* rdp = context->rdp;

	if (!transport_connect_tls(transport))
		return FALSE;

	if (!settings->Authentication)
		return TRUE;

	rdp->nla = nla_new(instance, transport, settings);

	if (!rdp->nla)
		return FALSE;

	transport_set_nla_mode(transport, TRUE);

	if (settings->AuthenticationServiceClass)
	{
		rdp->nla->ServicePrincipalName =
			nla_make_spn(settings->AuthenticationServiceClass, settings->ServerHostname);

		if (!rdp->nla->ServicePrincipalName)
			return FALSE;
	}

	if (nla_client_begin(rdp->nla) < 0)
	{
		if (!freerdp_get_last_error(context))
			freerdp_set_last_error(context, FREERDP_ERROR_AUTHENTICATION_FAILED);

		transport_set_nla_mode(transport, FALSE);

		return FALSE;
	}

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_NLA);

	return TRUE;
}
コード例 #8
0
ファイル: connection.c プロジェクト: AhmadKabakibi/FreeRDP
int rdp_client_connect_license(rdpRdp* rdp, wStream* s)
{
	int status;

	status = license_recv(rdp->license, s);

	if (status < 0)
		return status;

	if (rdp->license->state == LICENSE_STATE_ABORTED)
	{
		fprintf(stderr, "license connection sequence aborted.\n");
		return -1;
	}

	if (rdp->license->state == LICENSE_STATE_COMPLETED)
	{
		rdp_client_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
	}

	return 0;
}
コード例 #9
0
ファイル: connection.c プロジェクト: AhmadKabakibi/FreeRDP
BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
{
	UINT32 i;
	UINT16 channelId;
	BOOL allJoined = TRUE;
	rdpMcs* mcs = rdp->mcs;

	if (!mcs_recv_channel_join_confirm(mcs, s, &channelId))
		return FALSE;

	if (!mcs->userChannelJoined)
	{
		if (channelId != mcs->userId)
			return FALSE;

		mcs->userChannelJoined = TRUE;

		if (!mcs_send_channel_join_request(mcs, MCS_GLOBAL_CHANNEL_ID))
			return FALSE;
	}
	else if (!mcs->globalChannelJoined)
	{
		if (channelId != MCS_GLOBAL_CHANNEL_ID)
			return FALSE;

		mcs->globalChannelJoined = TRUE;

		if (mcs->messageChannelId != 0)
		{
			if (!mcs_send_channel_join_request(mcs, mcs->messageChannelId))
				return FALSE;

			allJoined = FALSE;
		}
		else
		{
			if (mcs->channelCount > 0)
			{
				if (!mcs_send_channel_join_request(mcs, mcs->channels[0].ChannelId))
					return FALSE;

				allJoined = FALSE;
			}
		}
	}
	else if ((mcs->messageChannelId != 0) && !mcs->messageChannelJoined)
	{
		if (channelId != mcs->messageChannelId)
			return FALSE;

		mcs->messageChannelJoined = TRUE;

		if (mcs->channelCount > 0)
		{
			if (!mcs_send_channel_join_request(mcs, mcs->channels[0].ChannelId))
				return FALSE;

			allJoined = FALSE;
		}
	}
	else
	{
		for (i = 0; i < mcs->channelCount; i++)
		{
			if (mcs->channels[i].joined)
				continue;

			if (mcs->channels[i].ChannelId != channelId)
				return FALSE;

			mcs->channels[i].joined = TRUE;

			break;
		}

		if (i + 1 < mcs->channelCount)
		{
			if (!mcs_send_channel_join_request(mcs, mcs->channels[i + 1].ChannelId))
				return FALSE;

			allJoined = FALSE;
		}
	}

	if (mcs->userChannelJoined && mcs->globalChannelJoined && allJoined)
	{
		if (!rdp_client_establish_keys(rdp))
			return FALSE;

		if (!rdp_send_client_info(rdp))
			return FALSE;

		rdp_client_transition_to_state(rdp, CONNECTION_STATE_LICENSING);
	}

	return TRUE;
}
コード例 #10
0
ファイル: connection.c プロジェクト: AhmadKabakibi/FreeRDP
BOOL rdp_client_connect(rdpRdp* rdp)
{
	rdpSettings* settings = rdp->settings;

	if (rdp->settingsCopy)
	{
		freerdp_settings_free(rdp->settingsCopy);
		rdp->settingsCopy = NULL;
	}

	rdp->settingsCopy = freerdp_settings_clone(settings);

	nego_init(rdp->nego);
	nego_set_target(rdp->nego, settings->ServerHostname, settings->ServerPort);

	if (settings->GatewayEnabled)
	{
		char* user = NULL;
		char* domain = NULL;
		char* cookie = NULL;
		int user_length = 0;
		int domain_length = 0;
		int cookie_length = 0;

		if (settings->Username)
		{
			user = settings->Username;
			user_length = strlen(settings->Username);
		}

		if (settings->Domain)
			domain = settings->Domain;
		else
			domain = settings->ComputerName;

		domain_length = strlen(domain);

		cookie_length = domain_length + 1 + user_length;
		cookie = (char*) malloc(cookie_length + 1);

		CopyMemory(cookie, domain, domain_length);
		CharUpperBuffA(cookie, domain_length);
		cookie[domain_length] = '\\';

		if (settings->Username)
			CopyMemory(&cookie[domain_length + 1], user, user_length);

		cookie[cookie_length] = '\0';

		nego_set_cookie(rdp->nego, cookie);
		free(cookie);
	}
	else
	{
		nego_set_cookie(rdp->nego, settings->Username);
	}

	nego_set_send_preconnection_pdu(rdp->nego, settings->SendPreconnectionPdu);
	nego_set_preconnection_id(rdp->nego, settings->PreconnectionId);
	nego_set_preconnection_blob(rdp->nego, settings->PreconnectionBlob);

	nego_set_negotiation_enabled(rdp->nego, settings->NegotiateSecurityLayer);
	nego_set_restricted_admin_mode_required(rdp->nego, settings->RestrictedAdminModeRequired);

	nego_enable_rdp(rdp->nego, settings->RdpSecurity);
	nego_enable_tls(rdp->nego, settings->TlsSecurity);
	nego_enable_nla(rdp->nego, settings->NlaSecurity);
	nego_enable_ext(rdp->nego, settings->ExtSecurity);

	if (settings->MstscCookieMode)
		settings->CookieMaxLength = MSTSC_COOKIE_MAX_LENGTH;

	nego_set_cookie_max_length(rdp->nego, settings->CookieMaxLength);

	if (settings->LoadBalanceInfo)
		nego_set_routing_token(rdp->nego, settings->LoadBalanceInfo, settings->LoadBalanceInfoLength);

	if (!nego_connect(rdp->nego))
	{
		fprintf(stderr, "Error: protocol security negotiation or connection failure\n");
		return FALSE;
	}

	if ((rdp->nego->selected_protocol & PROTOCOL_TLS) || (rdp->nego->selected_protocol == PROTOCOL_RDP))
	{
		if ((settings->Username != NULL) && ((settings->Password != NULL) ||
				(settings->RedirectionPassword != NULL && settings->RedirectionPasswordLength > 0)))
			settings->AutoLogonEnabled = TRUE;
	}

	rdp_set_blocking_mode(rdp, FALSE);

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_NEGO);
	rdp->finalize_sc_pdus = 0;

	if (!mcs_send_connect_initial(rdp->mcs))
	{
		if (!connectErrorCode)
		{
			connectErrorCode = MCSCONNECTINITIALERROR;                      
		}
		fprintf(stderr, "Error: unable to send MCS Connect Initial\n");
		return FALSE;
	}

	while (rdp->state != CONNECTION_STATE_ACTIVE)
	{
		if (rdp_check_fds(rdp) < 0)
			return FALSE;
	}

	return TRUE;
}
コード例 #11
0
ファイル: rdp.c プロジェクト: JozLes77/FreeRDP
static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
{
    int status = 0;
    rdpRdp* rdp = (rdpRdp*) extra;

    /*
     * At any point in the connection sequence between when all
     * MCS channels have been joined and when the RDP connection
     * enters the active state, an auto-detect PDU can be received
     * on the MCS message channel.
     */
    if ((rdp->state > CONNECTION_STATE_MCS_CHANNEL_JOIN) &&
            (rdp->state < CONNECTION_STATE_ACTIVE))
    {
        if (rdp_client_connect_auto_detect(rdp, s))
            return 0;
    }

    switch (rdp->state)
    {
    case CONNECTION_STATE_NEGO:
        if (!rdp_client_connect_mcs_connect_response(rdp, s))
            status = -1;
        break;

    case CONNECTION_STATE_MCS_ATTACH_USER:
        if (!rdp_client_connect_mcs_attach_user_confirm(rdp, s))
            status = -1;
        break;

    case CONNECTION_STATE_MCS_CHANNEL_JOIN:
        if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s))
            status = -1;
        break;

    case CONNECTION_STATE_LICENSING:
        status = rdp_client_connect_license(rdp, s);
        break;

    case CONNECTION_STATE_CAPABILITIES_EXCHANGE:
        status = rdp_client_connect_demand_active(rdp, s);
        break;

    case CONNECTION_STATE_FINALIZATION:
        status = rdp_recv_pdu(rdp, s);

        if ((status >= 0) && (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE))
            rdp_client_transition_to_state(rdp, CONNECTION_STATE_ACTIVE);
        break;

    case CONNECTION_STATE_ACTIVE:
        status = rdp_recv_pdu(rdp, s);
        break;

    default:
        DEBUG_WARN( "Invalid state %d\n", rdp->state);
        status = -1;
        break;
    }

    return status;
}
コード例 #12
0
ファイル: connection.c プロジェクト: artemh/FreeRDP
BOOL rdp_client_connect(rdpRdp* rdp)
{
	BOOL status;
	rdpSettings* settings = rdp->settings;

	if (rdp->settingsCopy)
	{
		freerdp_settings_free(rdp->settingsCopy);
		rdp->settingsCopy = NULL;
	}

	rdp->settingsCopy = freerdp_settings_clone(settings);

	if (!rdp->settingsCopy)
		return FALSE;

	nego_init(rdp->nego);
	nego_set_target(rdp->nego, settings->ServerHostname, settings->ServerPort);

	if (settings->GatewayEnabled)
	{
		char* user = NULL;
		char* domain = NULL;
		char* cookie = NULL;
		int user_length = 0;
		int domain_length = 0;
		int cookie_length = 0;

		if (settings->Username)
		{
			user = settings->Username;
			user_length = strlen(settings->Username);
		}

		if (settings->Domain)
			domain = settings->Domain;
		else
			domain = settings->ComputerName;

		domain_length = strlen(domain);

		cookie_length = domain_length + 1 + user_length;
		cookie = (char*) malloc(cookie_length + 1);

		if (!cookie)
			return FALSE;

		CopyMemory(cookie, domain, domain_length);
		CharUpperBuffA(cookie, domain_length);
		cookie[domain_length] = '\\';

		if (settings->Username)
			CopyMemory(&cookie[domain_length + 1], user, user_length);

		cookie[cookie_length] = '\0';

		status = nego_set_cookie(rdp->nego, cookie);
		free(cookie);
	}
	else
	{
		status = nego_set_cookie(rdp->nego, settings->Username);
	}

	if (!status)
		return FALSE;

	nego_set_send_preconnection_pdu(rdp->nego, settings->SendPreconnectionPdu);
	nego_set_preconnection_id(rdp->nego, settings->PreconnectionId);
	nego_set_preconnection_blob(rdp->nego, settings->PreconnectionBlob);

	nego_set_negotiation_enabled(rdp->nego, settings->NegotiateSecurityLayer);
	nego_set_restricted_admin_mode_required(rdp->nego, settings->RestrictedAdminModeRequired);

	nego_set_gateway_enabled(rdp->nego, settings->GatewayEnabled);
	nego_set_gateway_bypass_local(rdp->nego, settings->GatewayBypassLocal);

	nego_enable_rdp(rdp->nego, settings->RdpSecurity);
	nego_enable_tls(rdp->nego, settings->TlsSecurity);
	nego_enable_nla(rdp->nego, settings->NlaSecurity);
	nego_enable_ext(rdp->nego, settings->ExtSecurity);

	if (settings->MstscCookieMode)
		settings->CookieMaxLength = MSTSC_COOKIE_MAX_LENGTH;

	nego_set_cookie_max_length(rdp->nego, settings->CookieMaxLength);

	if (settings->LoadBalanceInfo)
	{
		if (!nego_set_routing_token(rdp->nego, settings->LoadBalanceInfo, settings->LoadBalanceInfoLength))
			return FALSE;
	}

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_NEGO);

	if (!nego_connect(rdp->nego))
	{
		if (!freerdp_get_last_error(rdp->context))
			freerdp_set_last_error(rdp->context, FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED);

		WLog_ERR(TAG, "Error: protocol security negotiation or connection failure");
		return FALSE;
	}

	if ((rdp->nego->SelectedProtocol & PROTOCOL_TLS) || (rdp->nego->SelectedProtocol == PROTOCOL_RDP))
	{
		if ((settings->Username != NULL) && ((settings->Password != NULL) ||
				(settings->RedirectionPassword != NULL && settings->RedirectionPasswordLength > 0)))
			settings->AutoLogonEnabled = TRUE;
	}

	/* everything beyond this point is event-driven and non blocking */

	rdp->transport->ReceiveCallback = rdp_recv_callback;
	rdp->transport->ReceiveExtra = rdp;
	transport_set_blocking_mode(rdp->transport, FALSE);

	if (rdp->state != CONNECTION_STATE_NLA)
	{
		if (!mcs_client_begin(rdp->mcs))
			return FALSE;
	}

	while (rdp->state != CONNECTION_STATE_ACTIVE)
	{
		if (rdp_check_fds(rdp) < 0)
		{
			if (!freerdp_get_last_error(rdp->context))
				freerdp_set_last_error(rdp->context, FREERDP_ERROR_CONNECT_TRANSPORT_FAILED);
			return FALSE;
		}
	}

	return TRUE;
}
コード例 #13
0
ファイル: connection.c プロジェクト: jat255/FreeRDP
BOOL rdp_client_connect(rdpRdp* rdp)
{
	BOOL status;
	rdpSettings* settings = rdp->settings;

	/* make sure SSL is initialize for earlier enough for crypto, by taking advantage of winpr SSL FIPS flag for openssl initialization */
	DWORD flags = WINPR_SSL_INIT_DEFAULT;

	if (settings->FIPSMode)
		flags |= WINPR_SSL_INIT_ENABLE_FIPS;
	winpr_InitializeSSL(flags);

	/* FIPS Mode forces the following and overrides the following(by happening later */
	/* in the command line processing): */
	/* 1. Disables NLA Security since NLA in freerdp uses NTLM(no Kerberos support yet) which uses algorithms */
	/*      not allowed in FIPS for sensitive data. So, we disallow NLA when FIPS is required. */
	/* 2. Forces the only supported RDP encryption method to be FIPS. */
	if (settings->FIPSMode || winpr_FIPSMode())
	{
		settings->NlaSecurity = FALSE;
		settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS;
	}

	nego_init(rdp->nego);
	nego_set_target(rdp->nego, settings->ServerHostname, settings->ServerPort);

	if (settings->GatewayEnabled)
	{
		char* user = NULL;
		char* domain = NULL;
		char* cookie = NULL;
		int user_length = 0;
		int domain_length = 0;
		int cookie_length = 0;

		if (settings->Username)
		{
			user = settings->Username;
			user_length = strlen(settings->Username);
		}

		if (settings->Domain)
			domain = settings->Domain;
		else
			domain = settings->ComputerName;

		domain_length = strlen(domain);

		cookie_length = domain_length + 1 + user_length;
		cookie = (char*) malloc(cookie_length + 1);

		if (!cookie)
			return FALSE;

		CopyMemory(cookie, domain, domain_length);
		CharUpperBuffA(cookie, domain_length);
		cookie[domain_length] = '\\';

		if (settings->Username)
			CopyMemory(&cookie[domain_length + 1], user, user_length);

		cookie[cookie_length] = '\0';

		status = nego_set_cookie(rdp->nego, cookie);
		free(cookie);
	}
	else
	{
		status = nego_set_cookie(rdp->nego, settings->Username);
	}

	if (!status)
		return FALSE;

	nego_set_send_preconnection_pdu(rdp->nego, settings->SendPreconnectionPdu);
	nego_set_preconnection_id(rdp->nego, settings->PreconnectionId);
	nego_set_preconnection_blob(rdp->nego, settings->PreconnectionBlob);

	nego_set_negotiation_enabled(rdp->nego, settings->NegotiateSecurityLayer);
	nego_set_restricted_admin_mode_required(rdp->nego, settings->RestrictedAdminModeRequired);

	nego_set_gateway_enabled(rdp->nego, settings->GatewayEnabled);
	nego_set_gateway_bypass_local(rdp->nego, settings->GatewayBypassLocal);

	nego_enable_rdp(rdp->nego, settings->RdpSecurity);
	nego_enable_tls(rdp->nego, settings->TlsSecurity);
	nego_enable_nla(rdp->nego, settings->NlaSecurity);
	nego_enable_ext(rdp->nego, settings->ExtSecurity);

	if (settings->MstscCookieMode)
		settings->CookieMaxLength = MSTSC_COOKIE_MAX_LENGTH;

	nego_set_cookie_max_length(rdp->nego, settings->CookieMaxLength);

	if (settings->LoadBalanceInfo)
	{
		if (!nego_set_routing_token(rdp->nego, settings->LoadBalanceInfo, settings->LoadBalanceInfoLength))
			return FALSE;
	}

	rdp_client_transition_to_state(rdp, CONNECTION_STATE_NEGO);

	if (!nego_connect(rdp->nego))
	{
		if (!freerdp_get_last_error(rdp->context))
			freerdp_set_last_error(rdp->context, FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED);

		WLog_ERR(TAG, "Error: protocol security negotiation or connection failure");
		return FALSE;
	}

	if ((rdp->nego->SelectedProtocol & PROTOCOL_TLS) || (rdp->nego->SelectedProtocol == PROTOCOL_RDP))
	{
		if ((settings->Username != NULL) && ((settings->Password != NULL) ||
				(settings->RedirectionPassword != NULL && settings->RedirectionPasswordLength > 0)))
			settings->AutoLogonEnabled = TRUE;
	}

	/* everything beyond this point is event-driven and non blocking */

	rdp->transport->ReceiveCallback = rdp_recv_callback;
	rdp->transport->ReceiveExtra = rdp;
	transport_set_blocking_mode(rdp->transport, FALSE);

	if (rdp->state != CONNECTION_STATE_NLA)
	{
		if (!mcs_client_begin(rdp->mcs))
			return FALSE;
	}

	while (rdp->state != CONNECTION_STATE_ACTIVE)
	{
		if (rdp_check_fds(rdp) < 0)
		{
			if (!freerdp_get_last_error(rdp->context))
				freerdp_set_last_error(rdp->context, FREERDP_ERROR_CONNECT_TRANSPORT_FAILED);
			return FALSE;
		}
	}

	return TRUE;
}