Exemple #1
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="PeaRoxyClient" /> class.
 /// </summary>
 /// <param name="client">
 ///     The client's socket.
 /// </param>
 /// <param name="parent">
 ///     The parent controller object.
 /// </param>
 /// <param name="encType">
 ///     The sending encryption type.
 /// </param>
 /// <param name="comTypes">
 ///     The sending compression type.
 /// </param>
 /// <param name="receivePacketSize">
 ///     The receiving packet size.
 /// </param>
 /// <param name="sendPacketSize">
 ///     The sending packet size.
 /// </param>
 /// <param name="selectedAuthMode">
 ///     The selected authentication mode.
 /// </param>
 /// <param name="noDataTimeout">
 ///     The no data timeout value.
 /// </param>
 /// <param name="clientSupportedEncryptionType">
 ///     The supported client encryption types.
 /// </param>
 /// <param name="clientSupportedCompressionType">
 ///     The supported client compression types.
 /// </param>
 public PeaRoxyClient(
     Socket client,
     PeaRoxyController parent,
     Common.EncryptionTypes encType   = Common.EncryptionTypes.None,
     Common.CompressionTypes comTypes = Common.CompressionTypes.None,
     int receivePacketSize            = 8192,
     int sendPacketSize = 1024,
     Common.AuthenticationMethods selectedAuthMode = Common.AuthenticationMethods.Invalid,
     int noDataTimeout = 6000,
     Common.EncryptionTypes clientSupportedEncryptionType   = Common.EncryptionTypes.None | Common.EncryptionTypes.SimpleXor | Common.EncryptionTypes.TripleDes,
     Common.CompressionTypes clientSupportedCompressionType = Common.CompressionTypes.None | Common.CompressionTypes.GZip | Common.CompressionTypes.Deflate)
 {
     this.Username         = "******"; // Use Anonymous as temporary user name until client introduce it-self
     this.CurrentStage     = RequestStages.JustConnected;
     this.SelectedAuthMode = selectedAuthMode;
     this.NoDataTimeout    = noDataTimeout;
     this.Controller       = parent;
     this.UnderlyingSocket = client;
     this.UnderlyingSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DontFragment, true);
     this.UnderlyingSocket.Blocking         = false;
     this.underlyingClientEncryption        = encType;
     this.underlyingClientCompression       = comTypes;
     this.ClientSupportedEncryptionType     = clientSupportedEncryptionType;
     this.ClientSupportedCompressionType    = clientSupportedCompressionType;
     this.underlyingClientReceivePacketSize = receivePacketSize;
     this.underlyingClientSendPacketSize    = sendPacketSize;
     this.currentTimeout = this.NoDataTimeout * 1000;
 }
Exemple #2
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="PeaRoxyProtocol" /> class.
        /// </summary>
        /// <param name="client">
        ///     The underlying socket.
        /// </param>
        /// <param name="encType">
        ///     The encryption type.
        /// </param>
        /// <param name="comType">
        ///     The compression type.
        /// </param>
        public PeaRoxyProtocol(
            Socket client,
            Common.EncryptionTypes encType  = Common.EncryptionTypes.None,
            Common.CompressionTypes comType = Common.CompressionTypes.None)
        {
            this.encryptionType  = encType;
            this.compressionType = comType;
            switch (this.compressionType)
            {
            case Common.CompressionTypes.GZip:
                this.compressor = new GZipCompressor();
                break;

            case Common.CompressionTypes.Deflate:
                this.compressor = new DeflateCompressor();
                break;
            }

            this.ReceivePacketSize              = 8192;
            this.SendPacketSize                 = 8192;
            this.PocketSent                     = 0;
            this.PocketReceived                 = 0;
            this.ClientSupportedEncryptionType  = Common.EncryptionTypes.None | Common.EncryptionTypes.SimpleXor | Common.EncryptionTypes.TripleDes;
            this.ClientSupportedCompressionType = Common.CompressionTypes.None | Common.CompressionTypes.GZip | Common.CompressionTypes.Deflate;
            this.UnderlyingSocket               = client;
            this.UnderlyingSocket.Blocking      = false;
        }
