コード例 #1
0
 /// <summary>
 ///  Removes the link between the rpce session context with its corresponding
 ///  nrpc session context.
 /// </summary>
 /// <param name="rpceSessionContext">The rpce layer session context</param>
 internal void RemoveSessionContext(RpceServerSessionContext rpceSessionContext)
 {
     lock (lockObj)
     {
         sessionContextMap.Remove(rpceSessionContext);
     }
 }
コード例 #2
0
        /// <summary>
        /// Lookup the RPCE session context.
        /// </summary>
        /// <param name="remoteEndpoint">remote Endpoint. (IPEndPoint or SmbFile)</param>
        /// <returns>The sessionContext with the specific key.</returns>
        internal RpceServerSessionContext LookupSessionContext(object remoteEndpoint)
        {
            string key = BuildSessionContextKey(remoteEndpoint);

            RpceServerSessionContext sessionContext;

            lock (this.sessions)
            {
                if (!this.sessions.TryGetValue(key, out sessionContext))
                {
                    sessionContext = null;
                }

                if (sessionContext == null)
                {
                    // Create / retrieve temp session when it is not created by user.
                    if (!this.tempSessions.TryGetValue(key, out sessionContext))
                    {
                        sessionContext = new RpceServerSessionContext(this, remoteEndpoint);
                        this.tempSessions.Add(key, sessionContext);
                    }
                }
            }

            return(sessionContext);
        }
コード例 #3
0
        /// <summary>
        /// Create and add a session context to the session collection.
        /// </summary>
        /// <param name="remoteEndpoint">remote Endpoint. (IPEndPoint or SmbFile)</param>
        /// <returns>The sessionContext with the specific key.</returns>
        internal RpceServerSessionContext CreateAndAddSessionContext(object remoteEndpoint)
        {
            string key = BuildSessionContextKey(remoteEndpoint);

            RpceServerSessionContext sessionContext;

            lock (this.sessions)
            {
                if (this.tempSessions.TryGetValue(key, out sessionContext))
                {
                    this.tempSessions.Remove(key);
                }
                else
                {
                    sessionContext = new RpceServerSessionContext(this, remoteEndpoint);
                }

                if (!this.sessions.ContainsKey(key))
                {
                    this.sessions.Add(key, sessionContext);
                }
            }

            return(sessionContext);
        }
