summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--dev/Makefile.am3
-rw-r--r--dev/lckdclient.c1
-rw-r--r--dev/main.c2
-rw-r--r--src/AFC.c51
-rw-r--r--src/AFC.h10
-rw-r--r--src/Makefile.am8
-rw-r--r--src/initconf.c30
-rw-r--r--src/lockdown.c639
-rw-r--r--src/lockdown.h15
-rw-r--r--src/plist.c245
-rw-r--r--src/plist.h38
-rw-r--r--src/usbmux.c2
-rw-r--r--src/usbmux.h20
-rw-r--r--src/userpref.c10
-rw-r--r--src/userpref.h2
-rw-r--r--src/utils.c2
17 files changed, 408 insertions, 671 deletions
diff --git a/configure.ac b/configure.ac
index 286b1d8..9516ec4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,7 @@ PKG_CHECK_MODULES(libglib2, glib-2.0 >= 2.14.1)
20PKG_CHECK_MODULES(libgthread2, gthread-2.0 >= 2.14.1) 20PKG_CHECK_MODULES(libgthread2, gthread-2.0 >= 2.14.1)
21PKG_CHECK_MODULES(libgnutls, gnutls >= 1.6.3 gnutls <= 2.5.0 ) 21PKG_CHECK_MODULES(libgnutls, gnutls >= 1.6.3 gnutls <= 2.5.0 )
22PKG_CHECK_MODULES(libtasn1, libtasn1 >= 1.1) 22PKG_CHECK_MODULES(libtasn1, libtasn1 >= 1.1)
23PKG_CHECK_MODULES(libplist, libplist-1.0 >= 0.1.0)
23 24
24# Checks for header files. 25# Checks for header files.
25AC_HEADER_STDC 26AC_HEADER_STDC
diff --git a/dev/Makefile.am b/dev/Makefile.am
index 4833728..d116581 100644
--- a/dev/Makefile.am
+++ b/dev/Makefile.am
@@ -16,4 +16,5 @@ lckd_client_LDADD = ../src/libiphone.la
16afccheck_SOURCES = afccheck.c 16afccheck_SOURCES = afccheck.c
17afccheck_CFLAGS = $(AM_CFLAGS) 17afccheck_CFLAGS = $(AM_CFLAGS)
18afccheck_LDFLAGS = $(AM_LDFLAGS) 18afccheck_LDFLAGS = $(AM_LDFLAGS)
19afccheck_LDADD = ../src/libiphone.la \ No newline at end of file 19afccheck_LDADD = ../src/libiphone.la
20
diff --git a/dev/lckdclient.c b/dev/lckdclient.c
index 96bc27d..c96f052 100644
--- a/dev/lckdclient.c
+++ b/dev/lckdclient.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <stdio.h> 22#include <stdio.h>
23#include <stdlib.h>
23#include <string.h> 24#include <string.h>
24#include <glib.h> 25#include <glib.h>
25#include <readline/readline.h> 26#include <readline/readline.h>
diff --git a/dev/main.c b/dev/main.c
index 2dbfb4a..4974eef 100644
--- a/dev/main.c
+++ b/dev/main.c
@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
87 iphone_afc_get_file_attr(afc, "/iTunesOnTheGoPlaylist.plist", &stbuf); 87 iphone_afc_get_file_attr(afc, "/iTunesOnTheGoPlaylist.plist", &stbuf);
88 if (IPHONE_E_SUCCESS == 88 if (IPHONE_E_SUCCESS ==
89 iphone_afc_open_file(afc, "/iTunesOnTheGoPlaylist.plist", IPHONE_AFC_FILE_READ, &my_file) && my_file) { 89 iphone_afc_open_file(afc, "/iTunesOnTheGoPlaylist.plist", IPHONE_AFC_FILE_READ, &my_file) && my_file) {
90 printf("A file size: %i\n", stbuf.st_size); 90 printf("A file size: %i\n", (int) stbuf.st_size);
91 char *file_data = (char *) malloc(sizeof(char) * stbuf.st_size); 91 char *file_data = (char *) malloc(sizeof(char) * stbuf.st_size);
92 iphone_afc_read_file(afc, my_file, file_data, stbuf.st_size, &bytes); 92 iphone_afc_read_file(afc, my_file, file_data, stbuf.st_size, &bytes);
93 if (bytes >= 0) { 93 if (bytes >= 0) {
diff --git a/src/AFC.c b/src/AFC.c
index 6027ed2..a1f7a08 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -21,8 +21,7 @@
21 21
22#include <stdio.h> 22#include <stdio.h>
23#include "AFC.h" 23#include "AFC.h"
24#include "plist.h" 24
25#include "utils.h"
26 25
27 26
28// This is the maximum size an AFC data packet can be 27// This is the maximum size an AFC data packet can be
@@ -246,7 +245,7 @@ static int receive_AFC_data(iphone_afc_client_t client, char **dump_here)
246 return retval; 245 return retval;
247 } 246 }
248 247
249 uint32 param1 = buffer[sizeof(AFCPacket)]; 248 uint32_t param1 = buffer[sizeof(AFCPacket)];
250 free(buffer); 249 free(buffer);
251 250
252 if (r_packet->operation == AFC_ERROR && !(client->afc_packet->operation == AFC_DELETE && param1 == 7)) { 251 if (r_packet->operation == AFC_ERROR && !(client->afc_packet->operation == AFC_DELETE && param1 == 7)) {
@@ -475,7 +474,7 @@ iphone_error_t iphone_afc_delete_file(iphone_afc_client_t client, const char *pa
475iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *from, const char *to) 474iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *from, const char *to)
476{ 475{
477 char *response = NULL; 476 char *response = NULL;
478 char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32))); 477 char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t)));
479 int bytes = 0; 478 int bytes = 0;
480 479
481 if (!client || !from || !to || !client->afc_packet || !client->connection) 480 if (!client || !from || !to || !client->afc_packet || !client->connection)
@@ -661,7 +660,7 @@ iphone_afc_open_file(iphone_afc_client_t client, const char *filename,
661 iphone_afc_file_mode_t file_mode, iphone_afc_file_t * file) 660 iphone_afc_file_mode_t file_mode, iphone_afc_file_t * file)
662{ 661{
663 iphone_afc_file_t file_loc = NULL; 662 iphone_afc_file_t file_loc = NULL;
664 uint32 ag = 0; 663 uint32_t ag = 0;
665 int bytes = 0, length = 0; 664 int bytes = 0, length = 0;
666 char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); 665 char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1));
667 666
@@ -796,8 +795,8 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
796{ 795{
797 char *acknowledgement = NULL; 796 char *acknowledgement = NULL;
798 const int MAXIMUM_WRITE_SIZE = 1 << 15; 797 const int MAXIMUM_WRITE_SIZE = 1 << 15;
799 uint32 zero = 0, current_count = 0, i = 0; 798 uint32_t zero = 0, current_count = 0, i = 0;
800 uint32 segments = (length / MAXIMUM_WRITE_SIZE); 799 uint32_t segments = (length / MAXIMUM_WRITE_SIZE);
801 int bytes_loc = 0; 800 int bytes_loc = 0;
802 char *out_buffer = NULL; 801 char *out_buffer = NULL;
803 802
@@ -815,8 +814,8 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
815 client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE; 814 client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE;
816 client->afc_packet->operation = AFC_WRITE; 815 client->afc_packet->operation = AFC_WRITE;
817 out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); 816 out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket));
818 memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32)); 817 memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32_t));
819 memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32)); 818 memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32_t));
820 memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE); 819 memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE);
821 bytes_loc = dispatch_AFC_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8); 820 bytes_loc = dispatch_AFC_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8);
822 if (bytes_loc < 0) { 821 if (bytes_loc < 0) {
@@ -848,8 +847,8 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,
848 client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count); 847 client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count);
849 client->afc_packet->operation = AFC_WRITE; 848 client->afc_packet->operation = AFC_WRITE;
850 out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); 849 out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket));
851 memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32)); 850 memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32_t));
852 memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32)); 851 memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32_t));
853 memcpy(out_buffer + 8, data + current_count, (length - current_count)); 852 memcpy(out_buffer + 8, data + current_count, (length - current_count));
854 bytes_loc = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8); 853 bytes_loc = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8);
855 free(out_buffer); 854 free(out_buffer);
@@ -884,7 +883,7 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file
884 if (!client || !file) 883 if (!client || !file)
885 return IPHONE_E_INVALID_ARG; 884 return IPHONE_E_INVALID_ARG;
886 char *buffer = malloc(sizeof(char) * 8); 885 char *buffer = malloc(sizeof(char) * 8);
887 uint32 zero = 0; 886 uint32_t zero = 0;
888 int bytes = 0; 887 int bytes = 0;
889 888
890 afc_lock(client); 889 afc_lock(client);
@@ -892,8 +891,8 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file
892 log_debug_msg("afc_close_file: File handle %i\n", file->filehandle); 891 log_debug_msg("afc_close_file: File handle %i\n", file->filehandle);
893 892
894 // Send command 893 // Send command
895 memcpy(buffer, &file->filehandle, sizeof(uint32)); 894 memcpy(buffer, &file->filehandle, sizeof(uint32_t));
896 memcpy(buffer + sizeof(uint32), &zero, sizeof(zero)); 895 memcpy(buffer + sizeof(uint32_t), &zero, sizeof(zero));
897 client->afc_packet->operation = AFC_FILE_CLOSE; 896 client->afc_packet->operation = AFC_FILE_CLOSE;
898 client->afc_packet->entire_length = client->afc_packet->this_length = 0; 897 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
899 bytes = dispatch_AFC_packet(client, buffer, sizeof(char) * 8); 898 bytes = dispatch_AFC_packet(client, buffer, sizeof(char) * 8);
@@ -929,7 +928,7 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file
929iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_t file, int seekpos) 928iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_t file, int seekpos)
930{ 929{
931 char *buffer = (char *) malloc(sizeof(char) * 24); 930 char *buffer = (char *) malloc(sizeof(char) * 24);
932 uint32 seekto = 0, zero = 0; 931 uint32_t seekto = 0, zero = 0;
933 int bytes = 0; 932 int bytes = 0;
934 933
935 if (seekpos < 0) 934 if (seekpos < 0)
@@ -939,12 +938,12 @@ iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_
939 938
940 // Send the command 939 // Send the command
941 seekto = seekpos; 940 seekto = seekpos;
942 memcpy(buffer, &file->filehandle, sizeof(uint32)); // handle 941 memcpy(buffer, &file->filehandle, sizeof(uint32_t)); // handle
943 memcpy(buffer + 4, &zero, sizeof(uint32)); // pad 942 memcpy(buffer + 4, &zero, sizeof(uint32_t)); // pad
944 memcpy(buffer + 8, &zero, sizeof(uint32)); // fromwhere 943 memcpy(buffer + 8, &zero, sizeof(uint32_t)); // fromwhere
945 memcpy(buffer + 12, &zero, sizeof(uint32)); // pad 944 memcpy(buffer + 12, &zero, sizeof(uint32_t)); // pad
946 memcpy(buffer + 16, &seekto, sizeof(uint32)); // offset 945 memcpy(buffer + 16, &seekto, sizeof(uint32_t)); // offset
947 memcpy(buffer + 20, &zero, sizeof(uint32)); // pad 946 memcpy(buffer + 20, &zero, sizeof(uint32_t)); // pad
948 client->afc_packet->operation = AFC_FILE_SEEK; 947 client->afc_packet->operation = AFC_FILE_SEEK;
949 client->afc_packet->this_length = client->afc_packet->entire_length = 0; 948 client->afc_packet->this_length = client->afc_packet->entire_length = 0;
950 bytes = dispatch_AFC_packet(client, buffer, 23); 949 bytes = dispatch_AFC_packet(client, buffer, 23);
@@ -984,14 +983,14 @@ iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_f
984{ 983{
985 char *buffer = (char *) malloc(sizeof(char) * 16); 984 char *buffer = (char *) malloc(sizeof(char) * 16);
986 int bytes = 0; 985 int bytes = 0;
987 uint32 zero = 0; 986 uint32_t zero = 0;
988 987
989 afc_lock(client); 988 afc_lock(client);
990 989
991 // Send command 990 // Send command
992 memcpy(buffer, &file->filehandle, sizeof(uint32)); // handle 991 memcpy(buffer, &file->filehandle, sizeof(uint32_t)); // handle
993 memcpy(buffer + 4, &zero, sizeof(uint32)); // pad 992 memcpy(buffer + 4, &zero, sizeof(uint32_t)); // pad
994 memcpy(buffer + 8, &newsize, sizeof(uint32)); // newsize 993 memcpy(buffer + 8, &newsize, sizeof(uint32_t)); // newsize
995 memcpy(buffer + 12, &zero, 3); // pad 994 memcpy(buffer + 12, &zero, 3); // pad
996 client->afc_packet->operation = AFC_FILE_TRUNCATE; 995 client->afc_packet->operation = AFC_FILE_TRUNCATE;
997 client->afc_packet->this_length = client->afc_packet->entire_length = 0; 996 client->afc_packet->this_length = client->afc_packet->entire_length = 0;
@@ -1017,7 +1016,7 @@ iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_f
1017 } 1016 }
1018} 1017}
1019 1018
1020uint32 iphone_afc_get_file_handle(iphone_afc_file_t file) 1019uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file)
1021{ 1020{
1022 return file->filehandle; 1021 return file->filehandle;
1023} 1022}
diff --git a/src/AFC.h b/src/AFC.h
index 463c13e..5e4d17c 100644
--- a/src/AFC.h
+++ b/src/AFC.h
@@ -29,12 +29,12 @@
29#include <glib.h> 29#include <glib.h>
30 30
31typedef struct { 31typedef struct {
32 uint32 header1, header2; 32 uint32_t header1, header2;
33 uint32 entire_length, unknown1, this_length, unknown2, packet_num, unknown3, operation, unknown4; 33 uint32_t entire_length, unknown1, this_length, unknown2, packet_num, unknown3, operation, unknown4;
34} AFCPacket; 34} AFCPacket;
35 35
36typedef struct { 36typedef struct {
37 uint32 filehandle, unknown1, size, unknown2; 37 uint32_t filehandle, unknown1, size, unknown2;
38} AFCFilePacket; 38} AFCFilePacket;
39 39
40typedef struct __AFCToken { 40typedef struct __AFCToken {
@@ -51,7 +51,7 @@ struct iphone_afc_client_int {
51}; 51};
52 52
53struct iphone_afc_file_int { 53struct iphone_afc_file_int {
54 uint32 filehandle, blocks, size, type; 54 uint32_t filehandle, blocks, size, type;
55}; 55};
56 56
57 57
@@ -74,4 +74,4 @@ enum {
74 AFC_WRITE = 0x00000010 74 AFC_WRITE = 0x00000010
75}; 75};
76 76
77uint32 iphone_afc_get_file_handle(iphone_afc_file_t file); 77uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file);
diff --git a/src/Makefile.am b/src/Makefile.am
index 785aacf..2514367 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,15 +1,15 @@
1INCLUDES = -I$(top_srcdir)/include 1INCLUDES = -I$(top_srcdir)/include
2 2
3AM_CFLAGS = $(libxml2_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) -g 3AM_CFLAGS = $(libxml2_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) -g
4AM_LDFLAGS = $(libxml2_LIBS) $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) 4AM_LDFLAGS = $(libxml2_LIBS) $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS)
5 5
6bin_PROGRAMS = libiphone-initconf 6bin_PROGRAMS = libiphone-initconf
7 7
8 8
9libiphone_initconf_SOURCES = initconf.c userpref.c lockdown.c plist.c usbmux.c iphone.c utils.c 9libiphone_initconf_SOURCES = initconf.c userpref.c utils.c
10libiphone_initconf_CFLAGS = $(libgthread2_CFLAGS) $(AM_CFLAGS) 10libiphone_initconf_CFLAGS = $(libgthread2_CFLAGS) $(AM_CFLAGS)
11libiphone_initconf_LDFLAGS = $(libgthread2_LIBS) $(AM_LDFLAGS) 11libiphone_initconf_LDFLAGS = $(libgthread2_LIBS) $(AM_LDFLAGS)
12 12
13 13
14lib_LTLIBRARIES = libiphone.la 14lib_LTLIBRARIES = libiphone.la
15libiphone_la_SOURCES = usbmux.c iphone.c plist.c lockdown.c AFC.c userpref.c utils.c 15libiphone_la_SOURCES = usbmux.c iphone.c lockdown.c AFC.c userpref.c utils.c
diff --git a/src/initconf.c b/src/initconf.c
index 205c97a..538f344 100644
--- a/src/initconf.c
+++ b/src/initconf.c
@@ -28,7 +28,6 @@
28 28
29#include "libiphone/libiphone.h" 29#include "libiphone/libiphone.h"
30#include "userpref.h" 30#include "userpref.h"
31#include "lockdown.h"
32#include "utils.h" 31#include "utils.h"
33 32
34/** Generates a 2048 byte key, split into a function so that it can be run in a 33/** Generates a 2048 byte key, split into a function so that it can be run in a
@@ -60,6 +59,35 @@ static void progress_bar(gpointer mutex)
60 g_thread_exit(0); 59 g_thread_exit(0);
61} 60}
62 61
62int get_rand(int min, int max)
63{
64 int retval = (rand() % (max - min)) + min;
65 return retval;
66}
67
68/** Generates a valid HostID (which is actually a UUID).
69 *
70 * @param A null terminated string containing a valid HostID.
71 */
72char *lockdownd_generate_hostid()
73{
74 char *hostid = (char *) malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long
75 const char *chars = "ABCDEF0123456789";
76 srand(time(NULL));
77 int i = 0;
78
79 for (i = 0; i < 36; i++) {
80 if (i == 8 || i == 13 || i == 18 || i == 23) {
81 hostid[i] = '-';
82 continue;
83 } else {
84 hostid[i] = chars[get_rand(0, 16)];
85 }
86 }
87 hostid[36] = '\0'; // make it a real string
88 return hostid;
89}
90
63int main(int argc, char *argv[]) 91int main(int argc, char *argv[])
64{ 92{
65 GThread *progress_thread, *key_thread; 93 GThread *progress_thread, *key_thread;
diff --git a/src/lockdown.c b/src/lockdown.c
index cf0d99e..c6d5f80 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -31,6 +31,8 @@
31#include <libtasn1.h> 31#include <libtasn1.h>
32#include <gnutls/x509.h> 32#include <gnutls/x509.h>
33 33
34#include <plist/plist.h>
35
34const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = { 36const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = {
35 {"PKCS1", 536872976, 0}, 37 {"PKCS1", 536872976, 0},
36 {0, 1073741836, 0}, 38 {0, 1073741836, 0},
@@ -40,35 +42,6 @@ const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = {
40 {0, 0, 0} 42 {0, 0, 0}
41}; 43};
42 44
43static int get_rand(int min, int max)
44{
45 int retval = (rand() % (max - min)) + min;
46 return retval;
47}
48
49/** Generates a valid HostID (which is actually a UUID).
50 *
51 * @param A null terminated string containing a valid HostID.
52 */
53char *lockdownd_generate_hostid(void)
54{
55 char *hostid = (char *) malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long
56 const char *chars = "ABCDEF0123456789";
57 srand(time(NULL));
58 int i = 0;
59
60 for (i = 0; i < 36; i++) {
61 if (i == 8 || i == 13 || i == 18 || i == 23) {
62 hostid[i] = '-';
63 continue;
64 } else {
65 hostid[i] = chars[get_rand(0, 16)];
66 }
67 }
68 hostid[36] = '\0'; // make it a real string
69 return hostid;
70}
71
72/** Creates a lockdownd client for the give iPhone. 45/** Creates a lockdownd client for the give iPhone.
73 * 46 *
74 * @param phone The iPhone to create a lockdownd client for 47 * @param phone The iPhone to create a lockdownd client for
@@ -92,7 +65,6 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone)
92 return control; 65 return control;
93} 66}
94 67
95
96/** Closes the lockdownd client and does the necessary housekeeping. 68/** Closes the lockdownd client and does the necessary housekeeping.
97 * 69 *
98 * @param control The lockdown client 70 * @param control The lockdown client
@@ -128,7 +100,7 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, char **dump_data, u
128 return IPHONE_E_INVALID_ARG; 100 return IPHONE_E_INVALID_ARG;
129 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 101 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
130 char *receive; 102 char *receive;
131 uint32 datalen = 0, bytes = 0; 103 uint32_t datalen = 0, bytes = 0;
132 104
133 if (!client->in_SSL) 105 if (!client->in_SSL)
134 ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes); 106 ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes);
@@ -202,49 +174,55 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control)
202{ 174{
203 if (!control) 175 if (!control)
204 return IPHONE_E_INVALID_ARG; 176 return IPHONE_E_INVALID_ARG;
205 xmlDocPtr plist = new_plist(); 177
206 xmlNode *dict, *key;
207 char **dictionary;
208 int bytes = 0, i = 0; 178 int bytes = 0, i = 0;
209 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 179 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
210 180
181 plist_t dict = plist_new_dict();
182 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request"));
183 plist_add_sub_element(dict, PLIST_STRING, (void *) "QueryType", strlen("QueryType"));
184
211 log_debug_msg("lockdownd_hello() called\n"); 185 log_debug_msg("lockdownd_hello() called\n");
212 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 186 char *XML_content = NULL;
213 key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1); 187 uint32_t length = 0;
214 char *XML_content;
215 uint32 length;
216 188
217 xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); 189 plist_to_xml(dict, &XML_content, &length);
190 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);
218 ret = iphone_lckd_send(control, XML_content, length, &bytes); 191 ret = iphone_lckd_send(control, XML_content, length, &bytes);
219 192
220 xmlFree(XML_content); 193 free(XML_content);
221 xmlFreeDoc(plist); 194 XML_content = NULL;
222 plist = NULL; 195 plist_free(dict);
196 dict = NULL;
197
223 ret = iphone_lckd_recv(control, &XML_content, &bytes); 198 ret = iphone_lckd_recv(control, &XML_content, &bytes);
199 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content);
200 plist_from_xml(XML_content, bytes, &dict);
224 201
225 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0);
226 if (!plist)
227 return IPHONE_E_PLIST_ERROR;
228 dict = xmlDocGetRootElement(plist);
229 for (dict = dict->children; dict; dict = dict->next) {
230 if (!xmlStrcmp(dict->name, "dict"))
231 break;
232 }
233 if (!dict) 202 if (!dict)
234 return IPHONE_E_DICT_ERROR; 203 return IPHONE_E_PLIST_ERROR;
235 dictionary = read_dict_element_strings(dict);
236 xmlFreeDoc(plist);
237 free(XML_content);
238 204
239 for (i = 0; dictionary[i]; i += 2) { 205 plist_t query_node = plist_find_node(dict, PLIST_STRING, "QueryType", strlen("QueryType"));
240 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) { 206 plist_t result_node = plist_get_next_sibling(query_node);
241 log_debug_msg("lockdownd_hello(): success\n"); 207 plist_t value_node = plist_get_next_sibling(result_node);
242 ret = IPHONE_E_SUCCESS; 208
243 break; 209 plist_type result_type;
244 } 210 plist_type value_type;
211
212 char *result_value = NULL;
213 char *value_value = NULL;
214 uint64_t result_length = 0;
215 uint64_t value_length = 0;
216
217 plist_get_type_and_value(result_node, &result_type, (void *) (&result_value), &result_length);
218 plist_get_type_and_value(value_node, &value_type, (void *) (&value_value), &value_length);
219
220 if (result_type == PLIST_KEY &&
221 value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) {
222 log_debug_msg("lockdownd_hello(): success\n");
223 ret = IPHONE_E_SUCCESS;
245 } 224 }
246 225
247 free_dictionary(dictionary);
248 return ret; 226 return ret;
249} 227}
250 228
@@ -256,74 +234,94 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control)
256 * 234 *
257 * @return IPHONE_E_SUCCESS on success. 235 * @return IPHONE_E_SUCCESS on success.
258 */ 236 */
259iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const char *req_key, const char *req_string, 237iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const char *req_key, char *req_string,
260 char **value) 238 gnutls_datum_t * value)
261{ 239{
262 if (!control || !req_key || !value || (value && *value)) 240 if (!control || !req_key || !value || value->data)
263 return IPHONE_E_INVALID_ARG; 241 return IPHONE_E_INVALID_ARG;
264 xmlDocPtr plist = new_plist(); 242
265 xmlNode *dict = NULL; 243 plist_t dict = NULL;
266 xmlNode *key = NULL;;
267 char **dictionary = NULL;
268 int bytes = 0, i = 0; 244 int bytes = 0, i = 0;
269 char *XML_content = NULL; 245 char *XML_content = NULL;
270 uint32 length = 0; 246 uint32_t length = 0;
271 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 247 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
272 248
273 /* Setup DevicePublicKey request plist */ 249 /* Setup DevicePublicKey request plist */
274 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 250 dict = plist_new_dict();
275 key = add_key_str_dict_element(plist, dict, req_key, req_string, 1); 251 plist_add_sub_element(dict, PLIST_KEY, (void *) req_key, strlen(req_key));
276 key = add_key_str_dict_element(plist, dict, "Request", "GetValue", 1); 252 plist_add_sub_element(dict, PLIST_STRING, (void *) req_string, strlen(req_string));
277 xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); 253 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request"));
254 plist_add_sub_element(dict, PLIST_STRING, (void *) "GetValue", strlen("GetValue"));
255 plist_to_xml(dict, &XML_content, &length);
278 256
279 /* send to iPhone */ 257 /* send to iPhone */
258 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);
280 ret = iphone_lckd_send(control, XML_content, length, &bytes); 259 ret = iphone_lckd_send(control, XML_content, length, &bytes);
281 260
282 xmlFree(XML_content); 261 free(XML_content);
283 xmlFreeDoc(plist); 262 XML_content = NULL;
284 plist = NULL; 263 plist_free(dict);
264 dict = NULL;
285 265
286 if (ret != IPHONE_E_SUCCESS) 266 if (ret != IPHONE_E_SUCCESS)
287 return ret; 267 return ret;
288 268
289 /* Now get iPhone's answer */ 269 /* Now get iPhone's answer */
290 ret = iphone_lckd_recv(control, &XML_content, &bytes); 270 ret = iphone_lckd_recv(control, &XML_content, &bytes);
271 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content);
291 272
292 if (ret != IPHONE_E_SUCCESS) 273 if (ret != IPHONE_E_SUCCESS)
293 return ret; 274 return ret;
294 275
295 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 276 plist_from_xml(XML_content, bytes, &dict);
296 if (!plist)
297 return IPHONE_E_PLIST_ERROR;
298 dict = xmlDocGetRootElement(plist);
299 for (dict = dict->children; dict; dict = dict->next) {
300 if (!xmlStrcmp(dict->name, "dict"))
301 break;
302 }
303 if (!dict) 277 if (!dict)
304 return IPHONE_E_DICT_ERROR; 278 return IPHONE_E_PLIST_ERROR;
305 279
306 /* Parse xml to check success and to find public key */ 280 plist_t query_node = plist_find_node(dict, PLIST_STRING, "GetValue", strlen("GetValue"));
307 dictionary = read_dict_element_strings(dict); 281 plist_t result_key_node = plist_get_next_sibling(query_node);
308 xmlFreeDoc(plist); 282 plist_t result_value_node = plist_get_next_sibling(result_key_node);
309 free(XML_content);
310 283
311 int success = 0; 284 plist_type result_key_type;
312 for (i = 0; dictionary[i]; i += 2) { 285 plist_type result_value_type;
313 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) { 286 char *result_key = NULL;
314 success = 1; 287 char *result_value = NULL;
315 } 288 uint64_t result_length = 0;
316 if (!strcmp(dictionary[i], "Value")) { 289 uint64_t value_length = 0;
317 *value = strdup(dictionary[i + 1]); 290
318 } 291 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &result_length);
292 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &value_length);
293
294 if (result_key_type == PLIST_KEY &&
295 result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) {
296 log_debug_msg("lockdownd_generic_get_value(): success\n");
297 ret = IPHONE_E_SUCCESS;
319 } 298 }
320 299
321 if (dictionary) { 300 if (ret != IPHONE_E_SUCCESS) {
322 free_dictionary(dictionary); 301 return IPHONE_E_DICT_ERROR;
323 dictionary = NULL;
324 } 302 }
325 if (success) 303
304 plist_t value_key_node = plist_get_next_sibling(result_key_node);
305 plist_t value_value_node = plist_get_next_sibling(value_key_node);
306 plist_type value_key_type;
307 plist_type value_value_type;
308 char *value_key = NULL;
309 char *value_value = NULL;
310 uint64_t key_length = 0;
311 uint64_t valval_length = 0;
312
313 plist_get_type_and_value(value_key_node, &value_key_type, (void *) (&value_key), &key_length);
314 plist_get_type_and_value(value_value_node, &value_value_type, (void *) (&value_value), &valval_length);
315
316 if (value_key_type == PLIST_KEY && !strcmp(result_key, "Value")) {
317 log_debug_msg("lockdownd_generic_get_value(): success\n");
318 value->data = value_value;
319 value->size = valval_length;
326 ret = IPHONE_E_SUCCESS; 320 ret = IPHONE_E_SUCCESS;
321 }
322
323 plist_free(dict);
324 free(XML_content);
327 return ret; 325 return ret;
328} 326}
329 327
@@ -335,7 +333,9 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c
335 */ 333 */
336iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid) 334iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid)
337{ 335{
338 return lockdownd_generic_get_value(control, "Key", "UniqueDeviceID", uid); 336 gnutls_datum_t temp = { NULL, 0 };
337 return lockdownd_generic_get_value(control, "Key", "UniqueDeviceID", &temp);
338 *uid = temp.data;
339} 339}
340 340
341/** Askes for the device's public key. Part of the lockdownd handshake. 341/** Askes for the device's public key. Part of the lockdownd handshake.
@@ -344,7 +344,7 @@ iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid
344 * 344 *
345 * @return 1 on success and 0 on failure. 345 * @return 1 on success and 0 on failure.
346 */ 346 */
347iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_key) 347iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, gnutls_datum_t * public_key)
348{ 348{
349 return lockdownd_generic_get_value(control, "Key", "DevicePublicKey", public_key); 349 return lockdownd_generic_get_value(control, "Key", "DevicePublicKey", public_key);
350} 350}
@@ -416,51 +416,52 @@ iphone_error_t iphone_lckd_new_client(iphone_device_t device, iphone_lckd_client
416iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id) 416iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id)
417{ 417{
418 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 418 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
419 xmlDocPtr plist = new_plist(); 419 plist_t dict = NULL;
420 xmlNode *dict = NULL; 420 plist_t dict_record = NULL;
421 xmlNode *dictRecord = NULL;
422 char **dictionary = NULL;
423 int bytes = 0, i = 0; 421 int bytes = 0, i = 0;
424 char *XML_content = NULL; 422 char *XML_content = NULL;
425 uint32 length = 0; 423 uint32_t length = 0;
426 424
427 char *device_cert_b64 = NULL; 425 gnutls_datum_t device_cert = { NULL, 0 };
428 char *host_cert_b64 = NULL; 426 gnutls_datum_t host_cert = { NULL, 0 };
429 char *root_cert_b64 = NULL; 427 gnutls_datum_t root_cert = { NULL, 0 };
430 char *public_key_b64 = NULL; 428 gnutls_datum_t public_key = { NULL, 0 };
431 429
432 ret = lockdownd_get_device_public_key(control, &public_key_b64); 430 ret = lockdownd_get_device_public_key(control, &public_key);
433 if (ret != IPHONE_E_SUCCESS) { 431 if (ret != IPHONE_E_SUCCESS) {
434 fprintf(stderr, "Device refused to send public key.\n"); 432 fprintf(stderr, "Device refused to send public key.\n");
435 return ret; 433 return ret;
436 } 434 }
437 435
438 ret = lockdownd_gen_pair_cert(public_key_b64, &device_cert_b64, &host_cert_b64, &root_cert_b64); 436 ret = lockdownd_gen_pair_cert(public_key, &device_cert, &host_cert, &root_cert);
439 if (ret != IPHONE_E_SUCCESS) { 437 if (ret != IPHONE_E_SUCCESS) {
440 free(public_key_b64); 438 free(public_key.data);
441 return ret; 439 return ret;
442 } 440 }
443 441
444 /* Setup Pair request plist */ 442 /* Setup Pair request plist */
445 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 443 dict = plist_new_dict();
446 dictRecord = add_key_dict_node(plist, dict, "PairRecord", "\n", 1); 444 plist_add_sub_element(dict, PLIST_KEY, (void *) "PairRecord", strlen("PairRecord"));
447 //dictRecord = add_child_to_plist(plist, "dict", "\n", NULL, 1); 445 dict_record = plist_add_sub_element(dict, PLIST_DICT, NULL, 0);
448 add_key_data_dict_element(plist, dictRecord, "DeviceCertificate", device_cert_b64, 2); 446 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "DeviceCertificate", strlen("DeviceCertificate"));
449 add_key_data_dict_element(plist, dictRecord, "HostCertificate", host_cert_b64, 2); 447 plist_add_sub_element(dict_record, PLIST_DATA, (void *) device_cert.data, device_cert.size);
450 add_key_str_dict_element(plist, dictRecord, "HostID", host_id, 2); 448 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "HostCertificate", strlen("HostCertificate"));
451 add_key_data_dict_element(plist, dictRecord, "RootCertificate", root_cert_b64, 2); 449 plist_add_sub_element(dict_record, PLIST_DATA, (void *) host_cert.data, host_cert.size);
452 add_key_str_dict_element(plist, dict, "Request", "Pair", 1); 450 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "HostID", strlen("HostID"));
453 451 plist_add_sub_element(dict_record, PLIST_STRING, (void *) host_id, strlen(host_id));
454 xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); 452 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "RootCertificate", strlen("RootCertificate"));
455 453 plist_add_sub_element(dict_record, PLIST_DATA, (void *) root_cert.data, root_cert.size);
456 printf("XML Pairing request : %s\n", XML_content); 454 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "Request", strlen("Request"));
455 plist_add_sub_element(dict_record, PLIST_STRING, (void *) "Pair", strlen("Pair"));
456 plist_to_xml(dict, &XML_content, &length);
457 log_debug_msg("XML Pairing request :\nsize : %i\nxml :\n %s", length, XML_content);
457 458
458 /* send to iPhone */ 459 /* send to iPhone */
459 ret = iphone_lckd_send(control, XML_content, length, &bytes); 460 ret = iphone_lckd_send(control, XML_content, length, &bytes);
460 461
461 xmlFree(XML_content); 462 free(XML_content);
462 xmlFreeDoc(plist); 463 plist_free(dict);
463 plist = NULL; 464 dict = NULL;
464 465
465 if (ret != IPHONE_E_SUCCESS) 466 if (ret != IPHONE_E_SUCCESS)
466 return ret; 467 return ret;
@@ -475,48 +476,39 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
475 log_debug_msg(XML_content); 476 log_debug_msg(XML_content);
476 log_debug_msg("\n\n"); 477 log_debug_msg("\n\n");
477 478
478 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 479 plist_from_xml(XML_content, bytes, &dict);
479 if (!plist) { 480 if (!dict)
480 free(public_key_b64);
481 return IPHONE_E_PLIST_ERROR; 481 return IPHONE_E_PLIST_ERROR;
482 }
483 dict = xmlDocGetRootElement(plist);
484 for (dict = dict->children; dict; dict = dict->next) {
485 if (!xmlStrcmp(dict->name, "dict"))
486 break;
487 }
488 if (!dict) {
489 free(public_key_b64);
490 return IPHONE_E_DICT_ERROR;
491 }
492 482
493 /* Parse xml to check success and to find public key */ 483 plist_t query_node = plist_find_node(dict, PLIST_STRING, "Pair", strlen("Pair"));
494 dictionary = read_dict_element_strings(dict); 484 plist_t result_key_node = plist_get_next_sibling(query_node);
495 xmlFreeDoc(plist); 485 plist_t result_value_node = plist_get_next_sibling(result_key_node);
496 free(XML_content);
497 486
498 int success = 0; 487 plist_type result_key_type;
499 for (i = 0; dictionary[i]; i += 2) { 488 plist_type result_value_type;
500 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) { 489 char *result_key = NULL;
501 success = 1; 490 char *result_value = NULL;
502 } 491 uint64_t key_length = 0;
503 } 492 uint64_t val_length = 0;
493
494 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length);
495 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length);
504 496
505 if (dictionary) { 497 if (result_key_type == PLIST_KEY &&
506 free_dictionary(dictionary); 498 result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) {
507 dictionary = NULL; 499 ret = IPHONE_E_SUCCESS;
508 } 500 }
509 501
510 /* store public key in config if pairing succeeded */ 502 /* store public key in config if pairing succeeded */
511 if (success) { 503 if (ret == IPHONE_E_SUCCESS) {
512 log_debug_msg("lockdownd_pair_device: pair success\n"); 504 log_debug_msg("lockdownd_pair_device: pair success\n");
513 store_device_public_key(uid, public_key_b64); 505 store_device_public_key(uid, public_key);
514 ret = IPHONE_E_SUCCESS; 506 ret = IPHONE_E_SUCCESS;
515 } else { 507 } else {
516 log_debug_msg("lockdownd_pair_device: pair failure\n"); 508 log_debug_msg("lockdownd_pair_device: pair failure\n");
517 ret = IPHONE_E_PAIRING_FAILED; 509 ret = IPHONE_E_PAIRING_FAILED;
518 } 510 }
519 free(public_key_b64); 511 free(public_key.data);
520 return ret; 512 return ret;
521} 513}
522 514
@@ -525,25 +517,19 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
525 * 517 *
526 * @return IPHONE_E_SUCCESS on success. 518 * @return IPHONE_E_SUCCESS on success.
527 */ 519 */
528iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64, 520iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * odevice_cert,
529 char **root_cert_b64) 521 gnutls_datum_t * ohost_cert, gnutls_datum_t * oroot_cert)
530{ 522{
531 if (!public_key_b64 || !device_cert_b64 || !host_cert_b64 || !root_cert_b64) 523 if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert)
532 return IPHONE_E_INVALID_ARG; 524 return IPHONE_E_INVALID_ARG;
533 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 525 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
534 526
535 gnutls_datum_t modulus = { NULL, 0 }; 527 gnutls_datum_t modulus = { NULL, 0 };
536 gnutls_datum_t exponent = { NULL, 0 }; 528 gnutls_datum_t exponent = { NULL, 0 };
537 529
538 /* first decode base64 public_key */
539 gnutls_datum_t pem_pub_key;
540 gsize decoded_size;
541 pem_pub_key.data = g_base64_decode(public_key_b64, &decoded_size);
542 pem_pub_key.size = decoded_size;
543
544 /* now decode the PEM encoded key */ 530 /* now decode the PEM encoded key */
545 gnutls_datum_t der_pub_key; 531 gnutls_datum_t der_pub_key;
546 if (GNUTLS_E_SUCCESS == gnutls_pem_base64_decode_alloc("RSA PUBLIC KEY", &pem_pub_key, &der_pub_key)) { 532 if (GNUTLS_E_SUCCESS == gnutls_pem_base64_decode_alloc("RSA PUBLIC KEY", &public_key, &der_pub_key)) {
547 533
548 /* initalize asn.1 parser */ 534 /* initalize asn.1 parser */
549 ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY; 535 ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY;
@@ -627,10 +613,18 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_
627 dev_pem.data = gnutls_malloc(dev_pem.size); 613 dev_pem.data = gnutls_malloc(dev_pem.size);
628 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &dev_pem.size); 614 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &dev_pem.size);
629 615
630 /* now encode certificates for output */ 616 /* copy buffer for output */
631 *device_cert_b64 = g_base64_encode(dev_pem.data, dev_pem.size); 617 odevice_cert->data = malloc(dev_pem.size);
632 *host_cert_b64 = g_base64_encode(pem_host_cert.data, pem_host_cert.size); 618 memcpy(odevice_cert->data, dev_pem.data, dev_pem.size);
633 *root_cert_b64 = g_base64_encode(pem_root_cert.data, pem_root_cert.size); 619 odevice_cert->size = dev_pem.size;
620
621 ohost_cert->data = malloc(pem_host_cert.size);
622 memcpy(ohost_cert->data, pem_host_cert.data, pem_host_cert.size);
623 ohost_cert->size = pem_host_cert.size;
624
625 oroot_cert->data = malloc(pem_root_cert.size);
626 memcpy(oroot_cert->data, pem_root_cert.data, pem_root_cert.size);
627 oroot_cert->size = pem_root_cert.size;
634 } 628 }
635 gnutls_free(pem_root_priv.data); 629 gnutls_free(pem_root_priv.data);
636 gnutls_free(pem_root_cert.data); 630 gnutls_free(pem_root_cert.data);
@@ -642,7 +636,6 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_
642 gnutls_free(exponent.data); 636 gnutls_free(exponent.data);
643 637
644 gnutls_free(der_pub_key.data); 638 gnutls_free(der_pub_key.data);
645 g_free(pem_pub_key.data);
646 639
647 return ret; 640 return ret;
648} 641}
@@ -656,113 +649,112 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_
656 */ 649 */
657iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const char *HostID) 650iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const char *HostID)
658{ 651{
659 xmlDocPtr plist = new_plist(); 652 plist_t dict = NULL;
660 xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 653 char *XML_content = NULL;
661 xmlNode *key; 654 uint32_t length = 0, bytes = 0, return_me = 0;
662 char *what2send = NULL, **dictionary = NULL; 655
663 uint32 len = 0, bytes = 0, return_me = 0, i = 0;
664 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 656 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
665 // end variables
666 657
667 key = add_key_str_dict_element(plist, dict, "HostID", HostID, 1); 658 /* Setup DevicePublicKey request plist */
668 if (!key) { 659 dict = plist_new_dict();
669 log_debug_msg("Couldn't add a key.\n"); 660 plist_add_sub_element(dict, PLIST_KEY, (void *) "HostID", strlen("HostID"));
670 xmlFreeDoc(plist); 661 plist_add_sub_element(dict, PLIST_STRING, (void *) HostID, strlen(HostID));
671 return IPHONE_E_DICT_ERROR; 662 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request"));
672 } 663 plist_add_sub_element(dict, PLIST_STRING, (void *) "StartSession", strlen("StartSession"));
673 key = add_key_str_dict_element(plist, dict, "Request", "StartSession", 1); 664 plist_to_xml(dict, &XML_content, &length);
674 if (!key) { 665 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);
675 log_debug_msg("Couldn't add a key.\n");
676 xmlFreeDoc(plist);
677 return IPHONE_E_DICT_ERROR;
678 }
679 666
680 xmlDocDumpMemory(plist, (xmlChar **) & what2send, &len); 667 ret = iphone_lckd_send(control, XML_content, length, &bytes);
681 ret = iphone_lckd_send(control, what2send, len, &bytes);
682 668
683 xmlFree(what2send); 669 free(XML_content);
684 xmlFreeDoc(plist); 670 XML_content = NULL;
671 plist_free(dict);
672 dict = NULL;
685 673
686 if (ret != IPHONE_E_SUCCESS) 674 if (ret != IPHONE_E_SUCCESS)
687 return ret; 675 return ret;
688 676
689 if (bytes > 0) { 677 if (bytes > 0) {
690 ret = iphone_lckd_recv(control, &what2send, &len); 678 ret = iphone_lckd_recv(control, &XML_content, &bytes);
691 plist = xmlReadMemory(what2send, len, NULL, NULL, 0); 679 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content);
692 dict = xmlDocGetRootElement(plist); 680 plist_from_xml(XML_content, bytes, &dict);
693 if (!dict) 681 if (!dict)
694 return IPHONE_E_DICT_ERROR; 682 return IPHONE_E_PLIST_ERROR;
695 for (dict = dict->children; dict; dict = dict->next) { 683
696 if (!xmlStrcmp(dict->name, "dict")) 684 plist_t query_node = plist_find_node(dict, PLIST_STRING, "StartSession", strlen("StartSession"));
697 break; 685 plist_t result_key_node = plist_get_next_sibling(query_node);
698 } 686 plist_t result_value_node = plist_get_next_sibling(result_key_node);
699 dictionary = read_dict_element_strings(dict); 687
700 xmlFreeDoc(plist); 688 plist_type result_key_type;
701 free(what2send); 689 plist_type result_value_type;
702 for (i = 0; dictionary[i]; i += 2) { 690 char *result_key = NULL;
703 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) { 691 char *result_value = NULL;
704 // Set up GnuTLS... 692 uint64_t key_length = 0;
705 //gnutls_anon_client_credentials_t anoncred; 693 uint64_t val_length = 0;
706 gnutls_certificate_credentials_t xcred; 694
707 695 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length);
708 log_debug_msg("We started the session OK, now trying GnuTLS\n"); 696 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length);
709 errno = 0; 697
710 gnutls_global_init(); 698 free(XML_content);
711 //gnutls_anon_allocate_client_credentials(&anoncred); 699 XML_content = NULL;
712 gnutls_certificate_allocate_credentials(&xcred); 700 plist_free(dict);
713 gnutls_certificate_set_x509_trust_file(xcred, "hostcert.pem", GNUTLS_X509_FMT_PEM); 701 dict = NULL;
714 gnutls_init(control->ssl_session, GNUTLS_CLIENT); 702
715 { 703 if (result_key_type == PLIST_KEY &&
716 int protocol_priority[16] = { GNUTLS_SSL3, 0 }; 704 result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) {
717 int kx_priority[16] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, 0 }; 705 // Set up GnuTLS...
718 int cipher_priority[16] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_AES_256_CBC, 0 }; 706 //gnutls_anon_client_credentials_t anoncred;
719 int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 }; 707 gnutls_certificate_credentials_t xcred;
720 int comp_priority[16] = { GNUTLS_COMP_NULL, 0 }; 708
721 709 log_debug_msg("We started the session OK, now trying GnuTLS\n");
722 gnutls_cipher_set_priority(*control->ssl_session, cipher_priority); 710 errno = 0;
723 gnutls_compression_set_priority(*control->ssl_session, comp_priority); 711 gnutls_global_init();
724 gnutls_kx_set_priority(*control->ssl_session, kx_priority); 712 //gnutls_anon_allocate_client_credentials(&anoncred);
725 gnutls_protocol_set_priority(*control->ssl_session, protocol_priority); 713 gnutls_certificate_allocate_credentials(&xcred);
726 gnutls_mac_set_priority(*control->ssl_session, mac_priority); 714 gnutls_certificate_set_x509_trust_file(xcred, "hostcert.pem", GNUTLS_X509_FMT_PEM);
727 715 gnutls_init(control->ssl_session, GNUTLS_CLIENT);
728 } 716 {
729 gnutls_credentials_set(*control->ssl_session, GNUTLS_CRD_CERTIFICATE, xcred); // this part is killing me. 717 int protocol_priority[16] = { GNUTLS_SSL3, 0 };
730 718 int kx_priority[16] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, 0 };
731 log_debug_msg("GnuTLS step 1...\n"); 719 int cipher_priority[16] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_AES_256_CBC, 0 };
732 gnutls_transport_set_ptr(*control->ssl_session, (gnutls_transport_ptr_t) control); 720 int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 };
733 log_debug_msg("GnuTLS step 2...\n"); 721 int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
734 gnutls_transport_set_push_function(*control->ssl_session, (gnutls_push_func) & lockdownd_secuwrite); 722
735 log_debug_msg("GnuTLS step 3...\n"); 723 gnutls_cipher_set_priority(*control->ssl_session, cipher_priority);
736 gnutls_transport_set_pull_function(*control->ssl_session, (gnutls_pull_func) & lockdownd_securead); 724 gnutls_compression_set_priority(*control->ssl_session, comp_priority);
737 log_debug_msg("GnuTLS step 4 -- now handshaking...\n"); 725 gnutls_kx_set_priority(*control->ssl_session, kx_priority);
738 726 gnutls_protocol_set_priority(*control->ssl_session, protocol_priority);
739 if (errno) 727 gnutls_mac_set_priority(*control->ssl_session, mac_priority);
740 log_debug_msg("WARN: errno says %s before handshake!\n", strerror(errno)); 728
741 return_me = gnutls_handshake(*control->ssl_session); 729 }
742 log_debug_msg("GnuTLS handshake done...\n"); 730 gnutls_credentials_set(*control->ssl_session, GNUTLS_CRD_CERTIFICATE, xcred); // this part is killing me.
743 731
744 free_dictionary(dictionary); 732 log_debug_msg("GnuTLS step 1...\n");
745 733 gnutls_transport_set_ptr(*control->ssl_session, (gnutls_transport_ptr_t) control);
746 if (return_me != GNUTLS_E_SUCCESS) { 734 log_debug_msg("GnuTLS step 2...\n");
747 log_debug_msg("GnuTLS reported something wrong.\n"); 735 gnutls_transport_set_push_function(*control->ssl_session, (gnutls_push_func) & lockdownd_secuwrite);
748 gnutls_perror(return_me); 736 log_debug_msg("GnuTLS step 3...\n");
749 log_debug_msg("oh.. errno says %s\n", strerror(errno)); 737 gnutls_transport_set_pull_function(*control->ssl_session, (gnutls_pull_func) & lockdownd_securead);
750 return IPHONE_E_SSL_ERROR; 738 log_debug_msg("GnuTLS step 4 -- now handshaking...\n");
751 } else { 739
752 control->in_SSL = 1; 740 if (errno)
753 return IPHONE_E_SUCCESS; 741 log_debug_msg("WARN: errno says %s before handshake!\n", strerror(errno));
754 } 742 return_me = gnutls_handshake(*control->ssl_session);
743 log_debug_msg("GnuTLS handshake done...\n");
744
745 if (return_me != GNUTLS_E_SUCCESS) {
746 log_debug_msg("GnuTLS reported something wrong.\n");
747 gnutls_perror(return_me);
748 log_debug_msg("oh.. errno says %s\n", strerror(errno));
749 return IPHONE_E_SSL_ERROR;
750 } else {
751 control->in_SSL = 1;
752 return IPHONE_E_SUCCESS;
755 } 753 }
756 } 754 }
757 755
758 log_debug_msg("Apparently failed negotiating with lockdownd.\n"); 756 log_debug_msg("Apparently failed negotiating with lockdownd.\n");
759 log_debug_msg("Responding dictionary: \n"); 757 log_debug_msg("Responding dictionary: \n");
760 for (i = 0; dictionary[i]; i += 2) {
761 log_debug_msg("\t%s: %s\n", dictionary[i], dictionary[i + 1]);
762 }
763
764
765 free_dictionary(dictionary);
766 return IPHONE_E_SSL_ERROR; 758 return IPHONE_E_SSL_ERROR;
767 } else { 759 } else {
768 log_debug_msg("Didn't get enough bytes.\n"); 760 log_debug_msg("Didn't get enough bytes.\n");
@@ -894,81 +886,90 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char
894 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) 886 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id))
895 return IPHONE_E_SSL_ERROR; 887 return IPHONE_E_SSL_ERROR;
896 888
897 char *XML_query, **dictionary; 889
898 uint32 length, i = 0, port_loc = 0, bytes = 0; 890 plist_t dict = NULL;
899 uint8 result = 0; 891 char *XML_content = NULL;
892 uint32_t length, i = 0, port_loc = 0, bytes = 0;
900 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 893 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
901 894
902 free(host_id); 895 free(host_id);
903 host_id = NULL; 896 host_id = NULL;
904 897
905 xmlDocPtr plist = new_plist(); 898 dict = plist_new_dict();
906 xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 899 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request"));
907 xmlNode *key; 900 plist_add_sub_element(dict, PLIST_STRING, (void *) "StartService", strlen("StartService"));
908 key = add_key_str_dict_element(plist, dict, "Request", "StartService", 1); 901 plist_add_sub_element(dict, PLIST_KEY, (void *) "Service", strlen("Service"));
909 if (!key) { 902 plist_add_sub_element(dict, PLIST_STRING, (void *) service, strlen(service));
910 xmlFreeDoc(plist); 903 plist_to_xml(dict, &XML_content, &length);
911 return IPHONE_E_UNKNOWN_ERROR;
912 }
913 key = add_key_str_dict_element(plist, dict, "Service", service, 1);
914 if (!key) {
915 xmlFreeDoc(plist);
916 return IPHONE_E_UNKNOWN_ERROR;
917 }
918 904
919 xmlDocDumpMemory(plist, (xmlChar **) & XML_query, &length); 905 /* send to iPhone */
906 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);
907 ret = iphone_lckd_send(client, XML_content, length, &bytes);
908
909 free(XML_content);
910 XML_content = NULL;
911 plist_free(dict);
912 dict = NULL;
920 913
921 ret = iphone_lckd_send(client, XML_query, length, &bytes);
922 free(XML_query);
923 if (IPHONE_E_SUCCESS != ret) 914 if (IPHONE_E_SUCCESS != ret)
924 return ret; 915 return ret;
925 916
926 ret = iphone_lckd_recv(client, &XML_query, &bytes); 917 ret = iphone_lckd_recv(client, &XML_content, &bytes);
927 xmlFreeDoc(plist); 918
928 if (IPHONE_E_SUCCESS != ret) 919 if (IPHONE_E_SUCCESS != ret)
929 return ret; 920 return ret;
930 921
922 plist_from_xml(XML_content, bytes, &dict);
923 if (!dict)
924 return IPHONE_E_PLIST_ERROR;
925
926
931 if (bytes <= 0) 927 if (bytes <= 0)
932 return IPHONE_E_NOT_ENOUGH_DATA; 928 return IPHONE_E_NOT_ENOUGH_DATA;
933 else { 929 else {
934 plist = xmlReadMemory(XML_query, bytes, NULL, NULL, 0);
935 if (!plist)
936 return IPHONE_E_UNKNOWN_ERROR;
937 dict = xmlDocGetRootElement(plist);
938 if (!dict)
939 return IPHONE_E_UNKNOWN_ERROR;
940 for (dict = dict->children; dict; dict = dict->next) {
941 if (!xmlStrcmp(dict->name, "dict"))
942 break;
943 }
944 930
945 if (!dict) 931 plist_t query_node = plist_find_node(dict, PLIST_STRING, "StartService", strlen("StartService"));
946 return IPHONE_E_UNKNOWN_ERROR; 932 plist_t result_key_node = plist_get_next_sibling(query_node);
947 dictionary = read_dict_element_strings(dict); 933 plist_t result_value_node = plist_get_next_sibling(result_key_node);
948 934
949 for (i = 0; dictionary[i]; i += 2) { 935 plist_t port_key_node = plist_find_node(dict, PLIST_KEY, "Port", strlen("Port"));
950 log_debug_msg("lockdownd_start_service() dictionary %s: %s\n", dictionary[i], dictionary[i + 1]); 936 plist_t port_value_node = plist_get_next_sibling(port_key_node);
951 937
952 if (!xmlStrcmp(dictionary[i], "Port")) { 938 plist_type result_key_type;
953 port_loc = atoi(dictionary[i + 1]); 939 plist_type result_value_type;
954 log_debug_msg("lockdownd_start_service() atoi'd port: %i\n", port); 940 plist_type port_key_type;
955 } 941 plist_type port_value_type;
956 942 char *result_key = NULL;
957 if (!xmlStrcmp(dictionary[i], "Result")) { 943 char *result_value = NULL;
958 if (!xmlStrcmp(dictionary[i + 1], "Success")) { 944 char *port_key = NULL;
959 result = 1; 945 uint64_t res_key_length = 0;
960 } 946 uint64_t res_val_length = 0;
961 } 947 uint64_t port_key_length = 0;
948 uint64_t port_val_length = 0;
949 uint64_t port_value = 0;
950
951 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &res_key_length);
952 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &res_val_length);
953 plist_get_type_and_value(port_key_node, &port_key_type, (void *) (&port_key), &port_key_length);
954 plist_get_type_and_value(port_value_node, &port_value_type, (void *) (&port_value), &port_val_length);
955
956 if (result_key_type == PLIST_KEY &&
957 result_value_type == PLIST_STRING &&
958 port_key_type == PLIST_KEY &&
959 port_value_type == PLIST_UINT &&
960 !strcmp(result_key, "Result") && !strcmp(result_value, "Success") && !strcmp(port_key, "Port")) {
961 port_loc = port_value;
962 ret = IPHONE_E_SUCCESS;
962 } 963 }
963 964
964 log_debug_msg("lockdownd_start_service(): DATA RECEIVED:\n\n"); 965 log_debug_msg("lockdownd_start_service(): DATA RECEIVED:\n\n");
965 log_debug_msg(XML_query); 966 log_debug_msg(XML_content);
966 log_debug_msg("end data received by lockdownd_start_service()\n"); 967 log_debug_msg("end data received by lockdownd_start_service()\n");
967 968
968 free(XML_query); 969 free(XML_content);
969 xmlFreeDoc(plist); 970 plist_free(dict);
970 free_dictionary(dictionary); 971 dict = NULL;
971 if (port && result) { 972 if (port && ret == IPHONE_E_SUCCESS) {
972 *port = port_loc; 973 *port = port_loc;
973 return IPHONE_E_SUCCESS; 974 return IPHONE_E_SUCCESS;
974 } else 975 } else
diff --git a/src/lockdown.h b/src/lockdown.h
index 79ca37e..8ca8a7f 100644
--- a/src/lockdown.h
+++ b/src/lockdown.h
@@ -23,7 +23,6 @@
23#define LOCKDOWND_H 23#define LOCKDOWND_H
24 24
25#include "usbmux.h" 25#include "usbmux.h"
26#include "plist.h"
27 26
28#include <gnutls/gnutls.h> 27#include <gnutls/gnutls.h>
29#include <string.h> 28#include <string.h>
@@ -40,18 +39,16 @@ struct iphone_lckd_client_int {
40 int gtls_buffer_hack_len; 39 int gtls_buffer_hack_len;
41}; 40};
42 41
43char *lockdownd_generate_hostid(void);
44
45iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone); 42iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone);
46iphone_error_t lockdownd_hello(iphone_lckd_client_t control); 43iphone_error_t lockdownd_hello(iphone_lckd_client_t control);
47iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const char *req_key, const char *req_string, 44iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const char *req_key, char *req_string,
48 char **value); 45 gnutls_datum_t * value);
49iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid); 46iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid);
50iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_key); 47iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, gnutls_datum_t * public_key);
51 48
52iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64, 49iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * device_cert,
53 char **root_cert_b64); 50 gnutls_datum_t * host_cert, gnutls_datum_t * root_cert);
54iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *public_key, char *host_id); 51iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id);
55void lockdownd_close(iphone_lckd_client_t control); 52void lockdownd_close(iphone_lckd_client_t control);
56 53
57// SSL functions 54// SSL functions
diff --git a/src/plist.c b/src/plist.c
deleted file mode 100644
index b9d9e6a..0000000
--- a/src/plist.c
+++ /dev/null
@@ -1,245 +0,0 @@
1/*
2 * plist.c
3 * Builds plist XML structures.
4 *
5 * Copyright (c) 2008 Zach C. All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * 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 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <libxml/parser.h>
23#include <libxml/tree.h>
24#include <string.h>
25#include <assert.h>
26#include "plist.h"
27
28const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
29<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\
30<plist version=\"1.0\">\n\
31</plist>\0";
32
33/** Formats a block of text to be a given indentation and width.
34 *
35 * The total width of the return string will be depth + cols.
36 *
37 * @param buf The string to format.
38 * @param cols The number of text columns for returned block of text.
39 * @param depth The number of tabs to indent the returned block of text.
40 *
41 * @return The formatted string.
42 */
43static char *format_string(const char *buf, int cols, int depth)
44{
45 int colw = depth + cols + 1;
46 int len = strlen(buf);
47 int nlines = len / cols + 1;
48 char *new_buf = (char *) malloc(nlines * colw + depth + 1);
49 int i = 0;
50 int j = 0;
51
52 assert(cols >= 0);
53 assert(depth >= 0);
54
55 // Inserts new lines and tabs at appropriate locations
56 for (i = 0; i < nlines; i++) {
57 new_buf[i * colw] = '\n';
58 for (j = 0; j < depth; j++)
59 new_buf[i * colw + 1 + j] = '\t';
60 memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, cols);
61 }
62 new_buf[len + (1 + depth) * nlines] = '\n';
63
64 // Inserts final row of indentation and termination character
65 for (j = 0; j < depth; j++)
66 new_buf[len + (1 + depth) * nlines + 1 + j] = '\t';
67 new_buf[len + (1 + depth) * nlines + depth + 1] = '\0';
68
69 return new_buf;
70}
71
72/** Creates a new plist XML document.
73 *
74 * @return The plist XML document.
75 */
76xmlDocPtr new_plist(void)
77{
78 char *plist = strdup(plist_base);
79 xmlDocPtr plist_xml = xmlReadMemory(plist, strlen(plist), NULL, NULL, 0);
80
81 if (!plist_xml)
82 return NULL;
83
84 free(plist);
85
86 return plist_xml;
87}
88
89/** Destroys a previously created XML document.
90 *
91 * @param plist The XML document to destroy.
92 */
93void free_plist(xmlDocPtr plist)
94{
95 if (!plist)
96 return;
97
98 xmlFreeDoc(plist);
99}
100
101/** Adds a new node as a child to a given node.
102 *
103 * This is a lower level function so you probably want to use
104 * add_key_str_dict_element, add_key_dict_node or add_key_data_dict_element
105 * instead.
106 *
107 * @param plist The plist XML document to which the to_node belongs.
108 * @param name The name of the new node.
109 * @param content The string containing the text node of the new node.
110 * @param to_node The node to attach the child node to. If none is given, the
111 * root node of the given document is used.
112 * @param depth The number of tabs to indent the new node.
113 *
114 * @return The newly created node.
115 */
116xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode * to_node, int depth)
117{
118 int i = 0;
119 xmlNode *child;
120
121 if (!plist)
122 return NULL;
123 assert(depth >= 0);
124 if (!to_node)
125 to_node = xmlDocGetRootElement(plist);
126
127 for (i = 0; i < depth; i++) {
128 xmlNodeAddContent(to_node, "\t");
129 }
130 child = xmlNewChild(to_node, NULL, name, content);
131 xmlNodeAddContent(to_node, "\n");
132
133 return child;
134}
135
136/** Adds a string key-pair to a plist XML document.
137 *
138 * @param plist The plist XML document to add the new node to.
139 * @param dict The dictionary node within the plist XML document to add the new node to.
140 * @param key The string containing the key value.
141 * @param value The string containing the value.
142 * @param depth The number of tabs to indent the new node.
143 *
144 * @return The newly created key node.
145 */
146xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth)
147{
148 xmlNode *keyPtr;
149
150 keyPtr = add_child_to_plist(plist, "key", key, dict, depth);
151 add_child_to_plist(plist, "string", value, dict, depth);
152
153 return keyPtr;
154}
155
156/** Adds a new dictionary key-pair to a plist XML document.
157 *
158 * @param plist The plist XML document to add the new node to.
159 * @param dict The dictionary node within the plist XML document to add the new node to.
160 * @param key The string containing the key value.
161 * @param value The string containing the value.
162 * @param depth The number of tabs to indent the new node.
163 *
164 * @return The newly created dict node.
165 */
166xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth)
167{
168 xmlNode *child;
169
170 add_child_to_plist(plist, "key", key, dict, depth);
171 child = add_child_to_plist(plist, "dict", value, dict, depth);
172
173 return child;
174}
175
176/** Adds a new data dictionary key-pair to a plist XML document.
177 *
178 * @param plist The plist XML document to add the new node to.
179 * @param dict The dictionary node within the plist XML document to add the new node to.
180 * @param key The string containing the key value.
181 * @param value The string containing the value.
182 * @param depth The number of tabs to indent the new node.
183 *
184 * @return The newly created key node.
185 */
186xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth)
187{
188 xmlNode *keyPtr;
189
190 keyPtr = add_child_to_plist(plist, "key", key, dict, depth);
191 add_child_to_plist(plist, "data", format_string(value, 60, depth), dict, depth);
192
193 return keyPtr;
194}
195
196/** Reads a set of keys and strings into an array from a plist XML document.
197 *
198 * @param dict The root XMLNode of a plist XML document to be read.
199 *
200 * @return An array where each even number is a key and the odd numbers are
201 * values. If the odd number is \0, that's the end of the list.
202 */
203char **read_dict_element_strings(xmlNode * dict)
204{
205 char **return_me = NULL, **old = NULL;
206 int current_length = 0;
207 int current_pos = 0;
208 xmlNode *dict_walker;
209
210 for (dict_walker = dict->children; dict_walker; dict_walker = dict_walker->next) {
211 if (!xmlStrcmp(dict_walker->name, "key")) {
212 current_length += 2;
213 old = return_me;
214 return_me = realloc(return_me, sizeof(char *) * current_length);
215 if (!return_me) {
216 free(old);
217 return NULL;
218 }
219 return_me[current_pos++] = xmlNodeGetContent(dict_walker);
220 return_me[current_pos++] = xmlNodeGetContent(dict_walker->next->next);
221 }
222 }
223
224 old = return_me;
225 return_me = realloc(return_me, sizeof(char *) * (current_length + 1));
226 return_me[current_pos] = NULL;
227
228 return return_me;
229}
230
231/** Destroys a dictionary as returned by read_dict_element_strings
232 */
233void free_dictionary(char **dictionary)
234{
235 int i = 0;
236
237 if (!dictionary)
238 return;
239
240 for (i = 0; dictionary[i]; i++) {
241 free(dictionary[i]);
242 }
243
244 free(dictionary);
245}
diff --git a/src/plist.h b/src/plist.h
deleted file mode 100644
index cd2028e..0000000
--- a/src/plist.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/*
2 * plist.h
3 * contains structures and the like for plists
4 *
5 * Copyright (c) 2008 Zach C. All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * 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 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#ifndef PLIST_H
23#define PLIST_H
24
25#include <libxml/parser.h>
26#include <libxml/tree.h>
27
28xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth);
29xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth);
30xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth);
31xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode * to_node, int depth);
32
33void free_plist(xmlDocPtr plist);
34xmlDocPtr new_plist(void);
35
36char **read_dict_element_strings(xmlNode * dict);
37void free_dictionary(char **dictionary);
38#endif
diff --git a/src/usbmux.c b/src/usbmux.c
index 770d0db..427b880 100644
--- a/src/usbmux.c
+++ b/src/usbmux.c
@@ -38,7 +38,7 @@ static int clients = 0;
38 * 38 *
39 * @return A USBMux packet 39 * @return A USBMux packet
40 */ 40 */
41usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port) 41usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port)
42{ 42{
43 usbmux_tcp_header *conn = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); 43 usbmux_tcp_header *conn = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header));
44 conn->type = htonl(6); 44 conn->type = htonl(6);
diff --git a/src/usbmux.h b/src/usbmux.h
index fd5fc78..bea83f7 100644
--- a/src/usbmux.h
+++ b/src/usbmux.h
@@ -22,6 +22,7 @@
22#include <sys/types.h> 22#include <sys/types.h>
23#include <stdlib.h> 23#include <stdlib.h>
24#include <stdint.h> 24#include <stdint.h>
25#include "libiphone/libiphone.h"
25 26
26#ifndef USBMUX_H 27#ifndef USBMUX_H
27#define USBMUX_H 28#define USBMUX_H
@@ -30,17 +31,12 @@
30#include "iphone.h" 31#include "iphone.h"
31#endif 32#endif
32 33
33typedef uint16_t uint16;
34typedef uint32_t uint32;
35typedef uint8_t uint8;
36
37
38typedef struct { 34typedef struct {
39 uint32 type, length; 35 uint32_t type, length;
40 uint16 sport, dport; 36 uint16_t sport, dport;
41 uint32 scnt, ocnt; 37 uint32_t scnt, ocnt;
42 uint8 offset, tcp_flags; 38 uint8_t offset, tcp_flags;
43 uint16 window, nullnull, length16; 39 uint16_t window, nullnull, length16;
44} usbmux_tcp_header; 40} usbmux_tcp_header;
45 41
46struct iphone_umux_client_int { 42struct iphone_umux_client_int {
@@ -50,10 +46,10 @@ struct iphone_umux_client_int {
50 int r_len; 46 int r_len;
51}; 47};
52 48
53usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port); 49usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port);
54 50
55typedef struct { 51typedef struct {
56 uint32 type, length, major, minor, allnull; 52 uint32_t type, length, major, minor, allnull;
57} usbmux_version_header; 53} usbmux_version_header;
58 54
59usbmux_version_header *version_header(void); 55usbmux_version_header *version_header(void);
diff --git a/src/userpref.c b/src/userpref.c
index 5f227b0..3e5eb06 100644
--- a/src/userpref.c
+++ b/src/userpref.c
@@ -111,10 +111,10 @@ int is_device_known(char *uid)
111 * @return 1 on success and 0 if no public key is given or if it has already 111 * @return 1 on success and 0 if no public key is given or if it has already
112 * been marked as connected previously. 112 * been marked as connected previously.
113 */ 113 */
114int store_device_public_key(char *uid, char *public_key) 114int store_device_public_key(char *uid, gnutls_datum_t public_key)
115{ 115{
116 116
117 if (NULL == public_key || is_device_known(uid)) 117 if (NULL == public_key.data || is_device_known(uid))
118 return 0; 118 return 0;
119 119
120 /* ensure config directory exists */ 120 /* ensure config directory exists */
@@ -124,15 +124,11 @@ int store_device_public_key(char *uid, char *public_key)
124 gchar *device_file = g_strconcat(uid, ".pem", NULL); 124 gchar *device_file = g_strconcat(uid, ".pem", NULL);
125 gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); 125 gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL);
126 126
127 /* decode public key for storing */
128 gsize decoded_size;
129 gchar *data = g_base64_decode(public_key, &decoded_size);
130 /* store file */ 127 /* store file */
131 FILE *pFile = fopen(pem, "wb"); 128 FILE *pFile = fopen(pem, "wb");
132 fwrite(data, 1, decoded_size, pFile); 129 fwrite(public_key.data, 1, public_key.size, pFile);
133 fclose(pFile); 130 fclose(pFile);
134 g_free(pem); 131 g_free(pem);
135 g_free(data);
136 g_free(device_file); 132 g_free(device_file);
137 return 1; 133 return 1;
138} 134}
diff --git a/src/userpref.h b/src/userpref.h
index e7835d0..7e606eb 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 */
43int store_device_public_key(char *uid, char *public_key); 43int 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/utils.c b/src/utils.c
index 049777a..ceb1f5d 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -46,7 +46,7 @@ void log_debug_msg(const char *format, ...)
46 va_start(args, format); 46 va_start(args, format);
47 47
48 if (toto_debug) 48 if (toto_debug)
49 fprintf(stderr, format, args); 49 vfprintf(stderr, format, args);
50 50
51 va_end(args); 51 va_end(args);
52 52