Exemple #3
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="PeaRoxy" /> class.
        /// </summary>
        /// <param name="address">
        ///     The server address.
        /// </param>
        /// <param name="port">
        ///     The server port.
        /// </param>
        /// <param name="domain">
        ///     The server domain identifier.
        /// </param>
        /// <param name="username">
        ///     The user name to authenticate, leave empty for no authentication.
        /// </param>
        /// <param name="password">
        ///     The password to authenticate, leave empty for no authentication.
        /// </param>
        /// <param name="encType">
        ///     The client encryption type.
        /// </param>
        /// <param name="comTypes">
        ///     The client compression type.
        /// </param>
        /// <exception cref="ArgumentException">
        ///     Invalid server address, port number, encryption or compression type
        /// </exception>
        public PeaRoxy(
            string address,
            ushort port,
            string domain,
            string username = "",
            string password = "",
            Common.EncryptionTypes encType   = Common.EncryptionTypes.None,
            Common.CompressionTypes comTypes = Common.CompressionTypes.None)
        {
            if (string.IsNullOrEmpty(address))
            {
                throw new ArgumentException(@"Invalid value.", "address");
            }

            IPAddress ip;

            if (IPAddress.TryParse(address, out ip))
            {
                address = ip.ToString();
            }
            else
            {
                try
                {
                    ip      = Dns.GetHostAddresses(address)[0];
                    address = ip.ToString();
                }
                catch
                {
                }
            }

            this.ServerDomain = domain.ToLower().Trim();

            this.IsServerValid    = false;
            this.ServerAddress    = address;
            this.ServerPort       = port;
            this.Username         = username;
            this.Password         = password;
            this.encryptionType   = encType;
            this.compressionTypes = comTypes;
            this.NoDataTimeout    = 60;
            this.IsDataSent       = false;
            this.IsClosed         = false;
        }
Exemple #4
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="PeaRoxyWeb" /> class.
        /// </summary>
        /// <param name="address">
        ///     The address of the server script.
        /// </param>
        /// <param name="username">
        ///     The user name to authenticate, leave empty for no authentication.
        /// </param>
        /// <param name="password">
        ///     The password to authenticate, leave empty for no authentication.
        /// </param>
        /// <param name="encType">
        ///     The client encryption type.
        /// </param>
        /// <param name="addressChecked">
        ///     The address checked boolean shows if we already sure about the script address or if we need to try and get the
        ///     correct address our-self.
        /// </param>
        /// <exception cref="ArgumentException">
        ///     Invalid server address or encryption type
        /// </exception>
        public PeaRoxyWeb(
            string address,
            string username = "",
            string password = "",
            Common.EncryptionTypes encType = Common.EncryptionTypes.None,
            bool addressChecked            = false)
        {
            if (string.IsNullOrEmpty(address))
            {
                throw new ArgumentException(@"Invalid value.", "address");
            }

            if (encType != Common.EncryptionTypes.SimpleXor && encType != Common.EncryptionTypes.None)
            {
                throw new ArgumentException(@"Invalid value.", "encType");
            }

            this.IsServerValid = false;
            this.ServerUri     = new Uri(address);

            if (!addressChecked)
            {
                HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create(this.ServerUri);
                wreq.AllowAutoRedirect = true;
                wreq.Proxy             = null;
                wreq.Method            = "HEAD";
                wreq.Headers.Add("X-Requested-With", "NOREDIRECT");
                HttpWebResponse wres = (HttpWebResponse)wreq.GetResponse();
                wres.Close();
                if (wres.StatusCode != HttpStatusCode.OK)
                {
                    throw new ArgumentException(@"Server responded with status code " + wres.StatusCode, "address");
                }

                this.ServerUri = wres.ResponseUri;
            }

            this.Username       = username;
            this.Password       = password;
            this.encryptionType = encType;
            this.NoDataTimeout  = 60;
            this.IsDataSent     = false;
            this.IsClosed       = false;
        }
