| 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 = plist.native_to_plist_t(value) |
| try: |
| self.handle_error(lockdownd_set_value(self._c_client, domain, key, c_node)) |
| except BaseError, e: |
| raise |
| finally: |
| if c_node != NULL: |
| plist.plist_free(c_node) |
| |
| 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) |