Ejemplo n.º 1
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)));
        }
Ejemplo n.º 2
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);
                }
            }
        }