Пример #1
0
        /// <summary>
        /// Append verification_trailer to stub.
        /// </summary>
        /// <param name="verificationTrailer">verification_trailer</param>
        /// <exception cref="ArgumentNullException">Thrown when verificationTrailer is null.</exception>
        public void AppendVerificationTrailerToStub(verification_trailer_t verificationTrailer)
        {
            if (verificationTrailer == null)
            {
                throw new ArgumentNullException("verificationTrailer");
            }

            if (stub == null)
            {
                stub = new byte[0];
            }

            stub = RpceUtility.AppendVerificationTrailerToStub(stub, verificationTrailer);

            if (auth_verifier != null)
            {
                auth_verifier_co_t authVerifier = auth_verifier.Value;
                authVerifier.auth_pad_length = (byte)(
                    RpceUtility.Align(stub.Length, RpceUtility.STUB_PAD_LENGTH) - stub.Length);
                authVerifier.auth_pad = new byte[authVerifier.auth_pad_length];
                auth_verifier         = authVerifier;
            }

            SetLength();
        }
Пример #2
0
        /// <summary>
        /// Append verification_trailer to stub.
        /// </summary>
        /// <param name="stub">The stub.</param>
        /// <param name="verificationTrailer">verification_trailer</param>
        /// <returns>The stub with verification_trailer.</returns>
        /// <exception cref="ArgumentNullException">Thrown when stub or verificationTrailer is null.</exception>
        public static byte[] AppendVerificationTrailerToStub(byte[] stub, verification_trailer_t verificationTrailer)
        {
            if (stub == null)
            {
                throw new ArgumentNullException("stub");
            }

            if (verificationTrailer == null)
            {
                throw new ArgumentNullException("verificationTrailer");
            }

            //The beginning of the header MUST be 4-byte aligned with respect to the beginning of the PDU.
            int padLength = RpceUtility.Align(stub.Length, 4) - stub.Length;

            verificationTrailer.pad = new byte[padLength];
            byte[] verificationTrailerBytes = verificationTrailer.ToBytes();
            return(ArrayUtility.ConcatenateArrays(stub, verificationTrailerBytes));
        }
Пример #3
0
        /// <summary>
        /// Send request to RPCE server.
        /// </summary>
        /// <param name="opnum">
        /// The opnum of a method.
        /// </param>
        /// <param name="requestStub">
        /// A byte array of the request stub of a method.<para/>
        /// RpceStubEncoder can be used to NDR marshal parameters to a byte array.
        /// </param>
        /// <param name="callId">
        /// The identifier of this call.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown when requestStub is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when receive error from server or RPC connection has not been established.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when this transport has been used as an synchronous transport.
        /// </exception>
        public virtual void SendRequest(
            ushort opnum,
            byte[] requestStub,
            out uint callId)
        {
            if (requestStub == null)
            {
                throw new ArgumentNullException("requestStub");
            }
            if (rpceClient.IsDisposed)
            {
                throw new InvalidOperationException("RPC connection has not been established.");
            }

            RpceCoRequestPdu requestPdu = rpceClient.CreateCoRequestPdu(
                opnum,
                requestStub);

            if (rpceClient.Context.AuthenticationType == RpceAuthenticationType.RPC_C_AUTHN_WINNT &&
                rpceClient.Context.AuthenticationLevel == RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY)
            {
                verification_trailer_t verificationTrailer = requestPdu.CreateVerificationTrailer(
                    SEC_VT_COMMAND.SEC_VT_COMMAND_BITMASK_1,
                    SEC_VT_COMMAND.SEC_VT_COMMAND_HEADER2,
                    SEC_VT_COMMAND.SEC_VT_COMMAND_PCONTEXT | SEC_VT_COMMAND.SEC_VT_COMMAND_END);
                requestPdu.AppendVerificationTrailerToStub(verificationTrailer);
            }

            FragmentAndSendPdu(requestPdu);

            lock (responseLock)
            {
                callId = requestPdu.call_id;
                outstandingCallIds.Add(callId);
            }
        }
Пример #4
0
        /// <summary>
        /// Extract verification_trailer from stub.
        /// </summary>
        /// <param name="stub">The stub.</param>
        /// <param name="startIndex">
        /// Input: The position of the end of stub (the beginning position to search for verification_trailer).
        /// Output: The start position of verification_trailer.
        /// </param>
        /// <returns>Returns verification_trailer if found; otherwise, returns null.</returns>
        /// <exception cref="ArgumentNullException">Thrown when stub is null.</exception>
        public static verification_trailer_t ExtractVerificationTrailerFromStub(byte[] stub, ref int startIndex)
        {
            if (stub == null)
            {
                throw new ArgumentNullException("stub");
            }

            //The beginning of the header MUST be 4-byte aligned with respect to the beginning of the PDU.
            for (int i = RpceUtility.Align(startIndex, 4); i < stub.Length; i += 4)
            {
                if ((stub.Length - i) >= Marshal.SizeOf(verification_trailer_t.SIGNATURE) &&
                    BitConverter.ToUInt64(stub, i) == verification_trailer_t.SIGNATURE)
                {
                    //found verification_trailer
                    byte[] verificationTrailerBuffer           = ArrayUtility.SubArray(stub, i);
                    verification_trailer_t verificationTrailer = new verification_trailer_t();
                    verificationTrailer.FromBytes(verificationTrailerBuffer);
                    startIndex = i;
                    return(verificationTrailer);
                }
            }

            return(null);
        }
Пример #5
0
        /// <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>
        /// Append verification_trailer to stub.
        /// </summary>
        /// <param name="verificationTrailer">verification_trailer</param>
        /// <exception cref="ArgumentNullException">Thrown when verificationTrailer is null.</exception>
        public void AppendVerificationTrailerToStub(verification_trailer_t verificationTrailer)
        {
            if (verificationTrailer == null)
            {
                throw new ArgumentNullException("verificationTrailer");
            }

            if (stub == null)
            {
                stub = new byte[0];
            }

            stub = RpceUtility.AppendVerificationTrailerToStub(stub, verificationTrailer);

            if (auth_verifier != null)
            {
                auth_verifier_co_t authVerifier = auth_verifier.Value;
                authVerifier.auth_pad_length = (byte)(
                    RpceUtility.Align(stub.Length, RpceUtility.STUB_PAD_LENGTH) - stub.Length);
                authVerifier.auth_pad = new byte[authVerifier.auth_pad_length];
                auth_verifier = authVerifier;
            }

            SetLength();
        }
        /// <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;
        }