summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am5
-rw-r--r--src/client.c1
-rw-r--r--src/device.c19
-rw-r--r--src/device.h2
-rw-r--r--src/main.c20
-rw-r--r--src/preflight.c271
-rw-r--r--src/preflight.h28
7 files changed, 338 insertions, 8 deletions
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 @@
1AM_CFLAGS = $(GLOBAL_CFLAGS) -I$(top_srcdir)/src $(libplist_CFLAGS) $(libusb_CFLAGS) 1AM_CFLAGS = $(GLOBAL_CFLAGS) -I$(top_srcdir)/src $(libplist_CFLAGS) $(libusb_CFLAGS) $(libimobildevice_CFLAGS)
2AM_LDFLAGS = $(libplist_LIBS) $(libusb_LIBS) 2AM_LDFLAGS = $(libplist_LIBS) $(libusb_LIBS) $(libimobiledevice_LIBS) $(libpthread_LIBS)
3 3
4sbin_PROGRAMS = usbmuxd 4sbin_PROGRAMS = usbmuxd
5 5
6usbmuxd_SOURCES = client.c client.h \ 6usbmuxd_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)
584void client_device_add(struct device_info *dev) 584void 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
467static void device_tcp_input(struct mux_device *dev, struct tcphdr *th, unsigned char *payload, uint32_t payload_length) 469static 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
686void 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
683int device_get_count(void) 696int 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
40void device_client_process(int device_id, struct mux_client *client, short events); 40void device_client_process(int device_id, struct mux_client *client, short events);
41void device_abort_connect(int device_id, struct mux_client *client); 41void device_abort_connect(int device_id, struct mux_client *client);
42 42
43void device_set_visible(int device_id);
44
43int device_get_count(void); 45int device_get_count(void);
44int device_get_list(struct device_info *p); 46int device_get_list(struct device_info *p);
45 47
diff --git a/src/main.c b/src/main.c
index 32c6a2b..1804c30 100644
--- a/src/main.c
+++ b/src/main.c
@@ -49,6 +49,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
49 49
50static const char *socket_path = "/var/run/usbmuxd"; 50static const char *socket_path = "/var/run/usbmuxd";
51static const char *lockfile = "/var/run/usbmuxd.pid"; 51static const char *lockfile = "/var/run/usbmuxd.pid";
52static const char *userprefdir = "/var/lib/lockdown";
52 53
53int should_exit; 54int should_exit;
54int should_discover; 55int 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
4Copyright (C) 2013 Nikias Bassen <nikias@gmx.li>
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 or version 3.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 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
42enum connection_type {
43 CONNECTION_USBMUXD = 1
44};
45
46struct idevice_private {
47 char *udid;
48 enum connection_type conn_type;
49 void *conn_data;
50};
51
52extern void userpref_get_system_buid(char **systembuid);
53
54struct np_cb_data {
55 idevice_t dev;
56 np_client_t np;
57};
58
59static 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
68static 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
110static 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
247leave:
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
259void 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
4Copyright (C) 2013 Nikias Bassen <nikias@gmx.li>
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 or version 3.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 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
26void preflight_worker_device_add(struct device_info* info);
27
28#endif