From fa8424a5da3d9e745541834048a5bbbfd5427a5c Mon Sep 17 00:00:00 2001
From: Martin Szulecki
Date: Wed, 22 Apr 2009 20:17:55 +0200
Subject: Fix receive of plists larger than a packet for lockdown and
 MobileSync

[#35 state:resolved]

Signed-off-by: Matt Colyer <matt@colyer.name>
---
 src/MobileSync.c | 20 ++++++++++++++++----
 src/lockdown.c   | 30 ++++++++++++++++++++----------
 2 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/src/MobileSync.c b/src/MobileSync.c
index b16a51b..25f9473 100644
--- a/src/MobileSync.c
+++ b/src/MobileSync.c
@@ -22,6 +22,7 @@
 #include "MobileSync.h"
 #include <plist/plist.h>
 #include <string.h>
+#include <arpa/inet.h>
 
 
 #define MSYNC_VERSION_INT1 100
@@ -136,16 +137,27 @@ iphone_error_t iphone_msync_recv(iphone_msync_client_t client, plist_t * plist)
 	if (!client || !plist || (plist && *plist))
 		return IPHONE_E_INVALID_ARG;
 	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
-	char *receive;
-	uint32_t datalen = 0, bytes = 0;
+	char *receive = NULL;
+	uint32_t datalen = 0, bytes = 0, received_bytes = 0;
 
 	ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes);
 	datalen = ntohl(datalen);
 
 	receive = (char *) malloc(sizeof(char) * datalen);
-	ret = iphone_mux_recv(client->connection, receive, datalen, &bytes);
 
-	plist_from_bin(receive, bytes, plist);
+	/* fill buffer and request more packets if needed */
+	while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) {
+		ret = iphone_mux_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes);
+		received_bytes += bytes;
+	}
+
+	if (ret != IPHONE_E_SUCCESS) {
+		free(receive);
+		return ret;
+	}
+
+	plist_from_bin(receive, received_bytes, plist);
+	free(receive);
 
 	char *XMLContent = NULL;
 	uint32_t length = 0;
diff --git a/src/lockdown.c b/src/lockdown.c
index e3636d1..64c325e 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -193,8 +193,8 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist)
 	if (!client || !plist || (plist && *plist))
 		return IPHONE_E_INVALID_ARG;
 	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
-	char *receive;
-	uint32_t datalen = 0, bytes = 0;
+	char *receive = NULL;
+	uint32_t datalen = 0, bytes = 0, received_bytes = 0;
 
 	if (!client->in_SSL)
 		ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes);
@@ -206,21 +206,31 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist)
 	datalen = ntohl(datalen);
 
 	receive = (char *) malloc(sizeof(char) * datalen);
-	if (!client->in_SSL)
-		ret = iphone_mux_recv(client->connection, receive, datalen, &bytes);
-	else {
-		bytes = gnutls_record_recv(*client->ssl_session, receive, datalen);
-		if (bytes > 0)
+
+	if (!client->in_SSL) {
+		/* fill buffer and request more packets if needed */
+		while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) {
+			ret = iphone_mux_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes);
+			received_bytes += bytes;
+		}
+	} else {
+		received_bytes = gnutls_record_recv(*client->ssl_session, receive, datalen);
+		if (received_bytes > 0)
 			ret = IPHONE_E_SUCCESS;
 	}
 
-	if (bytes <= 0) {
+	if (ret != IPHONE_E_SUCCESS) {
+		free(receive);
+		return ret;
+	}
+
+	if (received_bytes <= 0) {
 		free(receive);
 		return IPHONE_E_NOT_ENOUGH_DATA;
 	}
 
-	log_dbg_msg(DBGMASK_LOCKDOWND, "Recv msg :\nsize : %i\nbuffer :\n%s\n", bytes, receive);
-	plist_from_xml(receive, bytes, plist);
+	log_dbg_msg(DBGMASK_LOCKDOWND, "Recv msg :\nsize : %i\nbuffer :\n%s\n", received_bytes, receive);
+	plist_from_xml(receive, received_bytes, plist);
 	free(receive);
 
 	if (!*plist)
-- 
cgit v1.1-32-gdbae