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 @@
+cdef extern from "libimobiledevice/lockdown.h":
+ ctypedef enum lockdownd_error_t:
+ LOCKDOWN_E_SUCCESS
+ LOCKDOWN_E_INVALID_ARG
+ LOCKDOWN_E_INVALID_CONF
+ LOCKDOWN_E_PLIST_ERROR
+ LOCKDOWN_E_PAIRING_FAILED
+ LOCKDOWN_E_SSL_ERROR
+ LOCKDOWN_E_DICT_ERROR
+ LOCKDOWN_E_RECEIVE_TIMEOUT
+ LOCKDOWN_E_SET_VALUE_PROHIBITED
+ LOCKDOWN_E_GET_VALUE_PROHIBITED
+ LOCKDOWN_E_MUX_ERROR
+ LOCKDOWN_E_NO_RUNNING_SESSION
+ LOCKDOWN_E_INVALID_RESPONSE
+ LOCKDOWN_E_MISSING_KEY
+ LOCKDOWN_E_MISSING_VALUE
+ LOCKDOWN_E_GET_PROHIBITED
+ LOCKDOWN_E_SET_PROHIBITED
+ LOCKDOWN_E_REMOVE_PROHIBITED
+ LOCKDOWN_E_IMMUTABLE_VALUE
+ LOCKDOWN_E_PASSWORD_PROTECTED
+ LOCKDOWN_E_USER_DENIED_PAIRING
+ LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING
+ LOCKDOWN_E_MISSING_HOST_ID
+ LOCKDOWN_E_INVALID_HOST_ID
+ LOCKDOWN_E_SESSION_ACTIVE
+ LOCKDOWN_E_SESSION_INACTIVE
+ LOCKDOWN_E_MISSING_SESSION_ID
+ LOCKDOWN_E_INVALID_SESSION_ID
+ LOCKDOWN_E_MISSING_SERVICE
+ LOCKDOWN_E_INVALID_SERVICE
+ LOCKDOWN_E_SERVICE_LIMIT
+ LOCKDOWN_E_MISSING_PAIR_RECORD
+ LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED
+ LOCKDOWN_E_INVALID_PAIR_RECORD
+ LOCKDOWN_E_INVALID_ACTIVATION_RECORD
+ LOCKDOWN_E_MISSING_ACTIVATION_RECORD
+ LOCKDOWN_E_SERVICE_PROHIBITED
+ LOCKDOWN_E_ESCROW_LOCKED
+ LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION
+ LOCKDOWN_E_FMIP_PROTECTED
+ LOCKDOWN_E_MC_PROTECTED
+ LOCKDOWN_E_MC_CHALLENGE_REQUIRED
+ LOCKDOWN_E_UNKNOWN_ERROR
+
+ lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, char *label)
+ lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, char *label)
+ lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
+
+ lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **tp)
+ lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t *value)
+ lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t value)
+ lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, char *domain, char *key)
+ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, char *identifier, lockdownd_service_descriptor_t *service)
+ lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, char *host_id, char **session_id, int *ssl_enabled)
+ lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, char *session_id)
+ lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist.plist_t plist)
+ lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist.plist_t *plist)
+ lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
+ lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
+ lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
+ lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist.plist_t activation_record)
+ lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client)
+ lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client)
+ lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client)
+ lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count)
+ lockdownd_error_t lockdownd_data_classes_free(char **classes)
+ lockdownd_error_t lockdownd_service_descriptor_free(lockdownd_service_descriptor_t service)
+
+cdef class LockdownError(BaseError):
+ def __init__(self, *args, **kwargs):
+ self._lookup_table = {
+ LOCKDOWN_E_SUCCESS: "Success",
+ LOCKDOWN_E_INVALID_ARG: "Invalid argument",
+ LOCKDOWN_E_INVALID_CONF: "Invalid configuration",
+ LOCKDOWN_E_PLIST_ERROR: "Property list error",
+ LOCKDOWN_E_PAIRING_FAILED: "Pairing failed",
+ LOCKDOWN_E_SSL_ERROR: "SSL error",
+ LOCKDOWN_E_DICT_ERROR: "Dictionary error",
+ LOCKDOWN_E_RECEIVE_TIMEOUT: "Receive timeout",
+ LOCKDOWN_E_MUX_ERROR: "Mux Protocol Error",
+ LOCKDOWN_E_NO_RUNNING_SESSION: "No running session",
+ LOCKDOWN_E_INVALID_RESPONSE: "Invalid response",
+ LOCKDOWN_E_MISSING_KEY: "Missing key",
+ LOCKDOWN_E_MISSING_VALUE: "Missing value",
+ LOCKDOWN_E_GET_PROHIBITED: "Get value prohibited",
+ LOCKDOWN_E_SET_PROHIBITED: "Set value prohibited",
+ LOCKDOWN_E_REMOVE_PROHIBITED: "Remove value prohibited",
+ LOCKDOWN_E_IMMUTABLE_VALUE: "Immutable value",
+ LOCKDOWN_E_PASSWORD_PROTECTED: "Password protected",
+ LOCKDOWN_E_USER_DENIED_PAIRING: "User denied pairing",
+ LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING: "Pairing dialog response pending",
+ LOCKDOWN_E_MISSING_HOST_ID: "Missing host ID",
+ LOCKDOWN_E_INVALID_HOST_ID: "Invalid host ID",
+ LOCKDOWN_E_SESSION_ACTIVE: "Session active",
+ LOCKDOWN_E_SESSION_INACTIVE: "Session inactive",
+ LOCKDOWN_E_MISSING_SESSION_ID: "Missing session ID",
+ LOCKDOWN_E_INVALID_SESSION_ID: "Invalid session ID",
+ LOCKDOWN_E_MISSING_SERVICE: "Missing service",
+ LOCKDOWN_E_INVALID_SERVICE: "Invalid service",
+ LOCKDOWN_E_SERVICE_LIMIT: "Service limit reached",
+ LOCKDOWN_E_MISSING_PAIR_RECORD: "Missing pair record",
+ LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED: "Saving pair record failed",
+ LOCKDOWN_E_INVALID_PAIR_RECORD: "Invalid pair record",
+ LOCKDOWN_E_INVALID_ACTIVATION_RECORD: "Invalid activation record",
+ LOCKDOWN_E_MISSING_ACTIVATION_RECORD: "Missing activation record",
+ LOCKDOWN_E_SERVICE_PROHIBITED: "Service prohibited",
+ LOCKDOWN_E_ESCROW_LOCKED: "Escrow locked",
+ LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION: "Pairing prohibited over this connection",
+ LOCKDOWN_E_FMIP_PROTECTED: "Find My iPhone/iPod/iPad protected",
+ LOCKDOWN_E_MC_PROTECTED: "MC protected",
+ LOCKDOWN_E_MC_CHALLENGE_REQUIRED: "MC challenge required",
+ LOCKDOWN_E_UNKNOWN_ERROR: "Unknown error"
+ }
+ BaseError.__init__(self, *args, **kwargs)
+
+cdef class LockdownPairRecord:
+ #def __cinit__(self, bytes device_certificate, bytes host_certificate, bytes host_id, bytes root_certificate, *args, **kwargs):
+ property device_certificate:
+ def __get__(self):
+ cdef bytes result = self._c_record.device_certificate
+ return result
+ property host_certificate:
+ def __get__(self):
+ cdef bytes result = self._c_record.host_certificate
+ return result
+ property host_id:
+ def __get__(self):
+ cdef bytes result = self._c_record.host_id
+ return result
+ property root_certificate:
+ def __get__(self):
+ cdef bytes result = self._c_record.root_certificate
+ return result
+
+cdef class LockdownServiceDescriptor(Base):
+ #def __cinit__(self, uint16_t port, uint8_t ssl_enabled, *args, **kwargs):
+ def __dealloc__(self):
+ cdef lockdownd_error_t err
+ if self._c_service_descriptor is not NULL:
+ err = lockdownd_service_descriptor_free(self._c_service_descriptor)
+ self._c_service_descriptor = NULL
+ self.handle_error(err)
+ property port:
+ def __get__(self):
+ return self._c_service_descriptor.port
+ property ssl_enabled:
+ def __get__(self):
+ return self._c_service_descriptor.ssl_enabled
+
+cdef class LockdownClient(PropertyListService):
+ def __cinit__(self, iDevice device not None, bytes label=b'', bint handshake=True, *args, **kwargs):
+ cdef:
+ lockdownd_error_t err
+ char* c_label = NULL
+ if label:
+ c_label = label
+ if handshake:
+ err = lockdownd_client_new_with_handshake(device._c_dev, &self._c_client, c_label)
+ else:
+ err = lockdownd_client_new(device._c_dev, &self._c_client, c_label)
+ self.handle_error(err)
+
+ self.device = device
+
+ def __dealloc__(self):
+ cdef lockdownd_error_t err
+ if self._c_client is not NULL:
+ err = lockdownd_client_free(self._c_client)
+ self.handle_error(err)
+
+ cpdef bytes query_type(self):
+ cdef:
+ lockdownd_error_t err
+ char* c_type = NULL
+ bytes result
+ err = lockdownd_query_type(self._c_client, &c_type)
+ try:
+ self.handle_error(err)
+ result = c_type
+
+ return result
+ except BaseError, e:
+ raise
+ finally:
+ if c_type != NULL:
+ free(c_type)
+
+ cpdef plist.Node get_value(self, bytes domain=None, bytes key=None):
+ cdef:
+ lockdownd_error_t err
+ plist.plist_t c_node = NULL
+ char* c_domain = NULL
+ char* c_key = NULL
+ if domain is not None:
+ c_domain = domain
+ if key is not None:
+ c_key = key
+
+ err = lockdownd_get_value(self._c_client, c_domain, c_key, &c_node)
+
+ try:
+ self.handle_error(err)
+
+ return plist.plist_t_to_node(c_node)
+ except BaseError, e:
+ if c_node != NULL:
+ plist.plist_free(c_node)
+ raise
+
+ cpdef set_value(self, bytes domain, bytes key, object value):
+ cdef:
+ plist.plist_t c_node = NULL
+ char* c_domain = NULL
+ char* c_key = NULL
+
+ c_node = plist.native_to_plist_t(value)
+ if domain is not None:
+ c_domain = domain
+ if key is not None:
+ c_key = key
+ try:
+ self.handle_error(lockdownd_set_value(self._c_client, c_domain, c_key, c_node))
+ except BaseError, e:
+ raise
+ finally:
+ if c_node != NULL:
+ c_node = NULL
+
+ cpdef remove_value(self, bytes domain, bytes key):
+ self.handle_error(lockdownd_remove_value(self._c_client, domain, key))
+
+ cpdef object start_service(self, object service):
+ cdef:
+ char* c_service_name = NULL
+ lockdownd_service_descriptor_t c_descriptor = NULL
+ LockdownServiceDescriptor result
+
+ if issubclass(service, BaseService) and \
+ service.__service_name__ is not None \
+ and isinstance(service.__service_name__, (str, bytes)):
+ c_service_name_str = service.__service_name__.encode('utf-8')
+ elif isinstance(service, (str, bytes)):
+ c_service_name_str = service.encode('utf-8')
+ else:
+ raise TypeError("LockdownClient.start_service() takes a BaseService or string as its first argument")
+ c_service_name = c_service_name_str
+
+ try:
+ self.handle_error(lockdownd_start_service(self._c_client, c_service_name, &c_descriptor))
+
+ result = LockdownServiceDescriptor.__new__(LockdownServiceDescriptor)
+ result._c_service_descriptor = c_descriptor
+
+ return result
+ except BaseError, e:
+ raise
+
+ cpdef object get_service_client(self, object service_class):
+ cdef:
+ LockdownServiceDescriptor descriptor
+
+ if not hasattr(service_class, '__service_name__') and \
+ not service_class.__service_name__ is not None \
+ and not isinstance(service_class.__service_name__, (str, bytes)):
+ raise TypeError("LockdownClient.get_service_client() takes a BaseService as its first argument")
+
+ descriptor = self.start_service(service_class)
+ return service_class(self.device, descriptor)
+
+ cpdef tuple start_session(self, bytes host_id):
+ cdef:
+ lockdownd_error_t err
+ char* c_session_id = NULL
+ bint ssl_enabled
+ bytes session_id
+ err = lockdownd_start_session(self._c_client, host_id, &c_session_id, <int *>&ssl_enabled)
+ try:
+ self.handle_error(err)
+
+ session_id = c_session_id
+ return (session_id, ssl_enabled)
+ except BaseError, e:
+ raise
+ finally:
+ if c_session_id != NULL:
+ free(c_session_id)
+
+ cpdef stop_session(self, bytes session_id):
+ self.handle_error(lockdownd_stop_session(self._c_client, session_id))
+
+ cpdef pair(self, object pair_record=None):
+ cdef lockdownd_pair_record_t c_pair_record = NULL
+ if pair_record is not None:
+ c_pair_record = (<LockdownPairRecord>pair_record)._c_record
+ self.handle_error(lockdownd_pair(self._c_client, c_pair_record))
+
+ cpdef validate_pair(self, object pair_record=None):
+ cdef lockdownd_pair_record_t c_pair_record = NULL
+ if pair_record is not None:
+ c_pair_record = (<LockdownPairRecord>pair_record)._c_record
+ self.handle_error(lockdownd_validate_pair(self._c_client, c_pair_record))
+
+ cpdef unpair(self, object pair_record=None):
+ cdef lockdownd_pair_record_t c_pair_record = NULL
+ if pair_record is not None:
+ c_pair_record = (<LockdownPairRecord>pair_record)._c_record
+ self.handle_error(lockdownd_unpair(self._c_client, c_pair_record))
+
+ cpdef activate(self, plist.Node activation_record):
+ self.handle_error(lockdownd_activate(self._c_client, activation_record._c_node))
+
+ cpdef deactivate(self):
+ self.handle_error(lockdownd_deactivate(self._c_client))
+
+ cpdef enter_recovery(self):
+ self.handle_error(lockdownd_enter_recovery(self._c_client))
+
+ cpdef goodbye(self):
+ self.handle_error(lockdownd_goodbye(self._c_client))
+
+ cpdef list get_sync_data_classes(self):
+ cdef:
+ char **classes = NULL
+ int count = 0
+ list result = []
+ bytes data_class
+
+ try:
+ self.handle_error(lockdownd_get_sync_data_classes(self._c_client, &classes, &count))
+
+ for i from 0 <= i < count:
+ data_class = classes[i]
+ result.append(data_class)
+
+ return result
+ except Exception, e:
+ raise
+ finally:
+ if classes != NULL:
+ lockdownd_data_classes_free(classes)
+
+ cdef inline int16_t _send(self, plist.plist_t node):
+ return lockdownd_send(self._c_client, node)
+
+ cdef inline int16_t _receive(self, plist.plist_t* node):
+ return lockdownd_receive(self._c_client, node)
+
+ cdef inline BaseError _error(self, int16_t ret):
+ return LockdownError(ret)