/// <summary> /// Decode Suppress Output PDU. /// </summary> /// <param name="data">data to be parsed</param> /// <param name="decryptedUserData">decrypted user data to be parsed</param> /// <param name="type">security header type</param> /// <returns>decoded Suppress Output PDU</returns> public StackPacket DecodeSuppressOutputPDU( byte[] data, byte[] decryptedUserData, SecurityHeaderType type) { Client_Suppress_Output_Pdu pdu = new Client_Suppress_Output_Pdu(); int dataIndex = 0; pdu.commonHeader = ParseMcsCommonHeader(data, ref dataIndex, type); int userDataIndex = 0; pdu.suppressOutputPduData = ParseTsSuppressOutputPdu(decryptedUserData, ref userDataIndex); // ETW Provider Dump Message if (pdu.commonHeader.securityHeader != null) { // RDP Standard Security string messageName = "RDPBCGR:" + pdu.GetType().Name; ExtendedLogger.DumpMessage(messageName, RdpbcgrUtility.DumpLevel_Layer3, pdu.GetType().Name, decryptedUserData); } VerifyDataLength(decryptedUserData.Length, userDataIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED); return pdu; }
/// <summary> /// 2.2.11.3 /// </summary> /// <param name="suppressPdu"></param> public void VerifyPdu(Client_Suppress_Output_Pdu suppressPdu) { if (serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT || serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT || serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT) { site.CaptureRequirementIfIsInstanceOfType(suppressPdu.commonHeader.securityHeader, typeof(TS_SECURITY_HEADER1), 2174, @"[In Client Suppress Output PDU]The securityHeader in Server Set Keyboard Indicators PDU is a Non-FIPS " + @"Security Header (section 2.2.8.1.1.2.2) if the Encryption Level Method selected by the server (see " + @"sections 5.3.2 and 2.2.1.4.3) is ENCRYPTION_LEVEL_CLIENT_COMPATIBLE (2)METHOD_40BIT (0x00000001), " + @"ENCRYPTION_METHOD_56BIT (0x00000008), or ENCRYPTION_LEVEL_HIGH (3METHOD_128BIT (0x00000002). "); } else if (serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS) { site.CaptureRequirementIfIsInstanceOfType(suppressPdu.commonHeader.securityHeader, typeof(TS_SECURITY_HEADER2), 2175, @"In Client Suppress Output PDU, the securityHeader in Server Set Keyboard Indicators PDU is a FIPS " + @"Security Header if the Encryption Level Method selected by the server is ENCRYPTION_METHOD_FIPS" + @" (0x00000010)."); } else if (serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_NONE) { site.CaptureRequirementIfIsNull(suppressPdu.commonHeader.securityHeader, 2176, @"In Client Suppress Output PDU,If Enhanced RDP Security is in effect or the Encryption Method selected" + @" by the server is ENCRYPTION_METHOD_NONE (0), then this securityHeader MUST NOT be included in the PDU."); } site.CaptureRequirementIfAreEqual<ShareControlHeaderType>(ShareControlHeaderType.PDUTYPE_DATAPDU,(ShareControlHeaderType)(suppressPdu.suppressOutputPduData.shareDataHeader.shareControlHeader.pduType.typeAndVersionLow & 0xF), 2179, @"In Suppress Output PDU Data, the type subfield of the pduType field of the Share Control Header (section 2.2.8.1.1.1.1)" + @" MUST be set to PDUTYPE_DATAPDU (7)."); site.CaptureRequirementIfAreEqual<pduType2_Values>(pduType2_Values.PDUTYPE2_SUPPRESS_OUTPUT, suppressPdu.suppressOutputPduData.shareDataHeader.pduType2, 2180, @"In Suppress Output PDU Data, the type subfield of the pduType2 field of the Share Data Header MUST be set to " + @"PDUTYPE2_SUPPRESS_OUTPUT (35)."); bool isR2182Satisfied = suppressPdu.suppressOutputPduData.allowDisplayUpdates == AllowDisplayUpdates_SUPPRESS_OUTPUT.ALLOW_DISPLAY_UPDATES || suppressPdu.suppressOutputPduData.allowDisplayUpdates == AllowDisplayUpdates_SUPPRESS_OUTPUT.SUPPRESS_DISPLAY_UPDATES; site.CaptureRequirementIfIsTrue(isR2182Satisfied, 2182, @"In Suppress Output PDU Data, allowDisplayUpdates can be of two flags: SUPPRESS_DISPLAY_UPDATES 0x00, ALLOW_DISPLAY_UPDATES 0x01"); if (suppressPdu.suppressOutputPduData.allowDisplayUpdates == AllowDisplayUpdates_SUPPRESS_OUTPUT.ALLOW_DISPLAY_UPDATES) { bool isR2187Satisified = suppressPdu.suppressOutputPduData.desktopRect.right - suppressPdu.suppressOutputPduData.desktopRect.left != 0 && suppressPdu.suppressOutputPduData.desktopRect.bottom - suppressPdu.suppressOutputPduData.desktopRect.top != 0; site.CaptureRequirementIfIsTrue(isR2187Satisified, 2187, @"In Suppress Output PDU Data, the desktopRect field contains the coordinates of the desktop rectangle if" + @" the allowDisplayUpdates field is set to ALLOW_DISPLAY_UPDATES (1)."); } else { bool isR2188Satisified = suppressPdu.suppressOutputPduData.desktopRect.right - suppressPdu.suppressOutputPduData.desktopRect.left == 0 && suppressPdu.suppressOutputPduData.desktopRect.bottom - suppressPdu.suppressOutputPduData.desktopRect.top == 0; site.CaptureRequirementIfIsTrue(isR2188Satisified, 2188, @"In Suppress Output PDU Data, the desktopRect field MUST NOT be included in the PDU, if the " + @"allowDisplayUpdates field is set to SUPPRESS_DISPLAY_UPDATES (0)."); } }
/// <summary> /// Create an instance of the class that is identical to the current PDU. /// </summary> /// <returns>The new instance.</returns> public override StackPacket Clone() { Client_Suppress_Output_Pdu cloneSuppresspdu = new Client_Suppress_Output_Pdu(context); cloneSuppresspdu.commonHeader = commonHeader.Clone(); cloneSuppresspdu.suppressOutputPduData = suppressOutputPduData; cloneSuppresspdu.suppressOutputPduData.pad3Octects = RdpbcgrUtility.CloneByteArray(suppressOutputPduData.pad3Octects); return cloneSuppresspdu; }