예제 #1
0
        private void Accept_Completed(Socket none, ServerAsyncEventArgs e)
        {
            Socket      acceptSocket = e.AcceptSocket;
            SocketError socketError  = e.SocketError;

            while (true)
            {
                int num = Thread.VolatileRead(ref this.acceptBacklog);
                if (this.isRunning && num <= this.minAcceptBacklog)
                {
                    break;
                }
                if (Interlocked.CompareExchange(ref this.acceptBacklog, num - 1, num) == num)
                {
                    goto Block_3;
                }
            }
            e.AcceptSocket = null;
            this.listener.AcceptAsync(e, new ServerAsyncEventArgs.CompletedEventHandler(this.Accept_Completed));
            goto IL_66;
Block_3:
            EventArgsManager.Put(e);
IL_66:
            Server <C> .Connection <C> connection = this.CreateConnection(acceptSocket, socketError);
            if (connection != null)
            {
                this.NewTcpConnection(connection);
            }
        }
예제 #2
0
 private void Receive_Completed(Socket socket, ServerAsyncEventArgs e)
 {
     try
     {
         Server <C> .Connection <C> connection;
         this.connections.TryGetValue(e.RemoteEndPoint, out connection);
         if (connection != null && connection.Socket == socket && connection.Id == e.ConnectionId)
         {
             while (true)
             {
                 if (e != null)
                 {
                     connection.ReceiveQueue.Put(e);
                     e = null;
                 }
                 e = connection.ReceiveQueue.GetCurrent();
                 if (e == null)
                 {
                     goto IL_D4;
                 }
                 bool flag = true;
                 if (this.isRunning && e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
                 {
                     flag = !this.OnTcpReceived(connection, ref e);
                 }
                 if (flag)
                 {
                     break;
                 }
                 connection.ReceiveQueue.Next();
                 if (e == null)
                 {
                     e = EventArgsManager.Get();
                 }
                 else
                 {
                     e.SetDefaultValue();
                 }
                 if (this.TcpReceiveAsync(connection, e))
                 {
                     e = null;
                 }
             }
             this.connections.Remove(connection.RemoteEndPoint, connection);
             this.EndTcpConnection(connection);
         }
         IL_D4 :;
     }
     finally
     {
         if (e != null)
         {
             EventArgsManager.Put(ref e);
         }
     }
 }
예제 #3
0
 public void Dispose()
 {
     if (this.isPooled)
     {
         BufferManager.Free(ref this.segment);
         this.socketArgs.Dispose();
         return;
     }
     EventArgsManager.Put(this);
 }
예제 #4
0
                public void Put(ServerAsyncEventArgs e)
                {
                    int num = e.SequenceNumber % this.size;

                    Interlocked.Exchange <ServerAsyncEventArgs>(ref this.queue[num], e);
                    if (this.disposed && Interlocked.Exchange <ServerAsyncEventArgs>(ref this.queue[num], null) != null)
                    {
                        EventArgsManager.Put(e);
                    }
                }
예제 #5
0
 public void Dispose()
 {
     if (isPooled)
     {
         BufferManager.Free(ref segment);
         socketArgs.Dispose();
     }
     else
     {
         EventArgsManager.Put(this);
     }
 }
예제 #6
0
        public ServerAsyncEventArgs CreateDeepCopy()
        {
            ServerAsyncEventArgs serverAsyncEventArgs = EventArgsManager.Get();

            serverAsyncEventArgs.CopyAddressesFrom(this);
            serverAsyncEventArgs.offsetOffset = this.offsetOffset;
            serverAsyncEventArgs.count        = this.count;
            serverAsyncEventArgs.AllocateBuffer();
            serverAsyncEventArgs.bytesTransferred    = this.bytesTransferred;
            serverAsyncEventArgs.UserTokenForSending = this.UserTokenForSending;
            System.Buffer.BlockCopy(this.Buffer, this.Offset, serverAsyncEventArgs.Buffer, serverAsyncEventArgs.Offset, serverAsyncEventArgs.Count);
            return(serverAsyncEventArgs);
        }
예제 #7
0
                public void Dispose()
                {
                    this.disposed = true;
                    ServerAsyncEventArgs serverAsyncEventArgs = null;

                    for (int i = 0; i < this.queue.Length; i++)
                    {
                        if (this.queue[i] != null)
                        {
                            serverAsyncEventArgs = Interlocked.Exchange <ServerAsyncEventArgs>(ref this.queue[i], null);
                        }
                        if (serverAsyncEventArgs != null)
                        {
                            EventArgsManager.Put(ref serverAsyncEventArgs);
                        }
                    }
                }
예제 #8
0
        public ServerAsyncEventArgs CreateDeepCopy()
        {
            var e2 = EventArgsManager.Get();

            e2.CopyAddressesFrom(this);

            e2.offsetOffset = offsetOffset;
            e2.count        = count;
            e2.AllocateBuffer();

            e2.bytesTransferred    = bytesTransferred;
            e2.UserTokenForSending = UserTokenForSending;

            System.Buffer.BlockCopy(Buffer, Offset, e2.Buffer, e2.Offset, e2.Count);

            return(e2);
        }
예제 #9
0
        private ArraySegment <byte> Detach(ref ServerAsyncEventArgs e, int size)
        {
            ServerAsyncEventArgs serverAsyncEventArgs = null;

            if (e.BytesTransferred > size)
            {
                serverAsyncEventArgs = e.CreateDeepCopy();
            }
            ArraySegment <byte> result = e.DetachBuffer();

            EventArgsManager.Put(ref e);
            if (serverAsyncEventArgs != null)
            {
                e = serverAsyncEventArgs;
            }
            return(result);
        }
예제 #10
0
 private void EndTcpConnection(Server <C> .Connection <C> connection)
 {
     if (connection.Close())
     {
         this.OnEndTcpConnection(connection);
         if (connection.Socket.Connected)
         {
             try
             {
                 connection.Socket.Shutdown(SocketShutdown.Both);
             }
             catch (SocketException)
             {
             }
         }
         if (connection.IsSocketAccepted && this.socketReuseEnabled)
         {
             try
             {
                 try
                 {
                     ServerAsyncEventArgs serverAsyncEventArgs = EventArgsManager.Get();
                     serverAsyncEventArgs.FreeBuffer();
                     serverAsyncEventArgs.DisconnectReuseSocket = true;
                     serverAsyncEventArgs.Completed             = new ServerAsyncEventArgs.CompletedEventHandler(this.Disconnect_Completed);
                     if (!connection.Socket.DisconnectAsync(serverAsyncEventArgs))
                     {
                         serverAsyncEventArgs.OnCompleted(connection.Socket);
                     }
                 }
                 catch (SocketException)
                 {
                 }
             }
             catch (NotSupportedException)
             {
                 this.socketReuseEnabled = false;
             }
         }
         if (!this.socketReuseEnabled)
         {
             connection.Socket.Close();
         }
     }
 }
예제 #11
0
 private void Server_Sent(Server <C> server, ServerAsyncEventArgs e)
 {
     try
     {
         if (this.Sent != null)
         {
             this.Sent(this, ref e);
         }
         if (e != null)
         {
             EventArgsManager.Put(e);
         }
     }
     catch (Exception innerException)
     {
         throw new Exception("Error in Sent event handler", innerException);
     }
 }
예제 #12
0
        private ArraySegment <byte> Detach(ref ServerAsyncEventArgs e, int size)
        {
            ServerAsyncEventArgs copy = null;

            if (e.BytesTransferred > size)
            {
                copy = e.CreateDeepCopy();
            }

            var result = e.DetachBuffer();

            EventArgsManager.Put(ref e);
            if (copy != null)
            {
                e = copy;
            }

            return(result);
        }
예제 #13
0
                public void Dispose()
                {
                    disposed = true;

                    var e = default(ServerAsyncEventArgs);

                    for (int i = 0; i < queue.Length; i++)
                    {
                        if (queue[i] != null)
                        {
                            e = Interlocked.Exchange <ServerAsyncEventArgs>(ref queue[i], null);
                        }

                        if (e != null)
                        {
                            EventArgsManager.Put(ref e);
                        }
                    }
                }
예제 #14
0
        private void NewTcpConnection(Server <C> .Connection <C> connection)
        {
            this.OnNewTcpConnection(connection);
            ServerAsyncEventArgs serverAsyncEventArgs;

            for (int i = 0; i < this.receiveQueueSize; i++)
            {
                serverAsyncEventArgs = EventArgsManager.Get();
                if (!this.TcpReceiveAsync(connection, serverAsyncEventArgs))
                {
                    connection.ReceiveQueue.Put(serverAsyncEventArgs);
                }
            }
            serverAsyncEventArgs = connection.ReceiveQueue.GetCurrent();
            if (serverAsyncEventArgs != null)
            {
                this.Receive_Completed(connection.Socket, serverAsyncEventArgs);
            }
        }
예제 #15
0
        private void EndTcpConnection(Connection <C> connection)
        {
            if (connection.Close())
            {
                OnEndTcpConnection(connection);

                if (connection.Socket.Connected)
                {
                    try { connection.Socket.Shutdown(SocketShutdown.Both); }
                    catch (SocketException) { }
                }

                if (connection.IsSocketAccepted && socketReuseEnabled)
                {
                    try
                    {
                        try
                        {
                            var e = EventArgsManager.Get();

                            e.FreeBuffer();
                            e.DisconnectReuseSocket = true;
                            e.Completed             = Disconnect_Completed;

                            if (connection.Socket.DisconnectAsync(e) == false)
                            {
                                e.OnCompleted(connection.Socket);
                            }
                        }
                        catch (SocketException) { }
                    }
                    catch (NotSupportedException)
                    {
                        socketReuseEnabled = false;
                    }
                }

                if (socketReuseEnabled == false)
                {
                    connection.Socket.Close();
                }
            }
        }
예제 #16
0
        private void ReceiveFrom_Completed(Socket socket, ServerAsyncEventArgs e)
        {
            while (isRunning)
            {
                if (e.SocketError == SocketError.Success)
                {
                    OnReceived(null, ref e);

                    if (e == null)
                    {
                        e = EventArgsManager.Get();
                    }

                    PrepareBuffer(e);

                    try
                    {
                        if (socket.ReceiveFromAsync(e))
                        {
                            e = null;
                            break;
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                    }
                }
                else
                {
                    if (isRunning)
                    {
                        Dispose();
                        OnFailed(new ServerInfoEventArgs(realEndPoint, e.SocketError));
                    }
                }
            }

            if (e != null)
            {
                EventArgsManager.Put(e);
            }
        }
예제 #17
0
 private void EnqueueAsyncAccepts(object stateInfo)
 {
     lock (this.sync)
     {
         while (true)
         {
             int num = Thread.VolatileRead(ref this.acceptBacklog);
             if (!this.isRunning || num >= this.minAcceptBacklog)
             {
                 break;
             }
             if (Interlocked.CompareExchange(ref this.acceptBacklog, num + 1, num) == num)
             {
                 ServerAsyncEventArgs serverAsyncEventArgs = EventArgsManager.Get();
                 serverAsyncEventArgs.FreeBuffer();
                 this.listener.AcceptAsync(serverAsyncEventArgs, new ServerAsyncEventArgs.CompletedEventHandler(this.Accept_Completed));
             }
         }
     }
 }
예제 #18
0
                public void Put(ServerAsyncEventArgs e)
                {
                    int index = e.SequenceNumber % size;

#if DEBUG
                    if (queue[index] != null)
                    {
                        throw new InvalidOperationException();
                    }
#endif

                    Interlocked.Exchange <ServerAsyncEventArgs>(ref queue[index], e);

                    if (disposed)
                    {
                        if (Interlocked.Exchange <ServerAsyncEventArgs>(ref queue[index], null) != null)
                        {
                            EventArgsManager.Put(e);
                        }
                    }
                }
예제 #19
0
 public ServersManager(ServersManagerConfig config)
 {
     if (!BufferManager.IsInitialized())
     {
         BufferManager.Initialize(256);
     }
     if (!EventArgsManager.IsInitialized())
     {
         EventArgsManager.Initialize();
     }
     this.running           = false;
     this.sync              = new object();
     this.protocolPorts     = new List <ProtocolPort>();
     this.servers           = new ThreadSafeDictionary <ServerEndPoint, Server <C> >();
     this.fakeServers       = new ThreadSafeDictionary <ServerEndPoint, Server <C> >();
     this.AddressPredicate  = new Func <NetworkInterface, IPInterfaceProperties, UnicastIPAddressInformation, bool>(ServersManager <C> .DefaultAddressPredicate);
     this.FakeAddressAction = new Func <ServerEndPoint, IPEndPoint>(ServersManager <C> .DefaultFakeAddressAction);
     this.config            = config;
     this.nextPort          = config.MinPort;
     this.logger            = new Logger();
 }
예제 #20
0
        private void EnqueueBuffers(Object stateInfo)
        {
            int count = (int)stateInfo;

            lock (sync)
            {
                if (socket != null)
                {
                    for (int i = 0; i < count && isRunning; i++)
                    {
                        var e = EventArgsManager.Get();

                        PrepareBuffer(e);
                        if (socket.ReceiveFromAsync(e) == false)
                        {
                            e.OnCompleted(socket);
                        }
                    }
                }
            }
        }
예제 #21
0
        private void EnqueueBuffers(object stateInfo)
        {
            int num = (int)stateInfo;

            lock (this.sync)
            {
                if (this.socket != null)
                {
                    int num2 = 0;
                    while (num2 < num && this.isRunning)
                    {
                        ServerAsyncEventArgs serverAsyncEventArgs = EventArgsManager.Get();
                        this.PrepareBuffer(serverAsyncEventArgs);
                        if (!this.socket.ReceiveFromAsync(serverAsyncEventArgs))
                        {
                            serverAsyncEventArgs.OnCompleted(this.socket);
                        }
                        num2++;
                    }
                }
            }
        }
예제 #22
0
        private void NewTcpConnection(Connection <C> connection)
        {
            OnNewTcpConnection(connection);

            ServerAsyncEventArgs e;

            for (int i = 0; i < receiveQueueSize; i++)
            {
                e = EventArgsManager.Get();

                if (TcpReceiveAsync(connection, e) == false)
                {
                    connection.ReceiveQueue.Put(e);
                }
            }

            e = connection.ReceiveQueue.GetCurrent();
            if (e != null)
            {
                Receive_Completed(connection.Socket, e);
            }
        }
예제 #23
0
        private void EnqueueAsyncAccepts(Object stateInfo)
        {
            lock (sync)
            {
                for (; ;)
                {
                    int backlog = Thread.VolatileRead(ref acceptBacklog);
                    if (isRunning && backlog < minAcceptBacklog)
                    {
                        if (Interlocked.CompareExchange(ref acceptBacklog, backlog + 1, backlog) == backlog)
                        {
                            var e = EventArgsManager.Get();
                            e.FreeBuffer();

                            listener.AcceptAsync(e, Accept_Completed);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
예제 #24
0
        private void Receive_Completed(Socket socket, ServerAsyncEventArgs e)
        {
            try
            {
                Connection <C> connection;
                connections.TryGetValue(e.RemoteEndPoint, out connection);

                if (connection != null && connection.Socket == socket && connection.Id == e.ConnectionId)
                {
                    for (; ;)
                    {
                        if (e != null)
                        {
                            connection.ReceiveQueue.Put(e);
                            e = null;
                        }

                        e = connection.ReceiveQueue.GetCurrent();
                        if (e == null)
                        {
                            break;
                        }

                        bool close = true;
                        if (isRunning && e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
                        {
                            close = !OnTcpReceived(connection, ref e);
                        }

                        if (close)
                        {
                            connections.Remove(connection.RemoteEndPoint, connection);
                            EndTcpConnection(connection);

                            break;
                        }
                        else
                        {
                            connection.ReceiveQueue.Next();
                        }

                        if (e == null)
                        {
                            e = EventArgsManager.Get();
                        }
                        else
                        {
                            e.SetDefaultValue();
                        }

                        if (TcpReceiveAsync(connection, e))
                        {
                            e = null;
                        }
                    }
                }
#if DEBUG
                else
                {
                    if (e.BytesTransferred > 0)
                    {
                        Console.WriteLine("ERROR: {0}, conn-handle: {1}, socket-handle: {2}, ip: {3}", e.BytesTransferred,
                                          (connection == null) ? "Null" : connection.Socket.Handle.ToString(), socket.Handle.ToString(),
                                          e.RemoteEndPoint.ToString());
                    }
                }
#endif
            }
            finally
            {
                if (e != null)
                {
                    EventArgsManager.Put(ref e);
                }
            }
        }
예제 #25
0
        unsafe private bool DecryptData(ref ServerAsyncEventArgs e, Connection <C> connection)
        {
            var context = connection.SspiContext;
            var message = context.SecBufferDesc5;

            if (context.Buffer.IsValid && e != null)
            {
                if (context.Buffer.CopyTransferredFrom(e, 0) == false)
                {
                    return(false);
                }
            }

            for (; ;)
            {
                // prepare buffer
                //
                message.Buffers[0].BufferType = BufferType.SECBUFFER_DATA;
                if (context.Buffer.IsValid)
                {
                    SetSecBuffer(ref message.Buffers[0], context);
                }
                else
                {
                    SetSecBuffer(ref message.Buffers[0], e);
                }

                message.Buffers[1].SetBufferEmpty();
                message.Buffers[2].SetBufferEmpty();
                message.Buffers[3].SetBufferEmpty();
                message.Buffers[4].SetBufferEmpty();



                // call SSPI
                //
                var result = Sspi.SafeDecryptMessage(ref context.Handle, ref message, 0, null);


                // analize result
                //
                int extraIndex = message.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0);
                int dataIndex  = message.GetBufferIndex(BufferType.SECBUFFER_DATA, 0);

                switch (result)
                {
                case SecurityStatus.SEC_E_OK:

                    if (dataIndex >= 0)
                    {
                        if (context.Buffer.IsInvalid)
                        {
                            if (extraIndex >= 0)
                            {
                                if (context.Buffer.CopyFrom(message.Buffers[extraIndex]) == false)
                                {
                                    return(false);
                                }
                            }

                            e.Offset           = message.Buffers[dataIndex].Offset;
                            e.BytesTransferred = message.Buffers[dataIndex].Size;
                            e.SetMaxCount();

                            if (OnReceived(connection, ref e) == false)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            var buffer = context.Buffer.Detach();

                            if (extraIndex >= 0)
                            {
                                if (context.Buffer.CopyFrom(message.Buffers[extraIndex]) == false)
                                {
                                    return(false);
                                }
                            }


                            // create eventarg and call onreceived event
                            //
                            var e2 = EventArgsManager.Get();

                            base.PrepareEventArgs(connection, e2);

                            e2.AttachBuffer(buffer);
                            e2.Offset           = message.Buffers[dataIndex].Offset;
                            e2.BytesTransferred = message.Buffers[dataIndex].Size;
                            e2.SetMaxCount();

                            bool continue1 = OnReceived(connection, ref e2);

                            if (e2 != null)
                            {
                                EventArgsManager.Put(e2);
                            }

                            if (continue1 == false)
                            {
                                return(false);
                            }
                        }

                        if (extraIndex >= 0)
                        {
                            continue;
                        }

                        return(true);
                    }

                    return(false);


                case SecurityStatus.SEC_E_INCOMPLETE_MESSAGE:

                    if (context.Buffer.IsInvalid)
                    {
                        if (context.Buffer.CopyTransferredFrom(e, 0) == false)
                        {
                            return(false);
                        }
                    }

                    return(true);


                case SecurityStatus.SEC_I_RENEGOTIATE:

                    // MSDN: Renegotiation is not supported for Schannel kernel mode. The
                    // caller should either ignore this return value or shut down the
                    // connection.
                    // If the value is ignored, either the client or the server might shut
                    // down the connection as a result.

                    return(false);


                default:
                    return(false);
                }
            }
        }
예제 #26
0
        private unsafe bool Handshake(ServerAsyncEventArgs ie, Connection <C> connection)
        {
            int contextAttr         = 0;
            ServerAsyncEventArgs oe = null;
            var context             = connection.SspiContext;
            var input  = context.SecBufferDesc2[0];
            var output = context.SecBufferDesc2[1];

            try
            {
                if (context.Buffer.IsValid && ie != null)
                {
                    if (context.Buffer.CopyTransferredFrom(ie, 0) == false)
                    {
                        return(false);
                    }
                }

                for (; ;)
                {
                    // prepare input buffer
                    //
                    input.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN;
                    if (context.Buffer.IsValid)
                    {
                        SetSecBuffer(ref input.Buffers[0], context);
                    }
                    else
                    {
                        SetSecBuffer(ref input.Buffers[0], ie);
                    }

                    input.Buffers[1].SetBufferEmpty();


                    // prepare output buffer
                    //
                    if (oe == null)
                    {
                        oe = EventArgsManager.Get();
                    }
                    oe.AllocateBuffer();

                    output.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN;
                    output.Buffers[0].Size       = oe.Count;
                    output.Buffers[0].Buffer     = oe.Buffer;
                    output.Buffers[0].Offset     = oe.Offset;

                    output.Buffers[1].SetBufferEmpty();


                    // prepare some args and call SSPI
                    //
                    int contextReq = (int)(ContextReq.ASC_REQ_SEQUENCE_DETECT |
                                           ContextReq.ASC_REQ_REPLAY_DETECT |
                                           ContextReq.ASC_REQ_CONFIDENTIALITY |
                                           ContextReq.ASC_REQ_EXTENDED_ERROR |
                                           ContextReq.ASC_REQ_STREAM);

                    var newHandle = (context.Handle.IsInvalid) ? new SafeCtxtHandle() : context.Handle;

                    long timeStamp;

                    var result = Sspi.SafeAcceptSecurityContext(
                        ref credential,
                        ref context.Handle,
                        ref input,
                        contextReq,
                        TargetDataRep.SECURITY_NATIVE_DREP,
                        ref newHandle,
                        ref output,
                        out contextAttr,
                        out timeStamp);

                    if (context.Handle.IsInvalid)
                    {
                        context.Handle = newHandle;
                    }


                    // proccess non-critical errors
                    //
                    switch (result)
                    {
                    case SecurityStatus.SEC_E_INCOMPLETE_MESSAGE:

                        if (context.Buffer.IsInvalid)
                        {
                            if (context.Buffer.CopyTransferredFrom(ie, 0) == false)
                            {
                                return(false);
                            }
                        }
                        return(true);


                    case SecurityStatus.SEC_E_BUFFER_TOO_SMALL:

                        if (oe.Count < maxTokenSize)
                        {
                            oe.Count = maxTokenSize;
                            oe.ReAllocateBuffer(false);
                            continue;
                        }
                        return(false);
                    }


                    // send response to client
                    //
                    if (result == SecurityStatus.SEC_I_CONTINUE_NEEDED || result == SecurityStatus.SEC_E_OK ||
                        (Sspi.Failed(result) && (contextAttr & (int)ContextAttr.ASC_RET_EXTENDED_ERROR) != 0))
                    {
                        if (output.Buffers[0].Size > 0)
                        {
                            oe.Count = output.Buffers[0].Size;
                            oe.CopyAddressesFrom(ie);
                            oe.LocalEndPoint = GetLocalEndpoint(ie.RemoteEndPoint.Address);

                            base.SendAsync(connection, oe);
                            oe = null;
                        }
                    }


                    // move extra data to buffer
                    //
                    int extraIndex = input.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0);

                    if (extraIndex < 0)
                    {
                        context.Buffer.Free();
                    }
                    else
                    {
                        if (context.Buffer.IsInvalid)
                        {
                            if (context.Buffer.CopyTransferredFrom(ie,
                                                                   ie.BytesTransferred - input.Buffers[extraIndex].Size) == false)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            context.Buffer.MoveToBegin(context.Buffer.BytesTransferred - input.Buffers[extraIndex].Size,
                                                       input.Buffers[extraIndex].Size);
                        }
                    }


                    // proccess error-codes
                    //
                    switch (result)
                    {
                    case SecurityStatus.SEC_E_OK:

                        if (Sspi.SafeQueryContextAttributes(ref context.Handle, out context.StreamSizes)
                            != SecurityStatus.SEC_E_OK)
                        {
                            return(false);
                        }

                        context.Connected = true;
                        OnNewConnection(connection);

                        return(true);


                    case SecurityStatus.SEC_I_CONTINUE_NEEDED:

                        if (extraIndex >= 0)
                        {
                            continue;
                        }

                        return(true);


                    default:
                        return(false);
                    }
                }
            }
            finally
            {
                if (oe != null)
                {
                    EventArgsManager.Put(ref oe);
                }
            }
        }
예제 #27
0
        private bool DecryptData(ref ServerAsyncEventArgs e, Server <C> .Connection <C> connection)
        {
            SspiContext     sspiContext   = connection.SspiContext;
            SecBufferDescEx secBufferDesc = sspiContext.SecBufferDesc5;

            if (sspiContext.Buffer.IsValid && e != null && !sspiContext.Buffer.CopyTransferredFrom(e, 0))
            {
                return(false);
            }
            SecurityStatus securityStatus2;

            while (true)
            {
                secBufferDesc.Buffers[0].BufferType = BufferType.SECBUFFER_DATA;
                if (sspiContext.Buffer.IsValid)
                {
                    this.SetSecBuffer(ref secBufferDesc.Buffers[0], sspiContext);
                }
                else
                {
                    this.SetSecBuffer(ref secBufferDesc.Buffers[0], e);
                }
                secBufferDesc.Buffers[1].SetBufferEmpty();
                secBufferDesc.Buffers[2].SetBufferEmpty();
                secBufferDesc.Buffers[3].SetBufferEmpty();
                secBufferDesc.Buffers[4].SetBufferEmpty();
                SecurityStatus securityStatus = Sspi.SafeDecryptMessage(ref sspiContext.Handle, ref secBufferDesc, 0u, null);
                int            bufferIndex    = secBufferDesc.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0);
                int            bufferIndex2   = secBufferDesc.GetBufferIndex(BufferType.SECBUFFER_DATA, 0);
                securityStatus2 = securityStatus;
                if (securityStatus2 != SecurityStatus.SEC_E_OK)
                {
                    break;
                }
                if (bufferIndex2 < 0)
                {
                    return(false);
                }
                if (sspiContext.Buffer.IsInvalid)
                {
                    if (bufferIndex >= 0 && !sspiContext.Buffer.CopyFrom(secBufferDesc.Buffers[bufferIndex]))
                    {
                        return(false);
                    }
                    e.Offset           = secBufferDesc.Buffers[bufferIndex2].Offset;
                    e.BytesTransferred = secBufferDesc.Buffers[bufferIndex2].Size;
                    e.SetMaxCount();
                    if (!this.OnReceived(connection, ref e))
                    {
                        return(false);
                    }
                }
                else
                {
                    ArraySegment <byte> buffer = sspiContext.Buffer.Detach();
                    if (bufferIndex >= 0 && !sspiContext.Buffer.CopyFrom(secBufferDesc.Buffers[bufferIndex]))
                    {
                        return(false);
                    }
                    ServerAsyncEventArgs serverAsyncEventArgs = EventArgsManager.Get();
                    base.PrepareEventArgs(connection, serverAsyncEventArgs);
                    serverAsyncEventArgs.AttachBuffer(buffer);
                    serverAsyncEventArgs.Offset           = secBufferDesc.Buffers[bufferIndex2].Offset;
                    serverAsyncEventArgs.BytesTransferred = secBufferDesc.Buffers[bufferIndex2].Size;
                    serverAsyncEventArgs.SetMaxCount();
                    bool flag = this.OnReceived(connection, ref serverAsyncEventArgs);
                    if (serverAsyncEventArgs != null)
                    {
                        EventArgsManager.Put(serverAsyncEventArgs);
                    }
                    if (!flag)
                    {
                        return(false);
                    }
                }
                if (bufferIndex < 0)
                {
                    return(true);
                }
            }
            return(securityStatus2 != SecurityStatus.SEC_I_RENEGOTIATE && securityStatus2 == (SecurityStatus)2148074264u && (!sspiContext.Buffer.IsInvalid || sspiContext.Buffer.CopyTransferredFrom(e, 0)));
        }
예제 #28
0
        private bool Handshake(ServerAsyncEventArgs ie, Server <C> .Connection <C> connection)
        {
            int num = 0;
            ServerAsyncEventArgs serverAsyncEventArgs = null;
            SspiContext          sspiContext          = connection.SspiContext;
            SecBufferDescEx      secBufferDescEx      = sspiContext.SecBufferDesc2[0];
            SecBufferDescEx      secBufferDescEx2     = sspiContext.SecBufferDesc2[1];
            bool result;

            try
            {
                if (sspiContext.Buffer.IsValid && ie != null && !sspiContext.Buffer.CopyTransferredFrom(ie, 0))
                {
                    result = false;
                }
                else
                {
                    while (true)
                    {
                        secBufferDescEx.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN;
                        if (sspiContext.Buffer.IsValid)
                        {
                            this.SetSecBuffer(ref secBufferDescEx.Buffers[0], sspiContext);
                        }
                        else
                        {
                            this.SetSecBuffer(ref secBufferDescEx.Buffers[0], ie);
                        }
                        secBufferDescEx.Buffers[1].SetBufferEmpty();
                        if (serverAsyncEventArgs == null)
                        {
                            serverAsyncEventArgs = EventArgsManager.Get();
                        }
                        serverAsyncEventArgs.AllocateBuffer();
                        secBufferDescEx2.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN;
                        secBufferDescEx2.Buffers[0].Size       = serverAsyncEventArgs.Count;
                        secBufferDescEx2.Buffers[0].Buffer     = serverAsyncEventArgs.Buffer;
                        secBufferDescEx2.Buffers[0].Offset     = serverAsyncEventArgs.Offset;
                        secBufferDescEx2.Buffers[1].SetBufferEmpty();
                        int            contextReq = 98332;
                        SafeCtxtHandle handle     = sspiContext.Handle.IsInvalid ? new SafeCtxtHandle() : sspiContext.Handle;
                        long           num2;
                        SecurityStatus securityStatus = Sspi.SafeAcceptSecurityContext(ref this.credential, ref sspiContext.Handle, ref secBufferDescEx, contextReq, TargetDataRep.SECURITY_NATIVE_DREP, ref handle, ref secBufferDescEx2, out num, out num2);
                        if (sspiContext.Handle.IsInvalid)
                        {
                            sspiContext.Handle = handle;
                        }
                        SecurityStatus securityStatus2 = securityStatus;
                        if (securityStatus2 == (SecurityStatus)2148074264u)
                        {
                            break;
                        }
                        if (securityStatus2 != (SecurityStatus)2148074273u)
                        {
                            if ((securityStatus == SecurityStatus.SEC_I_CONTINUE_NEEDED || securityStatus == SecurityStatus.SEC_E_OK || (Sspi.Failed(securityStatus) && (num & 32768) != 0)) && secBufferDescEx2.Buffers[0].Size > 0)
                            {
                                serverAsyncEventArgs.Count = secBufferDescEx2.Buffers[0].Size;
                                serverAsyncEventArgs.CopyAddressesFrom(ie);
                                serverAsyncEventArgs.LocalEndPoint = base.GetLocalEndpoint(ie.RemoteEndPoint.Address);
                                base.SendAsync(connection, serverAsyncEventArgs);
                                serverAsyncEventArgs = null;
                            }
                            int bufferIndex = secBufferDescEx.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0);
                            if (bufferIndex < 0)
                            {
                                sspiContext.Buffer.Free();
                            }
                            else if (sspiContext.Buffer.IsInvalid)
                            {
                                if (!sspiContext.Buffer.CopyTransferredFrom(ie, ie.BytesTransferred - secBufferDescEx.Buffers[bufferIndex].Size))
                                {
                                    goto Block_21;
                                }
                            }
                            else
                            {
                                sspiContext.Buffer.MoveToBegin(sspiContext.Buffer.BytesTransferred - secBufferDescEx.Buffers[bufferIndex].Size, secBufferDescEx.Buffers[bufferIndex].Size);
                            }
                            SecurityStatus securityStatus3 = securityStatus;
                            if (securityStatus3 == SecurityStatus.SEC_E_OK)
                            {
                                goto IL_2FF;
                            }
                            if (securityStatus3 != SecurityStatus.SEC_I_CONTINUE_NEEDED)
                            {
                                goto Block_23;
                            }
                            if (bufferIndex < 0)
                            {
                                goto Block_25;
                            }
                        }
                        else
                        {
                            if (serverAsyncEventArgs.Count >= this.maxTokenSize)
                            {
                                goto IL_1DC;
                            }
                            serverAsyncEventArgs.Count = this.maxTokenSize;
                            serverAsyncEventArgs.ReAllocateBuffer(false);
                        }
                    }
                    if (sspiContext.Buffer.IsInvalid && !sspiContext.Buffer.CopyTransferredFrom(ie, 0))
                    {
                        result = false;
                        return(result);
                    }
                    result = true;
                    return(result);

IL_1DC:
                    result = false;
                    return(result);

Block_21:
                    result = false;
                    return(result);

Block_23:
                    result = false;
                    return(result);

IL_2FF:
                    if (Sspi.SafeQueryContextAttributes(ref sspiContext.Handle, out sspiContext.StreamSizes) != SecurityStatus.SEC_E_OK)
                    {
                        result = false;
                        return(result);
                    }
                    sspiContext.Connected = true;
                    this.OnNewConnection(connection);
                    result = true;
                    return(result);

Block_25:
                    result = true;
                }
            }
            finally
            {
                if (serverAsyncEventArgs != null)
                {
                    EventArgsManager.Put(ref serverAsyncEventArgs);
                }
            }
            return(result);
        }