server/shadow: Fix regression with rdp8.0
authorzihao.jiang <zihao.jiang@yahoo.com>
Sat, 27 Aug 2016 13:51:29 +0000 (21:51 +0800)
committerzihao.jiang <zihao.jiang@yahoo.com>
Sun, 28 Aug 2016 18:50:09 +0000 (02:50 +0800)
Shadow server crash with rdp8.0 with gfx enabled.
Root Cause: rdp8.0 is not support in shadow gfx and rdpgfx_caps_advertise returns an error. However setChannelError crashs because context->errorDescription is NULL
1. Fix shadow gfx to handle rdp8.0
2. Initialize context->errorDescription for server side new-context

libfreerdp/core/peer.c
server/shadow/shadow_rdpgfx.c

index 6462d46..482f855 100644 (file)
@@ -716,6 +716,12 @@ BOOL freerdp_peer_context_new(freerdp_peer* client)
        update_register_server_callbacks(client->update);
        autodetect_register_server_callbacks(client->autodetect);
 
+       if (!(context->errorDescription = calloc(1, 500)))
+       {
+               WLog_ERR(TAG, "calloc failed!");
+               goto fail_error_description;
+       }
+
        if (!transport_attach(rdp->transport, client->sockfd))
                goto fail_transport_attach;
 
@@ -734,6 +740,8 @@ BOOL freerdp_peer_context_new(freerdp_peer* client)
        WLog_ERR(TAG, "ContextNew callback failed");
 
 fail_transport_attach:
+       free(context->errorDescription);
+fail_error_description:
        rdp_free(client->context->rdp);
 fail_rdp:
        metrics_free(context->metrics);
@@ -750,7 +758,20 @@ void freerdp_peer_context_free(freerdp_peer* client)
 {
        IFCALL(client->ContextFree, client, client->context);
 
-       metrics_free(client->context->metrics);
+       if (client->context)
+       {
+               free(client->context->errorDescription);
+               client->context->errorDescription = NULL;
+
+               rdp_free(client->context->rdp);
+               client->context->rdp = NULL;
+
+               metrics_free(client->context->metrics);
+               client->context->metrics = NULL;
+
+               free(client->context);
+               client->context = NULL;
+       }
 }
 
 freerdp_peer* freerdp_peer_new(int sockfd)
@@ -798,10 +819,5 @@ void freerdp_peer_free(freerdp_peer* client)
        if (!client)
                return;
 
-       if (client->context)
-       {
-               rdp_free(client->context->rdp);
-               free(client->context);
-       }
        free(client);
 }
index a8ad115..cdf3f39 100644 (file)
@@ -53,7 +53,10 @@ static UINT rdpgfx_caps_advertise(RdpgfxServerContext* context, RDPGFX_CAPS_ADVE
 
                        return context->CapsConfirm(context, &pdu);
                }
-        else if (pdu.capsSet->version == RDPGFX_CAPVERSION_81)
+       }
+       for (index = 0; index < capsAdvertise->capsSetCount; index++)
+       {
+               if (pdu.capsSet->version == RDPGFX_CAPVERSION_81)
                {
                        if (settings)
                        {
@@ -66,6 +69,20 @@ static UINT rdpgfx_caps_advertise(RdpgfxServerContext* context, RDPGFX_CAPS_ADVE
                        return context->CapsConfirm(context, &pdu);
                }
        }
+       for (index = 0; index < capsAdvertise->capsSetCount; index++)
+       {
+               if (pdu.capsSet->version == RDPGFX_CAPVERSION_8)
+               {
+                       if (settings)
+                       {
+                               flags = pdu.capsSet->flags;
+                               settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_THINCLIENT);
+                               settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
+                       }
+
+                       return context->CapsConfirm(context, &pdu);
+               }
+       }
 
        return CHANNEL_RC_UNSUPPORTED_VERSION;
 }