/// <summary>
        /// Calling this method to be notified when a new RPC connection is coming.
        /// </summary>
        /// <param name="ifMatchFunc">Matching function.</param>
        /// <param name="timeout">Timeout of expecting a connection.</param>
        /// <param name="sessionContext">The sessionContext of binded connection.</param>
        /// <returns>If bind succeeded, return true; otherwise, false.</returns>
        private bool InternalExpectBind(
            RpcIfMatchFunc ifMatchFunc,
            TimeSpan timeout,
            ref RpceServerSessionContext sessionContext)
        {
            RpcePdu       receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext);
            RpceCoBindPdu bindPdu     = receivedPdu as RpceCoBindPdu;

            if (bindPdu == null)
            {
                throw new InvalidOperationException("Expect bind_pdu, but received others.");
            }

            RpcIf rpcIf = new RpcIf(sessionContext.InterfaceId, sessionContext.InterfaceMajorVersion, sessionContext.InterfaceMinorVersion);

            if (!ifMatchFunc(rpcIf))
            {
                // Interface doesn't match, response BindNak
                RpceCoBindNakPdu bindNakPdu =
                    rpceServer.CreateCoBindNakPdu(sessionContext, p_reject_reason_t.REASON_NOT_SPECIFIED, null);
                FragmentAndSendPdu(sessionContext, bindNakPdu);
                return(false);
            }

            RpceCoBindAckPdu bindAckPdu = rpceServer.CreateCoBindAckPdu(sessionContext);

            FragmentAndSendPdu(sessionContext, bindAckPdu);

            while (sessionContext.SecurityContext != null && sessionContext.SecurityContextNeedContinueProcessing)
            {
                receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext);
                RpceCoAlterContextPdu alterContextPdu = receivedPdu as RpceCoAlterContextPdu;
                RpceCoAuth3Pdu        auth3Pdu        = receivedPdu as RpceCoAuth3Pdu;

                if (alterContextPdu != null)
                {
                    RpceCoAlterContextRespPdu alterContextRespPdu =
                        rpceServer.CreateCoAlterContextRespPdu(sessionContext);

                    FragmentAndSendPdu(sessionContext, alterContextRespPdu);
                }
                else if (auth3Pdu != null)
                {
                    //Do nothing
                }
            }

            return(true);
        }
