Example #1
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;
        }
Example #2
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;
 }
Example #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;
        }
Example #4
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);
        }