Esempio n. 1
0
File: ssws.py Progetto: bbbhere/ssws
async def websocket_handler(request):

    peername = request.transport.get_extra_info('peername')
    if peername is not None:
        host, port = peername

    loop = asyncio.get_event_loop()
    queue = asyncio.Queue(loop=loop)

    ws = web.WebSocketResponse()
    await ws.prepare(request)

    key = b'1234567890123456'  # DEFAULT PASSWORD, NEVER USE!
    key = os.environ['PASS'].encode()

    future1 = None
    future2 = None

    preaddrind = 0

    secretdata, nonce = None, None
    gotdata = None

    async for msg in ws:
        if msg.type == aiohttp.WSMsgType.BINARY:
            secretdata = msg.data[:-16]
            nonce = msg.data[-16:]
            gotdata = mydecrypt((secretdata, nonce), key)
            secretdata, nonce = None, None

            if preaddrind == 0:
                preaddrind = 1

                addrtype = gotdata[0]

                if addrtype == 3:
                    addrlen = gotdata[1]

                if addrtype == 1:
                    remotehost = socket.inet_ntoa(gotdata[1:5])
                    remoteport = struct.unpack('>H', gotdata[5:7])[0]

                if addrtype == 3:
                    remotehost = gotdata[2:2 + addrlen]
                    remoteport = struct.unpack(
                        '>H', gotdata[2 + addrlen:4 + addrlen])[0]

                    remotehost = remotehost.decode()

                if addrtype == 1 or addrtype == 3:
                    logger.debug('%r Connect to %r at address %r' %
                                 (peername, remotehost, remoteport))

                    try:
                        reader, writer = await asyncio.open_connection(
                            host=remotehost, port=remoteport)

                        future1 = asyncio.run_coroutine_threadsafe(
                            remotereader(key, reader, ws), loop)
                        future2 = asyncio.run_coroutine_threadsafe(
                            remotewriter(writer, queue), loop)

                    except Exception as e:
                        logger.debug('%r Connect remote %r at address %r' %
                                     (peername, remotehost, remoteport))
                        logger.exception(
                            'Exception while connecting remote server %r' % e)

                        senddata = b'*** remote unaccess ***'
                        encdata = myencrypt(senddata, key)
                        await ws.send_bytes(encdata[0] + encdata[1])

                        break

                else:
                    break

            else:
                await queue.put(gotdata)

        elif msg.type == aiohttp.WSMsgType.CLOSED:
            await queue.put(None)
            break

        elif msg.type == aiohttp.WSMsgType.ERROR:
            await queue.put(None)
            logger.debug('ws connection closed with exception %r' %
                         ws.exception())
            break

    if future1:
        future1.cancel()

    if future2:
        future2.cancel()

    return ws
Esempio n. 2
0
async def localproxy(reader, writer):

    addrToSend = ""

    loop = asyncio.get_event_loop()
    queue = asyncio.Queue(loop=loop)

    key = config['key'].encode()
    url = config['url']
    proxy = config['proxy']
    connectstr = ''

    client_address = writer.get_extra_info('peername')
    logger.info('client connected: %r %r' % client_address)

    get_text = await reader.read(262)

    writer.write(b'\x05\x00')
    await writer.drain()

    data = await reader.read(4)
    if len(data) == 4 and url != '':
        fullurl = 'https://' + url + '/ws'
        mode = data[1]
        addrtype = data[3]

        addrToSend = data[3:4]

        if addrtype == 1:
            ip_bytes = await reader.read(4)
            addr = socket.inet_ntoa(ip_bytes)
            addrToSend = addrToSend + ip_bytes

        elif addrtype == 3:

            addrlen_byte = await reader.read(1)
            addrlen = ord(addrlen_byte)
            addr = await reader.read(addrlen)
            addrToSend = addrToSend + addrlen_byte + addr

            addr = addr.decode()

        port = await reader.read(2)

        addrToSend = addrToSend + port

        reply = b"\x05\x00\x00\x01\x00\x00\x00\x00"

        logger.info('%r connect remote :%r %r' %
                    (client_address, addr, struct.unpack('>H', port)[0]))

        if mode != 1:
            logger.info('unsupported mode: %r' % mode)
            reply = b"\x05\x07\x00\x01"
            writer.write(reply)
            await writer.drain()
            writer.close()

        if mode == 1:

            writer.write(reply + port)
            await writer.drain()

            config['concurrent'] = config['concurrent'] + 1
            logger.info('Concurrent connetion %d' % config['concurrent'])

            async with aiohttp.ClientSession() as session:
                try:

                    wsconnectargs = {}
                    if proxy:
                        wsconnectargs['proxy'] = proxy

                    async with session.ws_connect(fullurl,
                                                  **wsconnectargs) as ws:

                        senddata = addrToSend
                        encdata = myencrypt(senddata, key)
                        await ws.send_bytes(encdata[0] + encdata[1])

                        future1 = asyncio.run_coroutine_threadsafe(
                            localreader(client_address, key, reader, ws), loop)
                        future2 = asyncio.run_coroutine_threadsafe(
                            localwriter(client_address, writer, queue), loop)

                        secretdata, nonce = None, None
                        decMsg = None

                        async for msg in ws:
                            if msg.type == aiohttp.WSMsgType.BINARY:
                                secretdata = msg.data[:-16]
                                nonce = msg.data[-16:]

                                decMsg = mydecrypt((secretdata, nonce), key)
                                secretdata, nonce = None, None

                                if decMsg != b'*** remote unaccess ***':
                                    await queue.put(decMsg)
                                else:
                                    await queue.put(None)
                                    break

                                decMsg = None

                            elif msg.type == aiohttp.WSMsgType.CLOSED:
                                break
                            elif msg.type == aiohttp.WSMsgType.ERROR:
                                logger.info(
                                    '%r ws connection closed with exception %s'
                                    % (client_address, ws.exception()))
                                break

                    future1.cancel()
                    future2.cancel()

                except aiohttp.client_exceptions.ClientConnectorError:
                    logger.info(
                        '%r ws connection time out!', client_address
                    )  #aiohttp.client_exceptions.ClientConnectorError

                config['concurrent'] = config['concurrent'] - 1
                logger.info('Concurrent connetion %d' % config['concurrent'])

    writer.close()
    gc.collect()