diff options
| -rw-r--r-- | configure.ac | 30 | ||||
| -rw-r--r-- | src/Makefile.am | 5 | ||||
| -rw-r--r-- | src/client.c | 1 | ||||
| -rw-r--r-- | src/device.c | 19 | ||||
| -rw-r--r-- | src/device.h | 2 | ||||
| -rw-r--r-- | src/main.c | 20 | ||||
| -rw-r--r-- | src/preflight.c | 271 | ||||
| -rw-r--r-- | src/preflight.h | 28 |
8 files changed, 365 insertions, 11 deletions
diff --git a/configure.ac b/configure.ac index a874692..b7aa54b 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -18,6 +18,8 @@ AC_PROG_LIBTOOL | |||
| 18 | # Checks for libraries. | 18 | # Checks for libraries. |
| 19 | PKG_CHECK_MODULES(libusb, libusb-1.0 >= 1.0.3) | 19 | PKG_CHECK_MODULES(libusb, libusb-1.0 >= 1.0.3) |
| 20 | PKG_CHECK_MODULES(libplist, libplist >= 1.9, have_plist=yes, have_plist=no) | 20 | PKG_CHECK_MODULES(libplist, libplist >= 1.9, have_plist=yes, have_plist=no) |
| 21 | PKG_CHECK_MODULES(libimobiledevice, libimobiledevice-1.0 >= 1.1.6, have_limd=yes, have_limd=no) | ||
| 22 | AC_CHECK_LIB(pthread, [pthread_create, pthread_mutex_lock], [AC_SUBST(libpthread_LIBS,[-lpthread])], [AC_MSG_ERROR([libpthread is required to build usbmuxd])]) | ||
| 21 | 23 | ||
| 22 | AC_ARG_WITH([protov1], | 24 | AC_ARG_WITH([protov1], |
| 23 | [AS_HELP_STRING([--without-protov1], | 25 | [AS_HELP_STRING([--without-protov1], |
| @@ -40,6 +42,27 @@ else | |||
| 40 | fi | 42 | fi |
| 41 | fi | 43 | fi |
| 42 | 44 | ||
| 45 | AC_ARG_WITH([preflight], | ||
| 46 | [AS_HELP_STRING([--without-preflight], | ||
| 47 | [do not build with preflight worker support (default is yes)])], | ||
| 48 | [with_preflight=no], | ||
| 49 | [with_preflight=yes]) | ||
| 50 | |||
| 51 | if test "x$have_limd" = "xyes"; then | ||
| 52 | if test "x$with_preflight" != "xyes"; then | ||
| 53 | have_limd=no | ||
| 54 | echo "*** Note: preflight worker support has been disabled ***" | ||
| 55 | else | ||
| 56 | AC_DEFINE(HAVE_LIBIMOBILEDEVICE, 1, [Define if you have libimobiledevice support]) | ||
| 57 | AC_SUBST(libimobiledevice_CFLAGS) | ||
| 58 | AC_SUBST(libimobiledevice_LIBS) | ||
| 59 | fi | ||
| 60 | else | ||
| 61 | if test "x$with_preflight" == "xyes"; then | ||
| 62 | AC_MSG_ERROR([preflight worker support requested but libimobiledevice could not befound]) | ||
| 63 | fi | ||
| 64 | fi | ||
| 65 | |||
| 43 | # Checks for header files. | 66 | # Checks for header files. |
| 44 | AC_HEADER_STDC | 67 | AC_HEADER_STDC |
| 45 | AC_CHECK_HEADERS([stdint.h stdlib.h string.h]) | 68 | AC_CHECK_HEADERS([stdint.h stdlib.h string.h]) |
| @@ -73,7 +96,7 @@ case ${host_os} in | |||
| 73 | esac | 96 | esac |
| 74 | AM_CONDITIONAL(WIN32, test x$win32 = xtrue) | 97 | AM_CONDITIONAL(WIN32, test x$win32 = xtrue) |
| 75 | 98 | ||
| 76 | AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter") | 99 | AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-g -Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter") |
| 77 | AC_SUBST(GLOBAL_CFLAGS) | 100 | AC_SUBST(GLOBAL_CFLAGS) |
| 78 | 101 | ||
| 79 | m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) | 102 | m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) |
| @@ -88,8 +111,9 @@ echo " | |||
| 88 | Configuration for $PACKAGE $VERSION: | 111 | Configuration for $PACKAGE $VERSION: |
| 89 | ------------------------------------------- | 112 | ------------------------------------------- |
| 90 | 113 | ||
| 91 | Install prefix: .........: $prefix | 114 | Install prefix: ...........: $prefix |
| 92 | Protocol v1 support: ....: $have_plist | 115 | Protocol v1 support: ......: $have_plist |
| 116 | Preflight worker support ..: $have_limd | ||
| 93 | 117 | ||
| 94 | Now type 'make' to build $PACKAGE $VERSION, | 118 | Now type 'make' to build $PACKAGE $VERSION, |
| 95 | and then 'make install' for installation. | 119 | and then 'make install' for installation. |
diff --git a/src/Makefile.am b/src/Makefile.am index ae8fee7..883f1d8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | AM_CFLAGS = $(GLOBAL_CFLAGS) -I$(top_srcdir)/src $(libplist_CFLAGS) $(libusb_CFLAGS) | 1 | AM_CFLAGS = $(GLOBAL_CFLAGS) -I$(top_srcdir)/src $(libplist_CFLAGS) $(libusb_CFLAGS) $(libimobildevice_CFLAGS) |
| 2 | AM_LDFLAGS = $(libplist_LIBS) $(libusb_LIBS) | 2 | AM_LDFLAGS = $(libplist_LIBS) $(libusb_LIBS) $(libimobiledevice_LIBS) $(libpthread_LIBS) |
| 3 | 3 | ||
| 4 | sbin_PROGRAMS = usbmuxd | 4 | sbin_PROGRAMS = usbmuxd |
| 5 | 5 | ||
| 6 | usbmuxd_SOURCES = client.c client.h \ | 6 | usbmuxd_SOURCES = client.c client.h \ |
| 7 | device.c device.h \ | 7 | device.c device.h \ |
| 8 | preflight.c preflight.h \ | ||
| 8 | log.c log.h \ | 9 | log.c log.h \ |
| 9 | usb-linux.c usb.h \ | 10 | usb-linux.c usb.h \ |
| 10 | utils.c utils.h \ | 11 | utils.c utils.h \ |
diff --git a/src/client.c b/src/client.c index d4a4a10..b2e3644 100644 --- a/src/client.c +++ b/src/client.c | |||
| @@ -584,6 +584,7 @@ void client_process(int fd, short events) | |||
| 584 | void client_device_add(struct device_info *dev) | 584 | void client_device_add(struct device_info *dev) |
| 585 | { | 585 | { |
| 586 | usbmuxd_log(LL_DEBUG, "client_device_add: id %d, location 0x%x, serial %s", dev->id, dev->location, dev->serial); | 586 | usbmuxd_log(LL_DEBUG, "client_device_add: id %d, location 0x%x, serial %s", dev->id, dev->location, dev->serial); |
| 587 | device_set_visible(dev->id); | ||
| 587 | FOREACH(struct mux_client *client, &client_list) { | 588 | FOREACH(struct mux_client *client, &client_list) { |
| 588 | if(client->state == CLIENT_LISTEN) | 589 | if(client->state == CLIENT_LISTEN) |
| 589 | notify_device_add(client, dev); | 590 | notify_device_add(client, dev); |
diff --git a/src/device.c b/src/device.c index 91712be..27e25d5 100644 --- a/src/device.c +++ b/src/device.c | |||
| @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| 33 | #include <inttypes.h> | 33 | #include <inttypes.h> |
| 34 | #include "device.h" | 34 | #include "device.h" |
| 35 | #include "client.h" | 35 | #include "client.h" |
| 36 | #include "preflight.h" | ||
| 36 | #include "usb.h" | 37 | #include "usb.h" |
| 37 | #include "log.h" | 38 | #include "log.h" |
| 38 | 39 | ||
| @@ -106,6 +107,7 @@ struct mux_device | |||
| 106 | struct usb_device *usbdev; | 107 | struct usb_device *usbdev; |
| 107 | int id; | 108 | int id; |
| 108 | enum mux_dev_state state; | 109 | enum mux_dev_state state; |
| 110 | int visible; | ||
| 109 | struct collection connections; | 111 | struct collection connections; |
| 110 | uint16_t next_sport; | 112 | uint16_t next_sport; |
| 111 | unsigned char *pktbuf; | 113 | unsigned char *pktbuf; |
| @@ -461,7 +463,7 @@ static void device_version_input(struct mux_device *dev, struct version_header * | |||
| 461 | info.location = usb_get_location(dev->usbdev); | 463 | info.location = usb_get_location(dev->usbdev); |
| 462 | info.serial = usb_get_serial(dev->usbdev); | 464 | info.serial = usb_get_serial(dev->usbdev); |
| 463 | info.pid = usb_get_pid(dev->usbdev); | 465 | info.pid = usb_get_pid(dev->usbdev); |
| 464 | client_device_add(&info); | 466 | preflight_worker_device_add(&info); |
| 465 | } | 467 | } |
| 466 | 468 | ||
| 467 | static void device_tcp_input(struct mux_device *dev, struct tcphdr *th, unsigned char *payload, uint32_t payload_length) | 469 | static void device_tcp_input(struct mux_device *dev, struct tcphdr *th, unsigned char *payload, uint32_t payload_length) |
| @@ -642,6 +644,7 @@ int device_add(struct usb_device *usbdev) | |||
| 642 | dev->id = id; | 644 | dev->id = id; |
| 643 | dev->usbdev = usbdev; | 645 | dev->usbdev = usbdev; |
| 644 | dev->state = MUXDEV_INIT; | 646 | dev->state = MUXDEV_INIT; |
| 647 | dev->visible = 0; | ||
| 645 | dev->next_sport = 1; | 648 | dev->next_sport = 1; |
| 646 | dev->pktbuf = malloc(DEV_MRU); | 649 | dev->pktbuf = malloc(DEV_MRU); |
| 647 | dev->pktlen = 0; | 650 | dev->pktlen = 0; |
| @@ -680,11 +683,21 @@ void device_remove(struct usb_device *usbdev) | |||
| 680 | usbmuxd_log(LL_WARNING, "Cannot find device entry while removing USB device %p on location 0x%x", usbdev, usb_get_location(usbdev)); | 683 | usbmuxd_log(LL_WARNING, "Cannot find device entry while removing USB device %p on location 0x%x", usbdev, usb_get_location(usbdev)); |
| 681 | } | 684 | } |
| 682 | 685 | ||
| 686 | void device_set_visible(int device_id) | ||
| 687 | { | ||
| 688 | FOREACH(struct mux_device *dev, &device_list) { | ||
| 689 | if(dev->id == device_id) { | ||
| 690 | dev->visible = 1; | ||
| 691 | break; | ||
| 692 | } | ||
| 693 | } ENDFOREACH | ||
| 694 | } | ||
| 695 | |||
| 683 | int device_get_count(void) | 696 | int device_get_count(void) |
| 684 | { | 697 | { |
| 685 | int count = 0; | 698 | int count = 0; |
| 686 | FOREACH(struct mux_device *dev, &device_list) { | 699 | FOREACH(struct mux_device *dev, &device_list) { |
| 687 | if(dev->state == MUXDEV_ACTIVE) | 700 | if((dev->state == MUXDEV_ACTIVE) && dev->visible) |
| 688 | count++; | 701 | count++; |
| 689 | } ENDFOREACH | 702 | } ENDFOREACH |
| 690 | return count; | 703 | return count; |
| @@ -694,7 +707,7 @@ int device_get_list(struct device_info *p) | |||
| 694 | { | 707 | { |
| 695 | int count = 0; | 708 | int count = 0; |
| 696 | FOREACH(struct mux_device *dev, &device_list) { | 709 | FOREACH(struct mux_device *dev, &device_list) { |
| 697 | if(dev->state == MUXDEV_ACTIVE) { | 710 | if((dev->state == MUXDEV_ACTIVE) && dev->visible) { |
| 698 | p->id = dev->id; | 711 | p->id = dev->id; |
| 699 | p->serial = usb_get_serial(dev->usbdev); | 712 | p->serial = usb_get_serial(dev->usbdev); |
| 700 | p->location = usb_get_location(dev->usbdev); | 713 | p->location = usb_get_location(dev->usbdev); |
diff --git a/src/device.h b/src/device.h index ea77069..4b1a581 100644 --- a/src/device.h +++ b/src/device.h | |||
| @@ -40,6 +40,8 @@ int device_start_connect(int device_id, uint16_t port, struct mux_client *client | |||
| 40 | void device_client_process(int device_id, struct mux_client *client, short events); | 40 | void device_client_process(int device_id, struct mux_client *client, short events); |
| 41 | void device_abort_connect(int device_id, struct mux_client *client); | 41 | void device_abort_connect(int device_id, struct mux_client *client); |
| 42 | 42 | ||
| 43 | void device_set_visible(int device_id); | ||
| 44 | |||
| 43 | int device_get_count(void); | 45 | int device_get_count(void); |
| 44 | int device_get_list(struct device_info *p); | 46 | int device_get_list(struct device_info *p); |
| 45 | 47 | ||
| @@ -49,6 +49,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| 49 | 49 | ||
| 50 | static const char *socket_path = "/var/run/usbmuxd"; | 50 | static const char *socket_path = "/var/run/usbmuxd"; |
| 51 | static const char *lockfile = "/var/run/usbmuxd.pid"; | 51 | static const char *lockfile = "/var/run/usbmuxd.pid"; |
| 52 | static const char *userprefdir = "/var/lib/lockdown"; | ||
| 52 | 53 | ||
| 53 | int should_exit; | 54 | int should_exit; |
| 54 | int should_discover; | 55 | int should_discover; |
| @@ -285,9 +286,6 @@ static int daemonize(void) | |||
| 285 | close(pfd[0]); | 286 | close(pfd[0]); |
| 286 | report_to_parent = 1; | 287 | report_to_parent = 1; |
| 287 | 288 | ||
| 288 | // Change the file mode mask | ||
| 289 | umask(0); | ||
| 290 | |||
| 291 | // Create a new SID for the child process | 289 | // Create a new SID for the child process |
| 292 | sid = setsid(); | 290 | sid = setsid(); |
| 293 | if (sid < 0) { | 291 | if (sid < 0) { |
| @@ -531,6 +529,13 @@ int main(int argc, char *argv[]) | |||
| 531 | if(listenfd < 0) | 529 | if(listenfd < 0) |
| 532 | goto terminate; | 530 | goto terminate; |
| 533 | 531 | ||
| 532 | struct stat fst; | ||
| 533 | int userprefdir_created = 0; | ||
| 534 | if (stat(userprefdir, &fst) < 0) { | ||
| 535 | mkdir(userprefdir, 0775); | ||
| 536 | userprefdir_created = 1; | ||
| 537 | } | ||
| 538 | |||
| 534 | // drop elevated privileges | 539 | // drop elevated privileges |
| 535 | if (drop_privileges && (getuid() == 0 || geteuid() == 0)) { | 540 | if (drop_privileges && (getuid() == 0 || geteuid() == 0)) { |
| 536 | struct passwd *pw; | 541 | struct passwd *pw; |
| @@ -548,6 +553,15 @@ int main(int argc, char *argv[]) | |||
| 548 | if (pw->pw_uid == 0) { | 553 | if (pw->pw_uid == 0) { |
| 549 | usbmuxd_log(LL_INFO, "Not dropping privileges to root"); | 554 | usbmuxd_log(LL_INFO, "Not dropping privileges to root"); |
| 550 | } else { | 555 | } else { |
| 556 | if (userprefdir_created) { | ||
| 557 | if (chown(userprefdir, pw->pw_uid, pw->pw_gid) < 0) { | ||
| 558 | usbmuxd_log(LL_WARNING, "chown(%s, %d, %d) failed", userprefdir, pw->pw_uid, pw->pw_gid); | ||
| 559 | } | ||
| 560 | if (chmod(userprefdir, 02775) < 0) { | ||
| 561 | usbmuxd_log(LL_WARNING, "chmod %s failed", userprefdir); | ||
| 562 | } | ||
| 563 | } | ||
| 564 | |||
| 551 | if ((res = initgroups(drop_user, pw->pw_gid)) < 0) { | 565 | if ((res = initgroups(drop_user, pw->pw_gid)) < 0) { |
| 552 | usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set supplementary groups)"); | 566 | usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set supplementary groups)"); |
| 553 | goto terminate; | 567 | goto terminate; |
diff --git a/src/preflight.c b/src/preflight.c new file mode 100644 index 0000000..0041b21 --- /dev/null +++ b/src/preflight.c | |||
| @@ -0,0 +1,271 @@ | |||
| 1 | /* | ||
| 2 | usbmuxd - iPhone/iPod Touch USB multiplex server daemon | ||
| 3 | |||
| 4 | Copyright (C) 2013 Nikias Bassen <nikias@gmx.li> | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation, either version 2 or version 3. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the Free Software | ||
| 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | |||
| 19 | */ | ||
| 20 | |||
| 21 | #ifdef HAVE_CONFIG_H | ||
| 22 | #include <config.h> | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #include <stdlib.h> | ||
| 26 | #include <string.h> | ||
| 27 | #include <unistd.h> | ||
| 28 | |||
| 29 | #include <pthread.h> | ||
| 30 | |||
| 31 | #include <sys/time.h> | ||
| 32 | |||
| 33 | #include <libimobiledevice/libimobiledevice.h> | ||
| 34 | #include <libimobiledevice/lockdown.h> | ||
| 35 | #include <libimobiledevice/notification_proxy.h> | ||
| 36 | |||
| 37 | #include "preflight.h" | ||
| 38 | #include "client.h" | ||
| 39 | #include "log.h" | ||
| 40 | |||
| 41 | #ifdef HAVE_LIBIMOBILEDEVICE | ||
| 42 | enum connection_type { | ||
| 43 | CONNECTION_USBMUXD = 1 | ||
| 44 | }; | ||
| 45 | |||
| 46 | struct idevice_private { | ||
| 47 | char *udid; | ||
| 48 | enum connection_type conn_type; | ||
| 49 | void *conn_data; | ||
| 50 | }; | ||
| 51 | |||
| 52 | extern void userpref_get_system_buid(char **systembuid); | ||
| 53 | |||
| 54 | struct np_cb_data { | ||
| 55 | idevice_t dev; | ||
| 56 | np_client_t np; | ||
| 57 | }; | ||
| 58 | |||
| 59 | static void set_untrusted_host_buid(lockdownd_client_t lockdown) | ||
| 60 | { | ||
| 61 | char* system_buid = NULL; | ||
| 62 | userpref_get_system_buid(&system_buid); | ||
| 63 | usbmuxd_log(LL_DEBUG, "%s: Setting UntrustedHostBUID to %s", __func__, system_buid); | ||
| 64 | lockdownd_set_value(lockdown, NULL, "UntrustedHostBUID", plist_new_string(system_buid)); | ||
| 65 | free(system_buid); | ||
| 66 | } | ||
| 67 | |||
| 68 | static void np_callback(const char* notification, void* userdata) | ||
| 69 | { | ||
| 70 | struct np_cb_data *cbdata = (struct np_cb_data*)userdata; | ||
| 71 | idevice_t dev = cbdata->dev; | ||
| 72 | struct idevice_private *_dev = (struct idevice_private*)dev; | ||
| 73 | |||
| 74 | lockdownd_client_t lockdown = NULL; | ||
| 75 | lockdownd_error_t lerr; | ||
| 76 | |||
| 77 | if (strlen(notification) == 0) { | ||
| 78 | cbdata->np = NULL; | ||
| 79 | return; | ||
| 80 | } | ||
| 81 | |||
| 82 | if (strcmp(notification, "com.apple.mobile.lockdown.request_pair") == 0) { | ||
| 83 | usbmuxd_log(LL_INFO, "%s: user trusted this computer on device %s, pairing now", __func__, _dev->udid); | ||
| 84 | lerr = lockdownd_client_new(dev, &lockdown, "usbmuxd"); | ||
| 85 | if (lerr != LOCKDOWN_E_SUCCESS) { | ||
| 86 | usbmuxd_log(LL_ERROR, "%s: ERROR: Could not connect to lockdownd on device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | |||
| 90 | lerr = lockdownd_pair(lockdown, NULL); | ||
| 91 | if (lerr != LOCKDOWN_E_SUCCESS) { | ||
| 92 | usbmuxd_log(LL_ERROR, "%s: ERROR: Pair failed for device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 93 | lockdownd_client_free(lockdown); | ||
| 94 | return; | ||
| 95 | } | ||
| 96 | lockdownd_client_free(lockdown); | ||
| 97 | // device will reconnect by itself at this point. | ||
| 98 | |||
| 99 | } else if (strcmp(notification, "com.apple.mobile.lockdown.request_host_buid") == 0) { | ||
| 100 | lerr = lockdownd_client_new(cbdata->dev, &lockdown, "usbmuxd"); | ||
| 101 | if (lerr != LOCKDOWN_E_SUCCESS) { | ||
| 102 | usbmuxd_log(LL_ERROR, "%s: ERROR: Could not connect to lockdownd on device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 103 | } else { | ||
| 104 | set_untrusted_host_buid(lockdown); | ||
| 105 | lockdownd_client_free(lockdown); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | static void* preflight_worker_handle_device_add(void* userdata) | ||
| 111 | { | ||
| 112 | struct device_info *info = (struct device_info*)userdata; | ||
| 113 | struct idevice_private *_dev = (struct idevice_private*)malloc(sizeof(struct idevice_private)); | ||
| 114 | _dev->udid = strdup(info->serial); | ||
| 115 | _dev->conn_type = CONNECTION_USBMUXD; | ||
| 116 | _dev->conn_data = (void*)(long)info->id; | ||
| 117 | |||
| 118 | idevice_t dev = (idevice_t)_dev; | ||
| 119 | |||
| 120 | lockdownd_client_t lockdown; | ||
| 121 | lockdownd_error_t lerr; | ||
| 122 | |||
| 123 | lerr = lockdownd_client_new(dev, &lockdown, "usbmuxd"); | ||
| 124 | if (lerr != LOCKDOWN_E_SUCCESS) { | ||
| 125 | usbmuxd_log(LL_ERROR, "%s: ERROR: Could not connect to lockdownd on device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 126 | goto leave; | ||
| 127 | } | ||
| 128 | |||
| 129 | char *type = NULL; | ||
| 130 | lerr = lockdownd_query_type(lockdown, &type); | ||
| 131 | if (!type) { | ||
| 132 | usbmuxd_log(LL_ERROR, "%s: ERROR: Could not get lockdownd type from device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 133 | goto leave; | ||
| 134 | } | ||
| 135 | |||
| 136 | if (strcmp(type, "com.apple.mobile.lockdown") != 0) { | ||
| 137 | // make restore mode devices visible | ||
| 138 | client_device_add(info); | ||
| 139 | goto leave; | ||
| 140 | } | ||
| 141 | |||
| 142 | char *host_id = NULL; | ||
| 143 | userpref_device_record_get_host_id(dev->udid, &host_id); | ||
| 144 | lerr = lockdownd_start_session(lockdown, host_id, NULL, NULL); | ||
| 145 | free(host_id); | ||
| 146 | if (lerr == LOCKDOWN_E_SUCCESS) { | ||
| 147 | usbmuxd_log(LL_INFO, "%s: StartSession success for device %s", __func__, _dev->udid); | ||
| 148 | client_device_add(info); | ||
| 149 | goto leave; | ||
| 150 | } | ||
| 151 | |||
| 152 | usbmuxd_log(LL_INFO, "%s: StartSession failed on device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 153 | if (lerr == LOCKDOWN_E_INVALID_HOST_ID) { | ||
| 154 | usbmuxd_log(LL_INFO, "%s: Device %s is not paired with this host.", __func__, _dev->udid); | ||
| 155 | } | ||
| 156 | |||
| 157 | plist_t value = NULL; | ||
| 158 | lerr = lockdownd_get_value(lockdown, NULL, "ProductVersion", &value); | ||
| 159 | if (lerr != LOCKDOWN_E_SUCCESS) { | ||
| 160 | usbmuxd_log(LL_ERROR, "%s: ERROR: Could not get ProductVersion from device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 161 | goto leave; | ||
| 162 | } | ||
| 163 | |||
| 164 | char* version_str = NULL; | ||
| 165 | plist_get_string_val(value, &version_str); | ||
| 166 | if (!version_str) { | ||
| 167 | usbmuxd_log(LL_ERROR, "%s: Could not get ProductVersion string from device %s handle %d", __func__, _dev->udid, (int)(long)_dev->conn_data); | ||
| 168 | goto leave; | ||
| 169 | } | ||
| 170 | |||
| 171 | int version_major = strtol(version_str, NULL, 10); | ||
| 172 | if (version_major >= 7) { | ||
| 173 | // ============== iOS 7.0 and beyond ============= | ||
| 174 | usbmuxd_log(LL_INFO, "%s: Found ProductVersion %s device %s", __func__, version_str, _dev->udid); | ||
| 175 | |||
| 176 | set_untrusted_host_buid(lockdown); | ||
| 177 | |||
| 178 | lockdownd_service_descriptor_t service = NULL; | ||
| 179 | lerr = lockdownd_start_service(lockdown, "com.apple.mobile.insecure_notification_proxy", &service); | ||
| 180 | if (lerr != LOCKDOWN_E_SUCCESS) { | ||
| 181 | usbmuxd_log(LL_ERROR, "%s: ERROR: Could not start insecure_notification_proxy on %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 182 | goto leave; | ||
| 183 | } | ||
| 184 | |||
| 185 | np_client_t np = NULL; | ||
| 186 | np_client_new(dev, service, &np); | ||
| 187 | |||
| 188 | lockdownd_service_descriptor_free(service); | ||
| 189 | service = NULL; | ||
| 190 | |||
| 191 | lockdownd_client_free(lockdown); | ||
| 192 | lockdown = NULL; | ||
| 193 | |||
| 194 | struct np_cb_data cbdata; | ||
| 195 | cbdata.dev = dev; | ||
| 196 | cbdata.np = np; | ||
| 197 | |||
| 198 | np_set_notify_callback(np, np_callback, (void*)&cbdata); | ||
| 199 | |||
| 200 | const char* spec[] = { | ||
| 201 | "com.apple.mobile.lockdown.request_pair", | ||
| 202 | "com.apple.mobile.lockdown.request_host_buid", | ||
| 203 | NULL | ||
| 204 | }; | ||
| 205 | np_observe_notifications(np, spec); | ||
| 206 | |||
| 207 | usbmuxd_log(LL_INFO, "%s: Waiting for user to trust this computer on device %s", __func__, _dev->udid); | ||
| 208 | // TODO send notification to user's desktop | ||
| 209 | while (cbdata.np) { | ||
| 210 | sleep(1); | ||
| 211 | } | ||
| 212 | |||
| 213 | if (cbdata.np) { | ||
| 214 | np_client_free(cbdata.np); | ||
| 215 | } | ||
| 216 | } else { | ||
| 217 | // ============== iOS 6.x and below ============== | ||
| 218 | lerr = lockdownd_pair(lockdown, NULL); | ||
| 219 | if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) { | ||
| 220 | usbmuxd_log(LL_INFO, "%s: Device %s is locked with a passcode. Cannot pair.", __func__, _dev->udid); | ||
| 221 | // TODO send notification to user's desktop | ||
| 222 | goto leave; | ||
| 223 | } else if (lerr != LOCKDOWN_E_SUCCESS) { | ||
| 224 | usbmuxd_log(LL_ERROR, "%s: ERROR: Pair failed for device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 225 | goto leave; | ||
| 226 | } | ||
| 227 | |||
| 228 | host_id = NULL; | ||
| 229 | userpref_device_record_get_host_id(dev->udid, &host_id); | ||
| 230 | lerr = lockdownd_start_session(lockdown, host_id, NULL, NULL); | ||
| 231 | free(host_id); | ||
| 232 | if (lerr != LOCKDOWN_E_SUCCESS) { | ||
| 233 | usbmuxd_log(LL_ERROR, "%s: ERROR StartSession failed on device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 234 | goto leave; | ||
| 235 | } | ||
| 236 | |||
| 237 | lerr = lockdownd_validate_pair(lockdown, NULL); | ||
| 238 | if (lerr != LOCKDOWN_E_SUCCESS) { | ||
| 239 | usbmuxd_log(LL_ERROR, "%s: ERROR: ValidatePair failed for device %s, lockdown error %d", __func__, _dev->udid, lerr); | ||
| 240 | goto leave; | ||
| 241 | } | ||
| 242 | |||
| 243 | // make device visible | ||
| 244 | client_device_add(info); | ||
| 245 | } | ||
| 246 | |||
| 247 | leave: | ||
| 248 | if (lockdown) | ||
| 249 | lockdownd_client_free(lockdown); | ||
| 250 | if (dev) | ||
| 251 | idevice_free(dev); | ||
| 252 | |||
| 253 | free(info); | ||
| 254 | |||
| 255 | return NULL; | ||
| 256 | } | ||
| 257 | #endif | ||
| 258 | |||
| 259 | void preflight_worker_device_add(struct device_info* info) | ||
| 260 | { | ||
| 261 | #ifdef HAVE_LIBIMOBILEDEVICE | ||
| 262 | struct device_info *infocopy = (struct device_info*)malloc(sizeof(struct device_info)); | ||
| 263 | |||
| 264 | memcpy(infocopy, info, sizeof(struct device_info)); | ||
| 265 | |||
| 266 | pthread_t th; | ||
| 267 | pthread_create(&th, NULL, preflight_worker_handle_device_add, infocopy); | ||
| 268 | #else | ||
| 269 | client_device_add(info); | ||
| 270 | #endif | ||
| 271 | } | ||
diff --git a/src/preflight.h b/src/preflight.h new file mode 100644 index 0000000..dce3356 --- /dev/null +++ b/src/preflight.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | usbmuxd - iPhone/iPod Touch USB multiplex server daemon | ||
| 3 | |||
| 4 | Copyright (C) 2013 Nikias Bassen <nikias@gmx.li> | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation, either version 2 or version 3. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the Free Software | ||
| 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | |||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __PREFLIGHT_H__ | ||
| 22 | #define __PREFLIGHT_H__ | ||
| 23 | |||
| 24 | #include "device.h" | ||
| 25 | |||
| 26 | void preflight_worker_device_add(struct device_info* info); | ||
| 27 | |||
| 28 | #endif | ||
