Skip to content

Commit ba9a3f4

Browse files
authored
Merge pull request #329 from google/ios_13_support
iOS 13 support
2 parents ff26218 + b4b877e commit ba9a3f4

File tree

12 files changed

+161
-52
lines changed

12 files changed

+161
-52
lines changed

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ PKG_PROG_PKG_CONFIG
1818
# Checks for libraries.
1919
PKG_CHECK_MODULES(libimobiledevice, libimobiledevice-1.0 >= 1.2.0)
2020
PKG_CHECK_MODULES(libplist, libplist >= 1.12)
21+
PKG_CHECK_MODULES(openssl, openssl >= 0.9.8)
2122
AC_CHECK_LIB([plist], [plist_to_xml],
2223
[ ], [AC_MSG_FAILURE([*** Unable to link with libplist])],
2324
[$libplist_LIBS])

examples/Makefile.am

Lines changed: 2 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)
7-
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS)
6+
AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(openssl_CFLAGS)
7+
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(openssl_LIBS)
88

99
noinst_PROGRAMS = ws_echo1 ws_echo2 wi_client dl_client
1010

examples/wi_client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ int main(int argc, char **argv) {
103103
// connect to device
104104
char *device_id2 = NULL;
105105
int recv_timeout = 1000;
106-
int fd = wi_connect(device_id, &device_id2, NULL, NULL, recv_timeout);
106+
int fd = wi_connect(device_id, &device_id2, NULL, NULL, NULL, recv_timeout);
107107
if (fd < 0) {
108108
return -1;
109109
}

examples/ws_echo2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ int main(int argc, char** argv) {
8888
my_sm->port = port;
8989
//sm->state = my_sm; // optional
9090

91-
sm->add_fd(sm, s_fd, my_sm, true);
91+
sm->add_fd(sm, s_fd, NULL, my_sm, true);
9292

9393
int ret = 0;
9494
while (!quit_flag) {

include/ios-webkit-debug-proxy/ios_webkit_debug_proxy.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ struct iwdp_struct {
6868
// @param to_device_name optional selected device name
6969
// @result fd, or -1 for error
7070
int (*attach)(iwdp_t iwdp, const char *device_id, char **to_device_id,
71-
char **to_device_name, int *to_device_os_version);
71+
char **to_device_name, int *to_device_os_version,
72+
void **to_ssl_session);
7273

7374
// Select the port-scan range for the browser listener.
7475
// @param to_port preferred port, e.g. 9227. If a device is re-attached
@@ -90,8 +91,8 @@ struct iwdp_struct {
9091
iwdp_status (*send)(iwdp_t self, int fd, const char *data, size_t length);
9192

9293
// Add a fd that was returned from attach/listen/connect.
93-
iwdp_status (*add_fd)(iwdp_t self, int fd, void *value,
94-
bool is_server);
94+
iwdp_status (*add_fd)(iwdp_t self, int fd, void *ssl_session, void *value,
95+
bool is_server);
9596

9697
iwdp_status (*remove_fd)(iwdp_t self, int fd);
9798

include/ios-webkit-debug-proxy/socket_manager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ struct sm_struct {
4141

4242
// @param value a value to associate with this fd, which will be passed
4343
// in future on_accept/on_recv/on_close callbacks.
44-
sm_status (*add_fd)(sm_t self, int fd, void *value, bool is_server);
44+
sm_status (*add_fd)(sm_t self, int fd, void *ssl_session, void *value, bool
45+
is_server);
4546

4647
sm_status (*remove_fd)(sm_t self, int fd);
4748

include/ios-webkit-debug-proxy/webinspector.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ typedef uint8_t wi_status;
3333
// positive for milliseconds.
3434
// @result fd, or -1 for error
3535
int wi_connect(const char *device_id, char **to_device_id,
36-
char **to_device_name, int *to_device_os_version, int recv_timeout);
36+
char **to_device_name, int *to_device_os_version,
37+
void **to_ssl_session, int recv_timeout);
3738

3839
struct wi_struct;
3940
typedef struct wi_struct *wi_t;

src/Makefile.am

Lines changed: 2 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)
7-
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(libpcreposix_LIBS)
6+
AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(libpcreposix_CFLAGS) $(openssl_CFLAGS)
7+
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(libpcreposix_LIBS) $(openssl_LIBS)
88

99
lib_LTLIBRARIES = libios_webkit_debug_proxy.la
1010
libios_webkit_debug_proxy_la_LIBADD =

src/ios_webkit_debug_proxy.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ dl_status iwdp_listen(iwdp_t self, const char *device_id) {
328328
(device_id ? device_id : "\"devices list\""),
329329
min_port, max_port);
330330
}
331-
if (self->add_fd(self, s_fd, iport, true)) {
331+
if (self->add_fd(self, s_fd, NULL, iport, true)) {
332332
return self->on_error(self, "add_fd s_fd=%d failed", s_fd);
333333
}
334334
iport->s_fd = s_fd;
@@ -358,7 +358,7 @@ iwdp_status iwdp_start(iwdp_t self) {
358358
}
359359
idl->dl_fd = dl_fd;
360360

361-
if (self->add_fd(self, dl_fd, idl, false)) {
361+
if (self->add_fd(self, dl_fd, NULL, idl, false)) {
362362
return self->on_error(self, "add_fd failed");
363363
}
364364

@@ -410,6 +410,7 @@ dl_status iwdp_on_attach(dl_t dl, const char *device_id, int device_num) {
410410

411411
// connect to inspector
412412
int wi_fd;
413+
void *ssl_session = NULL;
413414
bool is_sim = !strcmp(device_id, "SIMULATOR");
414415
if (is_sim) {
415416
// TODO launch webinspectord
@@ -422,7 +423,7 @@ dl_status iwdp_on_attach(dl_t dl, const char *device_id, int device_num) {
422423
wi_fd = self->connect(self, my->sim_wi_socket_addr);
423424
} else {
424425
wi_fd = self->attach(self, device_id, NULL,
425-
(device_name ? NULL : &device_name), &device_os_version);
426+
(device_name ? NULL : &device_name), &device_os_version, &ssl_session);
426427
}
427428
if (wi_fd < 0) {
428429
self->remove_fd(self, iport->s_fd);
@@ -437,7 +438,7 @@ dl_status iwdp_on_attach(dl_t dl, const char *device_id, int device_num) {
437438
self->is_debug);
438439
iwi->iport = iport;
439440
iport->iwi = iwi;
440-
if (self->add_fd(self, wi_fd, iwi, false)) {
441+
if (self->add_fd(self, wi_fd, ssl_session, iwi, false)) {
441442
self->remove_fd(self, iport->s_fd);
442443
return self->on_error(self, "add_fd wi_fd=%d failed", wi_fd);
443444
}
@@ -981,7 +982,7 @@ ws_status iwdp_on_static_request_for_http(ws_t ws, bool is_head,
981982
ifs->iws = iws;
982983
ifs->fs_fd = fs_fd;
983984
iws->ifs = ifs;
984-
if (self->add_fd(self, fs_fd, ifs, false)) {
985+
if (self->add_fd(self, fs_fd, NULL, ifs, false)) {
985986
free(host_with_port);
986987
free(host);
987988
free(path);

src/ios_webkit_debug_proxy_main.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ int iwdpm_subscribe(iwdp_t iwdp) {
111111
return dl_connect(-1);
112112
}
113113
int iwdpm_attach(iwdp_t iwdp, const char *device_id, char **to_device_id,
114-
char **to_device_name, int *to_device_os_version) {
114+
char **to_device_name, int *to_device_os_version, void **to_ssl_session) {
115115
return wi_connect(device_id, to_device_id, to_device_name,
116-
to_device_os_version, -1);
116+
to_device_os_version, to_ssl_session, -1);
117117
}
118118
iwdp_status iwdpm_select_port(iwdp_t iwdp, const char *device_id,
119119
int *to_port, int *to_min_port, int *to_max_port) {
@@ -146,9 +146,10 @@ iwdp_status iwdpm_send(iwdp_t iwdp, int fd, const char *data, size_t length) {
146146
sm_t sm = ((iwdpm_t)iwdp->state)->sm;
147147
return sm->send(sm, fd, data, length, NULL);
148148
}
149-
iwdp_status iwdpm_add_fd(iwdp_t iwdp, int fd, void *value, bool is_server) {
149+
iwdp_status iwdpm_add_fd(iwdp_t iwdp, int fd, void *ssl_session, void *value,
150+
bool is_server) {
150151
sm_t sm = ((iwdpm_t)iwdp->state)->sm;
151-
return sm->add_fd(sm, fd, value, is_server);
152+
return sm->add_fd(sm, fd, ssl_session, value, is_server);
152153
}
153154
iwdp_status iwdpm_remove_fd(iwdp_t iwdp, int fd) {
154155
sm_t sm = ((iwdpm_t)iwdp->state)->sm;

src/socket_manager.c

Lines changed: 84 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <sys/un.h>
2929
#endif
3030

31+
#include <openssl/ssl.h>
32+
3133
#include "char_buffer.h"
3234
#include "socket_manager.h"
3335
#include "hash_table.h"
@@ -50,6 +52,8 @@ struct sm_private {
5052
fd_set *server_fds; // can on_accept, i.e. "is_server"
5153
fd_set *send_fds; // blocked sends, same as fd_to_sendq.keys
5254
fd_set *recv_fds; // can recv, same as all_fds - sendq.recv_fd's
55+
// fd to ssl_session
56+
ht_t fd_to_ssl;
5357
// fd to on_* callback
5458
ht_t fd_to_value;
5559
// fd to blocked sm_sendq_t, often empty
@@ -301,7 +305,8 @@ sm_status sm_on_debug(sm_t self, const char *format, ...) {
301305
return SM_SUCCESS;
302306
}
303307

304-
sm_status sm_add_fd(sm_t self, int fd, void *value, bool is_server) {
308+
sm_status sm_add_fd(sm_t self, int fd, void *ssl_session, void *value,
309+
bool is_server) {
305310
sm_private_t my = self->private_state;
306311
if (FD_ISSET(fd, my->all_fds)) {
307312
return SM_ERROR;
@@ -310,6 +315,9 @@ sm_status sm_add_fd(sm_t self, int fd, void *value, bool is_server) {
310315
// The above FD_ISSET(..master..) should prevent this
311316
return SM_ERROR;
312317
}
318+
if (ssl_session != NULL && ht_put(my->fd_to_ssl, HT_KEY(fd), ssl_session)) {
319+
return SM_ERROR;
320+
}
313321
// is_server == getsockopt(..., SO_ACCEPTCONN, ...)?
314322
sm_on_debug(self, "ss.add%s_fd(%d)", (is_server ? "_server" : ""), fd);
315323
FD_SET(fd, my->all_fds);
@@ -332,6 +340,7 @@ sm_status sm_remove_fd(sm_t self, int fd) {
332340
if (!FD_ISSET(fd, my->all_fds)) {
333341
return SM_ERROR;
334342
}
343+
ht_put(my->fd_to_ssl, HT_KEY(fd), NULL);
335344
void *value = ht_put(my->fd_to_value, HT_KEY(fd), NULL);
336345
bool is_server = FD_ISSET(fd, my->server_fds);
337346
sm_on_debug(self, "ss.remove%s_fd(%d)", (is_server ? "_server" : ""), fd);
@@ -380,20 +389,35 @@ sm_status sm_send(sm_t self, int fd, const char *data, size_t length,
380389
const char *head = data;
381390
const char *tail = data + length;
382391
if (!sendq) {
392+
void *ssl_session = ht_get_value(my->fd_to_ssl, HT_KEY(fd));
383393
// send as much as we can without blocking
384394
while (1) {
385-
ssize_t sent_bytes = send(fd, (void*)head, (tail - head), 0);
386-
if (sent_bytes <= 0) {
395+
ssize_t sent_bytes;
396+
if (ssl_session == NULL) {
397+
sent_bytes = send(fd, (void*)head, (tail - head), 0);
398+
if (sent_bytes <= 0) {
387399
#ifdef WIN32
388-
if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) {
400+
if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) {
389401
#else
390-
if (sent_bytes && errno != EWOULDBLOCK) {
402+
if (sent_bytes && errno != EWOULDBLOCK) {
391403
#endif
392-
sm_on_debug(self, "ss.failed fd=%d", fd);
393-
perror("send failed");
394-
return SM_ERROR;
404+
sm_on_debug(self, "ss.failed fd=%d", fd);
405+
perror("send failed");
406+
return SM_ERROR;
407+
}
408+
break;
409+
}
410+
} else {
411+
sent_bytes = SSL_write((SSL *)ssl_session, (void*)head, tail - head);
412+
if (sent_bytes <= 0) {
413+
if (SSL_get_error(ssl_session, sent_bytes) != SSL_ERROR_WANT_READ &&
414+
SSL_get_error(ssl_session, sent_bytes) != SSL_ERROR_WANT_WRITE) {
415+
sm_on_debug(self, "ss.failed fd=%d", fd);
416+
perror("ssl send failed");
417+
return SM_ERROR;
418+
}
419+
break;
395420
}
396-
break;
397421
}
398422
head += sent_bytes;
399423
if (head >= tail) {
@@ -454,7 +478,7 @@ void sm_accept(sm_t self, int fd) {
454478
#else
455479
close(new_fd);
456480
#endif
457-
} else if (self->add_fd(self, new_fd, new_value, false)) {
481+
} else if (self->add_fd(self, new_fd, NULL, new_value, false)) {
458482
self->on_close(self, new_fd, new_value, false);
459483
#ifdef WIN32
460484
closesocket(new_fd);
@@ -468,27 +492,42 @@ void sm_accept(sm_t self, int fd) {
468492
void sm_resend(sm_t self, int fd) {
469493
sm_private_t my = self->private_state;
470494
sm_sendq_t sendq = ht_get_value(my->fd_to_sendq, HT_KEY(fd));
495+
void *ssl_session = ht_get_value(my->fd_to_ssl, HT_KEY(fd));
471496
while (sendq) {
472497
char *head = sendq->head;
473498
char *tail = sendq->tail;
474499
// send as much as we can without blocking
475500
sm_on_debug(self, "ss.sendq<%p> resume send to fd=%d len=%zd", sendq, fd,
476501
(tail - head));
477502
while (head < tail) {
478-
ssize_t sent_bytes = send(fd, (void*)head, (tail - head), 0);
479-
if (sent_bytes <= 0) {
503+
ssize_t sent_bytes;
504+
if (ssl_session == NULL) {
505+
sent_bytes = send(fd, (void*)head, (tail - head), 0);
506+
if (sent_bytes <= 0) {
480507
#ifdef WIN32
481-
if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) {
482-
fprintf(stderr, "sendq retry failed with error: %d\n",
483-
WSAGetLastError());
508+
if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) {
509+
fprintf(stderr, "sendq retry failed with error: %d\n",
510+
WSAGetLastError());
484511
#else
485-
if (sent_bytes && errno != EWOULDBLOCK) {
486-
perror("sendq retry failed");
512+
if (sent_bytes && errno != EWOULDBLOCK) {
513+
perror("sendq retry failed");
487514
#endif
488-
self->remove_fd(self, fd);
489-
return;
515+
self->remove_fd(self, fd);
516+
return;
517+
}
518+
break;
519+
}
520+
} else {
521+
sent_bytes = SSL_write((SSL *)ssl_session, (void*)head, tail - head);
522+
if (sent_bytes <= 0) {
523+
if (SSL_get_error(ssl_session, sent_bytes) != SSL_ERROR_WANT_READ &&
524+
SSL_get_error(ssl_session, sent_bytes) != SSL_ERROR_WANT_WRITE) {
525+
perror("ssl sendq retry failed");
526+
self->remove_fd(self, fd);
527+
return;
528+
}
529+
break;
490530
}
491-
break;
492531
}
493532
head += sent_bytes;
494533
}
@@ -535,19 +574,33 @@ void sm_resend(sm_t self, int fd) {
535574
void sm_recv(sm_t self, int fd) {
536575
sm_private_t my = self->private_state;
537576
my->curr_recv_fd = fd;
577+
void *ssl_session = ht_get_value(my->fd_to_ssl, HT_KEY(fd));
538578
while (1) {
539-
ssize_t read_bytes = recv(fd, my->tmp_buf, my->tmp_buf_length, RECV_FLAGS);
540-
if (read_bytes < 0) {
579+
ssize_t read_bytes;
580+
if (ssl_session == NULL) {
581+
read_bytes = recv(fd, my->tmp_buf, my->tmp_buf_length, RECV_FLAGS);
582+
if (read_bytes < 0) {
541583
#ifdef WIN32
542-
if (WSAGetLastError() != WSAEWOULDBLOCK) {
543-
fprintf(stderr, "recv failed with error %d\n", WSAGetLastError());
584+
if (WSAGetLastError() != WSAEWOULDBLOCK) {
585+
fprintf(stderr, "recv failed with error %d\n", WSAGetLastError());
544586
#else
545-
if (errno != EWOULDBLOCK) {
546-
perror("recv failed");
587+
if (errno != EWOULDBLOCK) {
588+
perror("recv failed");
547589
#endif
548-
self->remove_fd(self, fd);
590+
self->remove_fd(self, fd);
591+
}
592+
break;
593+
}
594+
} else {
595+
read_bytes = SSL_read((SSL *)ssl_session, my->tmp_buf, my->tmp_buf_length);
596+
if (read_bytes <= 0) {
597+
if (SSL_get_error(ssl_session, read_bytes) != SSL_ERROR_WANT_READ &&
598+
SSL_get_error(ssl_session, read_bytes) != SSL_ERROR_WANT_WRITE) {
599+
perror("ssl recv failed");
600+
self->remove_fd(self, fd);
601+
}
602+
break;
549603
}
550-
break;
551604
}
552605
sm_on_debug(self, "ss.recv fd=%d len=%zd", fd, read_bytes);
553606
void *value = ht_get_value(my->fd_to_value, HT_KEY(fd));
@@ -648,6 +701,7 @@ void sm_private_free(sm_private_t my) {
648701
free(my->tmp_send_fds);
649702
free(my->tmp_recv_fds);
650703
free(my->tmp_fail_fds);
704+
ht_free(my->fd_to_ssl);
651705
ht_free(my->fd_to_value);
652706
ht_free(my->fd_to_sendq);
653707
free(my->tmp_buf);
@@ -669,13 +723,14 @@ sm_private_t sm_private_new(size_t buf_length) {
669723
my->tmp_send_fds = (fd_set *)malloc(SIZEOF_FD_SET);
670724
my->tmp_recv_fds = (fd_set *)malloc(SIZEOF_FD_SET);
671725
my->tmp_fail_fds = (fd_set *)malloc(SIZEOF_FD_SET);
726+
my->fd_to_ssl = ht_new(HT_INT_KEYS);
672727
my->fd_to_value = ht_new(HT_INT_KEYS);
673728
my->fd_to_sendq = ht_new(HT_INT_KEYS);
674729
my->tmp_buf = (char *)calloc(buf_length, sizeof(char *));
675730
if (!my->tmp_buf || !my->all_fds || !my->server_fds ||
676731
!my->send_fds || !my->recv_fds ||
677732
!my->tmp_send_fds || !my->tmp_recv_fds || !my->tmp_fail_fds ||
678-
!my->fd_to_value || !my->fd_to_sendq) {
733+
!my->fd_to_ssl || !my->fd_to_value || !my->fd_to_sendq) {
679734
sm_private_free(my);
680735
return NULL;
681736
}

0 commit comments

Comments
 (0)