/// <summary> /// Decode Control 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 Control PDU</returns> public StackPacket DecodeControlPDU( byte[] data, byte[] decryptedUserData, SecurityHeaderType type) { // data index int dataIndex = 0; // ControlPDU: commonHeader SlowPathPduCommonHeader commonHeader = ParseMcsCommonHeader(data, ref dataIndex, type); // user data index int userDataIndex = 0; // ControlPDU: controlPduData TS_CONTROL_PDU controlPduData = ParseTsControlPdu(decryptedUserData, ref userDataIndex); // Get pdu by action type StackPacket pdu; if (controlPduData.action == action_Values.CTRLACTION_COOPERATE) { // Control PDU - cooperate Client_Control_Pdu_Cooperate cooperatePdu = new Client_Control_Pdu_Cooperate(); cooperatePdu.commonHeader = commonHeader; cooperatePdu.controlPduData = controlPduData; pdu = cooperatePdu; // ETW Provider Dump Message if (cooperatePdu.commonHeader.securityHeader != null) { // RDP Standard Security string messageName = "RDPBCGR:" + cooperatePdu.GetType().Name; ExtendedLogger.DumpMessage(messageName, RdpbcgrUtility.DumpLevel_Layer3, cooperatePdu.GetType().Name, decryptedUserData); } } else if (controlPduData.action == action_Values.CTRLACTION_REQUEST_CONTROL) { // Control PDU - granted control Client_Control_Pdu_Request_Control requestPdu = new Client_Control_Pdu_Request_Control(); requestPdu.commonHeader = commonHeader; requestPdu.controlPduData = controlPduData; pdu = requestPdu; // ETW Provider Dump Message if (requestPdu.commonHeader.securityHeader != null) { // RDP Standard Security string messageName = "RDPBCGR:" + requestPdu.GetType().Name; ExtendedLogger.DumpMessage(messageName, RdpbcgrUtility.DumpLevel_Layer3, requestPdu.GetType().Name, decryptedUserData); } } else { throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED); } // Check if data length exceeded expectation VerifyDataLength(decryptedUserData.Length, userDataIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED); return pdu; }
/// <summary> /// 2.2.1.16 /// </summary> /// <param name="clientCtlRequestPdu"></param> public void VerifyPdu(Client_Control_Pdu_Request_Control clientCtlRequestPdu) { if (serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT || serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT || serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT) { site.CaptureRequirementIfIsInstanceOfType(clientCtlRequestPdu.commonHeader.securityHeader, typeof(TS_SECURITY_HEADER1), 771, @"[In Client Control PDU - Request Control]securityHeader (variable): The securityHeader in Server " + @"Demand Active PDU is a Non-FIPS Security Header (section 2.2.8.1.1.2.2) if the Encryption LevelMethod" + @" 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(clientCtlRequestPdu.commonHeader.securityHeader, typeof(TS_SECURITY_HEADER2), 772, @"[In Client Control PDU - Request Control]securityHeader (variable):The securityHeader in Server Demand Active " + @"PDU is a FIPS Security Header,if the Encryption LevelMethod selected by the server is ENCRYPTION_METHOD_FIPS (0x00000010)."); } else if (serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_NONE) { site.CaptureRequirementIfIsNull(clientCtlRequestPdu.commonHeader.securityHeader, 773, @"For Client Control PDU - Request Control, 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 Client Control PDU" + @" - Request Control."); } site.CaptureRequirementIfIsTrue(clientCtlRequestPdu.controlPduData.controlId == 0 && clientCtlRequestPdu.controlPduData.grantId == 0, 775, @"In Client Control PDU - Request Control, the grantId and controlId fields of the Control PDU Data MUST both be set to zero."); site.CaptureRequirementIfAreEqual<action_Values>(action_Values.CTRLACTION_REQUEST_CONTROL, clientCtlRequestPdu.controlPduData.action, 776, @"In Client Control PDU - Request Control,the action field of the Control PDU Data MUST be set to CTRLACTION_REQUEST_CONTROL (0x0001)."); }
/// <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_Control_Pdu_Request_Control cloneConrolReqPdu = new Client_Control_Pdu_Request_Control(context); cloneConrolReqPdu.commonHeader = commonHeader.Clone(); cloneConrolReqPdu.controlPduData = controlPduData; return cloneConrolReqPdu; }