Exemple #5
0
        /// <summary>
        ///     This method let us know if there is new data available to read from the underlying client. Should be executed
        ///     repeatedly.
        /// </summary>
        /// <param name="syncWait">
        ///     Indicates if we should wait until we have something to read.
        /// </param>
        /// <returns>
        ///     Indicates if we have new data available to read.
        /// </returns>
        public bool IsDataAvailable(bool syncWait = false)
        {
            try
            {
                if ((this.UnderlyingSocket.Available > 0 || syncWait) && this.waitingBuffer.Length == 0)
                {
                    int i = 10;

                    // Time out by second, This timeout is about the max seconds that we wait for something if we don't have anything
                    i = i * 1000;
                    int    i2     = i;
                    byte[] buffer = new byte[0];
                    while (i > 0)
                    {
                        if (!Common.IsSocketConnected(this.UnderlyingSocket))
                        {
                            this.Close();
                            return(false);
                        }

                        if (this.UnderlyingSocket.Available > 0)
                        {
                            i = i2;
                            int bufferLastLength = buffer.Length;
                            Array.Resize(ref buffer, bufferLastLength + this.ReceivePacketSize);
                            int bytes = this.UnderlyingSocket.Receive(
                                buffer,
                                bufferLastLength,
                                buffer.Length - bufferLastLength,
                                SocketFlags.None);
                            if (bytes == 0)
                            {
                                this.Close();
                                return(false);
                            }

                            Array.Resize(ref buffer, bytes + bufferLastLength);
                            bool doNext = true;
                            while (doNext)
                            {
                                doNext = false;
                                if (this.neededBytes == 0)
                                {
                                    if (this.workingBuffer.Length > 0)
                                    {
                                        if (!this.ClientSupportedEncryptionType.HasFlag(this.peerEncryptionType))
                                        {
                                            // Check if we support this type of encryption
                                            this.Close("Protocol 1. Unsupported encryption type.");
                                            return(false);
                                        }

                                        if (this.peerEncryptionType != Common.EncryptionTypes.None)
                                        {
                                            this.peerCryptor.SetSalt(this.pearEncryptionSalt);
                                            this.workingBuffer = this.peerCryptor.Decrypt(this.workingBuffer);
                                        }

                                        if (!this.ClientSupportedCompressionType.HasFlag(this.peerCompressionType))
                                        {
                                            // Check if we support this type of compression
                                            this.Close("Protocol 2. Unsupported compression type.");
                                            return(false);
                                        }

                                        this.workingBuffer = this.peerCompressor.Decompress(this.workingBuffer);

                                        Array.Resize(
                                            ref this.waitingBuffer,
                                            this.waitingBuffer.Length + this.workingBuffer.Length);
                                        Array.Copy(
                                            this.workingBuffer,
                                            0,
                                            this.waitingBuffer,
                                            this.waitingBuffer.Length - this.workingBuffer.Length,
                                            this.workingBuffer.Length);
                                        this.workingBuffer = new byte[0];
                                    }

                                    if (buffer.Length >= 10)
                                    {
                                        if (this.PocketReceived == 65535)
                                        {
                                            this.PocketReceived = 0;
                                        }

                                        if ((Common.CompressionTypes)buffer[1] != this.peerCompressionType)
                                        {
                                            this.peerCompressionType = (Common.CompressionTypes)buffer[1];
                                            switch (this.peerCompressionType)
                                            {
                                            case Common.CompressionTypes.GZip:
                                                this.peerCompressor = new GZipCompressor();
                                                break;

                                            case Common.CompressionTypes.Deflate:
                                                this.peerCompressor = new DeflateCompressor();
                                                break;
                                            }
                                        }

                                        int receiveCounter = (buffer[2] * 256) + buffer[3];
                                        this.neededBytes = (buffer[4] * 256) + buffer[5];
                                        Array.Copy(buffer, 6, this.pearEncryptionSalt, 0, 4);
                                        if ((Common.EncryptionTypes)buffer[0] != this.peerEncryptionType)
                                        {
                                            this.peerEncryptionType = (Common.EncryptionTypes)buffer[0];

                                            switch (this.peerEncryptionType)
                                            {
                                            case Common.EncryptionTypes.TripleDes:
                                                if (this.EncryptionKey.Length == 0)
                                                {
                                                    this.EncryptionKey = this.pearEncryptionSalt;
                                                }
                                                this.peerCryptor = new TripleDesCryptor(this.encryptionKey);
                                                break;

                                            case Common.EncryptionTypes.SimpleXor:
                                                if (this.EncryptionKey.Length == 0)
                                                {
                                                    this.EncryptionKey = this.pearEncryptionSalt;
                                                }
                                                this.peerCryptor = new SimpleXorCryptor(this.encryptionKey);
                                                break;
                                            }
                                        }

                                        if (receiveCounter != this.PocketReceived)
                                        {
                                            this.Close(
                                                "Protocol 3. Packet lost, Last received packet: " + receiveCounter
                                                + ", Expected: " + this.PocketReceived);
                                            return(false);
                                        }

                                        this.PocketReceived++;
                                        if (this.neededBytes <= buffer.Length - 10)
                                        {
                                            Array.Resize(
                                                ref this.workingBuffer,
                                                this.workingBuffer.Length + this.neededBytes);
                                            Array.Copy(buffer, 10, this.workingBuffer, 0, this.neededBytes);

                                            Array.Copy(
                                                buffer,
                                                10 + this.neededBytes,
                                                buffer,
                                                0,
                                                (buffer.Length - 10) - this.neededBytes);
                                            Array.Resize(ref buffer, (buffer.Length - 10) - this.neededBytes);
                                            this.neededBytes = 0;
                                            doNext           = true;
                                        }
                                        else
                                        {
                                            Array.Resize(
                                                ref this.workingBuffer,
                                                this.workingBuffer.Length + (buffer.Length - 10));
                                            Array.Copy(buffer, 10, this.workingBuffer, 0, buffer.Length - 10);
                                            this.neededBytes -= buffer.Length - 10;
                                            buffer            = new byte[0];
                                        }
                                    }
                                }
                                else
                                {
                                    if (buffer.Length > 0)
                                    {
                                        if (this.neededBytes <= buffer.Length)
                                        {
                                            Array.Resize(
                                                ref this.workingBuffer,
                                                this.workingBuffer.Length + this.neededBytes);
                                            Array.Copy(
                                                buffer,
                                                0,
                                                this.workingBuffer,
                                                this.workingBuffer.Length - this.neededBytes,
                                                this.neededBytes);

                                            Array.Copy(
                                                buffer,
                                                this.neededBytes,
                                                buffer,
                                                0,
                                                buffer.Length - this.neededBytes);
                                            Array.Resize(ref buffer, buffer.Length - this.neededBytes);
                                            this.neededBytes = 0;
                                            doNext           = true;
                                        }
                                        else
                                        {
                                            Array.Resize(
                                                ref this.workingBuffer,
                                                this.workingBuffer.Length + buffer.Length);
                                            Array.Copy(
                                                buffer,
                                                0,
                                                this.workingBuffer,
                                                this.workingBuffer.Length - buffer.Length,
                                                buffer.Length);
                                            this.neededBytes -= buffer.Length;
                                            buffer            = new byte[0];
                                        }
                                    }
                                }
                            }
                        }

                        if (buffer.Length == 0 && (this.waitingBuffer.Length > 0 || !syncWait))
                        {
                            return(this.waitingBuffer.Length > 0);
                        }

                        if (i != i2)
                        {
                            Thread.Sleep(1);
                        }

                        i--;
                    }
                }

                return(this.waitingBuffer.Length > 0);
            }
            catch (Exception e)
            {
                this.Close("Protocol 4. " + e);
            }

            return(false);
        }
