Esempio n. 1
0
BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
{
	BOOL status;
	rdpSettings* settings = rdp->settings;
	rdpNego *nego = rdp->nego;

	transport_set_blocking_mode(rdp->transport, TRUE);

	if (!nego_read_request(nego, s))
		return FALSE;

	nego->SelectedProtocol = 0;
	WLog_INFO(TAG, "Client Security: NLA:%d TLS:%d RDP:%d",
			 (nego->RequestedProtocols & PROTOCOL_NLA) ? 1 : 0,
			 (nego->RequestedProtocols & PROTOCOL_TLS) ? 1 : 0,
			 (nego->RequestedProtocols == PROTOCOL_RDP) ? 1 : 0
			);
	WLog_INFO(TAG, "Server Security: NLA:%d TLS:%d RDP:%d",
			 settings->NlaSecurity, settings->TlsSecurity, settings->RdpSecurity);

	if ((settings->NlaSecurity) && (nego->RequestedProtocols & PROTOCOL_NLA))
	{
		nego->SelectedProtocol = PROTOCOL_NLA;
	}
	else if ((settings->TlsSecurity) && (nego->RequestedProtocols & PROTOCOL_TLS))
	{
		nego->SelectedProtocol = PROTOCOL_TLS;
	}
	else if ((settings->RdpSecurity) && (nego->RequestedProtocols == PROTOCOL_RDP))
	{
		nego->SelectedProtocol = PROTOCOL_RDP;
	}
	else
	{
		/*
		 * when here client and server aren't compatible, we select the right
		 * error message to return to the client in the nego failure packet
		 */
		nego->SelectedProtocol = PROTOCOL_FAILED_NEGO;

		if (settings->RdpSecurity)
		{
			WLog_ERR(TAG, "server supports only Standard RDP Security");
			nego->SelectedProtocol |= SSL_NOT_ALLOWED_BY_SERVER;
		}
		else
		{
			if (settings->NlaSecurity && !settings->TlsSecurity)
			{
				WLog_ERR(TAG, "server supports only NLA Security");
				nego->SelectedProtocol |= HYBRID_REQUIRED_BY_SERVER;
			}
			else
			{
				WLog_ERR(TAG, "server supports only a SSL based Security (TLS or NLA)");
				nego->SelectedProtocol |= SSL_REQUIRED_BY_SERVER;
			}
		}

		WLog_ERR(TAG, "Protocol security negotiation failure");
	}

	if (!(nego->SelectedProtocol & PROTOCOL_FAILED_NEGO))
	{
		WLog_INFO(TAG, "Negotiated Security: NLA:%d TLS:%d RDP:%d",
				 (nego->SelectedProtocol & PROTOCOL_NLA) ? 1 : 0,
				 (nego->SelectedProtocol & PROTOCOL_TLS) ? 1 : 0,
				 (nego->SelectedProtocol == PROTOCOL_RDP) ? 1: 0
				);
	}

	if (!nego_send_negotiation_response(nego))
		return FALSE;

	status = FALSE;

	if (nego->SelectedProtocol & PROTOCOL_NLA)
		status = transport_accept_nla(rdp->transport);
	else if (nego->SelectedProtocol & PROTOCOL_TLS)
		status = transport_accept_tls(rdp->transport);
	else if (nego->SelectedProtocol == PROTOCOL_RDP) /* 0 */
		status = transport_accept_rdp(rdp->transport);

	if (!status)
		return FALSE;

	transport_set_blocking_mode(rdp->transport, FALSE);

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_NEGO);

	return TRUE;
}
Esempio n. 2
0
boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
{
	boolean status;

	transport_set_blocking_mode(rdp->transport, true);

	if (!nego_read_request(rdp->nego, s))
		return false;

	rdp->nego->selected_protocol = 0;

	printf("Requested protocols:");
	if ((rdp->nego->requested_protocols & PROTOCOL_TLS))
	{
		printf(" TLS");
		if (rdp->settings->tls_security)
		{
			printf("(Y)");
			rdp->nego->selected_protocol |= PROTOCOL_TLS;
		}
		else
			printf("(n)");
	}
	if ((rdp->nego->requested_protocols & PROTOCOL_NLA))
	{
		printf(" NLA");
		if (rdp->settings->nla_security)
		{
			printf("(Y)");
			rdp->nego->selected_protocol |= PROTOCOL_NLA;
		}
		else
			printf("(n)");
	}
	printf(" RDP");
	if (rdp->settings->rdp_security && rdp->nego->selected_protocol == 0)
	{
		printf("(Y)");
		rdp->nego->selected_protocol = PROTOCOL_RDP;
	}
	else
		printf("(n)");
	printf("\n");

	if (!nego_send_negotiation_response(rdp->nego))
		return false;

	status = false;
	if (rdp->nego->selected_protocol & PROTOCOL_NLA)
		status = transport_accept_nla(rdp->transport);
	else if (rdp->nego->selected_protocol & PROTOCOL_TLS)
		status = transport_accept_tls(rdp->transport);
	else if (rdp->nego->selected_protocol == PROTOCOL_RDP) /* 0 */
		status = transport_accept_rdp(rdp->transport);

	if (!status)
		return false;

	transport_set_blocking_mode(rdp->transport, false);

	rdp->state = CONNECTION_STATE_NEGO;

	return true;
}
Esempio n. 3
0
/**
 * Set non-blocking mode information.
 * @param rdp RDP module
 * @param blocking blocking mode
 */
