/// <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);
        }
Example #2
0
        /// <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;
        }
Example #4
0
        /// <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();
            }
        }