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; }
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; }
/** * 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); }
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; }
/** * 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); }
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; }
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; }
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; }
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; }