diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index c1e9594f6..d24a59b2e 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -745,9 +745,7 @@ JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, settings->TlsSecurity = FALSE; settings->NlaSecurity = FALSE; settings->ExtSecurity = FALSE; - settings->DisableEncryption = TRUE; - settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; - settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + settings->UseRdpSecurityLayer = TRUE; break; case 2: diff --git a/client/common/cmdline.c b/client/common/cmdline.c index dc477910f..5268267ce 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -3,6 +3,7 @@ * FreeRDP Client Command-Line Interface * * Copyright 2012 Marc-Andre Moreau + * Copyright 2014 Norbert Federa * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -167,6 +168,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "heartbeat", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support heartbeat PDUs" }, { "multitransport", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support multitransport protocol" }, { "assistance", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Remote assistance password" }, + { "encryption-methods", COMMAND_LINE_VALUE_REQUIRED, "<40,56,128,FIPS>", NULL, NULL, -1, NULL, "RDP standard security encryption methods" }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; @@ -1733,9 +1735,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, settings->TlsSecurity = FALSE; settings->NlaSecurity = FALSE; settings->ExtSecurity = FALSE; - settings->DisableEncryption = TRUE; - settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT| ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; - settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + settings->UseRdpSecurityLayer = TRUE; } else if (strcmp("tls", arg->Value) == 0) /* TLS */ { @@ -1763,6 +1763,33 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, WLog_ERR(TAG, "unknown protocol security: %s", arg->Value); } } + CommandLineSwitchCase(arg, "encryption-methods") + { + if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) + { + UINT32 i; + char** p; + int count = 0; + + p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count); + + for (i = 0; i < count; i++) + { + if (!strcmp(p[i], "40")) + settings->EncryptionMethods |= ENCRYPTION_METHOD_40BIT; + else if (!strcmp(p[i], "56")) + settings->EncryptionMethods |= ENCRYPTION_METHOD_56BIT; + else if (!strcmp(p[i], "128")) + settings->EncryptionMethods |= ENCRYPTION_METHOD_128BIT; + else if (!strcmp(p[i], "FIPS")) + settings->EncryptionMethods |= ENCRYPTION_METHOD_FIPS; + else + WLog_ERR(TAG, "unknown encryption method '%s'", p[i]); + } + + free(p); + } + } CommandLineSwitchCase(arg, "sec-rdp") { settings->RdpSecurity = arg->Value ? TRUE : FALSE; @@ -1801,7 +1828,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "encryption") { - settings->DisableEncryption = arg->Value ? FALSE : TRUE; + settings->UseRdpSecurityLayer = arg->Value ? FALSE : TRUE; } CommandLineSwitchCase(arg, "grab-keyboard") { diff --git a/client/common/compatibility.c b/client/common/compatibility.c index a290b49e8..c9af91629 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -695,9 +695,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe settings->RdpSecurity = TRUE; settings->TlsSecurity = FALSE; settings->NlaSecurity = FALSE; - settings->DisableEncryption = FALSE; - settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; - settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + settings->UseRdpSecurityLayer = FALSE; } else if (strncmp("tls", arg->Value, 1) == 0) /* TLS */ { diff --git a/client/iOS/Models/RDPSession.m b/client/iOS/Models/RDPSession.m index 8cb045754..d2ff9e361 100644 --- a/client/iOS/Models/RDPSession.m +++ b/client/iOS/Models/RDPSession.m @@ -158,9 +158,7 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect" settings->TlsSecurity = FALSE; settings->NlaSecurity = FALSE; settings->ExtSecurity = FALSE; - settings->DisableEncryption = TRUE; - settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; - settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + settings->UseRdpSecurityLayer = TRUE; break; default: diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index ce914b119..c92bc7142 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -529,7 +529,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_SupportGraphicsPipeline 142 #define FreeRDP_SupportDynamicTimeZone 143 #define FreeRDP_SupportHeartbeatPdu 144 -#define FreeRDP_DisableEncryption 192 +#define FreeRDP_UseRdpSecurityLayer 192 #define FreeRDP_EncryptionMethods 193 #define FreeRDP_ExtEncryptionMethods 194 #define FreeRDP_EncryptionLevel 195 @@ -860,7 +860,7 @@ struct rdp_settings UINT64 padding0192[192 - 145]; /* 145 */ /* Client/Server Security Data */ - ALIGN64 BOOL DisableEncryption; /* 192 */ + ALIGN64 BOOL UseRdpSecurityLayer; /* 192 */ ALIGN64 UINT32 EncryptionMethods; /* 193 */ ALIGN64 UINT32 ExtEncryptionMethods; /* 194 */ ALIGN64 UINT32 EncryptionLevel; /* 195 */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index d9c986668..872581431 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -682,8 +682,8 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) case FreeRDP_SupportDynamicTimeZone: return settings->SupportDynamicTimeZone; - case FreeRDP_DisableEncryption: - return settings->DisableEncryption; + case FreeRDP_UseRdpSecurityLayer: + return settings->UseRdpSecurityLayer; case FreeRDP_ConsoleSession: return settings->ConsoleSession; @@ -1075,8 +1075,8 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) settings->SupportDynamicTimeZone = param; break; - case FreeRDP_DisableEncryption: - settings->DisableEncryption = param; + case FreeRDP_UseRdpSecurityLayer: + settings->UseRdpSecurityLayer = param; break; case FreeRDP_ConsoleSession: diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index 92758d3c5..e794e2eed 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -3537,7 +3537,7 @@ BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId) if (rdp->disconnect) return TRUE; - if (rdp->settings->DisableEncryption) + if (rdp->settings->UseRdpSecurityLayer) { if (!rdp_read_security_header(s, &securityFlags)) return FALSE; diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index acd0d2741..13d14c929 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -398,7 +398,7 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) settings = rdp->settings; - if (!settings->DisableEncryption) + if (!settings->UseRdpSecurityLayer) { /* no RDP encryption */ return TRUE; @@ -515,7 +515,7 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) BYTE* priv_exp; BOOL ret = FALSE; - if (!rdp->settings->DisableEncryption) + if (!rdp->settings->UseRdpSecurityLayer) { /* No RDP Security. */ return TRUE; diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index d77a5ab0f..cff7de49f 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -3,6 +3,7 @@ * T.124 Generic Conference Control (GCC) * * Copyright 2011 Marc-Andre Moreau + * Copyright 2014 Norbert Federa * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +29,7 @@ #include "gcc.h" #include "certificate.h" -#define TAG FREERDP_TAG("core") +#define TAG FREERDP_TAG("core.gcc") /** * T.124 GCC is defined in: @@ -948,7 +949,7 @@ BOOL gcc_read_client_security_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (blockLength < 8) return FALSE; - if (settings->DisableEncryption) + if (settings->UseRdpSecurityLayer) { Stream_Read_UINT32(s, settings->EncryptionMethods); /* encryptionMethods */ if (settings->EncryptionMethods == 0) @@ -976,7 +977,7 @@ void gcc_write_client_security_data(wStream* s, rdpMcs* mcs) gcc_write_user_data_header(s, CS_SECURITY, 12); - if (settings->DisableEncryption) + if (settings->UseRdpSecurityLayer) { Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethods */ Stream_Write_UINT32(s, 0); /* extEncryptionMethods */ @@ -994,19 +995,87 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) BYTE* data; UINT32 length; rdpSettings* settings = mcs->settings; + BOOL validCryptoConfig = FALSE; + UINT32 serverEncryptionMethod; if (Stream_GetRemainingLength(s) < 8) return FALSE; - Stream_Read_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ + Stream_Read_UINT32(s, serverEncryptionMethod); /* encryptionMethod */ Stream_Read_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ - if (settings->EncryptionMethods == 0 && settings->EncryptionLevel == 0) + /* Only accept valid/known encryption methods */ + switch (serverEncryptionMethod) { - /* serverRandom and serverRandom must not be present */ - settings->DisableEncryption = FALSE; - settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; - settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; + case ENCRYPTION_METHOD_NONE: + WLog_DBG(TAG, "Server rdp encryption method: NONE"); + break; + case ENCRYPTION_METHOD_40BIT: + WLog_DBG(TAG, "Server rdp encryption method: 40BIT"); + break; + case ENCRYPTION_METHOD_56BIT: + WLog_DBG(TAG, "Server rdp encryption method: 56BIT"); + break; + case ENCRYPTION_METHOD_128BIT: + WLog_DBG(TAG, "Server rdp encryption method: 128BIT"); + break; + case ENCRYPTION_METHOD_FIPS: + WLog_DBG(TAG, "Server rdp encryption method: FIPS"); + break; + default: + WLog_ERR(TAG, "Received unknown encryption method %08X", serverEncryptionMethod); + return FALSE; + } + + if (settings->UseRdpSecurityLayer && !(settings->EncryptionMethods & serverEncryptionMethod)) + { + WLog_WARN(TAG, "Server uses non-advertised encryption method 0x%08X", serverEncryptionMethod); + /* FIXME: Should we return FALSE; in this case ?? */ + } + + settings->EncryptionMethods = serverEncryptionMethod; + + /* Verify encryption level/method combinations according to MS-RDPBCGR Section 5.3.2 */ + switch (settings->EncryptionLevel) + { + case ENCRYPTION_LEVEL_NONE: + if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE) + { + validCryptoConfig = TRUE; + } + break; + case ENCRYPTION_LEVEL_FIPS: + if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) + { + validCryptoConfig = TRUE; + } + break; + case ENCRYPTION_LEVEL_LOW: + case ENCRYPTION_LEVEL_HIGH: + case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: + if (settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT || + settings->EncryptionMethods == ENCRYPTION_METHOD_56BIT || + settings->EncryptionMethods == ENCRYPTION_METHOD_128BIT || + settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) + { + validCryptoConfig = TRUE; + } + break; + default: + WLog_ERR(TAG, "Received unknown encryption level %08X", settings->EncryptionLevel); + } + + if (!validCryptoConfig) + { + WLog_ERR(TAG, "Received invalid cryptographic configuration (level=0x%08X method=0x%08X)", + settings->EncryptionLevel, settings->EncryptionMethods); + return FALSE; + } + + if (settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE) + { + /* serverRandomLen and serverCertLen must not be present */ + settings->UseRdpSecurityLayer = FALSE; return TRUE; } @@ -1102,30 +1171,111 @@ void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) UINT32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; rdpSettings* settings = mcs->settings; - if (!settings->DisableEncryption) + /** + * Re: settings->EncryptionLevel: + * This is configured/set by the server implementation and serves the same + * purpose as the "Encryption Level" setting in the RDP-Tcp configuration + * dialog of Microsoft's Remote Desktop Session Host Configuration. + * Re: settings->EncryptionMethods: + * at this point this setting contains the client's supported encryption + * methods we've received in gcc_read_client_security_data() + */ + + if (!settings->UseRdpSecurityLayer) { - settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; + /* TLS/NLA is used: disable rdp style encryption */ settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } - else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS) != 0) + + /* verify server encryption level value */ + switch (settings->EncryptionLevel) { - settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; - } - else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) != 0) - { - settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; - } - else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_56BIT) != 0) - { - settings->EncryptionMethods = ENCRYPTION_METHOD_56BIT; - } - else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT) != 0) - { - settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT; + case ENCRYPTION_LEVEL_NONE: + WLog_INFO(TAG, "Active rdp encryption level: NONE"); + break; + case ENCRYPTION_LEVEL_FIPS: + WLog_INFO(TAG, "Active rdp encryption level: FIPS Compliant"); + break; + case ENCRYPTION_LEVEL_HIGH: + WLog_INFO(TAG, "Active rdp encryption level: HIGH"); + break; + case ENCRYPTION_LEVEL_LOW: + WLog_INFO(TAG, "Active rdp encryption level: LOW"); + break; + case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: + WLog_INFO(TAG, "Active rdp encryption level: CLIENT-COMPATIBLE"); + break; + default: + WLog_ERR(TAG, "Invalid server encryption level 0x%08X", settings->EncryptionLevel); + WLog_ERR(TAG, "Switching to encryption level CLIENT-COMPATIBLE"); + settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } - if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) - settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + /* choose rdp encryption method based on server level and client methods */ + switch (settings->EncryptionLevel) + { + case ENCRYPTION_LEVEL_NONE: + /* The only valid method is NONE in this case */ + settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; + break; + case ENCRYPTION_LEVEL_FIPS: + /* The only valid method is FIPS in this case */ + if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS)) + { + WLog_WARN(TAG, "client does not support FIPS as required by server configuration"); + } + settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; + break; + case ENCRYPTION_LEVEL_HIGH: + /* Maximum key strength supported by the server must be used (128 bit)*/ + if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT)) + { + WLog_WARN(TAG, "client does not support 128 bit encryption method as required by server configuration"); + } + settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; + break; + case ENCRYPTION_LEVEL_LOW: + case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: + /* Maximum key strength supported by the client must be used */ + if (settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) + settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; + else if (settings->EncryptionMethods & ENCRYPTION_METHOD_56BIT) + settings->EncryptionMethods = ENCRYPTION_METHOD_56BIT; + else if (settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT) + settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT; + else if (settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS) + settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; + else + { + WLog_WARN(TAG, "client has not announced any supported encryption methods"); + settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; + } + break; + default: + WLog_ERR(TAG, "internal error: unknown encryption level"); + } + + /* log selected encryption method */ + switch (settings->EncryptionMethods) + { + case ENCRYPTION_METHOD_NONE: + WLog_INFO(TAG, "Selected rdp encryption method: NONE"); + break; + case ENCRYPTION_METHOD_40BIT: + WLog_INFO(TAG, "Selected rdp encryption method: 40BIT"); + break; + case ENCRYPTION_METHOD_56BIT: + WLog_INFO(TAG, "Selected rdp encryption method: 56BIT"); + break; + case ENCRYPTION_METHOD_128BIT: + WLog_INFO(TAG, "Selected rdp encryption method: 128BIT"); + break; + case ENCRYPTION_METHOD_FIPS: + WLog_INFO(TAG, "Selected rdp encryption method: FIPS"); + break; + default: + WLog_ERR(TAG, "internal error: unknown encryption method"); + } headerLen = 12; keyLen = 0; @@ -1133,8 +1283,7 @@ void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) serverRandomLen = 0; serverCertLen = 0; - if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE || - settings->EncryptionLevel != ENCRYPTION_LEVEL_NONE) + if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) { serverRandomLen = 32; @@ -1170,8 +1319,7 @@ void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ - if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE && - settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE) + if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE) { return; } @@ -1243,7 +1391,7 @@ BOOL gcc_read_client_network_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (blockLength < 4 + mcs->channelCount * 12) return FALSE; - + if (mcs->channelCount > 16) return FALSE; diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 9fd499a8a..f16e7db51 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -590,7 +590,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s) if ((securityFlags & SEC_INFO_PKT) == 0) return FALSE; - if (rdp->settings->DisableEncryption) + if (rdp->settings->UseRdpSecurityLayer) { if (securityFlags & SEC_REDIRECTION_PKT) { diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index 874cc510b..59a715f90 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -3,6 +3,7 @@ * RDP Protocol Security Negotiation * * Copyright 2011 Marc-Andre Moreau + * Copyright 2014 Norbert Federa * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -164,9 +165,16 @@ BOOL nego_connect(rdpNego* nego) if (nego->selected_protocol == PROTOCOL_RDP) { - settings->DisableEncryption = TRUE; - settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; - settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + settings->UseRdpSecurityLayer = TRUE; + + if (!settings->EncryptionMethods) + { + /** + * Advertise all supported encryption methods if the client + * implementation did not set any security methods + */ + settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; + } } /* finally connect security layer (if not already done) */ @@ -964,14 +972,30 @@ BOOL nego_send_negotiation_response(rdpNego* nego) settings->TlsSecurity = FALSE; settings->NlaSecurity = FALSE; settings->RdpSecurity = TRUE; + settings->UseRdpSecurityLayer = TRUE; - if (!settings->LocalConnection) + if (settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE) { - settings->DisableEncryption = TRUE; - settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; + /** + * 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"); @@ -983,8 +1007,7 @@ BOOL nego_send_negotiation_response(rdpNego* nego) settings->TlsSecurity = TRUE; settings->NlaSecurity = FALSE; settings->RdpSecurity = FALSE; - settings->DisableEncryption = FALSE; - settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; + settings->UseRdpSecurityLayer = FALSE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } else if (settings->SelectedProtocol == PROTOCOL_NLA) @@ -992,8 +1015,7 @@ BOOL nego_send_negotiation_response(rdpNego* nego) settings->TlsSecurity = TRUE; settings->NlaSecurity = TRUE; settings->RdpSecurity = FALSE; - settings->DisableEncryption = FALSE; - settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; + settings->UseRdpSecurityLayer = FALSE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } } diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 53afc6006..652e0ef86 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -348,7 +348,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) if (rdp->disconnect) return 0; - if (rdp->settings->DisableEncryption) + if (rdp->settings->UseRdpSecurityLayer) { if (!rdp_read_security_header(s, &securityFlags)) return -1; @@ -485,7 +485,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) break; case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT: - if (rdp->settings->DisableEncryption) + if (rdp->settings->UseRdpSecurityLayer) { if (!rdp_server_establish_keys(rdp, s)) return -1; diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 9fa1901a5..abd14210a 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -1040,7 +1040,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) rdp->autodetect->bandwidthMeasureByteCount += length; } - if (rdp->settings->DisableEncryption) + if (rdp->settings->UseRdpSecurityLayer) { if (!rdp_read_security_header(s, &securityFlags)) return -1; diff --git a/libfreerdp/core/security.c b/libfreerdp/core/security.c index dc46c42b5..dd8c50bbf 100644 --- a/libfreerdp/core/security.c +++ b/libfreerdp/core/security.c @@ -422,7 +422,6 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp) CryptoSha1 sha1; BYTE client_encrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1]; BYTE client_decrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1]; - WLog_INFO(TAG, "FIPS Compliant encryption level."); sha1 = crypto_sha1_init(); if (!sha1) { diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index eabb8436d..2744b7ae2 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -232,7 +232,7 @@ rdpSettings* freerdp_settings_new(DWORD flags) settings->KeyboardSubType = 0; settings->KeyboardFunctionKey = 12; settings->KeyboardLayout = 0; - settings->DisableEncryption = FALSE; + settings->UseRdpSecurityLayer = FALSE; settings->SaltedChecksum = TRUE; settings->ServerPort = 3389; settings->GatewayPort = 443; diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index 405933d01..844907ab4 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -4,6 +4,7 @@ * * Copyright 2011 Marc-Andre Moreau * Copyright 2011 Vic Lee + * Copyright 2014 Norbert Federa * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -347,19 +348,19 @@ static BOOL test_sleep_tsdiff(UINT32 *old_sec, UINT32 *old_usec, UINT32 new_sec, *old_sec = new_sec; *old_usec = new_usec; - - while (usec < 0) + + while (usec < 0) { usec += 1000000; sec--; } - + if (sec > 0) Sleep(sec * 1000); - + if (usec > 0) USleep(usec); - + return TRUE; } @@ -669,7 +670,15 @@ static void* test_peer_mainloop(void* arg) /* Initialize the real server settings here */ client->settings->CertificateFile = _strdup("server.crt"); client->settings->PrivateKeyFile = _strdup("server.key"); + client->settings->RdpKeyFile = _strdup("server.key"); + client->settings->RdpSecurity = TRUE; + client->settings->TlsSecurity = TRUE; client->settings->NlaSecurity = FALSE; + client->settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + /* client->settings->EncryptionLevel = ENCRYPTION_LEVEL_HIGH; */ + /* client->settings->EncryptionLevel = ENCRYPTION_LEVEL_LOW; */ + /* client->settings->EncryptionLevel = ENCRYPTION_LEVEL_FIPS; */ + client->settings->RemoteFxCodec = TRUE; client->settings->ColorDepth = 32; client->settings->SuppressOutput = TRUE; @@ -844,7 +853,7 @@ int main(int argc, char* argv[]) if (argc > 1) test_pcap_file = argv[1]; - + if (argc > 2 && !strcmp(argv[2], "--fast")) test_dump_rfx_realtime = FALSE;