示例#1
0
        protected override void OnRecvData(byte[] bData, int nLen)
        {
            if (nLen == 0)
            {
                OnDisconnect("Normal closing");
                return;
            }

            if (ServerSessionState == ServerSessionState.Forwarding)
            {
                try
                {
                    if (ConnectClient != null) /// connected client may be null if we are acting as a socks5 bytestream proxy, where we don't actually forward anything
                        ConnectClient.Send(bData, nLen);

                    DoAsyncRead();
                }
                catch (Exception)
                { }

                return;
            }

            ReceiveBuffer.AppendData(bData, 0, nLen);

            if (ServerSessionState == ServerSessionState.JustExisting)
            {
                DoAsyncRead(); // go read some more
                return;
            }

            byte[] bCurData = ReceiveBuffer.PeekAllSamples();

            if (bCurData.Length <= 0)
            {
                DoAsyncRead();
                return;
            }

            if (ServerSessionState == ServerSessionState.WaitingForMethodSelections)
            {
                int nVersion = bCurData[0];

                if (nVersion == 5)
                {
                    MethodSelectionsMessage msg = new MethodSelectionsMessage();
                    int nRead = msg.ReadFromBytes(bData, 0);
                    if (nRead > 0)
                    {
                        ReceiveBuffer.GetNSamples(nRead);

                        /// Determine which method we support
                        ///
                        bool bCanDoNoAuth = false;
                        foreach (SockMethod method in msg.Methods)
                        {
                            if (method == SockMethod.NoAuthenticationRequired)
                            {
                                bCanDoNoAuth = true;
                                break;
                            }
                        }

                        if (bCanDoNoAuth == false)
                        {
                            MethodSelectedMessage retmsg = new MethodSelectedMessage();
                            retmsg.Version = 5;
                            retmsg.SockMethod = SockMethod.NoAcceptableMethods;
                            this.Send(retmsg.GetBytes());
                            this.Disconnect();
                            return;
                        }
                        else
                        {
                            ServerSessionState = ServerSessionState.WaitingForSocksRequestMessage;
                            MethodSelectedMessage retmsg = new MethodSelectedMessage();
                            retmsg.Version = msg.Version;
                            retmsg.SockMethod = SockMethod.NoAuthenticationRequired;
                            this.Send(retmsg.GetBytes());
                        }
                    }
                }
                else if (nVersion == 4)
                {
                    MethodSelectionsVersionFourMessage msg = new MethodSelectionsVersionFourMessage();
                    int nRead = msg.ReadFromBytes(bData, 0);
                    if (nRead > 0)
                    {
                        ReceiveBuffer.GetNSamples(nRead);

                        MethodSelectedVersionFourMessage reply = new MethodSelectedVersionFourMessage();
                        /// See what the man wants.  It appears that mozilla immediately starts sending data if we return success here, so let's do it
                        ///
                        this.ServerSessionState = ServerSessionState.Forwarding;
                        /// Let's try to connect
                        ///
                        bool bConnected = false;
                        if (msg.DomainName != null)
                            bConnected = ConnectClient.Connect(msg.DomainName, msg.DestinationPort, true);
                        else
                            bConnected = ConnectClient.Connect(msg.DestIPAddress.ToString(), msg.DestinationPort, true);

                        if (bConnected == false)
                        {
                            reply.SOCKS4Status = SOCKS4Status.RequestRejected;
                            Send(reply.GetBytes());
                            Disconnect();
                        }
                        else
                        {
                            reply.SOCKS4Status = SOCKS4Status.RequestGranted;
                            Send(reply.GetBytes());
                        }

                    }
                }
                else
                {
                    Console.WriteLine("Version {0} not supported", nVersion);
                    MethodSelectedMessage retmsg = new MethodSelectedMessage();
                    retmsg.Version = 5;
                    retmsg.SockMethod = SockMethod.NoAcceptableMethods;
                    this.Send(retmsg.GetBytes());
                    this.Disconnect();
                    return;
                }
            }
            else if (ServerSessionState == ServerSessionState.WaitingForSocksRequestMessage)
            {
                /// Read in our SocksRequestMessage
                ///
                SocksRequestMessage reqmsg = new SocksRequestMessage();
                int nRead = reqmsg.ReadFromBytes(bData, 0);
                if (nRead > 0)
                {
                    ReceiveBuffer.GetNSamples(nRead);

                    if (reqmsg.Version != 0x05)
                        Console.WriteLine("No version 5, client wants version: {0}", reqmsg.Version);

                    //Parent.HandleRequest(reqmsg, this);
                    if (reqmsg.SOCKSCommand == SOCKSCommand.Connect)
                    {
                        /// See what the man wants.  It appears that mozilla immediately starts sending data if we return success here, so let's do it
                        ///
                        bool bConnected = false;
                        if (SOCKSServerMode == SocketServer.SOCKSServerMode.NormalSOCKS5Server)
                        {
                            this.ServerSessionState = ServerSessionState.Forwarding;
                            /// Let's try to connect
                            ///
                            if (reqmsg.AddressType == AddressType.DomainName)
                                bConnected = ConnectClient.Connect(reqmsg.DestinationDomain, reqmsg.DestinationPort, true);
                            else
                                bConnected = ConnectClient.Connect(reqmsg.DestinationAddress.ToString(), reqmsg.DestinationPort, true);
                        }
                        else
                        {
                            Console.WriteLine("SOCKS5 Bytestream connection for: {0}", reqmsg.DestinationDomain);
                            RemoteHost = reqmsg.DestinationDomain;
                            bConnected = true;
                            this.ServerSessionState = SocketServer.ServerSessionState.JustExisting;
                        }

                        SocksReplyMessage reply = new SocksReplyMessage();

                        if (bConnected == false)
                        {
                            reply.SOCKSReply = SOCKSReply.ConnectionRefused;
                        }
                        else
                        {
                            reply.SOCKSReply = SOCKSReply.Succeeded;
                        }

                        Send(reply.GetBytes());
                    }
                    else
                    {
                        SocksReplyMessage reply = new SocksReplyMessage();
                        reply.SOCKSReply = SOCKSReply.CommandNotSupported;
                        reply.AddressType = AddressType.IPV4;
                        Send(reply.GetBytes());
                    }
                }
            }

            DoAsyncRead(); // go read some more
        }
