Пример #1
0
        private static async Task PerformAuth(Socket socket, Socks5Options options)
        {
            /*
             +-----+------+----------+------+----------+
             | VER | ULEN | UNAME    | PLEN | PASSWD   |
             +----+-------+----------+------+----------+
             | 1  | 1     | 1 to 255 | 1    | 1 to 255 |
             +----+-------+----------+------+----------+
             */
            var buffer = ConstructAuthBuffer(options.Credentials.Username, options.Credentials.Password);
            await socket.SendAsync(buffer, SocketFlags.None);

            /*
             +----+--------+
             |VER | STATUS |
             +----+--------+
             | 1  |   1    |
             +----+--------+
             */
            var response = new byte[2];
            var read     = await socket.ReceiveAsync(response, SocketFlags.None);

            if (read != 2)
            {
                throw new SocksocketException($"Failed to perform authentication, the server sent {read} bytes.");
            }

            if (response[1] != 0)
            {
                socket.Close();
                throw new SocksocketException("Proxy authentication failed.");
            }
        }
Пример #2
0
        private static async Task SelectAuth(Socket socket, Socks5Options options)
        {
            /*
             +----+----------+----------+
             | VER | NMETHODS | METHODS |
             +----+----------+----------+
             | 1  | 1        | 1 to 255 |
             +----+----------+----------+
             */
            var buffer = new byte[4] {
                5,
                2,
                Socks5Constants.AuthMethodNoAuthenticationRequired, Socks5Constants.AuthMethodUsernamePassword
            };
            await socket.SendAsync(buffer, SocketFlags.None);

            /*
             +-----+--------+
             | VER | METHOD |
             +-----+--------+
             | 1   | 1      |
             +-----+--------+
             */
            var response = new byte[2];
            var read     = await socket.ReceiveAsync(response, SocketFlags.None);

            if (read != 2)
            {
                throw new SocksocketException($"Failed to select an authentication method, the server sent {read} bytes.");
            }

            if (response[1] == Socks5Constants.AuthMethodReplyNoAcceptableMethods)
            {
                socket.Close();
                throw new SocksocketException("The proxy destination does not accept the supported proxy client authentication methods.");
            }

            if (response[1] == Socks5Constants.AuthMethodUsernamePassword && options.Auth == AuthType.None)
            {
                socket.Close();
                throw new SocksocketException("The proxy destination requires a username and password for authentication.");
            }

            if (response[1] == Socks5Constants.AuthMethodNoAuthenticationRequired)
            {
                return;
            }

            await PerformAuth(socket, options);
        }
Пример #3
0
        public static async Task <Socket> Connect(Func <Socket> socketFactory, Socks5Options options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var socket = socketFactory();
            await socket.ConnectAsync(options.ProxyHost, options.ProxyPort);

            await SelectAuth(socket, options);
            await Connect(socket, options);

            return(socket);
        }
Пример #4
0
        private static async Task Connect(Socket socket, Socks5Options options)
        {
            /*
             +-----+-----+-------+------+----------+----------+
             | VER | CMD | RSV   | ATYP | DST.ADDR | DST.PORT |
             +--- -+-----+-------+------+----------+----------+
             | 1   | 1   | X'00' | 1    | Variable | 2        |
             +-----+-----+-------+------+----------+----------+
             */

            var addressType = GetDestAddressType(options.DestinationHost);
            var destAddr    = GetDestAddressBytes(addressType, options.DestinationHost);
            var destPort    = GetDestPortBytes(options.DestinationPort);

            var buffer = new byte[6 + options.DestinationHost.Length];

            buffer[0] = 5;
            buffer[1] = Socks5Constants.CmdConnect;
            buffer[2] = Socks5Constants.Reserved;
            buffer[3] = addressType;
            destAddr.CopyTo(buffer, 4);
            destPort.CopyTo(buffer, 4 + destAddr.Length);

            await socket.SendAsync(buffer, SocketFlags.None);

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

            var response = new byte[255];
            await socket.ReceiveAsync(response, SocketFlags.None);

            if (response[1] != Socks5Constants.CmdReplySucceeded)
            {
                HandleProxyCommandError(response, options.DestinationHost, options.DestinationPort);
            }
        }