예제 #1
0
        /// <summary>
        /// Build packet binary data
        /// </summary>
        /// <returns>a byte buffer</returns>
        private ByteBuffer BuildImage()
        {
            ByteBuffer image = _imageBuffer.Value;

            image.Clear();
            int packetLength  = _payload.Length + 5; //type and CRC
            int paddingLength = 8 - (packetLength % 8);

            image.WriteInt32(packetLength);
            image.WriteSecureRandomBytes(paddingLength);
            image.WriteByte((byte)_type);
            if (_payload.Length > 0)
            {
                image.Append(_payload);
            }
            uint crc = CRC.Calc(
                image.RawBuffer,
                image.RawBufferOffset + PACKET_LENGTH_FIELD_LEN,
                image.Length - PACKET_LENGTH_FIELD_LEN);

            image.WriteUInt32(crc);
            return(image);
        }
예제 #2
0
        private byte[] BuildImage()
        {
            int packet_length  = (_data == null ? 0 : _data.Length) + 5; //type and CRC
            int padding_length = 8 - (packet_length % 8);

            byte[] image = new byte[packet_length + padding_length + 4];
            SSHUtil.WriteIntToByteArray(image, 0, packet_length);

            for (int i = 0; i < padding_length; i++)
            {
                image[4 + i] = 0; //padding: filling by random values is better
            }
            image[4 + padding_length] = _type;
            if (_data != null)
            {
                Array.Copy(_data, 0, image, 4 + padding_length + 1, _data.Length);
            }

            _CRC = CRC.Calc(image, 4, image.Length - 8);
            SSHUtil.WriteIntToByteArray(image, image.Length - 4, (int)_CRC);

            return(image);
        }
예제 #3
0
        /// <summary>
        /// Extracts SSH packet from the internal buffer.
        /// </summary>
        /// <returns>
        /// true if one SSH packet has been extracted.
        /// in this case, _packetImage contains Packet Type field and Data field of the SSH packet.
        /// </returns>
        private bool ConstructPacket()
        {
            const int PACKET_LENGTH_FIELD_LEN = 4;
            const int CHECK_BYTES_FIELD_LEN   = 4;

            if (_packetLength < 0)
            {
                if (_inputBuffer.Length < PACKET_LENGTH_FIELD_LEN)
                {
                    return(false);
                }

                uint packetLength = SSHUtil.ReadUInt32(_inputBuffer.RawBuffer, _inputBuffer.RawBufferOffset);
                _inputBuffer.RemoveHead(PACKET_LENGTH_FIELD_LEN);

                if (packetLength < MIN_PACKET_LENGTH || packetLength > MAX_PACKET_LENGTH)
                {
                    throw new SSHException(String.Format("invalid packet length : {0}", packetLength));
                }

                _packetLength = (int)packetLength;
            }

            int paddingLength  = 8 - (_packetLength % 8);
            int requiredLength = paddingLength + _packetLength;

            if (_inputBuffer.Length < requiredLength)
            {
                return(false);
            }

            _packetImage.Clear();
            _packetImage.Append(_inputBuffer, 0, requiredLength);   // Padding, Packet Type, Data, and Check fields
            _inputBuffer.RemoveHead(requiredLength);

            if (_cipher != null)
            {
                _cipher.Decrypt(
                    _packetImage.RawBuffer, _packetImage.RawBufferOffset, requiredLength,
                    _packetImage.RawBuffer, _packetImage.RawBufferOffset);
            }

            if (_checkMAC)
            {
                uint crc = CRC.Calc(
                    _packetImage.RawBuffer,
                    _packetImage.RawBufferOffset,
                    requiredLength - CHECK_BYTES_FIELD_LEN);
                uint expected = SSHUtil.ReadUInt32(
                    _packetImage.RawBuffer,
                    _packetImage.RawBufferOffset + requiredLength - CHECK_BYTES_FIELD_LEN);
                if (crc != expected)
                {
                    throw new SSHException("CRC Error");
                }
            }

            // retain only Packet Type and Data fields
            _packetImage.RemoveHead(paddingLength);
            _packetImage.RemoveTail(CHECK_BYTES_FIELD_LEN);

            // sanity check
            if (_packetImage.Length != _packetLength - CHECK_BYTES_FIELD_LEN)
            {
                throw new InvalidOperationException();
            }

            // prepare for the next packet
            _packetLength = -1;

            return(true);
        }