예제 #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 == 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("Incoming SOCKS5 Bytestream Connect command to domain: {0}, remote endppoint is: {1}", reqmsg.DestinationDomain, this.socket.RemoteEndPoint);
                            RemoteHost = reqmsg.DestinationDomain;
                            bConnected = true;
                            this.ServerSessionState = 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
        public bool HandleReceiveData(byte[] bRecv)
        {
            ReceiveBuffer.AppendData(bRecv);
            byte[] bAllData = ReceiveBuffer.PeekAllSamples();

            /// Recieve our response
            ///
            if (SocksVersion == 4)
            {
                MethodSelectedVersionFourMessage msg = new MethodSelectedVersionFourMessage();
                int nRead = msg.ReadFromBytes(bAllData, 0);
                if (nRead > 0)
                {
                    ReceiveBuffer.GetNSamples(nRead);
                    if (msg.SOCKS4Status == SOCKS4Status.RequestGranted)
                    {
                        return(true);
                    }
                    else
                    {
                        throw new Exception("Failed to negotiate a SOCKS4 session");
                    }
                }
                return(false);
            }
            else if (SocksVersion == 5)
            {
                if (SOCKS5ClientSessionState == SOCKS5ClientSessionState.WaitingForMethodSelected)
                {
                    MethodSelectedMessage msg = new MethodSelectedMessage();
                    int nRead = msg.ReadFromBytes(bAllData, 0);
                    if (nRead > 0)
                    {
                        ReceiveBuffer.GetNSamples(nRead);
                        if (msg.SockMethod != SockMethod.NoAuthenticationRequired)
                        {
                            throw new Exception("Failed to negotiate a SOCKS5 session");
                        }

                        SOCKS5ClientSessionState = SOCKS5ClientSessionState.WaitingForFinalResponse;

                        /// We're happy, send our connect request
                        SocksRequestMessage req = new SocksRequestMessage();
                        req.AddressType       = AddressType.DomainName;
                        req.DestinationDomain = RemoteHost;
                        req.DestinationPort   = (ushort)RemotePort;
                        req.Version           = 0x05;
                        req.SOCKSCommand      = SOCKSCommand.Connect;
                        byte[] bMsg = req.GetBytes();
                        Send(bMsg);
                    }
                    return(false);
                }
                else if (SOCKS5ClientSessionState == SOCKS5ClientSessionState.WaitingForFinalResponse)
                {
                    SocksReplyMessage msg = new SocksReplyMessage();
                    int nRead             = msg.ReadFromBytes(bAllData, 0);
                    if (nRead > 0)
                    {
                        ReceiveBuffer.GetNSamples(nRead);
                        if (msg.SOCKSReply == SOCKSReply.Succeeded)
                        {
                            return(true);
                        }
                        else
                        {
                            throw new Exception(string.Format("Failed to negotiate a SOCKS5 session, error: {0}", msg.SOCKSReply));
                        }
                    }
                    return(false);
                }

                return(false);
            }
            else
            {
                throw new Exception("Unsupported Version");
            }
        }