コード例 #4
0
        /// <summary>
        /// Calling this method to be notified when a new RPC connection is coming.
        /// Users, who don't care about the coming of a new connection, just call ExpectCall directly.
        /// </summary>
        /// <param name="ifId">
        /// If_id to accept the bind. Null to accept all interface regardless the if_id.
        /// </param>
        /// <param name="ifMajorVer">
        /// If_major_ver to accept the bind. Null to accept all interface regardless the if_major_ver.
        /// </param>
        /// <param name="ifMinorVer">
        /// If_minor_ver to accept the bind. Null to accept all interface regardless the if_minor_ver.
        /// </param>
        /// <param name="timeout">Timeout of expecting a connection.</param>
        /// <param name="sessionContext">The sessionContext of binded connection.</param>
        /// <exception cref="InvalidOperationException">
        /// Thrown when receive error from server.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when securityProvider is null and auth_level is not NONE
        /// </exception>
        /// <exception cref="SspiException">
        /// Thrown when accept client token failed
        /// </exception>
        public virtual void ExpectBind(
            Guid?ifId,
            ushort?ifMajorVer,
            ushort?ifMinorVer,
            TimeSpan timeout,
            out RpceServerSessionContext sessionContext)
        {
            if (this.registeredInterfaceList.Count > 0)
            {
                throw new InvalidOperationException("Auto accept bind was turned on, ExpectBind is not allowed.");
            }

            DateTime t0 = DateTime.Now;

            sessionContext = rpceServer.ExpectConnect(timeout);

            RpcIfMatchFunc matchFunc = delegate(RpcIf rpcIf)
            {
                return(!((ifId != null && rpcIf.id != ifId.Value) ||
                         (ifMajorVer != null && rpcIf.majorVer != ifMajorVer.Value) ||
                         (ifMinorVer != null && rpcIf.minorVer != ifMinorVer.Value)));
            };

            while (!InternalExpectBind(matchFunc, timeout - (DateTime.Now - t0), ref sessionContext))
            {
                if ((DateTime.Now - t0) >= timeout)
                {
                    throw new TimeoutException();
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// Expect to receive a call.
        /// </summary>
        /// <param name="timeout">Timeout of expecting a call.</param>
        /// <param name="sessionContext">Session Context of the received call.</param>
        /// <param name="opnum">Operation number of the method invoked.</param>
        /// <returns>Received a byte array of the request stub from a client.</returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown when receive error from server.
        /// </exception>
        public virtual byte[] ExpectCall(
            TimeSpan timeout,
            out RpceServerSessionContext sessionContext,
            out ushort opnum)
        {
            sessionContext = null;

            RpcePdu          receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext);
            RpceCoRequestPdu requestPdu  = receivedPdu as RpceCoRequestPdu;

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

            opnum = requestPdu.opnum;

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

            return(stub);
        }
コード例 #6
0
 /// <summary>
 /// Fragment and send PDU.
 /// </summary>
 /// <param name="sessionContext">Context of the RPCE session</param>
 /// <param name="pdu">PDU to Fragment and send.</param>
 private void FragmentAndSendPdu(
     RpceServerSessionContext sessionContext,
     RpceCoPdu pdu)
 {
     if (pdu.PTYPE == RpcePacketType.Bind ||
         pdu.PTYPE == RpcePacketType.BindAck ||
         pdu.PTYPE == RpcePacketType.AlterContext ||
         pdu.PTYPE == RpcePacketType.AlterContextResp ||
         pdu.PTYPE == RpcePacketType.Auth3)
     {
         pdu.InitializeAuthenticationToken();
         pdu.SetLength();
         foreach (RpceCoPdu fragPdu in RpceUtility.FragmentPdu(sessionContext, pdu))
         {
             rpceServer.SendPdu(sessionContext, fragPdu);
         }
     }
     else
     {
         foreach (RpceCoPdu fragPdu in RpceUtility.FragmentPdu(sessionContext, pdu))
         {
             fragPdu.InitializeAuthenticationToken();
             rpceServer.SendPdu(sessionContext, fragPdu);
         }
     }
 }
コード例 #7
0
        /// <summary>
        /// Expect to disconnect from the specific client.
        /// </summary>
        /// <param name="timeout">Timeout of expecting to disconnect with client.</param>
        /// <param name="sessionContext">The sessionContext of expecting to disconnect.</param>
        public virtual void ExpectDisconnect(
            TimeSpan timeout,
            out RpceServerSessionContext sessionContext)
        {
            if (this.registeredInterfaceList.Count > 0)
            {
                throw new InvalidOperationException("Auto accept bind was turned on, ExpectBind is not allowed.");
            }

            sessionContext = null;
            this.rpceServer.ExpectDisconnect(timeout, ref sessionContext);
        }
コード例 #8
0
 /// <summary>
 /// Initialize a RpceTransportEvent.
 /// </summary>
 /// <param name="type">the type of the occurred event.</param>
 /// <param name="remoteEndpoint">the remote endpoint from which the event occurred.</param>
 /// <param name="localEndpoint">the local endpoint from which the event occurred.</param>
 /// <param name="serverContext">The server context.</param>
 /// <param name="sessionContext">The session context.</param>
 /// <param name="pdu">A received PDU.</param>
 internal RpceTransportEvent(
     EventType type,
     object remoteEndpoint,
     object localEndpoint,
     RpceServerContext serverContext,
     RpceServerSessionContext sessionContext,
     RpcePdu pdu) : base(type, remoteEndpoint, localEndpoint, pdu)
 {
     //because sessionContext might be null when accept a connection, we must pass it in.
     this.serverContext  = serverContext;
     this.sessionContext = sessionContext;
     this.pdu            = pdu;
 }
コード例 #9
0
        /// <summary>
        /// Send a Response to client.
        /// </summary>
        /// <param name="sessionContext">Context of the RPCE session.</param>
        /// <param name="responseStub">A byte array of the response stub send to client.</param>
        /// <exception cref="ArgumentNullException">Thrown when responseStub is null.</exception>
        public virtual void SendResponse(
            RpceServerSessionContext sessionContext,
            byte[] responseStub)
        {
            if (responseStub == null)
            {
                throw new ArgumentNullException("responseStub");
            }

            RpceCoResponsePdu responsePdu = this.rpceServer.CreateCoResponsePdu(sessionContext, responseStub);

            FragmentAndSendPdu(sessionContext, responsePdu);
        }
コード例 #10
0
 /// <summary>
 /// Initialize a RpceTransportEvent.
 /// </summary>
 /// <param name="type">the type of the occurred event.</param>
 /// <param name="remoteEndpoint">the remote endpoint from which the event occurred.</param>
 /// <param name="localEndpoint">the local endpoint from which the event occurred.</param>
 /// <param name="serverContext">The server context.</param>
 /// <param name="sessionContext">The session context.</param>
 /// <param name="pdu">A received PDU.</param>
 internal RpceTransportEvent(
     EventType type,
     object remoteEndpoint,
     object localEndpoint,
     RpceServerContext serverContext,
     RpceServerSessionContext sessionContext,
     RpcePdu pdu)
     : base(type, remoteEndpoint, localEndpoint, pdu)
 {
     //because sessionContext might be null when accept a connection, we must pass it in.
     this.serverContext = serverContext;
     this.sessionContext = sessionContext;
     this.pdu = pdu;
 }
コード例 #11
0
        /// <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);
        }
コード例 #12
0
 /// <summary>
 /// Lookup the RPCE session context.
 /// </summary>
 /// <param name="remoteEndpoint">remote Endpoint. (IPEndPoint or SmbFile)</param>
 /// <returns>The sessionContext with the specific key.</returns>
 internal RpceServerSessionContext LookupSessionContext(object remoteEndpoint)
 {
     lock (this.serverContexts)
     {
         foreach (KeyValuePair <string, RpceServerContext> item in this.serverContexts)
         {
             RpceServerSessionContext sessionContext
                 = item.Value.LookupSessionContext(remoteEndpoint);
             if (sessionContext != null)
             {
                 return(sessionContext);
             }
         }
     }
     return(null);
 }
コード例 #13
0
        /// <summary>
        /// Remove a session context from the session collection.
        /// </summary>
        ///<param name="sessionContext">The session to remove.</param>
        internal void RemoveSessionContext(RpceServerSessionContext sessionContext)
        {
            string key = BuildSessionContextKey(sessionContext.RemoteEndpoint);

            lock (this.sessions)
            {
                if (this.sessions.ContainsKey(key))
                {
                    this.sessions.Remove(key);
                }

                if (this.tempSessions.ContainsKey(key))
                {
                    this.tempSessions.Remove(key);
                }
            }
        }
コード例 #14
0
 /// <summary>
 ///  Look up the NRPC session context using the session context of RPCE
 /// </summary>
 /// <param name="rpceSessionContext">The RPCE layer session context</param>
 /// <param name="sessionContext">The  corresponding NRPC session context</param>
 /// <returns>Whether the rpce session is a new session</returns>
 internal bool LookupSessionContext(RpceServerSessionContext rpceSessionContext,
     out NrpcServerSessionContext sessionContext)
 {
     lock (lockObj)
     {
         if (sessionContextMap.ContainsKey(rpceSessionContext))
         {
             sessionContext = sessionContextMap[rpceSessionContext];
             return false;
         }
         else
         {
             sessionContext = new NrpcServerSessionContext();
             sessionContextMap[rpceSessionContext] = sessionContext;
             return true;
         }
     }
 }
コード例 #15
0
        /// <summary>
        /// Generate PFC_*** based on context and package type.
        /// </summary>
        /// <param name="context">Context of the session.</param>
        /// <param name="packageType">package type.</param>
        /// <returns>RFC_*** flag.</returns>
        internal static RpceCoPfcFlags GeneratePfcFlags(RpceContext context, RpcePacketType packageType)
        {
            RpceServerSessionContext sessionContext = context as RpceServerSessionContext;

            RpceCoPfcFlags flags = RpceCoPfcFlags.PFC_FIRST_FRAG | RpceCoPfcFlags.PFC_LAST_FRAG;

            if (sessionContext == null) //client-side
            {
                if (context.SupportsConcurrentMultiplexing)
                {
                    flags |= RpceCoPfcFlags.PFC_CONC_MPX;
                }
            }
            else if ( //server-side
                (packageType == RpcePacketType.BindAck &&
                 sessionContext.ServerContext.SupportsConcurrentMultiplexing) ||    // first response, read server context
                sessionContext.SupportsConcurrentMultiplexing)    // if it's not first response, we can read session context
            {
                flags |= RpceCoPfcFlags.PFC_CONC_MPX;
            }

            if ((packageType == RpcePacketType.Bind ||
                 packageType == RpcePacketType.BindAck ||
                 packageType == RpcePacketType.AlterContext ||
                 packageType == RpcePacketType.AlterContextResp)
                &&
                context.SupportsHeaderSign)
            {
                if (sessionContext == null || //client-side
                    sessionContext.ServerContext.SupportsHeaderSign)    //server-side
                {
                    flags |= RpceCoPfcFlags.PFC_SUPPORT_HEADER_SIGN;
                }
            }

            return(flags);
        }
コード例 #16
0
        /// <summary>
        /// Send a PDU to a specific connected client.
        /// </summary>
        /// <param name="pdu">Rpce PDU to send.</param>
        /// <param name="sessionContext">Context of the RPCE session.</param>
        /// <exception cref="ArgumentNullException">
        /// Thrown when sessionContext or pdu is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when underlayer transport was not established.
        /// Thrown when protocol sequence is unknown.
        /// </exception>
        public virtual void SendPdu(
            RpceServerSessionContext sessionContext,
            RpcePdu pdu)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

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

            EnsureTransportIsValid();

            sessionContext.UpdateContextOnSendingPdu(pdu);

            if (sessionContext.ProtocolSequence.Equals(
                RpceUtility.RPC_OVER_TCPIP_PROTOCOL_SEQUENCE,
                StringComparison.OrdinalIgnoreCase))
            {
                this.tcpTransport.SendPacket(sessionContext.RemoteEndpoint, pdu);
            }
            else if (sessionContext.ProtocolSequence.Equals(
                RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE,
                StringComparison.OrdinalIgnoreCase))
            {
                lock (sessionContext.smbSendingLocker)
                {
                    sessionContext.smbBufferSending = ArrayUtility.ConcatenateArrays(
                        sessionContext.smbBufferSending,
                        pdu.ToBytes());

                    if (sessionContext.smbSendingFunc != null)
                    {
                        sessionContext.smbSendingFunc();
                    }
                }
            }
            else
            {
                throw new InvalidOperationException("Unknown protocol sequence.");
            }
        }
