/// <summary>
        /// Decode MCS Send Data Indication PDU
        /// </summary>
        /// <param name="data">data to be parsed</param>
        /// <param name="domainPdu">Mcs Domain PDU</param>
        /// <returns>decoded MCS Send Data Indication PDU</returns>
        private StackPacket DecodeMcsSendDataIndicationPDU(byte[] data, DomainMCSPDU domainPdu)
        {
            // Get Send Data Indication
            SendDataIndication indication = (SendDataIndication)domainPdu.GetData();
            byte[] userData = indication.userData.ByteArrayValue;

            // Get Security Header Type
            SecurityHeaderType securityHeaderType = GetSecurityHeaderTypeByContext();

            // Peek Security Header
            bool isLicenseErrorPdu = false;
            if (clientContext.IsWaitingLicenseErrorPdu)
            {
                isLicenseErrorPdu = IsLicenseErrorSecurityHeaderExist(userData);
            }

            // Decode PDU
            if (isLicenseErrorPdu)
            {
                // License Error PDU's Basic Security Header content is alway present
                int tempIndex = 0;
                TS_SECURITY_HEADER header = ParseTsSecurityHeader(userData, ref tempIndex, SecurityHeaderType.Basic);

                // Check if PDU is encrypted
                bool isEncryptedPdu = IsFlagExist((UInt16)header.flags,
                    (UInt16)TS_SECURITY_HEADER_flags_Values.SEC_ENCRYPT);

                // Correct Server License Error PDU's security header type if needed
                if (!isEncryptedPdu || EncryptionLevel.ENCRYPTION_LEVEL_NONE == clientContext.RdpEncryptionLevel)
                {
                    securityHeaderType = SecurityHeaderType.Basic;
                }

                // Get decrypted user data
                byte[] decryptedUserData = DecryptSendDataIndication(userData, securityHeaderType);

                // Decode Server License Error PDU
                return DecodeLicenseErrorPDU(data, decryptedUserData, securityHeaderType);
            }
            else
            {
                // Get decrypted user data
                byte[] decryptedUserData = DecryptSendDataIndication(userData, securityHeaderType);

                if (clientContext.MessageChannelId == indication.channelId.Value)
                {
                    if (IsInitiateMultitransportRequestSecurityHeaderExist(userData))
                    {
                        return DecodeServerInitiateMultitransportRequest(data, decryptedUserData, securityHeaderType);
                    }
                    else if (IsHeartbeatSecurityHeaderExist(userData))
                    {
                        return DecodeServerHeartbeatPDU(data, decryptedUserData, securityHeaderType);
                    }
                    else
                    {
                        return DecodeServerAutoDetectRequestPDU(data, decryptedUserData, securityHeaderType);
                    }
                }
                // Check channel ID (IO Channel ID/Virual Channel ID)
                else if (clientContext.IOChannelId != indication.channelId.Value)
                {
                    // Decode Virtual Channel PDU
                    return DecodeVirtualChannelPDU(data, decryptedUserData, securityHeaderType);
                }
                else if (IsStandardRedirectionPdu(userData, securityHeaderType))
                {
                    return DecodeServerRedirectionPDU(data, decryptedUserData, securityHeaderType);
                }
                else
                {
                    // Decode other Send Data Indication PDUs
                    return SwitchDecodeMcsSendDataIndicationPDU(data, decryptedUserData, securityHeaderType);
                }
            }
        }
        /// <summary>
        /// Parse MCS Domain PDU
        /// (parser index is updated according to parsed length)
        /// </summary>
        /// <param name="data">data to be parsed</param>
        /// <param name="currentIndex">current parser index</param>
        /// <returns>MCS Domain PDU</returns>
        private DomainMCSPDU ParseMcsDomainPdu(byte[] data, ref int currentIndex)
        {
            // initialize decode buffer
            byte[] temp = GetBytes(data, ref currentIndex, (data.Length - currentIndex));
            Asn1DecodingBuffer buffer = new Asn1DecodingBuffer(temp);

            // decode
            DomainMCSPDU domainPdu = new DomainMCSPDU();
            domainPdu.PerDecode(buffer);
            return domainPdu;
        }
