internal static int AcceptSecurityContext(SSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "AcceptSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "inFlags = " + inFlags + ")"); } int errorCode = secModule.AcceptSecurityContext(ref credential, ref context, inputBuffer, inFlags, datarep, outputBuffer, ref outFlags); if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_sspi_security_context_input_buffer, "AcceptSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (Interop.SecurityStatus)errorCode)); } return(errorCode); }
internal static int InitializeSecurityContext(SSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "InitializeSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "targetName = " + targetName + ", " + "inFlags = " + inFlags + ")"); } int errorCode = secModule.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, inputBuffers, outputBuffer, ref outFlags); if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_sspi_security_context_input_buffers, "InitializeSecurityContext", (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (Interop.SecurityStatus)errorCode)); } return(errorCode); }
public int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { return(SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags)); }
public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness endianness, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { return(SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags)); }
// // After PInvoke call the method will fix the handleTemplate.handle with the returned value. // The caller is responsible for creating a correct SafeFreeContextBuffer_XXX flavour or null can be passed if no handle is returned. // private static unsafe int MustRunAcceptSecurityContext_SECURITY( ref SafeFreeCredentials inCredentials, void *inContextPtr, Interop.Secur32.SecurityBufferDescriptor inputBuffer, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness endianness, SafeDeleteContext outContext, Interop.Secur32.SecurityBufferDescriptor outputBuffer, ref Interop.Secur32.ContextFlags outFlags, SafeFreeContextBuffer handleTemplate) { int errorCode = (int)Interop.SecurityStatus.InvalidHandle; // Run the body of this method as a non-interruptible block. try { bool ignore = false; inCredentials.DangerousAddRef(ref ignore); outContext.DangerousAddRef(ref ignore); Interop.Secur32.SSPIHandle credentialHandle = inCredentials._handle; long timeStamp; errorCode = Interop.Secur32.AcceptSecurityContext( ref credentialHandle, inContextPtr, inputBuffer, inFlags, endianness, ref outContext._handle, outputBuffer, ref outFlags, out timeStamp); } finally { // // When a credential handle is first associated with the context we keep credential // ref count bumped up to ensure ordered finalization. // If the credential handle has been changed we de-ref the old one and associate the // context with the new cred handle but only if the call was successful. if (outContext._EffectiveCredential != inCredentials && (errorCode & 0x80000000) == 0) { // Disassociate the previous credential handle. if (outContext._EffectiveCredential != null) { outContext._EffectiveCredential.DangerousRelease(); } outContext._EffectiveCredential = inCredentials; } else { inCredentials.DangerousRelease(); } outContext.DangerousRelease(); } // The idea is that SSPI has allocated a block and filled up outUnmanagedBuffer+8 slot with the pointer. if (handleTemplate != null) { //ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes. handleTemplate.Set(((Interop.Secur32.SecurityBufferStruct *)outputBuffer.UnmanagedPointer)->token); if (handleTemplate.IsInvalid) { handleTemplate.SetHandleAsInvalid(); } } if (inContextPtr == null && (errorCode & 0x80000000) != 0) { // An error on the first call, need to set the out handle to invalid value. outContext._handle.SetToInvalid(); } return(errorCode); }
//------------------------------------------------------------------- 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); }