Ejemplo n.º 1
0
BOOL rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, wStream* s)
{
	UINT32 i;
	UINT16 channelId;
	BOOL allJoined = TRUE;
	rdpMcs* mcs = rdp->mcs;

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

	if (!mcs_send_channel_join_confirm(mcs, channelId))
		return FALSE;

	if (channelId == mcs->userId)
		mcs->userChannelJoined = TRUE;
	else if (channelId == MCS_GLOBAL_CHANNEL_ID)
		mcs->globalChannelJoined = TRUE;

	for (i = 0; i < mcs->channelCount; i++)
	{
		if (mcs->channels[i].ChannelId == channelId)
			mcs->channels[i].joined = TRUE;

		if (!mcs->channels[i].joined)
			allJoined = FALSE;
	}

	if ((mcs->userChannelJoined) && (mcs->globalChannelJoined) && allJoined)
	{
		rdp_server_transition_to_state(rdp, CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT);
	}

	return TRUE;
}
Ejemplo n.º 2
0
BOOL rdp_server_accept_confirm_active(rdpRdp* rdp, wStream* s)
{
	freerdp_peer *peer = rdp->context->peer;

	if (rdp->state != CONNECTION_STATE_CAPABILITIES_EXCHANGE)
		return FALSE;

	if (!rdp_recv_confirm_active(rdp, s))
		return FALSE;

	if (peer->ClientCapabilities && !peer->ClientCapabilities(peer))
		return FALSE;

	if (rdp->settings->SaltedChecksum)
		rdp->do_secure_checksum = TRUE;

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION);

	if (!rdp_send_server_synchronize_pdu(rdp))
		return FALSE;

	if (!rdp_send_server_control_cooperate_pdu(rdp))
		return FALSE;

	return TRUE;
}
Ejemplo n.º 3
0
BOOL rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, wStream* s)
{
	if (!mcs_recv_erect_domain_request(rdp->mcs, s))
		return FALSE;

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_ERECT_DOMAIN);

	return TRUE;
}
Ejemplo n.º 4
0
BOOL rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, wStream* s)
{
	if (!mcs_recv_attach_user_request(rdp->mcs, s))
		return FALSE;

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

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER);

	return TRUE;
}
Ejemplo n.º 5
0
BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s)
{
	if (!rdp_recv_client_font_list_pdu(s))
		return FALSE;

	if (!rdp_send_server_font_map_pdu(rdp))
		return FALSE;

	if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_ACTIVE) < 0)
		return FALSE;

	return TRUE;
}
Ejemplo n.º 6
0
BOOL rdp_server_reactivate(rdpRdp* rdp)
{
	if (!rdp_send_deactivate_all(rdp))
		return FALSE;

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);

	if (!rdp_send_demand_active(rdp))
		return FALSE;

	rdp->AwaitCapabilities = TRUE;

	return TRUE;
}
Ejemplo n.º 7
0
BOOL rdp_server_accept_confirm_active(rdpRdp* rdp, wStream* s)
{
	if (rdp->state != CONNECTION_STATE_CAPABILITIES_EXCHANGE)
		return FALSE;

	if (!rdp_recv_confirm_active(rdp, s))
		return FALSE;

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION);

	if (!rdp_send_server_synchronize_pdu(rdp))
		return FALSE;

	if (!rdp_send_server_control_cooperate_pdu(rdp))
		return FALSE;

	return TRUE;
}
Ejemplo n.º 8
0
BOOL rdp_server_reactivate(rdpRdp* rdp)
{
	freerdp_peer* client = NULL;

	if (rdp->context && rdp->context->peer)
		client = rdp->context->peer;

	if (client)
		client->activated = FALSE;

	if (!rdp_send_deactivate_all(rdp))
		return FALSE;

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);

	if (!rdp_send_demand_active(rdp))
		return FALSE;

	rdp->AwaitCapabilities = TRUE;
	return TRUE;
}
Ejemplo n.º 9
0
BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s)
{
	rdpSettings* settings = rdp->settings;
	freerdp_peer* peer = rdp->context->peer;

	if (!rdp_recv_client_font_list_pdu(s))
		return FALSE;

	if (settings->SupportMonitorLayoutPdu && settings->MonitorCount && peer->AdjustMonitorsLayout &&
	    peer->AdjustMonitorsLayout(peer))
	{
		/* client supports the monitorLayout PDU, let's send him the monitors if any */
		wStream* st = rdp_data_pdu_init(rdp);
		BOOL r;

		if (!st)
			return FALSE;

		if (!rdp_write_monitor_layout_pdu(st, settings->MonitorCount, settings->MonitorDefArray))
		{
			Stream_Release(st);
			return FALSE;
		}

		r = rdp_send_data_pdu(rdp, st, DATA_PDU_TYPE_MONITOR_LAYOUT, 0);

		if (!r)
			return FALSE;
	}

	if (!rdp_send_server_font_map_pdu(rdp))
		return FALSE;

	if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_ACTIVE) < 0)
		return FALSE;

	return TRUE;
}
Ejemplo n.º 10
0
BOOL rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, wStream* s)
{
	UINT32 i;
	rdpMcs* mcs = rdp->mcs;

	if (!mcs_recv_connect_initial(mcs, s))
		return FALSE;

	WLog_INFO(TAG,  "Accepted client: %s", rdp->settings->ClientHostname);
	WLog_INFO(TAG,  "Accepted channels:");

	for (i = 0; i < mcs->channelCount; i++)
	{
		WLog_INFO(TAG,  " %s", mcs->channels[i].Name);
	}

	if (!mcs_send_connect_response(mcs))
		return FALSE;

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CONNECT);

	return TRUE;
}
Ejemplo n.º 11
0
static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
{
	freerdp_peer* client = (freerdp_peer*) extra;
	rdpRdp* rdp = client->context->rdp;

	switch (rdp->state)
	{
		case CONNECTION_STATE_INITIAL:
			if (!rdp_server_accept_nego(rdp, s))
			{
				WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_INITIAL - rdp_server_accept_nego() fail");
				return -1;
			}

			client->settings->NlaSecurity = (rdp->nego->SelectedProtocol & PROTOCOL_NLA) ? TRUE : FALSE;
			client->settings->TlsSecurity = (rdp->nego->SelectedProtocol & PROTOCOL_TLS) ? TRUE : FALSE;
			client->settings->RdpSecurity = (rdp->nego->SelectedProtocol & PROTOCOL_RDP) ? TRUE : FALSE;

			if (rdp->nego->SelectedProtocol & PROTOCOL_NLA)
			{
				sspi_CopyAuthIdentity(&client->identity, rdp->nego->transport->nla->identity);
				IFCALLRET(client->Logon, client->authenticated, client, &client->identity, TRUE);
				nla_free(rdp->nego->transport->nla);
				rdp->nego->transport->nla = NULL;
			}
			else
			{
				IFCALLRET(client->Logon, client->authenticated, client, &client->identity, FALSE);
			}

			break;

		case CONNECTION_STATE_NEGO:
			if (!rdp_server_accept_mcs_connect_initial(rdp, s))
			{
				WLog_ERR(TAG,
				         "peer_recv_callback: CONNECTION_STATE_NEGO - rdp_server_accept_mcs_connect_initial() fail");
				return -1;
			}

			break;

		case CONNECTION_STATE_MCS_CONNECT:
			if (!rdp_server_accept_mcs_erect_domain_request(rdp, s))
			{
				WLog_ERR(TAG,
				         "peer_recv_callback: CONNECTION_STATE_MCS_CONNECT - rdp_server_accept_mcs_erect_domain_request() fail");
				return -1;
			}

			break;

		case CONNECTION_STATE_MCS_ERECT_DOMAIN:
			if (!rdp_server_accept_mcs_attach_user_request(rdp, s))
			{
				WLog_ERR(TAG,
				         "peer_recv_callback: CONNECTION_STATE_MCS_ERECT_DOMAIN - rdp_server_accept_mcs_attach_user_request() fail");
				return -1;
			}

			break;

		case CONNECTION_STATE_MCS_ATTACH_USER:
			if (!rdp_server_accept_mcs_channel_join_request(rdp, s))
			{
				WLog_ERR(TAG,
				         "peer_recv_callback: CONNECTION_STATE_MCS_ATTACH_USER - rdp_server_accept_mcs_channel_join_request() fail");
				return -1;
			}

			break;

		case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT:
			if (rdp->settings->UseRdpSecurityLayer)
			{
				if (!rdp_server_establish_keys(rdp, s))
				{
					WLog_ERR(TAG,
					         "peer_recv_callback: CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT - rdp_server_establish_keys() fail");
					return -1;
				}
			}

			rdp_server_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE);

			if (Stream_GetRemainingLength(s) > 0)
				return peer_recv_callback(transport, s, extra);

			break;

		case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE:
			if (!rdp_recv_client_info(rdp, s))
			{
				WLog_ERR(TAG,
				         "peer_recv_callback: CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE - rdp_recv_client_info() fail");
				return -1;
			}

			rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING);
			return peer_recv_callback(transport, NULL, extra);
			break;

		case CONNECTION_STATE_LICENSING:
			if (!license_send_valid_client_error_packet(rdp->license))
			{
				WLog_ERR(TAG,
				         "peer_recv_callback: CONNECTION_STATE_LICENSING - license_send_valid_client_error_packet() fail");
				return FALSE;
			}

			rdp_server_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
			return peer_recv_callback(transport, NULL, extra);
			break;

		case CONNECTION_STATE_CAPABILITIES_EXCHANGE:
			if (!rdp->AwaitCapabilities)
			{
				IFCALL(client->Capabilities, client);

				if (!rdp_send_demand_active(rdp))
				{
					WLog_ERR(TAG,
					         "peer_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - rdp_send_demand_active() fail");
					return -1;
				}

				rdp->AwaitCapabilities = TRUE;

				if (s)
				{
					if (peer_recv_pdu(client, s) < 0)
					{
						WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - peer_recv_pdu() fail");
						return -1;
					}
				}
			}
			else
			{
				/**
				 * During reactivation sequence the client might sent some input or channel data
				 * before receiving the Deactivate All PDU. We need to process them as usual.
				 */
				if (peer_recv_pdu(client, s) < 0)
				{
					WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - peer_recv_pdu() fail");
					return -1;
				}
			}

			break;

		case CONNECTION_STATE_FINALIZATION:
			if (peer_recv_pdu(client, s) < 0)
			{
				WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_FINALIZATION - peer_recv_pdu() fail");
				return -1;
			}

			break;

		case CONNECTION_STATE_ACTIVE:
			if (peer_recv_pdu(client, s) < 0)
			{
				WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_ACTIVE - peer_recv_pdu() fail");
				return -1;
			}

			break;

		default:
			WLog_ERR(TAG, "Invalid state %d", rdp->state);
			return -1;
	}

	return 0;
}
Ejemplo n.º 12
0
BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
{
	BOOL 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;

	fprintf(stderr, "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);

	fprintf(stderr, "Server Security: NLA:%d TLS:%d RDP:%d\n",
			settings->NlaSecurity, settings->TlsSecurity, settings->RdpSecurity);

	if ((settings->NlaSecurity) && (rdp->nego->requested_protocols & PROTOCOL_NLA))
	{
		rdp->nego->selected_protocol = PROTOCOL_NLA;
	}
	else if ((settings->TlsSecurity) && (rdp->nego->requested_protocols & PROTOCOL_TLS))
	{
		rdp->nego->selected_protocol = PROTOCOL_TLS;
	}
	else if ((settings->RdpSecurity) && (rdp->nego->selected_protocol == PROTOCOL_RDP))
	{
		rdp->nego->selected_protocol = PROTOCOL_RDP;
	}
	else
	{
		fprintf(stderr, "Protocol security negotiation failure\n");
	}

	fprintf(stderr, "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_server_transition_to_state(rdp, CONNECTION_STATE_NEGO);

	return TRUE;
}
Ejemplo n.º 13
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;
}