コード例 #17
0
        private void ProcessReceivedData(
            RpceServerSessionContext sessionContext,
            byte[] buf)
        {
            RpceServerContext serverContext = sessionContext.ServerContext;
            string namedPipeName = serverContext.Endpoint;
            object fid = sessionContext.fsOpen.FileId;

            buf = ArrayUtility.ConcatenateArrays(sessionContext.smbBufferReceiving, buf);

            int consumedLength;
            int expectedLength;

            RpceCoPdu[] pduList = (RpceCoPdu[])this.RpceDecodePduCallback(
                fid,
                buf,
                out consumedLength,
                out expectedLength);

            for (int i = 0; i < pduList.Length; i++)
            {
                this.receivedTransportEvents.Enqueue(
                    new RpceTransportEvent(
                        EventType.ReceivedPacket,
                        fid,
                        namedPipeName,
                        serverContext,
                        sessionContext,
                        pduList[i]));
            }

            sessionContext.smbBufferReceiving = ArrayUtility.SubArray(buf, consumedLength);
        }
コード例 #18
0
        /// <summary>
        /// Receive and reassemble PDU.
        /// </summary>
        /// <param name="timeout">Timeout of receiving PDU</param>
        /// <param name="sessionContext">Context of the RPCE session</param>
        /// <returns>Received PDU</returns>
        private RpcePdu ReceiveAndReassemblePdu(
            TimeSpan timeout,
            ref RpceServerSessionContext sessionContext)
        {
            RpcePdu receivedPdu;
            bool    expectAny = sessionContext == null;

WaitForEvent:

            if (expectAny)
            {
                sessionContext = null;
            }
            EventType eventType = rpceServer.ExpectEvent(timeout, ref sessionContext, out receivedPdu);

            if (this.registeredInterfaceList.Count > 0)
            {
                // auto accept connect/bind/disconnect
                if (eventType == EventType.Connected)
                {
                    RpcIfMatchFunc matchFunc = delegate(RpcIf rpcIf)
                    {
                        for (int i = 0; i < this.registeredInterfaceList.Count; i++)
                        {
                            if (this.registeredInterfaceList[i].Equals(rpcIf))
                            {
                                return(true);
                            }
                        }
                        return(false);
                    };
                    InternalExpectBind(matchFunc, timeout, ref sessionContext);
                    goto WaitForEvent;
                }
                else if (eventType == EventType.Disconnected)
                {
                    goto WaitForEvent;
                }
                else
                {
                    // it is a PDU.
                }
            }
            else if (eventType != EventType.ReceivedPacket)
            {
                throw new InvalidOperationException(
                          string.Format("Unexpected event ({0}) received.", eventType));
            }


            RpceCoPdu receivedCoPdu = receivedPdu as RpceCoPdu;

            if (receivedCoPdu == null)
            {
                return(receivedPdu);
            }

            List <RpceCoPdu> pduList = new List <RpceCoPdu>();

            pduList.Add(receivedCoPdu);

            while ((receivedCoPdu.pfc_flags & RpceCoPfcFlags.PFC_LAST_FRAG) == 0)
            {
                receivedPdu = rpceServer.ExpectPdu(timeout, ref sessionContext);

                receivedCoPdu = receivedPdu as RpceCoPdu;
                if (receivedCoPdu == null)
                {
                    throw new InvalidOperationException("CL PDU received inside a connection.");
                }

                pduList.Add(receivedCoPdu);
            }

            return(RpceUtility.ReassemblePdu(sessionContext, pduList.ToArray()));
        }
