summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dev/afccheck.c2
-rw-r--r--dev/iphoneclient.c2
-rw-r--r--dev/iphoneenterrecovery.c2
-rw-r--r--dev/lckdclient.c2
-rwxr-xr-xdev/msync.py26
-rw-r--r--dev/msyncclient.c2
-rw-r--r--include/libiphone/lockdown.h8
-rw-r--r--include/libiphone/notification_proxy.h29
-rw-r--r--src/NotificationProxy.c20
-rw-r--r--src/NotificationProxy.h14
-rw-r--r--src/lockdown.c191
-rw-r--r--src/lockdown.h3
-rw-r--r--src/userpref.c24
-rw-r--r--src/userpref.h1
-rw-r--r--swig/iphone.i2
-rw-r--r--tools/iphone_id.c2
-rw-r--r--tools/iphoneinfo.c5
-rw-r--r--tools/iphonesyslog.c2
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[])
109 return 1; 109 return 1;
110 } 110 }
111 111
112 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { 112 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "afccheck")) {
113 iphone_device_free(phone); 113 iphone_device_free(phone);
114 return 1; 114 return 1;
115 } 115 }
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[])
87 if (uuid) 87 if (uuid)
88 free(uuid); 88 free(uuid);
89 89
90 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { 90 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphoneclient")) {
91 iphone_device_free(phone); 91 iphone_device_free(phone);
92 printf("Exiting.\n"); 92 printf("Exiting.\n");
93 return -1; 93 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[])
74 return -1; 74 return -1;
75 } 75 }
76 76
77 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { 77 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphoneenterrecovery")) {
78 iphone_device_free(phone); 78 iphone_device_free(phone);
79 return -1; 79 return -1;
80 } 80 }
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[])
48 if (uuid) 48 if (uuid)
49 free(uuid); 49 free(uuid);
50 50
51 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { 51 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "lckdclient")) {
52 iphone_device_free(phone); 52 iphone_device_free(phone);
53 return -1; 53 return -1;
54 } 54 }
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 @@
1#! /usr/bin/env python 1#! /usr/bin/env python
2 2
3from libiphone.iPhone import * 3from iphone import *
4from plist import *
4 5
5# get msync client 6# get msync client
6def GetMobileSyncClient() : 7def GetMobileSyncClient() :
@@ -24,17 +25,18 @@ msync = GetMobileSyncClient()
24if not msync : 25if not msync :
25 exit(1) 26 exit(1)
26 27
27array = PListNode(PLIST_ARRAY) 28a = Array()
28array.add_sub_string("SDMessageSyncDataClassWithDevice") 29a.append( String("SDMessageSyncDataClassWithDevice") )
29array.add_sub_string("com.apple.Contacts"); 30a.append( String("") )
30array.add_sub_string("---"); 31a.append( String("com.apple.Contacts") )
31array.add_sub_string("2009-01-13 22:25:58 +0100"); 32a.append( String("---") )
32array.add_sub_uint(106); 33a.append( String("2009-01-13 22:25:58 +0100") )
33array.add_sub_string("___EmptyParameterString___"); 34a.append( Integer(106) )
34 35a.append( String("___EmptyParameterString___") )
35msync.send(array) 36
36array = msync.receive() 37msync.send(a)
37print array.to_xml() 38a = msync.receive()
39print a.to_xml()
38 40
39 41
40 42
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[])
153 return -1; 153 return -1;
154 } 154 }
155 155
156 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { 156 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "msyncclient")) {
157 iphone_device_free(phone); 157 iphone_device_free(phone);
158 return -1; 158 return -1;
159 } 159 }
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" {
44#define LOCKDOWN_E_GET_VALUE_PROHIBITED -10 44#define LOCKDOWN_E_GET_VALUE_PROHIBITED -10
45#define LOCKDOWN_E_REMOVE_VALUE_PROHIBITED -11 45#define LOCKDOWN_E_REMOVE_VALUE_PROHIBITED -11
46#define LOCKDOWN_E_MUX_ERROR -12 46#define LOCKDOWN_E_MUX_ERROR -12
47#define LOCKDOWN_E_ACTIVATION_FAILED -13
48#define LOCKDOWN_E_PASSWORD_PROTECTED -14
47 49
48#define LOCKDOWN_E_UNKNOWN_ERROR -256 50#define LOCKDOWN_E_UNKNOWN_ERROR -256
49 51
@@ -53,8 +55,9 @@ struct lockdownd_client_int;
53typedef struct lockdownd_client_int *lockdownd_client_t; 55typedef struct lockdownd_client_int *lockdownd_client_t;
54 56
55/* Interface */ 57/* Interface */
56lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client); 58lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client, const char *label);
57lockdownd_error_t lockdownd_client_free(lockdownd_client_t client); 59lockdownd_error_t lockdownd_client_free(lockdownd_client_t client);
60void lockdownd_client_set_label(lockdownd_client_t client, const char *label);
58lockdownd_error_t lockdownd_query_type(lockdownd_client_t client); 61lockdownd_error_t lockdownd_query_type(lockdownd_client_t client);
59lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value); 62lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value);
60lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value); 63lockdownd_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);
65lockdownd_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist); 68lockdownd_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist);
66lockdownd_error_t lockdownd_pair(lockdownd_client_t client, char *host_id); 69lockdownd_error_t lockdownd_pair(lockdownd_client_t client, char *host_id);
67lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, char *host_id); 70lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, char *host_id);
71lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, char *host_id);
72lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record);
73lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client);
68lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t control, char **uuid); 74lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t control, char **uuid);
69lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name); 75lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name);
70lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client); 76lockdownd_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;
45#define NP_SYNC_DID_FINISH "com.apple.itunes-mobdev.syncDidFinish" 45#define NP_SYNC_DID_FINISH "com.apple.itunes-mobdev.syncDidFinish"
46 46
47/* Notification IDs for use with observe_notification (device --> client) */ 47/* Notification IDs for use with observe_notification (device --> client) */
48#define NP_SYNC_CANCEL_REQUEST "com.apple.itunes-client.syncCancelRequest" 48#define NP_SYNC_CANCEL_REQUEST "com.apple.itunes-client.syncCancelRequest"
49#define NP_SYNC_SUSPEND_REQUEST "com.apple.itunes-client.syncSuspendRequest" 49#define NP_SYNC_SUSPEND_REQUEST "com.apple.itunes-client.syncSuspendRequest"
50#define NP_SYNC_RESUME_REQUEST "com.apple.itunes-client.syncResumeRequest" 50#define NP_SYNC_RESUME_REQUEST "com.apple.itunes-client.syncResumeRequest"
51#define NP_PHONE_NUMBER_CHANGED "com.apple.mobile.lockdown.phone_number_changed" 51#define NP_PHONE_NUMBER_CHANGED "com.apple.mobile.lockdown.phone_number_changed"
52#define NP_DEVICE_NAME_CHANGED "com.apple.mobile.lockdown.device_name_changed" 52#define NP_DEVICE_NAME_CHANGED "com.apple.mobile.lockdown.device_name_changed"
53#define NP_ATTEMPTACTIVATION "com.apple.springboard.attemptactivation" 53#define NP_TRUSTED_HOST_ATTACHED "com.apple.mobile.lockdown.trusted_host_attached"
54#define NP_DS_DOMAIN_CHANGED "com.apple.mobile.data_sync.domain_changed" 54#define NP_HOST_DETACHED "com.apple.mobile.lockdown.host_detached"
55#define NP_APP_INSTALLED "com.apple.mobile.application_installed" 55#define NP_HOST_ATTACHED "com.apple.mobile.lockdown.host_attached"
56#define NP_APP_UNINSTALLED "com.apple.mobile.application_uninstalled" 56#define NP_REGISTRATION_FAILED "com.apple.mobile.lockdown.registration_failed"
57#define NP_ITDBPREP_DID_END "com.apple.itdbprep.notification.didEnd" 57#define NP_ACTIVATION_STATE "com.apple.mobile.lockdown.activation_state"
58#define NP_BRICK_STATE "com.apple.mobile.lockdown.brick_state"
59#define NP_ATTEMPTACTIVATION "com.apple.springboard.attemptactivation"
60#define NP_DS_DOMAIN_CHANGED "com.apple.mobile.data_sync.domain_changed"
61#define NP_APP_INSTALLED "com.apple.mobile.application_installed"
62#define NP_APP_UNINSTALLED "com.apple.mobile.application_uninstalled"
63#define NP_ITDBPREP_DID_END "com.apple.itdbprep.notification.didEnd"
64#define NP_LANGUAGE_CHANGED "com.apple.language.changed"
65#define NP_DEV_IMAGE_MOUNTED "com.apple.mobile.developer_image_mounted"
66#define NP_ADDRESS_BOOK_PREF_CHANGED "com.apple.AddressBook.PreferenceChanged"
58 67
59struct np_client_int; 68struct np_client_int;
60typedef struct np_client_int *np_client_t; 69typedef 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)
144 144
145/** Sends a notification to the device's Notification Proxy. 145/** Sends a notification to the device's Notification Proxy.
146 * 146 *
147 * notification messages seen so far:
148 * com.apple.itunes-mobdev.syncWillStart
149 * com.apple.itunes-mobdev.syncDidStart
150 *
151 * @param client The client to send to 147 * @param client The client to send to
152 * @param notification The notification message to send 148 * @param notification The notification message to send
153 * 149 *
@@ -212,22 +208,10 @@ np_error_t np_observe_notification( np_client_t client, const char *notification
212 208
213/** Notifies the iphone to send a notification on specified events. 209/** Notifies the iphone to send a notification on specified events.
214 * 210 *
215 * observation messages seen so far:
216 * com.apple.itunes-client.syncCancelRequest
217 * com.apple.itunes-client.syncSuspendRequest
218 * com.apple.itunes-client.syncResumeRequest
219 * com.apple.mobile.lockdown.phone_number_changed
220 * com.apple.mobile.lockdown.device_name_changed
221 * com.apple.springboard.attemptactivation
222 * com.apple.mobile.data_sync.domain_changed
223 * com.apple.mobile.application_installed
224 * com.apple.mobile.application_uninstalled
225 *
226 * @param client The client to send to 211 * @param client The client to send to
227 * @param notification_spec Specification of the notifications that should be 212 * @param notification_spec Specification of the notifications that should be
228 * observed. This is expected to be an array of const char* that MUST have a 213 * observed. This is expected to be an array of const char* that MUST have a
229 * terminating NULL entry. However this parameter can be NULL; in this case, 214 * terminating NULL entry.
230 * the default set of notifications will be used.
231 * 215 *
232 * @return NP_E_SUCCESS on success, NP_E_INVALID_ARG when client is null, 216 * @return NP_E_SUCCESS on success, NP_E_INVALID_ARG when client is null,
233 * or an error returned by np_observe_notification. 217 * 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
243 } 227 }
244 228
245 if (!notifications) { 229 if (!notifications) {
246 notifications = np_default_notifications; 230 return NP_E_INVALID_ARG;
247 } 231 }
248 232
249 while (notifications[i]) { 233 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 {
31 GThread *notifier; 31 GThread *notifier;
32}; 32};
33 33
34static const char *np_default_notifications[11] = {
35 NP_SYNC_SUSPEND_REQUEST,
36 NP_SYNC_RESUME_REQUEST,
37 NP_PHONE_NUMBER_CHANGED,
38 NP_SYNC_CANCEL_REQUEST,
39 NP_DEVICE_NAME_CHANGED,
40 NP_ATTEMPTACTIVATION,
41 NP_DS_DOMAIN_CHANGED,
42 NP_APP_INSTALLED,
43 NP_APP_UNINSTALLED,
44 NP_ITDBPREP_DID_END,
45 NULL
46};
47
48gpointer np_notifier(gpointer arg); 34gpointer np_notifier(gpointer arg);
49 35
50#endif 36#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)
108} 108}
109 109
110/** 110/**
111 * Adds a label key with the passed value to a plist dict node.
112 *
113 * @param plist The plist to add the key to
114 * @param label The value for the label key
115 *
116 */
117static void plist_dict_add_label(plist_t plist, const char *label)
118{
119 if (plist && label) {
120 if (plist_get_node_type(plist) == PLIST_DICT)
121 plist_dict_insert_item(plist, "Label", plist_new_string(label));
122 }
123}
124
125/**
111 * Closes the lockdownd communication session, by sending 126 * Closes the lockdownd communication session, by sending
112 * the StopSession Request to the device. 127 * the StopSession Request to the device.
113 * 128 *
@@ -128,6 +143,7 @@ lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client)
128 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; 143 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
129 144
130 plist_t dict = plist_new_dict(); 145 plist_t dict = plist_new_dict();
146 plist_dict_add_label(dict, client->label);
131 plist_dict_insert_item(dict,"Request", plist_new_string("StopSession")); 147 plist_dict_insert_item(dict,"Request", plist_new_string("StopSession"));
132 plist_dict_insert_item(dict,"SessionID", plist_new_string(client->session_id)); 148 plist_dict_insert_item(dict,"SessionID", plist_new_string(client->session_id));
133 149
@@ -223,11 +239,27 @@ lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
223 if (client->uuid) { 239 if (client->uuid) {
224 free(client->uuid); 240 free(client->uuid);
225 } 241 }
242 if (client->label) {
243 free(client->label);
244 }
226 245
227 free(client); 246 free(client);
228 return ret; 247 return ret;
229} 248}
230 249
250/**
251 * Sets the label to send for requests to lockdownd.
252 *
253 * @param client The lockdown client
254 * @param label The label to set or NULL to disable
255 *
256 */
257void lockdownd_client_set_label(lockdownd_client_t client, const char *label)
258{
259 if (client)
260 client->label = strdup(label);
261}
262
231/** Polls the iPhone for lockdownd data. 263/** Polls the iPhone for lockdownd data.
232 * 264 *
233 * @param control The lockdownd client 265 * @param control The lockdownd client
@@ -306,6 +338,7 @@ lockdownd_error_t lockdownd_query_type(lockdownd_client_t client)
306 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; 338 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
307 339
308 plist_t dict = plist_new_dict(); 340 plist_t dict = plist_new_dict();
341 plist_dict_add_label(dict, client->label);
309 plist_dict_insert_item(dict,"Request", plist_new_string("QueryType")); 342 plist_dict_insert_item(dict,"Request", plist_new_string("QueryType"));
310 343
311 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); 344 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
349 382
350 /* setup request plist */ 383 /* setup request plist */
351 dict = plist_new_dict(); 384 dict = plist_new_dict();
385 plist_dict_add_label(dict, client->label);
352 if (domain) { 386 if (domain) {
353 plist_dict_insert_item(dict,"Domain", plist_new_string(domain)); 387 plist_dict_insert_item(dict,"Domain", plist_new_string(domain));
354 } 388 }
@@ -410,6 +444,7 @@ lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *dom
410 444
411 /* setup request plist */ 445 /* setup request plist */
412 dict = plist_new_dict(); 446 dict = plist_new_dict();
447 plist_dict_add_label(dict, client->label);
413 if (domain) { 448 if (domain) {
414 plist_dict_insert_item(dict,"Domain", plist_new_string(domain)); 449 plist_dict_insert_item(dict,"Domain", plist_new_string(domain));
415 } 450 }
@@ -467,6 +502,7 @@ lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *
467 502
468 /* setup request plist */ 503 /* setup request plist */
469 dict = plist_new_dict(); 504 dict = plist_new_dict();
505 plist_dict_add_label(dict, client->label);
470 if (domain) { 506 if (domain) {
471 plist_dict_insert_item(dict,"Domain", plist_new_string(domain)); 507 plist_dict_insert_item(dict,"Domain", plist_new_string(domain));
472 } 508 }
@@ -576,10 +612,11 @@ lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **de
576 * 612 *
577 * @param phone The iPhone to create a lockdownd client for 613 * @param phone The iPhone to create a lockdownd client for
578 * @param client The pointer to the location of the new lockdownd_client 614 * @param client The pointer to the location of the new lockdownd_client
615 * @param label The label to use for communication. Usually the program name
579 * 616 *
580 * @return an error code (LOCKDOWN_E_SUCCESS on success) 617 * @return an error code (LOCKDOWN_E_SUCCESS on success)
581 */ 618 */
582lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client) 619lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client, const char *label)
583{ 620{
584 if (!client) 621 if (!client)
585 return LOCKDOWN_E_INVALID_ARG; 622 return LOCKDOWN_E_INVALID_ARG;
@@ -599,6 +636,7 @@ lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_
599 client_loc->in_SSL = 0; 636 client_loc->in_SSL = 0;
600 client_loc->session_id = NULL; 637 client_loc->session_id = NULL;
601 client_loc->uuid = NULL; 638 client_loc->uuid = NULL;
639 client_loc->label = strdup(label);
602 640
603 if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc)) { 641 if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc)) {
604 log_debug_msg("%s: QueryType failed in the lockdownd client.\n", __func__); 642 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
681 /* Setup Pair request plist */ 719 /* Setup Pair request plist */
682 dict = plist_new_dict(); 720 dict = plist_new_dict();
683 dict_record = plist_new_dict(); 721 dict_record = plist_new_dict();
722 plist_dict_add_label(dict, client->label);
684 plist_dict_insert_item(dict,"PairRecord", dict_record); 723 plist_dict_insert_item(dict,"PairRecord", dict_record);
685 724
686 plist_dict_insert_item(dict_record, "DeviceCertificate", plist_new_data((const char*)device_cert.data, device_cert.size)); 725 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
711 if (lockdown_check_result(dict, verb) != RESULT_SUCCESS) { 750 if (lockdown_check_result(dict, verb) != RESULT_SUCCESS) {
712 ret = LOCKDOWN_E_PAIRING_FAILED; 751 ret = LOCKDOWN_E_PAIRING_FAILED;
713 } 752 }
714 plist_free(dict);
715 dict = NULL;
716 753
717 /* store public key in config if pairing succeeded */ 754 /* if pairing succeeded */
718 if (ret == LOCKDOWN_E_SUCCESS) { 755 if (ret == LOCKDOWN_E_SUCCESS) {
719 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s success\n", __func__, verb); 756 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s success\n", __func__, verb);
720 userpref_set_device_public_key(client->uuid, public_key); 757 if (!strcmp("Unpair", verb)) {
758 /* remove public key from config */
759 userpref_remove_device_public_key(client->uuid);
760 } else {
761 /* store public key in config */
762 userpref_set_device_public_key(client->uuid, public_key);
763 }
721 } else { 764 } else {
722 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s failure\n", __func__, verb); 765 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s failure\n", __func__, verb);
766 plist_t error_node = NULL;
767 /* verify error condition */
768 error_node = plist_dict_get_item(dict, "Error");
769 if (error_node) {
770 char *value = NULL;
771 plist_get_string_val(error_node, &value);
772 /* the first pairing fails if the device is password protected */
773 if (value && !strcmp(value, "PasswordProtected")) {
774 ret = LOCKDOWN_E_PASSWORD_PROTECTED;
775 free(value);
776 }
777 plist_free(error_node);
778 error_node = NULL;
779 }
723 } 780 }
781 plist_free(dict);
782 dict = NULL;
724 free(public_key.data); 783 free(public_key.data);
725 return ret; 784 return ret;
726} 785}
@@ -758,6 +817,21 @@ lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, char *host_
758 return lockdownd_do_pair(client, host_id, "ValidatePair"); 817 return lockdownd_do_pair(client, host_id, "ValidatePair");
759} 818}
760 819
820/**
821 * Unpairs the device with the given HostID and removes the pairing records
822 * from the device and host.
823 *
824 * @param client The lockdown client to pair with.
825 * @param host_id The HostID to use for unpairing. If NULL is passed, then
826 * the HostID of the current machine is used.
827 *
828 * @return an error code (LOCKDOWN_E_SUCCESS on success)
829 */
830lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, char *host_id)
831{
832 return lockdownd_do_pair(client, host_id, "Unpair");
833}
834
761/** 835/**
762 * Tells the device to immediately enter recovery mode. 836 * Tells the device to immediately enter recovery mode.
763 * 837 *
@@ -773,6 +847,7 @@ lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client)
773 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; 847 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
774 848
775 plist_t dict = plist_new_dict(); 849 plist_t dict = plist_new_dict();
850 plist_dict_add_label(dict, client->label);
776 plist_dict_insert_item(dict,"Request", plist_new_string("EnterRecovery")); 851 plist_dict_insert_item(dict,"Request", plist_new_string("EnterRecovery"));
777 852
778 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: telling device to enter recovery mode\n", __func__); 853 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)
808 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; 883 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
809 884
810 plist_t dict = plist_new_dict(); 885 plist_t dict = plist_new_dict();
886 plist_dict_add_label(dict, client->label);
811 plist_dict_insert_item(dict,"Request", plist_new_string("Goodbye")); 887 plist_dict_insert_item(dict,"Request", plist_new_string("Goodbye"));
812 888
813 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); 889 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
977 * 1053 *
978 * @return an error code (LOCKDOWN_E_SUCCESS on success) 1054 * @return an error code (LOCKDOWN_E_SUCCESS on success)
979 */ 1055 */
980lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *HostID) 1056lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *host_id)
981{ 1057{
982 plist_t dict = NULL; 1058 plist_t dict = NULL;
983 uint32_t return_me = 0; 1059 uint32_t return_me = 0;
@@ -990,7 +1066,8 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c
990 1066
991 /* Setup DevicePublicKey request plist */ 1067 /* Setup DevicePublicKey request plist */
992 dict = plist_new_dict(); 1068 dict = plist_new_dict();
993 plist_dict_insert_item(dict,"HostID", plist_new_string(HostID)); 1069 plist_dict_add_label(dict, client->label);
1070 plist_dict_insert_item(dict,"HostID", plist_new_string(host_id));
994 plist_dict_insert_item(dict,"Request", plist_new_string("StartSession")); 1071 plist_dict_insert_item(dict,"Request", plist_new_string("StartSession"));
995 1072
996 ret = lockdownd_send(client, dict); 1073 ret = lockdownd_send(client, dict);
@@ -1013,14 +1090,15 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c
1013 1090
1014 if (!strcmp(error, "InvalidHostID")) { 1091 if (!strcmp(error, "InvalidHostID")) {
1015 /* hostid is unknown. Pair and try again */ 1092 /* hostid is unknown. Pair and try again */
1016 char *host_id = NULL; 1093 char *host_id_new = NULL;
1017 userpref_get_host_id(&host_id); 1094 userpref_get_host_id(&host_id_new);
1018 1095
1019 if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, host_id) ) { 1096 if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, host_id_new) ) {
1020 /* start session again */ 1097 /* start session again */
1021 plist_free(dict); 1098 plist_free(dict);
1022 dict = plist_new_dict(); 1099 dict = plist_new_dict();
1023 plist_dict_insert_item(dict,"HostID", plist_new_string(HostID)); 1100 plist_dict_add_label(dict, client->label);
1101 plist_dict_insert_item(dict,"HostID", plist_new_string(host_id_new));
1024 plist_dict_insert_item(dict,"Request", plist_new_string("StartSession")); 1102 plist_dict_insert_item(dict,"Request", plist_new_string("StartSession"));
1025 1103
1026 ret = lockdownd_send(client, dict); 1104 ret = lockdownd_send(client, dict);
@@ -1029,7 +1107,7 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c
1029 1107
1030 ret = lockdownd_recv(client, &dict); 1108 ret = lockdownd_recv(client, &dict);
1031 } 1109 }
1032 free(host_id); 1110 free(host_id_new);
1033 } 1111 }
1034 free(error); 1112 free(error);
1035 } 1113 }
@@ -1217,6 +1295,7 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char
1217 host_id = NULL; 1295 host_id = NULL;
1218 1296
1219 dict = plist_new_dict(); 1297 dict = plist_new_dict();
1298 plist_dict_add_label(dict, client->label);
1220 plist_dict_insert_item(dict,"Request", plist_new_string("StartService")); 1299 plist_dict_insert_item(dict,"Request", plist_new_string("StartService"));
1221 plist_dict_insert_item(dict,"Service", plist_new_string(service)); 1300 plist_dict_insert_item(dict,"Service", plist_new_string(service));
1222 1301
@@ -1260,3 +1339,91 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char
1260 return ret; 1339 return ret;
1261} 1340}
1262 1341
1342/**
1343 * Activates the device. Only works within an open session.
1344 * The ActivationRecord plist dictionary must be obtained using the
1345 * activation protocol requesting from Apple's https webservice.
1346 *
1347 * @see http://iphone-docs.org/doku.php?id=docs:protocols:activation
1348 *
1349 * @param control The lockdown client
1350 * @param activation_record The activation record plist dictionary
1351 *
1352 * @return an error code (LOCKDOWN_E_SUCCESS on success)
1353 */
1354lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record)
1355{
1356 if (!client)
1357 return LOCKDOWN_E_INVALID_ARG;
1358
1359 if (!activation_record)
1360 return LOCKDOWN_E_INVALID_ARG;
1361
1362 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
1363
1364 plist_t dict = plist_new_dict();
1365 plist_dict_add_label(dict, client->label);
1366 plist_dict_insert_item(dict,"Request", plist_new_string("Activate"));
1367 plist_dict_insert_item(dict,"ActivationRecord", activation_record);
1368
1369 ret = lockdownd_send(client, dict);
1370 plist_free(dict);
1371 dict = NULL;
1372
1373 ret = lockdownd_recv(client, &dict);
1374 if (!dict) {
1375 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: LOCKDOWN_E_PLIST_ERROR\n", __func__);
1376 return LOCKDOWN_E_PLIST_ERROR;
1377 }
1378
1379 ret = LOCKDOWN_E_ACTIVATION_FAILED;
1380 if (lockdown_check_result(dict, "Activate") == RESULT_SUCCESS) {
1381 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__);
1382 ret = LOCKDOWN_E_SUCCESS;
1383 }
1384 plist_free(dict);
1385 dict = NULL;
1386
1387 return ret;
1388}
1389
1390/**
1391 * Deactivates the device, returning it to the locked
1392 * “Activate with iTunes” screen.
1393 *
1394 * @param control The lockdown client
1395 *
1396 * @return an error code (LOCKDOWN_E_SUCCESS on success)
1397 */
1398lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client)
1399{
1400 if (!client)
1401 return LOCKDOWN_E_INVALID_ARG;
1402
1403 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
1404
1405 plist_t dict = plist_new_dict();
1406 plist_dict_add_label(dict, client->label);
1407 plist_dict_insert_item(dict,"Request", plist_new_string("Deactivate"));
1408
1409 ret = lockdownd_send(client, dict);
1410 plist_free(dict);
1411 dict = NULL;
1412
1413 ret = lockdownd_recv(client, &dict);
1414 if (!dict) {
1415 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: LOCKDOWN_E_PLIST_ERROR\n", __func__);
1416 return LOCKDOWN_E_PLIST_ERROR;
1417 }
1418
1419 ret = LOCKDOWN_E_UNKNOWN_ERROR;
1420 if (lockdown_check_result(dict, "Deactivate") == RESULT_SUCCESS) {
1421 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__);
1422 ret = LOCKDOWN_E_SUCCESS;
1423 }
1424 plist_free(dict);
1425 dict = NULL;
1426
1427 return ret;
1428}
1429
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 {
34 int in_SSL; 34 int in_SSL;
35 char *session_id; 35 char *session_id;
36 char *uuid; 36 char *uuid;
37 char *label;
37}; 38};
38 39
39lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnutls_datum_t * public_key); 40lockdownd_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
41 gnutls_datum_t * host_cert, gnutls_datum_t * root_cert); 42 gnutls_datum_t * host_cert, gnutls_datum_t * root_cert);
42 43
43/* SSL functions */ 44/* SSL functions */
44lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *HostID); 45lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *host_id);
45ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length); 46ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length);
46ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length); 47ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length);
47 48
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
212 return USERPREF_E_SUCCESS; 212 return USERPREF_E_SUCCESS;
213} 213}
214 214
215/** Remove the public key stored for the device with uuid from this host.
216 *
217 * @param uuid The uuid of the device
218 *
219 * @return USERPREF_E_SUCCESS on success.
220 */
221userpref_error_t userpref_remove_device_public_key(const char *uuid)
222{
223 if (!userpref_has_device_public_key(uuid))
224 return USERPREF_E_SUCCESS;
225
226 /* build file path */
227 gchar *device_file = g_strconcat(uuid, ".pem", NULL);
228 gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL);
229
230 /* remove file */
231 g_remove(pem);
232
233 g_free(pem);
234 g_free(device_file);
235
236 return USERPREF_E_SUCCESS;
237}
238
215/** Private function which reads the given file into a gnutls structure. 239/** Private function which reads the given file into a gnutls structure.
216 * 240 *
217 * @param file The filename of the file to read 241 * @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
38G_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); 38G_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);
39G_GNUC_INTERNAL userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert); 39G_GNUC_INTERNAL userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert);
40G_GNUC_INTERNAL userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t public_key); 40G_GNUC_INTERNAL userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t public_key);
41G_GNUC_INTERNAL userpref_error_t userpref_remove_device_public_key(const char *uuid);
41G_GNUC_INTERNAL int userpref_has_device_public_key(const char *uuid); 42G_GNUC_INTERNAL int userpref_has_device_public_key(const char *uuid);
42G_GNUC_INTERNAL void userpref_get_host_id(char **host_id); 43G_GNUC_INTERNAL void userpref_get_host_id(char **host_id);
43 44
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) {
71 Lockdownd* client = (Lockdownd*) malloc(sizeof(Lockdownd)); 71 Lockdownd* client = (Lockdownd*) malloc(sizeof(Lockdownd));
72 client->dev = phone; 72 client->dev = phone;
73 client->client = NULL; 73 client->client = NULL;
74 if (LOCKDOWN_E_SUCCESS == lockdownd_client_new(phone->dev , &(client->client))) { 74 if (LOCKDOWN_E_SUCCESS == lockdownd_client_new(phone->dev , &(client->client), NULL)) {
75 return client; 75 return client;
76 } 76 }
77 else { 77 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)
70 return -2; 70 return -2;
71 } 71 }
72 72
73 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { 73 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphone_id")) {
74 iphone_device_free(phone); 74 iphone_device_free(phone);
75 fprintf(stderr, "ERROR: Connecting to device failed!\n"); 75 fprintf(stderr, "ERROR: Connecting to device failed!\n");
76 return -2; 76 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[])
136 } 136 }
137 } 137 }
138 138
139 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { 139 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphoneinfo")) {
140 iphone_device_free(phone); 140 iphone_device_free(phone);
141 return -1; 141 return -1;
142 } 142 }
@@ -278,13 +278,10 @@ void plist_children_to_string(plist_t node)
278 plist_dict_next_item(node, it, &key, &subnode); 278 plist_dict_next_item(node, it, &key, &subnode);
279 while (subnode) 279 while (subnode)
280 { 280 {
281 subnode = NULL;
282
283 printf("%s: ", key); 281 printf("%s: ", key);
284 free(key); 282 free(key);
285 key = NULL; 283 key = NULL;
286 plist_node_to_string(subnode); 284 plist_node_to_string(subnode);
287
288 plist_dict_next_item(node, it, &key, &subnode); 285 plist_dict_next_item(node, it, &key, &subnode);
289 } 286 }
290 free(it); 287 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[])
99 } 99 }
100 } 100 }
101 101
102 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { 102 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphonesyslog")) {
103 iphone_device_free(phone); 103 iphone_device_free(phone);
104 return -1; 104 return -1;
105 } 105 }