Skip to content

Commit dad2336

Browse files
authored
Handle ssl connections internally (#394)
* initiate ssl sessions from iwdp * shutdown SSL session on disconnect * bump openssl dependency
1 parent d06f8d6 commit dad2336

File tree

7 files changed

+194
-60
lines changed

7 files changed

+194
-60
lines changed

configure.ac

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ PKG_PROG_PKG_CONFIG
1818
# Checks for libraries.
1919
PKG_CHECK_MODULES(libimobiledevice, libimobiledevice-1.0 >= 1.3.0)
2020
PKG_CHECK_MODULES(libplist, libplist-2.0 >= 2.2.0)
21-
PKG_CHECK_MODULES(openssl, openssl >= 0.9.8)
21+
PKG_CHECK_MODULES(libusbmuxd, libusbmuxd-2.0 >= 2.0.0)
22+
PKG_CHECK_MODULES(openssl, openssl >= 1.1.0)
2223
AC_CHECK_LIB([plist-2.0], [plist_to_xml],
2324
[ ], [AC_MSG_FAILURE([*** Unable to link with libplist])],
2425
[$libplist_LIBS])

examples/Makefile.am

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src
55

6-
AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(openssl_CFLAGS)
7-
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(openssl_LIBS)
6+
AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(libusbmuxd_CFLAGS) $(openssl_CFLAGS)
7+
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(libusbmuxd_LIBS) $(openssl_LIBS)
88

99
noinst_PROGRAMS = ws_echo1 ws_echo2 wi_client dl_client
1010

@@ -34,10 +34,12 @@ wi_client_SOURCES = \
3434
wi_client.c \
3535
char_buffer.h \
3636
rpc.h \
37+
idevice_ext.h \
3738
webinspector.h
3839
wi_client_LDADD = \
3940
../src/char_buffer.o \
4041
../src/rpc.o \
42+
../src/idevice_ext.o \
4143
../src/webinspector.o
4244

4345
dl_client_SOURCES = \
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Google BSD license https://developers.google.com/google-bsd-license
2+
// Copyright 2012 Google Inc. [email protected]
3+
4+
//
5+
// libimobildevice extensions
6+
//
7+
8+
#ifndef IDEVICE_EXT_H
9+
#define IDEVICE_EXT_H
10+
11+
#ifdef __cplusplus
12+
extern "C" {
13+
#endif
14+
15+
#include <openssl/ssl.h>
16+
#include <libimobiledevice/libimobiledevice.h>
17+
18+
int idevice_ext_connection_enable_ssl(const char *device_id, int fd, SSL **to_session);
19+
20+
#ifdef __cplusplus
21+
}
22+
#endif
23+
24+
#endif /* IDEVICE_EXT_H */

src/Makefile.am

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/ios-webkit-debug-proxy
55

6-
AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(libpcreposix_CFLAGS) $(openssl_CFLAGS)
7-
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(libpcreposix_LIBS) $(openssl_LIBS)
6+
AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(libusbmuxd_CFLAGS) $(libpcreposix_CFLAGS) $(openssl_CFLAGS)
7+
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(libusbmuxd_LIBS) $(libpcreposix_LIBS) $(openssl_LIBS)
88

99
lib_LTLIBRARIES = libios_webkit_debug_proxy.la
1010
libios_webkit_debug_proxy_la_LIBADD =
@@ -20,6 +20,7 @@ libios_webkit_debug_proxy_la_SOURCES = ios_webkit_debug_proxy_main.c \
2020
sha1.c sha1.h \
2121
socket_manager.c socket_manager.h \
2222
validate_utf8.h \
23+
idevice_ext.c idevice_ext.h \
2324
webinspector.c webinspector.h \
2425
websocket.c websocket.h
2526

@@ -35,6 +36,7 @@ ios_webkit_debug_proxy_SOURCES = ios_webkit_debug_proxy_main.c \
3536
sha1.c sha1.h \
3637
socket_manager.c socket_manager.h \
3738
validate_utf8.h \
39+
idevice_ext.c idevice_ext.h \
3840
webinspector.c webinspector.h \
3941
websocket.c websocket.h
4042
ios_webkit_debug_proxy_CFLAGS = $(AM_CFLAGS)

src/idevice_ext.c

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// Google BSD license https://developers.google.com/google-bsd-license
2+
// Copyright 2012 Google Inc. [email protected]
3+
4+
#ifdef HAVE_CONFIG_H
5+
#include <config.h>
6+
#endif
7+
8+
#define _GNU_SOURCE
9+
#include <string.h>
10+
#include <stdio.h>
11+
#include <time.h>
12+
#ifdef WIN32
13+
#include <windows.h>
14+
#endif
15+
16+
#include <usbmuxd.h>
17+
18+
#include "idevice_ext.h"
19+
20+
typedef struct {
21+
unsigned char *data;
22+
unsigned int size;
23+
} key_data_t;
24+
25+
int read_pair_record(const char *udid, plist_t *pair_record) {
26+
char* record_data = NULL;
27+
uint32_t record_size = 0;
28+
29+
int res = usbmuxd_read_pair_record(udid, &record_data, &record_size);
30+
if (res < 0) {
31+
free(record_data);
32+
return -1;
33+
}
34+
35+
*pair_record = NULL;
36+
plist_from_memory(record_data, record_size, pair_record);
37+
free(record_data);
38+
39+
if (!*pair_record) {
40+
return -1;
41+
}
42+
43+
return 0;
44+
}
45+
46+
int pair_record_get_item_as_key_data(plist_t pair_record, const char* name, key_data_t *value) {
47+
char* buffer = NULL;
48+
uint64_t length = 0;
49+
plist_t node = plist_dict_get_item(pair_record, name);
50+
51+
if (node && plist_get_node_type(node) == PLIST_DATA) {
52+
plist_get_data_val(node, &buffer, &length);
53+
value->data = (unsigned char*)malloc(length+1);
54+
memcpy(value->data, buffer, length);
55+
value->data[length] = '\0';
56+
value->size = length+1;
57+
free(buffer);
58+
return 0;
59+
}
60+
61+
return -1;
62+
}
63+
64+
int idevice_ext_connection_enable_ssl(const char *device_id, int fd, SSL **to_session) {
65+
plist_t pair_record = NULL;
66+
if (read_pair_record(device_id, &pair_record)) {
67+
fprintf(stderr, "Failed to read pair record\n");
68+
return -1;
69+
}
70+
71+
key_data_t root_cert = { NULL, 0 };
72+
key_data_t root_privkey = { NULL, 0 };
73+
pair_record_get_item_as_key_data(pair_record, "RootCertificate", &root_cert);
74+
pair_record_get_item_as_key_data(pair_record, "RootPrivateKey", &root_privkey);
75+
plist_free(pair_record);
76+
77+
BIO *ssl_bio = BIO_new(BIO_s_socket());
78+
if (!ssl_bio) {
79+
fprintf(stderr, "Could not create SSL bio\n");
80+
return -1;
81+
}
82+
83+
BIO_set_fd(ssl_bio, fd, BIO_NOCLOSE);
84+
SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method());
85+
if (ssl_ctx == NULL) {
86+
fprintf(stderr, "Could not create SSL context\n");
87+
BIO_free(ssl_bio);
88+
}
89+
90+
SSL_CTX_set_security_level(ssl_ctx, 0);
91+
SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_VERSION);
92+
93+
BIO* membp;
94+
X509* rootCert = NULL;
95+
membp = BIO_new_mem_buf(root_cert.data, root_cert.size);
96+
PEM_read_bio_X509(membp, &rootCert, NULL, NULL);
97+
BIO_free(membp);
98+
SSL_CTX_use_certificate(ssl_ctx, rootCert);
99+
X509_free(rootCert);
100+
free(root_cert.data);
101+
102+
RSA* rootPrivKey = NULL;
103+
membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size);
104+
PEM_read_bio_RSAPrivateKey(membp, &rootPrivKey, NULL, NULL);
105+
BIO_free(membp);
106+
SSL_CTX_use_RSAPrivateKey(ssl_ctx, rootPrivKey);
107+
RSA_free(rootPrivKey);
108+
free(root_privkey.data);
109+
110+
SSL *ssl = SSL_new(ssl_ctx);
111+
if (!ssl) {
112+
fprintf(stderr, "Could not create SSL object\n");
113+
BIO_free(ssl_bio);
114+
SSL_CTX_free(ssl_ctx);
115+
return -1;
116+
}
117+
118+
SSL_set_connect_state(ssl);
119+
SSL_set_verify(ssl, 0, NULL);
120+
SSL_set_bio(ssl, ssl_bio, ssl_bio);
121+
122+
int ssl_error = 0;
123+
while (1) {
124+
ssl_error = SSL_get_error(ssl, SSL_do_handshake(ssl));
125+
if (ssl_error == 0 || ssl_error != SSL_ERROR_WANT_READ) {
126+
break;
127+
}
128+
#ifdef WIN32
129+
Sleep(100);
130+
#else
131+
struct timespec ts = { 0, 100000000 };
132+
nanosleep(&ts, NULL);
133+
#endif
134+
}
135+
136+
if (ssl_error != 0) {
137+
SSL_free(ssl);
138+
SSL_CTX_free(ssl_ctx);
139+
return ssl_error;
140+
}
141+
142+
*to_session = ssl;
143+
return 0;
144+
}