コード例 #19
0
 /// <summary>
 /// Disconnect with a client.
 /// </summary>
 /// <param name="sessionContext">Context of the RPCE session</param>
 public virtual void Disconnect(RpceServerSessionContext sessionContext)
 {
     this.rpceServer.Disconnect(sessionContext);
 }
コード例 #20
0
 /// <summary>
 /// Send a Fault to client.
 /// </summary>
 /// <param name="sessionContext">Context of the RPCE session.</param>
 /// <param name="statusCode">Status code.</param>
 public virtual void SendFault(RpceServerSessionContext sessionContext, uint statusCode)
 {
     RpceCoFaultPdu faultPdu = this.rpceServer.CreateCoFaultPdu(sessionContext, null, statusCode);
     FragmentAndSendPdu(sessionContext, faultPdu);
 }
コード例 #21
0
        /// <summary>
        /// Send a Response to client.
        /// </summary>
        /// <param name="sessionContext">Context of the RPCE session.</param>
        /// <param name="responseStub">A byte array of the response stub send to client.</param>
        /// <exception cref="ArgumentNullException">Thrown when responseStub is null.</exception>
        public virtual void SendResponse(
            RpceServerSessionContext sessionContext,
            byte[] responseStub)
        {
            if (responseStub == null)
            {
                throw new ArgumentNullException("responseStub");
            }

            RpceCoResponsePdu responsePdu = this.rpceServer.CreateCoResponsePdu(sessionContext, responseStub);
            FragmentAndSendPdu(sessionContext, responsePdu);
        }
コード例 #22
0
        /// <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;
        }
コード例 #23
0
        /// <summary>
        /// Lookup the RPCE session context.
        /// </summary>
        /// <param name="remoteEndpoint">remote Endpoint. (IPEndPoint or SmbFile)</param>
        /// <returns>The sessionContext with the specific key.</returns>
        internal RpceServerSessionContext LookupSessionContext(object remoteEndpoint)
        {
            string key = BuildSessionContextKey(remoteEndpoint);

            RpceServerSessionContext sessionContext;
            lock (this.sessions)
            {
                if (!this.sessions.TryGetValue(key, out sessionContext))
                {
                    sessionContext = null;
                }

                if (sessionContext == null)
                {
                    // Create / retrieve temp session when it is not created by user.
                    if (!this.tempSessions.TryGetValue(key, out sessionContext))
                    {
                        sessionContext = new RpceServerSessionContext(this, remoteEndpoint);
                        this.tempSessions.Add(key, sessionContext);
                    }
                }
            }

            return sessionContext;
        }
コード例 #24
0
        private static byte[] PrepareSendingBuffer(RpceServerSessionContext sessionContext)
        {
            byte[] buf = sessionContext.smbBufferSending;
            sessionContext.smbBufferSending = new byte[0];

            if (sessionContext.smbMaxSendingLength < buf.Length)
            {
                sessionContext.smbBufferSending = ArrayUtility.SubArray(
                    buf,
                    sessionContext.smbMaxSendingLength);
                buf = ArrayUtility.SubArray(
                    buf,
                    0,
                    sessionContext.smbMaxSendingLength);
            }

            return buf;
        }
コード例 #25
0
 /// <summary>
 /// Create a RpceCoRequestPdu.
 /// </summary>
 /// <param name="sessionContext">Context of the RPCE session.</param>
 /// <param name="opnum">Operation number (opnum) to 
 /// inform a callback server of the operation it should invoke.</param>
 /// <param name="stub">Request stub.</param>
 /// <returns>Created RpceCoRequestPdu.</returns>
 /// <exception cref="ArgumentNullException">Thrown when sessionContext is null.</exception>
 public RpceCoRequestPdu CreateCoRequestPdu(
     RpceServerSessionContext sessionContext,
     ushort opnum,
     byte[] stub)
 {
     return CreateCoRequestPdu(sessionContext, opnum, sessionContext.CurrentCallId, stub);
 }
コード例 #26
0
        public RpceCoFaultPdu CreateCoFaultPdu(
            RpceServerSessionContext sessionContext,
            byte[] stub,
            uint statusCode)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

            RpceCoFaultPdu faultPdu = new RpceCoFaultPdu(sessionContext);

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

            faultPdu.alloc_hint = (uint)(stub == null ? 0 : stub.Length);
            faultPdu.p_cont_id = sessionContext.ContextIdentifier;
            faultPdu.cancel_count = 0;
            faultPdu.reserved = 0;
            faultPdu.status = statusCode;
            faultPdu.reserved2 = 0;
            faultPdu.stub = stub;

            faultPdu.AppendAuthenticationVerifier();
            faultPdu.SetLength();

            return faultPdu;
        }
