/// <summary> /// Create an verification trailer with commands parameter passed in to the method. /// </summary> /// <param name="commands"> /// A list of commands to be contained in the verification trailer.<para/> /// Flag SEC_VT_COMMAND_END is ignored by input, and will be added to /// the last command automatically. /// </param> /// <returns> /// Created verification trailer. Pad is not added until appending to stub. /// </returns> /// <exception cref="ArgumentNullException"> /// Thrown when commands is null. /// </exception> /// <exception cref="InvalidOperationException"> /// Thrown when a SEC_VT_COMMAND is invalid, or NDR/NDR64 was not negotiated. /// </exception> public verification_trailer_t CreateVerificationTrailer( params SEC_VT_COMMAND[] commands) { if (commands == null) { throw new ArgumentNullException("commands"); } verification_trailer_t verificationTrailer = new verification_trailer_t(); verificationTrailer.header = new rpc_sec_verification_trailer(); verificationTrailer.header.signature = BitConverter.GetBytes(verification_trailer_t.SIGNATURE); List <SEC_VT> secVtList = new List <SEC_VT>(); for (int i = 0; i < commands.Length; i++) { switch (commands[i] & ~(SEC_VT_COMMAND.SEC_VT_COMMAND_END | SEC_VT_COMMAND.SEC_VT_MUST_PROCESS_COMMAND)) { case SEC_VT_COMMAND.SEC_VT_COMMAND_BITMASK_1: rpc_sec_vt_bitmask secVtBitmask = new rpc_sec_vt_bitmask(); secVtBitmask.command = commands[i]; //length: MUST be 0x0004. secVtBitmask.length = verification_trailer_t.SEC_VT_BITMASK_LENGTH; //bits: The bits field is a bitmask. //A server MUST ignore bits it does not understand. //Currently, there is only one bit defined: CLIENT_SUPPORT_HEADER_SIGNING //(bitmask of 0x00000001). If this bit is set, the PFC_SUPPORT_HEADER_SIGN //bit, as specified in section 2.2.2.3, MUST be present in the PDU header //for the bind PDU on this connection. secVtBitmask.bits = context.SupportsHeaderSign ? (uint)0x00000001 : 0; secVtList.Add(secVtBitmask); break; case SEC_VT_COMMAND.SEC_VT_COMMAND_HEADER2: rpc_sec_vt_header2 secVtHeader2 = new rpc_sec_vt_header2(); secVtHeader2.command = commands[i]; //length: MUST be 0x0010. secVtHeader2.length = verification_trailer_t.SEC_VT_HEADER2_LENGTH; //PTYPE: MUST be the same as the PTYPE field in the request PDU header. secVtHeader2.PTYPE = PTYPE; secVtHeader2.reserved1 = 0; secVtHeader2.reserved2 = 0; secVtHeader2.drep = packed_drep; secVtHeader2.call_id = call_id; secVtHeader2.p_cont_id = p_cont_id; secVtHeader2.opnum = opnum; secVtList.Add(secVtHeader2); break; case SEC_VT_COMMAND.SEC_VT_COMMAND_PCONTEXT: rpc_sec_vt_pcontext secVtPcontext = new rpc_sec_vt_pcontext(); secVtPcontext.command = commands[i]; //length: MUST be set to 0x28. secVtPcontext.length = verification_trailer_t.SEC_VT_PCONTEXT_LENGTH; secVtPcontext.interfaceId = new p_syntax_id_t(); secVtPcontext.interfaceId.if_uuid = context.InterfaceId; secVtPcontext.interfaceId.if_vers_major = context.InterfaceMajorVersion; secVtPcontext.interfaceId.if_vers_minor = context.InterfaceMinorVersion; secVtPcontext.transferSyntax = new p_syntax_id_t(); if (context.NdrVersion == RpceNdrVersion.NDR) { secVtPcontext.transferSyntax.if_uuid = RpceUtility.NDR_INTERFACE_UUID; secVtPcontext.transferSyntax.if_vers_major = RpceUtility.NDR_INTERFACE_MAJOR_VERSION; secVtPcontext.transferSyntax.if_vers_minor = RpceUtility.NDR_INTERFACE_MINOR_VERSION; } else if (context.NdrVersion == RpceNdrVersion.NDR64) { secVtPcontext.transferSyntax.if_uuid = RpceUtility.NDR64_INTERFACE_UUID; secVtPcontext.transferSyntax.if_vers_major = RpceUtility.NDR64_INTERFACE_MAJOR_VERSION; secVtPcontext.transferSyntax.if_vers_minor = RpceUtility.NDR64_INTERFACE_MINOR_VERSION; } else { throw new InvalidOperationException("Neither NDR nore NDR64 was negotiated."); } secVtList.Add(secVtPcontext); break; default: throw new InvalidOperationException("Invalid SEC_VT_COMMAND."); } } verificationTrailer.commands = secVtList.ToArray(); return(verificationTrailer); }
/// <summary> /// Unmarshal a verification trailer from byte array. /// </summary> /// <param name="verificationTrailerBuffer">byte array.</param> public void FromBytes(byte[] verificationTrailerBuffer) { int padLength = -1; for (int i = 0; i < verificationTrailerBuffer.Length; i++) { if ((verificationTrailerBuffer.Length - i) >= Marshal.SizeOf(verification_trailer_t.SIGNATURE) && BitConverter.ToUInt64(verificationTrailerBuffer, i) == verification_trailer_t.SIGNATURE) { padLength = i; } } if (padLength < 0) { throw new InvalidOperationException("verification_trailer not found."); } using (BinaryReader reader = new BinaryReader(new MemoryStream(verificationTrailerBuffer))) { pad = reader.ReadBytes(padLength); header.signature = reader.ReadBytes(sizeof(ulong)); List <SEC_VT> secVtList = new List <SEC_VT>(); while (reader.BaseStream.Position < verificationTrailerBuffer.Length) { if ((verificationTrailerBuffer.Length - reader.BaseStream.Position) < SEC_VT_HEADER_LENGTH) { break; } SEC_VT_COMMAND command = (SEC_VT_COMMAND)reader.ReadUInt16(); ushort length = reader.ReadUInt16(); if ((verificationTrailerBuffer.Length - reader.BaseStream.Position) < length) { //length of remain bytes is less than expected. break; } switch (command & ~(SEC_VT_COMMAND.SEC_VT_MUST_PROCESS_COMMAND | SEC_VT_COMMAND.SEC_VT_COMMAND_END)) { case SEC_VT_COMMAND.SEC_VT_COMMAND_BITMASK_1: rpc_sec_vt_bitmask secVtBitmask = new rpc_sec_vt_bitmask(); secVtBitmask.command = command; secVtBitmask.length = length; secVtBitmask.bits = reader.ReadUInt32(); secVtList.Add(secVtBitmask); break; case SEC_VT_COMMAND.SEC_VT_COMMAND_PCONTEXT: rpc_sec_vt_pcontext secVtPcontext = new rpc_sec_vt_pcontext(); secVtPcontext.command = command; secVtPcontext.length = length; secVtPcontext.interfaceId = new p_syntax_id_t(); secVtPcontext.interfaceId.if_uuid = new Guid(reader.ReadBytes(RpceUtility.GUID_SIZE)); secVtPcontext.interfaceId.if_vers_major = reader.ReadUInt16(); secVtPcontext.interfaceId.if_vers_minor = reader.ReadUInt16(); secVtPcontext.transferSyntax = new p_syntax_id_t(); secVtPcontext.transferSyntax.if_uuid = new Guid(reader.ReadBytes(RpceUtility.GUID_SIZE)); secVtPcontext.transferSyntax.if_vers_major = reader.ReadUInt16(); secVtPcontext.transferSyntax.if_vers_minor = reader.ReadUInt16(); secVtList.Add(secVtPcontext); break; case SEC_VT_COMMAND.SEC_VT_COMMAND_HEADER2: rpc_sec_vt_header2 secVtHeader2 = new rpc_sec_vt_header2(); secVtHeader2.command = command; secVtHeader2.length = length; secVtHeader2.PTYPE = (RpcePacketType)reader.ReadByte(); secVtHeader2.reserved1 = reader.ReadByte(); secVtHeader2.reserved2 = reader.ReadUInt16(); secVtHeader2.drep = new DataRepresentationFormatLabel(); secVtHeader2.drep.dataRepFormat = (RpceDataRepresentationFormat)reader.ReadUInt16(); secVtHeader2.drep.reserved = reader.ReadUInt16(); secVtHeader2.call_id = reader.ReadUInt32(); secVtHeader2.p_cont_id = reader.ReadUInt16(); secVtHeader2.opnum = reader.ReadUInt16(); secVtList.Add(secVtHeader2); break; default: //do nothing break; } } commands = secVtList.ToArray(); } }
/// <summary> /// Create an verification trailer with commands parameter passed in to the method. /// </summary> /// <param name="commands"> /// A list of commands to be contained in the verification trailer.<para/> /// Flag SEC_VT_COMMAND_END is ignored by input, and will be added to /// the last command automatically. /// </param> /// <returns> /// Created verification trailer. Pad is not added until appending to stub. /// </returns> /// <exception cref="ArgumentNullException"> /// Thrown when commands is null. /// </exception> /// <exception cref="InvalidOperationException"> /// Thrown when a SEC_VT_COMMAND is invalid, or NDR/NDR64 was not negotiated. /// </exception> public verification_trailer_t CreateVerificationTrailer( params SEC_VT_COMMAND[] commands) { if (commands == null) { throw new ArgumentNullException("commands"); } verification_trailer_t verificationTrailer = new verification_trailer_t(); verificationTrailer.header = new rpc_sec_verification_trailer(); verificationTrailer.header.signature = BitConverter.GetBytes(verification_trailer_t.SIGNATURE); List<SEC_VT> secVtList = new List<SEC_VT>(); for (int i = 0; i < commands.Length; i++) { switch (commands[i] & ~(SEC_VT_COMMAND.SEC_VT_COMMAND_END | SEC_VT_COMMAND.SEC_VT_MUST_PROCESS_COMMAND)) { case SEC_VT_COMMAND.SEC_VT_COMMAND_BITMASK_1: rpc_sec_vt_bitmask secVtBitmask = new rpc_sec_vt_bitmask(); secVtBitmask.command = commands[i]; //length: MUST be 0x0004. secVtBitmask.length = verification_trailer_t.SEC_VT_BITMASK_LENGTH; //bits: The bits field is a bitmask. //A server MUST ignore bits it does not understand. //Currently, there is only one bit defined: CLIENT_SUPPORT_HEADER_SIGNING //(bitmask of 0x00000001). If this bit is set, the PFC_SUPPORT_HEADER_SIGN //bit, as specified in section 2.2.2.3, MUST be present in the PDU header //for the bind PDU on this connection. secVtBitmask.bits = context.SupportsHeaderSign ? (uint)0x00000001 : 0; secVtList.Add(secVtBitmask); break; case SEC_VT_COMMAND.SEC_VT_COMMAND_HEADER2: rpc_sec_vt_header2 secVtHeader2 = new rpc_sec_vt_header2(); secVtHeader2.command = commands[i]; //length: MUST be 0x0010. secVtHeader2.length = verification_trailer_t.SEC_VT_HEADER2_LENGTH; //PTYPE: MUST be the same as the PTYPE field in the request PDU header. secVtHeader2.PTYPE = PTYPE; secVtHeader2.reserved1 = 0; secVtHeader2.reserved2 = 0; secVtHeader2.drep = packed_drep; secVtHeader2.call_id = call_id; secVtHeader2.p_cont_id = p_cont_id; secVtHeader2.opnum = opnum; secVtList.Add(secVtHeader2); break; case SEC_VT_COMMAND.SEC_VT_COMMAND_PCONTEXT: rpc_sec_vt_pcontext secVtPcontext = new rpc_sec_vt_pcontext(); secVtPcontext.command = commands[i]; //length: MUST be set to 0x28. secVtPcontext.length = verification_trailer_t.SEC_VT_PCONTEXT_LENGTH; secVtPcontext.interfaceId = new p_syntax_id_t(); secVtPcontext.interfaceId.if_uuid = context.InterfaceId; secVtPcontext.interfaceId.if_vers_major = context.InterfaceMajorVersion; secVtPcontext.interfaceId.if_vers_minor = context.InterfaceMinorVersion; secVtPcontext.transferSyntax = new p_syntax_id_t(); if (context.NdrVersion == RpceNdrVersion.NDR) { secVtPcontext.transferSyntax.if_uuid = RpceUtility.NDR_INTERFACE_UUID; secVtPcontext.transferSyntax.if_vers_major = RpceUtility.NDR_INTERFACE_MAJOR_VERSION; secVtPcontext.transferSyntax.if_vers_minor = RpceUtility.NDR_INTERFACE_MINOR_VERSION; } else if (context.NdrVersion == RpceNdrVersion.NDR64) { secVtPcontext.transferSyntax.if_uuid = RpceUtility.NDR64_INTERFACE_UUID; secVtPcontext.transferSyntax.if_vers_major = RpceUtility.NDR64_INTERFACE_MAJOR_VERSION; secVtPcontext.transferSyntax.if_vers_minor = RpceUtility.NDR64_INTERFACE_MINOR_VERSION; } else { throw new InvalidOperationException("Neither NDR nore NDR64 was negotiated."); } secVtList.Add(secVtPcontext); break; default: throw new InvalidOperationException("Invalid SEC_VT_COMMAND."); } } verificationTrailer.commands = secVtList.ToArray(); return verificationTrailer; }
/// <summary> /// Marshal the verification trailer to a byte array. /// </summary> /// <returns> /// A byte array. /// </returns> public byte[] ToBytes() { byte[] buf = new byte[GetSize()]; using (BinaryWriter writer = new BinaryWriter(new MemoryStream(buf))) { if (pad != null) { writer.Write(pad); } if (header.signature != null) { writer.Write(header.signature); } if (commands != null) { for (int i = 0; i < commands.Length; i++) { if (commands[i] != null) { Type type = commands[i].GetType(); if (type == typeof(rpc_sec_vt_bitmask)) { rpc_sec_vt_bitmask secVtBitmask = (rpc_sec_vt_bitmask)commands[i]; writer.Write((ushort)secVtBitmask.command); writer.Write(secVtBitmask.length); writer.Write(secVtBitmask.bits); } else if (type == typeof(rpc_sec_vt_header2)) { rpc_sec_vt_header2 secVtHeader2 = (rpc_sec_vt_header2)commands[i]; writer.Write((ushort)secVtHeader2.command); writer.Write(secVtHeader2.length); writer.Write((byte)secVtHeader2.PTYPE); writer.Write(secVtHeader2.reserved1); writer.Write(secVtHeader2.reserved2); writer.Write((ushort)secVtHeader2.drep.dataRepFormat); writer.Write(secVtHeader2.drep.reserved); writer.Write(secVtHeader2.call_id); writer.Write(secVtHeader2.p_cont_id); writer.Write(secVtHeader2.opnum); } else if (type == typeof(rpc_sec_vt_pcontext)) { rpc_sec_vt_pcontext secVtPcontext = (rpc_sec_vt_pcontext)commands[i]; writer.Write((ushort)secVtPcontext.command); writer.Write(secVtPcontext.length); writer.Write(secVtPcontext.interfaceId.if_uuid.ToByteArray()); writer.Write(secVtPcontext.interfaceId.if_vers_major); writer.Write(secVtPcontext.interfaceId.if_vers_minor); writer.Write(secVtPcontext.transferSyntax.if_uuid.ToByteArray()); writer.Write(secVtPcontext.transferSyntax.if_vers_major); writer.Write(secVtPcontext.transferSyntax.if_vers_minor); } else { // we called GetSize() before, this won't happen. throw new InvalidOperationException("Invalid SEC_VT type."); } } } } } return(buf); }
/// <summary> /// Unmarshal a verification trailer from byte array. /// </summary> /// <param name="verificationTrailerBuffer">byte array.</param> public void FromBytes(byte[] verificationTrailerBuffer) { int padLength = -1; for (int i = 0; i < verificationTrailerBuffer.Length; i++) { if ((verificationTrailerBuffer.Length - i) >= Marshal.SizeOf(verification_trailer_t.SIGNATURE) && BitConverter.ToUInt64(verificationTrailerBuffer, i) == verification_trailer_t.SIGNATURE) { padLength = i; } } if (padLength < 0) { throw new InvalidOperationException("verification_trailer not found."); } using (BinaryReader reader = new BinaryReader(new MemoryStream(verificationTrailerBuffer))) { pad = reader.ReadBytes(padLength); header.signature = reader.ReadBytes(sizeof(ulong)); List<SEC_VT> secVtList = new List<SEC_VT>(); while (reader.BaseStream.Position < verificationTrailerBuffer.Length) { if ((verificationTrailerBuffer.Length - reader.BaseStream.Position) < SEC_VT_HEADER_LENGTH) { break; } SEC_VT_COMMAND command = (SEC_VT_COMMAND)reader.ReadUInt16(); ushort length = reader.ReadUInt16(); if ((verificationTrailerBuffer.Length - reader.BaseStream.Position) < length) { //length of remain bytes is less than expected. break; } switch (command & ~(SEC_VT_COMMAND.SEC_VT_MUST_PROCESS_COMMAND | SEC_VT_COMMAND.SEC_VT_COMMAND_END)) { case SEC_VT_COMMAND.SEC_VT_COMMAND_BITMASK_1: rpc_sec_vt_bitmask secVtBitmask = new rpc_sec_vt_bitmask(); secVtBitmask.command = command; secVtBitmask.length = length; secVtBitmask.bits = reader.ReadUInt32(); secVtList.Add(secVtBitmask); break; case SEC_VT_COMMAND.SEC_VT_COMMAND_PCONTEXT: rpc_sec_vt_pcontext secVtPcontext = new rpc_sec_vt_pcontext(); secVtPcontext.command = command; secVtPcontext.length = length; secVtPcontext.interfaceId = new p_syntax_id_t(); secVtPcontext.interfaceId.if_uuid = new Guid(reader.ReadBytes(RpceUtility.GUID_SIZE)); secVtPcontext.interfaceId.if_vers_major = reader.ReadUInt16(); secVtPcontext.interfaceId.if_vers_minor = reader.ReadUInt16(); secVtPcontext.transferSyntax = new p_syntax_id_t(); secVtPcontext.transferSyntax.if_uuid = new Guid(reader.ReadBytes(RpceUtility.GUID_SIZE)); secVtPcontext.transferSyntax.if_vers_major = reader.ReadUInt16(); secVtPcontext.transferSyntax.if_vers_minor = reader.ReadUInt16(); secVtList.Add(secVtPcontext); break; case SEC_VT_COMMAND.SEC_VT_COMMAND_HEADER2: rpc_sec_vt_header2 secVtHeader2 = new rpc_sec_vt_header2(); secVtHeader2.command = command; secVtHeader2.length = length; secVtHeader2.PTYPE = (RpcePacketType)reader.ReadByte(); secVtHeader2.reserved1 = reader.ReadByte(); secVtHeader2.reserved2 = reader.ReadUInt16(); secVtHeader2.drep = new DataRepresentationFormatLabel(); secVtHeader2.drep.dataRepFormat = (RpceDataRepresentationFormat)reader.ReadUInt16(); secVtHeader2.drep.reserved = reader.ReadUInt16(); secVtHeader2.call_id = reader.ReadUInt32(); secVtHeader2.p_cont_id = reader.ReadUInt16(); secVtHeader2.opnum = reader.ReadUInt16(); secVtList.Add(secVtHeader2); break; default: //do nothing break; } } commands = secVtList.ToArray(); } }