void rdp_set_blocking_mode(rdpRdp* rdp, BOOL blocking)
{
	rdp->transport->ReceiveCallback = rdp_recv_callback;
	rdp->transport->ReceiveExtra = rdp;
	transport_set_blocking_mode(rdp->transport, blocking);
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
File: rdp.c Progetto: ydal/FreeRDP
/**
 * Set non-blocking mode information.
 * @param rdp RDP module
 * @param blocking blocking mode
 */
void rdp_set_blocking_mode(rdpRdp* rdp, boolean blocking)
{
	rdp->transport->recv_callback = rdp_recv_callback;
	rdp->transport->recv_extra = rdp;
	transport_set_blocking_mode(rdp->transport, blocking);
}
Esempio n. 6
0
BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
{
    BOOL status;
    rdpSettings* settings = rdp->settings;
    rdpNego *nego = rdp->nego;

    transport_set_blocking_mode(rdp->transport, TRUE);

    if (!nego_read_request(nego, s))
        return FALSE;

    nego->SelectedProtocol = 0;
    WLog_INFO(TAG, "Client Security: NLA:%d TLS:%d RDP:%d",
              (nego->RequestedProtocols & PROTOCOL_NLA) ? 1 : 0,
              (nego->RequestedProtocols & PROTOCOL_TLS) ? 1 : 0,
              (nego->RequestedProtocols == PROTOCOL_RDP) ? 1 : 0
             );
    WLog_INFO(TAG, "Server Security: NLA:%d TLS:%d RDP:%d",
              settings->NlaSecurity, settings->TlsSecurity, settings->RdpSecurity);

    if ((settings->NlaSecurity) && (nego->RequestedProtocols & PROTOCOL_NLA))
    {
        nego->SelectedProtocol = PROTOCOL_NLA;
    }
    else if ((settings->TlsSecurity) && (nego->RequestedProtocols & PROTOCOL_TLS))
    {
        nego->SelectedProtocol = PROTOCOL_TLS;
    }
    else if ((settings->RdpSecurity) && (nego->SelectedProtocol == PROTOCOL_RDP))
    {
        nego->SelectedProtocol = PROTOCOL_RDP;
    }
    else
    {
        WLog_ERR(TAG, "Protocol security negotiation failure");
    }

    WLog_INFO(TAG, "Negotiated Security: NLA:%d TLS:%d RDP:%d",
              (nego->SelectedProtocol & PROTOCOL_NLA) ? 1 : 0,
              (nego->SelectedProtocol & PROTOCOL_TLS) ? 1 : 0,
              (nego->SelectedProtocol == PROTOCOL_RDP) ? 1: 0
             );

    if (!nego_send_negotiation_response(nego))
        return FALSE;

    status = FALSE;

    if (nego->SelectedProtocol & PROTOCOL_NLA)
        status = transport_accept_nla(rdp->transport);
    else if (nego->SelectedProtocol & PROTOCOL_TLS)
        status = transport_accept_tls(rdp->transport);
    else if (nego->SelectedProtocol == PROTOCOL_RDP) /* 0 */
        status = transport_accept_rdp(rdp->transport);

    if (!status)
        return FALSE;

    transport_set_blocking_mode(rdp->transport, FALSE);

    rdp_server_transition_to_state(rdp, CONNECTION_STATE_NEGO);

    return TRUE;
}
Esempio n. 7
0
BOOL freerdp_peer_context_new(freerdp_peer* client)
{
	rdpRdp* rdp;
	rdpContext* context;
	BOOL ret = TRUE;

	if (!client)
		return FALSE;

	if (!(context = (rdpContext*) calloc(1, client->ContextSize)))
		goto fail_context;

	client->context = context;

	context->peer = client;
	context->ServerMode = TRUE;

	if (!(context->metrics = metrics_new(context)))
		goto fail_metrics;

	if (!(rdp = rdp_new(context)))
		goto fail_rdp;

	client->input = rdp->input;
	client->update = rdp->update;
	client->settings = rdp->settings;
	client->autodetect = rdp->autodetect;

	context->rdp = rdp;
	context->input = client->input;
	context->update = client->update;
	context->settings = client->settings;
	context->autodetect = client->autodetect;

	client->update->context = context;
	client->input->context = context;
	client->autodetect->context = context;

	update_register_server_callbacks(client->update);
	autodetect_register_server_callbacks(client->autodetect);

	if (!transport_attach(rdp->transport, client->sockfd))
		goto fail_transport_attach;

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

	client->IsWriteBlocked = freerdp_peer_is_write_blocked;
	client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;

	IFCALLRET(client->ContextNew, ret, client, client->context);

	if (ret)
		return TRUE;

	WLog_ERR(TAG, "ContextNew callback failed");

fail_transport_attach:
	rdp_free(client->context->rdp);
fail_rdp:
	metrics_free(context->metrics);
fail_metrics:
	free(client->context);
fail_context:
	client->context = NULL;

	WLog_ERR(TAG, "Failed to create new peer context");
	return FALSE;
}
Esempio n. 8
0
boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
{
	boolean status;
	rdpSettings* settings = rdp->settings;

	transport_set_blocking_mode(rdp->transport, true);

	if (!nego_read_request(rdp->nego, s))
		return false;

	rdp->nego->selected_protocol = 0;

	freerdp_log(rdp->instance, "Client Security: NLA:%d TLS:%d RDP:%d\n",
			(rdp->nego->requested_protocols & PROTOCOL_NLA) ? 1 : 0,
			(rdp->nego->requested_protocols & PROTOCOL_TLS)	? 1 : 0,
			(rdp->nego->requested_protocols == PROTOCOL_RDP) ? 1: 0);

	freerdp_log(rdp->instance, "Server Security: NLA:%d TLS:%d RDP:%d\n",
			settings->nla_security, settings->tls_security, settings->rdp_security);

	if ((settings->nla_security) && (rdp->nego->requested_protocols & PROTOCOL_NLA))
	{
		rdp->nego->selected_protocol = PROTOCOL_NLA;
	}
	else if ((settings->tls_security) && (rdp->nego->requested_protocols & PROTOCOL_TLS))
	{
		rdp->nego->selected_protocol = PROTOCOL_TLS;
	}
	else if ((settings->rdp_security) && (rdp->nego->selected_protocol == PROTOCOL_RDP))
	{
		rdp->nego->selected_protocol = PROTOCOL_RDP;
	}
	else
	{
		freerdp_log(rdp->instance, "Protocol security negotiation failure\n");
	}

	freerdp_log(rdp->instance, "Negotiated Security: NLA:%d TLS:%d RDP:%d\n",
			(rdp->nego->selected_protocol & PROTOCOL_NLA) ? 1 : 0,
			(rdp->nego->selected_protocol & PROTOCOL_TLS)	? 1 : 0,
			(rdp->nego->selected_protocol == PROTOCOL_RDP) ? 1: 0);

	if (!nego_send_negotiation_response(rdp->nego))
		return false;

	status = false;
	if (rdp->nego->selected_protocol & PROTOCOL_NLA)
		status = transport_accept_nla(rdp->transport);
	else if (rdp->nego->selected_protocol & PROTOCOL_TLS)
		status = transport_accept_tls(rdp->transport);
	else if (rdp->nego->selected_protocol == PROTOCOL_RDP) /* 0 */
		status = transport_accept_rdp(rdp->transport);

	if (!status)
		return false;

	transport_set_blocking_mode(rdp->transport, false);

	rdp->state = CONNECTION_STATE_NEGO;

	return true;
}
Esempio n. 9
0
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;
}