Esempio n. 3
0
        /// <summary>
        /// Encode this structure into byte array.
        /// </summary>
        /// <returns>The byte array of the structure.</returns>
        public override byte[] ToBytes()
        {
            List<byte> totalBuffer = new List<byte>();

            RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader);
            RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data);

            DomainMCSPDU mcsDomain = new DomainMCSPDU(DomainMCSPDU.channelJoinConfirm, channelJoinConfirm);
            RdpbcgrEncoder.EncodeDomainMcsPdu(totalBuffer, mcsDomain);

            byte[] encodedBytes = RdpbcgrUtility.ToBytes(totalBuffer);

            // ToDo: Ugly dump message code here
            // ETW Provider Dump Code
            RdpbcgrUtility.ETWProviderDump(this.GetType().Name, encodedBytes);

            return encodedBytes;
        }
        /// <summary>
        /// Decode MCS Send Data Request PDU
        /// </summary>
        /// <param name="serverSessionContext">the server session context</param>
        /// <param name="data">data to be parsed</param>
        /// <param name="domainPdu">Mcs Domain PDU</param>
        /// <returns>decoded MCS Send Data Request PDU</returns>
        private StackPacket DecodeMcsSendDataRequestPDU(RdpbcgrServerSessionContext serverSessionContext, byte[] data, DomainMCSPDU domainPdu)
        {
            SendDataRequest indication = (SendDataRequest)domainPdu.GetData();
            byte[] userData = indication.userData.ByteArrayValue;

            bool isSecurityExchange;
            bool isClientInfo;
            bool isAutoDetectResponsePDU;
            bool isMultitransportErrorPDU;

            // Get Security Header Type
            SecurityHeaderType securityHeaderType = GetSecurityHeaderTypeByContext(serverSessionContext);

            int i = 0;
            if (userData.Length == ParseUInt16(userData, ref i, false)
                || (securityHeaderType == SecurityHeaderType.None && serverSessionContext.IOChannelId != indication.channelId.Value && serverSessionContext.McsMsgChannelId != indication.channelId.Value))
            {
                // the packet not transmitted in IO Channel cannot be Security Exchange PDU or Client Info PDU, so set all to false.
                isSecurityExchange = false;
                isClientInfo = false;
                isAutoDetectResponsePDU = false;
                isMultitransportErrorPDU = false;
            }
            else
            {
                int tempIndex = 0;
                TS_SECURITY_HEADER header = ParseTsSecurityHeader(userData, ref tempIndex, SecurityHeaderType.Basic);

                // Check if PDU is Security Exchange PDU
                isSecurityExchange = IsFlagExist((UInt16)header.flags,
                    (UInt16)TS_SECURITY_HEADER_flags_Values.SEC_EXCHANGE_PKT);

                //Check if PDU is Client Info PDU
                isClientInfo = IsFlagExist((UInt16)header.flags, (UInt16)TS_SECURITY_HEADER_flags_Values.SEC_INFO_PKT);

                //check if PDU is Auto Detect Response PDU
                isAutoDetectResponsePDU = IsFlagExist((UInt16)header.flags, (UInt16)TS_SECURITY_HEADER_flags_Values.SEC_AUTODETECT_RSP);

                //check if PDU is Client Initiate Multitransport Error PDU
                isMultitransportErrorPDU = IsFlagExist((UInt16)header.flags, (UInt16)TS_SECURITY_HEADER_flags_Values.SEC_TRANSPORT_RSP);
            }

            if (isSecurityExchange)
            {
                securityHeaderType = SecurityHeaderType.Basic;
                byte[] decryptedUserData = DecryptSendDataRequest(serverSessionContext, userData, securityHeaderType);
                return DecodeSecurityExchangePdu(serverSessionContext, data, decryptedUserData, securityHeaderType);
            }
            else if (isClientInfo)
            {
                if (serverSessionContext.RdpEncryptionLevel == EncryptionLevel.ENCRYPTION_LEVEL_NONE &&
                    serverSessionContext.RdpEncryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_NONE)
                {
                    securityHeaderType = SecurityHeaderType.Basic;
                }
                else if (serverSessionContext.RdpEncryptionLevel == EncryptionLevel.ENCRYPTION_LEVEL_FIPS &&
                    serverSessionContext.RdpEncryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS)
                {
                    securityHeaderType = SecurityHeaderType.Fips;
                }
                else
                {
                    securityHeaderType = SecurityHeaderType.NonFips;
                }
                byte[] decryptedUserData = DecryptSendDataRequest(serverSessionContext, userData, securityHeaderType);
                return DecodeClientInfoPdu(data, decryptedUserData, securityHeaderType);
            }
            else if (isAutoDetectResponsePDU)
            {
                if (serverSessionContext.RdpEncryptionLevel == EncryptionLevel.ENCRYPTION_LEVEL_NONE &&
                    serverSessionContext.RdpEncryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_NONE)
                {
                    securityHeaderType = SecurityHeaderType.Basic;
                }
                else if (serverSessionContext.RdpEncryptionLevel == EncryptionLevel.ENCRYPTION_LEVEL_FIPS &&
                    serverSessionContext.RdpEncryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS)
                {
                    securityHeaderType = SecurityHeaderType.Fips;
                }
                else
                {
                    securityHeaderType = SecurityHeaderType.NonFips;
                }
                byte[] decryptedUserData = DecryptSendDataRequest(serverSessionContext, userData, securityHeaderType);
                return DecodeClientAutoDetectResponsePDU(data, decryptedUserData, securityHeaderType);
            }
            else if (isMultitransportErrorPDU)
            {
                if (serverSessionContext.RdpEncryptionLevel == EncryptionLevel.ENCRYPTION_LEVEL_NONE &&
                    serverSessionContext.RdpEncryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_NONE)
                {
                    securityHeaderType = SecurityHeaderType.Basic;
                }
                else if (serverSessionContext.RdpEncryptionLevel == EncryptionLevel.ENCRYPTION_LEVEL_FIPS &&
                    serverSessionContext.RdpEncryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS)
                {
                    securityHeaderType = SecurityHeaderType.Fips;
                }
                else
                {
                    securityHeaderType = SecurityHeaderType.NonFips;
                }
                byte[] decryptedUserData = DecryptSendDataRequest(serverSessionContext, userData, securityHeaderType);
                return DecodeClientInitiateMultitransportResponsePDU(data, decryptedUserData, securityHeaderType);
            }
            else
            {
                if(!serverSessionContext.IsClientToServerEncrypted)
                    securityHeaderType = SecurityHeaderType.Basic;
                // Get decrypted user data
                byte[] decryptedUserData = DecryptSendDataRequest(serverSessionContext, userData, securityHeaderType);

                // Check channel ID (IO Channel ID/Virual Channel ID)
                if (serverSessionContext.IOChannelId != indication.channelId.Value)
                {
                    // Decode Virtual Channel PDU
                    return DecodeVirtualChannelPDU(data, decryptedUserData, securityHeaderType);
                }

                else
                {
                    // Decode other Send Data Indication PDUs
                    return SwitchDecodeMcsSendDataRequestPDU(data, decryptedUserData, securityHeaderType);
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Encode this structure into byte array.
        /// </summary>
        /// <returns>The byte array of the structure.</returns>
        public override byte[] ToBytes()
        {
            List<byte> totalBuffer = new List<byte>();

            RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader);
            RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data);

            if (disconnectProvider != null)
            {
                DomainMCSPDU mcsDPum = new DomainMCSPDU
                    (DomainMCSPDU.disconnectProviderUltimatum, disconnectProvider);
                RdpbcgrEncoder.EncodeDomainMcsPdu(totalBuffer, mcsDPum);
            }

            byte[] encodedBytes = RdpbcgrUtility.ToBytes(totalBuffer);

            // ToDo: Ugly dump message code here
            // ETW Provider Dump Code
            RdpbcgrUtility.ETWProviderDump(this.GetType().Name, encodedBytes);

            return encodedBytes;
        }
Esempio n. 6
0
        /// <summary>
        /// Encode this structure into byte array.
        /// </summary>
        /// <returns>The byte array of the structure.</returns>
        public override byte[] ToBytes()
        {
            List<byte> totalBuffer = new List<byte>();

            RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader);
            RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data);

            if (disconnectProvider != null)
            {
                DomainMCSPDU mcsDPum = new DomainMCSPDU
                    (DomainMCSPDU.disconnectProviderUltimatum, disconnectProvider);
                RdpbcgrEncoder.EncodeDomainMcsPdu(totalBuffer, mcsDPum);
            }

            return RdpbcgrUtility.ToBytes(totalBuffer);
        }
