Exemplo n.º 1
0
        public static async Task <StreamSocket> ConnectToSocks5Proxy(double timeout, StreamSocket s, DataWriter _dataWriter, DataReader _dataReader, string proxyAddress, ushort proxyPort, string destAddress, ushort destPort, string userName, string password)
        {
            var    destIP   = new HostName(destAddress);
            var    proxyIP  = new HostName(proxyAddress);
            var    request  = new byte[256];
            var    response = new byte[256];
            ushort nIndex;

            // open a TCP connection to SOCKS server...
            //Connect(s, proxyEndPoint);
            await s.ConnectAsync(proxyIP, proxyPort.ToString(CultureInfo.InvariantCulture)).WithTimeout(timeout);

            nIndex            = 0;
            request[nIndex++] = 0x05; // Version 5.
            request[nIndex++] = 0x02; // 2 Authentication methods are in packet...
            request[nIndex++] = 0x00; // NO AUTHENTICATION REQUIRED
            request[nIndex++] = 0x02; // USERNAME/PASSWORD

            Send(_dataWriter, request, 0, nIndex);
            var nGot = Receive(_dataReader, response, 0, response.Length);

            // Receive 2 byte response...
            if (nGot != 2)
            {
                throw new ConnectionException("Bad response received from proxy server.");
            }

            if (response[1] == 0xFF)
            {    // No authentication method was accepted close the socket.
                s.Dispose();
                throw new ConnectionException("None of the authentication method was accepted by proxy server.");
            }

            byte[] rawBytes;
            //Username/Password Authentication protocol
            if (response[1] == 0x02)
            {
                nIndex            = 0;
                request[nIndex++] = 0x01; // Version 5.

                // add user name
                request[nIndex++] = (byte)userName.Length;
                rawBytes          = Encoding.UTF8.GetBytes(userName);
                rawBytes.CopyTo(request, nIndex);
                nIndex += (ushort)rawBytes.Length;

                // add password
                request[nIndex++] = (byte)password.Length;
                rawBytes          = Encoding.UTF8.GetBytes(password);
                rawBytes.CopyTo(request, nIndex);
                nIndex += (ushort)rawBytes.Length;

                // Send the Username/Password request
                Send(_dataWriter, request, 0, nIndex);
                nGot = Receive(_dataReader, response, 0, response.Length);

                if (nGot != 2)
                {
                    throw new ConnectionException("Bad response received from proxy server.");
                }
                if (response[1] != 0x00)
                {
                    throw new ConnectionException("Bad Usernaem/Password.");
                }
            }
            //// This version only supports connect command.
            //// UDP and Bind are not supported.

            // Send connect request now...
            nIndex            = 0;
            request[nIndex++] = 0x05;    // version 5.
            request[nIndex++] = 0x01;    // command = connect.
            request[nIndex++] = 0x00;    // Reserve = must be 0x00

            // Destination adress in an IP.
            switch (destIP.Type)
            {
            case HostNameType.Ipv4:
                // Address is IPV4 format
                request[nIndex++] = 0x01;
                rawBytes          = destIP.GetAddressBytes();
                rawBytes.CopyTo(request, nIndex);
                nIndex += (ushort)rawBytes.Length;
                break;

            case HostNameType.Ipv6:
                // Address is IPV6 format
                request[nIndex++] = 0x04;
                rawBytes          = destIP.GetAddressBytes();
                rawBytes.CopyTo(request, nIndex);
                nIndex += (ushort)rawBytes.Length;
                break;
                //case HostNameType.DomainName:
                //    // Dest. address is domain name.
                //    request[nIndex++] = 0x03;    // Address is full-qualified domain name.
                //    request[nIndex++] = Convert.ToByte(destAddress.Length); // length of address.
                //    rawBytes = Encoding.UTF8.GetBytes(destAddress);
                //    rawBytes.CopyTo(request, nIndex);
                //    nIndex += (ushort)rawBytes.Length;
                //    break;
            }

            // using big-edian byte order
            byte[] portBytes = BitConverter.GetBytes(destPort);
            for (int i = portBytes.Length - 1; i >= 0; i--)
            {
                request[nIndex++] = portBytes[i];
            }

            // send connect request.
            Send(_dataWriter, request, 0, nIndex);
            nGot = Receive(_dataReader, response, 0, response.Length);

            if (response[1] != 0x00)
            {
                throw new ConnectionException(errorMsgs[response[1]]);
            }

            // Success Connected...
            return(s);
        }