#!/usr/bin/env python
# SOCKSv5 proxy server for network-sandbox
# Copyright 2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import asyncio
import errno
import os
import socket
import struct
import sys

if hasattr(asyncio, "ensure_future"):
    # Python >=3.4.4.
    asyncio_ensure_future = asyncio.ensure_future
else:
    # getattr() necessary because async is a keyword in Python >=3.7.
    asyncio_ensure_future = getattr(asyncio, "async")

try:
    current_task = asyncio.current_task
except AttributeError:
    # Deprecated since Python 3.7
    current_task = asyncio.Task.current_task


class Socks5Server:
    """
    An asynchronous SOCKSv5 server.
    """

    async def handle_proxy_conn(self, reader, writer):
        """
        Handle incoming client connection. Perform SOCKSv5 request
        exchange, open a proxied connection and start relaying.

        @param reader: Read side of the socket
        @type reader: asyncio.StreamReader
        @param writer: Write side of the socket
        @type writer: asyncio.StreamWriter
        """

        try:
            # SOCKS hello
            data = await reader.readexactly(2)
            vers, method_no = struct.unpack("!BB", data)

            if vers != 0x05:
                # disconnect on invalid packet -- we have no clue how
                # to reply in alien :)
                writer.close()
                return

            # ...and auth method list
            data = await reader.readexactly(method_no)
            for method in data:
                if method == 0x00:
                    break
            else:
                # no supported method
                method = 0xFF

            # auth reply
            repl = struct.pack("!BB", 0x05, method)
            writer.write(repl)
            await writer.drain()
            if method == 0xFF:
                writer.close()
                return

            # request
            data = await reader.readexactly(4)
            vers, cmd, rsv, atyp = struct.unpack("!BBBB", data)

            if vers != 0x05 or rsv != 0x00:
                # disconnect on malformed packet
                self.close()
                return

            # figure out if we can handle it
            rpl = 0x00
            if cmd != 0x01:  # CONNECT
                rpl = 0x07  # command not supported
            elif atyp == 0x01:  # IPv4
                data = await reader.readexactly(4)
                addr = socket.inet_ntoa(data)
            elif atyp == 0x03:  # domain name
                data = await reader.readexactly(1)
                (addr_len,) = struct.unpack("!B", data)
                addr = await reader.readexactly(addr_len)
                try:
                    addr = addr.decode("idna")
                except UnicodeDecodeError:
                    rpl = 0x04  # host unreachable

            elif atyp == 0x04:  # IPv6
                data = await reader.readexactly(16)
                addr = socket.inet_ntop(socket.AF_INET6, data)
            else:
                rpl = 0x08  # address type not supported

            # try to connect if we can handle it
            if rpl == 0x00:
                data = await reader.readexactly(2)
                (port,) = struct.unpack("!H", data)

                try:
                    # open a proxied connection
                    proxied_reader, proxied_writer = await asyncio.open_connection(
                        addr, port
                    )
                except (socket.gaierror, socket.herror):
                    # DNS failure
                    rpl = 0x04  # host unreachable
                except OSError as e:
                    # connection failure
                    if e.errno in (errno.ENETUNREACH, errno.ENETDOWN):
                        rpl = 0x03  # network unreachable
                    elif e.errno in (errno.EHOSTUNREACH, errno.EHOSTDOWN):
                        rpl = 0x04  # host unreachable
                    elif e.errno in (errno.ECONNREFUSED, errno.ETIMEDOUT):
                        rpl = 0x05  # connection refused
                    else:
                        raise
                else:
                    # get socket details that we can send back to the client
                    # local address (sockname) in particular -- but we need
                    # to ask for the whole socket since Python's sockaddr
                    # does not list the family...
                    sock = proxied_writer.get_extra_info("socket")
                    addr = sock.getsockname()
                    if sock.family == socket.AF_INET:
                        host, port = addr
                        bin_host = socket.inet_aton(host)

                        repl_addr = struct.pack("!B4sH", 0x01, bin_host, port)
                    elif sock.family == socket.AF_INET6:
                        # discard flowinfo, scope_id
                        host, port = addr[:2]
                        bin_host = socket.inet_pton(sock.family, host)

                        repl_addr = struct.pack("!B16sH", 0x04, bin_host, port)

            if rpl != 0x00:
                # fallback to 0.0.0.0:0
                repl_addr = struct.pack("!BLH", 0x01, 0x00000000, 0x0000)

            # reply to the request
            repl = struct.pack("!BBB", 0x05, rpl, 0x00)
            writer.write(repl + repl_addr)
            await writer.drain()

            # close if an error occured
            if rpl != 0x00:
                writer.close()
                return

            # otherwise, start two loops:
            # remote -> local...
            t = asyncio_ensure_future(
                self.handle_proxied_conn(proxied_reader, writer, current_task())
            )

            # and local -> remote...
            try:
                try:
                    while True:
                        data = await reader.read(4096)
                        if data == b"":
                            # client disconnected, stop relaying from
                            # remote host
                            t.cancel()
                            break

                        proxied_writer.write(data)
                        await proxied_writer.drain()
                except OSError:
                    # read or write failure
                    t.cancel()
                except:
                    t.cancel()
                    raise
            finally:
                # always disconnect in the end :)
                proxied_writer.close()
                writer.close()

        except (OSError, asyncio.IncompleteReadError, asyncio.CancelledError):
            writer.close()
            return
        except:
            writer.close()
            raise

    async def handle_proxied_conn(self, proxied_reader, writer, parent_task):
        """
        Handle the proxied connection. Relay incoming data
        to the client.

        @param reader: Read side of the socket
        @type reader: asyncio.StreamReader
        @param writer: Write side of the socket
        @type writer: asyncio.StreamWriter
        """

        try:
            try:
                while True:
                    data = await proxied_reader.read(4096)
                    if data == b"":
                        break

                    writer.write(data)
                    await writer.drain()
            finally:
                parent_task.cancel()
        except (OSError, asyncio.CancelledError):
            return


if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: %s <socket-path>" % sys.argv[0])
        sys.exit(1)

    loop = asyncio.get_event_loop()
    s = Socks5Server()
    server = loop.run_until_complete(
        asyncio.start_unix_server(s.handle_proxy_conn, sys.argv[1])
    )

    ret = 0
    try:
        try:
            loop.run_forever()
        except KeyboardInterrupt:
            pass
        except:
            ret = 1
    finally:
        server.close()
        loop.run_until_complete(server.wait_closed())
        loop.close()
        os.unlink(sys.argv[1])
