Description: fix rdp client gcc read server security data DoS
Origin: backport, https://github.com/FreeRDP/FreeRDP/commit/03ab68318966c3a22935a02838daaea7b7fbe96c
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=869880

Index: freerdp-1.0.2/libfreerdp-core/gcc.c
===================================================================
--- freerdp-1.0.2.orig/libfreerdp-core/gcc.c	2013-01-02 16:46:59.000000000 -0500
+++ freerdp-1.0.2/libfreerdp-core/gcc.c	2017-08-03 08:46:10.907353139 -0400
@@ -785,6 +785,9 @@ boolean gcc_read_server_security_data(ST
 	uint32 serverRandomLen;
 	uint32 serverCertLen;
 
+	if (stream_get_left(s) < 8)
+		return false;
+
 	stream_read_uint32(s, settings->encryption_method); /* encryptionMethod */
 	stream_read_uint32(s, settings->encryption_level); /* encryptionLevel */
 
@@ -797,39 +800,52 @@ boolean gcc_read_server_security_data(ST
 		return true;
 	}
 
+	if (stream_get_left(s) < 8)
+		return false;
+
 	stream_read_uint32(s, serverRandomLen); /* serverRandomLen */
 	stream_read_uint32(s, serverCertLen); /* serverCertLen */
 
-	if (serverRandomLen > 0)
-	{
-		/* serverRandom */
-		freerdp_blob_alloc(settings->server_random, serverRandomLen);
-		stream_read(s, settings->server_random->data, serverRandomLen);
-	}
-	else
-	{
-		return false;
-	}
+	if (serverRandomLen == 0 || serverCertLen == 0)
+ 		return false;
 
-	if (serverCertLen > 0)
-	{
-		/* serverCertificate */
-		freerdp_blob_alloc(settings->server_certificate, serverCertLen);
-		stream_read(s, settings->server_certificate->data, serverCertLen);
-		certificate_free(settings->server_cert);
-		settings->server_cert = certificate_new();
-		data = settings->server_certificate->data;
-		length = settings->server_certificate->length;
+	if (stream_get_left(s) < serverRandomLen)
+ 		return false;
 
-		if (!certificate_read_server_certificate(settings->server_cert, data, length))
-			return false;
-	}
-	else
-	{
+	/* serverRandom */
+	freerdp_blob_alloc(settings->server_random, serverRandomLen);
+	if (!settings->server_random->data)
 		return false;
-	}
+	stream_read(s, settings->server_random->data, serverRandomLen);
+
+	/* serverCertificate */
+	if(stream_get_left(s) < serverCertLen)
+		goto out_fail1;
+	freerdp_blob_alloc(settings->server_certificate, serverCertLen);
+	if (!settings->server_certificate->data)
+		goto out_fail1;
+
+	stream_read(s, settings->server_certificate->data, serverCertLen);
+	certificate_free(settings->server_cert);
+	settings->server_cert = certificate_new();
+	if (!settings->server_cert)
+		goto out_fail2;
+
+	data = settings->server_certificate->data;
+	length = settings->server_certificate->length;
+
+	if (!certificate_read_server_certificate(settings->server_cert, data, length))
+		goto out_fail2;
 
 	return true;
+
+	out_fail2:
+		freerdp_blob_free(settings->server_certificate);
+		settings->server_certificate->data = NULL;
+	out_fail1:
+		freerdp_blob_free(settings->server_random);
+		settings->server_random->data = NULL;
+		return false;
 }
 
 static const uint8 initial_signature[] =
