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);
}
}
}