예제 #1
0
        //-------------------------------------------------------------------
        internal unsafe static int AcceptSecurityContext(
            ref SafeFreeCredentials inCredentials,
            ref SafeDeleteContext refContext,
            Interop.SspiCli.ContextFlags inFlags,
            Interop.SspiCli.Endianness endianness,
            SecurityBuffer inSecBuffer,
            SecurityBuffer[] inSecBuffers,
            SecurityBuffer outSecBuffer,
            ref Interop.SspiCli.ContextFlags outFlags)
        {
#if TRACE_VERBOSE
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Enter("SafeDeleteContext::AcceptSecurityContex");
                GlobalLog.Print("    credential       = " + inCredentials.ToString());
                GlobalLog.Print("    refContext       = " + LoggingHash.ObjectToString(refContext));

                GlobalLog.Print("    inFlags          = " + inFlags);

                if (inSecBuffers == null)
                {
                    GlobalLog.Print("    inSecBuffers     = (null)");
                }
                else
                {
                    GlobalLog.Print("    inSecBuffers[]   = length:" + inSecBuffers.Length);
                }
            }
#endif
            if (outSecBuffer == null)
            {
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Assert("SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null");
                }

                Debug.Fail("SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null");
            }
            if (inSecBuffer != null && inSecBuffers != null)
            {
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Assert("SafeDeleteContext::AcceptSecurityContext()|inSecBuffer == null || inSecBuffers == null");
                }

                Debug.Fail("SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null");
            }

            if (inCredentials == null)
            {
                throw new ArgumentNullException("inCredentials");
            }

            Interop.SspiCli.SecurityBufferDescriptor inSecurityBufferDescriptor = null;
            if (inSecBuffer != null)
            {
                inSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(1);
            }
            else if (inSecBuffers != null)
            {
                inSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(inSecBuffers.Length);
            }

            Interop.SspiCli.SecurityBufferDescriptor outSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(1);

            // Actually, this is returned in outFlags.
            bool isSspiAllocated = (inFlags & Interop.SspiCli.ContextFlags.AllocateMemory) != 0 ? true : false;

            int errorCode = -1;

            Interop.SspiCli.SSPIHandle contextHandle = new Interop.SspiCli.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.SspiCli.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
                                if (GlobalLog.IsEnabled)
                                {
                                    GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type);
                                }
#endif
                            }
                        }
                    }

                    var outUnmanagedBuffer = new Interop.SspiCli.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);

                        if (GlobalLog.IsEnabled)
                        {
                            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();
                }
            }

            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Leave("SafeDeleteContext::AcceptSecurityContex() unmanaged AcceptSecurityContex()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + LoggingHash.ObjectToString(refContext));
            }

            return errorCode;
        }
예제 #2
0
        internal Interop.SspiCli.SSPIHandle _handle;    //should be always used as by ref in PInvokes parameters

        protected SafeFreeCredentials() : base(IntPtr.Zero, true)
        {
            _handle = new Interop.SspiCli.SSPIHandle();
        }
예제 #3
0
 protected SafeDeleteContext() : base(IntPtr.Zero, true)
 {
     _handle = new Interop.SspiCli.SSPIHandle();
 }
예제 #4
0
        internal unsafe static int CompleteAuthToken(
            ref SafeDeleteContext refContext,
            SecurityBuffer[] inSecBuffers)
        {
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Enter("SafeDeleteContext::CompleteAuthToken");
                GlobalLog.Print("    refContext       = " + LoggingHash.ObjectToString(refContext));
#if TRACE_VERBOSE
                GlobalLog.Print("    inSecBuffers[]   = length:" + inSecBuffers.Length);
#endif
            }
            if (inSecBuffers == null)
            {
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Assert("SafeDeleteContext::CompleteAuthToken()|inSecBuffers == null");
                }

                Debug.Fail("SafeDeleteContext::CompleteAuthToken()|inSecBuffers == null");
            }

            var inSecurityBufferDescriptor = new Interop.SspiCli.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.SspiCli.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
                        if (GlobalLog.IsEnabled)
                        {
                            GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type);
                        }
#endif
                    }
                }

                Interop.SspiCli.SSPIHandle contextHandle = new Interop.SspiCli.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.SspiCli.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();
                            }
                        }
                    }
                }
            }

            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Leave("SafeDeleteContext::CompleteAuthToken() unmanaged CompleteAuthToken()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + LoggingHash.ObjectToString(refContext));
            }

            return errorCode;
        }