mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
[core,gcc] split update of RDP encryption from gcc
* Update EncryptionLevel and EncryptionMethods before writing GCC data * Use const rdpSettings* in all GCC write functions
This commit is contained in:
@@ -1489,6 +1489,154 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL rdp_update_encryption_level(rdpSettings* settings)
|
||||
{
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
UINT32 EncryptionLevel = freerdp_settings_get_uint32(settings, FreeRDP_EncryptionLevel);
|
||||
UINT32 EncryptionMethods = freerdp_settings_get_uint32(settings, FreeRDP_EncryptionMethods);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
/* TLS/NLA is used: disable rdp style encryption */
|
||||
EncryptionLevel = ENCRYPTION_LEVEL_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* verify server encryption level value */
|
||||
switch (EncryptionLevel)
|
||||
{
|
||||
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%08" PRIX32 "", EncryptionLevel);
|
||||
WLog_ERR(TAG, "Switching to encryption level CLIENT-COMPATIBLE");
|
||||
EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* choose rdp encryption method based on server level and client methods */
|
||||
switch (EncryptionLevel)
|
||||
{
|
||||
case ENCRYPTION_LEVEL_NONE:
|
||||
/* The only valid method is NONE in this case */
|
||||
EncryptionMethods = ENCRYPTION_METHOD_NONE;
|
||||
break;
|
||||
|
||||
case ENCRYPTION_LEVEL_FIPS:
|
||||
|
||||
/* The only valid method is FIPS in this case */
|
||||
if (!(EncryptionMethods & ENCRYPTION_METHOD_FIPS))
|
||||
{
|
||||
WLog_WARN(TAG, "client does not support FIPS as required by server configuration");
|
||||
}
|
||||
|
||||
EncryptionMethods = ENCRYPTION_METHOD_FIPS;
|
||||
break;
|
||||
|
||||
case ENCRYPTION_LEVEL_HIGH:
|
||||
|
||||
/* Maximum key strength supported by the server must be used (128 bit)*/
|
||||
if (!(EncryptionMethods & ENCRYPTION_METHOD_128BIT))
|
||||
{
|
||||
WLog_WARN(TAG, "client does not support 128 bit encryption method as required by "
|
||||
"server configuration");
|
||||
}
|
||||
|
||||
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 (EncryptionMethods & ENCRYPTION_METHOD_128BIT)
|
||||
EncryptionMethods = ENCRYPTION_METHOD_128BIT;
|
||||
else if (EncryptionMethods & ENCRYPTION_METHOD_56BIT)
|
||||
EncryptionMethods = ENCRYPTION_METHOD_56BIT;
|
||||
else if (EncryptionMethods & ENCRYPTION_METHOD_40BIT)
|
||||
EncryptionMethods = ENCRYPTION_METHOD_40BIT;
|
||||
else if (EncryptionMethods & ENCRYPTION_METHOD_FIPS)
|
||||
EncryptionMethods = ENCRYPTION_METHOD_FIPS;
|
||||
else
|
||||
{
|
||||
WLog_WARN(TAG, "client has not announced any supported encryption methods");
|
||||
EncryptionMethods = ENCRYPTION_METHOD_128BIT;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "internal error: unknown encryption level");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* log selected encryption method */
|
||||
if (settings->UseRdpSecurityLayer)
|
||||
{
|
||||
switch (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");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionLevel, EncryptionLevel))
|
||||
return FALSE;
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionMethods, EncryptionMethods))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
WINPR_ASSERT(rdp);
|
||||
@@ -1528,6 +1676,8 @@ BOOL rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, wStream* s)
|
||||
|
||||
if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_RESPONSE))
|
||||
return FALSE;
|
||||
if (!rdp_update_encryption_level(rdp->settings))
|
||||
return FALSE;
|
||||
if (!mcs_send_connect_response(mcs))
|
||||
return FALSE;
|
||||
if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_ERECT_DOMAIN))
|
||||
|
||||
@@ -1504,7 +1504,7 @@ BOOL gcc_read_server_core_data(wStream* s, rdpMcs* mcs)
|
||||
*/
|
||||
BOOL gcc_write_server_core_data(wStream* s, rdpMcs* mcs)
|
||||
{
|
||||
rdpSettings* settings = mcs_get_settings(mcs);
|
||||
const rdpSettings* settings = mcs_get_const_settings(mcs);
|
||||
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(settings);
|
||||
@@ -1759,146 +1759,11 @@ static BOOL gcc_update_server_random(rdpSettings* settings)
|
||||
*/
|
||||
BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs)
|
||||
{
|
||||
rdpSettings* settings = mcs_get_settings(mcs);
|
||||
const rdpSettings* settings = mcs_get_const_settings(mcs);
|
||||
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
/* TLS/NLA is used: disable rdp style encryption */
|
||||
settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* verify server encryption level value */
|
||||
switch (settings->EncryptionLevel)
|
||||
{
|
||||
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%08" PRIX32 "",
|
||||
settings->EncryptionLevel);
|
||||
WLog_ERR(TAG, "Switching to encryption level CLIENT-COMPATIBLE");
|
||||
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");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* log selected encryption method */
|
||||
if (settings->UseRdpSecurityLayer)
|
||||
{
|
||||
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");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t posHeader = Stream_GetPosition(s);
|
||||
if (!gcc_write_user_data_header(s, SC_SECURITY, 12))
|
||||
return FALSE;
|
||||
|
||||
Reference in New Issue
Block a user