From b9ecd70c30ac1fd7024cadfcda9c7be1d1f7f44f Mon Sep 17 00:00:00 2001
From: Nikias Bassen
Date: Mon, 7 Dec 2009 18:58:55 +0100
Subject: cache device uuid in client struct

When accessing/storing key info with userprefs, a device uuid is
required that makes it possible to distinguish between different
devices. On execution of lockdownd_client_new, the uuid is queried
via lockdown and now stored in the client struct for later reuse.
This patch also removes the uuid parameter from lockdownd_pair().
---
 include/libiphone/lockdown.h |  2 +-
 src/lockdown.c               | 51 ++++++++++++++++++++++----------------------
 src/lockdown.h               |  1 +
 3 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/include/libiphone/lockdown.h b/include/libiphone/lockdown.h
index daa5800..e6b75da 100644
--- a/include/libiphone/lockdown.h
+++ b/include/libiphone/lockdown.h
@@ -63,7 +63,7 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char
 lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client);
 lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist);
 lockdownd_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist);
-lockdownd_error_t lockdownd_pair(lockdownd_client_t client, char *uuid, char *host_id);
+lockdownd_error_t lockdownd_pair(lockdownd_client_t client, char *host_id);
 lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t control, char **uuid);
 lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name);
 lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client);
diff --git a/src/lockdown.c b/src/lockdown.c
index 02b0024..b6289ed 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -220,6 +220,9 @@ lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
 	if (client->session_id) {
 		free(client->session_id);
 	}
+	if (client->uuid) {
+		free(client->uuid);
+	}
 
 	free(client);
 	return ret;
@@ -655,31 +658,26 @@ lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_
 	client_loc->ssl_certificate = NULL;
 	client_loc->in_SSL = 0;
 	client_loc->session_id = NULL;
+	client_loc->uuid = NULL;
 
 	if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc)) {
 		log_debug_msg("%s: QueryType failed in the lockdownd client.\n", __func__);
 		ret = LOCKDOWN_E_NOT_ENOUGH_DATA;
 	}
 
-	char *uuid = NULL;
-	ret = iphone_device_get_uuid(device, &uuid);
+	ret = iphone_device_get_uuid(device, &client_loc->uuid);
 	if (LOCKDOWN_E_SUCCESS != ret) {
 		log_debug_msg("%s: failed to get device uuid.\n", __func__);
 	}
-	log_debug_msg("%s: device uuid: %s\n", __func__, uuid);
+	log_debug_msg("%s: device uuid: %s\n", __func__, client_loc->uuid);
 
 	userpref_get_host_id(&host_id);
 	if (LOCKDOWN_E_SUCCESS == ret && !host_id) {
 		ret = LOCKDOWN_E_INVALID_CONF;
 	}
 
-	if (LOCKDOWN_E_SUCCESS == ret && !userpref_has_device_public_key(uuid))
-		ret = lockdownd_pair(client_loc, uuid, host_id);
-
-	if (uuid) {
-		free(uuid);
-		uuid = NULL;
-	}
+	if (LOCKDOWN_E_SUCCESS == ret && !userpref_has_device_public_key(client_loc->uuid))
+		ret = lockdownd_pair(client_loc, host_id);
 
 	if (LOCKDOWN_E_SUCCESS == ret) {
 		ret = lockdownd_start_ssl_session(client_loc, host_id);
@@ -703,9 +701,14 @@ lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_
 /** Generates the appropriate keys and pairs the device. It's part of the
  *  lockdownd handshake.
  *
+ * @param client The lockdown client to pair with.
+ * @param host_id The HostID to use for pairing. If NULL is passed, then
+ *    the HostID of the current machine is used. A new HostID will be
+ *    generated automatically when pairing is done for the first time.
+ *
  * @return an error code (LOCKDOWN_E_SUCCESS on success)
  */
-lockdownd_error_t lockdownd_pair(lockdownd_client_t client, char *uuid, char *host_id)
+lockdownd_error_t lockdownd_pair(lockdownd_client_t client, char *host_id)
 {
 	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
 	plist_t dict = NULL;
@@ -764,7 +767,7 @@ lockdownd_error_t lockdownd_pair(lockdownd_client_t client, char *uuid, char *ho
 	/* store public key in config if pairing succeeded */
 	if (ret == LOCKDOWN_E_SUCCESS) {
 		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pair success\n", __func__);
-		userpref_set_device_public_key(uuid, public_key);
+		userpref_set_device_public_key(client->uuid, public_key);
 	} else {
 		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pair failure\n", __func__);
 	}
@@ -1027,26 +1030,22 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c
 
 			if (!strcmp(error, "InvalidHostID")) {
 				/* hostid is unknown. Pair and try again */
-				char *uuid = NULL;
 				char *host_id = NULL;
 				userpref_get_host_id(&host_id);
 
-				if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_uuid(client, &uuid) ) {
-					if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, uuid, host_id) ) {
-						/* start session again */
-						plist_free(dict);
-						dict = plist_new_dict();
-						plist_dict_insert_item(dict,"HostID", plist_new_string(HostID));
-						plist_dict_insert_item(dict,"Request", plist_new_string("StartSession"));
+				if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, host_id) ) {
+					/* start session again */
+					plist_free(dict);
+					dict = plist_new_dict();
+					plist_dict_insert_item(dict,"HostID", plist_new_string(HostID));
+					plist_dict_insert_item(dict,"Request", plist_new_string("StartSession"));
 
-						ret = lockdownd_send(client, dict);
-						plist_free(dict);
-						dict = NULL;
+					ret = lockdownd_send(client, dict);
+					plist_free(dict);
+					dict = NULL;
 
-						ret = lockdownd_recv(client, &dict);
-					}
+					ret = lockdownd_recv(client, &dict);
 				}
-				free(uuid);
 				free(host_id);
 			}
 			free(error);
diff --git a/src/lockdown.h b/src/lockdown.h
index 49b467f..931623a 100644
--- a/src/lockdown.h
+++ b/src/lockdown.h
@@ -33,6 +33,7 @@ struct lockdownd_client_int {
 	gnutls_certificate_credentials_t ssl_certificate;
 	int in_SSL;
 	char *session_id;
+	char *uuid;
 };
 
 lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnutls_datum_t * public_key);
-- 
cgit v1.1-32-gdbae