src/socket_manager.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,11 @@ sm_status sm_remove_fd(sm_t self, int fd) {
340340
if (!FD_ISSET(fd, my->all_fds)) {
341341
return SM_ERROR;
342342
}
343-
ht_put(my->fd_to_ssl, HT_KEY(fd), NULL);
343+
SSL *ssl_session = (SSL *)ht_put(my->fd_to_ssl, HT_KEY(fd), NULL);
344+
if (ssl_session) {
345+
SSL_shutdown(ssl_session);
346+
SSL_free(ssl_session);
347+
}
344348
void *value = ht_put(my->fd_to_value, HT_KEY(fd), NULL);
345349
bool is_server = FD_ISSET(fd, my->server_fds);
346350
sm_on_debug(self, "ss.remove%s_fd(%d)", (is_server ? "_server" : ""), fd);

src/webinspector.c

Lines changed: 11 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <libimobiledevice/lockdown.h>
3131

3232
#include "char_buffer.h"
33+
#include "idevice_ext.h"
3334
#include "webinspector.h"
3435

3536

@@ -52,50 +53,6 @@ struct wi_private {
5253
//
5354
// CONNECT
5455
//
55-
56-
// based on latest libimobiledevice/src/idevice.h
57-
struct idevice_connection_private {
58-
idevice_t device;
59-
enum idevice_connection_type type;
60-
void *data;
61-
void *ssl_data;
62-
};
63-
64-
struct ssl_data_private {
65-
SSL *session;
66-
SSL_CTX *ctx;
67-
};
68-
typedef struct ssl_data_private *ssl_data_t;
69-
70-
wi_status idevice_connection_get_ssl_session(idevice_connection_t connection,
71-
SSL **to_session) {
72-
if (!connection || !to_session) {
73-
return WI_ERROR;
74-
}
75-
76-
idevice_connection_private *c = (
77-
(sizeof(*connection) == sizeof(idevice_connection_private)) ?
78-
(idevice_connection_private *) connection : NULL);
79-
80-
if (!c || c->data <= 0) {
81-
perror("Invalid idevice_connection struct. Please verify that "
82-
__FILE__ "'s idevice_connection_private matches your version of"
83-
" libimbiledevice/src/idevice.h");
84-
return WI_ERROR;
85-
}
86-
87-
ssl_data_t sd = (ssl_data_t)c->ssl_data;
88-
if (!sd || !sd->session) {
89-
perror("Invalid ssl_data struct. Make sure libimobiledevice was compiled"
90-
" with openssl. Otherwise please verify that " __FILE__ "'s ssl_data"
91-
" matches your version of libimbiledevice/src/idevice.h");
92-
return WI_ERROR;
93-
}
94-
95-
*to_session = sd->session;
96-
return WI_SUCCESS;
97-
}
98-
9956
int wi_connect(const char *device_id, char **to_device_id,
10057
char **to_device_name, int *to_device_os_version,
10158
void **to_ssl_session, int recv_timeout) {
@@ -166,16 +123,6 @@ int wi_connect(const char *device_id, char **to_device_id,
166123
goto leave_cleanup;
167124
}
168125

169-
// enable ssl
170-
if (service->ssl_enabled == 1) {
171-
if (!to_ssl_session || idevice_connection_enable_ssl(connection) ||
172-
idevice_connection_get_ssl_session(connection, &ssl_session)) {
173-
perror("ssl connection failed!");
174-
goto leave_cleanup;
175-
}
176-
*to_ssl_session = ssl_session;
177-
}
178-
179126
if (client) {
180127
// not needed anymore
181128
lockdownd_client_free(client);
@@ -188,6 +135,16 @@ int wi_connect(const char *device_id, char **to_device_id,
188135
goto leave_cleanup;
189136
}
190137

138+
// enable ssl
139+
if (service->ssl_enabled == 1) {
140+
int ssl_ret = 0;
141+
if (!to_ssl_session || (ssl_ret = idevice_ext_connection_enable_ssl(device_id, fd, &ssl_session))) {
142+
fprintf(stderr, "SSL connection failed! Error code: %d\n", ssl_ret);
143+
goto leave_cleanup;
144+
}
145+
*to_ssl_session = ssl_session;
146+
}
147+
191148
if (recv_timeout < 0) {
192149
#ifdef WIN32
193150
u_long nb = 1;

0 commit comments

Comments
 (0)