diff options
Diffstat (limited to 'README')
| -rw-r--r-- | README | 218 |
1 files changed, 0 insertions, 218 deletions
| @@ -1,218 +0,0 @@ | |||
| 1 | Background | ||
| 2 | ========== | ||
| 3 | |||
| 4 | 'usbmuxd' stands for "USB multiplexing daemon". This daemon is in charge of | ||
| 5 | multiplexing connections over USB to an iPhone or iPod touch. To users, it means | ||
| 6 | you can sync your music, contacts, photos, etc. over USB. To developers, it | ||
| 7 | means you can connect to any listening localhost socket on the device. usbmuxd | ||
| 8 | is not used for tethering data transfer, which uses a dedicated USB interface as | ||
| 9 | a virtual network device. | ||
| 10 | |||
| 11 | Multiple connections to different TCP ports can happen in parallel. An example | ||
| 12 | (and useful) tool called 'iproxy' is included that allows you to forward | ||
| 13 | localhost ports to the device---allows SSH over USB on jailbroken devices, or | ||
| 14 | allowing access the lockdown daemon (and then to all of the file access, sync, | ||
| 15 | notification and backup services running on the device). | ||
| 16 | |||
| 17 | The higher-level layers are handled by libimobiledevice. 'ifuse' is then able | ||
| 18 | to sit on top of this and mount your device's AFC filesystem share. | ||
| 19 | |||
| 20 | There is also a Python implementation of the client library in the python-client | ||
| 21 | library, and an example tcprelay.py which performs a similar function to iproxy. | ||
| 22 | This implementation supports OSX and Windows and the new iTunes plist-based | ||
| 23 | usbmuxd protocol, so it is portable and will run on those operating systems with | ||
| 24 | no modification, using Apple's native usbmuxd. This is useful if you need to | ||
| 25 | tunnel to your device from another OS in a pinch. Run python tcpclient.py --help | ||
| 26 | for usage information. | ||
| 27 | |||
| 28 | License | ||
| 29 | ======= | ||
| 30 | |||
| 31 | The contents of this package are licensed under the GNU General Public License, | ||
| 32 | versions 2 or 3 (see COPYING.GPLv2 and COPYING.GPLv3), except for libuxbmuxd | ||
| 33 | which is licensed under the GNU Lesser General Public License, version 2.1 or, | ||
| 34 | at your option, any later version (see COPYING.LGPLv2.1). If a more permissive | ||
| 35 | license is specified at the top of a source file, it takes precedence over this. | ||
| 36 | |||
| 37 | Legal | ||
| 38 | ===== | ||
| 39 | |||
| 40 | Apple, iPhone, and iPod touch are trademarks of Apple Inc., registered in the | ||
| 41 | U.S. and other countries. | ||
| 42 | |||
| 43 | Building | ||
| 44 | ======== | ||
| 45 | |||
| 46 | mkdir build | ||
| 47 | cd build | ||
| 48 | cmake .. | ||
| 49 | make | ||
| 50 | sudo make install | ||
| 51 | |||
| 52 | You should also create a 'usbmux' user that has access to USB devices on your | ||
| 53 | system. Alternatively, you can pass a different username after the -U argument. | ||
| 54 | |||
| 55 | Running (with magic) | ||
| 56 | ==================== | ||
| 57 | |||
| 58 | (Unplug + replug your jailbroken device) | ||
| 59 | ./iproxy 2222 22 & | ||
| 60 | ssh -p 2222 root@localhost | ||
| 61 | |||
| 62 | Hopefully you get the normal SSH login prompt. You may still lots of debugging | ||
| 63 | output for the moment. If this is getting in the way of your ssh login, then | ||
| 64 | run the 'ssh' command from a different xterminal or virtual console. Of course, | ||
| 65 | you need to have OpenSSH installed on your jailbroken device for this to work. | ||
| 66 | |||
| 67 | If you have iFuse, you can run "ifuse <mountpoint">. This doesn't require | ||
| 68 | iproxy and works on all devices, jailbroken or not. | ||
| 69 | |||
| 70 | Running (without magic) | ||
| 71 | ======================= | ||
| 72 | |||
| 73 | If 'udev' is _not_ automatically running on your machine and picking up the new | ||
| 74 | .rules file, you will need to start usbmuxd by hand first. Check it's running | ||
| 75 | and that there is only one copy with 'ps aux | grep | ||
| 76 | usbmuxd'. | ||
| 77 | |||
| 78 | sudo usbmuxd -U -v -v & | ||
| 79 | ./iproxy 2222 22 & | ||
| 80 | ssh -p 2222 root@localhost | ||
| 81 | |||
| 82 | Tip: Starting SSH if disabled | ||
| 83 | ============================= | ||
| 84 | |||
| 85 | If your device is rooted, but SSH isn't started and you _cannot_ (for instance, | ||
| 86 | cracked/broken screen) get to the Services control panel on the device, then you | ||
| 87 | can start the SSH service over the USB by mounting the (jailbroken) filesystem. | ||
| 88 | |||
| 89 | You will need to mount it using 'ifuse --afc2' (to access the root directory of | ||
| 90 | the device), and then edit: | ||
| 91 | |||
| 92 | /Library/LaunchDaemons/com.openssh.sshd.plist | ||
| 93 | |||
| 94 | to _remove_ the lines: | ||
| 95 | |||
| 96 | <key>Disabled</key> | ||
| 97 | <true/> | ||
| 98 | |||
| 99 | Reboot the device and then sshd should be running. | ||
| 100 | |||
| 101 | TODO | ||
| 102 | ==== | ||
| 103 | |||
| 104 | The server currently assumes that the device is well-behaved and does not do a | ||
| 105 | bunch of checks like looking for the expected SEQ and ACK numbers from it. This | ||
| 106 | is normally not an issue, but it's annoying for debugging because lost packets | ||
| 107 | (which shouldn't happen, but can happen if the code is buggy) mean that stuff | ||
| 108 | gets out of sync and then might crash and burn dozens of packets later. | ||
| 109 | |||
| 110 | The server needs more testing, and some optimizing. | ||
| 111 | |||
| 112 | Someone should probably do some edge-case testing on the TCP stuff. | ||
| 113 | |||
| 114 | The outgoing ACK handling on the server probably needs some thought. Currently, | ||
| 115 | when there's an outstanding ACK, we send it after a timeout (to avoid sending | ||
| 116 | a no-payload ACK packet for everything the phone sends us). However, there's | ||
| 117 | probably a better way of doing this. | ||
| 118 | |||
| 119 | Architecture information | ||
| 120 | ======================== | ||
| 121 | |||
| 122 | The iPhone / iPod Touch basically implements a rather strange USB networking | ||
| 123 | system that operates at a higher level. It is of course completely proprietary. | ||
| 124 | Generally speaking, this is what goes on in a typical usage scenario: | ||
| 125 | |||
| 126 | 0. iTunes opens a connection to usbmuxd and asks it for device notifications | ||
| 127 | 1. User inserts phone into computer | ||
| 128 | 2. usbmuxd notices the phone and pings it with a version packet | ||
| 129 | 3. phone replies | ||
| 130 | 4. usbmuxd now considers the phone to be connected and tells iTunes | ||
| 131 | 5. iTunes opens another separate connection to usbmuxd and asks it to connect | ||
| 132 | to, say, the afc port on the device | ||
| 133 | 6. usbmuxd sends a pseudo-TCP SYN packet to the phone | ||
| 134 | 7. the phone's kernel driver receives the SYN packet and itself opens a | ||
| 135 | TCP connection to localhost on the afc port | ||
| 136 | 8. the phone replies with a pseudo-TCP SYN/ACK indicating that the port is open | ||
| 137 | and the connection can proceed | ||
| 138 | 7. usbmuxd sends a final ACK to the phone | ||
| 139 | 8. usbmuxd replies to iTunes with a "connection successful" message | ||
| 140 | 9. any data that iTunes writes to the usbmuxd socket from now on is forwarded, | ||
| 141 | through pseudo-TCP, through USB, back into a more regular TCP connection to | ||
| 142 | localhost, to the afc daemon on the phone, and vice versa | ||
| 143 | |||
| 144 | The usbmuxd protocol is a relatively simple binary message protocol documented | ||
| 145 | here: | ||
| 146 | |||
| 147 | http://wikee.iphwn.org/usb:usbmux | ||
| 148 | |||
| 149 | Note that once a connection is established the UNIX socket essentially becomes | ||
| 150 | a dedicated pipe to the TCP connction and no more high-level control is | ||
| 151 | possible (closing the socket closes the TCP connection). Ditto for the "listen | ||
| 152 | for devices" mode - usbmuxd will reject any commands in such mode, and the | ||
| 153 | socket essentially becomes a dedicated device notification pipe. This means | ||
| 154 | that you need, at minimum, TWO connections to usbmuxd to do anything useful. | ||
| 155 | |||
| 156 | On Windows, usbmuxd works the same way but a TCP connection to localhost port | ||
| 157 | 27015 replaces the UNIX socket. On OSX, the UNIX socket is /var/run/usbmuxd. The | ||
| 158 | server and client implemented here default the same /var/run/usbmuxd socket. | ||
| 159 | |||
| 160 | The phone protocol operates over a pair of USB bulk endpoints. There is an outer | ||
| 161 | layer used for packet size info and a "protocol" (version and TCP are the only | ||
| 162 | two options), and that header is followed by TCP headers for actual data comms. | ||
| 163 | However, the protocol isn't actual TCP, just a custom protocol which for some | ||
| 164 | reason uses a standard TCP header and leaves most fields unused. | ||
| 165 | |||
| 166 | There is no reordering or retransmission. There are no checksums, no URG, no | ||
| 167 | PSH, no non-ACK, no FIN. What there *is* is the SEQ/ACK/window mechanism used | ||
| 168 | for flow control, and RST is used as the only connection teardown mechanism (and | ||
| 169 | also for "connection refused"), and the connection startup is SYN/SYNACK/ACK. | ||
| 170 | |||
| 171 | Windows are constant-scaled by 8 bits. This is legal TCP as long as the | ||
| 172 | corresponding option is negotiated. Of course, no such negotiation happens on | ||
| 173 | this protocol. | ||
| 174 | |||
| 175 | Note that, since there are no retransmissions, there is some overlap between ACK | ||
| 176 | and window for flow control. For example, the server doesn't ever touch its | ||
| 177 | window size, and just refuses to ACK stuff if its buffers are full and the | ||
| 178 | client isn't reading data. The phone happily seems to stop sending stuff. | ||
| 179 | |||
| 180 | Also, if the phone RSTs you out of nowhere, look at the packet payload for a | ||
| 181 | textual error message. Note: if it claims to suffer from amnesia, that probably | ||
| 182 | means you overflowed its input buffer by ignoring its flow control / window | ||
| 183 | size. Go figure. Probably a logic bug in the kernel code. | ||
| 184 | |||
| 185 | Note that all normal packets need to have flags set to ACK (and only ACK). There | ||
| 186 | is no support for, erm, not-acking. Keep the ack number field valid at all | ||
| 187 | times. | ||
| 188 | |||
| 189 | The usbmuxd CONNECT request port field is byte-swapped (network-endian). This is | ||
| 190 | even more annoying for the plist based protocol, since it's even true there | ||
| 191 | (where the field is plain text). So even for the plain text int, you need to | ||
| 192 | swap the bytes (port 22 becomes <integer>5632</integer>). I have no clue if this | ||
| 193 | is the case on the new plist protocol on PPC macs (is the newer iTunes available | ||
| 194 | for those?) | ||
| 195 | |||
| 196 | There are a bunch of gotchas due to the USB framing, and this is even worse | ||
| 197 | because implementations tend to get it wrong (i.e. libusb, and this is the | ||
| 198 | reason for the patch). Basically, USB Bulk offers, at the low level, the ability | ||
| 199 | to transfer packets from 0 to wMaxPacketSize (512 here) bytes, period. There is | ||
| 200 | no other support for higher level framing of transfers. The way you do those is | ||
| 201 | by breaking them up into packets, and the final shorter packet marks the end of | ||
| 202 | the transfer. The critical bit is that, if the transfer happens to be divisible | ||
| 203 | by 512, you send a zero-length packet (ZLP) to indicate the end of the transfer. | ||
| 204 | Libusb doesn't set this option by default and the iPhone gets packets stuck to | ||
| 205 | each other, which it doesn't like. Actually, this framing is sort of redundant | ||
| 206 | because the usbmux packet header includes a length field, but the phone still | ||
| 207 | wants the ZLPs or else it breaks. To make matters worse, usbdevfs imposes a max | ||
| 208 | transfer size of 16k, so libusb breaks transfers into that size. This is okay | ||
| 209 | for sending as long as the ZLP is only added to the last transfer (the patch | ||
| 210 | does that), but it can easily cause nasty race conditions on RX due to libusb | ||
| 211 | doing multiple outstanding reads at the same time and then cancelling the rest | ||
| 212 | when shorter data arrives (but what if some data got into the other requests | ||
| 213 | already?), so we only do 16k reads and stick them together ourselves by looking | ||
| 214 | at the packet size header. We still depend on ZLPs being sent to end transfers | ||
| 215 | at non-16k boundaries that are multiples of 512, but that seems to work fine. I | ||
| 216 | guess the ZLPs might cause spurious 0-byte transfers to show up on RX if things | ||
| 217 | line up right, but we ignore those. By the way, the maximum packet/transfer size | ||
| 218 | is 65535 bytes due to the 16-bit length header of the usbmux protocol. | ||
