示例#1
0
 /// <summary>
 /// Handle the received pdu from server.
 /// </summary>
 /// <param name="rpcePdu">
 /// Received pdu received from server.
 /// </param>
 /// <param name="responseStub">
 /// A byte array of the response stub of a method.
 /// RpceStubDecoder can be used to NDR un-marshal parameters to a byte array.
 /// </param>
 /// <exception cref="InvalidOperationException">
 /// Thrown when receive error from server or RPC connection has not been established.
 /// </exception>
 private void HandleRpcePdu(RpcePdu rpcePdu, out byte[] responseStub)
 {
     if (rpcePdu is RpceCoResponsePdu)
     {
         responseStub = (rpcePdu as RpceCoResponsePdu).stub;
     }
     else if (rpcePdu is RpceCoFaultPdu)
     {
         throw new InvalidOperationException((rpcePdu as RpceCoFaultPdu).status.ToString());
     }
     else
     {
         throw new InvalidOperationException(rpcePdu.GetType().ToString());
     }
 }
示例#2
0
        /// <summary>
        /// Parse the identifier of the call from the received pdu from server.
        /// </summary>
        /// <param name="rpcePdu">
        /// Received pdu received from server.
        /// </param>
        /// <exception cref="RpceDisconnectedException">
        /// Thrown when receive shutdown PDU.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when receive error from server.
        /// </exception>
        /// <returns>Return the identifier of the call if success, otherwise throw an exception.</returns>
        private uint ParseRpcePdu(RpcePdu rpcePdu)
        {
            if (rpcePdu is RpceCoResponsePdu)
            {
                return((rpcePdu as RpceCoResponsePdu).call_id);
            }
            else if (rpcePdu is RpceCoFaultPdu)
            {
                return((rpcePdu as RpceCoFaultPdu).call_id);
            }

            if (rpcePdu is RpceCoShutdownPdu)
            {
                throw new RpceDisconnectedException("Shutdown PDU received");
            }

            throw new InvalidOperationException(
                      string.Format("Unexpected packet type received - {0}.",
                                    rpcePdu.GetType().Name));
        }
        /// <summary>
        /// Parse the identifier of the call from the received pdu from server.
        /// </summary>
        /// <param name="rpcePdu">
        /// Received pdu received from server.
        /// </param>
        /// <exception cref="RpceDisconnectedException">
        /// Thrown when receive shutdown PDU.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when receive error from server.
        /// </exception>
        /// <returns>Return the identifier of the call if success, otherwise throw an exception.</returns>
        private uint ParseRpcePdu(RpcePdu rpcePdu)
        {
            if (rpcePdu is RpceCoResponsePdu)
            {
                return (rpcePdu as RpceCoResponsePdu).call_id;
            }
            else if (rpcePdu is RpceCoFaultPdu)
            {
                return (rpcePdu as RpceCoFaultPdu).call_id;
            }

            if (rpcePdu is RpceCoShutdownPdu)
            {
                throw new RpceDisconnectedException("Shutdown PDU received");
            }

            throw new InvalidOperationException(
                string.Format("Unexpected packet type received - {0}.",
                rpcePdu.GetType().Name));
        }
