Skip to content

iOS 13 support #329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ PKG_PROG_PKG_CONFIG
# Checks for libraries.
PKG_CHECK_MODULES(libimobiledevice, libimobiledevice-1.0 >= 1.2.0)
PKG_CHECK_MODULES(libplist, libplist >= 1.12)
PKG_CHECK_MODULES(openssl, openssl >= 0.9.8)
AC_CHECK_LIB([plist], [plist_to_xml],
[ ], [AC_MSG_FAILURE([*** Unable to link with libplist])],
[$libplist_LIBS])
Expand Down
4 changes: 2 additions & 2 deletions examples/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

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

AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS)
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS)
AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(openssl_CFLAGS)
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(openssl_LIBS)

noinst_PROGRAMS = ws_echo1 ws_echo2 wi_client dl_client

Expand Down
2 changes: 1 addition & 1 deletion examples/wi_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ int main(int argc, char **argv) {
// connect to device
char *device_id2 = NULL;
int recv_timeout = 1000;
int fd = wi_connect(device_id, &device_id2, NULL, NULL, recv_timeout);
int fd = wi_connect(device_id, &device_id2, NULL, NULL, NULL, recv_timeout);
if (fd < 0) {
return -1;
}
Expand Down
2 changes: 1 addition & 1 deletion examples/ws_echo2.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ int main(int argc, char** argv) {
my_sm->port = port;
//sm->state = my_sm; // optional

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

int ret = 0;
while (!quit_flag) {
Expand Down
7 changes: 4 additions & 3 deletions include/ios-webkit-debug-proxy/ios_webkit_debug_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ struct iwdp_struct {
// @param to_device_name optional selected device name
// @result fd, or -1 for error
int (*attach)(iwdp_t iwdp, const char *device_id, char **to_device_id,
char **to_device_name, int *to_device_os_version);
char **to_device_name, int *to_device_os_version,
void **to_ssl_session);

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

// Add a fd that was returned from attach/listen/connect.
iwdp_status (*add_fd)(iwdp_t self, int fd, void *value,
bool is_server);
iwdp_status (*add_fd)(iwdp_t self, int fd, void *ssl_session, void *value,
bool is_server);

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

Expand Down
3 changes: 2 additions & 1 deletion include/ios-webkit-debug-proxy/socket_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ struct sm_struct {

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

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

Expand Down
3 changes: 2 additions & 1 deletion include/ios-webkit-debug-proxy/webinspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ typedef uint8_t wi_status;
// positive for milliseconds.
// @result fd, or -1 for error
int wi_connect(const char *device_id, char **to_device_id,
char **to_device_name, int *to_device_os_version, int recv_timeout);
char **to_device_name, int *to_device_os_version,
void **to_ssl_session, int recv_timeout);

struct wi_struct;
typedef struct wi_struct *wi_t;
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

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

AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(libpcreposix_CFLAGS)
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(libpcreposix_LIBS)
AM_CFLAGS = $(GLOBAL_CFLAGS) $(libimobiledevice_CFLAGS) $(libplist_CFLAGS) $(libpcreposix_CFLAGS) $(openssl_CFLAGS)
AM_LDFLAGS = $(libimobiledevice_LIBS) $(libplist_LIBS) $(libpcreposix_LIBS) $(openssl_LIBS)

lib_LTLIBRARIES = libios_webkit_debug_proxy.la
libios_webkit_debug_proxy_la_LIBADD =
Expand Down
11 changes: 6 additions & 5 deletions src/ios_webkit_debug_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ dl_status iwdp_listen(iwdp_t self, const char *device_id) {
(device_id ? device_id : "\"devices list\""),
min_port, max_port);
}
if (self->add_fd(self, s_fd, iport, true)) {
if (self->add_fd(self, s_fd, NULL, iport, true)) {
return self->on_error(self, "add_fd s_fd=%d failed", s_fd);
}
iport->s_fd = s_fd;
Expand Down Expand Up @@ -358,7 +358,7 @@ iwdp_status iwdp_start(iwdp_t self) {
}
idl->dl_fd = dl_fd;

if (self->add_fd(self, dl_fd, idl, false)) {
if (self->add_fd(self, dl_fd, NULL, idl, false)) {
return self->on_error(self, "add_fd failed");
}

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

// connect to inspector
int wi_fd;
void *ssl_session = NULL;
bool is_sim = !strcmp(device_id, "SIMULATOR");
if (is_sim) {
// TODO launch webinspectord
Expand All @@ -422,7 +423,7 @@ dl_status iwdp_on_attach(dl_t dl, const char *device_id, int device_num) {
wi_fd = self->connect(self, my->sim_wi_socket_addr);
} else {
wi_fd = self->attach(self, device_id, NULL,
(device_name ? NULL : &device_name), &device_os_version);
(device_name ? NULL : &device_name), &device_os_version, &ssl_session);
}
if (wi_fd < 0) {
self->remove_fd(self, iport->s_fd);
Expand All @@ -437,7 +438,7 @@ dl_status iwdp_on_attach(dl_t dl, const char *device_id, int device_num) {
self->is_debug);
iwi->iport = iport;
iport->iwi = iwi;
if (self->add_fd(self, wi_fd, iwi, false)) {
if (self->add_fd(self, wi_fd, ssl_session, iwi, false)) {
self->remove_fd(self, iport->s_fd);
return self->on_error(self, "add_fd wi_fd=%d failed", wi_fd);
}
Expand Down Expand Up @@ -981,7 +982,7 @@ ws_status iwdp_on_static_request_for_http(ws_t ws, bool is_head,
ifs->iws = iws;
ifs->fs_fd = fs_fd;
iws->ifs = ifs;
if (self->add_fd(self, fs_fd, ifs, false)) {
if (self->add_fd(self, fs_fd, NULL, ifs, false)) {
free(host_with_port);
free(host);
free(path);
Expand Down
9 changes: 5 additions & 4 deletions src/ios_webkit_debug_proxy_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ int iwdpm_subscribe(iwdp_t iwdp) {
return dl_connect(-1);
}
int iwdpm_attach(iwdp_t iwdp, const char *device_id, char **to_device_id,
char **to_device_name, int *to_device_os_version) {
char **to_device_name, int *to_device_os_version, void **to_ssl_session) {
return wi_connect(device_id, to_device_id, to_device_name,
to_device_os_version, -1);
to_device_os_version, to_ssl_session, -1);
}
iwdp_status iwdpm_select_port(iwdp_t iwdp, const char *device_id,
int *to_port, int *to_min_port, int *to_max_port) {
Expand Down Expand Up @@ -146,9 +146,10 @@ iwdp_status iwdpm_send(iwdp_t iwdp, int fd, const char *data, size_t length) {
sm_t sm = ((iwdpm_t)iwdp->state)->sm;
return sm->send(sm, fd, data, length, NULL);
}
iwdp_status iwdpm_add_fd(iwdp_t iwdp, int fd, void *value, bool is_server) {
iwdp_status iwdpm_add_fd(iwdp_t iwdp, int fd, void *ssl_session, void *value,
bool is_server) {
sm_t sm = ((iwdpm_t)iwdp->state)->sm;
return sm->add_fd(sm, fd, value, is_server);
return sm->add_fd(sm, fd, ssl_session, value, is_server);
}
iwdp_status iwdpm_remove_fd(iwdp_t iwdp, int fd) {
sm_t sm = ((iwdpm_t)iwdp->state)->sm;
Expand Down
113 changes: 84 additions & 29 deletions src/socket_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <sys/un.h>
#endif

#include <openssl/ssl.h>

#include "char_buffer.h"
#include "socket_manager.h"
#include "hash_table.h"
Expand All @@ -50,6 +52,8 @@ struct sm_private {
fd_set *server_fds; // can on_accept, i.e. "is_server"
fd_set *send_fds; // blocked sends, same as fd_to_sendq.keys
fd_set *recv_fds; // can recv, same as all_fds - sendq.recv_fd's
// fd to ssl_session
ht_t fd_to_ssl;
// fd to on_* callback
ht_t fd_to_value;
// fd to blocked sm_sendq_t, often empty
Expand Down Expand Up @@ -301,7 +305,8 @@ sm_status sm_on_debug(sm_t self, const char *format, ...) {
return SM_SUCCESS;
}

sm_status sm_add_fd(sm_t self, int fd, void *value, bool is_server) {
sm_status sm_add_fd(sm_t self, int fd, void *ssl_session, void *value,
bool is_server) {
sm_private_t my = self->private_state;
if (FD_ISSET(fd, my->all_fds)) {
return SM_ERROR;
Expand All @@ -310,6 +315,9 @@ sm_status sm_add_fd(sm_t self, int fd, void *value, bool is_server) {
// The above FD_ISSET(..master..) should prevent this
return SM_ERROR;
}
if (ssl_session != NULL && ht_put(my->fd_to_ssl, HT_KEY(fd), ssl_session)) {
return SM_ERROR;
}
// is_server == getsockopt(..., SO_ACCEPTCONN, ...)?
sm_on_debug(self, "ss.add%s_fd(%d)", (is_server ? "_server" : ""), fd);
FD_SET(fd, my->all_fds);
Expand All @@ -332,6 +340,7 @@ sm_status sm_remove_fd(sm_t self, int fd) {
if (!FD_ISSET(fd, my->all_fds)) {
return SM_ERROR;
}
ht_put(my->fd_to_ssl, HT_KEY(fd), NULL);
void *value = ht_put(my->fd_to_value, HT_KEY(fd), NULL);
bool is_server = FD_ISSET(fd, my->server_fds);
sm_on_debug(self, "ss.remove%s_fd(%d)", (is_server ? "_server" : ""), fd);
Expand Down Expand Up @@ -380,20 +389,35 @@ sm_status sm_send(sm_t self, int fd, const char *data, size_t length,
const char *head = data;
const char *tail = data + length;
if (!sendq) {
void *ssl_session = ht_get_value(my->fd_to_ssl, HT_KEY(fd));
// send as much as we can without blocking
while (1) {
ssize_t sent_bytes = send(fd, (void*)head, (tail - head), 0);
if (sent_bytes <= 0) {
ssize_t sent_bytes;
if (ssl_session == NULL) {
sent_bytes = send(fd, (void*)head, (tail - head), 0);
if (sent_bytes <= 0) {
#ifdef WIN32
if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) {
if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) {
#else
if (sent_bytes && errno != EWOULDBLOCK) {
if (sent_bytes && errno != EWOULDBLOCK) {
#endif
sm_on_debug(self, "ss.failed fd=%d", fd);
perror("send failed");
return SM_ERROR;
sm_on_debug(self, "ss.failed fd=%d", fd);
perror("send failed");
return SM_ERROR;
}
break;
}
} else {
sent_bytes = SSL_write((SSL *)ssl_session, (void*)head, tail - head);
if (sent_bytes <= 0) {
if (SSL_get_error(ssl_session, sent_bytes) != SSL_ERROR_WANT_READ &&
SSL_get_error(ssl_session, sent_bytes) != SSL_ERROR_WANT_WRITE) {
sm_on_debug(self, "ss.failed fd=%d", fd);
perror("ssl send failed");
return SM_ERROR;
}
break;
}
break;
}
head += sent_bytes;
if (head >= tail) {
Expand Down Expand Up @@ -454,7 +478,7 @@ void sm_accept(sm_t self, int fd) {
#else
close(new_fd);
#endif
} else if (self->add_fd(self, new_fd, new_value, false)) {
} else if (self->add_fd(self, new_fd, NULL, new_value, false)) {
self->on_close(self, new_fd, new_value, false);
#ifdef WIN32
closesocket(new_fd);
Expand All @@ -468,27 +492,42 @@ void sm_accept(sm_t self, int fd) {
void sm_resend(sm_t self, int fd) {
sm_private_t my = self->private_state;
sm_sendq_t sendq = ht_get_value(my->fd_to_sendq, HT_KEY(fd));
void *ssl_session = ht_get_value(my->fd_to_ssl, HT_KEY(fd));
while (sendq) {
char *head = sendq->head;
char *tail = sendq->tail;
// send as much as we can without blocking
sm_on_debug(self, "ss.sendq<%p> resume send to fd=%d len=%zd", sendq, fd,
(tail - head));
while (head < tail) {
ssize_t sent_bytes = send(fd, (void*)head, (tail - head), 0);
if (sent_bytes <= 0) {
ssize_t sent_bytes;
if (ssl_session == NULL) {
sent_bytes = send(fd, (void*)head, (tail - head), 0);
if (sent_bytes <= 0) {
#ifdef WIN32
if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) {
fprintf(stderr, "sendq retry failed with error: %d\n",
WSAGetLastError());
if (sent_bytes && WSAGetLastError() != WSAEWOULDBLOCK) {
fprintf(stderr, "sendq retry failed with error: %d\n",
WSAGetLastError());
#else
if (sent_bytes && errno != EWOULDBLOCK) {
perror("sendq retry failed");
if (sent_bytes && errno != EWOULDBLOCK) {
perror("sendq retry failed");
#endif
self->remove_fd(self, fd);
return;
self->remove_fd(self, fd);
return;
}
break;
}
} else {
sent_bytes = SSL_write((SSL *)ssl_session, (void*)head, tail - head);
if (sent_bytes <= 0) {
if (SSL_get_error(ssl_session, sent_bytes) != SSL_ERROR_WANT_READ &&
SSL_get_error(ssl_session, sent_bytes) != SSL_ERROR_WANT_WRITE) {
perror("ssl sendq retry failed");
self->remove_fd(self, fd);
return;
}
break;
}
break;
}
head += sent_bytes;
}
Expand Down Expand Up @@ -535,19 +574,33 @@ void sm_resend(sm_t self, int fd) {
void sm_recv(sm_t self, int fd) {
sm_private_t my = self->private_state;
my->curr_recv_fd = fd;
void *ssl_session = ht_get_value(my->fd_to_ssl, HT_KEY(fd));
while (1) {
ssize_t read_bytes = recv(fd, my->tmp_buf, my->tmp_buf_length, RECV_FLAGS);
if (read_bytes < 0) {
ssize_t read_bytes;
if (ssl_session == NULL) {
read_bytes = recv(fd, my->tmp_buf, my->tmp_buf_length, RECV_FLAGS);
if (read_bytes < 0) {
#ifdef WIN32
if (WSAGetLastError() != WSAEWOULDBLOCK) {
fprintf(stderr, "recv failed with error %d\n", WSAGetLastError());
if (WSAGetLastError() != WSAEWOULDBLOCK) {
fprintf(stderr, "recv failed with error %d\n", WSAGetLastError());
#else
if (errno != EWOULDBLOCK) {
perror("recv failed");
if (errno != EWOULDBLOCK) {
perror("recv failed");
#endif
self->remove_fd(self, fd);
self->remove_fd(self, fd);
}
break;
}
} else {
read_bytes = SSL_read((SSL *)ssl_session, my->tmp_buf, my->tmp_buf_length);
if (read_bytes <= 0) {
if (SSL_get_error(ssl_session, read_bytes) != SSL_ERROR_WANT_READ &&
SSL_get_error(ssl_session, read_bytes) != SSL_ERROR_WANT_WRITE) {
perror("ssl recv failed");
self->remove_fd(self, fd);
}
break;
}
break;
}
sm_on_debug(self, "ss.recv fd=%d len=%zd", fd, read_bytes);
void *value = ht_get_value(my->fd_to_value, HT_KEY(fd));
Expand Down Expand Up @@ -648,6 +701,7 @@ void sm_private_free(sm_private_t my) {
free(my->tmp_send_fds);
free(my->tmp_recv_fds);
free(my->tmp_fail_fds);
ht_free(my->fd_to_ssl);
ht_free(my->fd_to_value);
ht_free(my->fd_to_sendq);
free(my->tmp_buf);
Expand All @@ -669,13 +723,14 @@ sm_private_t sm_private_new(size_t buf_length) {
my->tmp_send_fds = (fd_set *)malloc(SIZEOF_FD_SET);
my->tmp_recv_fds = (fd_set *)malloc(SIZEOF_FD_SET);
my->tmp_fail_fds = (fd_set *)malloc(SIZEOF_FD_SET);
my->fd_to_ssl = ht_new(HT_INT_KEYS);
my->fd_to_value = ht_new(HT_INT_KEYS);
my->fd_to_sendq = ht_new(HT_INT_KEYS);
my->tmp_buf = (char *)calloc(buf_length, sizeof(char *));
if (!my->tmp_buf || !my->all_fds || !my->server_fds ||
!my->send_fds || !my->recv_fds ||
!my->tmp_send_fds || !my->tmp_recv_fds || !my->tmp_fail_fds ||
!my->fd_to_value || !my->fd_to_sendq) {
!my->fd_to_ssl || !my->fd_to_value || !my->fd_to_sendq) {
sm_private_free(my);
return NULL;
}
Expand Down
Loading