public bool Accept(SocksConnectionInfo info)
        {
            _info = info;

            var clientEndPoint = (IPEndPoint)info.Client.Client.RemoteEndPoint;

            Console.WriteLine("New connection from {0}:{1} to {2}:{3}", clientEndPoint.Address, clientEndPoint.Port, info.DestIpAddress, info.DestPort);

            return(true);
        }
Exemple #2
0
        private void ProcessConnection(object clientObject)
        {
            //int b;
            var user   = new StringBuilder();
            var client = (TcpClient)clientObject;

            var stream = client.GetStream();

            //Version4();

            try
            {
                // Parse Version
                var version = stream.ReadByte();

                if (version == -1)
                {
                    return;
                }

                if (version != 5)
                {
                    throw new UnsupportedSocksVersionException(version);
                }


                // Parse Authentication Method
                var authMethodCount = stream.ReadByte();

                if (authMethodCount == 0)
                {
                    throw new InvalidSocksHeaderException(string.Format("Authentication Method Count was {0}", authMethodCount));
                }
                else if (authMethodCount < 0)
                {
                    return;
                }

                var authMethods = new byte[authMethodCount];
                if (!stream.ReadExactly(authMethods))
                {
                    return;
                }

                if (!authMethods.Any(x => x == (int)SocksAuthMethodCode.None))
                {
                    throw new UnsupportedSocksAuthMethodException(authMethods.Select(x => (SocksAuthMethodCode)x).ToArray());
                }

                stream.Write(_successReply, 0, _successReply.Length);


                // Parse Command Code
                var header = new byte[4];
                if (!stream.ReadExactly(header))
                {
                    return;
                }

                var info = new SocksConnectionInfo
                {
                    Proxy           = this,
                    Client          = client,
                    Version         = header[0],
                    Command         = (SocksCommandCode)header[1],
                    DestAddressType = (SocksAddressType)header[3]
                };

                if (info.Version != 5)
                {
                    throw new UnsupportedSocksVersionException(version);
                }

                if (info.Command != SocksCommandCode.Stream)
                {
                    throw new UnsupportedSocksCommandException(info.Command);
                }

                if (header[2] != 0)
                {
                    throw new InvalidSocksHeaderException(string.Format("Expected reserved field to be 0 and not {0}.", header[2]));
                }


                // Parse Destination Address Type
                switch (info.DestAddressType)
                {
                case SocksAddressType.IPv4:
                    var ipv4 = new byte[4];
                    if (!stream.ReadExactly(ipv4))
                    {
                        return;
                    }

                    info.DestIpAddress = new IPAddress(ipv4);
                    break;

                case SocksAddressType.IPv6:
                    var ipv6 = new byte[16];
                    if (!stream.ReadExactly(ipv6))
                    {
                        return;
                    }

                    info.DestIpAddress = new IPAddress(ipv6);
                    break;

                case SocksAddressType.DomainName:
                    var domainNameLen = stream.ReadByte();

                    if (domainNameLen == 0)
                    {
                        throw new InvalidSocksHeaderException(string.Format("Unexpected domain name length, {0}.", domainNameLen));
                    }
                    else if (domainNameLen < 0)
                    {
                        return;
                    }

                    var domainName = new byte[domainNameLen];

                    if (!stream.ReadExactly(domainName))
                    {
                        return;
                    }

                    info.DestDomainName = Encoding.ASCII.GetString(domainName);
                    info.DestIpAddress  = Dns.GetHostAddresses(info.DestDomainName).FirstOrDefault();

                    if (info.DestIpAddress == null)
                    {
                        throw new SocksDnsException(info.DestDomainName);
                    }
                    break;

                default:
                    throw new InvalidSocksHeaderException(string.Format("Unexpected address Type {0}.", (int)info.DestAddressType));
                }


                // Parse Destination Port
                var port = new byte[2];

                if (!stream.ReadExactly(port))
                {
                    return;
                }

                info.DestPort = port[0] * 256 + port[1];


                // Reply Success
                stream.Write(_successReply, 0, _successReply.Length);
                stream.WriteByte(0);

                var addressBytes = info.DestIpAddress.GetAddressBytes();
                stream.WriteByte((byte)(addressBytes.Length == 4 ? SocksAddressType.IPv4 : SocksAddressType.IPv6));
                stream.Write(addressBytes, 0, addressBytes.Length);
                stream.Write(port, 0, port.Length);


                var connection = _factory();

                if (!connection.Accept(info))
                {
                    return;
                }

                _connections.Add(connection);
                connection.Receive(client);
            }
            finally
            {
                client.Close();
            }
        }