コード例 #27
0
        public RpceCoBindNakPdu CreateCoBindNakPdu(
            RpceServerSessionContext sessionContext,
            p_reject_reason_t rejectReason,
            byte[] extendedErrorInfo)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

            RpceCoBindNakPdu bindNakPdu = new RpceCoBindNakPdu(sessionContext);

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

            bindNakPdu.provider_reject_reason = rejectReason;
            bindNakPdu.versions.n_protocols = 1; // only one rpc version in server context.
            bindNakPdu.versions.p_protocols = new version_t[bindNakPdu.versions.n_protocols];
            // It's the supported rpc versions, so we response version number in server context.
            bindNakPdu.versions.p_protocols[0].major = sessionContext.ServerContext.RpcVersionMajor;
            bindNakPdu.versions.p_protocols[0].major = sessionContext.ServerContext.RpcVersionMinor;

            int sizeOfReasonAndVersions = Marshal.SizeOf(typeof(ushort)); // bindNakPdu.provider_reject_reason
            sizeOfReasonAndVersions += Marshal.SizeOf(bindNakPdu.versions.n_protocols);
            sizeOfReasonAndVersions += Marshal.SizeOf(typeof(version_t)) * bindNakPdu.versions.n_protocols;
            bindNakPdu.pad = new byte[RpceUtility.Align(sizeOfReasonAndVersions, 4) - sizeOfReasonAndVersions];

            if (extendedErrorInfo != null)
            {
                bindNakPdu.signature = RpceUtility.BINDNAK_SIGNATURE;
                bindNakPdu.extended_error_info = extendedErrorInfo;
            }

            bindNakPdu.SetLength();

            return bindNakPdu;
        }
コード例 #28
0
        public RpceCoBindAckPdu CreateCoBindAckPdu(
            RpceServerSessionContext sessionContext)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

            RpceCoBindAckPdu bindAckPdu = new RpceCoBindAckPdu(sessionContext);

            float serverRpcVersion
                = (float)sessionContext.ServerContext.RpcVersionMajor
                + (float)sessionContext.ServerContext.RpcVersionMinor / 10.0f;
            float proposedRpcVersion
                = (float)sessionContext.RpcVersionMajor
                + (float)sessionContext.RpcVersionMinor / 10.0f;
            float rpcVersion = Math.Min(serverRpcVersion, proposedRpcVersion);

            bindAckPdu.rpc_vers = (byte)Math.Truncate(rpcVersion);
            bindAckPdu.rpc_vers_minor = (byte)((rpcVersion - Math.Truncate(rpcVersion)) * 10.0f);
            bindAckPdu.PTYPE = RpcePacketType.BindAck;
            bindAckPdu.pfc_flags = RpceUtility.GeneratePfcFlags(sessionContext, RpcePacketType.BindAck);
            bindAckPdu.packed_drep.dataRepFormat = sessionContext.PackedDataRepresentationFormat;
            bindAckPdu.packed_drep.reserved = 0;
            bindAckPdu.call_id = sessionContext.CurrentCallId;

            bindAckPdu.max_xmit_frag = sessionContext.MaxTransmitFragmentSize;
            bindAckPdu.max_recv_frag = sessionContext.MaxReceiveFragmentSize;
            bindAckPdu.assoc_group_id = sessionContext.AssociateGroupId;
            if (sessionContext.SecondaryAddress == null)
            {
                bindAckPdu.sec_addr.port_spec = new byte[0];
            }
            else
            {
                bindAckPdu.sec_addr.port_spec = Encoding.ASCII.GetBytes(sessionContext.SecondaryAddress);
            }
            bindAckPdu.sec_addr.length = (ushort)bindAckPdu.sec_addr.port_spec.Length;

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

            RpceNdrVersion ndrVersion = sessionContext.ServerContext.NdrVersion;
            List<p_result_t> presentationResultList = new List<p_result_t>();
            for (int i = 0; i < sessionContext.PresentationContextsTable.Count; i++)
            {
                p_result_t pResult = new p_result_t();
                RpceNdrVersion proposedNdrVersion = sessionContext.PresentationContextsTable.Values[i];
                if ((proposedNdrVersion & ndrVersion) != 0)
                {
                    pResult.result = p_cont_def_result_t.acceptance;
                    // donot accept any more NDR version.
                    ndrVersion = RpceNdrVersion.None;
                }
                else
                {
                    pResult.result = p_cont_def_result_t.provider_rejection;
                }
                pResult.reason = p_provider_reason_t.reason_not_specified;
                if (proposedNdrVersion == RpceNdrVersion.NDR)
                {
                    pResult.transfer_syntax.if_uuid = RpceUtility.NDR_INTERFACE_UUID;
                    pResult.transfer_syntax.if_vers_major = RpceUtility.NDR_INTERFACE_MAJOR_VERSION;
                    pResult.transfer_syntax.if_vers_minor = RpceUtility.NDR_INTERFACE_MINOR_VERSION;
                }
                else if (proposedNdrVersion == RpceNdrVersion.NDR64)
                {
                    pResult.transfer_syntax.if_uuid = RpceUtility.NDR64_INTERFACE_UUID;
                    pResult.transfer_syntax.if_vers_major = RpceUtility.NDR64_INTERFACE_MAJOR_VERSION;
                    pResult.transfer_syntax.if_vers_minor = RpceUtility.NDR64_INTERFACE_MINOR_VERSION;
                }
                presentationResultList.Add(pResult);
            }
            if (sessionContext.BindTimeFeatureNegotiationBitmask != RpceBindTimeFeatureNegotiationBitmask.None)
            {
                RpceBindTimeFeatureNegotiationBitmask bindTimeFeatureNegotiationBitmask
                    = sessionContext.BindTimeFeatureNegotiationBitmask;
                if ((bindTimeFeatureNegotiationBitmask
                    & RpceBindTimeFeatureNegotiationBitmask.KeepConnectionOnOrphanSupported)
                    != 0)
                {
                    bindTimeFeatureNegotiationBitmask
                        |= RpceBindTimeFeatureNegotiationBitmask.KeepConnectionOnOrphanSupported_Resp;
                }
                bindTimeFeatureNegotiationBitmask
                    &= (sessionContext.ServerContext.SupportsSecurityContextMultiplexing
                        ? RpceBindTimeFeatureNegotiationBitmask.SecurityContextMultiplexingSupported
                        : RpceBindTimeFeatureNegotiationBitmask.None)
                        |
                       (sessionContext.ServerContext.SupportsKeepConnectionOnOrphan
                        ? RpceBindTimeFeatureNegotiationBitmask.KeepConnectionOnOrphanSupported_Resp
                        : RpceBindTimeFeatureNegotiationBitmask.None);

                p_result_t pResult = new p_result_t();
                pResult.result = p_cont_def_result_t.negotiate_ack;
                pResult.reason = (p_provider_reason_t)bindTimeFeatureNegotiationBitmask;
                presentationResultList.Add(pResult);
            }

            bindAckPdu.p_result_list.n_results = (byte)presentationResultList.Count;
            bindAckPdu.p_result_list.p_results = presentationResultList.ToArray();

            bindAckPdu.AppendAuthenticationVerifier();
            bindAckPdu.SetLength();

            return bindAckPdu;
        }
