//------------------------------------------------------------------- internal unsafe static int AcceptSecurityContext( ref SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref Interop.Secur32.ContextFlags outFlags) { #if TRACE_VERBOSE GlobalLog.Enter("SafeDeleteContext::AcceptSecurityContex"); GlobalLog.Print(" credential = " + inCredentials.ToString()); GlobalLog.Print(" refContext = " + Logging.ObjectToString(refContext)); GlobalLog.Print(" inFlags = " + inFlags); if (inSecBuffers == null) { GlobalLog.Print(" inSecBuffers = (null)"); } else { GlobalLog.Print(" inSecBuffers[] = length:" + inSecBuffers.Length); } #endif GlobalLog.Assert(outSecBuffer != null, "SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null"); GlobalLog.Assert(inSecBuffer == null || inSecBuffers == null, "SafeDeleteContext::AcceptSecurityContext()|inSecBuffer == null || inSecBuffers == null"); if (inCredentials == null) { throw new ArgumentNullException("inCredentials"); } Interop.Secur32.SecurityBufferDescriptor inSecurityBufferDescriptor = null; if (inSecBuffer != null) { inSecurityBufferDescriptor = new Interop.Secur32.SecurityBufferDescriptor(1); } else if (inSecBuffers != null) { inSecurityBufferDescriptor = new Interop.Secur32.SecurityBufferDescriptor(inSecBuffers.Length); } Interop.Secur32.SecurityBufferDescriptor outSecurityBufferDescriptor = new Interop.Secur32.SecurityBufferDescriptor(1); // Actually, this is returned in outFlags. bool isSspiAllocated = (inFlags & Interop.Secur32.ContextFlags.AllocateMemory) != 0 ? true : false; int errorCode = -1; Interop.Secur32.SSPIHandle contextHandle = new Interop.Secur32.SSPIHandle(); if (refContext != null) { contextHandle = refContext._handle; } // These are pinned user byte arrays passed along with SecurityBuffers. GCHandle[] pinnedInBytes = null; GCHandle pinnedOutBytes = new GCHandle(); // Optional output buffer that may need to be freed. SafeFreeContextBuffer outFreeContextBuffer = null; try { pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned); var inUnmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.Count]; fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) { if (inSecurityBufferDescriptor != null) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; SecurityBuffer securityBuffer; for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) { securityBuffer = inSecBuffer != null ? inSecBuffer : inSecBuffers[index]; if (securityBuffer != null) { // Copy the SecurityBuffer content into unmanaged place holder. inUnmanagedBuffer[index].count = securityBuffer.size; inUnmanagedBuffer[index].type = securityBuffer.type; // Use the unmanaged token if it's not null; otherwise use the managed buffer. if (securityBuffer.unmanagedToken != null) { inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token == null || securityBuffer.token.Length == 0) { inUnmanagedBuffer[index].token = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } #if TRACE_VERBOSE GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type); #endif } } } var outUnmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[1]; fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr; // Copy the SecurityBuffer content into unmanaged place holder. outUnmanagedBuffer[0].count = outSecBuffer.size; outUnmanagedBuffer[0].type = outSecBuffer.type; if (outSecBuffer.token == null || outSecBuffer.token.Length == 0) { outUnmanagedBuffer[0].token = IntPtr.Zero; } else { outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); } if (isSspiAllocated) { outFreeContextBuffer = SafeFreeContextBuffer.CreateEmptyHandle(); } if (refContext == null || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECURITY(); } errorCode = MustRunAcceptSecurityContext_SECURITY( ref inCredentials, contextHandle.IsZero ? null : &contextHandle, inSecurityBufferDescriptor, inFlags, endianness, refContext, outSecurityBufferDescriptor, ref outFlags, outFreeContextBuffer); GlobalLog.Print("SafeDeleteContext:AcceptSecurityContext Marshalling OUT buffer"); // Get unmanaged buffer with index 0 as the only one passed into PInvoke. outSecBuffer.size = outUnmanagedBuffer[0].count; outSecBuffer.type = outUnmanagedBuffer[0].type; if (outSecBuffer.size > 0) { outSecBuffer.token = new byte[outSecBuffer.size]; Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size); } else { outSecBuffer.token = null; } } } } finally { if (pinnedInBytes != null) { for (int index = 0; index < pinnedInBytes.Length; index++) { if (pinnedInBytes[index].IsAllocated) { pinnedInBytes[index].Free(); } } } if (pinnedOutBytes.IsAllocated) { pinnedOutBytes.Free(); } if (outFreeContextBuffer != null) { outFreeContextBuffer.Dispose(); } } GlobalLog.Leave("SafeDeleteContext::AcceptSecurityContex() unmanaged AcceptSecurityContex()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + Logging.ObjectToString(refContext)); return errorCode; }
internal unsafe static int CompleteAuthToken( ref SafeDeleteContext refContext, SecurityBuffer[] inSecBuffers) { GlobalLog.Enter("SafeDeleteContext::CompleteAuthToken"); GlobalLog.Print(" refContext = " + Logging.ObjectToString(refContext)); #if TRACE_VERBOSE GlobalLog.Print(" inSecBuffers[] = length:" + inSecBuffers.Length); #endif GlobalLog.Assert(inSecBuffers != null, "SafeDeleteContext::CompleteAuthToken()|inSecBuffers == null"); var inSecurityBufferDescriptor = new Interop.Secur32.SecurityBufferDescriptor(inSecBuffers.Length); int errorCode = (int)Interop.SecurityStatus.InvalidHandle; // These are pinned user byte arrays passed along with SecurityBuffers. GCHandle[] pinnedInBytes = null; var inUnmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[inSecurityBufferDescriptor.Count]; fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; SecurityBuffer securityBuffer; for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) { securityBuffer = inSecBuffers[index]; if (securityBuffer != null) { inUnmanagedBuffer[index].count = securityBuffer.size; inUnmanagedBuffer[index].type = securityBuffer.type; // Use the unmanaged token if it's not null; otherwise use the managed buffer. if (securityBuffer.unmanagedToken != null) { inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token == null || securityBuffer.token.Length == 0) { inUnmanagedBuffer[index].token = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } #if TRACE_VERBOSE GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type); #endif } } Interop.Secur32.SSPIHandle contextHandle = new Interop.Secur32.SSPIHandle(); if (refContext != null) { contextHandle = refContext._handle; } try { if (refContext == null || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECURITY(); } try { bool ignore = false; refContext.DangerousAddRef(ref ignore); errorCode = Interop.Secur32.CompleteAuthToken(contextHandle.IsZero ? null : &contextHandle, inSecurityBufferDescriptor); } finally { refContext.DangerousRelease(); } } finally { if (pinnedInBytes != null) { for (int index = 0; index < pinnedInBytes.Length; index++) { if (pinnedInBytes[index].IsAllocated) { pinnedInBytes[index].Free(); } } } } } GlobalLog.Leave("SafeDeleteContext::CompleteAuthToken() unmanaged CompleteAuthToken()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + Logging.ObjectToString(refContext)); return errorCode; }
private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) { Interop.Secur32.SecurityBufferDescriptor sdcInOut = new Interop.Secur32.SecurityBufferDescriptor(input.Length); var unmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[input.Length]; fixed (Interop.Secur32.SecurityBufferStruct* unmanagedBufferPtr = unmanagedBuffer) { sdcInOut.UnmanagedPointer = unmanagedBufferPtr; GCHandle[] pinnedBuffers = new GCHandle[input.Length]; byte[][] buffers = new byte[input.Length][]; try { for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; unmanagedBuffer[i].count = iBuffer.size; unmanagedBuffer[i].type = iBuffer.type; if (iBuffer.token == null || iBuffer.token.Length == 0) { unmanagedBuffer[i].token = IntPtr.Zero; } else { pinnedBuffers[i] = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned); unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset); buffers[i] = iBuffer.token; } } // The result is written in the input Buffer passed as type=BufferType.Data. int errorCode; switch (op) { case OP.Encrypt: errorCode = secModule.EncryptMessage(context, sdcInOut, sequenceNumber); break; case OP.Decrypt: errorCode = secModule.DecryptMessage(context, sdcInOut, sequenceNumber); break; case OP.MakeSignature: errorCode = secModule.MakeSignature(context, sdcInOut, sequenceNumber); break; case OP.VerifySignature: errorCode = secModule.VerifySignature(context, sdcInOut, sequenceNumber); break; default: GlobalLog.Assert("SSPIWrapper::EncryptDecryptHelper", "Unknown OP: " + op); throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException); } // Marshalling back returned sizes / data. for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; iBuffer.size = unmanagedBuffer[i].count; iBuffer.type = unmanagedBuffer[i].type; if (iBuffer.size == 0) { iBuffer.offset = 0; iBuffer.token = null; } else { checked { // Find the buffer this is inside of. Usually they all point inside buffer 0. int j; for (j = 0; j < input.Length; j++) { if (buffers[j] == null) { continue; } byte* bufferAddress = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0); if ((byte*)unmanagedBuffer[i].token >= bufferAddress && (byte*)unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length) { iBuffer.offset = (int)((byte*)unmanagedBuffer[i].token - bufferAddress); iBuffer.token = buffers[j]; break; } } if (j >= input.Length) { GlobalLog.Assert("SSPIWrapper::EncryptDecryptHelper", "Output buffer out of range."); iBuffer.size = 0; iBuffer.offset = 0; iBuffer.token = null; } } } // Backup validate the new sizes. GlobalLog.Assert(iBuffer.offset >= 0 && iBuffer.offset <= (iBuffer.token == null ? 0 : iBuffer.token.Length), "SSPIWrapper::EncryptDecryptHelper|'offset' out of range. [{0}]", iBuffer.offset); GlobalLog.Assert(iBuffer.size >= 0 && iBuffer.size <= (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset), "SSPIWrapper::EncryptDecryptHelper|'size' out of range. [{0}]", iBuffer.size); } if (errorCode != 0 && NetEventSource.Log.IsEnabled()) { if (errorCode == Interop.Secur32.SEC_I_RENEGOTIATE) { NetEventSource.PrintError(NetEventSource.ComponentType.Security, SR.Format(SR.event_OperationReturnedSomething, op, "SEC_I_RENEGOTIATE")); } else { NetEventSource.PrintError(NetEventSource.ComponentType.Security, SR.Format(SR.net_log_operation_failed_with_error, op, String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode))); } } return errorCode; } finally { for (int i = 0; i < pinnedBuffers.Length; ++i) { if (pinnedBuffers[i].IsAllocated) { pinnedBuffers[i].Free(); } } } } }
private unsafe SecurityStatus EncryptDecryptHelper(OP op, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) { Interop.Secur32.SecurityBufferDescriptor sdcInOut = new Interop.Secur32.SecurityBufferDescriptor(input.Length); var unmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[input.Length]; fixed(Interop.Secur32.SecurityBufferStruct *unmanagedBufferPtr = unmanagedBuffer) { sdcInOut.UnmanagedPointer = unmanagedBufferPtr; GCHandle[] pinnedBuffers = new GCHandle[input.Length]; byte[][] buffers = new byte[input.Length][]; try { for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; unmanagedBuffer[i].count = iBuffer.size; unmanagedBuffer[i].type = iBuffer.type; if (iBuffer.token == null || iBuffer.token.Length == 0) { unmanagedBuffer[i].token = IntPtr.Zero; } else { pinnedBuffers[i] = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned); unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset); buffers[i] = iBuffer.token; } } // The result is written in the input Buffer passed as type=BufferType.Data. int errorCode; switch (op) { case OP.Encrypt: errorCode = EncryptMessage(context, sdcInOut, sequenceNumber); break; case OP.Decrypt: errorCode = DecryptMessage(context, sdcInOut, sequenceNumber); break; default: throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException); } // Marshalling back returned sizes / data. for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; iBuffer.size = unmanagedBuffer[i].count; iBuffer.type = unmanagedBuffer[i].type; if (iBuffer.size == 0) { iBuffer.offset = 0; iBuffer.token = null; } else { checked { // Find the buffer this is inside of. Usually they all point inside buffer 0. int j; for (j = 0; j < input.Length; j++) { if (buffers[j] == null) { continue; } byte *bufferAddress = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0); if ((byte *)unmanagedBuffer[i].token >= bufferAddress && (byte *)unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length) { iBuffer.offset = (int)((byte *)unmanagedBuffer[i].token - bufferAddress); iBuffer.token = buffers[j]; break; } } if (j >= input.Length) { GlobalLog.Assert("SSPIWrapper::EncryptDecryptHelper", "Output buffer out of range."); iBuffer.size = 0; iBuffer.offset = 0; iBuffer.token = null; } } } // Backup validate the new sizes. GlobalLog.Assert(iBuffer.offset >= 0 && iBuffer.offset <= (iBuffer.token == null ? 0 : iBuffer.token.Length), "SSPIWrapper::EncryptDecryptHelper|'offset' out of range. [{0}]", iBuffer.offset); GlobalLog.Assert(iBuffer.size >= 0 && iBuffer.size <= (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset), "SSPIWrapper::EncryptDecryptHelper|'size' out of range. [{0}]", iBuffer.size); } if (errorCode != 0 && Logging.On) { if (errorCode == 0x90321) { Logging.PrintError(Logging.Web, SR.Format(SR.net_log_operation_returned_something, op, "SEC_I_RENEGOTIATE")); } else { Logging.PrintError(Logging.Web, SR.Format(SR.net_log_operation_failed_with_error, op, String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode))); } } return(MapToSecurityStatus((Interop.SecurityStatus)errorCode)); } finally { for (int i = 0; i < pinnedBuffers.Length; ++i) { if (pinnedBuffers[i].IsAllocated) { pinnedBuffers[i].Free(); } } } } }
//------------------------------------------------------------------- internal unsafe static int AcceptSecurityContext( ref SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref Interop.Secur32.ContextFlags outFlags) { #if TRACE_VERBOSE GlobalLog.Enter("SafeDeleteContext::AcceptSecurityContex"); GlobalLog.Print(" credential = " + inCredentials.ToString()); GlobalLog.Print(" refContext = " + Logging.ObjectToString(refContext)); GlobalLog.Print(" inFlags = " + inFlags); if (inSecBuffers == null) { GlobalLog.Print(" inSecBuffers = (null)"); } else { GlobalLog.Print(" inSecBuffers[] = length:" + inSecBuffers.Length); } #endif GlobalLog.Assert(outSecBuffer != null, "SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null"); GlobalLog.Assert(inSecBuffer == null || inSecBuffers == null, "SafeDeleteContext::AcceptSecurityContext()|inSecBuffer == null || inSecBuffers == null"); if (inCredentials == null) { throw new ArgumentNullException("inCredentials"); } Interop.Secur32.SecurityBufferDescriptor inSecurityBufferDescriptor = null; if (inSecBuffer != null) { inSecurityBufferDescriptor = new Interop.Secur32.SecurityBufferDescriptor(1); } else if (inSecBuffers != null) { inSecurityBufferDescriptor = new Interop.Secur32.SecurityBufferDescriptor(inSecBuffers.Length); } Interop.Secur32.SecurityBufferDescriptor outSecurityBufferDescriptor = new Interop.Secur32.SecurityBufferDescriptor(1); // Actually, this is returned in outFlags. bool isSspiAllocated = (inFlags & Interop.Secur32.ContextFlags.AllocateMemory) != 0 ? true : false; int errorCode = -1; Interop.Secur32.SSPIHandle contextHandle = new Interop.Secur32.SSPIHandle(); if (refContext != null) { contextHandle = refContext._handle; } // These are pinned user byte arrays passed along with SecurityBuffers. GCHandle[] pinnedInBytes = null; GCHandle pinnedOutBytes = new GCHandle(); // Optional output buffer that may need to be freed. SafeFreeContextBuffer outFreeContextBuffer = null; try { pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned); var inUnmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.Count]; fixed(void *inUnmanagedBufferPtr = inUnmanagedBuffer) { if (inSecurityBufferDescriptor != null) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; SecurityBuffer securityBuffer; for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) { securityBuffer = inSecBuffer != null ? inSecBuffer : inSecBuffers[index]; if (securityBuffer != null) { // Copy the SecurityBuffer content into unmanaged place holder. inUnmanagedBuffer[index].count = securityBuffer.size; inUnmanagedBuffer[index].type = securityBuffer.type; // Use the unmanaged token if it's not null; otherwise use the managed buffer. if (securityBuffer.unmanagedToken != null) { inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token == null || securityBuffer.token.Length == 0) { inUnmanagedBuffer[index].token = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } #if TRACE_VERBOSE GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type); #endif } } } var outUnmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[1]; fixed(void *outUnmanagedBufferPtr = outUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr; // Copy the SecurityBuffer content into unmanaged place holder. outUnmanagedBuffer[0].count = outSecBuffer.size; outUnmanagedBuffer[0].type = outSecBuffer.type; if (outSecBuffer.token == null || outSecBuffer.token.Length == 0) { outUnmanagedBuffer[0].token = IntPtr.Zero; } else { outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); } if (isSspiAllocated) { outFreeContextBuffer = SafeFreeContextBuffer.CreateEmptyHandle(); } if (refContext == null || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECURITY(); } errorCode = MustRunAcceptSecurityContext_SECURITY( ref inCredentials, contextHandle.IsZero ? null : &contextHandle, inSecurityBufferDescriptor, inFlags, endianness, refContext, outSecurityBufferDescriptor, ref outFlags, outFreeContextBuffer); GlobalLog.Print("SafeDeleteContext:AcceptSecurityContext Marshalling OUT buffer"); // Get unmanaged buffer with index 0 as the only one passed into PInvoke. outSecBuffer.size = outUnmanagedBuffer[0].count; outSecBuffer.type = outUnmanagedBuffer[0].type; if (outSecBuffer.size > 0) { outSecBuffer.token = new byte[outSecBuffer.size]; Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size); } else { outSecBuffer.token = null; } } } } finally { if (pinnedInBytes != null) { for (int index = 0; index < pinnedInBytes.Length; index++) { if (pinnedInBytes[index].IsAllocated) { pinnedInBytes[index].Free(); } } } if (pinnedOutBytes.IsAllocated) { pinnedOutBytes.Free(); } if (outFreeContextBuffer != null) { outFreeContextBuffer.Dispose(); } } GlobalLog.Leave("SafeDeleteContext::AcceptSecurityContex() unmanaged AcceptSecurityContex()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + Logging.ObjectToString(refContext)); return(errorCode); }
internal unsafe static int CompleteAuthToken( ref SafeDeleteContext refContext, SecurityBuffer[] inSecBuffers) { GlobalLog.Enter("SafeDeleteContext::CompleteAuthToken"); GlobalLog.Print(" refContext = " + Logging.ObjectToString(refContext)); #if TRACE_VERBOSE GlobalLog.Print(" inSecBuffers[] = length:" + inSecBuffers.Length); #endif GlobalLog.Assert(inSecBuffers != null, "SafeDeleteContext::CompleteAuthToken()|inSecBuffers == null"); var inSecurityBufferDescriptor = new Interop.Secur32.SecurityBufferDescriptor(inSecBuffers.Length); int errorCode = (int)Interop.SecurityStatus.InvalidHandle; // These are pinned user byte arrays passed along with SecurityBuffers. GCHandle[] pinnedInBytes = null; var inUnmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[inSecurityBufferDescriptor.Count]; fixed(void *inUnmanagedBufferPtr = inUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; SecurityBuffer securityBuffer; for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) { securityBuffer = inSecBuffers[index]; if (securityBuffer != null) { inUnmanagedBuffer[index].count = securityBuffer.size; inUnmanagedBuffer[index].type = securityBuffer.type; // Use the unmanaged token if it's not null; otherwise use the managed buffer. if (securityBuffer.unmanagedToken != null) { inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token == null || securityBuffer.token.Length == 0) { inUnmanagedBuffer[index].token = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } #if TRACE_VERBOSE GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type); #endif } } Interop.Secur32.SSPIHandle contextHandle = new Interop.Secur32.SSPIHandle(); if (refContext != null) { contextHandle = refContext._handle; } try { if (refContext == null || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECURITY(); } try { bool ignore = false; refContext.DangerousAddRef(ref ignore); errorCode = Interop.Secur32.CompleteAuthToken(contextHandle.IsZero ? null : &contextHandle, inSecurityBufferDescriptor); } finally { refContext.DangerousRelease(); } } finally { if (pinnedInBytes != null) { for (int index = 0; index < pinnedInBytes.Length; index++) { if (pinnedInBytes[index].IsAllocated) { pinnedInBytes[index].Free(); } } } } } GlobalLog.Leave("SafeDeleteContext::CompleteAuthToken() unmanaged CompleteAuthToken()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + Logging.ObjectToString(refContext)); return(errorCode); }