idevicepair.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * idevicepair.c
  3. * Manage pairings with devices and this host
  4. *
  5. * Copyright (c) 2014 Martin Szulecki All Rights Reserved.
  6. * Copyright (c) 2010 Nikias Bassen All Rights Reserved.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <getopt.h>
  26. #include "common/userpref.h"
  27. #include <libimobiledevice/libimobiledevice.h>
  28. #include <libimobiledevice/lockdown.h>
  29. static char *udid = NULL;
  30. static void print_error_message(lockdownd_error_t err)
  31. {
  32. switch (err) {
  33. case LOCKDOWN_E_PASSWORD_PROTECTED:
  34. printf("ERROR: Could not validate with device %s because a passcode is set. Please enter the passcode on the device and retry.\n", udid);
  35. break;
  36. case LOCKDOWN_E_INVALID_HOST_ID:
  37. printf("ERROR: Device %s is not paired with this host\n", udid);
  38. break;
  39. case LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING:
  40. printf("ERROR: Please accept the trust dialog on the screen of device %s, then attempt to pair again.\n", udid);
  41. break;
  42. case LOCKDOWN_E_USER_DENIED_PAIRING:
  43. printf("ERROR: Device %s said that the user denied the trust dialog.\n", udid);
  44. break;
  45. default:
  46. printf("ERROR: Device %s returned unhandled error code %d\n", udid, err);
  47. break;
  48. }
  49. }
  50. static void print_usage(int argc, char **argv)
  51. {
  52. char *name = NULL;
  53. name = strrchr(argv[0], '/');
  54. printf("\n%s - Manage host pairings with devices and usbmuxd.\n\n", (name ? name + 1: argv[0]));
  55. printf("Usage: %s [OPTIONS] COMMAND\n\n", (name ? name + 1: argv[0]));
  56. printf(" Where COMMAND is one of:\n");
  57. printf(" systembuid print the system buid of the usbmuxd host\n");
  58. printf(" hostid print the host id for target device\n");
  59. printf(" pair pair device with this host\n");
  60. printf(" validate validate if device is paired with this host\n");
  61. printf(" unpair unpair device with this host\n");
  62. printf(" list list devices paired with this host\n\n");
  63. printf(" The following OPTIONS are accepted:\n");
  64. printf(" -d, --debug enable communication debugging\n");
  65. printf(" -u, --udid UDID target specific device by its 40-digit device UDID\n");
  66. printf(" -h, --help prints usage information\n");
  67. printf("\n");
  68. printf("Homepage: <http://libimobiledevice.org>\n");
  69. }
  70. static void parse_opts(int argc, char **argv)
  71. {
  72. static struct option longopts[] = {
  73. {"help", 0, NULL, 'h'},
  74. {"udid", 1, NULL, 'u'},
  75. {"debug", 0, NULL, 'd'},
  76. {NULL, 0, NULL, 0}
  77. };
  78. int c;
  79. while (1) {
  80. c = getopt_long(argc, argv, "hu:d", longopts, (int*)0);
  81. if (c == -1) {
  82. break;
  83. }
  84. switch (c) {
  85. case 'h':
  86. print_usage(argc, argv);
  87. exit(EXIT_SUCCESS);
  88. case 'u':
  89. if (strlen(optarg) != 40) {
  90. printf("%s: invalid UDID specified (length != 40)\n", argv[0]);
  91. print_usage(argc, argv);
  92. exit(2);
  93. }
  94. udid = strdup(optarg);
  95. break;
  96. case 'd':
  97. idevice_set_debug_level(1);
  98. break;
  99. default:
  100. print_usage(argc, argv);
  101. exit(EXIT_SUCCESS);
  102. }
  103. }
  104. }
  105. int main(int argc, char **argv)
  106. {
  107. lockdownd_client_t client = NULL;
  108. idevice_t device = NULL;
  109. idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
  110. lockdownd_error_t lerr;
  111. int result;
  112. char *type = NULL;
  113. char *cmd;
  114. typedef enum {
  115. OP_NONE = 0, OP_PAIR, OP_VALIDATE, OP_UNPAIR, OP_LIST, OP_HOSTID, OP_SYSTEMBUID
  116. } op_t;
  117. op_t op = OP_NONE;
  118. parse_opts(argc, argv);
  119. if ((argc - optind) < 1) {
  120. printf("ERROR: You need to specify a COMMAND!\n");
  121. print_usage(argc, argv);
  122. exit(EXIT_FAILURE);
  123. }
  124. cmd = (argv+optind)[0];
  125. if (!strcmp(cmd, "pair")) {
  126. op = OP_PAIR;
  127. } else if (!strcmp(cmd, "validate")) {
  128. op = OP_VALIDATE;
  129. } else if (!strcmp(cmd, "unpair")) {
  130. op = OP_UNPAIR;
  131. } else if (!strcmp(cmd, "list")) {
  132. op = OP_LIST;
  133. } else if (!strcmp(cmd, "hostid")) {
  134. op = OP_HOSTID;
  135. } else if (!strcmp(cmd, "systembuid")) {
  136. op = OP_SYSTEMBUID;
  137. } else {
  138. printf("ERROR: Invalid command '%s' specified\n", cmd);
  139. print_usage(argc, argv);
  140. exit(EXIT_FAILURE);
  141. }
  142. if (op == OP_SYSTEMBUID) {
  143. char *systembuid = NULL;
  144. userpref_read_system_buid(&systembuid);
  145. printf("%s\n", systembuid);
  146. if (systembuid)
  147. free(systembuid);
  148. return EXIT_SUCCESS;
  149. }
  150. if (op == OP_LIST) {
  151. unsigned int i;
  152. char **udids = NULL;
  153. unsigned int count = 0;
  154. userpref_get_paired_udids(&udids, &count);
  155. for (i = 0; i < count; i++) {
  156. printf("%s\n", udids[i]);
  157. free(udids[i]);
  158. }
  159. if (udids)
  160. free(udids);
  161. if (udid)
  162. free(udid);
  163. return EXIT_SUCCESS;
  164. }
  165. if (udid) {
  166. ret = idevice_new(&device, udid);
  167. free(udid);
  168. udid = NULL;
  169. if (ret != IDEVICE_E_SUCCESS) {
  170. printf("No device found with udid %s, is it plugged in?\n", udid);
  171. return EXIT_FAILURE;
  172. }
  173. } else {
  174. ret = idevice_new(&device, NULL);
  175. if (ret != IDEVICE_E_SUCCESS) {
  176. printf("No device found, is it plugged in?\n");
  177. return EXIT_FAILURE;
  178. }
  179. }
  180. ret = idevice_get_udid(device, &udid);
  181. if (ret != IDEVICE_E_SUCCESS) {
  182. printf("ERROR: Could not get device udid, error code %d\n", ret);
  183. result = EXIT_FAILURE;
  184. goto leave;
  185. }
  186. if (op == OP_HOSTID) {
  187. plist_t pair_record = NULL;
  188. char *hostid = NULL;
  189. userpref_read_pair_record(udid, &pair_record);
  190. pair_record_get_host_id(pair_record, &hostid);
  191. printf("%s\n", hostid);
  192. if (hostid)
  193. free(hostid);
  194. if (pair_record)
  195. plist_free(pair_record);
  196. return EXIT_SUCCESS;
  197. }
  198. lerr = lockdownd_client_new(device, &client, "idevicepair");
  199. if (lerr != LOCKDOWN_E_SUCCESS) {
  200. idevice_free(device);
  201. printf("ERROR: Could not connect to lockdownd, error code %d\n", lerr);
  202. return EXIT_FAILURE;
  203. }
  204. result = EXIT_SUCCESS;
  205. lerr = lockdownd_query_type(client, &type);
  206. if (lerr != LOCKDOWN_E_SUCCESS) {
  207. printf("QueryType failed, error code %d\n", lerr);
  208. result = EXIT_FAILURE;
  209. goto leave;
  210. } else {
  211. if (strcmp("com.apple.mobile.lockdown", type)) {
  212. printf("WARNING: QueryType request returned '%s'\n", type);
  213. }
  214. if (type) {
  215. free(type);
  216. }
  217. }
  218. switch(op) {
  219. default:
  220. case OP_PAIR:
  221. lerr = lockdownd_pair(client, NULL);
  222. if (lerr == LOCKDOWN_E_SUCCESS) {
  223. printf("SUCCESS: Paired with device %s\n", udid);
  224. } else {
  225. result = EXIT_FAILURE;
  226. print_error_message(lerr);
  227. }
  228. break;
  229. case OP_VALIDATE:
  230. lerr = lockdownd_validate_pair(client, NULL);
  231. if (lerr == LOCKDOWN_E_SUCCESS) {
  232. printf("SUCCESS: Validated pairing with device %s\n", udid);
  233. } else {
  234. result = EXIT_FAILURE;
  235. print_error_message(lerr);
  236. }
  237. break;
  238. case OP_UNPAIR:
  239. lerr = lockdownd_unpair(client, NULL);
  240. if (lerr == LOCKDOWN_E_SUCCESS) {
  241. printf("SUCCESS: Unpaired with device %s\n", udid);
  242. } else {
  243. result = EXIT_FAILURE;
  244. print_error_message(lerr);
  245. }
  246. break;
  247. }
  248. leave:
  249. lockdownd_client_free(client);
  250. idevice_free(device);
  251. if (udid) {
  252. free(udid);
  253. }
  254. return result;
  255. }