コード例 #29
0
 /// <summary>
 /// Disconnect with a client.
 /// </summary>
 /// <param name="sessionContext">Context of the RPCE session</param>
 public virtual void Disconnect(RpceServerSessionContext sessionContext)
 {
     this.rpceServer.Disconnect(sessionContext);
 }
コード例 #30
0
        /// <summary>
        /// Receive and reassemble PDU.
        /// </summary>
        /// <param name="timeout">Timeout of receiving PDU</param>
        /// <param name="sessionContext">Context of the RPCE session</param>
        /// <returns>Received PDU</returns>
        private RpcePdu ReceiveAndReassemblePdu(
            TimeSpan timeout,
            ref RpceServerSessionContext sessionContext)
        {
            RpcePdu receivedPdu;
            bool expectAny = sessionContext == null;

            WaitForEvent:

            if (expectAny)
            {
                sessionContext = null;
            }
            EventType eventType = rpceServer.ExpectEvent(timeout, ref sessionContext, out receivedPdu);
            if (this.registeredInterfaceList.Count > 0)
            {
                // auto accept connect/bind/disconnect
                if (eventType == EventType.Connected)
                {
                    RpcIfMatchFunc matchFunc = delegate(RpcIf rpcIf)
                    {
                        for (int i = 0; i < this.registeredInterfaceList.Count; i++)
                        {
                            if (this.registeredInterfaceList[i].Equals(rpcIf))
                            {
                                return true;
                            }
                        }
                        return false;
                    };
                    InternalExpectBind(matchFunc, timeout, ref sessionContext);
                    goto WaitForEvent;
                }
                else if (eventType == EventType.Disconnected)
                {
                    goto WaitForEvent;
                }
                else
                {
                    // it is a PDU.
                }
            }
            else if (eventType != EventType.ReceivedPacket)
            {
                throw new InvalidOperationException(
                    string.Format("Unexpected event ({0}) received.", eventType));
            }

            RpceCoPdu receivedCoPdu = receivedPdu as RpceCoPdu;
            if (receivedCoPdu == null)
            {
                return receivedPdu;
            }

            List<RpceCoPdu> pduList = new List<RpceCoPdu>();
            pduList.Add(receivedCoPdu);

            while ((receivedCoPdu.pfc_flags & RpceCoPfcFlags.PFC_LAST_FRAG) == 0)
            {
                receivedPdu = rpceServer.ExpectPdu(timeout, ref sessionContext);

                receivedCoPdu = receivedPdu as RpceCoPdu;
                if (receivedCoPdu == null)
                {
                    throw new InvalidOperationException("CL PDU received inside a connection.");
                }

                pduList.Add(receivedCoPdu);
            }

            return RpceUtility.ReassemblePdu(sessionContext, pduList.ToArray());
        }
コード例 #31
0
        /// <summary>
        /// Disconnect from the specific client
        /// </summary>
        /// <param name="sessionContext">Context of session</param>
        /// <exception cref="ArgumentNullException">
        /// Thrown when sessionContext is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when server was not started.
        /// </exception>
        public virtual void Disconnect(RpceServerSessionContext sessionContext)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

            EnsureTransportIsValid();

            if (sessionContext.ProtocolSequence.Equals(
                RpceUtility.RPC_OVER_TCPIP_PROTOCOL_SEQUENCE,
                StringComparison.OrdinalIgnoreCase))
            {
                this.tcpTransport.Disconnect(sessionContext.RemoteEndpoint);
            }
            else if (sessionContext.ProtocolSequence.Equals(
                RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE,
                StringComparison.OrdinalIgnoreCase))
            {
                if (sessionContext.fsConnection != null)
                {
                    Smb.SmbServerConnection connection = sessionContext.fsConnection as Smb.SmbServerConnection;
                    if (connection.OpenList.Count == 0
                        || (connection.OpenList.Count == 1 && connection.OpenList[0].Equals(sessionContext.fsOpen)))
                    {
                        this.smbTransport.Disconnect(connection);
                    }
                }
            }

            sessionContext.ServerContext.RemoveSessionContext(sessionContext);
        }
