Search code examples
iphonesshopenssh

usbmuxd for multiple idevices


By using usbmuxd with the help of following command..

tcprelay.py -t 5900

I am able to connect to iphone with VNC viewer by giving hostname as 127.0.0.1 and port as 5900. By using above command i able to connect to the last connected iphone.

Now how can i connect to multiple devices at same time by using usbmuxd. i studied in documentation of usbmuxd that we can connect to multiple devices. I seen help but unable to workout on it. can anyone kindly give suggestions.

Iphone is jail broken with veency, openssh installed

Thanks in advance.


Solution

  • In the latest version of tcprelay.py (http://cgit.sukimashita.com/usbmuxd.git, v1.0.8), multiple device support is not yet implemented. Commands are always sent to the first device:

        print "Waiting for devices..."
        if not mux.devices:
            mux.process(1.0)
        if not mux.devices:
            print "No device found"
            self.request.close()
            return
        dev = mux.devices[0]
    

    This has to be changed to something like:

        dev = None
        while dev is None:
            for d in mux.devices:
                if d.serial == self.server.serial:
                    dev = d
                    print "Found the device %s"%str(dev)
                    break
            if dev is None:
                mux.process()
    

    Here's the complete tcprelay.py, I'm using:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    #
    #   tcprelay.py - TCP connection relay for usbmuxd
    #
    # Copyright (C) 2009    Hector Martin "marcan" <[email protected]>
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 2 or version 3.
    #
    # This program 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 General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    
    import usbmux
    import SocketServer
    import select
    from optparse import OptionParser
    import sys
    import threading
    
    class SocketRelay(object):
        def __init__(self, a, b, maxbuf=65535):
            self.a = a
            self.b = b
            self.atob = ""
            self.btoa = ""
            self.maxbuf = maxbuf
        def handle(self):
            while True:
                rlist = []
                wlist = []
                xlist = [self.a, self.b]
                if self.atob:
                    wlist.append(self.b)
                if self.btoa:
                    wlist.append(self.a)
                if len(self.atob) < self.maxbuf:
                    rlist.append(self.a)
                if len(self.btoa) < self.maxbuf:
                    rlist.append(self.b)
                rlo, wlo, xlo = select.select(rlist, wlist, xlist)
                if xlo:
                    return
                if self.a in wlo:
                    n = self.a.send(self.btoa)
                    self.btoa = self.btoa[n:]
                if self.b in wlo:
                    n = self.b.send(self.atob)
                    self.atob = self.atob[n:]
                if self.a in rlo:
                    s = self.a.recv(self.maxbuf - len(self.atob))
                    if not s:
                        return
                    self.atob += s
                if self.b in rlo:
                    s = self.b.recv(self.maxbuf - len(self.btoa))
                    if not s:
                        return
                    self.btoa += s
                #print "Relay iter: %8d atob, %8d btoa, lists: %r %r %r"%(len(self.atob), len(self.btoa), rlo, wlo, xlo)
    
    class TCPRelay(SocketServer.BaseRequestHandler):
        def handle(self):
            print "Incoming connection to %d"%self.server.server_address[1]
            mux = usbmux.USBMux(options.sockpath)
    
            #print "Waiting for devices..."
            #if not mux.devices:
            #   mux.process(1.0)
            #if not mux.devices:
            #   print "No device found"
            #   self.request.close()
            #   return
            #dev = mux.devices[0]
    
            dev = None
            while dev is None:
                for d in mux.devices:
                    if d.serial == self.server.serial:
                        dev = d
                        print "Found the device %s"%str(dev)
                        break
                if dev is None:
                    mux.process()
    
            print "Connecting to device %s"%str(dev)
            dsock = mux.connect(dev, self.server.rport)
            lsock = self.request
            print "Connection established, relaying data"
            try:
                fwd = SocketRelay(dsock, lsock, self.server.bufsize * 1024)
                fwd.handle()
            finally:
                dsock.close()
                lsock.close()
            print "Connection closed"
    
    class TCPServer(SocketServer.TCPServer):
        allow_reuse_address = True
    
    class ThreadedTCPServer(SocketServer.ThreadingMixIn, TCPServer):
        pass
    
    HOST = "localhost"
    
    parser = OptionParser(usage="usage: %prog [OPTIONS] RemotePort[:LocalPort] [RemotePort[:LocalPort]]...")
    parser.add_option("-t", "--threaded", dest='threaded', action='store_true', default=False, help="use threading to handle multiple connections at once")
    parser.add_option("-b", "--bufsize", dest='bufsize', action='store', metavar='KILOBYTES', type='int', default=128, help="specify buffer size for socket forwarding")
    parser.add_option("-s", "--socket", dest='sockpath', action='store', metavar='PATH', type='str', default=None, help="specify the path of the usbmuxd socket")
    
    options, args = parser.parse_args()
    
    serverclass = TCPServer
    if options.threaded:
        serverclass = ThreadedTCPServer
    
    if len(args) == 0:
        parser.print_help()
        sys.exit(1)
    
    ports = []
    
    for arg in args:
        try:
    
    #       if ':' in arg:
    #           rport, lport = arg.split(":")
    #           lport = int(lport)
    #           ports.append((rport, lport))
    #       else:
    #           ports.append((int(arg), int(arg)))
    
            rport, lport, serial = arg.split(":")
            lport = int(lport)
            ports.append((int(rport), int(lport), serial))
    
        except:
            parser.print_help()
            sys.exit(1)
    
    servers=[]
    
    for rport, lport, serial in ports:
        print "Forwarding local port %d to remote port %d"%(lport, rport)
        server = serverclass((HOST, lport), TCPRelay)
        server.rport = rport
        server.bufsize = options.bufsize
        server.serial = serial
        servers.append(server)
    
    alive = True
    
    while alive:
        try:
            rl, wl, xl = select.select(servers, [], [])
            for server in rl:
                server.handle_request()
        except:
            alive = False