diff options
| -rw-r--r-- | .github/FUNDING.yml | 3 | ||||
| -rw-r--r-- | .github/workflows/build.yml | 20 | ||||
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | configure.ac | 6 | ||||
| -rw-r--r-- | src/client.c | 30 | ||||
| -rw-r--r-- | src/conf.c | 64 | ||||
| -rw-r--r-- | src/conf.h | 1 | ||||
| -rw-r--r-- | src/main.c | 21 | ||||
| -rw-r--r-- | src/usb.c | 49 |
9 files changed, 121 insertions, 79 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..e995b30 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +github: nikias +patreon: nikias +custom: ["https://www.paypal.me/NikiasBassen"] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f8c3f94..1ced463 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,10 @@ name: build -on: [push] +on: + push: + pull_request: + schedule: + - cron: '0 0 1 * *' jobs: build-linux-ubuntu: @@ -14,28 +18,28 @@ jobs: run: | echo "target_triplet=`gcc -dumpmachine`" >> $GITHUB_ENV - name: fetch libplist - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v6 with: github_token: ${{secrets.GITHUB_TOKEN}} workflow: build.yml name: libplist-latest_${{env.target_triplet}} repo: libimobiledevice/libplist - name: fetch libusbmuxd - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v6 with: github_token: ${{secrets.GITHUB_TOKEN}} workflow: build.yml name: libusbmuxd-latest_${{env.target_triplet}} repo: libimobiledevice/libusbmuxd - name: fetch libimobiledevice-glue - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v6 with: github_token: ${{secrets.GITHUB_TOKEN}} workflow: build.yml name: libimobiledevice-glue-latest_${{env.target_triplet}} repo: libimobiledevice/libimobiledevice-glue - name: fetch libimobiledevice - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v6 with: github_token: ${{secrets.GITHUB_TOKEN}} workflow: build.yml @@ -49,7 +53,7 @@ jobs: done sudo cp -r extract/* / sudo ldconfig - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: autogen @@ -65,9 +69,9 @@ jobs: run: | mkdir -p dest DESTDIR=`pwd`/dest make install - tar -C dest -cf usbmuxd.tar usr lib + tar -C dest -cf usbmuxd.tar --strip-components 1 . - name: publish artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: usbmuxd-latest_${{env.target_triplet}} path: usbmuxd.tar @@ -135,8 +135,8 @@ We are still working on the guidelines so bear with us! ## Links * Homepage: https://libimobiledevice.org/ -* Repository: https://git.libimobiledevice.org/usbmuxd.git -* Repository (Mirror): https://github.com/libimobiledevice/usbmuxd.git +* Repository: https://github.com/libimobiledevice/usbmuxd.git +* Repository (Mirror): https://git.libimobiledevice.org/usbmuxd.git * Issue Tracker: https://github.com/libimobiledevice/usbmuxd/issues * Mailing List: https://lists.libimobiledevice.org/mailman/listinfo/libimobiledevice-devel * Twitter: https://twitter.com/libimobiledev @@ -156,4 +156,4 @@ iPadOS, tvOS, watchOS, and macOS are trademarks of Apple Inc. usbmuxd is an independent software application and has not been authorized, sponsored, or otherwise approved by Apple Inc. -README Updated on: 2022-04-04 +README Updated on: 2024-12-02 diff --git a/configure.ac b/configure.ac index c51d53a..3bf88ef 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ LT_INIT # Checks for libraries. PKG_CHECK_MODULES(libusb, libusb-1.0 >= 1.0.9) -PKG_CHECK_MODULES(libplist, libplist-2.0 >= 2.3.0) +PKG_CHECK_MODULES(libplist, libplist-2.0 >= 2.6.0) PKG_CHECK_MODULES(libimobiledevice, libimobiledevice-1.0 >= 1.3.0, have_limd=yes, have_limd=no) PKG_CHECK_MODULES(limd_glue, libimobiledevice-glue-1.0 >= 1.0.0) @@ -40,7 +40,7 @@ if test "x$have_limd" = "xyes"; then AC_SUBST(libimobiledevice_CFLAGS) AC_SUBST(libimobiledevice_LIBS) CACHED_CFLAGS="$CFLAGS" - CFLAGS+=" $libimobiledevice_CFLAGS" + CFLAGS="$CFLAGS $libimobiledevice_CFLAGS" AC_CACHE_CHECK(for enum idevice_connection_type, ac_cv_enum_idevice_connection_type, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #include <libimobiledevice/libimobiledevice.h> @@ -153,7 +153,7 @@ AM_CONDITIONAL(WIN32, test x$win32 = xtrue) AC_SUBST([UDEV_SUB]) AC_SUBST([SYSTEMD_SUB]) -AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-g -Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter") +AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter") AC_SUBST(GLOBAL_CFLAGS) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) diff --git a/src/client.c b/src/client.c index dbbdd5f..2ac04bf 100644 --- a/src/client.c +++ b/src/client.c @@ -452,10 +452,7 @@ static int send_listener_list(struct mux_client *client, uint32_t tag) plist_dict_set_item(l, "Blacklisted", plist_new_bool(0)); n = NULL; if (lc->info) { - n = plist_dict_get_item(lc->info, "BundleID"); - } - if (n) { - plist_dict_set_item(l, "BundleID", plist_copy(n)); + plist_dict_copy_item(l, lc->info, "BundleID", NULL); } plist_dict_set_item(l, "ConnType", plist_new_uint(0)); @@ -632,28 +629,11 @@ static char* plist_dict_get_string_val(plist_t dict, const char* key) static void update_client_info(struct mux_client *client, plist_t dict) { - plist_t node = NULL; plist_t info = plist_new_dict(); - - node = plist_dict_get_item(dict, "BundleID"); - if (node && (plist_get_node_type(node) == PLIST_STRING)) { - plist_dict_set_item(info, "BundleID", plist_copy(node)); - } - - node = plist_dict_get_item(dict, "ClientVersionString"); - if (node && (plist_get_node_type(node) == PLIST_STRING)) { - plist_dict_set_item(info, "ClientVersionString", plist_copy(node)); - } - - node = plist_dict_get_item(dict, "ProgName"); - if (node && (plist_get_node_type(node) == PLIST_STRING)) { - plist_dict_set_item(info, "ProgName", plist_copy(node)); - } - - node = plist_dict_get_item(dict, "kLibUSBMuxVersion"); - if (node && (plist_get_node_type(node) == PLIST_UINT)) { - plist_dict_set_item(info, "kLibUSBMuxVersion", plist_copy(node)); - } + plist_dict_copy_item(info, dict, "BundleID", NULL); + plist_dict_copy_item(info, dict, "ClientVersionString", NULL); + plist_dict_copy_item(info, dict, "ProgName", NULL); + plist_dict_copy_item(info, dict, "kLibUSBMuxVersion", NULL); plist_free(client->info); client->info = info; } @@ -34,10 +34,7 @@ #include <libgen.h> #include <sys/stat.h> #include <errno.h> - -#ifdef WIN32 -#include <shlobj.h> -#endif +#include <ctype.h> #include <libimobiledevice-glue/utils.h> #include <plist/plist.h> @@ -47,6 +44,8 @@ #include "log.h" #ifdef WIN32 +#include <shlobj.h> + #define DIR_SEP '\\' #define DIR_SEP_S "\\" #else @@ -180,13 +179,26 @@ static int mkdir_with_parents(const char *dir, int mode) /** * Creates a freedesktop compatible configuration directory. */ -static void config_create_config_dir(void) +static int config_create_config_dir(void) { const char *config_path = config_get_config_dir(); struct stat st; - if (stat(config_path, &st) != 0) { - mkdir_with_parents(config_path, 0755); + int res = stat(config_path, &st); + if (res != 0) { + res = mkdir_with_parents(config_path, 0755); + } + return res; +} + +int config_set_config_dir(const char* path) +{ + if (!path) { + return -1; } + free(__config_dir); + __config_dir = strdup(path); + usbmuxd_log(LL_DEBUG, "Setting config_dir to %s", __config_dir); + return config_create_config_dir(); } static int get_rand(int min, int max) @@ -270,7 +282,10 @@ static int config_set_value(const char *key, plist_t value) char *config_file = NULL; /* Make sure config directory exists */ - config_create_config_dir(); + if (config_create_config_dir() < 0) { + usbmuxd_log(LL_ERROR, "ERROR: Failed to create config directory\n"); + return -1; + } config_path = config_get_config_dir(); config_file = string_concat(config_path, DIR_SEP_S, CONFIG_FILE, NULL); @@ -342,7 +357,10 @@ int config_has_device_record(const char *udid) if (!udid) return 0; /* ensure config directory exists */ - config_create_config_dir(); + if (config_create_config_dir() < 0) { + usbmuxd_log(LL_ERROR, "ERROR: Failed to create config directory\n"); + return -1; + } /* build file path */ const char *config_path = config_get_config_dir(); @@ -408,13 +426,19 @@ int config_set_device_record(const char *udid, char* record_data, uint64_t recor if (!udid || !record_data || record_size < 8) return -EINVAL; - plist_t plist = NULL; - if (memcmp(record_data, "bplist00", 8) == 0) { - plist_from_bin(record_data, record_size, &plist); - } else { - plist_from_xml(record_data, record_size, &plist); + /* verify udid input */ + const char* u = udid; + while (*u != '\0') { + if (!isalnum(*u) && (*u != '-')) { + usbmuxd_log(LL_ERROR, "ERROR: %s: udid contains invalid character.\n", __func__); + return -EINVAL; + } + u++; } + plist_t plist = NULL; + plist_from_memory(record_data, record_size, &plist, NULL); + if (!plist || plist_get_node_type(plist) != PLIST_DICT) { if (plist) plist_free(plist); @@ -422,7 +446,10 @@ int config_set_device_record(const char *udid, char* record_data, uint64_t recor } /* ensure config directory exists */ - config_create_config_dir(); + if (config_create_config_dir() < 0) { + usbmuxd_log(LL_ERROR, "ERROR: Failed to create config directory\n"); + return -1; + } /* build file path */ const char *config_path = config_get_config_dir(); @@ -431,7 +458,7 @@ int config_set_device_record(const char *udid, char* record_data, uint64_t recor remove(device_record_file); /* store file */ - if (!plist_write_to_file(plist, device_record_file, PLIST_FORMAT_XML, 0)) { + if (plist_write_to_file(plist, device_record_file, PLIST_FORMAT_XML, 0) != PLIST_ERR_SUCCESS) { usbmuxd_log(LL_DEBUG, "Could not open '%s' for writing: %s", device_record_file, strerror(errno)); res = -ENOENT; } @@ -458,7 +485,10 @@ int config_get_device_record(const char *udid, char **record_data, uint64_t *rec int res = 0; /* ensure config directory exists */ - config_create_config_dir(); + if (config_create_config_dir() < 0) { + usbmuxd_log(LL_ERROR, "ERROR: Failed to create config directory\n"); + return -1; + } /* build file path */ const char *config_path = config_get_config_dir(); @@ -27,6 +27,7 @@ #include <plist/plist.h> const char *config_get_config_dir(); +int config_set_config_dir(const char* path); void config_get_system_buid(char **system_buid); @@ -517,6 +517,7 @@ static void usage() #ifdef HAVE_SYSTEMD printf(" -s, --systemd\t\tRun in systemd operation mode (implies -z and -f).\n"); #endif + printf(" -C, --config-dir PATH\tSpecify different configuration directory.\n"); printf(" -S, --socket ADDR:PORT | PATH Specify source ADDR and PORT or a UNIX\n"); printf(" \t\tsocket PATH to use for the listening socket.\n"); printf(" \t\tDefault: %s\n", socket_path); @@ -549,6 +550,7 @@ static void parse_opts(int argc, char **argv) #ifdef HAVE_SYSTEMD {"systemd", no_argument, NULL, 's'}, #endif + {"config-dir", required_argument, NULL, 'C'}, {"socket", required_argument, NULL, 'S'}, {"pidfile", required_argument, NULL, 'P'}, {"exit", no_argument, NULL, 'x'}, @@ -560,11 +562,11 @@ static void parse_opts(int argc, char **argv) int c; #ifdef HAVE_SYSTEMD - const char* opts_spec = "hfvVuU:xXsnzl:pS:P:"; + const char* opts_spec = "hfvVuU:xXsnzl:pC:S:P:"; #elif HAVE_UDEV - const char* opts_spec = "hfvVuU:xXnzl:pS:P:"; + const char* opts_spec = "hfvVuU:xXnzl:pC:S:P:"; #else - const char* opts_spec = "hfvVU:xXnzl:pS:P:"; + const char* opts_spec = "hfvVU:xXnzl:pC:S:P:"; #endif while (1) { @@ -584,7 +586,7 @@ static void parse_opts(int argc, char **argv) ++verbose; break; case 'V': - printf("%s\n", PACKAGE_STRING); + printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION); exit(0); case 'U': drop_privileges = 1; @@ -611,6 +613,14 @@ static void parse_opts(int argc, char **argv) case 'z': opt_enable_exit = 1; break; + case 'C': + if (!*optarg) { + usbmuxd_log(LL_FATAL, "ERROR: --config-dir requires an argument"); + usage(); + exit(2); + } + config_set_config_dir(optarg); + break; case 'S': if (!*optarg || *optarg == '-') { usbmuxd_log(LL_FATAL, "ERROR: --socket requires an argument"); @@ -796,11 +806,12 @@ int main(int argc, char *argv[]) #ifdef HAVE_LIBIMOBILEDEVICE const char* userprefdir = config_get_config_dir(); + usbmuxd_log(LL_NOTICE, "Configuration directory: %s", userprefdir); struct stat fst; memset(&fst, '\0', sizeof(struct stat)); if (stat(userprefdir, &fst) < 0) { if (mkdir(userprefdir, 0775) < 0) { - usbmuxd_log(LL_FATAL, "Failed to create required directory '%s': %s", userprefdir, strerror(errno)); + usbmuxd_log(LL_FATAL, "Failed to create configuration directory '%s': %s", userprefdir, strerror(errno)); res = -1; goto terminate; } @@ -53,7 +53,7 @@ #define NUM_RX_LOOPS 3 struct usb_device { - libusb_device_handle *dev; + libusb_device_handle *handle; uint8_t bus, address; char serial[256]; int alive; @@ -83,7 +83,7 @@ static int device_hotplug = 1; static void usb_disconnect(struct usb_device *dev) { - if(!dev->dev) { + if(!dev->handle) { return; } @@ -114,9 +114,9 @@ static void usb_disconnect(struct usb_device *dev) collection_free(&dev->tx_xfers); collection_free(&dev->rx_xfers); - libusb_release_interface(dev->dev, dev->interface); - libusb_close(dev->dev); - dev->dev = NULL; + libusb_release_interface(dev->handle, dev->interface); + libusb_close(dev->handle); + dev->handle = NULL; collection_remove(&device_list, dev); free(dev); } @@ -177,7 +177,7 @@ int usb_send(struct usb_device *dev, const unsigned char *buf, int length) { int res; struct libusb_transfer *xfer = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(xfer, dev->dev, dev->ep_out, (void*)buf, length, tx_callback, dev, 0); + libusb_fill_bulk_transfer(xfer, dev->handle, dev->ep_out, (void*)buf, length, tx_callback, dev, 0); if((res = libusb_submit_transfer(xfer)) < 0) { usbmuxd_log(LL_ERROR, "Failed to submit TX transfer %p len %d to device %d-%d: %s", buf, length, dev->bus, dev->address, libusb_error_name(res)); libusb_free_transfer(xfer); @@ -189,7 +189,7 @@ int usb_send(struct usb_device *dev, const unsigned char *buf, int length) // Send Zero Length Packet xfer = libusb_alloc_transfer(0); void *buffer = malloc(1); - libusb_fill_bulk_transfer(xfer, dev->dev, dev->ep_out, buffer, 0, tx_callback, dev, 0); + libusb_fill_bulk_transfer(xfer, dev->handle, dev->ep_out, buffer, 0, tx_callback, dev, 0); if((res = libusb_submit_transfer(xfer)) < 0) { usbmuxd_log(LL_ERROR, "Failed to submit TX ZLP transfer to device %d-%d: %s", dev->bus, dev->address, libusb_error_name(res)); libusb_free_transfer(xfer); @@ -256,7 +256,7 @@ static int start_rx_loop(struct usb_device *dev) void *buf; struct libusb_transfer *xfer = libusb_alloc_transfer(0); buf = malloc(USB_MRU); - libusb_fill_bulk_transfer(xfer, dev->dev, dev->ep_in, buf, USB_MRU, rx_callback, dev, 0); + libusb_fill_bulk_transfer(xfer, dev->handle, dev->ep_in, buf, USB_MRU, rx_callback, dev, 0); if((res = libusb_submit_transfer(xfer)) != 0) { usbmuxd_log(LL_ERROR, "Failed to submit RX transfer to device %d-%d: %s", dev->bus, dev->address, libusb_error_name(res)); libusb_free_transfer(xfer); @@ -357,7 +357,7 @@ static void get_langid_callback(struct libusb_transfer *transfer) libusb_fill_control_setup(transfer->buffer, LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t)((LIBUSB_DT_STRING << 8) | usbdev->devdesc.iSerialNumber), langid, 1024 + LIBUSB_CONTROL_SETUP_SIZE); - libusb_fill_control_transfer(transfer, usbdev->dev, transfer->buffer, get_serial_callback, usbdev, 1000); + libusb_fill_control_transfer(transfer, usbdev->handle, transfer->buffer, get_serial_callback, usbdev, 1000); if((res = libusb_submit_transfer(transfer)) < 0) { usbmuxd_log(LL_ERROR, "Could not request transfer for device %d-%d: %s", usbdev->bus, usbdev->address, libusb_error_name(res)); @@ -394,7 +394,7 @@ static struct usb_device* find_device(int bus, int address) /// @param dev /// @param usbdev /// @param handle -/// @return 0 - undetermined, 1 - initial, 2 - valeria, 3 - cdc_ncm +/// @return 0 - undetermined, 1 - initial, 2 - valeria, 3 - cdc_ncm, 4 - usbeth+cdc_ncm, 5 - cdc_ncm direct static int guess_mode(struct libusb_device* dev, struct usb_device *usbdev) { int res, j; @@ -404,11 +404,21 @@ static int guess_mode(struct libusb_device* dev, struct usb_device *usbdev) int bus = usbdev->bus; int address = usbdev->address; + if(devdesc.bNumConfigurations == 1) { + // CDC-NCM Direct + return 5; + } + if(devdesc.bNumConfigurations <= 4) { // Assume this is initial mode return 1; } + if(devdesc.bNumConfigurations == 6) { + // USB Ethernet + CDC-NCM + return 4; + } + if(devdesc.bNumConfigurations != 5) { // No known modes with more then 5 configurations return 0; @@ -595,7 +605,7 @@ static void device_complete_initialization(struct mode_context *context, struct usbdev->address = address; usbdev->devdesc = devdesc; usbdev->speed = 480000000; - usbdev->dev = handle; + usbdev->handle = handle; usbdev->alive = 1; usbdev->wMaxPacketSize = libusb_get_max_packet_size(dev, usbdev->ep_out); if (usbdev->wMaxPacketSize <= 0) { @@ -615,6 +625,9 @@ static void device_complete_initialization(struct mode_context *context, struct case LIBUSB_SPEED_SUPER: usbdev->speed = 5000000000; break; + case LIBUSB_SPEED_SUPER_PLUS: + usbdev->speed = 10000000000; + break; case LIBUSB_SPEED_HIGH: case LIBUSB_SPEED_UNKNOWN: default: @@ -691,12 +704,12 @@ static void get_mode_cb(struct libusb_transfer* transfer) unsigned char *data = libusb_control_transfer_get_data(transfer); char* desired_mode_char = getenv(ENV_DEVICE_MODE); - int desired_mode = desired_mode_char ? atoi(desired_mode_char) : 3; + int desired_mode = desired_mode_char ? atoi(desired_mode_char) : 1; int guessed_mode = guess_mode(context->dev, dev); // Response is 3:3:3:0 for initial mode, 5:3:3:0 otherwise. usbmuxd_log(LL_INFO, "Received response %i:%i:%i:%i for get_mode request for device %i-%i", data[0], data[1], data[2], data[3], context->bus, context->address); - if(desired_mode >= 1 && desired_mode <= 3 && + if(desired_mode >= 1 && desired_mode <= 5 && guessed_mode > 0 && // do not switch mode if guess failed guessed_mode != desired_mode) { usbmuxd_log(LL_WARNING, "Switching device %i-%i mode to %i", context->bus, context->address, desired_mode); @@ -764,7 +777,7 @@ static int usb_device_add(libusb_device* dev) usbdev->address = address; usbdev->devdesc = devdesc; usbdev->speed = 0; - usbdev->dev = handle; + usbdev->handle = handle; usbdev->alive = 1; collection_init(&usbdev->tx_xfers); @@ -854,7 +867,7 @@ int usb_discover(void) const char *usb_get_serial(struct usb_device *dev) { - if(!dev->dev) { + if(!dev->handle) { return NULL; } return dev->serial; @@ -862,7 +875,7 @@ const char *usb_get_serial(struct usb_device *dev) uint32_t usb_get_location(struct usb_device *dev) { - if(!dev->dev) { + if(!dev->handle) { return 0; } return (dev->bus << 16) | dev->address; @@ -870,7 +883,7 @@ uint32_t usb_get_location(struct usb_device *dev) uint16_t usb_get_pid(struct usb_device *dev) { - if(!dev->dev) { + if(!dev->handle) { return 0; } return dev->devdesc.idProduct; @@ -878,7 +891,7 @@ uint16_t usb_get_pid(struct usb_device *dev) uint64_t usb_get_speed(struct usb_device *dev) { - if (!dev->dev) { + if (!dev->handle) { return 0; } return dev->speed; |
