server: proxy: separate client and server security settings

This commit is contained in:
kubistika 2019-09-18 16:08:25 +03:00 committed by akallabeth
parent 21f2ca93d3
commit 32913850d5
5 changed files with 104 additions and 41 deletions

View File

@ -19,9 +19,11 @@ Mouse = 1
Keyboard = 1
[Security]
NlaSecurity = 0
TlsSecurity = 1
RdpSecurity = 1
ServerTlsSecurity = 1
ServerRdpSecurity = 0
ClientTlsSecurity = 1
ClientRdpSecurity = 0
ClientNlaSecurity = 0
[Channels]
GFX = 1

View File

@ -266,47 +266,94 @@ static void pf_client_post_disconnect(freerdp* instance)
proxy_data_abort_connect(pdata);
}
/*
* pf_client_should_retry_without_nla:
*
* returns TRUE if in case of connection failure, the client should try again without NLA.
* Otherwise, returns FALSE.
*/
static BOOL pf_client_should_retry_without_nla(pClientContext* pc)
{
rdpSettings* settings = pc->context.settings;
proxyConfig* config = pc->pdata->config;
if (!settings->NlaSecurity)
return FALSE;
return config->ClientTlsSecurity || config->ClientRdpSecurity;
}
static void pf_client_set_security_settings(pClientContext* pc)
{
rdpSettings* settings = pc->context.settings;
proxyConfig* config = pc->pdata->config;
settings->RdpSecurity = config->ClientRdpSecurity;
settings->TlsSecurity = config->ClientTlsSecurity;
settings->NlaSecurity = FALSE;
if (!config->ClientNlaSecurity)
return;
if (!settings->Username || !settings->Password)
return;
settings->NlaSecurity = TRUE;
}
static BOOL pf_client_connect_without_nla(pClientContext* pc)
{
freerdp* instance = pc->context.instance;
rdpSettings* settings = pc->context.settings;
/* disable NLA */
settings->NlaSecurity = FALSE;
/* do not allow next connection failure */
pc->allow_next_conn_failure = FALSE;
return freerdp_connect(instance);
}
static BOOL pf_client_connect(freerdp* instance)
{
pClientContext* pc = (pClientContext*) instance->context;
rdpSettings* settings = pc->context.settings;
BOOL rc = FALSE;
BOOL retry_without_nla = FALSE;
/* if credentials are available, always try to connect with NLA on first try */
if (settings->Username && settings->Password)
{
settings->NlaSecurity = TRUE;
pc->allow_next_conn_failure = TRUE;
}
else
settings->NlaSecurity = FALSE;
pf_client_set_security_settings(pc);
if (pf_client_should_retry_without_nla(pc))
retry_without_nla = pc->allow_next_conn_failure = TRUE;
if (!freerdp_connect(instance))
{
if (settings->NlaSecurity)
UINT32 last_error = freerdp_get_last_error(instance->context);
UINT32 last_error_type = GET_FREERDP_ERROR_TYPE(last_error);
/* Do not retry if last error is not ERRCONNECT_LOGON_FAILURE */
if (last_error_type != ERRCONNECT_LOGON_FAILURE)
retry_without_nla = FALSE;
if (retry_without_nla)
{
WLog_ERR(TAG, "freerdp_connect() failed, trying to connect without NLA");
WLog_ERR(TAG, "failed to connect with NLA. disabling NLA and retyring...");
/* disable NLA, enable TLS */
settings->NlaSecurity = FALSE;
settings->RdpSecurity = TRUE;
settings->TlsSecurity = TRUE;
pc->allow_next_conn_failure = FALSE;
if (!freerdp_connect(instance))
if (!pf_client_connect_without_nla(pc))
{
WLog_ERR(TAG, "connection failure");
return FALSE;
WLog_ERR(TAG, "pf_client_connect_without_nla failed!");
goto out;
}
}
else
{
WLog_ERR(TAG, "connection failure");
return FALSE;
WLog_ERR(TAG, "connection failure!");
goto out;
}
}
rc = TRUE;
out:
pc->allow_next_conn_failure = FALSE;
return TRUE;
return rc;
}
/**
@ -337,7 +384,10 @@ static DWORD WINAPI pf_client_thread_proc(LPVOID arg)
return FALSE;
if (!pf_client_connect(instance))
{
proxy_data_abort_connect(pdata);
return FALSE;
}
while (!freerdp_shall_disconnect(instance))
{

View File

@ -105,9 +105,12 @@ static BOOL pf_config_load_input(wIniFile* ini, proxyConfig* config)
static BOOL pf_config_load_security(wIniFile* ini, proxyConfig* config)
{
config->TlsSecurity = CONFIG_GET_BOOL(ini, "Security", "TlsSecurity");
config->NlaSecurity = CONFIG_GET_BOOL(ini, "Security", "NlaSecurity");
config->RdpSecurity = CONFIG_GET_BOOL(ini, "Security", "RdpSecurity");
config->ServerTlsSecurity = CONFIG_GET_BOOL(ini, "Security", "ServerTlsSecurity");
config->ServerRdpSecurity = CONFIG_GET_BOOL(ini, "Security", "ServerRdpSecurity");
config->ClientTlsSecurity = CONFIG_GET_BOOL(ini, "Security", "ClientTlsSecurity");
config->ClientNlaSecurity = CONFIG_GET_BOOL(ini, "Security", "ClientNlaSecurity");
config->ClientRdpSecurity = CONFIG_GET_BOOL(ini, "Security", "ClientRdpSecurity");
return TRUE;
}
@ -210,10 +213,14 @@ void pf_server_config_print(proxyConfig* config)
CONFIG_PRINT_BOOL(config, Keyboard);
CONFIG_PRINT_BOOL(config, Mouse);
CONFIG_PRINT_SECTION("Security");
CONFIG_PRINT_BOOL(config, NlaSecurity);
CONFIG_PRINT_BOOL(config, TlsSecurity);
CONFIG_PRINT_BOOL(config, RdpSecurity);
CONFIG_PRINT_SECTION("Server Security");
CONFIG_PRINT_BOOL(config, ServerTlsSecurity);
CONFIG_PRINT_BOOL(config, ServerRdpSecurity);
CONFIG_PRINT_SECTION("Client Security");
CONFIG_PRINT_BOOL(config, ClientNlaSecurity);
CONFIG_PRINT_BOOL(config, ClientTlsSecurity);
CONFIG_PRINT_BOOL(config, ClientRdpSecurity);
CONFIG_PRINT_SECTION("Channels");
CONFIG_PRINT_BOOL(config, GFX);

View File

@ -43,10 +43,14 @@ struct proxy_config
BOOL Keyboard;
BOOL Mouse;
/* security */
BOOL NlaSecurity;
BOOL TlsSecurity;
BOOL RdpSecurity;
/* server security */
BOOL ServerTlsSecurity;
BOOL ServerRdpSecurity;
/* client security */
BOOL ClientNlaSecurity;
BOOL ClientTlsSecurity;
BOOL ClientRdpSecurity;
/* channels */
BOOL GFX;
@ -54,7 +58,7 @@ struct proxy_config
BOOL Clipboard;
BOOL AudioOutput;
/* clipboard specific settings*/
/* clipboard specific settings */
BOOL TextOnly;
UINT32 MaxTextLength;
};

View File

@ -240,9 +240,9 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg)
goto out_free_peer;
}
client->settings->RdpSecurity = config->RdpSecurity;
client->settings->TlsSecurity = config->TlsSecurity;
client->settings->NlaSecurity = config->NlaSecurity;
client->settings->RdpSecurity = config->ServerRdpSecurity;
client->settings->TlsSecurity = config->ServerTlsSecurity;
client->settings->NlaSecurity = FALSE; /* currently NLA is not supported in proxy server */
client->settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
client->settings->ColorDepth = 32;
client->settings->SuppressOutput = TRUE;