def test_dialRemote(self):
        remoteServer = socket.socket()
        remoteServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        address = net.Address('127.0.0.1', 11111)
        remoteServer.bind(address)
        remoteServer.listen(1)

        self.securesocket.remoteAddr = address

        localServer = self.securesocket.dialRemote()
        localServer.setblocking(True)
        localServer.send(self.msg)

        remoteConn, _ = remoteServer.accept()
        received_msg = remoteConn.recv(1024)

        self.assertEqual(received_msg, self.msg)

        with self.assertRaises(Exception):
            self.securesocket.remoteAddr = net.Address('127.0.0.1', 0)
            self.securesocket.dialRemote()

        localServer.close()
        remoteServer.close()
Beispiel #2
0
def run_server(config: lsConfig.Config):
    loop = asyncio.get_event_loop()

    listenAddr = net.Address(config.localAddr, config.localPort)
    remoteAddr = net.Address(config.serverAddr, config.serverPort)
    server = LsLocal(loop=loop,
                     password=config.password,
                     listenAddr=listenAddr,
                     remoteAddr=remoteAddr)

    def didListen(address):
        print('Listen to %s:%d\n' % address)

    asyncio.ensure_future(server.listen(didListen))
    loop.run_forever()
Beispiel #3
0
    def setUp(self):
        self.listenAddr = net.Address('127.0.0.1', getValidAddr()[1])

        password = randomPassword()
        self.cipher = Cipher.NewCipher(password)
        self.loop = asyncio.new_event_loop()
        self.server = LsServer(loop=self.loop,
                               password=password,
                               listenAddr=self.listenAddr)
Beispiel #4
0
    def setUp(self):
        self.listenAddr = net.Address('127.0.0.1', 11111)
        self.remoteAddr = net.Address('127.0.0.1', 22222)
        self.remoteServer = socket.socket()
        self.remoteServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.remoteServer.bind(self.remoteAddr)
        self.remoteServer.listen(1)

        password = randomPassword()
        self.cipher = Cipher.NewCipher(password)
        self.loop = asyncio.new_event_loop()
        self.local = LsLocal(loop=self.loop,
                             password=password,
                             listenAddr=self.listenAddr,
                             remoteAddr=self.remoteAddr)

        self.msg = bytearray(b'hello world')
        self.encrypted_msg = self.msg.copy()
        self.cipher.encode(self.encrypted_msg)
Beispiel #5
0
    async def handleConn(self, connection: Connection):
        buf = await self.decodeRead(connection)
        if buf[0] != 0x05:
            connection.close()
            return

        await self.encodeWrite(connection, bytearray((0x05, 0x00)))

        buf = await self.decodeRead(connection)
        if len(buf) < 7:
            connection.close()
            return

        if buf[1] != 0x01:
            connection.close()
            return

        dstIP = None

        if buf[3] == 0x01:
            dstIP = buf[4:4 + 4]
            dstIP = '.'.join(map(str, dstIP))
        elif buf[3] == 0x03:
            dstIP = buf[4:-2].decode()
        elif buf[3] == 0x04:
            dstIP = buf[4: 4 + 16]
            dstIP = ':'.join(map(lambda x: hex(x)[2:], dstIP))
        else:
            connection.close()
            return

        dstPort = buf[-2:]
        dstPort = int(dstPort.hex(), 16)

        dstAddress = net.Address(ip=dstIP, port=dstPort)
        dstServer = socket.create_connection(dstAddress)
        dstServer.setblocking(False)

        def cleanUp(task):
            dstServer.close()
            connection.close()

        await self.encodeWrite(connection,
                               bytearray((0x05, 0x00, 0x00, 0x01, 0x00, 0x00,
                                          0x00, 0x00, 0x00, 0x00)))
        conn2dst = asyncio.ensure_future(
            self.decodeCopy(dstServer, connection))
        dst2conn = asyncio.ensure_future(
            self.encodeCopy(connection, dstServer))
        task = asyncio.ensure_future(
            asyncio.gather(conn2dst, dst2conn, return_exceptions=True))
        task.add_done_callback(cleanUp)
    def test_dialRemote(self):
        async def test():
            with await self.local.dialRemote() as connection:
                await self.loop.sock_sendall(connection, self.msg)
                remoteConn, _ = await self.loop.sock_accept(self.remoteServer)
                received_msg = await self.loop.sock_recv(remoteConn, 1024)
                remoteConn.close()
                self.assertEqual(received_msg, self.msg)

        self.loop.run_until_complete(test())

        with self.assertRaises(ConnectionError):
            self.local.remoteAddr = net.Address('127.0.0.1', 0)
            self.loop.run_until_complete(self.local.dialRemote())
Beispiel #7
0
    def setUp(self):
        self.listenAddr = net.Address('127.0.0.1',
                                      random.randint(10000, 20000))

        self.dstServer = socket.socket()
        self.dstServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.dstServer.bind(('127.0.0.1', 44444))
        self.dstServer.listen(1)

        password = randomPassword()
        self.cipher = Cipher.NewCipher(password)
        self.loop = asyncio.new_event_loop()
        self.server = LsServer(loop=self.loop,
                               password=password,
                               listenAddr=self.listenAddr)
def run_server(config: lsConfig.Config):
    loop = asyncio.get_event_loop()

    listenAddr = net.Address(config.serverAddr, config.serverPort)
    server = LsServer(loop=loop,
                      password=config.password,
                      listenAddr=listenAddr)

    def didListen(address):
        print('Listen to %s:%d\n' % address)
        print('Please use:\n')
        print('''lslocal -u "http://hostname:port/#'''
              f'''{dumpsPassword(config.password)}"''')
        print('\nto config lslocal')

    asyncio.ensure_future(server.listen(didListen))
    loop.run_forever()
