示例#1
0
        public void ParsePack(byte[] bPack)
        {
            switch (this.Phase)
            {
            case Socks5Request.Socks5Phase.spGreeting:
                if (bPack[0] != 5)
                {
                    throw new ProxyAuthException(403, "Only Socks5 response are supported");
                }
                if (bPack[1] == 0xFF)
                {
                    throw new ProxyAuthException(0xFF, "Authentication method not supported");
                }

                if (this.Anonymous = bPack[1] == 0)
                {
                    this.Phase = Socks5Request.Socks5Phase.spConnecting;
                }
                else
                {
                    this.Phase = Socks5Request.Socks5Phase.spAuthenticating;
                }
                break;

            case Socks5Request.Socks5Phase.spAuthenticating:
                if (bPack[0] != 1)
                {
                    throw new ProxyAuthException(403, "Only Socks5 response are supported");
                }

                this.Phase = Socks5Request.Socks5Phase.spConnecting;

                this.Status = (ResponseStatus)bPack[1];
                if (this.Status != ResponseStatus.Success)
                {
                    throw new ProxyAuthException((int)this.Status, this.Status.ToDescription());
                }
                break;

            case Socks5Request.Socks5Phase.spConnecting:
                if (bPack[0] != 5)
                {
                    throw new ProxyAuthException(403, "Only Socks5 response are supported");
                }

                int        offset = 4;
                IPEndPoint ipe;
                Socks4Request.PackOut(bPack, ref offset, out ipe);
                this.RemoteEndPoint = ipe;
                break;
            }
        }
示例#2
0
        public void ParsePack(byte[] bPack)
        {
            if (bPack[0] != 0x00)
            {
                throw new ProxyAuthException(403, "Only Socks4/4a response are supported");
            }

            var response = this;

            response.Status = (ResponseStatus)bPack[1];

            int        offset = 2;
            IPEndPoint ipe;

            Socks4Request.PackOut(bPack, ref offset, out ipe, false);
            response.RemoteEndPoint = ipe;

            if (response.Status != Socks4Response.ResponseStatus.RequestGranted)
            {
                throw new ProxyAuthException((int)response.Status, response.Status.ToDescription());
            }
        }
示例#3
0
        private void UdpDirectReceive(object state)
        {
            var controlClient = (TcpClient)state;

            if (!controlClient.Connected)
            {
                return;
            }
            IPEndPoint remoteIpe = null;

            try
            {
                var currentState = this.GetUdpClientState(controlClient);
                //Udp无连接先发送后接收
                currentState.WaitOnce();
                var tunnel = this.CreateTunnel(TunnelCommand.UdpReceive, controlClient);
                tunnel.SendReceiveTimeout = Timeout.Infinite;
                var response = tunnel.GetResponse(webResponse =>
                {
                    var pushStream = webResponse.GetResponseStream();
                    byte[] data    = new byte[(int)BufferSizeof.MaxSocket];
                    //00 00 00 01
                    data[3] = 1;
                    while (controlClient.Connected && pushStream.CanRead)
                    {
                        try
                        {
                            int offset = 4;
                            int read   = pushStream.Read(data, offset, data.Length - offset);
                            if (read == 0 || !(controlClient.Connected && pushStream.CanRead))
                            {
                                break;
                            }
                            //4-10 中间6字节为remoteIpe
                            Socks4Request.PackOut(data, ref offset, out remoteIpe);
                            if (!currentState.HasRemoteEndPoint(remoteIpe))
                            {
                                this.OutWrite("Udp Receive Discard {0} {1}bytes.", remoteIpe, read);
                                App.LogInfo("Udp Receive Discard 非法远程端点.");
                                continue;
                            }

                            int length = 4 + read;
                            int sent   = currentState.Client.Send(data, length, currentState.LocalEndPoint);
                            if (length != sent)
                            {
                                throw new InvalidOperationException("Udp数据包错误");
                            }
                            this.OutWrite("Udp {0} Receive {1}\t{2}bytes.", currentState.LocalEndPoint, remoteIpe, read);
                        }
                        catch (ObjectDisposedException ex)
                        {
#if DEBUG
                            App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace));
#endif
                            return;
                        }
                        catch (IOException ex)
                        {
                            TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectReceive={0}", remoteIpe));
                        }
                        catch (SocketException ex)
                        {
                            TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectReceive={0}", remoteIpe));
                        }
                    }
                });
                response.Close();
            }
            catch (WebException ex)
            {
                bool isRejected;
                TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectReceive={0}", remoteIpe), _output, out isRejected);
                if (isRejected)
                {
                    this.OnServerRejected();
                }
            }
            catch (Exception ex)
            {
                TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectReceive={0}", remoteIpe));
            }
        }
