server: proxy: pf_context.c: Fix nla crash

Because the proxy uses freerdp_settings_copy to do re-negotiation after
first connection to remote server, all redirection information
(RedirectionPassword, RedirectionDomain, etc.) pointers were duplicated
(to both client and server settings structs). Then, at disconnection, a
double-free occured.
This commit is contained in:
kubistika 2019-08-13 15:06:45 +03:00 committed by akallabeth
parent 749c88ab0d
commit ef306fbff6
3 changed files with 18 additions and 11 deletions

View File

@ -100,8 +100,12 @@ static BOOL pf_client_pre_connect(freerdp* instance)
* GlyphCacheSupport must be explicitly set to GLYPH_SUPPORT_NONE.
*/
settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE;
/* proxy client should always try to connect with NLA */
settings->NlaSecurity = TRUE;
settings->OsMajorType = OSMAJORTYPE_UNIX;
settings->OsMinorType = OSMINORTYPE_NATIVE_XSERVER;
/**
* settings->OrderSupport is initialized at this point.
* Only override it if you plan to implement custom order
@ -336,14 +340,12 @@ static BOOL pf_client_global_init(void)
static int pf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
{
pClientContext* pc;
const char* str_data = freerdp_get_logon_error_info_data(data);
const char* str_type = freerdp_get_logon_error_info_type(type);
if (!instance || !instance->context)
return -1;
pc = (pClientContext*) instance->context;
WLog_INFO(TAG, "Logon Error Info %s [%s]", str_data, str_type);
return 1;
}

View File

@ -63,16 +63,21 @@ BOOL init_p_server_context(freerdp_peer* client)
return freerdp_peer_context_new(client);
}
void pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src, BOOL is_server)
/*
* pf_context_copy_settings copies settings from `src` to `dst`.
* when using this function, is_dst_server must be set to TRUE if the destination
* settings are server's settings. otherwise, they must be set to FALSE.
*/
BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src, BOOL is_dst_server)
{
rdpSettings* before_copy = freerdp_settings_clone(dst);
if (!before_copy)
return;
return FALSE;
if (!freerdp_settings_copy(dst, src))
{
freerdp_settings_free(before_copy);
return;
return FALSE;
}
free(dst->ConfigPath);
@ -83,10 +88,11 @@ void pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src, BOOL is_
free(dst->CertificateFile);
free(dst->CertificateName);
free(dst->CertificateContent);
free(dst->ClientRandom);
/* adjust pointer to instance pointer */
dst->ServerMode = is_server;
dst->ServerMode = is_dst_server;
/* revert some values that must not be changed */
dst->ConfigPath = _strdup(before_copy->ConfigPath);
dst->PrivateKeyContent = _strdup(before_copy->PrivateKeyContent);
dst->RdpKeyContent = _strdup(before_copy->RdpKeyContent);
@ -95,10 +101,8 @@ void pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src, BOOL is_
dst->CertificateFile = _strdup(before_copy->CertificateFile);
dst->CertificateName = _strdup(before_copy->CertificateName);
dst->CertificateContent = _strdup(before_copy->CertificateContent);
dst->ClientRandomLength = before_copy->ClientRandomLength;
CopyMemory(dst->ClientRandom, before_copy->ClientRandom, before_copy->ClientRandomLength);
if (is_server)
if (is_dst_server)
{
free(dst->ServerCertificate);
dst->ServerCertificateLength = before_copy->ServerCertificateLength;
@ -113,6 +117,7 @@ void pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src, BOOL is_
}
freerdp_settings_free(before_copy);
return TRUE;
}
rdpContext* p_client_context_create(rdpSettings* clientSettings)

View File

@ -102,7 +102,7 @@ rdpContext* p_client_context_create(rdpSettings* clientSettings);
proxyData* proxy_data_new();
BOOL proxy_data_set_connection_info(proxyData* pdata, rdpSettings* ps, rdpSettings* pc);
void proxy_data_free(proxyData* pdata);
void pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src, BOOL is_server);
BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src, BOOL is_dst_server);
void proxy_data_abort_connect(proxyData* pdata);
BOOL proxy_data_shall_disconnect(proxyData* pdata);