diff options
| -rw-r--r-- | src/lockdown.c | 143 | ||||
| -rw-r--r-- | src/lockdown.h | 11 | ||||
| -rw-r--r-- | src/plist.c | 8 | ||||
| -rw-r--r-- | src/plist.h | 4 | ||||
| -rw-r--r-- | src/userpref.c | 10 | ||||
| -rw-r--r-- | src/userpref.h | 2 | ||||
| -rw-r--r-- | src/xplist.c | 8 |
7 files changed, 104 insertions, 82 deletions
diff --git a/src/lockdown.c b/src/lockdown.c index 4c96a7d..e882128 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -180,7 +180,7 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) | |||
| 180 | plist_t dict = NULL; | 180 | plist_t dict = NULL; |
| 181 | plist_new_dict(&dict); | 181 | plist_new_dict(&dict); |
| 182 | 182 | ||
| 183 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "QueryType"); | 183 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "QueryType", strlen("QueryType")); |
| 184 | 184 | ||
| 185 | log_debug_msg("lockdownd_hello() called\n"); | 185 | log_debug_msg("lockdownd_hello() called\n"); |
| 186 | char *XML_content = NULL; | 186 | char *XML_content = NULL; |
| @@ -190,7 +190,7 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) | |||
| 190 | log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); | 190 | log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); |
| 191 | ret = iphone_lckd_send(control, XML_content, length, &bytes); | 191 | ret = iphone_lckd_send(control, XML_content, length, &bytes); |
| 192 | 192 | ||
| 193 | xmlFree(XML_content); | 193 | free(XML_content); |
| 194 | XML_content = NULL; | 194 | XML_content = NULL; |
| 195 | plist_free(dict); | 195 | plist_free(dict); |
| 196 | dict = NULL; | 196 | dict = NULL; |
| @@ -211,9 +211,11 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) | |||
| 211 | 211 | ||
| 212 | char *result_value = NULL; | 212 | char *result_value = NULL; |
| 213 | char *value_value = NULL; | 213 | char *value_value = NULL; |
| 214 | uint64_t result_length = 0; | ||
| 215 | uint64_t value_length = 0; | ||
| 214 | 216 | ||
| 215 | get_type_and_value(result_node, &result_type, (void *) (&result_value)); | 217 | get_type_and_value(result_node, &result_type, (void *) (&result_value), &result_length); |
| 216 | get_type_and_value(value_node, &value_type, (void *) (&value_value)); | 218 | get_type_and_value(value_node, &value_type, (void *) (&value_value), &value_length); |
| 217 | 219 | ||
| 218 | if (result_type == PLIST_KEY && | 220 | if (result_type == PLIST_KEY && |
| 219 | value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { | 221 | value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { |
| @@ -232,9 +234,10 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) | |||
| 232 | * | 234 | * |
| 233 | * @return IPHONE_E_SUCCESS on success. | 235 | * @return IPHONE_E_SUCCESS on success. |
| 234 | */ | 236 | */ |
| 235 | iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, char *req_string, char **value) | 237 | iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, char *req_string, |
| 238 | gnutls_datum_t * value) | ||
| 236 | { | 239 | { |
| 237 | if (!control || !req_key || !value || (value && *value)) | 240 | if (!control || !req_key || !value || value->data) |
| 238 | return IPHONE_E_INVALID_ARG; | 241 | return IPHONE_E_INVALID_ARG; |
| 239 | 242 | ||
| 240 | plist_t dict = NULL; | 243 | plist_t dict = NULL; |
| @@ -245,15 +248,15 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r | |||
| 245 | 248 | ||
| 246 | /* Setup DevicePublicKey request plist */ | 249 | /* Setup DevicePublicKey request plist */ |
| 247 | plist_new_dict(&dict); | 250 | plist_new_dict(&dict); |
| 248 | plist_add_dict_element(dict, req_key, PLIST_STRING, (void *) req_string); | 251 | plist_add_dict_element(dict, req_key, PLIST_STRING, (void *) req_string, strlen(req_string)); |
| 249 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "GetValue"); | 252 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "GetValue", strlen("GetValue")); |
| 250 | plist_to_xml(dict, &XML_content, &length); | 253 | plist_to_xml(dict, &XML_content, &length); |
| 251 | 254 | ||
| 252 | /* send to iPhone */ | 255 | /* send to iPhone */ |
| 253 | log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); | 256 | log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); |
| 254 | ret = iphone_lckd_send(control, XML_content, length, &bytes); | 257 | ret = iphone_lckd_send(control, XML_content, length, &bytes); |
| 255 | 258 | ||
| 256 | xmlFree(XML_content); | 259 | free(XML_content); |
| 257 | XML_content = NULL; | 260 | XML_content = NULL; |
| 258 | plist_free(dict); | 261 | plist_free(dict); |
| 259 | dict = NULL; | 262 | dict = NULL; |
| @@ -280,9 +283,11 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r | |||
| 280 | plist_type result_value_type; | 283 | plist_type result_value_type; |
| 281 | char *result_key = NULL; | 284 | char *result_key = NULL; |
| 282 | char *result_value = NULL; | 285 | char *result_value = NULL; |
| 286 | uint64_t result_length = 0; | ||
| 287 | uint64_t value_length = 0; | ||
| 283 | 288 | ||
| 284 | get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key)); | 289 | get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &result_length); |
| 285 | get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value)); | 290 | get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &value_length); |
| 286 | 291 | ||
| 287 | if (result_key_type == PLIST_KEY && | 292 | if (result_key_type == PLIST_KEY && |
| 288 | result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { | 293 | result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { |
| @@ -300,13 +305,16 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r | |||
| 300 | plist_type value_value_type; | 305 | plist_type value_value_type; |
| 301 | char *value_key = NULL; | 306 | char *value_key = NULL; |
| 302 | char *value_value = NULL; | 307 | char *value_value = NULL; |
| 308 | uint64_t key_length = 0; | ||
| 309 | uint64_t valval_length = 0; | ||
| 303 | 310 | ||
| 304 | get_type_and_value(value_key_node, &value_key_type, (void *) (&value_key)); | 311 | get_type_and_value(value_key_node, &value_key_type, (void *) (&value_key), &key_length); |
| 305 | get_type_and_value(value_value_node, &value_value_type, (void *) (&value_value)); | 312 | get_type_and_value(value_value_node, &value_value_type, (void *) (&value_value), &valval_length); |
| 306 | 313 | ||
| 307 | if (value_key_type == PLIST_KEY && !strcmp(result_key, "Value")) { | 314 | if (value_key_type == PLIST_KEY && !strcmp(result_key, "Value")) { |
| 308 | log_debug_msg("lockdownd_generic_get_value(): success\n"); | 315 | log_debug_msg("lockdownd_generic_get_value(): success\n"); |
| 309 | *value = value_value; | 316 | value->data = value_value; |
| 317 | value->size = valval_length; | ||
| 310 | ret = IPHONE_E_SUCCESS; | 318 | ret = IPHONE_E_SUCCESS; |
| 311 | } | 319 | } |
| 312 | 320 | ||
| @@ -323,7 +331,9 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r | |||
| 323 | */ | 331 | */ |
| 324 | iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid) | 332 | iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid) |
| 325 | { | 333 | { |
| 326 | return lockdownd_generic_get_value(control, "Key", "UniqueDeviceID", uid); | 334 | gnutls_datum_t temp = { NULL, 0 }; |
| 335 | return lockdownd_generic_get_value(control, "Key", "UniqueDeviceID", &temp); | ||
| 336 | *uid = temp.data; | ||
| 327 | } | 337 | } |
| 328 | 338 | ||
| 329 | /** Askes for the device's public key. Part of the lockdownd handshake. | 339 | /** Askes for the device's public key. Part of the lockdownd handshake. |
| @@ -332,7 +342,7 @@ iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid | |||
| 332 | * | 342 | * |
| 333 | * @return 1 on success and 0 on failure. | 343 | * @return 1 on success and 0 on failure. |
| 334 | */ | 344 | */ |
| 335 | iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_key) | 345 | iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, gnutls_datum_t * public_key) |
| 336 | { | 346 | { |
| 337 | return lockdownd_generic_get_value(control, "Key", "DevicePublicKey", public_key); | 347 | return lockdownd_generic_get_value(control, "Key", "DevicePublicKey", public_key); |
| 338 | } | 348 | } |
| @@ -410,39 +420,39 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch | |||
| 410 | char *XML_content = NULL; | 420 | char *XML_content = NULL; |
| 411 | uint32_t length = 0; | 421 | uint32_t length = 0; |
| 412 | 422 | ||
| 413 | char *device_cert_b64 = NULL; | 423 | gnutls_datum_t device_cert = { NULL, 0 }; |
| 414 | char *host_cert_b64 = NULL; | 424 | gnutls_datum_t host_cert = { NULL, 0 }; |
| 415 | char *root_cert_b64 = NULL; | 425 | gnutls_datum_t root_cert = { NULL, 0 }; |
| 416 | char *public_key_b64 = NULL; | 426 | gnutls_datum_t public_key = { NULL, 0 }; |
| 417 | 427 | ||
| 418 | ret = lockdownd_get_device_public_key(control, &public_key_b64); | 428 | ret = lockdownd_get_device_public_key(control, &public_key); |
| 419 | if (ret != IPHONE_E_SUCCESS) { | 429 | if (ret != IPHONE_E_SUCCESS) { |
| 420 | fprintf(stderr, "Device refused to send public key.\n"); | 430 | fprintf(stderr, "Device refused to send public key.\n"); |
| 421 | return ret; | 431 | return ret; |
| 422 | } | 432 | } |
| 423 | 433 | ||
| 424 | ret = lockdownd_gen_pair_cert(public_key_b64, &device_cert_b64, &host_cert_b64, &root_cert_b64); | 434 | ret = lockdownd_gen_pair_cert(public_key, &device_cert, &host_cert, &root_cert); |
| 425 | if (ret != IPHONE_E_SUCCESS) { | 435 | if (ret != IPHONE_E_SUCCESS) { |
| 426 | free(public_key_b64); | 436 | free(public_key.data); |
| 427 | return ret; | 437 | return ret; |
| 428 | } | 438 | } |
| 429 | 439 | ||
| 430 | /* Setup Pair request plist */ | 440 | /* Setup Pair request plist */ |
| 431 | plist_new_dict(&dict); | 441 | plist_new_dict(&dict); |
| 432 | plist_add_dict_element(dict, "PairRecord", PLIST_DICT, NULL); | 442 | plist_add_dict_element(dict, "PairRecord", PLIST_DICT, NULL, 0); |
| 433 | dict_record = g_node_last_child(dict); | 443 | dict_record = g_node_last_child(dict); |
| 434 | plist_add_dict_element(dict_record, "DeviceCertificate", PLIST_DATA, (void *) device_cert_b64); | 444 | plist_add_dict_element(dict_record, "DeviceCertificate", PLIST_DATA, (void *) device_cert.data, device_cert.size); |
| 435 | plist_add_dict_element(dict_record, "HostCertificate", PLIST_DATA, (void *) host_cert_b64); | 445 | plist_add_dict_element(dict_record, "HostCertificate", PLIST_DATA, (void *) host_cert.data, host_cert.size); |
| 436 | plist_add_dict_element(dict_record, "HostID", PLIST_STRING, (void *) host_id); | 446 | plist_add_dict_element(dict_record, "HostID", PLIST_STRING, (void *) host_id, strlen(host_id)); |
| 437 | plist_add_dict_element(dict_record, "RootCertificate", PLIST_DATA, (void *) root_cert_b64); | 447 | plist_add_dict_element(dict_record, "RootCertificate", PLIST_DATA, (void *) root_cert.data, root_cert.size); |
| 438 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "Pair"); | 448 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "Pair", strlen("Pair")); |
| 439 | plist_to_xml(dict, &XML_content, &length); | 449 | plist_to_xml(dict, &XML_content, &length); |
| 440 | log_debug_msg("XML Pairing request :\nsize : %i\nxml :\n %s", length, XML_content); | 450 | log_debug_msg("XML Pairing request :\nsize : %i\nxml :\n %s", length, XML_content); |
| 441 | 451 | ||
| 442 | /* send to iPhone */ | 452 | /* send to iPhone */ |
| 443 | ret = iphone_lckd_send(control, XML_content, length, &bytes); | 453 | ret = iphone_lckd_send(control, XML_content, length, &bytes); |
| 444 | 454 | ||
| 445 | xmlFree(XML_content); | 455 | free(XML_content); |
| 446 | plist_free(dict); | 456 | plist_free(dict); |
| 447 | dict = NULL; | 457 | dict = NULL; |
| 448 | 458 | ||
| @@ -471,9 +481,11 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch | |||
| 471 | plist_type result_value_type; | 481 | plist_type result_value_type; |
| 472 | char *result_key = NULL; | 482 | char *result_key = NULL; |
| 473 | char *result_value = NULL; | 483 | char *result_value = NULL; |
| 484 | uint64_t key_length = 0; | ||
| 485 | uint64_t val_length = 0; | ||
| 474 | 486 | ||
| 475 | get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key)); | 487 | get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length); |
| 476 | get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value)); | 488 | get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length); |
| 477 | 489 | ||
| 478 | if (result_key_type == PLIST_KEY && | 490 | if (result_key_type == PLIST_KEY && |
| 479 | result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { | 491 | result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { |
| @@ -483,13 +495,13 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch | |||
| 483 | /* store public key in config if pairing succeeded */ | 495 | /* store public key in config if pairing succeeded */ |
| 484 | if (ret == IPHONE_E_SUCCESS) { | 496 | if (ret == IPHONE_E_SUCCESS) { |
| 485 | log_debug_msg("lockdownd_pair_device: pair success\n"); | 497 | log_debug_msg("lockdownd_pair_device: pair success\n"); |
| 486 | store_device_public_key(uid, public_key_b64); | 498 | store_device_public_key(uid, public_key); |
| 487 | ret = IPHONE_E_SUCCESS; | 499 | ret = IPHONE_E_SUCCESS; |
| 488 | } else { | 500 | } else { |
| 489 | log_debug_msg("lockdownd_pair_device: pair failure\n"); | 501 | log_debug_msg("lockdownd_pair_device: pair failure\n"); |
| 490 | ret = IPHONE_E_PAIRING_FAILED; | 502 | ret = IPHONE_E_PAIRING_FAILED; |
| 491 | } | 503 | } |
| 492 | free(public_key_b64); | 504 | free(public_key.data); |
| 493 | return ret; | 505 | return ret; |
| 494 | } | 506 | } |
| 495 | 507 | ||
| @@ -498,25 +510,19 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch | |||
| 498 | * | 510 | * |
| 499 | * @return IPHONE_E_SUCCESS on success. | 511 | * @return IPHONE_E_SUCCESS on success. |
| 500 | */ | 512 | */ |
| 501 | iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64, | 513 | iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * odevice_cert, |
| 502 | char **root_cert_b64) | 514 | gnutls_datum_t * ohost_cert, gnutls_datum_t * oroot_cert) |
| 503 | { | 515 | { |
| 504 | if (!public_key_b64 || !device_cert_b64 || !host_cert_b64 || !root_cert_b64) | 516 | if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert) |
| 505 | return IPHONE_E_INVALID_ARG; | 517 | return IPHONE_E_INVALID_ARG; |
| 506 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 518 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 507 | 519 | ||
| 508 | gnutls_datum_t modulus = { NULL, 0 }; | 520 | gnutls_datum_t modulus = { NULL, 0 }; |
| 509 | gnutls_datum_t exponent = { NULL, 0 }; | 521 | gnutls_datum_t exponent = { NULL, 0 }; |
| 510 | 522 | ||
| 511 | /* first decode base64 public_key */ | ||
| 512 | gnutls_datum_t pem_pub_key; | ||
| 513 | gsize decoded_size; | ||
| 514 | pem_pub_key.data = g_base64_decode(public_key_b64, &decoded_size); | ||
| 515 | pem_pub_key.size = decoded_size; | ||
| 516 | |||
| 517 | /* now decode the PEM encoded key */ | 523 | /* now decode the PEM encoded key */ |
| 518 | gnutls_datum_t der_pub_key; | 524 | gnutls_datum_t der_pub_key; |
| 519 | if (GNUTLS_E_SUCCESS == gnutls_pem_base64_decode_alloc("RSA PUBLIC KEY", &pem_pub_key, &der_pub_key)) { | 525 | if (GNUTLS_E_SUCCESS == gnutls_pem_base64_decode_alloc("RSA PUBLIC KEY", &public_key, &der_pub_key)) { |
| 520 | 526 | ||
| 521 | /* initalize asn.1 parser */ | 527 | /* initalize asn.1 parser */ |
| 522 | ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY; | 528 | ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY; |
| @@ -600,10 +606,18 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_ | |||
| 600 | dev_pem.data = gnutls_malloc(dev_pem.size); | 606 | dev_pem.data = gnutls_malloc(dev_pem.size); |
| 601 | gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &dev_pem.size); | 607 | gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &dev_pem.size); |
| 602 | 608 | ||
| 603 | /* now encode certificates for output */ | 609 | /* copy buffer for output */ |
| 604 | *device_cert_b64 = g_base64_encode(dev_pem.data, dev_pem.size); | 610 | odevice_cert->data = malloc(dev_pem.size); |
| 605 | *host_cert_b64 = g_base64_encode(pem_host_cert.data, pem_host_cert.size); | 611 | memcpy(odevice_cert->data, dev_pem.data, dev_pem.size); |
| 606 | *root_cert_b64 = g_base64_encode(pem_root_cert.data, pem_root_cert.size); | 612 | odevice_cert->size = dev_pem.size; |
| 613 | |||
| 614 | ohost_cert->data = malloc(pem_host_cert.size); | ||
| 615 | memcpy(ohost_cert->data, pem_host_cert.data, pem_host_cert.size); | ||
| 616 | ohost_cert->size = pem_host_cert.size; | ||
| 617 | |||
| 618 | oroot_cert->data = malloc(pem_root_cert.size); | ||
| 619 | memcpy(oroot_cert->data, pem_root_cert.data, pem_root_cert.size); | ||
| 620 | oroot_cert->size = pem_root_cert.size; | ||
| 607 | } | 621 | } |
| 608 | gnutls_free(pem_root_priv.data); | 622 | gnutls_free(pem_root_priv.data); |
| 609 | gnutls_free(pem_root_cert.data); | 623 | gnutls_free(pem_root_cert.data); |
| @@ -615,7 +629,6 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_ | |||
| 615 | gnutls_free(exponent.data); | 629 | gnutls_free(exponent.data); |
| 616 | 630 | ||
| 617 | gnutls_free(der_pub_key.data); | 631 | gnutls_free(der_pub_key.data); |
| 618 | g_free(pem_pub_key.data); | ||
| 619 | 632 | ||
| 620 | return ret; | 633 | return ret; |
| 621 | } | 634 | } |
| @@ -637,14 +650,14 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c | |||
| 637 | 650 | ||
| 638 | /* Setup DevicePublicKey request plist */ | 651 | /* Setup DevicePublicKey request plist */ |
| 639 | plist_new_dict(&dict); | 652 | plist_new_dict(&dict); |
| 640 | plist_add_dict_element(dict, "HostID", PLIST_STRING, (void *) HostID); | 653 | plist_add_dict_element(dict, "HostID", PLIST_STRING, (void *) HostID, strlen(HostID)); |
| 641 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "StartSession"); | 654 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "StartSession", strlen("StartSession")); |
| 642 | plist_to_xml(dict, &XML_content, &length); | 655 | plist_to_xml(dict, &XML_content, &length); |
| 643 | log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); | 656 | log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); |
| 644 | 657 | ||
| 645 | ret = iphone_lckd_send(control, XML_content, length, &bytes); | 658 | ret = iphone_lckd_send(control, XML_content, length, &bytes); |
| 646 | 659 | ||
| 647 | xmlFree(XML_content); | 660 | free(XML_content); |
| 648 | XML_content = NULL; | 661 | XML_content = NULL; |
| 649 | plist_free(dict); | 662 | plist_free(dict); |
| 650 | dict = NULL; | 663 | dict = NULL; |
| @@ -667,11 +680,13 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c | |||
| 667 | plist_type result_value_type; | 680 | plist_type result_value_type; |
| 668 | char *result_key = NULL; | 681 | char *result_key = NULL; |
| 669 | char *result_value = NULL; | 682 | char *result_value = NULL; |
| 683 | uint64_t key_length = 0; | ||
| 684 | uint64_t val_length = 0; | ||
| 670 | 685 | ||
| 671 | get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key)); | 686 | get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length); |
| 672 | get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value)); | 687 | get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length); |
| 673 | 688 | ||
| 674 | xmlFree(XML_content); | 689 | free(XML_content); |
| 675 | XML_content = NULL; | 690 | XML_content = NULL; |
| 676 | plist_free(dict); | 691 | plist_free(dict); |
| 677 | dict = NULL; | 692 | dict = NULL; |
| @@ -872,15 +887,15 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char | |||
| 872 | host_id = NULL; | 887 | host_id = NULL; |
| 873 | 888 | ||
| 874 | plist_new_dict(&dict); | 889 | plist_new_dict(&dict); |
| 875 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "StartService"); | 890 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "StartService", strlen("StartService")); |
| 876 | plist_add_dict_element(dict, "Service", PLIST_STRING, (void *) service); | 891 | plist_add_dict_element(dict, "Service", PLIST_STRING, (void *) service, strlen(service)); |
| 877 | plist_to_xml(dict, &XML_content, &length); | 892 | plist_to_xml(dict, &XML_content, &length); |
| 878 | 893 | ||
| 879 | /* send to iPhone */ | 894 | /* send to iPhone */ |
| 880 | log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); | 895 | log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); |
| 881 | ret = iphone_lckd_send(client, XML_content, length, &bytes); | 896 | ret = iphone_lckd_send(client, XML_content, length, &bytes); |
| 882 | 897 | ||
| 883 | xmlFree(XML_content); | 898 | free(XML_content); |
| 884 | XML_content = NULL; | 899 | XML_content = NULL; |
| 885 | plist_free(dict); | 900 | plist_free(dict); |
| 886 | dict = NULL; | 901 | dict = NULL; |
| @@ -916,12 +931,16 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char | |||
| 916 | char *result_key = NULL; | 931 | char *result_key = NULL; |
| 917 | char *result_value = NULL; | 932 | char *result_value = NULL; |
| 918 | char *port_key = NULL; | 933 | char *port_key = NULL; |
| 934 | uint64_t res_key_length = 0; | ||
| 935 | uint64_t res_val_length = 0; | ||
| 936 | uint64_t port_key_length = 0; | ||
| 937 | uint64_t port_val_length = 0; | ||
| 919 | uint64_t port_value = 0; | 938 | uint64_t port_value = 0; |
| 920 | 939 | ||
| 921 | get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key)); | 940 | get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &res_key_length); |
| 922 | get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value)); | 941 | get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &res_val_length); |
| 923 | get_type_and_value(port_key_node, &port_key_type, (void *) (&port_key)); | 942 | get_type_and_value(port_key_node, &port_key_type, (void *) (&port_key), &port_key_length); |
| 924 | get_type_and_value(port_value_node, &port_value_type, (void *) (&port_value)); | 943 | get_type_and_value(port_value_node, &port_value_type, (void *) (&port_value), &port_val_length); |
| 925 | 944 | ||
| 926 | if (result_key_type == PLIST_KEY && | 945 | if (result_key_type == PLIST_KEY && |
| 927 | result_value_type == PLIST_STRING && | 946 | result_value_type == PLIST_STRING && |
diff --git a/src/lockdown.h b/src/lockdown.h index b75d4bf..8b3dd41 100644 --- a/src/lockdown.h +++ b/src/lockdown.h | |||
| @@ -42,13 +42,14 @@ struct iphone_lckd_client_int { | |||
| 42 | 42 | ||
| 43 | iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone); | 43 | iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone); |
| 44 | iphone_error_t lockdownd_hello(iphone_lckd_client_t control); | 44 | iphone_error_t lockdownd_hello(iphone_lckd_client_t control); |
| 45 | iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, char *req_string, char **value); | 45 | iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, char *req_string, |
| 46 | gnutls_datum_t * value); | ||
| 46 | iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid); | 47 | iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid); |
| 47 | iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_key); | 48 | iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, gnutls_datum_t * public_key); |
| 48 | 49 | ||
| 49 | iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64, | 50 | iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * device_cert, |
| 50 | char **root_cert_b64); | 51 | gnutls_datum_t * host_cert, gnutls_datum_t * root_cert); |
| 51 | iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *public_key, char *host_id); | 52 | iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id); |
| 52 | void lockdownd_close(iphone_lckd_client_t control); | 53 | void lockdownd_close(iphone_lckd_client_t control); |
| 53 | 54 | ||
| 54 | // SSL functions | 55 | // SSL functions |
diff --git a/src/plist.c b/src/plist.c index 66a74c3..932ea5e 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -67,7 +67,7 @@ void plist_new_dict_in_plist(plist_t plist, plist_t * dict) | |||
| 67 | * @param value a pointer to the actual buffer containing the value. WARNING : the buffer is supposed to match the type of the value | 67 | * @param value a pointer to the actual buffer containing the value. WARNING : the buffer is supposed to match the type of the value |
| 68 | * | 68 | * |
| 69 | */ | 69 | */ |
| 70 | void plist_add_dict_element(plist_t dict, char *key, plist_type type, void *value) | 70 | void plist_add_dict_element(plist_t dict, char *key, plist_type type, void *value, uint64_t length) |
| 71 | { | 71 | { |
| 72 | if (!dict || !key || !value) | 72 | if (!dict || !key || !value) |
| 73 | return; | 73 | return; |
| @@ -81,6 +81,7 @@ void plist_add_dict_element(plist_t dict, char *key, plist_type type, void *valu | |||
| 81 | //now handle value | 81 | //now handle value |
| 82 | struct plist_data *val = (struct plist_data *) calloc(sizeof(struct plist_data), 1); | 82 | struct plist_data *val = (struct plist_data *) calloc(sizeof(struct plist_data), 1); |
| 83 | val->type = type; | 83 | val->type = type; |
| 84 | val->length = length; | ||
| 84 | 85 | ||
| 85 | switch (type) { | 86 | switch (type) { |
| 86 | case PLIST_BOOLEAN: | 87 | case PLIST_BOOLEAN: |
| @@ -99,7 +100,7 @@ void plist_add_dict_element(plist_t dict, char *key, plist_type type, void *valu | |||
| 99 | val->unicodeval = wcsdup((wchar_t *) value); | 100 | val->unicodeval = wcsdup((wchar_t *) value); |
| 100 | break; | 101 | break; |
| 101 | case PLIST_DATA: | 102 | case PLIST_DATA: |
| 102 | val->buff = strdup((char *) value); | 103 | memcpy(val->buff, value, length); |
| 103 | break; | 104 | break; |
| 104 | case PLIST_ARRAY: | 105 | case PLIST_ARRAY: |
| 105 | case PLIST_DICT: | 106 | case PLIST_DICT: |
| @@ -195,7 +196,7 @@ plist_t find_node(plist_t plist, plist_type type, void *value) | |||
| 195 | return NULL; | 196 | return NULL; |
| 196 | } | 197 | } |
| 197 | 198 | ||
| 198 | void get_type_and_value(GNode * node, plist_type * type, void *value) | 199 | void get_type_and_value(GNode * node, plist_type * type, void *value, uint64_t * length) |
| 199 | { | 200 | { |
| 200 | if (!node) | 201 | if (!node) |
| 201 | return; | 202 | return; |
| @@ -203,6 +204,7 @@ void get_type_and_value(GNode * node, plist_type * type, void *value) | |||
| 203 | struct plist_data *data = (struct plist_data *) node->data; | 204 | struct plist_data *data = (struct plist_data *) node->data; |
| 204 | 205 | ||
| 205 | *type = data->type; | 206 | *type = data->type; |
| 207 | *length = data->length; | ||
| 206 | 208 | ||
| 207 | switch (*type) { | 209 | switch (*type) { |
| 208 | case PLIST_BOOLEAN: | 210 | case PLIST_BOOLEAN: |
diff --git a/src/plist.h b/src/plist.h index ff4bdbf..1dc464a 100644 --- a/src/plist.h +++ b/src/plist.h | |||
| @@ -67,7 +67,7 @@ typedef GNode *plist_t; | |||
| 67 | void plist_new_dict(plist_t * plist); | 67 | void plist_new_dict(plist_t * plist); |
| 68 | void plist_new_array(plist_t * plist); | 68 | void plist_new_array(plist_t * plist); |
| 69 | void plist_new_dict_in_plist(plist_t plist, plist_t * dict); | 69 | void plist_new_dict_in_plist(plist_t plist, plist_t * dict); |
| 70 | void plist_add_dict_element(plist_t dict, char *key, plist_type type, void *value); | 70 | void plist_add_dict_element(plist_t dict, char *key, plist_type type, void *value, uint64_t length); |
| 71 | void plist_free(plist_t plist); | 71 | void plist_free(plist_t plist); |
| 72 | 72 | ||
| 73 | void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); | 73 | void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); |
| @@ -78,6 +78,6 @@ void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist); | |||
| 78 | 78 | ||
| 79 | plist_t find_query_node(plist_t plist, char *key, char *request); | 79 | plist_t find_query_node(plist_t plist, char *key, char *request); |
| 80 | plist_t find_node(plist_t plist, plist_type type, void *value); | 80 | plist_t find_node(plist_t plist, plist_type type, void *value); |
| 81 | void get_type_and_value(plist_t node, plist_type * type, void *value); | 81 | void get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length); |
| 82 | 82 | ||
| 83 | #endif | 83 | #endif |
diff --git a/src/userpref.c b/src/userpref.c index db54679..b707957 100644 --- a/src/userpref.c +++ b/src/userpref.c | |||
| @@ -114,10 +114,10 @@ int is_device_known(char *uid) | |||
| 114 | * @return 1 on success and 0 if no public key is given or if it has already | 114 | * @return 1 on success and 0 if no public key is given or if it has already |
| 115 | * been marked as connected previously. | 115 | * been marked as connected previously. |
| 116 | */ | 116 | */ |
| 117 | int store_device_public_key(char *uid, char *public_key) | 117 | int store_device_public_key(char *uid, gnutls_datum_t public_key) |
| 118 | { | 118 | { |
| 119 | 119 | ||
| 120 | if (NULL == public_key || is_device_known(uid)) | 120 | if (NULL == public_key.data || is_device_known(uid)) |
| 121 | return 0; | 121 | return 0; |
| 122 | 122 | ||
| 123 | /* ensure config directory exists */ | 123 | /* ensure config directory exists */ |
| @@ -127,15 +127,11 @@ int store_device_public_key(char *uid, char *public_key) | |||
| 127 | gchar *device_file = g_strconcat(uid, ".pem", NULL); | 127 | gchar *device_file = g_strconcat(uid, ".pem", NULL); |
| 128 | gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); | 128 | gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); |
| 129 | 129 | ||
| 130 | /* decode public key for storing */ | ||
| 131 | gsize decoded_size; | ||
| 132 | gchar *data = g_base64_decode(public_key, &decoded_size); | ||
| 133 | /* store file */ | 130 | /* store file */ |
| 134 | FILE *pFile = fopen(pem, "wb"); | 131 | FILE *pFile = fopen(pem, "wb"); |
| 135 | fwrite(data, 1, decoded_size, pFile); | 132 | fwrite(public_key.data, 1, public_key.size, pFile); |
| 136 | fclose(pFile); | 133 | fclose(pFile); |
| 137 | g_free(pem); | 134 | g_free(pem); |
| 138 | g_free(data); | ||
| 139 | g_free(device_file); | 135 | g_free(device_file); |
| 140 | return 1; | 136 | return 1; |
| 141 | } | 137 | } |
diff --git a/src/userpref.h b/src/userpref.h index 5171929..450549f 100644 --- a/src/userpref.h +++ b/src/userpref.h | |||
| @@ -40,7 +40,7 @@ int is_device_known(char *uid); | |||
| 40 | /** | 40 | /** |
| 41 | * @return 1 if everything went well. Returns 0 otherwise. | 41 | * @return 1 if everything went well. Returns 0 otherwise. |
| 42 | */ | 42 | */ |
| 43 | int store_device_public_key(char *uid, char *public_key); | 43 | int store_device_public_key(char *uid, gnutls_datum_t public_key); |
| 44 | 44 | ||
| 45 | /** | 45 | /** |
| 46 | * @return 1 if everything went well. Returns 0 otherwise. | 46 | * @return 1 if everything went well. Returns 0 otherwise. |
diff --git a/src/xplist.c b/src/xplist.c index 3e975f6..2d650b4 100644 --- a/src/xplist.c +++ b/src/xplist.c | |||
| @@ -165,7 +165,9 @@ void node_to_xml(GNode * node, gpointer xml_struct) | |||
| 165 | 165 | ||
| 166 | case PLIST_DATA: | 166 | case PLIST_DATA: |
| 167 | tag = "data"; | 167 | tag = "data"; |
| 168 | val = format_string(node_data->buff, 60, xstruct->depth); | 168 | gchar *valtmp = g_base64_encode(node_data->buff, node_data->length); |
| 169 | val = format_string(valtmp, 60, xstruct->depth); | ||
| 170 | g_free(valtmp); | ||
| 169 | break; | 171 | break; |
| 170 | case PLIST_ARRAY: | 172 | case PLIST_ARRAY: |
| 171 | tag = "array"; | 173 | tag = "array"; |
| @@ -267,7 +269,9 @@ void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) | |||
| 267 | } | 269 | } |
| 268 | 270 | ||
| 269 | if (!xmlStrcmp(node->name, "data")) { | 271 | if (!xmlStrcmp(node->name, "data")) { |
| 270 | data->buff = strdup(xmlNodeGetContent(node)); | 272 | gsize size = 0; |
| 273 | data->buff = g_base64_decode(xmlNodeGetContent(node), &size); | ||
| 274 | data->length = size; | ||
| 271 | data->type = PLIST_DATA; | 275 | data->type = PLIST_DATA; |
| 272 | continue; | 276 | continue; |
| 273 | } | 277 | } |
