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))); }
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); } } }