コード例 #32
0
 /// <summary>
 /// Fragment and send PDU.
 /// </summary>
 /// <param name="sessionContext">Context of the RPCE session</param>
 /// <param name="pdu">PDU to Fragment and send.</param>
 private void FragmentAndSendPdu(
     RpceServerSessionContext sessionContext,
     RpceCoPdu pdu)
 {
     if (pdu.PTYPE == RpcePacketType.Bind
         || pdu.PTYPE == RpcePacketType.BindAck
         || pdu.PTYPE == RpcePacketType.AlterContext
         || pdu.PTYPE == RpcePacketType.AlterContextResp
         || pdu.PTYPE == RpcePacketType.Auth3)
     {
         pdu.InitializeAuthenticationToken();
         pdu.SetLength();
         foreach (RpceCoPdu fragPdu in RpceUtility.FragmentPdu(sessionContext, pdu))
         {
             rpceServer.SendPdu(sessionContext, fragPdu);
         }
     }
     else
     {
         foreach (RpceCoPdu fragPdu in RpceUtility.FragmentPdu(sessionContext, pdu))
         {
             fragPdu.InitializeAuthenticationToken();
             rpceServer.SendPdu(sessionContext, fragPdu);
         }
     }
 }
コード例 #33
0
        /// <summary>
        /// Expect to disconnect from the client.
        /// </summary>
        /// <param name="timeout">Timeout of expecting a disconnect.</param>
        /// <param name="sessionContext">The sessionContext of expecting to disconnect.</param>
        /// <exception cref="InvalidOperationException">
        /// Thrown when unknown object was received from transport.
        /// Thrown when server was not started.
        /// </exception>
        public virtual void ExpectDisconnect(
            TimeSpan timeout,
            ref RpceServerSessionContext sessionContext)
        {
            RpcePdu pdu;

            EventType eventType = ExpectEvent(
                timeout,
                ref sessionContext,
                out pdu);

            if (eventType != EventType.Disconnected)
            {
                throw new InvalidOperationException(
                    string.Format("{0} (unexpected) event received.", eventType));
            }
        }
コード例 #34
0
        /// <summary>
        /// Send a Fault to client.
        /// </summary>
        /// <param name="sessionContext">Context of the RPCE session.</param>
        /// <param name="statusCode">Status code.</param>
        public virtual void SendFault(RpceServerSessionContext sessionContext, uint statusCode)
        {
            RpceCoFaultPdu faultPdu = this.rpceServer.CreateCoFaultPdu(sessionContext, null, statusCode);

            FragmentAndSendPdu(sessionContext, faultPdu);
        }
コード例 #35
0
        /// <summary>
        /// Expect an event (connect, disconnect, pdu received) with the specific sessionContext.
        /// </summary>
        /// <param name="timeout">Timeout of expecting a PDU.</param>
        /// <param name="sessionContext">
        /// Session context to receive the event.
        /// Null means expect event on all sessions.
        /// </param>
        /// <param name="pdu">The PDU if receiving a packet; otherwise, null.</param>
        /// <returns>The expected PDU. It is null when event is connect or disconnect.</returns>
        /// <returns>The event type.</returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown when server was not started.
        /// </exception>
        public virtual EventType ExpectEvent(
            TimeSpan timeout,
            ref RpceServerSessionContext sessionContext,
            out RpcePdu pdu)
        {
            EnsureTransportIsValid();

            RpceEventFilter filter;
            if (sessionContext == null)
            {
                filter = new RpceEventFilter(
                EventType.Connected | EventType.ReceivedPacket | EventType.Disconnected);
            }
            else
            {
                filter = new RpceEventFilter(
                EventType.Connected | EventType.ReceivedPacket | EventType.Disconnected,
                    sessionContext.RemoteEndpoint);
            }

            RpceTransportEvent transportEvent =
                this.receivedTransportEvents.Dequeue(timeout, filter.EventFilter);
            ValidateTransportEvent(
                transportEvent,
                EventType.Connected | EventType.ReceivedPacket | EventType.Disconnected);

            if (transportEvent.EventType == EventType.Connected)
            {
                pdu = null;
                RpceServerContext serverContext = transportEvent.ServerContext;
                sessionContext = serverContext.CreateAndAddSessionContext(
                    transportEvent.RemoteEndPoint);
                return EventType.Connected;
            }

            sessionContext = transportEvent.SessionContext;
            if (sessionContext == null)
            {
                throw new InvalidOperationException(
                    "Session context was not found for this disconnect event.");
            }

            if (transportEvent.EventType == EventType.ReceivedPacket)
            {
                pdu = transportEvent.Pdu;
                if (pdu == null)
                {
                    throw new InvalidOperationException("Unknown object received from transport.");
                }
                sessionContext.UpdateContextOnReceivingPdu(pdu);

                return EventType.ReceivedPacket;
            }

            if (transportEvent.EventType == EventType.Disconnected)
            {
                pdu = null;
                transportEvent.ServerContext.RemoveSessionContext(sessionContext);
                return EventType.Disconnected;
            }

            throw new InvalidOperationException("unknown event type");
        }
コード例 #36
0
        /// <summary>
        /// Expect to disconnect from the specific client.
        /// </summary>
        /// <param name="timeout">Timeout of expecting to disconnect with client.</param>
        /// <param name="sessionContext">The sessionContext of expecting to disconnect.</param>
        public virtual void ExpectDisconnect(
            TimeSpan timeout,
            out RpceServerSessionContext sessionContext)
        {
            if (this.registeredInterfaceList.Count > 0)
            {
                throw new InvalidOperationException("Auto accept bind was turned on, ExpectBind is not allowed.");
            }

            sessionContext = null;
            this.rpceServer.ExpectDisconnect(timeout, ref sessionContext);
        }