Esempio n. 7
0
        /// <summary>
        /// Encode this structure into byte array.
        /// </summary>
        /// <returns>The byte array of the structure.</returns>
        public override byte[] ToBytes()
        {
            List<byte> totalBuffer = new List<byte>();

            RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader);
            RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data);

            ErectDomainRequest erectDomain = new ErectDomainRequest(new Asn1Integer(subHeight), new Asn1Integer(subInterval));
            DomainMCSPDU mcsDomain = new DomainMCSPDU(DomainMCSPDU.erectDomainRequest, erectDomain);
            RdpbcgrEncoder.EncodeDomainMcsPdu(totalBuffer, mcsDomain);

            return RdpbcgrUtility.ToBytes(totalBuffer);
        }
Esempio n. 8
0
        /// <summary>
        /// Encode this structure into byte array.
        /// </summary>
        /// <returns>The byte array of the structure.</returns>
        public override byte[] ToBytes()
        {
            List<byte> totalBuffer = new List<byte>();

            RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader);
            RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data);

            ChannelJoinRequest joinRequest = new ChannelJoinRequest(new UserId(userChannelId), new ChannelId(mcsChannelId));
            DomainMCSPDU mcsDomain = new DomainMCSPDU(DomainMCSPDU.channelJoinRequest, joinRequest);
            RdpbcgrEncoder.EncodeDomainMcsPdu(totalBuffer, mcsDomain);

            return RdpbcgrUtility.ToBytes(totalBuffer);
        }
Esempio n. 9
0
        /// <summary>
        /// Encode this structure into byte array.
        /// </summary>
        /// <returns>The byte array of the structure.</returns>
        public override byte[] ToBytes()
        {
            List<byte> totalBuffer = new List<byte>();

            RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader);
            RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data);

            AttachUserRequest attachUserRequest = new AttachUserRequest();
            DomainMCSPDU mcsDomain = new DomainMCSPDU(DomainMCSPDU.attachUserRequest, attachUserRequest);
            RdpbcgrEncoder.EncodeDomainMcsPdu(totalBuffer, mcsDomain);

            return RdpbcgrUtility.ToBytes(totalBuffer);
        }