示例#1
0
    async def _handle_client(self, client_reader, client_writer):
        # ignore client greeting
        data = await client_reader.read(32)
        logger.debug('Ignore client greeting ({} bytes)'.format(len(data)))
        server_greeting = socks.ServerGreeting()
        client_writer.write(server_greeting.to_bytes())
        # recv CMD
        msg = await socks.Message.from_reader(client_reader)
        if msg.code is not socks.CMD.CONNECT:
            logger.warn('unhandle msg {}'.format(msg))
            return
        fut = asyncio.open_connection(msg.addr[0], msg.addr[1])
        try:
            remote_reader, remote_writer = await asyncio.wait_for(fut, 3)
        except (asyncio.TimeoutError, ConnectionRefusedError):
            logger.warn('connet {}:{} failed'.format(msg.addr[0], msg.addr[1]))
            err_reply = socks.Message(ver=socks.VER.SOCKS5,
                                      code=socks.REP.CONNECTION_REFUSED,
                                      atype=socks.ATYPE.IPV4,
                                      addr=('127.0.0.1', 9999))
            client_writer.write(err_reply.to_bytes())
            return

        logger.info('connected to {}:{}'.format(msg.addr[0], msg.addr[1]))
        # send REP
        bind_address = remote_writer.transport._extra['sockname']
        reply = socks.Message(ver=socks.VER.SOCKS5,
                              code=socks.REP.SUCCEEDED,
                              atype=socks.ATYPE.IPV4,
                              addr=bind_address)
        client_writer.write(reply.to_bytes())
        # piping
        await asyncio.gather(pipe('remote', remote_reader, client_writer),
                             pipe('user', client_reader, remote_writer))
示例#2
0
 async def connect(self, host, port):
     self.state = self.CMD
     loop = asyncio.get_event_loop()
     bind_addr = ('255.255.255.255', 0)
     try:
         logger.info('connecting {}:{}'.format(host, port))
         fut = loop.create_connection(Client, host, port)
         transport, client = await \
             asyncio.wait_for(fut, timeout=config.timeout)
     except (asyncio.TimeoutError, ConnectionRefusedError,
             socket.gaierror) as e:
         logger.warn('connect {}'.format(e))
         socks_err = socks.Message(socks.VER.SOCKS5,
                                   socks.REP.NETWORK_UNREACHABLE,
                                   socks.ATYPE.IPV4, bind_addr)
         rep = protocol.Reply(self.remote, self.user, socks_err)
         self.tunnel_transport.write(rep.to_packet(self.fuzz))
         self.state = self.IDLE
         return
     client.channel = self
     self.remote_transport = transport
     self.remote = transport._sock_fd
     bind_addr = transport.get_extra_info('sockname')
     socks_ok = socks.Message(socks.VER.SOCKS5, socks.REP.SUCCEEDED,
                              socks.ATYPE.IPV4, bind_addr)
     rep = protocol.Reply(self.remote, self.user, socks_ok)
     self.tunnel_transport.write(rep.to_packet(self.fuzz))
     self.state = self.DATA
     logger.debug('channel {} opened'.format(self))
示例#3
0
 async def _handle_user(self, user):
     # ignore client SOCKS5 greeting
     data = await user.reader.read(256)
     logger.debug('ignore SOCK5 greeting ({} bytes)'.format(len(data)))
     # response greeting without auth
     server_greeting = socks.ServerGreeting()
     await self.safe_write(user.writer, server_greeting.to_bytes())
     # recv CMD
     try:
         msg = await socks.Message.from_reader(user.reader)
     except asyncio.streams.IncompleteReadError:
         self._delete_user(user)
         return
     if msg.code is not socks.CMD.CONNECT:
         logger.warn('unhandle msg {}'.format(msg))
         rep = socks.Message(socks.VER.SOCKS5,
                             socks.REP.COMMAND_NOT_SUPPORTED,
                             socks.ATYPE.IPV4, ('0', 0))
         await self.safe_write(user.writer, rep.to_bytes())
         return
     logger.info('connecting {}:{}'.format(msg.addr[0], msg.addr[1]))
     # send to tunnel
     connect_reqeust = protocol.Request(user.user_id, 0, msg)
     await self.safe_write(self.tunnel_writer,
                           connect_reqeust.to_packet(self.fuzz))
     await self._pipe_user(user)
示例#4
0
 def data_received(self, data):
     # logger.debug('{}: {}'.format(self.user, data))
     if self.state == self.INIT:
         client_greeting = socks.ClientGreeting.from_stream(
             io.BytesIO(data))
         server_greeting = socks.ServerGreeting()
         self.transport.write(server_greeting.to_bytes())
         self.state = self.CMD
     elif self.state == self.CMD:
         msg = socks.Message.from_stream(io.BytesIO(data))
         global concurrent
         logger.info('connecting {}:{} ({})'.format(msg.addr[0],
                                                    msg.addr[1],
                                                    concurrent))
         bind_addr = ('127.0.0.1', 9999)
         if msg.code is not socks.CMD.CONNECT:
             rep = socks.Message(socks.VER.SOCKS5,
                                 socks.REP.COMMAND_NOT_SUPPORTED,
                                 socks.ATYPE.IPV4, bind_addr)
             self.transport.write(rep.to_bytes())
             return
         # connect
         asyncio.ensure_future(self.connect(msg.addr[0], msg.addr[1]))
     elif self.state == self.DATA:
         self.client_transport.write(data)
     else:
         logger.warn('receiving data from user in CLOSED state')
示例#5
0
 def test_basic(self):
     socks_msg = socks.Message(socks.VER.SOCKS5,
                               socks.REP.ADDRESS_TYPE_NOT_SUPPORTED,
                               socks.ATYPE.IPV4, ('127.0.0.1', 1234))
     m = Reply(3, 4, socks_msg)
     m1 = Reply.from_stream(io.BytesIO(m.to_bytes()))
     self.assertEqual(m.to_bytes(), m1.to_bytes())
示例#6
0
 async def connect(self, host, port):
     loop = asyncio.get_event_loop()
     bind_addr = ('127.0.0.1', 80)
     try:
         transport, client = \
             await loop.create_connection(Client, host, port)
     except asyncio.TimeoutError:
         rep = socks.Message(socks.VER.SOCKS5,
                             socks.REP.NETWORK_UNREACHABLE,
                             socks.ATYPE.IPV4, bind_addr)
         self.transport.write(rep.to_bytes())
         self.state = self.CMD
         return
     client.server_transport = self.transport
     self.client_transport = transport
     bind_addr = transport.get_extra_info('sockname')
     rep = socks.Message(socks.VER.SOCKS5, socks.REP.SUCCEEDED,
                         socks.ATYPE.IPV4, bind_addr)
     self.transport.write(rep.to_bytes())
     self.state = self.DATA
示例#7
0
 def test_corner(self):
     socks_msg = socks.Message(socks.VER.SOCKS5, socks.CMD.CONNECT,
                               socks.ATYPE.IPV4, ('127.0.0.1', 1234))
     m = Request(3, 4, socks_msg)
     self.assertRaises(ProtocolError, Reply.from_stream,
                       io.BytesIO(m.to_bytes()))
示例#8
0
 def test_basic(self):
     socks_msg = socks.Message(socks.VER.SOCKS5, socks.CMD.CONNECT,
                               socks.ATYPE.IPV4, ('127.0.0.1', 1234))
     m = Request(3, 4, socks_msg)
     m1 = Request.from_stream(io.BytesIO(m.to_bytes()))
     self.assertEqual(m.to_bytes(), m1.to_bytes())