Beispiel #2
0
        public static RpceCoPdu DecodeCoPdu(
            RpceContext context,
            byte[] pduBytes)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

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

            RpceCoPdu pdu;

            //#2 byte is PTYPE
            RpcePacketType packageType = (RpcePacketType)pduBytes[2];
            //#3 byte is PFC_*** flags
            RpceCoPfcFlags pfcFlags = (RpceCoPfcFlags)pduBytes[3];

            RpceCoPfcFlags pfcFlagsNoFragment = RpceCoPfcFlags.PFC_FIRST_FRAG | RpceCoPfcFlags.PFC_LAST_FRAG;

            if (((pfcFlags & pfcFlagsNoFragment) != pfcFlagsNoFragment) &&
                (packageType == RpcePacketType.Bind ||
                 packageType == RpcePacketType.BindAck ||
                 packageType == RpcePacketType.AlterContext ||
                 packageType == RpcePacketType.AlterContextResp ||
                 packageType == RpcePacketType.Auth3))
            {
                //If it's a fragment and PTYPE is bind/bind_ack/alter_context/alter_context_resp
                //Windows RPC support version 5.0 only.
                //Bind fragment requires RPC ver 5.1.
                //We don't support it.
                throw new NotSupportedException("bind/bind_ack/alt_context/alt_context_resp/auth3 PDU fragment are not supported.");
            }
            else
            {
                switch (packageType)
                {
                case RpcePacketType.Bind:
                    pdu = new RpceCoBindPdu(context, pduBytes);
                    break;

                case RpcePacketType.BindAck:
                    pdu = new RpceCoBindAckPdu(context, pduBytes);
                    break;

                case RpcePacketType.BindNak:
                    pdu = new RpceCoBindNakPdu(context, pduBytes);
                    break;

                case RpcePacketType.AlterContext:
                    pdu = new RpceCoAlterContextPdu(context, pduBytes);
                    break;

                case RpcePacketType.AlterContextResp:
                    pdu = new RpceCoAlterContextRespPdu(context, pduBytes);
                    break;

                case RpcePacketType.Auth3:
                    pdu = new RpceCoAuth3Pdu(context, pduBytes);
                    break;

                case RpcePacketType.Request:
                    pdu = new RpceCoRequestPdu(context, pduBytes);
                    break;

                case RpcePacketType.Response:
                    pdu = new RpceCoResponsePdu(context, pduBytes);
                    break;

                case RpcePacketType.Fault:
                    pdu = new RpceCoFaultPdu(context, pduBytes);
                    break;

                case RpcePacketType.CoCancel:
                    pdu = new RpceCoCancelPdu(context, pduBytes);
                    break;

                case RpcePacketType.Orphaned:
                    pdu = new RpceCoOrphanedPdu(context, pduBytes);
                    break;

                case RpcePacketType.Shutdown:
                    pdu = new RpceCoShutdownPdu(context, pduBytes);
                    break;

                default:
                    throw new InvalidOperationException(
                              string.Format("Receive invalid packet - {0}.", packageType));
                }
            }

            return(pdu);
        }
        public RpceCoAlterContextRespPdu CreateCoAlterContextRespPdu(
            RpceServerSessionContext sessionContext)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

            RpceCoAlterContextRespPdu alterContextRespPdu = new RpceCoAlterContextRespPdu(sessionContext);

            alterContextRespPdu.rpc_vers = sessionContext.RpcVersionMajor;
            alterContextRespPdu.rpc_vers_minor = sessionContext.RpcVersionMinor;
            alterContextRespPdu.PTYPE = RpcePacketType.AlterContextResp;
            alterContextRespPdu.pfc_flags = RpceUtility.GeneratePfcFlags(sessionContext, RpcePacketType.AlterContextResp);
            alterContextRespPdu.packed_drep.dataRepFormat = sessionContext.PackedDataRepresentationFormat;
            alterContextRespPdu.packed_drep.reserved = 0;
            alterContextRespPdu.call_id = sessionContext.CurrentCallId;

            alterContextRespPdu.max_xmit_frag = 0;
            alterContextRespPdu.max_recv_frag = 0;
            alterContextRespPdu.assoc_group_id = 0;
            alterContextRespPdu.sec_addr.length = 0;
            alterContextRespPdu.sec_addr.port_spec = new byte[0];

            int sizeOfSecAddr = alterContextRespPdu.sec_addr.length + Marshal.SizeOf(alterContextRespPdu.sec_addr.length);
            alterContextRespPdu.pad2 = new byte[RpceUtility.Align(sizeOfSecAddr, 4) - sizeOfSecAddr];

            //there's only one presentation result in alter_context_resp
            alterContextRespPdu.p_result_list.n_results = 1;
            alterContextRespPdu.p_result_list.p_results = new p_result_t[1];
            alterContextRespPdu.p_result_list.p_results[0].result = p_cont_def_result_t.acceptance;
            alterContextRespPdu.p_result_list.p_results[0].reason = p_provider_reason_t.reason_not_specified;
            if (sessionContext.NdrVersion == RpceNdrVersion.NDR)
            {
                alterContextRespPdu.p_result_list.p_results[0].transfer_syntax.if_uuid
                    = RpceUtility.NDR_INTERFACE_UUID;
                alterContextRespPdu.p_result_list.p_results[0].transfer_syntax.if_vers_major
                    = RpceUtility.NDR_INTERFACE_MAJOR_VERSION;
                alterContextRespPdu.p_result_list.p_results[0].transfer_syntax.if_vers_minor
                    = RpceUtility.NDR_INTERFACE_MINOR_VERSION;
            }
            else if (sessionContext.NdrVersion == RpceNdrVersion.NDR64)
            {
                alterContextRespPdu.p_result_list.p_results[0].transfer_syntax.if_uuid
                    = RpceUtility.NDR64_INTERFACE_UUID;
                alterContextRespPdu.p_result_list.p_results[0].transfer_syntax.if_vers_major
                    = RpceUtility.NDR64_INTERFACE_MAJOR_VERSION;
                alterContextRespPdu.p_result_list.p_results[0].transfer_syntax.if_vers_minor
                    = RpceUtility.NDR64_INTERFACE_MINOR_VERSION;
            }

            alterContextRespPdu.AppendAuthenticationVerifier();
            alterContextRespPdu.SetLength();

            return alterContextRespPdu;
        }