diff options
Diffstat (limited to 'tools/idevicepair.c')
| -rw-r--r-- | tools/idevicepair.c | 112 |
1 files changed, 75 insertions, 37 deletions
diff --git a/tools/idevicepair.c b/tools/idevicepair.c index 85aa903..b9676b9 100644 --- a/tools/idevicepair.c +++ b/tools/idevicepair.c | |||
| @@ -35,13 +35,14 @@ static void print_usage(int argc, char **argv) | |||
| 35 | char *name = NULL; | 35 | char *name = NULL; |
| 36 | 36 | ||
| 37 | name = strrchr(argv[0], '/'); | 37 | name = strrchr(argv[0], '/'); |
| 38 | printf("\n%s - Pair or unpair a connected iPhone/iPod Touch/iPad.\n\n", (name ? name + 1: argv[0])); | 38 | printf("\n%s - Manage pairings with iPhone/iPod Touch/iPad devices and this host.\n\n", (name ? name + 1: argv[0])); |
| 39 | printf("Usage: %s [OPTIONS] COMMAND\n\n", (name ? name + 1: argv[0])); | 39 | printf("Usage: %s [OPTIONS] COMMAND\n\n", (name ? name + 1: argv[0])); |
| 40 | printf(" Where COMMAND is one of:\n"); | 40 | printf(" Where COMMAND is one of:\n"); |
| 41 | printf(" pair pair device\n"); | 41 | printf(" hostid print the host id of this computer\n"); |
| 42 | printf(" validate validate if paired with device\n"); | 42 | printf(" pair pair device with this computer\n"); |
| 43 | printf(" unpair unpair device\n"); | 43 | printf(" validate validate if device is paired with this computer\n"); |
| 44 | printf(" list list currently paired devices\n\n"); | 44 | printf(" unpair unpair device with this computer\n"); |
| 45 | printf(" list list devices paired with this computer\n\n"); | ||
| 45 | printf(" The following OPTIONS are accepted:\n"); | 46 | printf(" The following OPTIONS are accepted:\n"); |
| 46 | printf(" -d, --debug enable communication debugging\n"); | 47 | printf(" -d, --debug enable communication debugging\n"); |
| 47 | printf(" -u, --uuid UUID target specific device by its 40-digit device UUID\n"); | 48 | printf(" -u, --uuid UUID target specific device by its 40-digit device UUID\n"); |
| @@ -53,7 +54,7 @@ static void parse_opts(int argc, char **argv) | |||
| 53 | { | 54 | { |
| 54 | static struct option longopts[] = { | 55 | static struct option longopts[] = { |
| 55 | {"help", 0, NULL, 'h'}, | 56 | {"help", 0, NULL, 'h'}, |
| 56 | {"uuid", 0, NULL, 'u'}, | 57 | {"uuid", 1, NULL, 'u'}, |
| 57 | {"debug", 0, NULL, 'd'}, | 58 | {"debug", 0, NULL, 'd'}, |
| 58 | {NULL, 0, NULL, 0} | 59 | {NULL, 0, NULL, 0} |
| 59 | }; | 60 | }; |
| @@ -68,7 +69,7 @@ static void parse_opts(int argc, char **argv) | |||
| 68 | switch (c) { | 69 | switch (c) { |
| 69 | case 'h': | 70 | case 'h': |
| 70 | print_usage(argc, argv); | 71 | print_usage(argc, argv); |
| 71 | exit(0); | 72 | exit(EXIT_SUCCESS); |
| 72 | case 'u': | 73 | case 'u': |
| 73 | if (strlen(optarg) != 40) { | 74 | if (strlen(optarg) != 40) { |
| 74 | printf("%s: invalid UUID specified (length != 40)\n", argv[0]); | 75 | printf("%s: invalid UUID specified (length != 40)\n", argv[0]); |
| @@ -82,7 +83,7 @@ static void parse_opts(int argc, char **argv) | |||
| 82 | break; | 83 | break; |
| 83 | default: | 84 | default: |
| 84 | print_usage(argc, argv); | 85 | print_usage(argc, argv); |
| 85 | exit(2); | 86 | exit(EXIT_SUCCESS); |
| 86 | } | 87 | } |
| 87 | } | 88 | } |
| 88 | } | 89 | } |
| @@ -94,10 +95,11 @@ int main(int argc, char **argv) | |||
| 94 | idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; | 95 | idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; |
| 95 | lockdownd_error_t lerr; | 96 | lockdownd_error_t lerr; |
| 96 | int result; | 97 | int result; |
| 98 | |||
| 97 | char *type = NULL; | 99 | char *type = NULL; |
| 98 | char *cmd; | 100 | char *cmd; |
| 99 | typedef enum { | 101 | typedef enum { |
| 100 | OP_NONE = 0, OP_PAIR, OP_VALIDATE, OP_UNPAIR, OP_LIST | 102 | OP_NONE = 0, OP_PAIR, OP_VALIDATE, OP_UNPAIR, OP_LIST, OP_HOSTID |
| 101 | } op_t; | 103 | } op_t; |
| 102 | op_t op = OP_NONE; | 104 | op_t op = OP_NONE; |
| 103 | 105 | ||
| @@ -106,8 +108,8 @@ int main(int argc, char **argv) | |||
| 106 | if ((argc - optind) < 1) { | 108 | if ((argc - optind) < 1) { |
| 107 | printf("ERROR: You need to specify a COMMAND!\n"); | 109 | printf("ERROR: You need to specify a COMMAND!\n"); |
| 108 | print_usage(argc, argv); | 110 | print_usage(argc, argv); |
| 109 | exit(2); | 111 | exit(EXIT_FAILURE); |
| 110 | } | 112 | } |
| 111 | 113 | ||
| 112 | cmd = (argv+optind)[0]; | 114 | cmd = (argv+optind)[0]; |
| 113 | 115 | ||
| @@ -119,10 +121,24 @@ int main(int argc, char **argv) | |||
| 119 | op = OP_UNPAIR; | 121 | op = OP_UNPAIR; |
| 120 | } else if (!strcmp(cmd, "list")) { | 122 | } else if (!strcmp(cmd, "list")) { |
| 121 | op = OP_LIST; | 123 | op = OP_LIST; |
| 124 | } else if (!strcmp(cmd, "hostid")) { | ||
| 125 | op = OP_HOSTID; | ||
| 122 | } else { | 126 | } else { |
| 123 | printf("ERROR: Invalid command '%s' specified\n", cmd); | 127 | printf("ERROR: Invalid command '%s' specified\n", cmd); |
| 124 | print_usage(argc, argv); | 128 | print_usage(argc, argv); |
| 125 | exit(2); | 129 | exit(EXIT_FAILURE); |
| 130 | } | ||
| 131 | |||
| 132 | if (op == OP_HOSTID) { | ||
| 133 | char *hostid = NULL; | ||
| 134 | userpref_get_host_id(&hostid); | ||
| 135 | |||
| 136 | printf("%s\n", hostid); | ||
| 137 | |||
| 138 | if (hostid) | ||
| 139 | free(hostid); | ||
| 140 | |||
| 141 | return EXIT_SUCCESS; | ||
| 126 | } | 142 | } |
| 127 | 143 | ||
| 128 | if (op == OP_LIST) { | 144 | if (op == OP_LIST) { |
| @@ -133,28 +149,26 @@ int main(int argc, char **argv) | |||
| 133 | for (i = 0; i < count; i++) { | 149 | for (i = 0; i < count; i++) { |
| 134 | printf("%s\n", uuids[i]); | 150 | printf("%s\n", uuids[i]); |
| 135 | } | 151 | } |
| 136 | if (uuids) { | 152 | if (uuids) |
| 137 | g_strfreev(uuids); | 153 | g_strfreev(uuids); |
| 138 | } | 154 | if (uuid) |
| 139 | if (uuid) { | ||
| 140 | free(uuid); | 155 | free(uuid); |
| 141 | } | 156 | return EXIT_SUCCESS; |
| 142 | return 0; | ||
| 143 | } | 157 | } |
| 144 | 158 | ||
| 145 | if (uuid) { | 159 | if (uuid) { |
| 146 | ret = idevice_new(&phone, uuid); | 160 | ret = idevice_new(&phone, uuid); |
| 147 | free(uuid); | 161 | free(uuid); |
| 148 | uuid = NULL; | 162 | uuid = NULL; |
| 149 | if (ret != IDEVICE_E_SUCCESS) { | 163 | if (ret != IDEVICE_E_SUCCESS) { |
| 150 | printf("No device found with uuid %s, is it plugged in?\n", uuid); | 164 | printf("No device found with uuid %s, is it plugged in?\n", uuid); |
| 151 | return -1; | 165 | return EXIT_FAILURE; |
| 152 | } | 166 | } |
| 153 | } else { | 167 | } else { |
| 154 | ret = idevice_new(&phone, NULL); | 168 | ret = idevice_new(&phone, NULL); |
| 155 | if (ret != IDEVICE_E_SUCCESS) { | 169 | if (ret != IDEVICE_E_SUCCESS) { |
| 156 | printf("No device found, is it plugged in?\n"); | 170 | printf("No device found, is it plugged in?\n"); |
| 157 | return -1; | 171 | return EXIT_FAILURE; |
| 158 | } | 172 | } |
| 159 | } | 173 | } |
| 160 | 174 | ||
| @@ -162,14 +176,15 @@ int main(int argc, char **argv) | |||
| 162 | if (lerr != LOCKDOWN_E_SUCCESS) { | 176 | if (lerr != LOCKDOWN_E_SUCCESS) { |
| 163 | idevice_free(phone); | 177 | idevice_free(phone); |
| 164 | printf("ERROR: lockdownd_client_new failed with error code %d\n", lerr); | 178 | printf("ERROR: lockdownd_client_new failed with error code %d\n", lerr); |
| 165 | return -1; | 179 | return EXIT_FAILURE; |
| 166 | } | 180 | } |
| 167 | 181 | ||
| 168 | result = 0; | 182 | result = EXIT_SUCCESS; |
| 183 | |||
| 169 | lerr = lockdownd_query_type(client, &type); | 184 | lerr = lockdownd_query_type(client, &type); |
| 170 | if (lerr != LOCKDOWN_E_SUCCESS) { | 185 | if (lerr != LOCKDOWN_E_SUCCESS) { |
| 171 | printf("QueryType failed, error code %d\n", lerr); | 186 | printf("QueryType failed, error code %d\n", lerr); |
| 172 | result = -1; | 187 | result = EXIT_FAILURE; |
| 173 | goto leave; | 188 | goto leave; |
| 174 | } else { | 189 | } else { |
| 175 | if (strcmp("com.apple.mobile.lockdown", type)) { | 190 | if (strcmp("com.apple.mobile.lockdown", type)) { |
| @@ -182,35 +197,58 @@ int main(int argc, char **argv) | |||
| 182 | 197 | ||
| 183 | ret = idevice_get_uuid(phone, &uuid); | 198 | ret = idevice_get_uuid(phone, &uuid); |
| 184 | if (ret != IDEVICE_E_SUCCESS) { | 199 | if (ret != IDEVICE_E_SUCCESS) { |
| 185 | printf("Could not get device uuid, error code %d\n", ret); | 200 | printf("ERROR: Could not get device uuid, error code %d\n", ret); |
| 186 | result = -1; | 201 | result = EXIT_FAILURE; |
| 187 | goto leave; | 202 | goto leave; |
| 188 | } | 203 | } |
| 189 | 204 | ||
| 190 | if ((op == OP_PAIR) || (op == OP_VALIDATE)) { | 205 | switch(op) { |
| 191 | /* TODO */ | 206 | default: |
| 207 | case OP_PAIR: | ||
| 192 | lerr = lockdownd_pair(client, NULL); | 208 | lerr = lockdownd_pair(client, NULL); |
| 193 | if (op == OP_VALIDATE) { | 209 | if (lerr == LOCKDOWN_E_SUCCESS) { |
| 194 | ret = lockdownd_validate_pair(client, NULL); | 210 | printf("SUCCESS: Paired with device %s\n", uuid); |
| 211 | } else { | ||
| 212 | result = EXIT_FAILURE; | ||
| 213 | if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) { | ||
| 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 | } | ||
| 195 | } | 218 | } |
| 219 | break; | ||
| 220 | |||
| 221 | case OP_VALIDATE: | ||
| 222 | lerr = lockdownd_validate_pair(client, NULL); | ||
| 196 | if (lerr == LOCKDOWN_E_SUCCESS) { | 223 | if (lerr == LOCKDOWN_E_SUCCESS) { |
| 197 | printf("SUCCESS - device %s paired\n", uuid); | 224 | printf("SUCCESS: Validated pairing with device %s\n", uuid); |
| 198 | } else if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) { | ||
| 199 | printf("ERROR - Could not pair device because a passcode is set. Enter the passcode on the device and try again.\n"); | ||
| 200 | } else { | 225 | } else { |
| 201 | printf("ERROR - Pairing failed, error code %d\n", lerr); | 226 | result = EXIT_FAILURE; |
| 227 | if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) { | ||
| 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 | } | ||
| 202 | } | 234 | } |
| 203 | } else if (op == OP_UNPAIR) { | 235 | break; |
| 236 | |||
| 237 | case OP_UNPAIR: | ||
| 204 | lerr = lockdownd_unpair(client, NULL); | 238 | lerr = lockdownd_unpair(client, NULL); |
| 205 | if (lerr == LOCKDOWN_E_SUCCESS) { | 239 | if (lerr == LOCKDOWN_E_SUCCESS) { |
| 206 | printf("SUCCESS - device %s unpaired\n", uuid); | 240 | /* also remove local device public key */ |
| 241 | userpref_remove_device_public_key(uuid); | ||
| 242 | printf("SUCCESS: Unpaired with device %s\n", uuid); | ||
| 207 | } else { | 243 | } else { |
| 244 | result = EXIT_FAILURE; | ||
| 208 | if (lerr == LOCKDOWN_E_INVALID_HOST_ID) { | 245 | if (lerr == LOCKDOWN_E_INVALID_HOST_ID) { |
| 209 | printf("ERROR - Unpair %s failed: device is not paired with this system\n", uuid); | 246 | printf("ERROR: Device %s is not paired with this host\n", uuid); |
| 210 | } else { | 247 | } else { |
| 211 | printf("ERROR - Unpair %s failed: return code %d\n", uuid, lerr); | 248 | printf("ERROR: Unpairing with device %s failed with unhandled error code %d\n", uuid, lerr); |
| 212 | } | 249 | } |
| 213 | } | 250 | } |
| 251 | break; | ||
| 214 | } | 252 | } |
| 215 | 253 | ||
| 216 | leave: | 254 | leave: |