示例#2
0
        protected override void OnRecvData(byte[] bData, int nLen)
        {
            if (nLen == 0)
            {
                OnDisconnect("Normal closing");
                return;
            }

            //Console.WriteLine(string.Format("<-- {0}", ByteSize.ByteUtils.HexStringFromByte(bData, true)));

            if (ServerSessionState == ServerSessionState.Forwarding)
            {
                try
                {
                    ConnectClient.Send(bData, nLen);

                    DoAsyncRead();
                }
                catch (Exception)
                { }

                return;
            }

            ReceiveBuffer.AppendData(bData, 0, nLen);

            if (ServerSessionState == ServerSessionState.JustExisting)
            {
                DoAsyncRead(); // go read some more
                return;
            }

            byte[] bCurData = ReceiveBuffer.PeekAllSamples();

            if (bCurData.Length <= 0)
            {
                DoAsyncRead();
                return;
            }

            if (ServerSessionState == ServerSessionState.WaitingForMethodSelections)
            {
                int nVersion = bCurData[0];

                if (nVersion == 5)
                {
                    MethodSelectionsMessage msg = new MethodSelectionsMessage();
                    int nRead = msg.ReadFromBytes(bData, 0);
                    if (nRead > 0)
                    {
                        ReceiveBuffer.GetNSamples(nRead);

                        /// Determine which method we support
                        ///
                        bool bCanDoNoAuth = false;
                        foreach (SockMethod method in msg.Methods)
                        {
                            if (method == SockMethod.NoAuthenticationRequired)
                            {
                                bCanDoNoAuth = true;
                                break;
                            }
                        }

                        if (bCanDoNoAuth == false)
                        {
                            MethodSelectedMessage retmsg = new MethodSelectedMessage();
                            retmsg.Version = 5;
                            retmsg.SockMethod = SockMethod.NoAcceptableMethods;
                            this.Send(retmsg.GetBytes());
                            this.Disconnect();
                            return;
                        }
                        else
                        {
                            ServerSessionState = ServerSessionState.WaitingForSocksRequestMessage;
                            MethodSelectedMessage retmsg = new MethodSelectedMessage();
                            retmsg.Version = msg.Version;
                            retmsg.SockMethod = SockMethod.NoAuthenticationRequired;
                            this.Send(retmsg.GetBytes());
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Version {0} not supported", nVersion);
                    MethodSelectedMessage retmsg = new MethodSelectedMessage();
                    retmsg.Version = 5;
                    retmsg.SockMethod = SockMethod.NoAcceptableMethods;
                    this.Send(retmsg.GetBytes());
                    this.Disconnect();
                    return;
                }
            }
            else if (ServerSessionState == ServerSessionState.WaitingForSocksRequestMessage)
            {
                /// Read in our SocksRequestMessage
                ///
                SocksRequestMessage reqmsg = new SocksRequestMessage();
                int nRead = reqmsg.ReadFromBytes(bData, 0);
                if (nRead > 0)
                {
                    ReceiveBuffer.GetNSamples(nRead);

                    if (reqmsg.Version != 0x05)
                        Console.WriteLine("No version 5, client wants version: {0}", reqmsg.Version);

                    //Parent.HandleRequest(reqmsg, this);
                    if (reqmsg.SOCKSCommand == SOCKSCommand.Connect)
                    {
                        /// See what the man wants.  It appears that mozilla immediately starts sending data if we return success here, so let's do it
                        ///
                        this.ServerSessionState = ServerSessionState.Forwarding;
                        /// Let's try to connect
                        ///

                        /// Don't connect to a remote host in this version, just check the hash here, if it matches, send back success
                        bool bHashMatched = false;

                        //if (reqmsg.AddressType == AddressType.DomainName)
                        //    bConnected = ConnectClient.Connect(reqmsg.DestinationDomain, reqmsg.DestinationPort, true);
                        //else
                        //    bConnected = ConnectClient.Connect(reqmsg.DestinationAddress.ToString(), reqmsg.DestinationPort, true);

                        SocksReplyMessage reply = new SocksReplyMessage();

                        if (bHashMatched == false)
                        {
                            reply.SOCKSReply = SOCKSReply.ConnectionRefused;
                        }
                        else
                        {
                            reply.SOCKSReply = SOCKSReply.Succeeded;
                        }

                        Send(reply.GetBytes());
                    }
                    else
                    {
                        SocksReplyMessage reply = new SocksReplyMessage();
                        reply.SOCKSReply = SOCKSReply.CommandNotSupported;
                        reply.AddressType = AddressType.IPV4;
                        Send(reply.GetBytes());
                    }
                }
            }

            DoAsyncRead(); // go read some more
        }