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)
- {
- WLog_ERR(TAG, "freerdp_connect() failed, trying to connect without NLA");
+ UINT32 last_error = freerdp_get_last_error(instance->context);
+ UINT32 last_error_type = GET_FREERDP_ERROR_TYPE(last_error);
- /* disable NLA, enable TLS */
- settings->NlaSecurity = FALSE;
- settings->RdpSecurity = TRUE;
- settings->TlsSecurity = TRUE;
+ /* Do not retry if last error is not ERRCONNECT_LOGON_FAILURE */
+ if (last_error_type != ERRCONNECT_LOGON_FAILURE)
+ retry_without_nla = FALSE;
- pc->allow_next_conn_failure = FALSE;
- if (!freerdp_connect(instance))
+ if (retry_without_nla)
+ {
+ WLog_ERR(TAG, "failed to connect with NLA. disabling NLA and retyring...");
+
+ 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;
}
/**
return FALSE;
if (!pf_client_connect(instance))
+ {
+ proxy_data_abort_connect(pdata);
return FALSE;
+ }
while (!freerdp_shall_disconnect(instance))
{
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;
}
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);