idevice 1.1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/NOTICE +202 -0
- data/README.md +74 -0
- data/Rakefile +37 -0
- data/examples/idevimgmount +58 -0
- data/examples/idumplockdownvalues +64 -0
- data/examples/ifetchcrashreports +54 -0
- data/examples/ilistapps +38 -0
- data/examples/ilistudids +26 -0
- data/examples/ilog +35 -0
- data/examples/installipa +51 -0
- data/examples/iremoveapp +42 -0
- data/examples/irestart +26 -0
- data/examples/iscreenshotr +39 -0
- data/idevice.gemspec +33 -0
- data/lib/idevice.rb +69 -0
- data/lib/idevice/afc.rb +518 -0
- data/lib/idevice/c.rb +129 -0
- data/lib/idevice/diagnostics_relay.rb +185 -0
- data/lib/idevice/file_relay.rb +83 -0
- data/lib/idevice/heartbeat.rb +99 -0
- data/lib/idevice/house_arrest.rb +138 -0
- data/lib/idevice/idevice.rb +208 -0
- data/lib/idevice/image_mounter.rb +117 -0
- data/lib/idevice/installation_proxy.rb +193 -0
- data/lib/idevice/lockdown.rb +350 -0
- data/lib/idevice/misagent.rb +112 -0
- data/lib/idevice/mobilebackup.rb +183 -0
- data/lib/idevice/mobilebackup2.rb +174 -0
- data/lib/idevice/mobilesync.rb +306 -0
- data/lib/idevice/notification_proxy.rb +168 -0
- data/lib/idevice/plist.rb +366 -0
- data/lib/idevice/restore.rb +176 -0
- data/lib/idevice/sbservices.rb +152 -0
- data/lib/idevice/screenshotr.rb +88 -0
- data/lib/idevice/version.rb +3 -0
- data/lib/idevice/webinspector.rb +96 -0
- data/spec/afc_devicespec.rb +409 -0
- data/spec/diagnostics_relay_devicespec.rb +125 -0
- data/spec/file_relay_devicespec.rb +45 -0
- data/spec/heartbeat_devicespec.rb +39 -0
- data/spec/idevice_devicespec.rb +93 -0
- data/spec/idevice_spec.rb +29 -0
- data/spec/image_mounter_devicespec.rb +65 -0
- data/spec/installation_proxy_devicespec.rb +54 -0
- data/spec/lockdown_devicespec.rb +106 -0
- data/spec/misagent_devicespec.rb +43 -0
- data/spec/mobilebackup2_devicespec.rb +58 -0
- data/spec/mobilebackup_devicespec.rb +41 -0
- data/spec/mobilesync_devicespec.rb +62 -0
- data/spec/notification_proxy_devicespec.rb +45 -0
- data/spec/plist_spec.rb +176 -0
- data/spec/restore_devicespec.rb +72 -0
- data/spec/samples/plist.bin +0 -0
- data/spec/samples/plist.xml +10 -0
- data/spec/sbservices_devicespec.rb +64 -0
- data/spec/screenshotr_devicespec.rb +39 -0
- data/spec/spec_helper.rb +73 -0
- data/spec/webinspector_devicespec.rb +36 -0
- metadata +233 -0
@@ -0,0 +1,193 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Eric Monti - Bluebox Security
|
3
|
+
#
|
4
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
5
|
+
# or more contributor license agreements. See the NOTICE file
|
6
|
+
# distributed with this work for additional information
|
7
|
+
# regarding copyright ownership. The ASF licenses this file
|
8
|
+
# to you under the Apache License, Version 2.0 (the
|
9
|
+
# "License"); you may not use this file except in compliance
|
10
|
+
# with the License. You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing,
|
15
|
+
# software distributed under the License is distributed on an
|
16
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
17
|
+
# KIND, either express or implied. See the License for the
|
18
|
+
# specific language governing permissions and limitations
|
19
|
+
# under the License.
|
20
|
+
|
21
|
+
require 'idevice/c'
|
22
|
+
require 'idevice/idevice'
|
23
|
+
require 'idevice/lockdown'
|
24
|
+
require 'idevice/plist'
|
25
|
+
|
26
|
+
module Idevice
|
27
|
+
class InstProxyError < IdeviceLibError
|
28
|
+
end
|
29
|
+
|
30
|
+
class InstProxyClient < C::ManagedOpaquePointer
|
31
|
+
include LibHelpers
|
32
|
+
|
33
|
+
def self.release(ptr)
|
34
|
+
C.instproxy_client_free(ptr) unless ptr.null?
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.attach(opts={})
|
38
|
+
_attach_helper("com.apple.mobile.installation_proxy", opts) do |idevice, ldsvc, p_ip|
|
39
|
+
err = C.instproxy_client_new(idevice, ldsvc, p_ip)
|
40
|
+
raise InstProxyError, "instproxy_client error: #{err}" if err != :SUCCESS
|
41
|
+
|
42
|
+
ip = p_ip.read_pointer
|
43
|
+
raise InstProxyError, "instproxy_client_new returned a NULL house_arrest_client_t pointer" if ip.null?
|
44
|
+
|
45
|
+
return new(ip)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def browse(opts={})
|
50
|
+
opts ||= {}
|
51
|
+
FFI::MemoryPointer.new(:pointer) do |p_result|
|
52
|
+
err = C.instproxy_browse(self, opts.to_plist_t, p_result)
|
53
|
+
raise InstProxyError, "instproxy_client error: #{err}" if err != :SUCCESS
|
54
|
+
|
55
|
+
result = p_result.read_pointer.read_plist_t
|
56
|
+
raise InstProxyError, "instproxy_browse returned a null plist_t" if result.nil?
|
57
|
+
|
58
|
+
return result
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def install(pkg_path, opts={}, &block)
|
63
|
+
opts ||= {}
|
64
|
+
err = C.instproxy_install(self, pkg_path, opts.to_plist_t, _cb(&block), nil)
|
65
|
+
raise InstProxyError, "instproxy_client error: #{err}" if err != :SUCCESS
|
66
|
+
|
67
|
+
return true
|
68
|
+
end
|
69
|
+
|
70
|
+
def upgrade(pkg_path, opts={}, &block)
|
71
|
+
opts ||= {}
|
72
|
+
err = C.instproxy_upgrade(self, pkg_path, opts.to_plist_t, _cb(&block), nil)
|
73
|
+
raise InstProxyError, "instproxy_client error: #{err}" if err != :SUCCESS
|
74
|
+
|
75
|
+
return true
|
76
|
+
end
|
77
|
+
|
78
|
+
def uninstall(appid, opts={}, &block)
|
79
|
+
opts ||= {}
|
80
|
+
err = C.instproxy_uninstall(self, appid, opts.to_plist_t, _cb(&block), nil)
|
81
|
+
raise InstProxyError, "instproxy_client error: #{err}" if err != :SUCCESS
|
82
|
+
|
83
|
+
return true
|
84
|
+
end
|
85
|
+
|
86
|
+
def lookup_archives(opts={})
|
87
|
+
opts ||= {}
|
88
|
+
FFI::MemoryPointer.new(:pointer) do |p_result|
|
89
|
+
err = C.instproxy_lookup_archives(self, opts.to_plist_t, p_result)
|
90
|
+
raise InstProxyError, "instproxy_client error: #{err}" if err != :SUCCESS
|
91
|
+
|
92
|
+
result = p_result.read_pointer.read_plist_t
|
93
|
+
raise InstProxyError, "instproxy_lookup_archives returned a null plist_t" if result.nil?
|
94
|
+
|
95
|
+
return result
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def archive(appid, opts={}, &block)
|
100
|
+
opts ||= {}
|
101
|
+
err = C.instproxy_archive(self, appid, opts.to_plist_t, _cb(&block), nil)
|
102
|
+
raise InstProxyError, "instproxy_client error: #{err}" if err != :SUCCESS
|
103
|
+
|
104
|
+
return true
|
105
|
+
end
|
106
|
+
|
107
|
+
def restore(appid, opts={}, &block)
|
108
|
+
opts ||= {}
|
109
|
+
err = C.instproxy_restore(self, appid, opts.to_plist_t, _cb(&block), nil)
|
110
|
+
raise InstProxyError, "instproxy_client error: #{err}" if err != :SUCCESS
|
111
|
+
|
112
|
+
return true
|
113
|
+
end
|
114
|
+
|
115
|
+
def remove_archive(appid, opts={}, &block)
|
116
|
+
opts ||= {}
|
117
|
+
err = C.instproxy_remove_archive(self, appid, opts.to_plist_t, _cb(&block), nil)
|
118
|
+
raise InstProxyError, "instproxy_client error: #{err}" if err != :SUCCESS
|
119
|
+
|
120
|
+
return true
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
def _cb(&blk)
|
125
|
+
if blk
|
126
|
+
lambda {|op, status, junk| blk.call(op, status.to_ruby) }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
module C
|
133
|
+
ffi_lib 'imobiledevice'
|
134
|
+
|
135
|
+
typedef enum(
|
136
|
+
:SUCCESS , 0,
|
137
|
+
:INVALID_ARG , -1,
|
138
|
+
:PLIST_ERROR , -2,
|
139
|
+
:CONN_FAILED , -3,
|
140
|
+
:OP_IN_PROGRESS , -4,
|
141
|
+
:OP_FAILED , -5,
|
142
|
+
:UNKNOWN_ERROR , -256,
|
143
|
+
), :instproxy_error_t
|
144
|
+
|
145
|
+
#/** Reports the status of the given operation */
|
146
|
+
#typedef void (*instproxy_status_cb_t) (const char *operation, plist_t status, void *user_data);
|
147
|
+
callback :instproxy_status_cb_t, [:string, Plist_t_Unmanaged, :pointer], :void
|
148
|
+
|
149
|
+
#/* Interface */
|
150
|
+
#instproxy_error_t instproxy_client_new(idevice_t device, lockdownd_service_descriptor_t service, instproxy_client_t *client);
|
151
|
+
attach_function :instproxy_client_new, [Idevice, LockdownServiceDescriptor, :pointer], :instproxy_error_t
|
152
|
+
|
153
|
+
#instproxy_error_t instproxy_client_free(instproxy_client_t client);
|
154
|
+
attach_function :instproxy_client_free, [InstProxyClient], :instproxy_error_t
|
155
|
+
|
156
|
+
#instproxy_error_t instproxy_browse(instproxy_client_t client, plist_t client_options, plist_t *result);
|
157
|
+
attach_function :instproxy_browse, [InstProxyClient, Plist_t, :pointer], :instproxy_error_t
|
158
|
+
|
159
|
+
#instproxy_error_t instproxy_install(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data);
|
160
|
+
attach_function :instproxy_install, [InstProxyClient, :string, Plist_t, :instproxy_status_cb_t, :pointer], :instproxy_error_t
|
161
|
+
|
162
|
+
#instproxy_error_t instproxy_upgrade(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data);
|
163
|
+
attach_function :instproxy_upgrade, [InstProxyClient, :string, Plist_t, :instproxy_status_cb_t, :pointer], :instproxy_error_t
|
164
|
+
|
165
|
+
#instproxy_error_t instproxy_uninstall(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data);
|
166
|
+
attach_function :instproxy_uninstall, [InstProxyClient, :string, Plist_t, :instproxy_status_cb_t, :pointer], :instproxy_error_t
|
167
|
+
|
168
|
+
#instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist_t client_options, plist_t *result);
|
169
|
+
attach_function :instproxy_lookup_archives, [InstProxyClient, Plist_t, :pointer], :instproxy_error_t
|
170
|
+
|
171
|
+
#instproxy_error_t instproxy_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data);
|
172
|
+
attach_function :instproxy_archive, [InstProxyClient, :string, Plist_t, :instproxy_status_cb_t, :pointer], :instproxy_error_t
|
173
|
+
|
174
|
+
#instproxy_error_t instproxy_restore(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data);
|
175
|
+
attach_function :instproxy_restore, [InstProxyClient, :string, Plist_t, :instproxy_status_cb_t, :pointer], :instproxy_error_t
|
176
|
+
|
177
|
+
#instproxy_error_t instproxy_remove_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data);
|
178
|
+
attach_function :instproxy_remove_archive, [InstProxyClient, :string, Plist_t, :instproxy_status_cb_t, :pointer], :instproxy_error_t
|
179
|
+
|
180
|
+
|
181
|
+
### favor use of regular plist_t over the less rubyful instproxy_client_options interface
|
182
|
+
|
183
|
+
#plist_t instproxy_client_options_new();
|
184
|
+
#attach_function :instproxy_client_options_new, [], Plist_t
|
185
|
+
|
186
|
+
#void instproxy_client_options_add(plist_t client_options, ...);
|
187
|
+
#attach_function :instproxy_client_options_add, [Plist_t, :varargs], :void
|
188
|
+
|
189
|
+
#void instproxy_client_options_free(plist_t client_options);
|
190
|
+
#attach_function :instproxy_client_options_free, [Plist_t], :void
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,350 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Eric Monti - Bluebox Security
|
3
|
+
#
|
4
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
5
|
+
# or more contributor license agreements. See the NOTICE file
|
6
|
+
# distributed with this work for additional information
|
7
|
+
# regarding copyright ownership. The ASF licenses this file
|
8
|
+
# to you under the Apache License, Version 2.0 (the
|
9
|
+
# "License"); you may not use this file except in compliance
|
10
|
+
# with the License. You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing,
|
15
|
+
# software distributed under the License is distributed on an
|
16
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
17
|
+
# KIND, either express or implied. See the License for the
|
18
|
+
# specific language governing permissions and limitations
|
19
|
+
# under the License.
|
20
|
+
|
21
|
+
require 'idevice/c'
|
22
|
+
require 'idevice/plist'
|
23
|
+
require 'idevice/idevice'
|
24
|
+
|
25
|
+
module Idevice
|
26
|
+
class LockdownError < IdeviceLibError
|
27
|
+
end
|
28
|
+
|
29
|
+
# Used to manage device preferences, start services, pairing and activation on the device.
|
30
|
+
class LockdownClient < C::ManagedOpaquePointer
|
31
|
+
def self.release(ptr)
|
32
|
+
C.lockdownd_client_free(ptr) unless ptr.null?
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.attach(opts={})
|
36
|
+
idevice = opts[:idevice] || Idevice.attach(opts)
|
37
|
+
|
38
|
+
label = opts[:label] || "ruby-idevice"
|
39
|
+
|
40
|
+
FFI::MemoryPointer.new(:pointer) do |p_lockdown_client|
|
41
|
+
err =
|
42
|
+
if opts[:nohandshake]
|
43
|
+
C.lockdownd_client_new(idevice, p_lockdown_client, label)
|
44
|
+
else
|
45
|
+
C.lockdownd_client_new_with_handshake(idevice, p_lockdown_client, label)
|
46
|
+
end
|
47
|
+
|
48
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
49
|
+
|
50
|
+
lockdown_client = p_lockdown_client.read_pointer
|
51
|
+
if lockdown_client.null?
|
52
|
+
raise LockdownError, "lockdownd_client creation returned a NULL object"
|
53
|
+
else
|
54
|
+
return new(lockdown_client)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def device_udid
|
60
|
+
res = nil
|
61
|
+
FFI::MemoryPointer.new(:pointer) do |p_udid|
|
62
|
+
err = C.lockdownd_get_device_udid(self, p_udid)
|
63
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
64
|
+
|
65
|
+
udid = p_udid.read_pointer
|
66
|
+
unless udid.null?
|
67
|
+
res = udid.read_string
|
68
|
+
C.free(udid)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
return res
|
72
|
+
end
|
73
|
+
|
74
|
+
def device_name
|
75
|
+
res = nil
|
76
|
+
FFI::MemoryPointer.new(:pointer) do |p_name|
|
77
|
+
err = C.lockdownd_get_device_name(self, p_name)
|
78
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
79
|
+
|
80
|
+
name = p_name.read_pointer
|
81
|
+
unless name.null?
|
82
|
+
res = name.read_string
|
83
|
+
C.free(name)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
return res
|
87
|
+
end
|
88
|
+
|
89
|
+
def sync_data_classes
|
90
|
+
res = nil
|
91
|
+
FFI::MemoryPointer.new(:pointer) do |p_sync_classes|
|
92
|
+
FFI::MemoryPointer.new(:int) do |p_count|
|
93
|
+
err = C.lockdownd_get_sync_data_classes(self, p_sync_classes, p_count)
|
94
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
95
|
+
|
96
|
+
sync_classes = p_sync_classes.read_pointer
|
97
|
+
count = p_count.read_int
|
98
|
+
unless sync_classes.null?
|
99
|
+
res = sync_classes.read_array_of_pointer(count).map{|p| p.read_string }
|
100
|
+
err = C.lockdownd_data_classes_free(sync_classes)
|
101
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
return res
|
106
|
+
end
|
107
|
+
|
108
|
+
def query_type
|
109
|
+
res = nil
|
110
|
+
FFI::MemoryPointer.new(:pointer) do |p_type|
|
111
|
+
err = C.lockdownd_query_type(self, p_type)
|
112
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
113
|
+
|
114
|
+
type = p_type.read_pointer
|
115
|
+
res = type.read_string
|
116
|
+
C.free(type)
|
117
|
+
end
|
118
|
+
return res
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_value(domain, key)
|
122
|
+
res = nil
|
123
|
+
FFI::MemoryPointer.new(:pointer) do |p_val|
|
124
|
+
err = C.lockdownd_get_value(self, domain, key, p_val)
|
125
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
126
|
+
|
127
|
+
res = p_val.read_pointer.read_plist_t
|
128
|
+
end
|
129
|
+
return res
|
130
|
+
end
|
131
|
+
|
132
|
+
def set_value(domain, key, value)
|
133
|
+
err = C.lockdownd_set_value(self, domain, key, Plist_t.from_ruby(value))
|
134
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
135
|
+
return true
|
136
|
+
end
|
137
|
+
|
138
|
+
def remove_value(domain, key)
|
139
|
+
err = C.lockdownd_remove_value(self, domain, key)
|
140
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
141
|
+
return true
|
142
|
+
end
|
143
|
+
|
144
|
+
def start_service(identifier)
|
145
|
+
ret = nil
|
146
|
+
FFI::MemoryPointer.new(:pointer) do |p_ldsvc|
|
147
|
+
err = C.lockdownd_start_service(self, identifier, p_ldsvc)
|
148
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
149
|
+
|
150
|
+
ldsvc = p_ldsvc.read_pointer
|
151
|
+
unless ldsvc.null?
|
152
|
+
ret = LockdownServiceDescriptor.new(ldsvc)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
return ret
|
156
|
+
end
|
157
|
+
|
158
|
+
def send_plist(obj)
|
159
|
+
err = C.lockdownd_send(self, Plist_t.from_ruby(obj))
|
160
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
161
|
+
|
162
|
+
return true
|
163
|
+
end
|
164
|
+
|
165
|
+
def receive_plist
|
166
|
+
ret = nil
|
167
|
+
FFI::MemoryPointer.new(:pointer) do |p_plist|
|
168
|
+
err = C.lockdownd_receive(self, p_plist)
|
169
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
170
|
+
|
171
|
+
ret = p_plist.read_pointer.read_plist_t
|
172
|
+
end
|
173
|
+
return ret
|
174
|
+
end
|
175
|
+
|
176
|
+
def pair(pair_record)
|
177
|
+
raise TypeError, "pair_record must be a LockdownPairRecord" unless pair_record.is_a?(LockdownPairRecord)
|
178
|
+
err = C.lockdownd_pair(self, pair_record)
|
179
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
180
|
+
return true
|
181
|
+
end
|
182
|
+
|
183
|
+
def validate_pair(pair_record)
|
184
|
+
raise TypeError, "pair_record must be a LockdownPairRecord" unless pair_record.is_a?(LockdownPairRecord)
|
185
|
+
err = C.lockdownd_validate_pair(self, pair_record)
|
186
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
187
|
+
return true
|
188
|
+
end
|
189
|
+
|
190
|
+
def unpair(pair_record)
|
191
|
+
raise TypeError, "pair_record must be a LockdownPairRecord" unless pair_record.is_a?(LockdownPairRecord)
|
192
|
+
err = C.lockdownd_unpair(self, pair_record)
|
193
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
194
|
+
return true
|
195
|
+
end
|
196
|
+
|
197
|
+
def activate(activation_record)
|
198
|
+
err = C.lockdownd_activate(self, Plist_t.from_ruby(activation_record))
|
199
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
200
|
+
return true
|
201
|
+
end
|
202
|
+
|
203
|
+
def deactivate
|
204
|
+
err = C.lockdownd_deactivate(self)
|
205
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
206
|
+
return true
|
207
|
+
end
|
208
|
+
|
209
|
+
def enter_recovery
|
210
|
+
err = C.lockdownd_enter_recovery(self)
|
211
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
212
|
+
return true
|
213
|
+
end
|
214
|
+
|
215
|
+
def goodbye
|
216
|
+
err = C.lockdownd_goodbye(self)
|
217
|
+
raise LockdownError, "Lockdownd error: #{err}" if err != :SUCCESS
|
218
|
+
return true
|
219
|
+
end
|
220
|
+
|
221
|
+
def set_label(label)
|
222
|
+
C.lockdownd_client_set_label(self, label)
|
223
|
+
return true
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
class LockdownPairRecord < FFI::Struct
|
228
|
+
layout(
|
229
|
+
:device_certificate, :string,
|
230
|
+
:host_certificate, :string,
|
231
|
+
:host_id, :string,
|
232
|
+
:root_certificate, :string,
|
233
|
+
)
|
234
|
+
end
|
235
|
+
|
236
|
+
class LockdownServiceDescriptor < FFI::ManagedStruct
|
237
|
+
layout(
|
238
|
+
:port, :uint16,
|
239
|
+
:ssl_enabled, :uint8,
|
240
|
+
)
|
241
|
+
|
242
|
+
def self.release(ptr)
|
243
|
+
C::lockdownd_service_descriptor_free(ptr)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
module C
|
248
|
+
ffi_lib 'imobiledevice'
|
249
|
+
|
250
|
+
typedef enum(
|
251
|
+
:SUCCESS , 0,
|
252
|
+
:INVALID_ARG , -1,
|
253
|
+
:INVALID_CONF , -2,
|
254
|
+
:PLIST_ERROR , -3,
|
255
|
+
:PAIRING_FAILED , -4,
|
256
|
+
:SSL_ERROR , -5,
|
257
|
+
:DICT_ERROR , -6,
|
258
|
+
:START_SERVICE_FAILED , -7,
|
259
|
+
:NOT_ENOUGH_DATA , -8,
|
260
|
+
:SET_VALUE_PROHIBITED , -9,
|
261
|
+
:GET_VALUE_PROHIBITED ,-10,
|
262
|
+
:REMOVE_VALUE_PROHIBITED ,-11,
|
263
|
+
:MUX_ERROR ,-12,
|
264
|
+
:ACTIVATION_FAILED ,-13,
|
265
|
+
:PASSWORD_PROTECTED ,-14,
|
266
|
+
:NO_RUNNING_SESSION ,-15,
|
267
|
+
:INVALID_HOST_ID ,-16,
|
268
|
+
:INVALID_SERVICE ,-17,
|
269
|
+
:INVALID_ACTIVATION_RECORD,-18,
|
270
|
+
:UNKNOWN_ERROR ,-256,
|
271
|
+
), :lockdownd_error_t
|
272
|
+
|
273
|
+
typedef :pointer, :lockdownd_client_t
|
274
|
+
|
275
|
+
#lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label);
|
276
|
+
attach_function :lockdownd_client_new, [Idevice, :pointer, :string], :lockdownd_error_t
|
277
|
+
|
278
|
+
#lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, const char *label);
|
279
|
+
attach_function :lockdownd_client_new_with_handshake, [Idevice, :pointer, :string], :lockdownd_error_t
|
280
|
+
|
281
|
+
#lockdownd_error_t lockdownd_client_free(lockdownd_client_t client);
|
282
|
+
attach_function :lockdownd_client_free, [LockdownClient], :lockdownd_error_t
|
283
|
+
|
284
|
+
#lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **type);
|
285
|
+
attach_function :lockdownd_query_type, [LockdownClient, :pointer], :lockdownd_error_t
|
286
|
+
|
287
|
+
#lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value);
|
288
|
+
attach_function :lockdownd_get_value, [LockdownClient, :string, :string, :pointer], :lockdownd_error_t
|
289
|
+
|
290
|
+
#lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value);
|
291
|
+
attach_function :lockdownd_set_value, [LockdownClient, :string, :string, Plist_t], :lockdownd_error_t
|
292
|
+
|
293
|
+
#lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key);
|
294
|
+
attach_function :lockdownd_remove_value, [LockdownClient, :string, :string], :lockdownd_error_t
|
295
|
+
|
296
|
+
#lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *identifier, lockdownd_service_descriptor_t *service);
|
297
|
+
attach_function :lockdownd_start_service, [LockdownClient, :string, :pointer], :lockdownd_error_t
|
298
|
+
|
299
|
+
#lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char *host_id, char **session_id, int *ssl_enabled);
|
300
|
+
attach_function :lockdownd_start_session, [LockdownClient, :string, :pointer, :pointer], :lockdownd_error_t
|
301
|
+
|
302
|
+
#lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *session_id);
|
303
|
+
attach_function :lockdownd_stop_session, [LockdownClient, :string], :lockdownd_error_t
|
304
|
+
|
305
|
+
#lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist);
|
306
|
+
attach_function :lockdownd_send, [LockdownClient, Plist_t], :lockdownd_error_t
|
307
|
+
|
308
|
+
#lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist_t *plist);
|
309
|
+
attach_function :lockdownd_receive, [LockdownClient, :pointer], :lockdownd_error_t
|
310
|
+
|
311
|
+
#lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record);
|
312
|
+
attach_function :lockdownd_pair, [LockdownClient, LockdownPairRecord], :lockdownd_error_t
|
313
|
+
|
314
|
+
#lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record);
|
315
|
+
attach_function :lockdownd_validate_pair, [LockdownClient, LockdownPairRecord], :lockdownd_error_t
|
316
|
+
|
317
|
+
#lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record);
|
318
|
+
attach_function :lockdownd_unpair, [LockdownClient, LockdownPairRecord], :lockdownd_error_t
|
319
|
+
|
320
|
+
#lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record);
|
321
|
+
attach_function :lockdownd_activate, [LockdownClient, Plist_t], :lockdownd_error_t
|
322
|
+
|
323
|
+
#lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client);
|
324
|
+
attach_function :lockdownd_deactivate, [LockdownClient], :lockdownd_error_t
|
325
|
+
|
326
|
+
#lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client);
|
327
|
+
attach_function :lockdownd_enter_recovery, [LockdownClient], :lockdownd_error_t
|
328
|
+
|
329
|
+
#lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client);
|
330
|
+
attach_function :lockdownd_goodbye, [LockdownClient], :lockdownd_error_t
|
331
|
+
|
332
|
+
#void lockdownd_client_set_label(lockdownd_client_t client, const char *label);
|
333
|
+
attach_function :lockdownd_client_set_label, [LockdownClient, :string], :void
|
334
|
+
|
335
|
+
#lockdownd_error_t lockdownd_get_device_udid(lockdownd_client_t control, char **udid);
|
336
|
+
attach_function :lockdownd_get_device_udid, [LockdownClient, :pointer], :lockdownd_error_t
|
337
|
+
|
338
|
+
#lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name);
|
339
|
+
attach_function :lockdownd_get_device_name, [LockdownClient, :pointer], :lockdownd_error_t
|
340
|
+
|
341
|
+
#lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count);
|
342
|
+
attach_function :lockdownd_get_sync_data_classes, [LockdownClient, :pointer, :pointer], :lockdownd_error_t
|
343
|
+
|
344
|
+
#lockdownd_error_t lockdownd_data_classes_free(char **classes);
|
345
|
+
attach_function :lockdownd_data_classes_free, [:pointer], :lockdownd_error_t
|
346
|
+
|
347
|
+
#lockdownd_error_t lockdownd_service_descriptor_free(lockdownd_service_descriptor_t service);
|
348
|
+
attach_function :lockdownd_service_descriptor_free, [LockdownServiceDescriptor], :lockdownd_error_t
|
349
|
+
end
|
350
|
+
end
|