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