From c57ebf917e30afd78dac8042552966811531c632 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Tue, 28 Jul 2009 14:59:07 +0200 Subject: Fix potential memory corruption in calls to gnutls function on 64 bit arch [#60 state:resolved] Signed-off-by: Matt Colyer --- src/lockdown.c | 8 +++++--- src/userpref.c | 32 ++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/lockdown.c b/src/lockdown.c index bc430c9..88ab7b0 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -954,10 +954,12 @@ lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datu if (LOCKDOWN_E_SUCCESS == ret) { /* if everything went well, export in PEM format */ + size_t export_size = 0; gnutls_datum_t dev_pem = { NULL, 0 }; - gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &dev_pem.size); - dev_pem.data = gnutls_malloc(dev_pem.size); - gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &dev_pem.size); + gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &export_size); + dev_pem.data = gnutls_malloc(export_size); + gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &export_size); + dev_pem.size = export_size; gnutls_datum_t pem_root_cert = { NULL, 0 }; gnutls_datum_t pem_host_cert = { NULL, 0 }; diff --git a/src/userpref.c b/src/userpref.c index 4b6dd98..b930693 100644 --- a/src/userpref.c +++ b/src/userpref.c @@ -289,29 +289,37 @@ static userpref_error_t userpref_gen_keys_and_cert(void) gnutls_x509_crt_sign(host_cert, root_cert, root_privkey); /* export to PEM format */ + size_t root_key_export_size = 0; + size_t host_key_export_size = 0; gnutls_datum_t root_key_pem = { NULL, 0 }; gnutls_datum_t host_key_pem = { NULL, 0 }; - gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, NULL, &root_key_pem.size); - gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, NULL, &host_key_pem.size); + gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, NULL, &root_key_export_size); + gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, NULL, &host_key_export_size); - root_key_pem.data = gnutls_malloc(root_key_pem.size); - host_key_pem.data = gnutls_malloc(host_key_pem.size); + root_key_pem.data = gnutls_malloc(root_key_export_size); + host_key_pem.data = gnutls_malloc(host_key_export_size); - gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, root_key_pem.data, &root_key_pem.size); - gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, host_key_pem.data, &host_key_pem.size); + gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, root_key_pem.data, &root_key_export_size); + root_key_pem.size = root_key_export_size; + gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, host_key_pem.data, &host_key_export_size); + host_key_pem.size = host_key_export_size; + size_t root_cert_export_size = 0; + size_t host_cert_export_size = 0; gnutls_datum_t root_cert_pem = { NULL, 0 }; gnutls_datum_t host_cert_pem = { NULL, 0 }; - gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, NULL, &root_cert_pem.size); - gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, NULL, &host_cert_pem.size); + gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, NULL, &root_cert_export_size); + gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, NULL, &host_cert_export_size); - root_cert_pem.data = gnutls_malloc(root_cert_pem.size); - host_cert_pem.data = gnutls_malloc(host_cert_pem.size); + root_cert_pem.data = gnutls_malloc(root_cert_export_size); + host_cert_pem.data = gnutls_malloc(host_cert_export_size); - gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, root_cert_pem.data, &root_cert_pem.size); - gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, host_cert_pem.data, &host_cert_pem.size); + gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, root_cert_pem.data, &root_cert_export_size); + root_cert_pem.size = root_cert_export_size; + gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, host_cert_pem.data, &host_cert_export_size); + host_cert_pem.size = host_cert_export_size; if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && NULL != host_cert_pem.data && 0 != host_cert_pem.size) -- cgit v1.1-32-gdbae From d089bc54e88d7fa70be9f0c228403c6d02248b52 Mon Sep 17 00:00:00 2001 From: Martin Szulecki Date: Tue, 28 Jul 2009 10:58:50 +0200 Subject: Move production ready tools into tools/ and do not install the dev/ ones --- Makefile.am | 2 +- autogen.sh | 2 +- configure.ac | 2 +- dev/Makefile.am | 19 +--- dev/iphone_id.c | 94 ----------------- dev/iphoneclient.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++ dev/iphoneinfo.c | 281 --------------------------------------------------- dev/main.c | 255 ---------------------------------------------- dev/syslog_relay.c | 169 ------------------------------- tools/Makefile.am | 21 ++++ tools/iphone_id.c | 94 +++++++++++++++++ tools/iphoneinfo.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/iphonesyslog.c | 169 +++++++++++++++++++++++++++++++ 13 files changed, 825 insertions(+), 819 deletions(-) delete mode 100644 dev/iphone_id.c create mode 100644 dev/iphoneclient.c delete mode 100644 dev/iphoneinfo.c delete mode 100644 dev/main.c delete mode 100644 dev/syslog_relay.c create mode 100644 tools/Makefile.am create mode 100644 tools/iphone_id.c create mode 100644 tools/iphoneinfo.c create mode 100644 tools/iphonesyslog.c diff --git a/Makefile.am b/Makefile.am index 6761838..bf4205d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src include fdi swig $(DEV_SUB) +SUBDIRS = src include fdi swig $(DEV_SUB) tools DISTCHECK_CONFIGURE_FLAGS = --enable-dev-tools diff --git a/autogen.sh b/autogen.sh index 460bc5e..cb3887a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -6,5 +6,5 @@ automake --add-missing autoconf if [ -z "$NOCONFIGURE" ]; then - ./configure --enable-dev-tools "$@" + ./configure "$@" fi diff --git a/configure.ac b/configure.ac index 2acc6be..d6b27f4 100644 --- a/configure.ac +++ b/configure.ac @@ -100,4 +100,4 @@ if test "$enable_largefile" != no; then fi AC_SUBST(LFS_CFLAGS) -AC_OUTPUT(Makefile src/Makefile include/Makefile fdi/Makefile dev/Makefile swig/Makefile libiphone-1.0.pc) +AC_OUTPUT(Makefile src/Makefile include/Makefile fdi/Makefile dev/Makefile tools/Makefile swig/Makefile libiphone-1.0.pc) diff --git a/dev/Makefile.am b/dev/Makefile.am index 9e06339..70cd52b 100644 --- a/dev/Makefile.am +++ b/dev/Makefile.am @@ -3,9 +3,9 @@ INCLUDES = -I$(top_srcdir)/include AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) -bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient iphoneinfo iphonesyslog iphone_id +noinst_PROGRAMS = iphoneclient lckd-client afccheck msyncclient -iphoneclient_SOURCES = main.c +iphoneclient_SOURCES = iphoneclient.c iphoneclient_LDADD = ../src/libiphone.la lckd_client_SOURCES = lckdclient.c @@ -22,18 +22,3 @@ msyncclient_SOURCES = msyncclient.c msyncclient_CFLAGS = $(AM_CFLAGS) msyncclient_LDFLAGS = $(AM_LDFLAGS) msyncclient_LDADD = ../src/libiphone.la - -iphoneinfo_SOURCES = iphoneinfo.c -iphoneinfo_CFLAGS = $(AM_CFLAGS) -iphoneinfo_LDFLAGS = $(AM_LDFLAGS) -iphoneinfo_LDADD = ../src/libiphone.la - -iphonesyslog_SOURCES = syslog_relay.c -iphonesyslog_CFLAGS = $(AM_CFLAGS) -iphonesyslog_LDFLAGS = $(AM_LDFLAGS) -iphonesyslog_LDADD = ../src/libiphone.la - -iphone_id_SOURCES = iphone_id.c -iphone_id_CFLAGS = $(AM_CFLAGS) -iphone_id_LDFLAGS = $(AM_LDFLAGS) -iphone_id_LDADD = ../src/libiphone.la diff --git a/dev/iphone_id.c b/dev/iphone_id.c deleted file mode 100644 index f68fc8b..0000000 --- a/dev/iphone_id.c +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static void usage() -{ - printf("usage: iphone_id \n" - "\tdevice_uuid is the 40-digit hexadecimal UUID of the device\n" - "\tfor which the name should be retrieved.\n\n" - "usage: iphone_id -l\n" - "\tList all attached devices.\n"); - exit(0); -} - -int main(int argc, char **argv) -{ - iphone_device_t phone = NULL; - lockdownd_client_t client = NULL; - usbmuxd_scan_result *dev_list; - char *devname = NULL; - int ret = 0; - int c; - int i; - int opt_list = 0; - - while ((c = getopt(argc, argv, "lh")) != -1) { - switch (c) { - case 'l': - opt_list = 1; - break; - case 'h': - default: - usage(); - } - } - - if (argc < 2) { - usage(); - } - - argc -= optind; - argv += optind; - - if ((!opt_list) && (strlen(argv[0]) != 40)) { - usage(); - } - - if (opt_list) { - if (usbmuxd_scan(&dev_list) < 0) { - fprintf(stderr, "ERROR: usbmuxd is not running!\n"); - return -1; - } - for (i = 0; dev_list[i].handle > 0; i++) { - printf("handle=%d product_id=%04x uuid=%s\n", dev_list[i].handle, dev_list[i].product_id, dev_list[i].serial_number); - } - return 0; - } - - iphone_set_debug_level(0); - - iphone_get_device_by_uuid(&phone, argv[0]); - if (!phone) { - fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", argv[0]); - return -2; - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { - iphone_device_free(phone); - fprintf(stderr, "ERROR: Connecting to device failed!\n"); - return -2; - } - - if ((LOCKDOWN_E_SUCCESS != lockdownd_get_device_name(client, &devname)) || !devname) { - fprintf(stderr, "ERROR: Could not get device name!\n"); - ret = -2; - } - - lockdownd_client_free(client); - iphone_device_free(phone); - - if (ret == 0) { - printf("%s\n", devname); - } - - if (devname) { - free(devname); - } - - return ret; -} diff --git a/dev/iphoneclient.c b/dev/iphoneclient.c new file mode 100644 index 0000000..bb5dfdd --- /dev/null +++ b/dev/iphoneclient.c @@ -0,0 +1,255 @@ +/* + * main.c + * Rudimentary interface to the iPhone + * + * Copyright (c) 2008 Zach C. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "../src/utils.h" + +static void notifier(const char *notification) +{ + printf("---------------------------------------------------------\n"); + printf("------> Notification received: %s\n", notification); + printf("---------------------------------------------------------\n"); +} + +static void perform_notification(iphone_device_t phone, lockdownd_client_t client, const char *notification) +{ + int nport = 0; + np_client_t np; + + lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &nport); + if (nport) { + printf("::::::::::::::: np was started ::::::::::::\n"); + np_client_new(phone, nport, &np); + if (np) { + printf("::::::::: PostNotification %s\n", notification); + np_post_notification(np, notification); + np_client_free(np); + } + } else { + printf("::::::::::::::: np was NOT started ::::::::::::\n"); + } +} + +int main(int argc, char *argv[]) +{ + unsigned int bytes = 0; + int port = 0, i = 0; + int npp; + lockdownd_client_t client = NULL; + iphone_device_t phone = NULL; + uint64_t lockfile = 0; + np_client_t gnp = NULL; + + if (argc > 1 && !strcasecmp(argv[1], "--debug")) { + iphone_set_debug_level(1); + iphone_set_debug_mask(DBGMASK_ALL); + } else { + iphone_set_debug_level(0); + iphone_set_debug_mask(DBGMASK_NONE); + } + + if (IPHONE_E_SUCCESS != iphone_get_device(&phone)) { + printf("No iPhone found, is it plugged in?\n"); + return -1; + } + + char *uuid = NULL; + if (IPHONE_E_SUCCESS == iphone_device_get_uuid(phone, &uuid)) { + printf("DeviceUniqueID : %s\n", uuid); + } + if (uuid) + free(uuid); + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { + iphone_device_free(phone); + printf("Exiting.\n"); + return -1; + } + + char *nnn = NULL; + if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_name(client, &nnn)) { + printf("DeviceName : %s\n", nnn); + free(nnn); + } + + lockdownd_start_service(client, "com.apple.afc", &port); + + if (port) { + afc_client_t afc = NULL; + afc_client_new(phone, port, &afc); + if (afc) { + lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &npp); + if (npp) { + printf("Notification Proxy started.\n"); + np_client_new(phone, npp, &gnp); + } else { + printf("ERROR: Notification proxy could not be started.\n"); + } + if (gnp) { + const char *nspec[5] = { + NP_SYNC_CANCEL_REQUEST, + NP_SYNC_SUSPEND_REQUEST, + NP_SYNC_RESUME_REQUEST, + NP_ITDBPREP_DID_END, + NULL + }; + np_observe_notifications(gnp, nspec); + np_set_notify_callback(gnp, notifier); + } + + perform_notification(phone, client, NP_SYNC_WILL_START); + + afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile); + if (lockfile) { + printf("locking file\n"); + afc_file_lock(afc, lockfile, AFC_LOCK_EX); + + perform_notification(phone, client, NP_SYNC_DID_START); + } + + char **dirs = NULL; + afc_read_directory(afc, "/eafaedf", &dirs); + if (!dirs) + afc_read_directory(afc, "/", &dirs); + printf("Directory time.\n"); + for (i = 0; dirs[i]; i++) { + printf("/%s\n", dirs[i]); + } + + g_strfreev(dirs); + + dirs = NULL; + afc_get_device_info(afc, &dirs); + if (dirs) { + for (i = 0; dirs[i]; i += 2) { + printf("%s: %s\n", dirs[i], dirs[i + 1]); + } + } + g_strfreev(dirs); + + uint64_t my_file = 0; + char **info = NULL; + uint64_t fsize = 0; + if (AFC_E_SUCCESS == afc_get_file_info(afc, "/readme.libiphone.fx", &info) && info) { + for (i = 0; info[i]; i += 2) { + printf("%s: %s\n", info[i], info[i+1]); + if (!strcmp(info[i], "st_size")) { + fsize = atoll(info[i+1]); + } + } + } + + if (AFC_E_SUCCESS == + afc_file_open(afc, "/readme.libiphone.fx", AFC_FOPEN_RDONLY, &my_file) && my_file) { + printf("A file size: %llu\n", (long long)fsize); + char *file_data = (char *) malloc(sizeof(char) * fsize); + afc_file_read(afc, my_file, file_data, fsize, &bytes); + if (bytes > 0) { + printf("The file's data:\n"); + fwrite(file_data, 1, bytes, stdout); + } + printf("\nClosing my file.\n"); + afc_file_close(afc, my_file); + free(file_data); + } else + printf("couldn't open a file\n"); + + afc_file_open(afc, "/readme.libiphone.fx", AFC_FOPEN_WR, &my_file); + if (my_file) { + char *outdatafile = strdup("this is a bitchin text file\n"); + afc_file_write(afc, my_file, outdatafile, strlen(outdatafile), &bytes); + free(outdatafile); + if (bytes > 0) + printf("Wrote a surprise. ;)\n"); + else + printf("I wanted to write a surprise, but... :(\n"); + afc_file_close(afc, my_file); + } + printf("Deleting a file...\n"); + bytes = afc_remove_path(afc, "/delme"); + if (bytes) + printf("Success.\n"); + else + printf("Failure. (expected unless you have a /delme file on your phone)\n"); + + printf("Renaming a file...\n"); + bytes = afc_rename_path(afc, "/renme", "/renme2"); + if (bytes > 0) + printf("Success.\n"); + else + printf("Failure. (expected unless you have a /renme file on your phone)\n"); + + printf("Seek & read\n"); + afc_file_open(afc, "/readme.libiphone.fx", AFC_FOPEN_RDONLY, &my_file); + if (AFC_E_SUCCESS != afc_file_seek(afc, my_file, 5, SEEK_CUR)) + printf("WARN: SEEK DID NOT WORK\n"); + char *threeletterword = (char *) malloc(sizeof(char) * 5); + afc_file_read(afc, my_file, threeletterword, 3, &bytes); + threeletterword[3] = '\0'; + if (bytes > 0) + printf("Result: %s\n", threeletterword); + else + printf("Couldn't read!\n"); + free(threeletterword); + afc_file_close(afc, my_file); + } + + if (gnp && lockfile) { + printf("XXX sleeping\n"); + sleep(5); + + printf("XXX unlocking file\n"); + afc_file_lock(afc, lockfile, AFC_LOCK_UN); + + printf("XXX closing file\n"); + afc_file_close(afc, lockfile); + + printf("XXX sleeping\n"); + sleep(5); + //perform_notification(phone, client, NP_SYNC_DID_FINISH); + } + + if (gnp) { + np_client_free(gnp); + gnp = NULL; + } + + afc_client_free(afc); + } else { + printf("Start service failure.\n"); + } + + printf("All done.\n"); + + lockdownd_client_free(client); + iphone_device_free(phone); + + return 0; +} diff --git a/dev/iphoneinfo.c b/dev/iphoneinfo.c deleted file mode 100644 index 7e275b2..0000000 --- a/dev/iphoneinfo.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * iphoneinfo.c - * Simple utility to show information about an attached device - * - * Copyright (c) 2009 Martin Szulecki All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -#include -#include - -#define FORMAT_KEY_VALUE 1 -#define FORMAT_XML 2 - -static const char *domains[] = { - "com.apple.disk_usage", - "com.apple.mobile.battery", -/* FIXME: For some reason lockdownd segfaults on this, works sometimes though - "com.apple.mobile.debug",. */ - "com.apple.xcode.developerdomain", - "com.apple.international", - "com.apple.mobile.mobile_application_usage", - "com.apple.mobile.backup", - "com.apple.mobile.user_preferences", - "com.apple.mobile.sync_data_class", - "com.apple.mobile.software_behavior", - "com.apple.mobile.iTunes.SQLMusicLibraryPostProcessCommands", - "com.apple.iTunes", - "com.apple.mobile.iTunes.store", - "com.apple.mobile.iTunes", - NULL -}; - -int is_domain_known(char *domain); -void print_usage(int argc, char **argv); -void plist_node_to_string(plist_t *node); -void plist_children_to_string(plist_t *node); - -int main(int argc, char *argv[]) -{ - lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; - iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; - int i; - int format = FORMAT_KEY_VALUE; - char uuid[41]; - char *domain = NULL; - char *key = NULL; - char *xml_doc = NULL; - uint32_t xml_length; - plist_t node = NULL; - uuid[0] = 0; - - /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { - iphone_set_debug_mask(DBGMASK_ALL); - iphone_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { - i++; - if (!argv[i] || (strlen(argv[i]) != 40)) { - print_usage(argc, argv); - return 0; - } - strcpy(uuid, argv[i]); - continue; - } - else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--domain")) { - i++; - if (!argv[i] || (strlen(argv[i]) < 4)) { - print_usage(argc, argv); - return 0; - } - if (!is_domain_known(argv[i])) { - fprintf(stderr, "WARNING: Sending query with unknown domain \"%s\".\n", argv[i]); - } - domain = strdup(argv[i]); - continue; - } - else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--key")) { - i++; - if (!argv[i] || (strlen(argv[i]) <= 1)) { - print_usage(argc, argv); - return 0; - } - key = strdup(argv[i]); - continue; - } - else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) { - format = FORMAT_XML; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return 0; - } - else { - print_usage(argc, argv); - return 0; - } - } - - if (uuid[0] != 0) { - ret = iphone_get_device_by_uuid(&phone, uuid); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found with uuid %s, is it plugged in?\n", uuid); - return -1; - } - } - else - { - ret = iphone_get_device(&phone); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found, is it plugged in?\n"); - return -1; - } - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { - iphone_device_free(phone); - return -1; - } - - /* run query and output information */ - if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS) - { - if (plist_get_node_type(node) == PLIST_DICT) { - if (plist_get_first_child(node)) - { - switch (format) { - case FORMAT_XML: - plist_to_xml(node, &xml_doc, &xml_length); - printf(xml_doc); - free(xml_doc); - break; - case FORMAT_KEY_VALUE: - default: - plist_children_to_string(node); - break; - } - } - } - else if(node && (key != NULL)) - plist_node_to_string(node); - if (node) - plist_free(node); - node = NULL; - } - - if (domain != NULL) - free(domain); - lockdownd_client_free(client); - iphone_device_free(phone); - - return 0; -} - -int is_domain_known(char *domain) -{ - int i = 0; - while (domains[i] != NULL) { - if (strstr(domain, domains[i++])) { - return 1; - } - } - return 0; -} - -void print_usage(int argc, char **argv) -{ - int i = 0; - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); - printf("Show information about the first connected iPhone/iPod Touch.\n\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); - printf(" -q, --domain NAME\tset domain of query to NAME. Default: None\n"); - printf(" -k, --key NAME\tonly query key specified by NAME. Default: All keys.\n"); - printf(" -x, --xml\t\toutput information as xml plist instead of key/value pairs\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf("\n"); - printf(" Known domains are:\n\n"); - while (domains[i] != NULL) { - printf(" %s\n", domains[i++]); - } - printf("\n"); -} - -void plist_node_to_string(plist_t *node) -{ - char *s = NULL; - double d; - uint8_t b; - - uint64_t u = 0; - - plist_type t; - - if (!node) - return; - - t = plist_get_node_type(node); - - switch (t) { - case PLIST_BOOLEAN: - plist_get_bool_val(node, &b); - printf("%s\n", (b ? "true" : "false")); - break; - - case PLIST_UINT: - plist_get_uint_val(node, &u); - printf("%llu\n", (long long)u); - break; - - case PLIST_REAL: - plist_get_real_val(node, &d); - printf("%f\n", d); - break; - - case PLIST_STRING: - plist_get_string_val(node, &s); - printf("%s\n", s); - free(s); - break; - - case PLIST_KEY: - plist_get_key_val(node, &s); - printf("%s: ", s); - free(s); - break; - - case PLIST_DATA: - printf("\n"); - break; - case PLIST_DATE: - printf("\n"); - break; - case PLIST_ARRAY: - case PLIST_DICT: - printf("\n"); - plist_children_to_string(node); - break; - default: - break; - } -} - -void plist_children_to_string(plist_t *node) -{ - /* iterate over key/value pairs */ - for ( - node = plist_get_first_child(node); - node != NULL; - node = plist_get_next_sibling(node) - ) { - plist_node_to_string(node); - } -} - diff --git a/dev/main.c b/dev/main.c deleted file mode 100644 index bb5dfdd..0000000 --- a/dev/main.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * main.c - * Rudimentary interface to the iPhone - * - * Copyright (c) 2008 Zach C. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "../src/utils.h" - -static void notifier(const char *notification) -{ - printf("---------------------------------------------------------\n"); - printf("------> Notification received: %s\n", notification); - printf("---------------------------------------------------------\n"); -} - -static void perform_notification(iphone_device_t phone, lockdownd_client_t client, const char *notification) -{ - int nport = 0; - np_client_t np; - - lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &nport); - if (nport) { - printf("::::::::::::::: np was started ::::::::::::\n"); - np_client_new(phone, nport, &np); - if (np) { - printf("::::::::: PostNotification %s\n", notification); - np_post_notification(np, notification); - np_client_free(np); - } - } else { - printf("::::::::::::::: np was NOT started ::::::::::::\n"); - } -} - -int main(int argc, char *argv[]) -{ - unsigned int bytes = 0; - int port = 0, i = 0; - int npp; - lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; - uint64_t lockfile = 0; - np_client_t gnp = NULL; - - if (argc > 1 && !strcasecmp(argv[1], "--debug")) { - iphone_set_debug_level(1); - iphone_set_debug_mask(DBGMASK_ALL); - } else { - iphone_set_debug_level(0); - iphone_set_debug_mask(DBGMASK_NONE); - } - - if (IPHONE_E_SUCCESS != iphone_get_device(&phone)) { - printf("No iPhone found, is it plugged in?\n"); - return -1; - } - - char *uuid = NULL; - if (IPHONE_E_SUCCESS == iphone_device_get_uuid(phone, &uuid)) { - printf("DeviceUniqueID : %s\n", uuid); - } - if (uuid) - free(uuid); - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { - iphone_device_free(phone); - printf("Exiting.\n"); - return -1; - } - - char *nnn = NULL; - if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_name(client, &nnn)) { - printf("DeviceName : %s\n", nnn); - free(nnn); - } - - lockdownd_start_service(client, "com.apple.afc", &port); - - if (port) { - afc_client_t afc = NULL; - afc_client_new(phone, port, &afc); - if (afc) { - lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &npp); - if (npp) { - printf("Notification Proxy started.\n"); - np_client_new(phone, npp, &gnp); - } else { - printf("ERROR: Notification proxy could not be started.\n"); - } - if (gnp) { - const char *nspec[5] = { - NP_SYNC_CANCEL_REQUEST, - NP_SYNC_SUSPEND_REQUEST, - NP_SYNC_RESUME_REQUEST, - NP_ITDBPREP_DID_END, - NULL - }; - np_observe_notifications(gnp, nspec); - np_set_notify_callback(gnp, notifier); - } - - perform_notification(phone, client, NP_SYNC_WILL_START); - - afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile); - if (lockfile) { - printf("locking file\n"); - afc_file_lock(afc, lockfile, AFC_LOCK_EX); - - perform_notification(phone, client, NP_SYNC_DID_START); - } - - char **dirs = NULL; - afc_read_directory(afc, "/eafaedf", &dirs); - if (!dirs) - afc_read_directory(afc, "/", &dirs); - printf("Directory time.\n"); - for (i = 0; dirs[i]; i++) { - printf("/%s\n", dirs[i]); - } - - g_strfreev(dirs); - - dirs = NULL; - afc_get_device_info(afc, &dirs); - if (dirs) { - for (i = 0; dirs[i]; i += 2) { - printf("%s: %s\n", dirs[i], dirs[i + 1]); - } - } - g_strfreev(dirs); - - uint64_t my_file = 0; - char **info = NULL; - uint64_t fsize = 0; - if (AFC_E_SUCCESS == afc_get_file_info(afc, "/readme.libiphone.fx", &info) && info) { - for (i = 0; info[i]; i += 2) { - printf("%s: %s\n", info[i], info[i+1]); - if (!strcmp(info[i], "st_size")) { - fsize = atoll(info[i+1]); - } - } - } - - if (AFC_E_SUCCESS == - afc_file_open(afc, "/readme.libiphone.fx", AFC_FOPEN_RDONLY, &my_file) && my_file) { - printf("A file size: %llu\n", (long long)fsize); - char *file_data = (char *) malloc(sizeof(char) * fsize); - afc_file_read(afc, my_file, file_data, fsize, &bytes); - if (bytes > 0) { - printf("The file's data:\n"); - fwrite(file_data, 1, bytes, stdout); - } - printf("\nClosing my file.\n"); - afc_file_close(afc, my_file); - free(file_data); - } else - printf("couldn't open a file\n"); - - afc_file_open(afc, "/readme.libiphone.fx", AFC_FOPEN_WR, &my_file); - if (my_file) { - char *outdatafile = strdup("this is a bitchin text file\n"); - afc_file_write(afc, my_file, outdatafile, strlen(outdatafile), &bytes); - free(outdatafile); - if (bytes > 0) - printf("Wrote a surprise. ;)\n"); - else - printf("I wanted to write a surprise, but... :(\n"); - afc_file_close(afc, my_file); - } - printf("Deleting a file...\n"); - bytes = afc_remove_path(afc, "/delme"); - if (bytes) - printf("Success.\n"); - else - printf("Failure. (expected unless you have a /delme file on your phone)\n"); - - printf("Renaming a file...\n"); - bytes = afc_rename_path(afc, "/renme", "/renme2"); - if (bytes > 0) - printf("Success.\n"); - else - printf("Failure. (expected unless you have a /renme file on your phone)\n"); - - printf("Seek & read\n"); - afc_file_open(afc, "/readme.libiphone.fx", AFC_FOPEN_RDONLY, &my_file); - if (AFC_E_SUCCESS != afc_file_seek(afc, my_file, 5, SEEK_CUR)) - printf("WARN: SEEK DID NOT WORK\n"); - char *threeletterword = (char *) malloc(sizeof(char) * 5); - afc_file_read(afc, my_file, threeletterword, 3, &bytes); - threeletterword[3] = '\0'; - if (bytes > 0) - printf("Result: %s\n", threeletterword); - else - printf("Couldn't read!\n"); - free(threeletterword); - afc_file_close(afc, my_file); - } - - if (gnp && lockfile) { - printf("XXX sleeping\n"); - sleep(5); - - printf("XXX unlocking file\n"); - afc_file_lock(afc, lockfile, AFC_LOCK_UN); - - printf("XXX closing file\n"); - afc_file_close(afc, lockfile); - - printf("XXX sleeping\n"); - sleep(5); - //perform_notification(phone, client, NP_SYNC_DID_FINISH); - } - - if (gnp) { - np_client_free(gnp); - gnp = NULL; - } - - afc_client_free(afc); - } else { - printf("Start service failure.\n"); - } - - printf("All done.\n"); - - lockdownd_client_free(client); - iphone_device_free(phone); - - return 0; -} diff --git a/dev/syslog_relay.c b/dev/syslog_relay.c deleted file mode 100644 index a096101..0000000 --- a/dev/syslog_relay.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * syslog_relay.c - * Relay the syslog of a device to stdout - * - * Copyright (c) 2009 Martin Szulecki All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static int quit_flag = 0; - -void print_usage(int argc, char **argv); - -/** - * signal handler function for cleaning up properly - */ -static void clean_exit(int sig) -{ - fprintf(stderr, "Exiting...\n"); - quit_flag++; -} - -int main(int argc, char *argv[]) -{ - lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; - iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; - int i; - char uuid[41]; - int port = 0; - uuid[0] = 0; - uint32_t handle = 0; - - signal(SIGINT, clean_exit); - signal(SIGQUIT, clean_exit); - signal(SIGTERM, clean_exit); - signal(SIGPIPE, SIG_IGN); - - /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { - iphone_set_debug_mask(DBGMASK_ALL); - iphone_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { - i++; - if (!argv[i] || (strlen(argv[i]) != 40)) { - print_usage(argc, argv); - return 0; - } - strcpy(uuid, argv[i]); - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return 0; - } - else { - print_usage(argc, argv); - return 0; - } - } - - if (uuid[0] != 0) { - ret = iphone_get_device_by_uuid(&phone, uuid); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found with uuid %s, is it plugged in?\n", uuid); - return -1; - } - } - else - { - ret = iphone_get_device(&phone); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found, is it plugged in?\n"); - return -1; - } - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { - iphone_device_free(phone); - return -1; - } - - /* start syslog_relay service and retrieve port */ - ret = lockdownd_start_service(client, "com.apple.syslog_relay", &port); - if ((ret == LOCKDOWN_E_SUCCESS) && port) { - lockdownd_client_free(client); - - /* connect to socket relay messages */ - iphone_device_get_handle(phone, &handle); - int sfd = usbmuxd_connect(handle, port); - if (sfd < 0) { - printf("ERROR: Could not open usbmux connection.\n"); - } else { - while (!quit_flag) { - char *receive = NULL; - uint32_t datalen = 0, bytes = 0, recv_bytes = 0; - - ret = usbmuxd_recv(sfd, (char *) &datalen, sizeof(datalen), &bytes); - datalen = ntohl(datalen); - - if (datalen == 0) - continue; - - recv_bytes += bytes; - receive = (char *) malloc(sizeof(char) * datalen); - - while (!quit_flag && (recv_bytes <= datalen)) { - ret = usbmuxd_recv(sfd, receive, datalen, &bytes); - - if (bytes == 0) - break; - - recv_bytes += bytes; - - fwrite(receive, sizeof(char), bytes, stdout); - } - - free(receive); - } - } - usbmuxd_disconnect(sfd); - } else { - printf("ERROR: Could not start service com.apple.syslog_relay.\n"); - } - - iphone_device_free(phone); - - return 0; -} - -void print_usage(int argc, char **argv) -{ - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); - printf("Relay syslog of a connected iPhone/iPod Touch.\n\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf("\n"); -} - diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..7f1be1c --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,21 @@ +INCLUDES = -I$(top_srcdir)/include + +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) +AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) + +bin_PROGRAMS = iphone_id iphoneinfo iphonesyslog + +iphoneinfo_SOURCES = iphoneinfo.c +iphoneinfo_CFLAGS = $(AM_CFLAGS) +iphoneinfo_LDFLAGS = $(AM_LDFLAGS) +iphoneinfo_LDADD = ../src/libiphone.la + +iphonesyslog_SOURCES = iphonesyslog.c +iphonesyslog_CFLAGS = $(AM_CFLAGS) +iphonesyslog_LDFLAGS = $(AM_LDFLAGS) +iphonesyslog_LDADD = ../src/libiphone.la + +iphone_id_SOURCES = iphone_id.c +iphone_id_CFLAGS = $(AM_CFLAGS) +iphone_id_LDFLAGS = $(AM_LDFLAGS) +iphone_id_LDADD = ../src/libiphone.la diff --git a/tools/iphone_id.c b/tools/iphone_id.c new file mode 100644 index 0000000..f68fc8b --- /dev/null +++ b/tools/iphone_id.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include +#include + +static void usage() +{ + printf("usage: iphone_id \n" + "\tdevice_uuid is the 40-digit hexadecimal UUID of the device\n" + "\tfor which the name should be retrieved.\n\n" + "usage: iphone_id -l\n" + "\tList all attached devices.\n"); + exit(0); +} + +int main(int argc, char **argv) +{ + iphone_device_t phone = NULL; + lockdownd_client_t client = NULL; + usbmuxd_scan_result *dev_list; + char *devname = NULL; + int ret = 0; + int c; + int i; + int opt_list = 0; + + while ((c = getopt(argc, argv, "lh")) != -1) { + switch (c) { + case 'l': + opt_list = 1; + break; + case 'h': + default: + usage(); + } + } + + if (argc < 2) { + usage(); + } + + argc -= optind; + argv += optind; + + if ((!opt_list) && (strlen(argv[0]) != 40)) { + usage(); + } + + if (opt_list) { + if (usbmuxd_scan(&dev_list) < 0) { + fprintf(stderr, "ERROR: usbmuxd is not running!\n"); + return -1; + } + for (i = 0; dev_list[i].handle > 0; i++) { + printf("handle=%d product_id=%04x uuid=%s\n", dev_list[i].handle, dev_list[i].product_id, dev_list[i].serial_number); + } + return 0; + } + + iphone_set_debug_level(0); + + iphone_get_device_by_uuid(&phone, argv[0]); + if (!phone) { + fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", argv[0]); + return -2; + } + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { + iphone_device_free(phone); + fprintf(stderr, "ERROR: Connecting to device failed!\n"); + return -2; + } + + if ((LOCKDOWN_E_SUCCESS != lockdownd_get_device_name(client, &devname)) || !devname) { + fprintf(stderr, "ERROR: Could not get device name!\n"); + ret = -2; + } + + lockdownd_client_free(client); + iphone_device_free(phone); + + if (ret == 0) { + printf("%s\n", devname); + } + + if (devname) { + free(devname); + } + + return ret; +} diff --git a/tools/iphoneinfo.c b/tools/iphoneinfo.c new file mode 100644 index 0000000..7e275b2 --- /dev/null +++ b/tools/iphoneinfo.c @@ -0,0 +1,281 @@ +/* + * iphoneinfo.c + * Simple utility to show information about an attached device + * + * Copyright (c) 2009 Martin Szulecki All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include +#include + +#define FORMAT_KEY_VALUE 1 +#define FORMAT_XML 2 + +static const char *domains[] = { + "com.apple.disk_usage", + "com.apple.mobile.battery", +/* FIXME: For some reason lockdownd segfaults on this, works sometimes though + "com.apple.mobile.debug",. */ + "com.apple.xcode.developerdomain", + "com.apple.international", + "com.apple.mobile.mobile_application_usage", + "com.apple.mobile.backup", + "com.apple.mobile.user_preferences", + "com.apple.mobile.sync_data_class", + "com.apple.mobile.software_behavior", + "com.apple.mobile.iTunes.SQLMusicLibraryPostProcessCommands", + "com.apple.iTunes", + "com.apple.mobile.iTunes.store", + "com.apple.mobile.iTunes", + NULL +}; + +int is_domain_known(char *domain); +void print_usage(int argc, char **argv); +void plist_node_to_string(plist_t *node); +void plist_children_to_string(plist_t *node); + +int main(int argc, char *argv[]) +{ + lockdownd_client_t client = NULL; + iphone_device_t phone = NULL; + iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; + int i; + int format = FORMAT_KEY_VALUE; + char uuid[41]; + char *domain = NULL; + char *key = NULL; + char *xml_doc = NULL; + uint32_t xml_length; + plist_t node = NULL; + uuid[0] = 0; + + /* parse cmdline args */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + iphone_set_debug_mask(DBGMASK_ALL); + iphone_set_debug_level(1); + continue; + } + else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { + i++; + if (!argv[i] || (strlen(argv[i]) != 40)) { + print_usage(argc, argv); + return 0; + } + strcpy(uuid, argv[i]); + continue; + } + else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--domain")) { + i++; + if (!argv[i] || (strlen(argv[i]) < 4)) { + print_usage(argc, argv); + return 0; + } + if (!is_domain_known(argv[i])) { + fprintf(stderr, "WARNING: Sending query with unknown domain \"%s\".\n", argv[i]); + } + domain = strdup(argv[i]); + continue; + } + else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--key")) { + i++; + if (!argv[i] || (strlen(argv[i]) <= 1)) { + print_usage(argc, argv); + return 0; + } + key = strdup(argv[i]); + continue; + } + else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) { + format = FORMAT_XML; + continue; + } + else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + print_usage(argc, argv); + return 0; + } + else { + print_usage(argc, argv); + return 0; + } + } + + if (uuid[0] != 0) { + ret = iphone_get_device_by_uuid(&phone, uuid); + if (ret != IPHONE_E_SUCCESS) { + printf("No device found with uuid %s, is it plugged in?\n", uuid); + return -1; + } + } + else + { + ret = iphone_get_device(&phone); + if (ret != IPHONE_E_SUCCESS) { + printf("No device found, is it plugged in?\n"); + return -1; + } + } + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { + iphone_device_free(phone); + return -1; + } + + /* run query and output information */ + if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS) + { + if (plist_get_node_type(node) == PLIST_DICT) { + if (plist_get_first_child(node)) + { + switch (format) { + case FORMAT_XML: + plist_to_xml(node, &xml_doc, &xml_length); + printf(xml_doc); + free(xml_doc); + break; + case FORMAT_KEY_VALUE: + default: + plist_children_to_string(node); + break; + } + } + } + else if(node && (key != NULL)) + plist_node_to_string(node); + if (node) + plist_free(node); + node = NULL; + } + + if (domain != NULL) + free(domain); + lockdownd_client_free(client); + iphone_device_free(phone); + + return 0; +} + +int is_domain_known(char *domain) +{ + int i = 0; + while (domains[i] != NULL) { + if (strstr(domain, domains[i++])) { + return 1; + } + } + return 0; +} + +void print_usage(int argc, char **argv) +{ + int i = 0; + char *name = NULL; + + name = strrchr(argv[0], '/'); + printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); + printf("Show information about the first connected iPhone/iPod Touch.\n\n"); + printf(" -d, --debug\t\tenable communication debugging\n"); + printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); + printf(" -q, --domain NAME\tset domain of query to NAME. Default: None\n"); + printf(" -k, --key NAME\tonly query key specified by NAME. Default: All keys.\n"); + printf(" -x, --xml\t\toutput information as xml plist instead of key/value pairs\n"); + printf(" -h, --help\t\tprints usage information\n"); + printf("\n"); + printf(" Known domains are:\n\n"); + while (domains[i] != NULL) { + printf(" %s\n", domains[i++]); + } + printf("\n"); +} + +void plist_node_to_string(plist_t *node) +{ + char *s = NULL; + double d; + uint8_t b; + + uint64_t u = 0; + + plist_type t; + + if (!node) + return; + + t = plist_get_node_type(node); + + switch (t) { + case PLIST_BOOLEAN: + plist_get_bool_val(node, &b); + printf("%s\n", (b ? "true" : "false")); + break; + + case PLIST_UINT: + plist_get_uint_val(node, &u); + printf("%llu\n", (long long)u); + break; + + case PLIST_REAL: + plist_get_real_val(node, &d); + printf("%f\n", d); + break; + + case PLIST_STRING: + plist_get_string_val(node, &s); + printf("%s\n", s); + free(s); + break; + + case PLIST_KEY: + plist_get_key_val(node, &s); + printf("%s: ", s); + free(s); + break; + + case PLIST_DATA: + printf("\n"); + break; + case PLIST_DATE: + printf("\n"); + break; + case PLIST_ARRAY: + case PLIST_DICT: + printf("\n"); + plist_children_to_string(node); + break; + default: + break; + } +} + +void plist_children_to_string(plist_t *node) +{ + /* iterate over key/value pairs */ + for ( + node = plist_get_first_child(node); + node != NULL; + node = plist_get_next_sibling(node) + ) { + plist_node_to_string(node); + } +} + diff --git a/tools/iphonesyslog.c b/tools/iphonesyslog.c new file mode 100644 index 0000000..a096101 --- /dev/null +++ b/tools/iphonesyslog.c @@ -0,0 +1,169 @@ +/* + * syslog_relay.c + * Relay the syslog of a device to stdout + * + * Copyright (c) 2009 Martin Szulecki All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int quit_flag = 0; + +void print_usage(int argc, char **argv); + +/** + * signal handler function for cleaning up properly + */ +static void clean_exit(int sig) +{ + fprintf(stderr, "Exiting...\n"); + quit_flag++; +} + +int main(int argc, char *argv[]) +{ + lockdownd_client_t client = NULL; + iphone_device_t phone = NULL; + iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; + int i; + char uuid[41]; + int port = 0; + uuid[0] = 0; + uint32_t handle = 0; + + signal(SIGINT, clean_exit); + signal(SIGQUIT, clean_exit); + signal(SIGTERM, clean_exit); + signal(SIGPIPE, SIG_IGN); + + /* parse cmdline args */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + iphone_set_debug_mask(DBGMASK_ALL); + iphone_set_debug_level(1); + continue; + } + else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { + i++; + if (!argv[i] || (strlen(argv[i]) != 40)) { + print_usage(argc, argv); + return 0; + } + strcpy(uuid, argv[i]); + continue; + } + else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + print_usage(argc, argv); + return 0; + } + else { + print_usage(argc, argv); + return 0; + } + } + + if (uuid[0] != 0) { + ret = iphone_get_device_by_uuid(&phone, uuid); + if (ret != IPHONE_E_SUCCESS) { + printf("No device found with uuid %s, is it plugged in?\n", uuid); + return -1; + } + } + else + { + ret = iphone_get_device(&phone); + if (ret != IPHONE_E_SUCCESS) { + printf("No device found, is it plugged in?\n"); + return -1; + } + } + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { + iphone_device_free(phone); + return -1; + } + + /* start syslog_relay service and retrieve port */ + ret = lockdownd_start_service(client, "com.apple.syslog_relay", &port); + if ((ret == LOCKDOWN_E_SUCCESS) && port) { + lockdownd_client_free(client); + + /* connect to socket relay messages */ + iphone_device_get_handle(phone, &handle); + int sfd = usbmuxd_connect(handle, port); + if (sfd < 0) { + printf("ERROR: Could not open usbmux connection.\n"); + } else { + while (!quit_flag) { + char *receive = NULL; + uint32_t datalen = 0, bytes = 0, recv_bytes = 0; + + ret = usbmuxd_recv(sfd, (char *) &datalen, sizeof(datalen), &bytes); + datalen = ntohl(datalen); + + if (datalen == 0) + continue; + + recv_bytes += bytes; + receive = (char *) malloc(sizeof(char) * datalen); + + while (!quit_flag && (recv_bytes <= datalen)) { + ret = usbmuxd_recv(sfd, receive, datalen, &bytes); + + if (bytes == 0) + break; + + recv_bytes += bytes; + + fwrite(receive, sizeof(char), bytes, stdout); + } + + free(receive); + } + } + usbmuxd_disconnect(sfd); + } else { + printf("ERROR: Could not start service com.apple.syslog_relay.\n"); + } + + iphone_device_free(phone); + + return 0; +} + +void print_usage(int argc, char **argv) +{ + char *name = NULL; + + name = strrchr(argv[0], '/'); + printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); + printf("Relay syslog of a connected iPhone/iPod Touch.\n\n"); + printf(" -d, --debug\t\tenable communication debugging\n"); + printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); + printf(" -h, --help\t\tprints usage information\n"); + printf("\n"); +} + -- cgit v1.1-32-gdbae From 4a5d3174ddc5a9596191176829f0b8ae1feae32b Mon Sep 17 00:00:00 2001 From: Martin Szulecki Date: Tue, 28 Jul 2009 09:33:58 +0000 Subject: Rewrite option handling in iphone_id, add --debug and improve usage message [#64 state:resolved] Signed-off-by: Matt Colyer --- tools/iphone_id.c | 130 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 58 deletions(-) diff --git a/tools/iphone_id.c b/tools/iphone_id.c index f68fc8b..835e214 100644 --- a/tools/iphone_id.c +++ b/tools/iphone_id.c @@ -1,19 +1,27 @@ #include #include #include -#include #include #include #include -static void usage() +#define MODE_NONE 0 +#define MODE_SHOW_ID 1 +#define MODE_LIST_DEVICES 2 + +static void print_usage(int argc, char **argv) { - printf("usage: iphone_id \n" - "\tdevice_uuid is the 40-digit hexadecimal UUID of the device\n" - "\tfor which the name should be retrieved.\n\n" - "usage: iphone_id -l\n" - "\tList all attached devices.\n"); - exit(0); + char *name = NULL; + + name = strrchr(argv[0], '/'); + printf("Usage: %s [OPTIONS] [UUID]\n", (name ? name + 1: argv[0])); + printf("Prints device name or a list of attached iPhone/iPod Touch devices.\n\n"); + printf(" The UUID is a 40-digit hexadecimal number of the device\n"); + printf(" for which the name should be retrieved.\n\n"); + printf(" -l, --list\t\tlist all attached devices\n"); + printf(" -d, --debug\t\tenable communication debugging\n"); + printf(" -h, --help\t\tprints usage information\n"); + printf("\n"); } int main(int argc, char **argv) @@ -23,33 +31,71 @@ int main(int argc, char **argv) usbmuxd_scan_result *dev_list; char *devname = NULL; int ret = 0; - int c; int i; - int opt_list = 0; + int mode = MODE_SHOW_ID; + char uuid[41]; + uuid[0] = 0; - while ((c = getopt(argc, argv, "lh")) != -1) { - switch (c) { - case 'l': - opt_list = 1; - break; - case 'h': - default: - usage(); + /* parse cmdline args */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + iphone_set_debug_mask(DBGMASK_ALL); + iphone_set_debug_level(1); + continue; + } + else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--list")) { + mode = MODE_LIST_DEVICES; + continue; + } + else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + print_usage(argc, argv); + return 0; } } - if (argc < 2) { - usage(); + /* check if uuid was passed */ + if (mode == MODE_SHOW_ID) { + i--; + if (!argv[i] || (strlen(argv[i]) != 40)) { + print_usage(argc, argv); + return 0; + } + strcpy(uuid, argv[i]); } - argc -= optind; - argv += optind; + switch (mode) { + case MODE_SHOW_ID: + iphone_get_device_by_uuid(&phone, uuid); + if (!phone) { + fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", uuid); + return -2; + } - if ((!opt_list) && (strlen(argv[0]) != 40)) { - usage(); - } + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { + iphone_device_free(phone); + fprintf(stderr, "ERROR: Connecting to device failed!\n"); + return -2; + } + + if ((LOCKDOWN_E_SUCCESS != lockdownd_get_device_name(client, &devname)) || !devname) { + fprintf(stderr, "ERROR: Could not get device name!\n"); + ret = -2; + } + + lockdownd_client_free(client); + iphone_device_free(phone); + + if (ret == 0) { + printf("%s\n", devname); + } + + if (devname) { + free(devname); + } - if (opt_list) { + return ret; + case MODE_LIST_DEVICES: + default: if (usbmuxd_scan(&dev_list) < 0) { fprintf(stderr, "ERROR: usbmuxd is not running!\n"); return -1; @@ -59,36 +105,4 @@ int main(int argc, char **argv) } return 0; } - - iphone_set_debug_level(0); - - iphone_get_device_by_uuid(&phone, argv[0]); - if (!phone) { - fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", argv[0]); - return -2; - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client)) { - iphone_device_free(phone); - fprintf(stderr, "ERROR: Connecting to device failed!\n"); - return -2; - } - - if ((LOCKDOWN_E_SUCCESS != lockdownd_get_device_name(client, &devname)) || !devname) { - fprintf(stderr, "ERROR: Could not get device name!\n"); - ret = -2; - } - - lockdownd_client_free(client); - iphone_device_free(phone); - - if (ret == 0) { - printf("%s\n", devname); - } - - if (devname) { - free(devname); - } - - return ret; } -- cgit v1.1-32-gdbae