Beispiel #9
0
    async def handleConn(self, connection: Connection):
        """
        Handle the connection from LsLocal.
        """
        """
        SOCKS Protocol Version 5 https://www.ietf.org/rfc/rfc1928.txt
        The localConn connects to the dstServer, and sends a ver
        identifier/method selection message:
                    +----+----------+----------+
                    |VER | NMETHODS | METHODS  |
                    +----+----------+----------+
                    | 1  |    1     | 1 to 255 |
                    +----+----------+----------+
        The VER field is set to X'05' for this ver of the protocol.  The
        NMETHODS field contains the number of method identifier octets that
        appear in the METHODS field.
        """
        buf = await self.decodeRead(connection)
        if not buf or buf[0] != 0x05:
            connection.close()
            return
        """
        The dstServer selects from one of the methods given in METHODS, and
        sends a METHOD selection message:
                    +----+--------+
                    |VER | METHOD |
                    +----+--------+
                    | 1  |   1    |
                    +----+--------+
        If the selected METHOD is X'FF', none of the methods listed by the
        client are acceptable, and the client MUST close the connection.

        The values currently defined for METHOD are:

                o  X'00' NO AUTHENTICATION REQUIRED
                o  X'01' GSSAPI
                o  X'02' USERNAME/PASSWORD
                o  X'03' to X'7F' IANA ASSIGNED
                o  X'80' to X'FE' RESERVED FOR PRIVATE METHODS
                o  X'FF' NO ACCEPTABLE METHODS

        The client and server then enter a method-specific sub-negotiation.
        """
        await self.encodeWrite(connection, bytearray((0x05, 0x00)))
        """
        The SOCKS request is formed as follows:
            +----+-----+-------+------+----------+----------+
            |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
            +----+-----+-------+------+----------+----------+
            | 1  |  1  | X'00' |  1   | Variable |    2     |
            +----+-----+-------+------+----------+----------+
        Where:

          o  VER    protocol version: X'05'
          o  CMD
             o  CONNECT X'01'
             o  BIND X'02'
             o  UDP ASSOCIATE X'03'
          o  RSV    RESERVED
          o  ATYP   address type of following address
             o  IP V4 address: X'01'
             o  DOMAINNAME: X'03'
             o  IP V6 address: X'04'
          o  DST.ADDR       desired destination address
          o  DST.PORT desired destination port in network octet
             order
        """
        buf = await self.decodeRead(connection)
        if len(buf) < 7:
            connection.close()
            return

        if buf[1] != 0x01:
            connection.close()
            return

        dstIP = None

        dstPort = buf[-2:]
        dstPort = int(dstPort.hex(), 16)

        dstFamily = None

        if buf[3] == 0x01:
            # ipv4
            dstIP = socket.inet_ntop(socket.AF_INET, buf[4:4 + 4])
            dstAddress = net.Address(ip=dstIP, port=dstPort)
            dstFamily = socket.AF_INET
        elif buf[3] == 0x03:
            # domain
            dstIP = buf[5:-2].decode()
            dstAddress = net.Address(ip=dstIP, port=dstPort)
        elif buf[3] == 0x04:
            # ipv6
            dstIP = socket.inet_ntop(socket.AF_INET6, buf[4:4 + 16])
            dstAddress = (dstIP, dstPort, 0, 0)
            dstFamily = socket.AF_INET6
        else:
            connection.close()
            return

        dstServer = None
        if dstFamily:
            try:
                dstServer = socket.socket(family=dstFamily,
                                          type=socket.SOCK_STREAM)
                dstServer.setblocking(False)
                await self.loop.sock_connect(dstServer, dstAddress)
            except OSError:
                if dstServer is not None:
                    dstServer.close()
                    dstServer = None
        else:
            host, port = dstAddress
            for res in await self.loop.getaddrinfo(host, port):
                dstFamily, socktype, proto, _, dstAddress = res
                try:
                    dstServer = socket.socket(dstFamily, socktype, proto)
                    dstServer.setblocking(False)
                    await self.loop.sock_connect(dstServer, dstAddress)
                    break
                except OSError:
                    if dstServer is not None:
                        dstServer.close()
                        dstServer = None

        if dstFamily is None:
            return
        """
        The SOCKS request information is sent by the client as soon as it has
        established a connection to the SOCKS server, and completed the
        authentication negotiations.  The server evaluates the request, and
        returns a reply formed as follows:

                +----+-----+-------+------+----------+----------+
                |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
                +----+-----+-------+------+----------+----------+
                | 1  |  1  | X'00' |  1   | Variable |    2     |
                +----+-----+-------+------+----------+----------+

            Where:

                o  VER    protocol version: X'05'
                o  REP    Reply field:
                    o  X'00' succeeded
                    o  X'01' general SOCKS server failure
                    o  X'02' connection not allowed by ruleset
                    o  X'03' Network unreachable
                    o  X'04' Host unreachable
                    o  X'05' Connection refused
                    o  X'06' TTL expired
                    o  X'07' Command not supported
                    o  X'08' Address type not supported
                    o  X'09' to X'FF' unassigned
                o  RSV    RESERVED
                o  ATYP   address type of following address
        """
        await self.encodeWrite(
            connection,
            bytearray(
                (0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)))

        def cleanUp(task):
            """
            Close the socket when they succeeded or had an exception.
            """
            dstServer.close()
            connection.close()

        conn2dst = asyncio.ensure_future(self.decodeCopy(
            dstServer, connection))
        dst2conn = asyncio.ensure_future(self.encodeCopy(
            connection, dstServer))
        task = asyncio.ensure_future(
            asyncio.gather(conn2dst,
                           dst2conn,
                           loop=self.loop,
                           return_exceptions=True))
        task.add_done_callback(cleanUp)