Exemple #6
0
        // ReSharper disable once RedundantAssignment
        private bool ReadServerResponse(ref byte[] bytes)
        {
            this.currentTimeout = this.NoDataTimeout * 1000; // let make it 60sec
            string responseHeader = string.Empty;

            bytes = new byte[0];
            while (responseHeader.IndexOf("\r\n\r\n", StringComparison.Ordinal) == -1)
            {
                if ((this.ParentClient.UnderlyingSocket != null &&
                     !Common.IsSocketConnected(this.ParentClient.UnderlyingSocket)) ||
                    !Common.IsSocketConnected(this.UnderlyingSocket))
                {
                    this.Close();
                    return(false);
                }

                if (this.UnderlyingSocket.Available > 0)
                {
                    this.currentTimeout = this.NoDataTimeout * 1000;
                    byte[] response = this.Read();
                    if (response == null || response.Length <= 0)
                    {
                        this.Close(
                            "No response from server, Read Failure.",
                            null,
                            ErrorRenderer.HttpHeaderCode.C504GatewayTimeout);
                        return(false);
                    }

                    Array.Resize(ref bytes, bytes.Length + response.Length);
                    Array.Copy(response, 0, bytes, bytes.Length - response.Length, response.Length);
                    responseHeader += Encoding.ASCII.GetString(response);
                }
                else
                {
                    if (!this.BusyWrite)
                    {
                        this.currentTimeout--;
                        if (this.currentTimeout == 0)
                        {
                            this.Close(
                                "No response from server, Timeout.",
                                null,
                                ErrorRenderer.HttpHeaderCode.C504GatewayTimeout);
                            return(false);
                        }
                    }

                    Thread.Sleep(1);
                }
            }

            int endOfHeaderIndex = responseHeader.IndexOf("\r\n\r\n", StringComparison.Ordinal) + 4;

            responseHeader = responseHeader.Substring(0, endOfHeaderIndex);
            if (!responseHeader.StartsWith("HTTP/1.1 200", StringComparison.InvariantCultureIgnoreCase) &&
                !responseHeader.StartsWith("HTTP/1.0 200", StringComparison.InvariantCultureIgnoreCase))
            {
                this.Close(
                    "Bad server response. Is address of server ",
                    responseHeader.Substring(
                        0,
                        Math.Min(responseHeader.Length, responseHeader.IndexOf("\r", StringComparison.Ordinal))),
                    ErrorRenderer.HttpHeaderCode.C502BadGateway);
                return(false);
            }

            int headerLenght = Encoding.ASCII.GetByteCount(responseHeader);

            Array.Copy(bytes, headerLenght, bytes, 0, bytes.Length - headerLenght);
            Array.Resize(ref bytes, bytes.Length - headerLenght);

            // --------------------------- We have header. Reading cookies for getting encryption type
            int indexOfCookies = responseHeader.IndexOf("\r\nSet-Cookie: ", StringComparison.InvariantCultureIgnoreCase);

            if (indexOfCookies != -1)
            {
                int startOfCookies = responseHeader.IndexOf(
                    "=",
                    indexOfCookies,
                    StringComparison.InvariantCultureIgnoreCase) + 1;
                int endOfCookies = responseHeader.IndexOf(
                    ";",
                    indexOfCookies,
                    StringComparison.InvariantCultureIgnoreCase);
                this.serverEncryptionType =
                    (Common.EncryptionTypes)
                    int.Parse(responseHeader.Substring(startOfCookies, endOfCookies - startOfCookies));
            }

            if (this.serverEncryptionType == this.encryptionType)
            {
                this.peerCryptor = this.cryptor;
            }
            else
            {
                switch (this.serverEncryptionType)
                {
                case Common.EncryptionTypes.None:

                    // Do Nothing. It is OK
                    break;

                case Common.EncryptionTypes.SimpleXor:
                    this.peerCryptor = new SimpleXorCryptor(this.encryptionKey, false);
                    this.peerCryptor.SetSalt(this.encryptionSaltBytes);
                    break;

                default:
                    this.Close(
                        "Unsupported encryption method used by server.",
                        null,
                        ErrorRenderer.HttpHeaderCode.C502BadGateway);
                    return(false);
                }
            }

            return(true);
        }