示例#4
0
        private void UdpDirectSend(object state)
        {
            var controlClient = (TcpClient)state;

            if (!controlClient.Connected)
            {
                return;
            }
            string destIpe = null;

            try
            {
                var currentState = this.GetUdpClientState(controlClient);
                while (controlClient.Connected)
                {
                    try
                    {
                        var    localIpe = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);
                        byte[] data     = currentState.Client.Receive(ref localIpe);
                        if (!controlClient.Connected)
                        {
                            break;
                        }
                        if (data.IsNullOrEmpty() || !(data[0] == 0 && data[1] == 0 && data[2] == 0))
                        {
                            this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length);
                            App.LogInfo("Udp Send Discard 非法数据包.");
                            continue;
                        }
                        else if (!currentState.LocalEndPoint.Equals(localIpe))
                        {
                            this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length);
                            App.LogInfo("Udp Send Discard 非法本地端点.");
                            continue;
                        }

                        int offset = 4;
                        if (data[3] == 3)
                        {
                            DnsEndPoint de;
                            Socks4Request.PackOut(data, ref offset, out de);
                            currentState.AddRemoteEndPoint(de);
                            destIpe = string.Format("{0}:{1}", de.Host, de.Port);
                        }
                        else
                        {
                            IPEndPoint ipe;
                            Socks4Request.PackOut(data, ref offset, out ipe);
                            currentState.AddRemoteEndPoint(ipe);
                            destIpe = ipe.ToString();
                        }
                        var tunnel = this.CreateTunnel(TunnelCommand.UdpSend, controlClient);
                        tunnel.Headers[xHttpHandler.AgentDirect] = destIpe;
                        var outStream = new MemoryStream(data, offset, data.Length - offset);
#if DEBUG
                        tunnel.Form[xHttpHandler.AgentChecksum] = CryptoManaged.MD5Hash(outStream).ToString();
                        outStream.Position = 0L;
#endif
                        tunnel.Files.Add(new HttpFileContent(xHttpHandler.AgentDirect, xHttpHandler.AgentDirect, outStream));
                        var response = tunnel.GetResponse();
                        if (response.GetResponseText() != "1")
                        {
                            this.OutWrite("Udp {0} Send {1}\t{2}bytes failure.", currentState.LocalEndPoint, destIpe, outStream.Length);
                            return;
                        }
                        this.OutWrite("Udp {0} Send {1}\t{2}bytes.", currentState.LocalEndPoint, destIpe, outStream.Length);

                        //开始接收数据
                        currentState.SetOnce();
                    }
                    catch (ObjectDisposedException ex)
                    {
#if DEBUG
                        App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace));
#endif
                    }
                    catch (WebException ex)
                    {
                        bool isRejected;
                        if (TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe), _output, out isRejected))
                        {
                            controlClient.Client.Close();
                        }
                        if (isRejected)
                        {
                            this.OnServerRejected();
                        }
                    }
                    catch (SocketException ex)
                    {
                        if (ex.SocketErrorCode == SocketError.Interrupted)
                        {
#if DEBUG
                            App.LogInfo(string.Format("Predictable interrupted exception: {0}", ex.Message));
#endif
                            return;
                        }
                        TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectSend={0}", destIpe));
                    }
                }
            }
            catch (Exception ex)
            {
                TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe));
            }
        }
示例#5
0
        public void ParsePack(byte[] bPack)
        {
            switch (this.Phase)
            {
            case Socks5Phase.spGreeting:
            {
                if (bPack[0] != 5)
                {
                    throw new ProxyAuthException(403, "Only Socks5 request are supported");
                }

                //要求匿名代理
                if (bPack[1] == 1 && bPack[2] == 0)
                {
                    this.Credential = null;
                    this.Phase      = Socks5Phase.spConnecting;
                }
                //要求匿名或用户名密码代理
                else
                {
                    this.Credential = new NetworkCredential();
                    this.Phase      = Socks5Phase.spAuthenticating;
                }
            }
            break;

            case Socks5Phase.spAuthenticating:
            {
                if (bPack[0] != 1)
                {
                    throw new ProxyAuthException(403, "Only Socks5 request are supported");
                }
                if (this.Credential == null)
                {
                    throw new ProxyAuthException(403, "Socks5Phase.spAuthenticating");
                }

                int length = Convert.ToInt32(bPack[1]);
                this.Credential.UserName = Encoding.ASCII.GetString(bPack, 2, length);

                int offset = 2 + length;
                length = Convert.ToInt32(bPack[offset]);
                this.Credential.Password = Encoding.ASCII.GetString(bPack, offset + 1, length);
                this.Phase = Socks5Phase.spConnecting;
            }
            break;

            case Socks5Phase.spConnecting:
            {
                if (bPack[0] != 5 || bPack[2] != 0)
                {
                    throw new ProxyAuthException(403, "Only Socks5 request are supported");
                }

                this.Command = (Socks5Command)bPack[1];

                int offset = 4;
                if (bPack[3] == 3)
                {
                    DnsEndPoint de;
                    Socks4Request.PackOut(bPack, ref offset, out de);
                    this.EndPoint = de;
                }
                else
                {
                    IPEndPoint ipe;
                    Socks4Request.PackOut(bPack, ref offset, out ipe);
                    this.EndPoint = ipe;
                }
            }
            break;
            }
        }