示例#4
0
        /// <summary>
        /// Connect and bind to a RPCE remote host.
        /// </summary>
        /// <param name="protocolSequence">
        /// A protocol sequence.<para/>
        /// Support ncacn_ip_tcp and ncacn_np only.
        /// </param>
        /// <param name="networkAddress">
        /// A network address of RPCE remote host.
        /// </param>
        /// <param name="endpoint">
        /// An endpoint that its format and content
        /// are associated with the protocol sequence.
        /// </param>
        /// <param name="transportCredential">
        /// If connect by SMB/SMB2, it's the security credential
        /// used by underlayer transport (SMB/SMB2).
        /// If connect by TCP, this parameter is ignored.
        /// </param>
        /// <param name="interfaceId">
        /// A Guid of interface_id that is binding to.
        /// </param>
        /// <param name="interfaceMajorVersion">
        /// interface_major_ver that is binding to.
        /// </param>
        /// <param name="interfaceMinorVersion">
        /// interface_minor_ver that is binding to.
        /// </param>
        /// <param name="securityContext">
        /// A security provider. If setting to null, indicate the default authentication type NTLM is selected.
        /// </param>
        /// <param name="connectSecurityContext">
        /// A security provider for connect authentication. If setting to null, indicate the default authentication type NTLM is selected.
        /// </param>
        /// <param name="authenticationLevel">
        /// An authentication level.
        /// </param>
        /// <param name="supportsHeaderSign">
        /// Indicates whether client supports header sign or not.
        /// </param>
        /// <param name="timeout">
        /// Timeout period.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown when protSeq, networkAddr or endpoint is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when receive error from server.
        /// </exception>
        public virtual void Bind(
            string protocolSequence,
            string networkAddress,
            string endpoint,
            AccountCredential transportCredential,
            Guid interfaceId,
            ushort interfaceMajorVersion,
            ushort interfaceMinorVersion,
            ClientSecurityContext securityContext,
            ClientSecurityContext connectSecurityContext,
            RpceAuthenticationLevel authenticationLevel,
            bool supportsHeaderSign,
            TimeSpan timeout)
        {
            if (protocolSequence == null)
            {
                throw new ArgumentNullException("protocolSequence");
            }
            if (networkAddress == null)
            {
                throw new ArgumentNullException("networkAddress");
            }
            if (endpoint == null)
            {
                throw new ArgumentNullException("endpoint");
            }

            // RPC over named-pipe does not support asynchronous call in this library.
            // http://msdn.microsoft.com/en-us/library/windows/desktop/aa373551(v=vs.85).aspx
            rpceClient.Context.IsAsynchronous = (string.Compare(protocolSequence, RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, true) != 0);

            rpceClient.Connect(protocolSequence, networkAddress, endpoint, transportCredential, timeout,
                               connectSecurityContext == null ? SecurityPackageType.Ntlm : connectSecurityContext.PackageType);

            rpceClient.SetAuthInfo(securityContext, authenticationLevel, rpceClient.Context.AuthenticationContextId);

            RpceCoBindPdu bindPdu = rpceClient.CreateCoBindPdu(
                //read from context, donot hardcode.
                rpceClient.Context.RpcVersionMinor,         // default is rpc vers 5.0
                supportsHeaderSign ? RpceCoPfcFlags.PFC_SUPPORT_HEADER_SIGN : RpceCoPfcFlags.None,
                rpceClient.ComputeNextCallId(),             // call id, default is 1
                rpceClient.Context.MaxTransmitFragmentSize, // max xmit frag
                rpceClient.Context.MaxReceiveFragmentSize,  // max recv frag
                rpceClient.Context.AssociateGroupId,        // assoc group id, default 0
                interfaceId,
                interfaceMajorVersion,
                interfaceMinorVersion,
                rpceClient.Context.NdrVersion,                                                                       // default is NDR
                (rpceClient.Context.BindTimeFeatureNegotiationBitmask != RpceBindTimeFeatureNegotiationBitmask.None) // default is None
                    ? (RpceBindTimeFeatureNegotiationBitmask?)rpceClient.Context.BindTimeFeatureNegotiationBitmask
                    : null);

            FragmentAndSendPdu(bindPdu);

            RpcePdu receivedPdu = ReceiveAndReassemblePdu(timeout);

            if (receivedPdu is RpceCoBindAckPdu)
            {
                if (rpceClient.Context.NdrVersion == RpceNdrVersion.None)
                {
                    throw new InvalidOperationException("Neither NDR nor NDR64 is supported.");
                }
            }
            else
            {
                RpceCoBindNakPdu bindNakPdu = receivedPdu as RpceCoBindNakPdu;
                if (bindNakPdu != null)
                {
                    throw new InvalidOperationException(bindNakPdu.provider_reject_reason.ToString());
                }
                else
                {
                    throw new InvalidOperationException(
                              string.Format("Unexpected packet type received - {0}.",
                                            receivedPdu.GetType().Name));
                }
            }

            while (rpceClient.Context.SecurityContext != null &&
                   rpceClient.Context.SecurityContext.NeedContinueProcessing)
            {
                RpceCoAlterContextPdu alterContextPdu = rpceClient.CreateCoAlterContextPdu();
                FragmentAndSendPdu(alterContextPdu);
                receivedPdu = ReceiveAndReassemblePdu(timeout);

                RpceCoFaultPdu faultPdu = receivedPdu as RpceCoFaultPdu;
                if (faultPdu != null)
                {
                    throw new InvalidOperationException(faultPdu.status.ToString());
                }

                if (!(receivedPdu is RpceCoAlterContextRespPdu))
                {
                    throw new InvalidOperationException("Expect alter_context_pdu, but received others.");
                }
            }

            if (rpceClient.Context.SecurityContext != null &&
                rpceClient.Context.SecurityContext.Token != null &&
                rpceClient.Context.SecurityContext.Token.Length != 0)
            {
                RpceCoAuth3Pdu auth3Pdu = rpceClient.CreateCoAuth3Pdu();
                FragmentAndSendPdu(auth3Pdu);
                // no expected response from server
                rpceClient.Context.OutstandingCalls.Remove(auth3Pdu.call_id);
            }

            if (rpceClient.Context.IsAsynchronous)
            {
                // Start the receiving thread to receive the response from server.
                cancellationToken = new CancellationTokenSource();
                receiveTask       = new Task(EventLoop, cancellationToken.Token); //new Thread(new ThreadStart(EventLoop));
                //receiveThread.IsBackground = true;
                receiveTask.Start();
            }
        }
 /// <summary>
 /// Handle the received pdu from server.
 /// </summary>
 /// <param name="rpcePdu">
 /// Received pdu received from server.
 /// </param>
 /// <param name="responseStub">
 /// A byte array of the response stub of a method.
 /// RpceStubDecoder can be used to NDR un-marshal parameters to a byte array.
 /// </param>
 /// <exception cref="InvalidOperationException">
 /// Thrown when receive error from server or RPC connection has not been established.
 /// </exception>
 private void HandleRpcePdu(RpcePdu rpcePdu, out byte[] responseStub)
 {
     if (rpcePdu is RpceCoResponsePdu)
     {
         responseStub = (rpcePdu as RpceCoResponsePdu).stub;
     }
     else if (rpcePdu is RpceCoFaultPdu)
     {
         throw new InvalidOperationException((rpcePdu as RpceCoFaultPdu).status.ToString());
     }
     else
     {
         throw new InvalidOperationException(rpcePdu.GetType().ToString());
     }
 }