diff options
Diffstat (limited to 'tools/idevicepair.c')
-rw-r--r-- | tools/idevicepair.c | 473 |
1 files changed, 345 insertions, 128 deletions
diff --git a/tools/idevicepair.c b/tools/idevicepair.c index b9676b9..94d3f04 100644 --- a/tools/idevicepair.c +++ b/tools/idevicepair.c | |||
@@ -1,114 +1,314 @@ | |||
1 | /* | 1 | /* |
2 | * idevicepair.c | 2 | * idevicepair.c |
3 | * Simple utility to pair/unpair an iDevice | 3 | * Manage pairings with devices and this host |
4 | * | 4 | * |
5 | * Copyright (c) 2010 Nikias Bassen All Rights Reserved. | 5 | * Copyright (c) 2010-2021 Nikias Bassen, All Rights Reserved. |
6 | * Copyright (c) 2014 Martin Szulecki, All Rights Reserved. | ||
6 | * | 7 | * |
7 | * This library is free software; you can redistribute it and/or | 8 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public | 9 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either | 10 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. | 11 | * version 2.1 of the License, or (at your option) any later version. |
11 | * | 12 | * |
12 | * This library is distributed in the hope that it will be useful, | 13 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. | 16 | * Lesser General Public License for more details. |
16 | * | 17 | * |
17 | * You should have received a copy of the GNU Lesser General Public | 18 | * You should have received a copy of the GNU Lesser General Public |
18 | * License along with this library; if not, write to the Free Software | 19 | * License along with this library; if not, write to the Free Software |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ | 21 | */ |
21 | 22 | ||
23 | #ifdef HAVE_CONFIG_H | ||
24 | #include <config.h> | ||
25 | #endif | ||
26 | |||
27 | #define TOOL_NAME "idevicepair" | ||
28 | |||
22 | #include <stdio.h> | 29 | #include <stdio.h> |
23 | #include <string.h> | 30 | #include <string.h> |
24 | #include <stdlib.h> | 31 | #include <stdlib.h> |
25 | #include <getopt.h> | 32 | #include <getopt.h> |
26 | #include "userpref.h" | 33 | #include <ctype.h> |
34 | #include <unistd.h> | ||
35 | #ifdef WIN32 | ||
36 | #include <windows.h> | ||
37 | #include <conio.h> | ||
38 | #else | ||
39 | #include <termios.h> | ||
40 | #include <signal.h> | ||
41 | #endif | ||
42 | |||
43 | #include "common/userpref.h" | ||
27 | 44 | ||
28 | #include <libimobiledevice/libimobiledevice.h> | 45 | #include <libimobiledevice/libimobiledevice.h> |
29 | #include <libimobiledevice/lockdown.h> | 46 | #include <libimobiledevice/lockdown.h> |
47 | #include <plist/plist.h> | ||
48 | |||
49 | static char *udid = NULL; | ||
30 | 50 | ||
31 | static char *uuid = NULL; | 51 | #ifdef HAVE_WIRELESS_PAIRING |
32 | 52 | ||
33 | static void print_usage(int argc, char **argv) | 53 | #ifdef WIN32 |
54 | #define BS_CC '\b' | ||
55 | #define my_getch getch | ||
56 | #else | ||
57 | #define BS_CC 0x7f | ||
58 | static int my_getch(void) | ||
34 | { | 59 | { |
35 | char *name = NULL; | 60 | struct termios oldt, newt; |
36 | 61 | int ch; | |
37 | name = strrchr(argv[0], '/'); | 62 | tcgetattr(STDIN_FILENO, &oldt); |
38 | printf("\n%s - Manage pairings with iPhone/iPod Touch/iPad devices and this host.\n\n", (name ? name + 1: argv[0])); | 63 | newt = oldt; |
39 | printf("Usage: %s [OPTIONS] COMMAND\n\n", (name ? name + 1: argv[0])); | 64 | newt.c_lflag &= ~(ICANON | ECHO); |
40 | printf(" Where COMMAND is one of:\n"); | 65 | tcsetattr(STDIN_FILENO, TCSANOW, &newt); |
41 | printf(" hostid print the host id of this computer\n"); | 66 | ch = getchar(); |
42 | printf(" pair pair device with this computer\n"); | 67 | tcsetattr(STDIN_FILENO, TCSANOW, &oldt); |
43 | printf(" validate validate if device is paired with this computer\n"); | 68 | return ch; |
44 | printf(" unpair unpair device with this computer\n"); | ||
45 | printf(" list list devices paired with this computer\n\n"); | ||
46 | printf(" The following OPTIONS are accepted:\n"); | ||
47 | printf(" -d, --debug enable communication debugging\n"); | ||
48 | printf(" -u, --uuid UUID target specific device by its 40-digit device UUID\n"); | ||
49 | printf(" -h, --help prints usage information\n"); | ||
50 | printf("\n"); | ||
51 | } | 69 | } |
70 | #endif | ||
52 | 71 | ||
53 | static void parse_opts(int argc, char **argv) | 72 | static int get_hidden_input(char *buf, int maxlen) |
54 | { | 73 | { |
55 | static struct option longopts[] = { | 74 | int pwlen = 0; |
56 | {"help", 0, NULL, 'h'}, | ||
57 | {"uuid", 1, NULL, 'u'}, | ||
58 | {"debug", 0, NULL, 'd'}, | ||
59 | {NULL, 0, NULL, 0} | ||
60 | }; | ||
61 | int c; | 75 | int c; |
62 | 76 | ||
63 | while (1) { | 77 | while ((c = my_getch())) { |
64 | c = getopt_long(argc, argv, "hu:d", longopts, (int*)0); | 78 | if ((c == '\r') || (c == '\n')) { |
65 | if (c == -1) { | ||
66 | break; | 79 | break; |
80 | } else if (isprint(c)) { | ||
81 | if (pwlen < maxlen-1) | ||
82 | buf[pwlen++] = c; | ||
83 | fputc('*', stderr); | ||
84 | } else if (c == BS_CC) { | ||
85 | if (pwlen > 0) { | ||
86 | fputs("\b \b", stderr); | ||
87 | pwlen--; | ||
88 | } | ||
67 | } | 89 | } |
90 | } | ||
91 | buf[pwlen] = 0; | ||
92 | return pwlen; | ||
93 | } | ||
68 | 94 | ||
69 | switch (c) { | 95 | static void pairing_cb(lockdownd_cu_pairing_cb_type_t cb_type, void *user_data, void* data_ptr, unsigned int* data_size) |
70 | case 'h': | 96 | { |
71 | print_usage(argc, argv); | 97 | if (cb_type == LOCKDOWN_CU_PAIRING_PIN_REQUESTED) { |
72 | exit(EXIT_SUCCESS); | 98 | printf("Enter PIN: "); |
73 | case 'u': | 99 | fflush(stdout); |
74 | if (strlen(optarg) != 40) { | 100 | |
75 | printf("%s: invalid UUID specified (length != 40)\n", argv[0]); | 101 | *data_size = get_hidden_input((char*)data_ptr, *data_size); |
76 | print_usage(argc, argv); | 102 | |
77 | exit(2); | 103 | printf("\n"); |
78 | } | 104 | } else if (cb_type == LOCKDOWN_CU_PAIRING_DEVICE_INFO) { |
79 | uuid = strdup(optarg); | 105 | printf("Device info:\n"); |
106 | plist_write_to_stream((plist_t)data_ptr, stdout, PLIST_FORMAT_LIMD, PLIST_OPT_INDENT | PLIST_OPT_INDENT_BY(2)); | ||
107 | } else if (cb_type == LOCKDOWN_CU_PAIRING_ERROR) { | ||
108 | printf("ERROR: %s\n", (data_ptr) ? (char*)data_ptr : "(unknown)"); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | #endif /* HAVE_WIRELESS_PAIRING */ | ||
113 | |||
114 | static void print_error_message(lockdownd_error_t err) | ||
115 | { | ||
116 | switch (err) { | ||
117 | case LOCKDOWN_E_PASSWORD_PROTECTED: | ||
118 | printf("ERROR: Could not validate with device %s because a passcode is set. Please enter the passcode on the device and retry.\n", udid); | ||
80 | break; | 119 | break; |
81 | case 'd': | 120 | case LOCKDOWN_E_INVALID_CONF: |
82 | idevice_set_debug_level(1); | 121 | case LOCKDOWN_E_INVALID_HOST_ID: |
122 | printf("ERROR: Device %s is not paired with this host\n", udid); | ||
123 | break; | ||
124 | case LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING: | ||
125 | printf("ERROR: Please accept the trust dialog on the screen of device %s, then attempt to pair again.\n", udid); | ||
126 | break; | ||
127 | case LOCKDOWN_E_USER_DENIED_PAIRING: | ||
128 | printf("ERROR: Device %s said that the user denied the trust dialog.\n", udid); | ||
129 | break; | ||
130 | case LOCKDOWN_E_PAIRING_FAILED: | ||
131 | printf("ERROR: Pairing with device %s failed.\n", udid); | ||
132 | break; | ||
133 | case LOCKDOWN_E_GET_PROHIBITED: | ||
134 | case LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION: | ||
135 | printf("ERROR: Pairing is not possible over this connection.\n"); | ||
136 | #ifdef HAVE_WIRELESS_PAIRING | ||
137 | printf("To perform a wireless pairing use the -w command line switch. See usage or man page for details.\n"); | ||
138 | #endif | ||
83 | break; | 139 | break; |
84 | default: | 140 | default: |
85 | print_usage(argc, argv); | 141 | printf("ERROR: Device %s returned unhandled error code %d\n", udid, err); |
86 | exit(EXIT_SUCCESS); | 142 | break; |
87 | } | ||
88 | } | 143 | } |
89 | } | 144 | } |
90 | 145 | ||
146 | static void print_usage(int argc, char **argv, int is_error) | ||
147 | { | ||
148 | char *name = strrchr(argv[0], '/'); | ||
149 | fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0])); | ||
150 | fprintf(is_error ? stderr : stdout, | ||
151 | "\n" | ||
152 | "Manage host pairings with devices and usbmuxd.\n" | ||
153 | "\n" | ||
154 | "Where COMMAND is one of:\n" | ||
155 | " systembuid print the system buid of the usbmuxd host\n" | ||
156 | " hostid print the host id for target device\n" | ||
157 | " pair pair device with this host\n" | ||
158 | " validate validate if device is paired with this host\n" | ||
159 | " unpair unpair device with this host\n" | ||
160 | " list list devices paired with this host\n" | ||
161 | "\n" | ||
162 | "The following OPTIONS are accepted:\n" | ||
163 | " -u, --udid UDID target specific device by UDID\n" | ||
164 | ); | ||
165 | #ifdef HAVE_WIRELESS_PAIRING | ||
166 | fprintf(is_error ? stderr : stdout, | ||
167 | " -w, --wireless perform wireless pairing (see NOTE)\n" | ||
168 | " -n, --network connect to network device (see NOTE)\n" | ||
169 | ); | ||
170 | #endif | ||
171 | fprintf(is_error ? stderr : stdout, | ||
172 | " -d, --debug enable communication debugging\n" | ||
173 | " -h, --help prints usage information\n" | ||
174 | " -v, --version prints version information\n" | ||
175 | ); | ||
176 | #ifdef HAVE_WIRELESS_PAIRING | ||
177 | fprintf(is_error ? stderr : stdout, | ||
178 | "\n" | ||
179 | "NOTE: Pairing over network (wireless pairing) is only supported by Apple TV\n" | ||
180 | "devices. To perform a wireless pairing, you need to use the -w command line\n" | ||
181 | "switch. Make sure to put the device into pairing mode first by opening\n" | ||
182 | "Settings > Remotes and Devices > Remote App and Devices.\n" | ||
183 | ); | ||
184 | #endif | ||
185 | fprintf(is_error ? stderr : stdout, | ||
186 | "\n" | ||
187 | "Homepage: <" PACKAGE_URL ">\n" | ||
188 | "Bug Reports: <" PACKAGE_BUGREPORT ">\n" | ||
189 | ); | ||
190 | } | ||
191 | |||
91 | int main(int argc, char **argv) | 192 | int main(int argc, char **argv) |
92 | { | 193 | { |
194 | int c = 0; | ||
195 | static struct option longopts[] = { | ||
196 | { "help", no_argument, NULL, 'h' }, | ||
197 | { "udid", required_argument, NULL, 'u' }, | ||
198 | #ifdef HAVE_WIRELESS_PAIRING | ||
199 | { "wireless", no_argument, NULL, 'w' }, | ||
200 | { "network", no_argument, NULL, 'n' }, | ||
201 | { "hostinfo", required_argument, NULL, 1 }, | ||
202 | #endif | ||
203 | { "debug", no_argument, NULL, 'd' }, | ||
204 | { "version", no_argument, NULL, 'v' }, | ||
205 | { NULL, 0, NULL, 0} | ||
206 | }; | ||
207 | #ifdef HAVE_WIRELESS_PAIRING | ||
208 | #define SHORT_OPTIONS "hu:wndv" | ||
209 | #else | ||
210 | #define SHORT_OPTIONS "hu:dv" | ||
211 | #endif | ||
93 | lockdownd_client_t client = NULL; | 212 | lockdownd_client_t client = NULL; |
94 | idevice_t phone = NULL; | 213 | idevice_t device = NULL; |
95 | idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; | 214 | idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; |
96 | lockdownd_error_t lerr; | 215 | lockdownd_error_t lerr; |
97 | int result; | 216 | int result; |
98 | 217 | ||
99 | char *type = NULL; | 218 | char *type = NULL; |
219 | int use_network = 0; | ||
220 | int wireless_pairing = 0; | ||
221 | #ifdef HAVE_WIRELESS_PAIRING | ||
222 | plist_t host_info_plist = NULL; | ||
223 | #endif | ||
100 | char *cmd; | 224 | char *cmd; |
101 | typedef enum { | 225 | typedef enum { |
102 | OP_NONE = 0, OP_PAIR, OP_VALIDATE, OP_UNPAIR, OP_LIST, OP_HOSTID | 226 | OP_NONE = 0, OP_PAIR, OP_VALIDATE, OP_UNPAIR, OP_LIST, OP_HOSTID, OP_SYSTEMBUID |
103 | } op_t; | 227 | } op_t; |
104 | op_t op = OP_NONE; | 228 | op_t op = OP_NONE; |
105 | 229 | ||
106 | parse_opts(argc, argv); | 230 | while ((c = getopt_long(argc, argv, SHORT_OPTIONS, longopts, NULL)) != -1) { |
231 | switch (c) { | ||
232 | case 'h': | ||
233 | print_usage(argc, argv, 0); | ||
234 | exit(EXIT_SUCCESS); | ||
235 | case 'u': | ||
236 | if (!*optarg) { | ||
237 | fprintf(stderr, "ERROR: UDID must not be empty!\n"); | ||
238 | print_usage(argc, argv, 1); | ||
239 | result = EXIT_FAILURE; | ||
240 | goto leave; | ||
241 | } | ||
242 | free(udid); | ||
243 | udid = strdup(optarg); | ||
244 | break; | ||
245 | #ifdef HAVE_WIRELESS_PAIRING | ||
246 | case 'w': | ||
247 | wireless_pairing = 1; | ||
248 | break; | ||
249 | case 'n': | ||
250 | use_network = 1; | ||
251 | break; | ||
252 | case 1: | ||
253 | if (!*optarg) { | ||
254 | fprintf(stderr, "ERROR: --hostinfo argument must not be empty!\n"); | ||
255 | result = EXIT_FAILURE; | ||
256 | goto leave; | ||
257 | } | ||
258 | if (*optarg == '@') { | ||
259 | plist_read_from_file(optarg+1, &host_info_plist, NULL); | ||
260 | if (!host_info_plist) { | ||
261 | fprintf(stderr, "ERROR: Could not read from file '%s'\n", optarg+1); | ||
262 | result = EXIT_FAILURE; | ||
263 | goto leave; | ||
264 | } | ||
265 | } | ||
266 | #ifdef HAVE_PLIST_JSON | ||
267 | else if (*optarg == '{') { | ||
268 | if (plist_from_json(optarg, strlen(optarg), &host_info_plist) != PLIST_ERR_SUCCESS) { | ||
269 | fprintf(stderr, "ERROR: --hostinfo argument not valid. Make sure it is a JSON dictionary.\n"); | ||
270 | result = EXIT_FAILURE; | ||
271 | goto leave; | ||
272 | } | ||
273 | } | ||
274 | #endif | ||
275 | else { | ||
276 | fprintf(stderr, "ERROR: --hostinfo argument not valid. To specify a path prefix with '@'\n"); | ||
277 | result = EXIT_FAILURE; | ||
278 | goto leave; | ||
279 | } | ||
280 | break; | ||
281 | #endif | ||
282 | case 'd': | ||
283 | idevice_set_debug_level(1); | ||
284 | break; | ||
285 | case 'v': | ||
286 | printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION); | ||
287 | result = EXIT_SUCCESS; | ||
288 | goto leave; | ||
289 | default: | ||
290 | print_usage(argc, argv, 1); | ||
291 | result = EXIT_FAILURE; | ||
292 | goto leave; | ||
293 | } | ||
294 | } | ||
295 | |||
296 | #ifndef WIN32 | ||
297 | signal(SIGPIPE, SIG_IGN); | ||
298 | #endif | ||
107 | 299 | ||
108 | if ((argc - optind) < 1) { | 300 | if ((argc - optind) < 1) { |
109 | printf("ERROR: You need to specify a COMMAND!\n"); | 301 | fprintf(stderr, "ERROR: You need to specify a COMMAND!\n"); |
110 | print_usage(argc, argv); | 302 | print_usage(argc, argv, 1); |
111 | exit(EXIT_FAILURE); | 303 | result = EXIT_FAILURE; |
304 | goto leave; | ||
305 | } | ||
306 | |||
307 | if (wireless_pairing && use_network) { | ||
308 | fprintf(stderr, "ERROR: You cannot use -w and -n together.\n"); | ||
309 | print_usage(argc, argv, 1); | ||
310 | result = EXIT_FAILURE; | ||
311 | goto leave; | ||
112 | } | 312 | } |
113 | 313 | ||
114 | cmd = (argv+optind)[0]; | 314 | cmd = (argv+optind)[0]; |
@@ -123,60 +323,91 @@ int main(int argc, char **argv) | |||
123 | op = OP_LIST; | 323 | op = OP_LIST; |
124 | } else if (!strcmp(cmd, "hostid")) { | 324 | } else if (!strcmp(cmd, "hostid")) { |
125 | op = OP_HOSTID; | 325 | op = OP_HOSTID; |
326 | } else if (!strcmp(cmd, "systembuid")) { | ||
327 | op = OP_SYSTEMBUID; | ||
126 | } else { | 328 | } else { |
127 | printf("ERROR: Invalid command '%s' specified\n", cmd); | 329 | fprintf(stderr, "ERROR: Invalid command '%s' specified\n", cmd); |
128 | print_usage(argc, argv); | 330 | print_usage(argc, argv, 1); |
129 | exit(EXIT_FAILURE); | 331 | result = EXIT_FAILURE; |
332 | goto leave; | ||
130 | } | 333 | } |
131 | 334 | ||
132 | if (op == OP_HOSTID) { | 335 | if (wireless_pairing) { |
133 | char *hostid = NULL; | 336 | if (op == OP_VALIDATE || op == OP_UNPAIR) { |
134 | userpref_get_host_id(&hostid); | 337 | fprintf(stderr, "ERROR: Command '%s' is not supported with -w\n", cmd); |
338 | print_usage(argc, argv, 1); | ||
339 | result = EXIT_FAILURE; | ||
340 | goto leave; | ||
341 | } | ||
342 | use_network = 1; | ||
343 | } | ||
135 | 344 | ||
136 | printf("%s\n", hostid); | 345 | if (op == OP_SYSTEMBUID) { |
346 | char *systembuid = NULL; | ||
347 | userpref_read_system_buid(&systembuid); | ||
137 | 348 | ||
138 | if (hostid) | 349 | printf("%s\n", systembuid); |
139 | free(hostid); | ||
140 | 350 | ||
141 | return EXIT_SUCCESS; | 351 | free(systembuid); |
352 | |||
353 | result = EXIT_SUCCESS; | ||
354 | goto leave; | ||
142 | } | 355 | } |
143 | 356 | ||
144 | if (op == OP_LIST) { | 357 | if (op == OP_LIST) { |
145 | unsigned int i; | 358 | unsigned int i; |
146 | char **uuids = NULL; | 359 | char **udids = NULL; |
147 | unsigned int count = 0; | 360 | unsigned int count = 0; |
148 | userpref_get_paired_uuids(&uuids, &count); | 361 | userpref_get_paired_udids(&udids, &count); |
149 | for (i = 0; i < count; i++) { | 362 | for (i = 0; i < count; i++) { |
150 | printf("%s\n", uuids[i]); | 363 | printf("%s\n", udids[i]); |
364 | free(udids[i]); | ||
151 | } | 365 | } |
152 | if (uuids) | 366 | free(udids); |
153 | g_strfreev(uuids); | 367 | result = EXIT_SUCCESS; |
154 | if (uuid) | 368 | goto leave; |
155 | free(uuid); | ||
156 | return EXIT_SUCCESS; | ||
157 | } | 369 | } |
158 | 370 | ||
159 | if (uuid) { | 371 | ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX); |
160 | ret = idevice_new(&phone, uuid); | 372 | if (ret != IDEVICE_E_SUCCESS) { |
161 | free(uuid); | 373 | if (udid) { |
162 | uuid = NULL; | 374 | printf("No device found with udid %s.\n", udid); |
163 | if (ret != IDEVICE_E_SUCCESS) { | 375 | } else { |
164 | printf("No device found with uuid %s, is it plugged in?\n", uuid); | 376 | printf("No device found.\n"); |
165 | return EXIT_FAILURE; | ||
166 | } | 377 | } |
167 | } else { | 378 | result = EXIT_FAILURE; |
168 | ret = idevice_new(&phone, NULL); | 379 | goto leave; |
380 | } | ||
381 | if (!udid) { | ||
382 | ret = idevice_get_udid(device, &udid); | ||
169 | if (ret != IDEVICE_E_SUCCESS) { | 383 | if (ret != IDEVICE_E_SUCCESS) { |
170 | printf("No device found, is it plugged in?\n"); | 384 | printf("ERROR: Could not get device udid, error code %d\n", ret); |
171 | return EXIT_FAILURE; | 385 | result = EXIT_FAILURE; |
386 | goto leave; | ||
172 | } | 387 | } |
173 | } | 388 | } |
174 | 389 | ||
175 | lerr = lockdownd_client_new(phone, &client, "idevicepair"); | 390 | if (op == OP_HOSTID) { |
391 | plist_t pair_record = NULL; | ||
392 | char *hostid = NULL; | ||
393 | |||
394 | userpref_read_pair_record(udid, &pair_record); | ||
395 | pair_record_get_host_id(pair_record, &hostid); | ||
396 | |||
397 | printf("%s\n", hostid); | ||
398 | |||
399 | free(hostid); | ||
400 | plist_free(pair_record); | ||
401 | |||
402 | result = EXIT_SUCCESS; | ||
403 | goto leave; | ||
404 | } | ||
405 | |||
406 | lerr = lockdownd_client_new(device, &client, TOOL_NAME); | ||
176 | if (lerr != LOCKDOWN_E_SUCCESS) { | 407 | if (lerr != LOCKDOWN_E_SUCCESS) { |
177 | idevice_free(phone); | 408 | printf("ERROR: Could not connect to lockdownd, error code %d\n", lerr); |
178 | printf("ERROR: lockdownd_client_new failed with error code %d\n", lerr); | 409 | result = EXIT_FAILURE; |
179 | return EXIT_FAILURE; | 410 | goto leave; |
180 | } | 411 | } |
181 | 412 | ||
182 | result = EXIT_SUCCESS; | 413 | result = EXIT_SUCCESS; |
@@ -187,76 +418,62 @@ int main(int argc, char **argv) | |||
187 | result = EXIT_FAILURE; | 418 | result = EXIT_FAILURE; |
188 | goto leave; | 419 | goto leave; |
189 | } else { | 420 | } else { |
190 | if (strcmp("com.apple.mobile.lockdown", type)) { | 421 | if (strcmp("com.apple.mobile.lockdown", type) != 0) { |
191 | printf("WARNING: QueryType request returned '%s'\n", type); | 422 | printf("WARNING: QueryType request returned '%s'\n", type); |
192 | } | 423 | } |
193 | if (type) { | 424 | free(type); |
194 | free(type); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | ret = idevice_get_uuid(phone, &uuid); | ||
199 | if (ret != IDEVICE_E_SUCCESS) { | ||
200 | printf("ERROR: Could not get device uuid, error code %d\n", ret); | ||
201 | result = EXIT_FAILURE; | ||
202 | goto leave; | ||
203 | } | 425 | } |
204 | 426 | ||
205 | switch(op) { | 427 | switch(op) { |
206 | default: | 428 | default: |
207 | case OP_PAIR: | 429 | case OP_PAIR: |
208 | lerr = lockdownd_pair(client, NULL); | 430 | #ifdef HAVE_WIRELESS_PAIRING |
431 | if (wireless_pairing) { | ||
432 | lerr = lockdownd_cu_pairing_create(client, pairing_cb, NULL, host_info_plist, NULL); | ||
433 | if (lerr == LOCKDOWN_E_SUCCESS) { | ||
434 | lerr = lockdownd_pair_cu(client); | ||
435 | } | ||
436 | } else | ||
437 | #endif | ||
438 | { | ||
439 | lerr = lockdownd_pair(client, NULL); | ||
440 | } | ||
209 | if (lerr == LOCKDOWN_E_SUCCESS) { | 441 | if (lerr == LOCKDOWN_E_SUCCESS) { |
210 | printf("SUCCESS: Paired with device %s\n", uuid); | 442 | printf("SUCCESS: Paired with device %s\n", udid); |
211 | } else { | 443 | } else { |
212 | result = EXIT_FAILURE; | 444 | result = EXIT_FAILURE; |
213 | if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) { | 445 | print_error_message(lerr); |
214 | printf("ERROR: Could not pair with the device because a passcode is set. Please enter the passcode on the device and retry.\n"); | ||
215 | } else { | ||
216 | printf("ERROR: Pairing with device %s failed with unhandled error code %d\n", uuid, lerr); | ||
217 | } | ||
218 | } | 446 | } |
219 | break; | 447 | break; |
220 | 448 | ||
221 | case OP_VALIDATE: | 449 | case OP_VALIDATE: |
222 | lerr = lockdownd_validate_pair(client, NULL); | 450 | lockdownd_client_free(client); |
451 | client = NULL; | ||
452 | lerr = lockdownd_client_new_with_handshake(device, &client, TOOL_NAME); | ||
223 | if (lerr == LOCKDOWN_E_SUCCESS) { | 453 | if (lerr == LOCKDOWN_E_SUCCESS) { |
224 | printf("SUCCESS: Validated pairing with device %s\n", uuid); | 454 | printf("SUCCESS: Validated pairing with device %s\n", udid); |
225 | } else { | 455 | } else { |
226 | result = EXIT_FAILURE; | 456 | result = EXIT_FAILURE; |
227 | if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) { | 457 | print_error_message(lerr); |
228 | printf("ERROR: Could not validate with the device because a passcode is set. Please enter the passcode on the device and retry.\n"); | ||
229 | } else if (lerr == LOCKDOWN_E_INVALID_HOST_ID) { | ||
230 | printf("ERROR: Device %s is not paired with this host\n", uuid); | ||
231 | } else { | ||
232 | printf("ERROR: Pairing failed with unhandled error code %d\n", lerr); | ||
233 | } | ||
234 | } | 458 | } |
235 | break; | 459 | break; |
236 | 460 | ||
237 | case OP_UNPAIR: | 461 | case OP_UNPAIR: |
238 | lerr = lockdownd_unpair(client, NULL); | 462 | lerr = lockdownd_unpair(client, NULL); |
239 | if (lerr == LOCKDOWN_E_SUCCESS) { | 463 | if (lerr == LOCKDOWN_E_SUCCESS) { |
240 | /* also remove local device public key */ | 464 | printf("SUCCESS: Unpaired with device %s\n", udid); |
241 | userpref_remove_device_public_key(uuid); | ||
242 | printf("SUCCESS: Unpaired with device %s\n", uuid); | ||
243 | } else { | 465 | } else { |
244 | result = EXIT_FAILURE; | 466 | result = EXIT_FAILURE; |
245 | if (lerr == LOCKDOWN_E_INVALID_HOST_ID) { | 467 | print_error_message(lerr); |
246 | printf("ERROR: Device %s is not paired with this host\n", uuid); | ||
247 | } else { | ||
248 | printf("ERROR: Unpairing with device %s failed with unhandled error code %d\n", uuid, lerr); | ||
249 | } | ||
250 | } | 468 | } |
251 | break; | 469 | break; |
252 | } | 470 | } |
253 | 471 | ||
254 | leave: | 472 | leave: |
255 | lockdownd_client_free(client); | 473 | lockdownd_client_free(client); |
256 | idevice_free(phone); | 474 | idevice_free(device); |
257 | if (uuid) { | 475 | free(udid); |
258 | free(uuid); | 476 | |
259 | } | ||
260 | return result; | 477 | return result; |
261 | } | 478 | } |
262 | 479 | ||