summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Jonathan Beck2009-01-08 23:27:28 +0100
committerGravatar Jonathan Beck2009-01-08 23:27:28 +0100
commit8f239549c124d11eb8899aec6c048d6a496e3911 (patch)
tree340b439d5ca46b06c088b6c59d2b58451d050302
parentf53b61c82be8aa6223ab6a524c2287d892f9864c (diff)
downloadlibimobiledevice-8f239549c124d11eb8899aec6c048d6a496e3911.tar.gz
libimobiledevice-8f239549c124d11eb8899aec6c048d6a496e3911.tar.bz2
Implement skeleton of MobileSync protocol (handshake and goodbye).
-rw-r--r--dev/Makefile.am6
-rw-r--r--src/Makefile.am2
-rw-r--r--src/MobileSync.c210
-rw-r--r--src/MobileSync.h41
-rw-r--r--src/lockdown.c16
5 files changed, 264 insertions, 11 deletions
diff --git a/dev/Makefile.am b/dev/Makefile.am
index d116581..7ca7e99 100644
--- a/dev/Makefile.am
+++ b/dev/Makefile.am
@@ -3,7 +3,7 @@ INCLUDES = -I$(top_srcdir)/include
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) -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)
5 5
6bin_PROGRAMS = iphoneclient lckd-client afccheck 6bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient
7 7
8iphoneclient_SOURCES = main.c 8iphoneclient_SOURCES = main.c
9iphoneclient_LDADD = ../src/libiphone.la 9iphoneclient_LDADD = ../src/libiphone.la
@@ -18,3 +18,7 @@ afccheck_CFLAGS = $(AM_CFLAGS)
18afccheck_LDFLAGS = $(AM_LDFLAGS) 18afccheck_LDFLAGS = $(AM_LDFLAGS)
19afccheck_LDADD = ../src/libiphone.la 19afccheck_LDADD = ../src/libiphone.la
20 20
21msyncclient_SOURCES = msyncclient.c
22msyncclient_CFLAGS = $(AM_CFLAGS)
23msyncclient_LDFLAGS = $(AM_LDFLAGS)
24msyncclient_LDADD = ../src/libiphone.la
diff --git a/src/Makefile.am b/src/Makefile.am
index 2514367..2e92fd1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,4 +12,4 @@ libiphone_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 lockdown.c AFC.c userpref.c utils.c 15libiphone_la_SOURCES = usbmux.c iphone.c lockdown.c AFC.c userpref.c utils.c MobileSync.c
diff --git a/src/MobileSync.c b/src/MobileSync.c
new file mode 100644
index 0000000..2e574d2
--- /dev/null
+++ b/src/MobileSync.c
@@ -0,0 +1,210 @@
1/*
2 * MobileSync.c
3 * Contains functions for the built-in MobileSync client.
4 *
5 * Copyright (c) 2009 Jonathan Beck 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 "MobileSync.h"
23#include <plist/plist.h>
24#include <string.h>
25
26#define MSYNC_VERSION_INT1 100
27#define MSYNC_VERSION_INT2 100
28
29iphone_error_t iphone_msync_new_client(iphone_device_t device, int src_port, int dst_port,
30 iphone_msync_client_t * client)
31{
32 if (!device || src_port == 0 || dst_port == 0 || !client || *client)
33 return IPHONE_E_INVALID_ARG;
34
35 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
36
37 iphone_msync_client_t client_loc = (iphone_msync_client_t) malloc(sizeof(struct iphone_msync_client_int));
38
39 // Attempt connection
40 client_loc->connection = NULL;
41 ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection);
42 if (IPHONE_E_SUCCESS != ret || !client_loc->connection) {
43 free(client_loc);
44 return ret;
45 }
46 //perform handshake
47 int bytes = 0;
48 char *content = NULL;
49 uint32_t length = 0;
50 plist_t array = NULL;
51
52 //first receive version
53 ret = iphone_msync_recv(client_loc, &content, &bytes);
54 log_debug_msg("Receive msg :\nsize : %i\nbuffer :\n", bytes);
55 log_debug_buffer(content, bytes);
56 plist_from_bin(content, bytes, &array);
57
58 free(content);
59 content = NULL;
60
61 plist_t msg_node =
62 plist_find_node(array, PLIST_STRING, "DLMessageVersionExchange", strlen("DLMessageVersionExchange"));
63 plist_t ver_1 = plist_get_next_sibling(msg_node);
64 plist_t ver_2 = plist_get_next_sibling(ver_1);
65
66 plist_type ver_1_type = plist_get_node_type(ver_1);
67 plist_type ver_2_type = plist_get_node_type(ver_2);
68
69 if (PLIST_UINT == ver_1_type && PLIST_UINT == ver_2_type) {
70
71 uint64_t ver_1_val = 0;
72 uint64_t ver_2_val = 0;
73
74 plist_get_uint_val(ver_1, &ver_1_val);
75 plist_get_uint_val(ver_2, &ver_2_val);
76
77 plist_free(array);
78 array = NULL;
79
80 if (ver_1_type == PLIST_UINT && ver_2_type == PLIST_UINT && ver_1_val == MSYNC_VERSION_INT1
81 && ver_2_val == MSYNC_VERSION_INT2) {
82
83 array = plist_new_array();
84 plist_add_sub_string_el(array, "DLMessageVersionExchange");
85 plist_add_sub_string_el(array, "DLVersionsOk");
86
87 plist_to_bin(array, &content, &length);
88 log_debug_msg("Send msg :\nsize : %i\nbuffer :\n", length);
89 log_debug_buffer(content, length);
90 ret = iphone_msync_send(client_loc, content, length, &bytes);
91
92 free(content);
93 content = NULL;
94 plist_free(array);
95 array = NULL;
96
97 ret = iphone_msync_recv(client_loc, &content, &bytes);
98 log_debug_msg("Receive msg :\nsize : %i\nbuffer :\n", bytes);
99 log_debug_buffer(content, bytes);
100 plist_from_bin(content, bytes, &array);
101
102 free(content);
103 content = NULL;
104
105 plist_t rep_node =
106 plist_find_node(array, PLIST_STRING, "DLMessageDeviceReady", strlen("DLMessageDeviceReady"));
107
108 if (rep_node) {
109 ret = IPHONE_E_SUCCESS;
110 *client = client_loc;
111 }
112 }
113 }
114
115 if (IPHONE_E_SUCCESS != ret)
116 iphone_msync_free_client(client_loc);
117
118 return ret;
119}
120
121static void iphone_msync_stop_session(iphone_msync_client_t client)
122{
123 if (!client)
124 return;
125
126 int bytes = 0;
127 char *content = NULL;
128 uint32_t length = 0;
129
130 plist_t array = plist_new_array();
131 plist_add_sub_string_el(array, "DLMessageDisconnect");
132 plist_add_sub_string_el(array, "All done, thanks for the memories");
133
134 plist_to_bin(array, &content, &length);
135 log_debug_msg("Send msg :\nsize : %i\nbuffer :\n", length);
136 log_debug_buffer(content, length);
137 iphone_msync_send(client, content, length, &bytes);
138
139 free(content);
140 content = NULL;
141 plist_free(array);
142 array = NULL;
143}
144
145void iphone_msync_free_client(iphone_msync_client_t client)
146{
147 iphone_msync_stop_session(client);
148
149 iphone_mux_free_client(client->connection);
150}
151
152/** Polls the iPhone for MobileSync data.
153 *
154 * @param client The MobileSync client
155 * @param dump_data The pointer to the location of the buffer in which to store
156 * the received data
157 * @param recv_byhtes The number of bytes received
158 *
159 * @return an error code
160 */
161iphone_error_t iphone_msync_recv(iphone_msync_client_t client, char **dump_data, uint32_t * recv_bytes)
162{
163 if (!client || !dump_data || !recv_bytes)
164 return IPHONE_E_INVALID_ARG;
165 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
166 char *receive;
167 uint32_t datalen = 0, bytes = 0;
168
169 ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes);
170 datalen = ntohl(datalen);
171
172 receive = (char *) malloc(sizeof(char) * datalen);
173 ret = iphone_mux_recv(client->connection, receive, datalen, &bytes);
174
175 *dump_data = receive;
176 *recv_bytes = bytes;
177 return ret;
178}
179
180/** Sends MobileSync data to the iPhone
181 *
182 * @note This function is low-level and should only be used if you need to send
183 * a new type of message.
184 *
185 * @param client The MobileSync client
186 * @param raw_data The null terminated string buffer to send
187 * @param length The length of data to send
188 * @param sent_bytes The number of bytes sent
189 *
190 * @return an error code
191 */
192iphone_error_t iphone_msync_send(iphone_msync_client_t client, char *raw_data, uint32_t length, uint32_t * sent_bytes)
193{
194 if (!client || !raw_data || length == 0 || !sent_bytes)
195 return IPHONE_E_INVALID_ARG;
196 char *real_query;
197 int bytes;
198 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
199
200 real_query = (char *) malloc(sizeof(char) * (length + 4));
201 length = htonl(length);
202 memcpy(real_query, &length, sizeof(length));
203 memcpy(real_query + 4, raw_data, ntohl(length));
204
205 ret = iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes);
206 free(real_query);
207 *sent_bytes = bytes;
208 return ret;
209}
210
diff --git a/src/MobileSync.h b/src/MobileSync.h
new file mode 100644
index 0000000..d7c774e
--- /dev/null
+++ b/src/MobileSync.h
@@ -0,0 +1,41 @@
1/*
2 * MobileSync.h
3 * Definitions for the built-in MobileSync client
4 *
5 * Copyright (c) 2009 Jonathan Beck 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#ifndef MOBILESYNC_H
22#define MOBILESYNC_H
23
24#include "usbmux.h"
25#include "iphone.h"
26
27struct iphone_msync_client_int;
28typedef struct iphone_msync_client_int *iphone_msync_client_t;
29
30struct iphone_msync_client_int {
31 iphone_umux_client_t connection;
32};
33
34iphone_error_t iphone_msync_new_client(iphone_device_t device, int src_port, int dst_port,
35 iphone_msync_client_t * client);
36void iphone_msync_free_client(iphone_msync_client_t client);
37
38iphone_error_t iphone_msync_recv(iphone_msync_client_t client, char **dump_data, uint32_t * recv_bytes);
39iphone_error_t iphone_msync_send(iphone_msync_client_t client, char *raw_data, uint32_t length, uint32_t * sent_bytes);
40
41#endif
diff --git a/src/lockdown.c b/src/lockdown.c
index 872b7b0..56a6f4e 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -845,6 +845,8 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
845 ret = iphone_lckd_recv(control, &XML_content, &bytes); 845 ret = iphone_lckd_recv(control, &XML_content, &bytes);
846 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); 846 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content);
847 plist_from_xml(XML_content, bytes, &dict); 847 plist_from_xml(XML_content, bytes, &dict);
848 free(XML_content);
849 XML_content = NULL;
848 if (!dict) 850 if (!dict)
849 return IPHONE_E_PLIST_ERROR; 851 return IPHONE_E_PLIST_ERROR;
850 852
@@ -862,10 +864,6 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
862 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length); 864 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length);
863 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length); 865 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length);
864 866
865 free(XML_content);
866 XML_content = NULL;
867 plist_free(dict);
868 dict = NULL;
869 ret = IPHONE_E_SSL_ERROR; 867 ret = IPHONE_E_SSL_ERROR;
870 if (result_key_type == PLIST_KEY && 868 if (result_key_type == PLIST_KEY &&
871 result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { 869 result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) {
@@ -934,14 +932,14 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
934 // we need to store the session ID for StopSession 932 // we need to store the session ID for StopSession
935 strcpy(control->session_id, session_id); 933 strcpy(control->session_id, session_id);
936 log_debug_msg("SessionID: %s\n", control->session_id); 934 log_debug_msg("SessionID: %s\n", control->session_id);
937 return ret;
938 } 935 }
939 } 936 } else
940
941 if (ret == IPHONE_E_SUCCESS) {
942 log_debug_msg("Failed to get SessionID!\n"); 937 log_debug_msg("Failed to get SessionID!\n");
938 plist_free(dict);
939 dict = NULL;
940
941 if (ret == IPHONE_E_SUCCESS)
943 return ret; 942 return ret;
944 }
945 943
946 log_debug_msg("Apparently failed negotiating with lockdownd.\n"); 944 log_debug_msg("Apparently failed negotiating with lockdownd.\n");
947 return IPHONE_E_SSL_ERROR; 945 return IPHONE_E_SSL_ERROR;