Standard RDP Security Layer Levels/Method Overhaul
[MS-RDPBCGR] Section 5.3 describes the encryption level and method values for standard RDP security. Looking at the current usage of these values in the FreeRDP code gives me reason to believe that there is a certain lack of understanding of how these values should be handled. The encryption level is only configured on the server side in the "Encryption Level" setting found in the Remote Desktop Session Host Configuration RDP-Tcp properties dialog and this value is never transferred from the client to the server over the wire. The possible options are "None", "Low", "Client Compatible", "High" and "FIPS Compliant". The client receices this value in the Server Security Data block (TS_UD_SC_SEC1), probably only for informational purposes and maybe to give the client the possibility to verify if the server's decision for the encryption method confirms to the server's encryption level. The possible encryption methods are "NONE", "40BIT", "56BIT", "128BIT" and "FIPS" and the RDP client advertises the ones it supports to the server in the Client Security Data block (TS_UD_CS_SEC). The server's configured encryption level value restricts the possible final encryption method. Something that I was not able to find in the documentation is the priority level of the individual encryption methods based on which the server makes its final method decision if there are several options. My analysis with Windows Servers reveiled that the order is 128, 56, 40, FIPS. The server only chooses FIPS if the level is "FIPS Comliant" or if it is the only method advertised by the client. Bottom line: * FreeRDP's client side does not need to set settings->EncryptionLevel (which was done quite frequently). * FreeRDP's server side does not have to set the supported encryption methods list in settings->EncryptionMethods Changes in this commit: Removed unnecessary/confusing changes of EncryptionLevel/Methods settings Refactor settings->DisableEncryption * This value actually means "Advanced RDP Encryption (NLA/TLS) is NOT used" * The old name caused lots of confusion among developers * Renamed it to "UseRdpSecurityLayer" (the compare logic stays untouched) Any client's setting of settings->EncryptionMethods were annihilated * All clients "want" to set all supported methods * Some clients forgot 56bit because 56bit was not supported at the time the code was written * settings->EncryptionMethods was overwritten anyways in nego_connect() * Removed all client side settings of settings->EncryptionMethods The default is "None" (0) * Changed nego_connect() to advertise all supported methods if settings->EncryptionMethods is 0 (None) * Added a commandline option /encryption-methods:comma separated list of the values "40", "56", "128", "FIPS". E.g. /encryption-methods:56,128 * Print warning if server chooses non-advertised method Verify received level and method in client's gcc_read_server_security_data * Only accept valid/known encryption methods * Verify encryption level/method combinations according to MS-RDPBCGR 5.3.2 Server implementations can now set settings->EncryptionLevel * The default for settings->EncryptionLevel is 0 (None) * nego_send_negotiation_response() changes it to ClientCompatible in that case * default to ClientCompatible if the server implementation set an invalid level Fix server's gcc_write_server_security_data * Verify server encryption level value set by server implementations * Choose rdp encryption method based on level and supported client methods * Moved FIPS to the lowest priority (only used if other methods are possible) Updated sample server * Support RDP Security (RdpKeyFile was not set) * Added commented sample code for setting the security level
This commit is contained in:
parent
b579ad3cec
commit
939f1c639a
@ -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:
|
||||
|
@ -3,6 +3,7 @@
|
||||
* FreeRDP Client Command-Line Interface
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2014 Norbert Federa <norbert.federa@thincast.com>
|
||||
*
|
||||
* 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, "<password>", 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")
|
||||
{
|
||||
|
@ -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 */
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -3,6 +3,7 @@
|
||||
* T.124 Generic Conference Control (GCC)
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2014 Norbert Federa <norbert.federa@thincast.com>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
* RDP Protocol Security Negotiation
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2014 Norbert Federa <norbert.federa@thincast.com>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -4,6 +4,7 @@
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2011 Vic Lee
|
||||
* Copyright 2014 Norbert Federa <norbert.federa@thincast.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user