server: proxy: pf_context.c: Fix nla crash
authorkubistika <kmizrachi18@gmail.com>
Tue, 13 Aug 2019 12:06:45 +0000 (15:06 +0300)
committerakallabeth <akallabeth@users.noreply.github.com>
Wed, 14 Aug 2019 17:39:34 +0000 (19:39 +0200)
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.

server/proxy/pf_client.c
server/proxy/pf_context.c
server/proxy/pf_context.h

index a83f89e..97b744f 100644 (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;
 }
index bcca78e..1f4a42e 100644 (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)
index 815a740..c57544c 100644 (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);