diff options
| -rw-r--r-- | dev/afccheck.c | 2 | ||||
| -rw-r--r-- | dev/iphoneclient.c | 2 | ||||
| -rw-r--r-- | dev/iphoneenterrecovery.c | 2 | ||||
| -rw-r--r-- | dev/lckdclient.c | 2 | ||||
| -rwxr-xr-x | dev/msync.py | 26 | ||||
| -rw-r--r-- | dev/msyncclient.c | 2 | ||||
| -rw-r--r-- | include/libiphone/lockdown.h | 8 | ||||
| -rw-r--r-- | include/libiphone/notification_proxy.h | 29 | ||||
| -rw-r--r-- | src/NotificationProxy.c | 20 | ||||
| -rw-r--r-- | src/NotificationProxy.h | 14 | ||||
| -rw-r--r-- | src/lockdown.c | 191 | ||||
| -rw-r--r-- | src/lockdown.h | 3 | ||||
| -rw-r--r-- | src/userpref.c | 24 | ||||
| -rw-r--r-- | src/userpref.h | 1 | ||||
| -rw-r--r-- | swig/iphone.i | 2 | ||||
| -rw-r--r-- | tools/iphone_id.c | 2 | ||||
| -rw-r--r-- | tools/iphoneinfo.c | 5 | ||||
| -rw-r--r-- | tools/iphonesyslog.c | 2 | 
18 files changed, 257 insertions, 80 deletions
| diff --git a/dev/afccheck.c b/dev/afccheck.c index 88935a0..00c0f52 100644 --- a/dev/afccheck.c +++ b/dev/afccheck.c @@ -109,7 +109,7 @@ int main(int argc, char *argv[])  		return 1;  	} -	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "afccheck")) {  		iphone_device_free(phone);  		return 1;  	} diff --git a/dev/iphoneclient.c b/dev/iphoneclient.c index d62d23f..685f6ef 100644 --- a/dev/iphoneclient.c +++ b/dev/iphoneclient.c @@ -87,7 +87,7 @@ int main(int argc, char *argv[])  	if (uuid)  		free(uuid); -	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphoneclient")) {  		iphone_device_free(phone);  		printf("Exiting.\n");  		return -1; diff --git a/dev/iphoneenterrecovery.c b/dev/iphoneenterrecovery.c index 1d4d332..126941c 100644 --- a/dev/iphoneenterrecovery.c +++ b/dev/iphoneenterrecovery.c @@ -74,7 +74,7 @@ int main(int argc, char *argv[])  		return -1;  	} -	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphoneenterrecovery")) {  		iphone_device_free(phone);  		return -1;  	} diff --git a/dev/lckdclient.c b/dev/lckdclient.c index d866435..c8d717c 100644 --- a/dev/lckdclient.c +++ b/dev/lckdclient.c @@ -48,7 +48,7 @@ int main(int argc, char *argv[])  	if (uuid)  		free(uuid); -	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "lckdclient")) {  		iphone_device_free(phone);  		return -1;  	} diff --git a/dev/msync.py b/dev/msync.py index fe7f1fd..6bb85d7 100755 --- a/dev/msync.py +++ b/dev/msync.py @@ -1,6 +1,7 @@  #! /usr/bin/env python -from libiphone.iPhone import * +from iphone import * +from plist import *  # get msync client  def GetMobileSyncClient() : @@ -24,17 +25,18 @@ msync = GetMobileSyncClient()  if not msync :      exit(1) -array = PListNode(PLIST_ARRAY) -array.add_sub_string("SDMessageSyncDataClassWithDevice") -array.add_sub_string("com.apple.Contacts"); -array.add_sub_string("---"); -array.add_sub_string("2009-01-13 22:25:58 +0100"); -array.add_sub_uint(106); -array.add_sub_string("___EmptyParameterString___"); - -msync.send(array) -array = msync.receive() -print array.to_xml() +a = Array() +a.append( String("SDMessageSyncDataClassWithDevice") ) +a.append( String("") ) +a.append( String("com.apple.Contacts") ) +a.append( String("---") ) +a.append( String("2009-01-13 22:25:58 +0100") ) +a.append( Integer(106) ) +a.append( String("___EmptyParameterString___") ) + +msync.send(a) +a = msync.receive() +print a.to_xml() diff --git a/dev/msyncclient.c b/dev/msyncclient.c index 53018ac..dfe2a2b 100644 --- a/dev/msyncclient.c +++ b/dev/msyncclient.c @@ -153,7 +153,7 @@ int main(int argc, char *argv[])  		return -1;  	} -	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "msyncclient")) {  		iphone_device_free(phone);  		return -1;  	} diff --git a/include/libiphone/lockdown.h b/include/libiphone/lockdown.h index 31ffeab..459fbbd 100644 --- a/include/libiphone/lockdown.h +++ b/include/libiphone/lockdown.h @@ -44,6 +44,8 @@ extern "C" {  #define LOCKDOWN_E_GET_VALUE_PROHIBITED     -10  #define LOCKDOWN_E_REMOVE_VALUE_PROHIBITED  -11  #define LOCKDOWN_E_MUX_ERROR                -12 +#define LOCKDOWN_E_ACTIVATION_FAILED        -13 +#define LOCKDOWN_E_PASSWORD_PROTECTED       -14  #define LOCKDOWN_E_UNKNOWN_ERROR           -256 @@ -53,8 +55,9 @@ struct lockdownd_client_int;  typedef struct lockdownd_client_int *lockdownd_client_t;  /* Interface */ -lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client); +lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client, const char *label);  lockdownd_error_t lockdownd_client_free(lockdownd_client_t client); +void lockdownd_client_set_label(lockdownd_client_t client, const char *label);  lockdownd_error_t lockdownd_query_type(lockdownd_client_t client);  lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value);  lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value); @@ -65,6 +68,9 @@ 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 *host_id);  lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, char *host_id); +lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, char *host_id); +lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record); +lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client);  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/include/libiphone/notification_proxy.h b/include/libiphone/notification_proxy.h index 96af5fd..4c02f55 100644 --- a/include/libiphone/notification_proxy.h +++ b/include/libiphone/notification_proxy.h @@ -45,16 +45,25 @@ typedef int16_t np_error_t;  #define NP_SYNC_DID_FINISH      "com.apple.itunes-mobdev.syncDidFinish"  /* Notification IDs for use with observe_notification (device --> client) */ -#define NP_SYNC_CANCEL_REQUEST  "com.apple.itunes-client.syncCancelRequest" -#define NP_SYNC_SUSPEND_REQUEST "com.apple.itunes-client.syncSuspendRequest" -#define NP_SYNC_RESUME_REQUEST  "com.apple.itunes-client.syncResumeRequest" -#define NP_PHONE_NUMBER_CHANGED "com.apple.mobile.lockdown.phone_number_changed" -#define NP_DEVICE_NAME_CHANGED  "com.apple.mobile.lockdown.device_name_changed" -#define NP_ATTEMPTACTIVATION    "com.apple.springboard.attemptactivation" -#define NP_DS_DOMAIN_CHANGED    "com.apple.mobile.data_sync.domain_changed" -#define NP_APP_INSTALLED        "com.apple.mobile.application_installed" -#define NP_APP_UNINSTALLED      "com.apple.mobile.application_uninstalled" -#define NP_ITDBPREP_DID_END     "com.apple.itdbprep.notification.didEnd" +#define NP_SYNC_CANCEL_REQUEST       "com.apple.itunes-client.syncCancelRequest" +#define NP_SYNC_SUSPEND_REQUEST      "com.apple.itunes-client.syncSuspendRequest" +#define NP_SYNC_RESUME_REQUEST       "com.apple.itunes-client.syncResumeRequest" +#define NP_PHONE_NUMBER_CHANGED      "com.apple.mobile.lockdown.phone_number_changed" +#define NP_DEVICE_NAME_CHANGED       "com.apple.mobile.lockdown.device_name_changed" +#define NP_TRUSTED_HOST_ATTACHED     "com.apple.mobile.lockdown.trusted_host_attached" +#define NP_HOST_DETACHED             "com.apple.mobile.lockdown.host_detached" +#define NP_HOST_ATTACHED             "com.apple.mobile.lockdown.host_attached" +#define NP_REGISTRATION_FAILED       "com.apple.mobile.lockdown.registration_failed" +#define NP_ACTIVATION_STATE          "com.apple.mobile.lockdown.activation_state" +#define NP_BRICK_STATE               "com.apple.mobile.lockdown.brick_state" +#define NP_ATTEMPTACTIVATION         "com.apple.springboard.attemptactivation" +#define NP_DS_DOMAIN_CHANGED         "com.apple.mobile.data_sync.domain_changed" +#define NP_APP_INSTALLED             "com.apple.mobile.application_installed" +#define NP_APP_UNINSTALLED           "com.apple.mobile.application_uninstalled" +#define NP_ITDBPREP_DID_END          "com.apple.itdbprep.notification.didEnd" +#define NP_LANGUAGE_CHANGED          "com.apple.language.changed" +#define NP_DEV_IMAGE_MOUNTED         "com.apple.mobile.developer_image_mounted" +#define NP_ADDRESS_BOOK_PREF_CHANGED "com.apple.AddressBook.PreferenceChanged"  struct np_client_int;  typedef struct np_client_int *np_client_t; diff --git a/src/NotificationProxy.c b/src/NotificationProxy.c index e2c1faa..b73b521 100644 --- a/src/NotificationProxy.c +++ b/src/NotificationProxy.c @@ -144,10 +144,6 @@ np_error_t np_client_free(np_client_t client)  /** Sends a notification to the device's Notification Proxy.   * - * notification messages seen so far: - *   com.apple.itunes-mobdev.syncWillStart - *   com.apple.itunes-mobdev.syncDidStart - *   * @param client The client to send to   * @param notification The notification message to send   * @@ -212,22 +208,10 @@ np_error_t np_observe_notification( np_client_t client, const char *notification  /** Notifies the iphone to send a notification on specified events.   * - * observation messages seen so far: - *   com.apple.itunes-client.syncCancelRequest - *   com.apple.itunes-client.syncSuspendRequest - *   com.apple.itunes-client.syncResumeRequest - *   com.apple.mobile.lockdown.phone_number_changed - *   com.apple.mobile.lockdown.device_name_changed - *   com.apple.springboard.attemptactivation - *   com.apple.mobile.data_sync.domain_changed - *   com.apple.mobile.application_installed - *   com.apple.mobile.application_uninstalled - *   * @param client The client to send to   * @param notification_spec Specification of the notifications that should be   *  observed. This is expected to be an array of const char* that MUST have a - *  terminating NULL entry. However this parameter can be NULL; in this case, - *  the default set of notifications will be used. + *  terminating NULL entry.   *   * @return NP_E_SUCCESS on success, NP_E_INVALID_ARG when client is null,   *   or an error returned by np_observe_notification. @@ -243,7 +227,7 @@ np_error_t np_observe_notifications(np_client_t client, const char **notificatio  	}  	if (!notifications) { -		notifications = np_default_notifications; +		return NP_E_INVALID_ARG;  	}  	while (notifications[i]) { diff --git a/src/NotificationProxy.h b/src/NotificationProxy.h index 84f1f89..ea993c5 100644 --- a/src/NotificationProxy.h +++ b/src/NotificationProxy.h @@ -31,20 +31,6 @@ struct np_client_int {  	GThread *notifier;  }; -static const char *np_default_notifications[11] = { -	NP_SYNC_SUSPEND_REQUEST, -	NP_SYNC_RESUME_REQUEST, -	NP_PHONE_NUMBER_CHANGED, -	NP_SYNC_CANCEL_REQUEST, -	NP_DEVICE_NAME_CHANGED, -	NP_ATTEMPTACTIVATION, -	NP_DS_DOMAIN_CHANGED, -	NP_APP_INSTALLED, -	NP_APP_UNINSTALLED, -	NP_ITDBPREP_DID_END, -	NULL -}; -  gpointer np_notifier(gpointer arg);  #endif diff --git a/src/lockdown.c b/src/lockdown.c index 2532999..24dd4a1 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -108,6 +108,21 @@ static int lockdown_check_result(plist_t dict, const char *query_match)  }  /** + * Adds a label key with the passed value to a plist dict node. + * + * @param plist The plist to add the key to + * @param label The value for the label key + * + */ +static void plist_dict_add_label(plist_t plist, const char *label) +{ +	if (plist && label) { +		if (plist_get_node_type(plist) == PLIST_DICT) +			plist_dict_insert_item(plist, "Label", plist_new_string(label)); +	} +} + +/**   * Closes the lockdownd communication session, by sending   * the StopSession Request to the device.   * @@ -128,6 +143,7 @@ lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client)  	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;  	plist_t dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label);  	plist_dict_insert_item(dict,"Request", plist_new_string("StopSession"));  	plist_dict_insert_item(dict,"SessionID", plist_new_string(client->session_id)); @@ -223,11 +239,27 @@ lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)  	if (client->uuid) {  		free(client->uuid);  	} +	if (client->label) { +		free(client->label); +	}  	free(client);  	return ret;  } +/** + * Sets the label to send for requests to lockdownd. + * + * @param client The lockdown client + * @param label The label to set or NULL to disable + * + */ +void lockdownd_client_set_label(lockdownd_client_t client, const char *label) +{ +	if (client) +		client->label = strdup(label); +} +  /** Polls the iPhone for lockdownd data.   *   * @param control The lockdownd client @@ -306,6 +338,7 @@ lockdownd_error_t lockdownd_query_type(lockdownd_client_t client)  	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;  	plist_t dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label);  	plist_dict_insert_item(dict,"Request", plist_new_string("QueryType"));  	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); @@ -349,6 +382,7 @@ lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *dom  	/* setup request plist */  	dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label);  	if (domain) {  		plist_dict_insert_item(dict,"Domain", plist_new_string(domain));  	} @@ -410,6 +444,7 @@ lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *dom  	/* setup request plist */  	dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label);  	if (domain) {  		plist_dict_insert_item(dict,"Domain", plist_new_string(domain));  	} @@ -467,6 +502,7 @@ lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *  	/* setup request plist */  	dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label);  	if (domain) {  		plist_dict_insert_item(dict,"Domain", plist_new_string(domain));  	} @@ -576,10 +612,11 @@ lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **de   *   * @param phone The iPhone to create a lockdownd client for   * @param client The pointer to the location of the new lockdownd_client + * @param label The label to use for communication. Usually the program name   *   * @return an error code (LOCKDOWN_E_SUCCESS on success)   */ -lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client) +lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client, const char *label)  {  	if (!client)  		return LOCKDOWN_E_INVALID_ARG; @@ -599,6 +636,7 @@ lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_  	client_loc->in_SSL = 0;  	client_loc->session_id = NULL;  	client_loc->uuid = NULL; +	client_loc->label = strdup(label);  	if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc)) {  		log_debug_msg("%s: QueryType failed in the lockdownd client.\n", __func__); @@ -681,6 +719,7 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, char *host  	/* Setup Pair request plist */  	dict = plist_new_dict();  	dict_record = plist_new_dict(); +	plist_dict_add_label(dict, client->label);  	plist_dict_insert_item(dict,"PairRecord", dict_record);  	plist_dict_insert_item(dict_record, "DeviceCertificate", plist_new_data((const char*)device_cert.data, device_cert.size)); @@ -711,16 +750,36 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, char *host  	if (lockdown_check_result(dict, verb) != RESULT_SUCCESS) {  		ret = LOCKDOWN_E_PAIRING_FAILED;  	} -	plist_free(dict); -	dict = NULL; -	/* store public key in config if pairing succeeded */ +	/* if pairing succeeded */  	if (ret == LOCKDOWN_E_SUCCESS) {  		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s success\n", __func__, verb); -		userpref_set_device_public_key(client->uuid, public_key); +		if (!strcmp("Unpair", verb)) { +			/* remove public key from config */ +			userpref_remove_device_public_key(client->uuid); +		} else { +			/* store public key in config */ +			userpref_set_device_public_key(client->uuid, public_key); +		}  	} else {  		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s failure\n", __func__, verb); +		plist_t error_node = NULL; +		/* verify error condition */ +		error_node = plist_dict_get_item(dict, "Error"); +		if (error_node) { +			char *value = NULL; +			plist_get_string_val(error_node, &value); +			/* the first pairing fails if the device is password protected */ +			if (value && !strcmp(value, "PasswordProtected")) { +				ret = LOCKDOWN_E_PASSWORD_PROTECTED; +				free(value); +			} +			plist_free(error_node); +			error_node = NULL; +		}  	} +	plist_free(dict); +	dict = NULL;  	free(public_key.data);  	return ret;  } @@ -758,6 +817,21 @@ lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, char *host_  	return lockdownd_do_pair(client, host_id, "ValidatePair");  } +/**  + * Unpairs the device with the given HostID and removes the pairing records + * from the device and host. + * + * @param client The lockdown client to pair with. + * @param host_id The HostID to use for unpairing. If NULL is passed, then + *    the HostID of the current machine is used. + * + * @return an error code (LOCKDOWN_E_SUCCESS on success) + */ +lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, char *host_id) +{ +	return lockdownd_do_pair(client, host_id, "Unpair"); +} +  /**   * Tells the device to immediately enter recovery mode.   * @@ -773,6 +847,7 @@ lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client)  	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;  	plist_t dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label);  	plist_dict_insert_item(dict,"Request", plist_new_string("EnterRecovery"));  	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: telling device to enter recovery mode\n", __func__); @@ -808,6 +883,7 @@ lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client)  	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;  	plist_t dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label);  	plist_dict_insert_item(dict,"Request", plist_new_string("Goodbye"));  	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); @@ -977,7 +1053,7 @@ lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datu   *   * @return an error code (LOCKDOWN_E_SUCCESS on success)   */ -lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *HostID) +lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *host_id)  {  	plist_t dict = NULL;  	uint32_t return_me = 0; @@ -990,7 +1066,8 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c  	/* Setup DevicePublicKey request plist */  	dict = plist_new_dict(); -	plist_dict_insert_item(dict,"HostID", plist_new_string(HostID)); +	plist_dict_add_label(dict, client->label); +	plist_dict_insert_item(dict,"HostID", plist_new_string(host_id));  	plist_dict_insert_item(dict,"Request", plist_new_string("StartSession"));  	ret = lockdownd_send(client, dict); @@ -1013,14 +1090,15 @@ 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 *host_id = NULL; -				userpref_get_host_id(&host_id); +				char *host_id_new = NULL; +				userpref_get_host_id(&host_id_new); -				if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, host_id) ) { +				if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, host_id_new) ) {  					/* start session again */  					plist_free(dict);  					dict = plist_new_dict(); -					plist_dict_insert_item(dict,"HostID", plist_new_string(HostID)); +					plist_dict_add_label(dict, client->label); +					plist_dict_insert_item(dict,"HostID", plist_new_string(host_id_new));  					plist_dict_insert_item(dict,"Request", plist_new_string("StartSession"));  					ret = lockdownd_send(client, dict); @@ -1029,7 +1107,7 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c  					ret = lockdownd_recv(client, &dict);  				} -				free(host_id); +				free(host_id_new);  			}  			free(error);  		} @@ -1217,6 +1295,7 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char  	host_id = NULL;  	dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label);  	plist_dict_insert_item(dict,"Request", plist_new_string("StartService"));  	plist_dict_insert_item(dict,"Service", plist_new_string(service)); @@ -1260,3 +1339,91 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char  	return ret;  } +/** + * Activates the device. Only works within an open session. + * The ActivationRecord plist dictionary must be obtained using the + * activation protocol requesting from Apple's https webservice. + * + * @see http://iphone-docs.org/doku.php?id=docs:protocols:activation + * + * @param control The lockdown client + * @param activation_record The activation record plist dictionary + * + * @return an error code (LOCKDOWN_E_SUCCESS on success) + */ +lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record)  +{ +	if (!client) +		return LOCKDOWN_E_INVALID_ARG; + +	if (!activation_record) +		return LOCKDOWN_E_INVALID_ARG; + +	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; + +	plist_t dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label); +	plist_dict_insert_item(dict,"Request", plist_new_string("Activate")); +	plist_dict_insert_item(dict,"ActivationRecord", activation_record); + +	ret = lockdownd_send(client, dict); +	plist_free(dict); +	dict = NULL; + +	ret = lockdownd_recv(client, &dict); +	if (!dict) { +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: LOCKDOWN_E_PLIST_ERROR\n", __func__); +		return LOCKDOWN_E_PLIST_ERROR; +	} + +	ret = LOCKDOWN_E_ACTIVATION_FAILED; +	if (lockdown_check_result(dict, "Activate") == RESULT_SUCCESS) { +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); +		ret = LOCKDOWN_E_SUCCESS; +	} +	plist_free(dict); +	dict = NULL; + +	return ret; +} + +/** + * Deactivates the device, returning it to the locked + * “Activate with iTunes” screen. + * + * @param control The lockdown client + * + * @return an error code (LOCKDOWN_E_SUCCESS on success) + */ +lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client) +{ +	if (!client) +		return LOCKDOWN_E_INVALID_ARG; + +	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; + +	plist_t dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label); +	plist_dict_insert_item(dict,"Request", plist_new_string("Deactivate")); + +	ret = lockdownd_send(client, dict); +	plist_free(dict); +	dict = NULL; + +	ret = lockdownd_recv(client, &dict); +	if (!dict) { +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: LOCKDOWN_E_PLIST_ERROR\n", __func__); +		return LOCKDOWN_E_PLIST_ERROR; +	} + +	ret = LOCKDOWN_E_UNKNOWN_ERROR; +	if (lockdown_check_result(dict, "Deactivate") == RESULT_SUCCESS) { +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); +		ret = LOCKDOWN_E_SUCCESS; +	} +	plist_free(dict); +	dict = NULL; + +	return ret; +} + diff --git a/src/lockdown.h b/src/lockdown.h index 931623a..6e1b843 100644 --- a/src/lockdown.h +++ b/src/lockdown.h @@ -34,6 +34,7 @@ struct lockdownd_client_int {  	int in_SSL;  	char *session_id;  	char *uuid; +	char *label;  };  lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnutls_datum_t * public_key); @@ -41,7 +42,7 @@ lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datu  									   gnutls_datum_t * host_cert, gnutls_datum_t * root_cert);  /* SSL functions */ -lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *HostID); +lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *host_id);  ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length);  ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length); diff --git a/src/userpref.c b/src/userpref.c index 10c14a0..09ec495 100644 --- a/src/userpref.c +++ b/src/userpref.c @@ -212,6 +212,30 @@ userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t  	return USERPREF_E_SUCCESS;  } +/** Remove the public key stored for the device with uuid from this host. + * + * @param uuid The uuid of the device + * + * @return USERPREF_E_SUCCESS on success. + */ +userpref_error_t userpref_remove_device_public_key(const char *uuid) +{ +	if (!userpref_has_device_public_key(uuid)) +		return USERPREF_E_SUCCESS; + +	/* build file path */ +	gchar *device_file = g_strconcat(uuid, ".pem", NULL); +	gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); + +	/* remove file */ +	g_remove(pem); + +	g_free(pem); +	g_free(device_file); + +	return USERPREF_E_SUCCESS; +} +  /** Private function which reads the given file into a gnutls structure.   *   * @param file The filename of the file to read diff --git a/src/userpref.h b/src/userpref.h index 3540468..48b8969 100644 --- a/src/userpref.h +++ b/src/userpref.h @@ -38,6 +38,7 @@ G_GNUC_INTERNAL userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey  G_GNUC_INTERNAL userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert);  G_GNUC_INTERNAL userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert);  G_GNUC_INTERNAL userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t public_key); +G_GNUC_INTERNAL userpref_error_t userpref_remove_device_public_key(const char *uuid);  G_GNUC_INTERNAL int userpref_has_device_public_key(const char *uuid);  G_GNUC_INTERNAL void userpref_get_host_id(char **host_id); diff --git a/swig/iphone.i b/swig/iphone.i index a0ee509..6e1849e 100644 --- a/swig/iphone.i +++ b/swig/iphone.i @@ -71,7 +71,7 @@ Lockdownd* my_new_Lockdownd(iPhone* phone) {  	Lockdownd* client = (Lockdownd*) malloc(sizeof(Lockdownd));  	client->dev = phone;  	client->client = NULL; -	if (LOCKDOWN_E_SUCCESS == lockdownd_client_new(phone->dev , &(client->client))) { +	if (LOCKDOWN_E_SUCCESS == lockdownd_client_new(phone->dev , &(client->client), NULL)) {  		return client;  	}  	else { diff --git a/tools/iphone_id.c b/tools/iphone_id.c index 80f22e1..a293469 100644 --- a/tools/iphone_id.c +++ b/tools/iphone_id.c @@ -70,7 +70,7 @@ int main(int argc, char **argv)  			return -2;  		} -		if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +		if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphone_id")) {  			iphone_device_free(phone);  			fprintf(stderr, "ERROR: Connecting to device failed!\n");  			return -2; diff --git a/tools/iphoneinfo.c b/tools/iphoneinfo.c index e0d7693..b5344be 100644 --- a/tools/iphoneinfo.c +++ b/tools/iphoneinfo.c @@ -136,7 +136,7 @@ int main(int argc, char *argv[])  		}  	} -	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphoneinfo")) {  		iphone_device_free(phone);  		return -1;  	} @@ -278,13 +278,10 @@ void plist_children_to_string(plist_t node)  	plist_dict_next_item(node, it, &key, &subnode);  	while (subnode)  	{ -		subnode = NULL; -  		printf("%s: ", key);  		free(key);  		key = NULL;  		plist_node_to_string(subnode); -  		plist_dict_next_item(node, it, &key, &subnode);  	}  	free(it); diff --git a/tools/iphonesyslog.c b/tools/iphonesyslog.c index 8fa3b04..5d4f564 100644 --- a/tools/iphonesyslog.c +++ b/tools/iphonesyslog.c @@ -99,7 +99,7 @@ int main(int argc, char *argv[])  		}  	} -	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { +	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphonesyslog")) {  		iphone_device_free(phone);  		return -1;  	} | 
