/// <summary> /// Decode Refresh Rect 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 Refresh Rect PDU</returns> public StackPacket DecodeRefreshRectPDU( byte[] data, byte[] decryptedUserData, SecurityHeaderType type) { Client_Refresh_Rect_Pdu pdu = new Client_Refresh_Rect_Pdu(); int dataIndex = 0; pdu.commonHeader = ParseMcsCommonHeader(data, ref dataIndex, type); int userDataIndex = 0; pdu.refreshRectPduData = ParseTsRefreshRectPdu(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.2 /// </summary> /// <param name="refreshPdu"></param> public void VerifyPdu(Client_Refresh_Rect_Pdu refreshPdu) { if (serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT || serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT || serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT) { site.CaptureRequirementIfIsInstanceOfType(refreshPdu.commonHeader.securityHeader, typeof(TS_SECURITY_HEADER1), 2158, @"In Client Refresh Rect 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(refreshPdu.commonHeader.securityHeader, typeof(TS_SECURITY_HEADER2), 2159, @"In Client Refresh Rect 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(refreshPdu.commonHeader.securityHeader, 2160, @"In Client Refresh Rect PDU, If Enhanced RDP Security is in effect or the Encryption Method" + @" selected by the server is ENCRYPTION_METHOD_NONE (0), then securityHeader MUST NOT be" + @" included in the PDU."); } site.CaptureRequirementIfAreEqual<ShareControlHeaderType>((ShareControlHeaderType)(refreshPdu.refreshRectPduData.shareDataHeader.shareControlHeader.pduType.typeAndVersionLow & 0xF), ShareControlHeaderType.PDUTYPE_DATAPDU, 2163, @"In Refresh Rect PDU Data,the type subfield of the pduType field of the Share Control Header MUST" + @" be set to PDUTYPE_DATAPDU (7)."); site.CaptureRequirementIfAreEqual<pduType2_Values>(pduType2_Values.PDUTYPE2_REFRESH_RECT, refreshPdu.refreshRectPduData.shareDataHeader.pduType2, 2164, @"In Refresh Rect PDU Data,the pduType2 field of the Share Data Header MUST be set to PDUTYPE2_REFRESH_RECT (33)."); site.CaptureRequirementIfAreEqual<int>(refreshPdu.refreshRectPduData.numberOfAreas, refreshPdu.refreshRectPduData.areasToRefresh.Count, 2168, @"In Refresh Rect PDU Data(TS_REFRESH_RECT_PDU), the areasToRefresh field is an array of TS_RECTANGLE16" + @" structures (variable number of bytes). Array of screen area Inclusive Rectangles to redraw. The number" + @" of rectangles is given by the numberOfAreas field."); }
/// <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_Refresh_Rect_Pdu cloneRefreshPdu = new Client_Refresh_Rect_Pdu(context); cloneRefreshPdu.commonHeader = commonHeader.Clone(); cloneRefreshPdu.refreshRectPduData = refreshRectPduData; cloneRefreshPdu.refreshRectPduData.pad3Octects = RdpbcgrUtility.CloneByteArray(refreshRectPduData.pad3Octects); if (refreshRectPduData.areasToRefresh != null) { cloneRefreshPdu.refreshRectPduData.areasToRefresh = new Collection<TS_RECTANGLE16>(); for (int i = 0; i < refreshRectPduData.areasToRefresh.Count; ++i) { cloneRefreshPdu.refreshRectPduData.areasToRefresh.Add(refreshRectPduData.areasToRefresh[i]); } } return cloneRefreshPdu; }