コード例 #37
0
        /// <summary>
        /// Expect a Pdu with the specific sessionContext.
        /// </summary>
        /// <param name="timeout">Timeout of expecting a PDU.</param>
        /// <param name="sessionContext">
        /// Session Context to receive PDU.
        /// Null means expect PDU on all sessions.
        /// </param>
        /// <returns>The expected PDU.</returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown when server was not started.
        /// </exception>
        public virtual RpcePdu ExpectPdu(
            TimeSpan timeout,
            ref RpceServerSessionContext sessionContext)
        {
            RpcePdu pdu;

            EventType eventType = ExpectEvent(
                timeout,
                ref sessionContext,
                out pdu);

            if (eventType != EventType.ReceivedPacket)
            {
                throw new InvalidOperationException(
                    string.Format("{0} (unexpected) event received.", eventType));
            }

            return pdu;
        }
コード例 #38
0
        /// <summary>
        /// Expect to receive a call.
        /// </summary>
        /// <param name="timeout">Timeout of expecting a call.</param>
        /// <param name="sessionContext">Session Context of the received call.</param>
        /// <param name="opnum">Operation number of the method invoked.</param>
        /// <returns>Received a byte array of the request stub from a client.</returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown when receive error from server.
        /// </exception>
        public virtual byte[] ExpectCall(
            TimeSpan timeout,
            out RpceServerSessionContext sessionContext,
            out ushort opnum)
        {
            sessionContext = null;

            RpcePdu receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext);
            RpceCoRequestPdu requestPdu = receivedPdu as RpceCoRequestPdu;

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

            opnum = requestPdu.opnum;

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

            return stub;
        }
コード例 #39
0
        /// <summary>
        /// Remove a session from the server context.
        /// </summary>
        /// <param name="sessionContext">Context of the RPCE session.</param>
        /// <exception cref="ArgumentNullException">Thrown when sessionContext is null.</exception>
        public virtual void RemoveSessionContext(RpceServerSessionContext sessionContext)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

            for (int i = 0; i < this.ServerContexts.Count; i++)
            {
                this.ServerContexts[i].RemoveSessionContext(sessionContext);
            }
        }
コード例 #40
0
        public RpceCoResponsePdu CreateCoResponsePdu(
            RpceServerSessionContext sessionContext,
            uint callId,
            byte[] stub)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

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

            RpceCoResponsePdu responsePdu = new RpceCoResponsePdu(sessionContext);

            responsePdu.rpc_vers = sessionContext.RpcVersionMajor;
            responsePdu.rpc_vers_minor = sessionContext.RpcVersionMinor;
            responsePdu.PTYPE = RpcePacketType.Response;
            responsePdu.pfc_flags = RpceUtility.GeneratePfcFlags(sessionContext, RpcePacketType.Response);
            responsePdu.packed_drep.dataRepFormat = sessionContext.PackedDataRepresentationFormat;
            responsePdu.packed_drep.reserved = 0;
            responsePdu.call_id = callId;

            responsePdu.alloc_hint = (uint)stub.Length;
            responsePdu.p_cont_id = sessionContext.ContextIdentifier;
            responsePdu.stub = stub;
            responsePdu.cancel_count = 0;
            responsePdu.reserved = 0;

            responsePdu.AppendAuthenticationVerifier();
            responsePdu.SetLength();

            return responsePdu;
        }
コード例 #41
0
        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;
        }
コード例 #42
0
        /// <summary>
        /// Create and add a session context to the session collection.
        /// </summary>
        /// <param name="remoteEndpoint">remote Endpoint. (IPEndPoint or SmbFile)</param>
        /// <returns>The sessionContext with the specific key.</returns>
        internal RpceServerSessionContext CreateAndAddSessionContext(object remoteEndpoint)
        {
            string key = BuildSessionContextKey(remoteEndpoint);

            RpceServerSessionContext sessionContext;
            lock (this.sessions)
            {
                if (this.tempSessions.TryGetValue(key, out sessionContext))
                {
                    this.tempSessions.Remove(key);
                }
                else
                {
                    sessionContext = new RpceServerSessionContext(this, remoteEndpoint);
                }

                if (!this.sessions.ContainsKey(key))
                {
                    this.sessions.Add(key, sessionContext);
                }
            }

            return sessionContext;
        }
コード例 #43
0
 /// <summary>
 /// Create a RpceCoResponsePdu, the call_id is set to current call_id.
 /// The server maintains a current call_id for each connection.
 /// The current call_id is the highest call_id that the server has processed on this connection.
 /// </summary>
 /// <param name="sessionContext">Context of the RPCE session.</param>
 /// <param name="stub">Response stub.</param>
 /// <returns>Created RpceCoResponsePdu.</returns>
 public RpceCoResponsePdu CreateCoResponsePdu(
     RpceServerSessionContext sessionContext,
     byte[] stub)
 {
     return this.CreateCoResponsePdu(sessionContext, sessionContext.CurrentCallId, stub);
 }
コード例 #44
0
        /// <summary>
        /// Remove a session context from the session collection.
        /// </summary>
        ///<param name="sessionContext">The session to remove.</param>
        internal void RemoveSessionContext(RpceServerSessionContext sessionContext)
        {
            string key = BuildSessionContextKey(sessionContext.RemoteEndpoint);
            lock (this.sessions)
            {
                if (this.sessions.ContainsKey(key))
                {
                    this.sessions.Remove(key);
                }

                if (this.tempSessions.ContainsKey(key))
                {
                    this.tempSessions.Remove(key);
                }
            }
        }
コード例 #45
0
        public RpceCoShutdownPdu CreateCoShutdownPdu(RpceServerSessionContext sessionContext)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

            RpceCoShutdownPdu shutdownPdu = new RpceCoShutdownPdu(sessionContext);

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

            shutdownPdu.AppendAuthenticationVerifier();
            shutdownPdu.SetLength();

            return shutdownPdu;
        }