Merge pull request #2273 from nfedera/fix-2014-12-12-01
Standard RDP Security Layer Levels/Method Overhaul
This commit is contained in:
commit
5ee4fb5fe6
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user