boolean nego_send_negotiation_response(rdpNego* nego) { STREAM* s; int length; uint8 *bm, *em; s = transport_send_stream_init(nego->transport, 256); length = TPDU_CONNECTION_CONFIRM_LENGTH; stream_get_mark(s, bm); stream_seek(s, length); if (nego->selected_protocol > PROTOCOL_RDP) { /* RDP_NEG_DATA must be present for TLS and NLA */ stream_write_uint8(s, TYPE_RDP_NEG_RSP); stream_write_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */ stream_write_uint32(s, nego->selected_protocol); /* selectedProtocol */ length += 8; } stream_get_mark(s, em); stream_set_mark(s, bm); tpkt_write_header(s, length); tpdu_write_connection_confirm(s, length - 5); stream_set_mark(s, em); if (transport_write(nego->transport, s) < 0) return false; /* update settings with negotiated protocol security */ nego->transport->settings->requested_protocols = nego->requested_protocols; nego->transport->settings->selected_protocol = nego->selected_protocol; return true; }
BOOL nego_send_negotiation_response(rdpNego* nego) { int length; int bm, em; BOOL status; wStream* s; BYTE flags; rdpSettings* settings; status = TRUE; settings = nego->transport->settings; s = Stream_New(NULL, 512); if (!s) return FALSE; length = TPDU_CONNECTION_CONFIRM_LENGTH; bm = Stream_GetPosition(s); Stream_Seek(s, length); if (nego->SelectedProtocol & PROTOCOL_FAILED_NEGO) { UINT32 errorCode = (nego->SelectedProtocol & ~PROTOCOL_FAILED_NEGO); flags = 0; Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE); Stream_Write_UINT8(s, flags); /* flags */ Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ Stream_Write_UINT32(s, errorCode); length += 8; status = FALSE; } else { flags = EXTENDED_CLIENT_DATA_SUPPORTED; if (settings->SupportGraphicsPipeline) flags |= DYNVC_GFX_PROTOCOL_SUPPORTED; /* RDP_NEG_DATA must be present for TLS, NLA, and RDP */ Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP); Stream_Write_UINT8(s, flags); /* flags */ Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ Stream_Write_UINT32(s, nego->SelectedProtocol); /* selectedProtocol */ length += 8; } em = Stream_GetPosition(s); Stream_SetPosition(s, bm); tpkt_write_header(s, length); tpdu_write_connection_confirm(s, length - 5); Stream_SetPosition(s, em); Stream_SealLength(s); if (transport_write(nego->transport, s) < 0) { Stream_Free(s, TRUE); return FALSE; } Stream_Free(s, TRUE); if (status) { /* update settings with negotiated protocol security */ settings->RequestedProtocols = nego->RequestedProtocols; settings->SelectedProtocol = nego->SelectedProtocol; if (settings->SelectedProtocol == PROTOCOL_RDP) { settings->TlsSecurity = FALSE; settings->NlaSecurity = FALSE; settings->RdpSecurity = TRUE; settings->UseRdpSecurityLayer = TRUE; if (settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE) { /** * If the server implementation did not explicitely set a * encryption level we default to client compatible */ settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } if (settings->LocalConnection) { /** * Note: This hack was firstly introduced in commit 95f5e115 to * disable the unnecessary encryption with peers connecting to * 127.0.0.1 or local unix sockets. * This also affects connections via port tunnels! (e.g. ssh -L) */ WLog_INFO(TAG, "Turning off encryption for local peer with standard rdp security"); settings->UseRdpSecurityLayer = FALSE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } if (!settings->RdpServerRsaKey && !settings->RdpKeyFile) { WLog_ERR(TAG, "Missing server certificate"); return FALSE; } } else if (settings->SelectedProtocol == PROTOCOL_TLS) { settings->TlsSecurity = TRUE; settings->NlaSecurity = FALSE; settings->RdpSecurity = FALSE; settings->UseRdpSecurityLayer = FALSE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } else if (settings->SelectedProtocol == PROTOCOL_NLA) { settings->TlsSecurity = TRUE; settings->NlaSecurity = TRUE; settings->RdpSecurity = FALSE; settings->UseRdpSecurityLayer = FALSE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } } return status; }
BOOL nego_send_negotiation_response(rdpNego* nego) { STREAM* s; BYTE* bm; BYTE* em; int length; BOOL status; rdpSettings* settings; status = TRUE; settings = nego->transport->settings; s = transport_send_stream_init(nego->transport, 256); length = TPDU_CONNECTION_CONFIRM_LENGTH; stream_get_mark(s, bm); stream_seek(s, length); if (nego->selected_protocol > PROTOCOL_RDP) { /* RDP_NEG_DATA must be present for TLS and NLA */ stream_write_BYTE(s, TYPE_RDP_NEG_RSP); stream_write_BYTE(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ stream_write_UINT32(s, nego->selected_protocol); /* selectedProtocol */ length += 8; } else if (!settings->RdpSecurity) { stream_write_BYTE(s, TYPE_RDP_NEG_FAILURE); stream_write_BYTE(s, 0); /* flags */ stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ /* * TODO: Check for other possibilities, * like SSL_NOT_ALLOWED_BY_SERVER. */ printf("nego_send_negotiation_response: client supports only Standard RDP Security\n"); stream_write_UINT32(s, SSL_REQUIRED_BY_SERVER); length += 8; status = FALSE; } stream_get_mark(s, em); stream_set_mark(s, bm); tpkt_write_header(s, length); tpdu_write_connection_confirm(s, length - 5); stream_set_mark(s, em); if (transport_write(nego->transport, s) < 0) return FALSE; if (status) { /* update settings with negotiated protocol security */ settings->RequestedProtocols = nego->requested_protocols; settings->SelectedProtocol = nego->selected_protocol; if (settings->SelectedProtocol == PROTOCOL_RDP) { settings->TlsSecurity = FALSE; settings->NlaSecurity = FALSE; settings->RdpSecurity = TRUE; if (!settings->LocalConnection) { settings->DisableEncryption = TRUE; settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } if (settings->DisableEncryption && settings->RdpServerRsaKey == NULL && settings->RdpKeyFile == NULL) return FALSE; } else if (settings->SelectedProtocol == PROTOCOL_TLS) { settings->TlsSecurity = TRUE; settings->NlaSecurity = FALSE; settings->RdpSecurity = FALSE; settings->DisableEncryption = FALSE; settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } else if (settings->SelectedProtocol == PROTOCOL_NLA) { settings->TlsSecurity = TRUE; settings->NlaSecurity = TRUE; settings->RdpSecurity = FALSE; settings->DisableEncryption = FALSE; settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } } return status; }
boolean nego_send_negotiation_response(rdpNego* nego) { STREAM* s; uint8* bm; uint8* em; int length; boolean status; rdpSettings* settings; status = true; settings = nego->transport->settings; s = transport_send_stream_init(nego->transport, 256); length = TPDU_CONNECTION_CONFIRM_LENGTH; stream_get_mark(s, bm); stream_seek(s, length); if (nego->selected_protocol > PROTOCOL_RDP) { /* RDP_NEG_DATA must be present for TLS and NLA */ stream_write_uint8(s, TYPE_RDP_NEG_RSP); stream_write_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */ stream_write_uint32(s, nego->selected_protocol); /* selectedProtocol */ length += 8; } else if (!settings->rdp_security) { stream_write_uint8(s, TYPE_RDP_NEG_FAILURE); stream_write_uint8(s, 0); /* flags */ stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */ /* * TODO: Check for other possibilities, * like SSL_NOT_ALLOWED_BY_SERVER. */ printf("nego_send_negotiation_response: client supports only Standard RDP Security\n"); stream_write_uint32(s, SSL_REQUIRED_BY_SERVER); length += 8; status = false; } stream_get_mark(s, em); stream_set_mark(s, bm); tpkt_write_header(s, length); tpdu_write_connection_confirm(s, length - 5); stream_set_mark(s, em); if (transport_write(nego->transport, s) < 0) return false; if (status) { /* update settings with negotiated protocol security */ settings->requested_protocols = nego->requested_protocols; settings->selected_protocol = nego->selected_protocol; if (settings->selected_protocol == PROTOCOL_RDP) { settings->tls_security = false; settings->nla_security = false; settings->rdp_security = true; if (!settings->local) { settings->encryption = true; settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } if (settings->encryption && settings->server_key == NULL && settings->rdp_key_file == NULL) return false; } else if (settings->selected_protocol == PROTOCOL_TLS) { settings->tls_security = true; settings->nla_security = false; settings->rdp_security = false; settings->encryption = false; settings->encryption_method = ENCRYPTION_METHOD_NONE; settings->encryption_level = ENCRYPTION_LEVEL_NONE; } else if (settings->selected_protocol == PROTOCOL_NLA) { settings->tls_security = true; settings->nla_security = true; settings->rdp_security = false; settings->encryption = false; settings->encryption_method = ENCRYPTION_METHOD_NONE; settings->encryption_level = ENCRYPTION_LEVEL_NONE; } } return status; }