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