summaryrefslogtreecommitdiffstats
path: root/cython/lockdown.pxi
diff options
context:
space:
mode:
Diffstat (limited to 'cython/lockdown.pxi')
-rw-r--r--cython/lockdown.pxi351
1 files changed, 351 insertions, 0 deletions
diff --git a/cython/lockdown.pxi b/cython/lockdown.pxi
new file mode 100644
index 0000000..25edb4c
--- /dev/null
+++ b/cython/lockdown.pxi
@@ -0,0 +1,351 @@
1cdef extern from "libimobiledevice/lockdown.h":
2 ctypedef enum lockdownd_error_t:
3 LOCKDOWN_E_SUCCESS
4 LOCKDOWN_E_INVALID_ARG
5 LOCKDOWN_E_INVALID_CONF
6 LOCKDOWN_E_PLIST_ERROR
7 LOCKDOWN_E_PAIRING_FAILED
8 LOCKDOWN_E_SSL_ERROR
9 LOCKDOWN_E_DICT_ERROR
10 LOCKDOWN_E_RECEIVE_TIMEOUT
11 LOCKDOWN_E_SET_VALUE_PROHIBITED
12 LOCKDOWN_E_GET_VALUE_PROHIBITED
13 LOCKDOWN_E_MUX_ERROR
14 LOCKDOWN_E_NO_RUNNING_SESSION
15 LOCKDOWN_E_INVALID_RESPONSE
16 LOCKDOWN_E_MISSING_KEY
17 LOCKDOWN_E_MISSING_VALUE
18 LOCKDOWN_E_GET_PROHIBITED
19 LOCKDOWN_E_SET_PROHIBITED
20 LOCKDOWN_E_REMOVE_PROHIBITED
21 LOCKDOWN_E_IMMUTABLE_VALUE
22 LOCKDOWN_E_PASSWORD_PROTECTED
23 LOCKDOWN_E_USER_DENIED_PAIRING
24 LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING
25 LOCKDOWN_E_MISSING_HOST_ID
26 LOCKDOWN_E_INVALID_HOST_ID
27 LOCKDOWN_E_SESSION_ACTIVE
28 LOCKDOWN_E_SESSION_INACTIVE
29 LOCKDOWN_E_MISSING_SESSION_ID
30 LOCKDOWN_E_INVALID_SESSION_ID
31 LOCKDOWN_E_MISSING_SERVICE
32 LOCKDOWN_E_INVALID_SERVICE
33 LOCKDOWN_E_SERVICE_LIMIT
34 LOCKDOWN_E_MISSING_PAIR_RECORD
35 LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED
36 LOCKDOWN_E_INVALID_PAIR_RECORD
37 LOCKDOWN_E_INVALID_ACTIVATION_RECORD
38 LOCKDOWN_E_MISSING_ACTIVATION_RECORD
39 LOCKDOWN_E_SERVICE_PROHIBITED
40 LOCKDOWN_E_ESCROW_LOCKED
41 LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION
42 LOCKDOWN_E_FMIP_PROTECTED
43 LOCKDOWN_E_MC_PROTECTED
44 LOCKDOWN_E_MC_CHALLENGE_REQUIRED
45 LOCKDOWN_E_UNKNOWN_ERROR
46
47 lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, char *label)
48 lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, char *label)
49 lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
50
51 lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **tp)
52 lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t *value)
53 lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t value)
54 lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, char *domain, char *key)
55 lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, char *identifier, lockdownd_service_descriptor_t *service)
56 lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, char *host_id, char **session_id, int *ssl_enabled)
57 lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, char *session_id)
58 lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist.plist_t plist)
59 lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist.plist_t *plist)
60 lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
61 lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
62 lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
63 lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist.plist_t activation_record)
64 lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client)
65 lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client)
66 lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client)
67 lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count)
68 lockdownd_error_t lockdownd_data_classes_free(char **classes)
69 lockdownd_error_t lockdownd_service_descriptor_free(lockdownd_service_descriptor_t service)
70
71cdef class LockdownError(BaseError):
72 def __init__(self, *args, **kwargs):
73 self._lookup_table = {
74 LOCKDOWN_E_SUCCESS: "Success",
75 LOCKDOWN_E_INVALID_ARG: "Invalid argument",
76 LOCKDOWN_E_INVALID_CONF: "Invalid configuration",
77 LOCKDOWN_E_PLIST_ERROR: "Property list error",
78 LOCKDOWN_E_PAIRING_FAILED: "Pairing failed",
79 LOCKDOWN_E_SSL_ERROR: "SSL error",
80 LOCKDOWN_E_DICT_ERROR: "Dictionary error",
81 LOCKDOWN_E_RECEIVE_TIMEOUT: "Receive timeout",
82 LOCKDOWN_E_MUX_ERROR: "Mux Protocol Error",
83 LOCKDOWN_E_NO_RUNNING_SESSION: "No running session",
84 LOCKDOWN_E_INVALID_RESPONSE: "Invalid response",
85 LOCKDOWN_E_MISSING_KEY: "Missing key",
86 LOCKDOWN_E_MISSING_VALUE: "Missing value",
87 LOCKDOWN_E_GET_PROHIBITED: "Get value prohibited",
88 LOCKDOWN_E_SET_PROHIBITED: "Set value prohibited",
89 LOCKDOWN_E_REMOVE_PROHIBITED: "Remove value prohibited",
90 LOCKDOWN_E_IMMUTABLE_VALUE: "Immutable value",
91 LOCKDOWN_E_PASSWORD_PROTECTED: "Password protected",
92 LOCKDOWN_E_USER_DENIED_PAIRING: "User denied pairing",
93 LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING: "Pairing dialog response pending",
94 LOCKDOWN_E_MISSING_HOST_ID: "Missing host ID",
95 LOCKDOWN_E_INVALID_HOST_ID: "Invalid host ID",
96 LOCKDOWN_E_SESSION_ACTIVE: "Session active",
97 LOCKDOWN_E_SESSION_INACTIVE: "Session inactive",
98 LOCKDOWN_E_MISSING_SESSION_ID: "Missing session ID",
99 LOCKDOWN_E_INVALID_SESSION_ID: "Invalid session ID",
100 LOCKDOWN_E_MISSING_SERVICE: "Missing service",
101 LOCKDOWN_E_INVALID_SERVICE: "Invalid service",
102 LOCKDOWN_E_SERVICE_LIMIT: "Service limit reached",
103 LOCKDOWN_E_MISSING_PAIR_RECORD: "Missing pair record",
104 LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED: "Saving pair record failed",
105 LOCKDOWN_E_INVALID_PAIR_RECORD: "Invalid pair record",
106 LOCKDOWN_E_INVALID_ACTIVATION_RECORD: "Invalid activation record",
107 LOCKDOWN_E_MISSING_ACTIVATION_RECORD: "Missing activation record",
108 LOCKDOWN_E_SERVICE_PROHIBITED: "Service prohibited",
109 LOCKDOWN_E_ESCROW_LOCKED: "Escrow locked",
110 LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION: "Pairing prohibited over this connection",
111 LOCKDOWN_E_FMIP_PROTECTED: "Find My iPhone/iPod/iPad protected",
112 LOCKDOWN_E_MC_PROTECTED: "MC protected",
113 LOCKDOWN_E_MC_CHALLENGE_REQUIRED: "MC challenge required",
114 LOCKDOWN_E_UNKNOWN_ERROR: "Unknown error"
115 }
116 BaseError.__init__(self, *args, **kwargs)
117
118cdef class LockdownPairRecord:
119 #def __cinit__(self, bytes device_certificate, bytes host_certificate, bytes host_id, bytes root_certificate, *args, **kwargs):
120 property device_certificate:
121 def __get__(self):
122 cdef bytes result = self._c_record.device_certificate
123 return result
124 property host_certificate:
125 def __get__(self):
126 cdef bytes result = self._c_record.host_certificate
127 return result
128 property host_id:
129 def __get__(self):
130 cdef bytes result = self._c_record.host_id
131 return result
132 property root_certificate:
133 def __get__(self):
134 cdef bytes result = self._c_record.root_certificate
135 return result
136
137cdef class LockdownServiceDescriptor(Base):
138 #def __cinit__(self, uint16_t port, uint8_t ssl_enabled, *args, **kwargs):
139 def __dealloc__(self):
140 cdef lockdownd_error_t err
141 if self._c_service_descriptor is not NULL:
142 err = lockdownd_service_descriptor_free(self._c_service_descriptor)
143 self._c_service_descriptor = NULL
144 self.handle_error(err)
145 property port:
146 def __get__(self):
147 return self._c_service_descriptor.port
148 property ssl_enabled:
149 def __get__(self):
150 return self._c_service_descriptor.ssl_enabled
151
152cdef class LockdownClient(PropertyListService):
153 def __cinit__(self, iDevice device not None, bytes label=b'', bint handshake=True, *args, **kwargs):
154 cdef:
155 lockdownd_error_t err
156 char* c_label = NULL
157 if label:
158 c_label = label
159 if handshake:
160 err = lockdownd_client_new_with_handshake(device._c_dev, &self._c_client, c_label)
161 else:
162 err = lockdownd_client_new(device._c_dev, &self._c_client, c_label)
163 self.handle_error(err)
164
165 self.device = device
166
167 def __dealloc__(self):
168 cdef lockdownd_error_t err
169 if self._c_client is not NULL:
170 err = lockdownd_client_free(self._c_client)
171 self.handle_error(err)
172
173 cpdef bytes query_type(self):
174 cdef:
175 lockdownd_error_t err
176 char* c_type = NULL
177 bytes result
178 err = lockdownd_query_type(self._c_client, &c_type)
179 try:
180 self.handle_error(err)
181 result = c_type
182
183 return result
184 except BaseError, e:
185 raise
186 finally:
187 if c_type != NULL:
188 free(c_type)
189
190 cpdef plist.Node get_value(self, bytes domain=None, bytes key=None):
191 cdef:
192 lockdownd_error_t err
193 plist.plist_t c_node = NULL
194 char* c_domain = NULL
195 char* c_key = NULL
196 if domain is not None:
197 c_domain = domain
198 if key is not None:
199 c_key = key
200
201 err = lockdownd_get_value(self._c_client, c_domain, c_key, &c_node)
202
203 try:
204 self.handle_error(err)
205
206 return plist.plist_t_to_node(c_node)
207 except BaseError, e:
208 if c_node != NULL:
209 plist.plist_free(c_node)
210 raise
211
212 cpdef set_value(self, bytes domain, bytes key, object value):
213 cdef:
214 plist.plist_t c_node = NULL
215 char* c_domain = NULL
216 char* c_key = NULL
217
218 c_node = plist.native_to_plist_t(value)
219 if domain is not None:
220 c_domain = domain
221 if key is not None:
222 c_key = key
223 try:
224 self.handle_error(lockdownd_set_value(self._c_client, c_domain, c_key, c_node))
225 except BaseError, e:
226 raise
227 finally:
228 if c_node != NULL:
229 c_node = NULL
230
231 cpdef remove_value(self, bytes domain, bytes key):
232 self.handle_error(lockdownd_remove_value(self._c_client, domain, key))
233
234 cpdef object start_service(self, object service):
235 cdef:
236 char* c_service_name = NULL
237 lockdownd_service_descriptor_t c_descriptor = NULL
238 LockdownServiceDescriptor result
239
240 if issubclass(service, BaseService) and \
241 service.__service_name__ is not None \
242 and isinstance(service.__service_name__, (str, bytes)):
243 c_service_name_str = service.__service_name__.encode('utf-8')
244 elif isinstance(service, (str, bytes)):
245 c_service_name_str = service.encode('utf-8')
246 else:
247 raise TypeError("LockdownClient.start_service() takes a BaseService or string as its first argument")
248 c_service_name = c_service_name_str
249
250 try:
251 self.handle_error(lockdownd_start_service(self._c_client, c_service_name, &c_descriptor))
252
253 result = LockdownServiceDescriptor.__new__(LockdownServiceDescriptor)
254 result._c_service_descriptor = c_descriptor
255
256 return result
257 except BaseError, e:
258 raise
259
260 cpdef object get_service_client(self, object service_class):
261 cdef:
262 LockdownServiceDescriptor descriptor
263
264 if not hasattr(service_class, '__service_name__') and \
265 not service_class.__service_name__ is not None \
266 and not isinstance(service_class.__service_name__, (str, bytes)):
267 raise TypeError("LockdownClient.get_service_client() takes a BaseService as its first argument")
268
269 descriptor = self.start_service(service_class)
270 return service_class(self.device, descriptor)
271
272 cpdef tuple start_session(self, bytes host_id):
273 cdef:
274 lockdownd_error_t err
275 char* c_session_id = NULL
276 bint ssl_enabled
277 bytes session_id
278 err = lockdownd_start_session(self._c_client, host_id, &c_session_id, <int *>&ssl_enabled)
279 try:
280 self.handle_error(err)
281
282 session_id = c_session_id
283 return (session_id, ssl_enabled)
284 except BaseError, e:
285 raise
286 finally:
287 if c_session_id != NULL:
288 free(c_session_id)
289
290 cpdef stop_session(self, bytes session_id):
291 self.handle_error(lockdownd_stop_session(self._c_client, session_id))
292
293 cpdef pair(self, object pair_record=None):
294 cdef lockdownd_pair_record_t c_pair_record = NULL
295 if pair_record is not None:
296 c_pair_record = (<LockdownPairRecord>pair_record)._c_record
297 self.handle_error(lockdownd_pair(self._c_client, c_pair_record))
298
299 cpdef validate_pair(self, object pair_record=None):
300 cdef lockdownd_pair_record_t c_pair_record = NULL
301 if pair_record is not None:
302 c_pair_record = (<LockdownPairRecord>pair_record)._c_record
303 self.handle_error(lockdownd_validate_pair(self._c_client, c_pair_record))
304
305 cpdef unpair(self, object pair_record=None):
306 cdef lockdownd_pair_record_t c_pair_record = NULL
307 if pair_record is not None:
308 c_pair_record = (<LockdownPairRecord>pair_record)._c_record
309 self.handle_error(lockdownd_unpair(self._c_client, c_pair_record))
310
311 cpdef activate(self, plist.Node activation_record):
312 self.handle_error(lockdownd_activate(self._c_client, activation_record._c_node))
313
314 cpdef deactivate(self):
315 self.handle_error(lockdownd_deactivate(self._c_client))
316
317 cpdef enter_recovery(self):
318 self.handle_error(lockdownd_enter_recovery(self._c_client))
319
320 cpdef goodbye(self):
321 self.handle_error(lockdownd_goodbye(self._c_client))
322
323 cpdef list get_sync_data_classes(self):
324 cdef:
325 char **classes = NULL
326 int count = 0
327 list result = []
328 bytes data_class
329
330 try:
331 self.handle_error(lockdownd_get_sync_data_classes(self._c_client, &classes, &count))
332
333 for i from 0 <= i < count:
334 data_class = classes[i]
335 result.append(data_class)
336
337 return result
338 except Exception, e:
339 raise
340 finally:
341 if classes != NULL:
342 lockdownd_data_classes_free(classes)
343
344 cdef inline int16_t _send(self, plist.plist_t node):
345 return lockdownd_send(self._c_client, node)
346
347 cdef inline int16_t _receive(self, plist.plist_t* node):
348 return lockdownd_receive(self._c_client, node)
349
350 cdef inline BaseError _error(self, int16_t ret):
351 return LockdownError(ret)