HostedImpersonationContext.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / System.ServiceModel.Activation / System / ServiceModel / Activation / HostedImpersonationContext.cs / 1305376 / HostedImpersonationContext.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Activation
{ 
    using System.ComponentModel;
    using System.Runtime; 
    using System.Runtime.InteropServices; 
    using System.Security;
    using System.Security.Principal; 
    using System.ServiceModel.Activation.Interop;
    using System.Threading;

    [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - All member methods are security critical. The class might be used outside of the restricted SecurityContext." + 
        "Ensure they do not accidentally satisfy any demands.")]
    class HostedImpersonationContext 
    { 
        [Fx.Tag.SecurityNote(Critical = "Stores the impersonation token handle. Since we're allowing 'safe' Impersonation of the token we got from asp.net we need to protect this value.")]
        [SecurityCritical] 
        SafeCloseHandleCritical tokenHandle;

        [Fx.Tag.SecurityNote(Critical = "Controls lifetime of token handle, caller must use care.")]
        [SecurityCritical] 
        int refCount = 0;
 
        [Fx.Tag.SecurityNote(Critical = "Security critical field, caller must use care.")] 
        [SecurityCritical]
        bool isImpersonated; 

        [Fx.Tag.SecurityNote(Critical = "Calls two safe native methods under OpenCurrentThreadTokenCritical: GetCurrentThread and OpenThreadToken." +
            "Marshal.GetLastWin32Error captures current thread token in a SecurityCritical field.")]
        [SecurityCritical] 
        public HostedImpersonationContext()
        { 
            if (ServiceHostingEnvironment.AspNetCompatibilityEnabled) 
            {
                int error; 
                bool isSuccess = SafeNativeMethods.OpenCurrentThreadTokenCritical(TokenAccessLevels.Query | TokenAccessLevels.Impersonate,
                    true, out tokenHandle, out error);

                if (isSuccess) 
                {
                    isImpersonated = true; 
                    Interlocked.Increment(ref refCount); 
                }
                else 
                {
                    CloseInvalidOutSafeHandleCritical(tokenHandle);
                    tokenHandle = null;
                    if (error != SafeNativeMethods.ERROR_NO_TOKEN) 
                    {
                        throw FxTrace.Exception.AsError(new Win32Exception(error, SR.Hosting_ImpersonationFailed)); 
                    } 
                }
            } 
        }

        [Fx.Tag.SecurityNote(Critical = "Calls SetHandleAsInvalid which has a LinkDemand for UnmanagedCode.")]
        [SecurityCritical] 
        static void CloseInvalidOutSafeHandleCritical(SafeHandle handle)
        { 
            // Workaround for 64-bit CLR bug VSWhidbey 546830 - sometimes invalid SafeHandles come back null. 
            if (handle != null)
            { 
                Fx.Assert(handle.IsInvalid, "CloseInvalidOutSafeHandle called with a valid handle!");

                // Calls SuppressFinalize.
                handle.SetHandleAsInvalid(); 
            }
        } 
 

        public bool IsImpersonated 
        {
            [Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical isImpersonated field.", Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
            [SecuritySafeCritical]
            get 
            {
                return isImpersonated; 
            } 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical tokenHandle field and uses LinkDemanded DangerousGetHandle method as well as UnsafeCreate." +
            "Caller should use with care, must take responsibility for reverting impersonation.")]
        [SecurityCritical]
        public IDisposable Impersonate() 
        {
            if (!isImpersonated) 
                return null; 

            Fx.Assert(tokenHandle != null, "The token handle was incorrectly released earlier."); 
            HostedInnerImpersonationContext context = null;
            lock(tokenHandle)
            {
                context = HostedInnerImpersonationContext.UnsafeCreate(tokenHandle.DangerousGetHandle()); 
                GC.KeepAlive(tokenHandle);
            } 
            return context; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Controls lifetime of token handle, caller must use care.")]
        [SecurityCritical]
        public void AddRef()
        { 
            if (IsImpersonated)
            { 
                Interlocked.Increment(ref refCount); 
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Controls lifetime of token handle, caller must use care.")]
        [SecurityCritical]
        public void Release() 
        {
            if (IsImpersonated) 
            { 
                Fx.Assert(tokenHandle != null, "The token handle is incorrectly released earlier.");
                int currentCount = Interlocked.Decrement(ref refCount); 
                if (currentCount == 0)
                {
                    lock(tokenHandle)
                    { 
                        tokenHandle.Close();
                        tokenHandle = null; 
                    } 
                }
            } 
        }

        [Fx.Tag.SecurityNote(Critical = "Keeps track of impersonated user, caller must use with care and call Dispose at the appropriate time.")]
#pragma warning disable 618 // have not moved to the v4 security model yet 
        [SecurityCritical(SecurityCriticalScope.Everything)]
#pragma warning restore 618 
        class HostedInnerImpersonationContext : IDisposable 
        {
            IDisposable impersonatedContext; 

            HostedInnerImpersonationContext(IDisposable impersonatedContext)
            {
                if (impersonatedContext == null) 
                {
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_ImpersonationFailed)); 
                } 
                this.impersonatedContext = impersonatedContext;
            } 

            public static HostedInnerImpersonationContext UnsafeCreate(IntPtr token)
            {
                return new HostedInnerImpersonationContext(HostingEnvironmentWrapper.UnsafeImpersonate(token)); 
            }
 
            public void Dispose() 
            {
                if (impersonatedContext != null) 
                {
                    impersonatedContext.Dispose();
                    impersonatedContext = null;
                } 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Activation
{ 
    using System.ComponentModel;
    using System.Runtime; 
    using System.Runtime.InteropServices; 
    using System.Security;
    using System.Security.Principal; 
    using System.ServiceModel.Activation.Interop;
    using System.Threading;

    [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - All member methods are security critical. The class might be used outside of the restricted SecurityContext." + 
        "Ensure they do not accidentally satisfy any demands.")]
    class HostedImpersonationContext 
    { 
        [Fx.Tag.SecurityNote(Critical = "Stores the impersonation token handle. Since we're allowing 'safe' Impersonation of the token we got from asp.net we need to protect this value.")]
        [SecurityCritical] 
        SafeCloseHandleCritical tokenHandle;

        [Fx.Tag.SecurityNote(Critical = "Controls lifetime of token handle, caller must use care.")]
        [SecurityCritical] 
        int refCount = 0;
 
        [Fx.Tag.SecurityNote(Critical = "Security critical field, caller must use care.")] 
        [SecurityCritical]
        bool isImpersonated; 

        [Fx.Tag.SecurityNote(Critical = "Calls two safe native methods under OpenCurrentThreadTokenCritical: GetCurrentThread and OpenThreadToken." +
            "Marshal.GetLastWin32Error captures current thread token in a SecurityCritical field.")]
        [SecurityCritical] 
        public HostedImpersonationContext()
        { 
            if (ServiceHostingEnvironment.AspNetCompatibilityEnabled) 
            {
                int error; 
                bool isSuccess = SafeNativeMethods.OpenCurrentThreadTokenCritical(TokenAccessLevels.Query | TokenAccessLevels.Impersonate,
                    true, out tokenHandle, out error);

                if (isSuccess) 
                {
                    isImpersonated = true; 
                    Interlocked.Increment(ref refCount); 
                }
                else 
                {
                    CloseInvalidOutSafeHandleCritical(tokenHandle);
                    tokenHandle = null;
                    if (error != SafeNativeMethods.ERROR_NO_TOKEN) 
                    {
                        throw FxTrace.Exception.AsError(new Win32Exception(error, SR.Hosting_ImpersonationFailed)); 
                    } 
                }
            } 
        }

        [Fx.Tag.SecurityNote(Critical = "Calls SetHandleAsInvalid which has a LinkDemand for UnmanagedCode.")]
        [SecurityCritical] 
        static void CloseInvalidOutSafeHandleCritical(SafeHandle handle)
        { 
            // Workaround for 64-bit CLR bug VSWhidbey 546830 - sometimes invalid SafeHandles come back null. 
            if (handle != null)
            { 
                Fx.Assert(handle.IsInvalid, "CloseInvalidOutSafeHandle called with a valid handle!");

                // Calls SuppressFinalize.
                handle.SetHandleAsInvalid(); 
            }
        } 
 

        public bool IsImpersonated 
        {
            [Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical isImpersonated field.", Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
            [SecuritySafeCritical]
            get 
            {
                return isImpersonated; 
            } 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical tokenHandle field and uses LinkDemanded DangerousGetHandle method as well as UnsafeCreate." +
            "Caller should use with care, must take responsibility for reverting impersonation.")]
        [SecurityCritical]
        public IDisposable Impersonate() 
        {
            if (!isImpersonated) 
                return null; 

            Fx.Assert(tokenHandle != null, "The token handle was incorrectly released earlier."); 
            HostedInnerImpersonationContext context = null;
            lock(tokenHandle)
            {
                context = HostedInnerImpersonationContext.UnsafeCreate(tokenHandle.DangerousGetHandle()); 
                GC.KeepAlive(tokenHandle);
            } 
            return context; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Controls lifetime of token handle, caller must use care.")]
        [SecurityCritical]
        public void AddRef()
        { 
            if (IsImpersonated)
            { 
                Interlocked.Increment(ref refCount); 
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Controls lifetime of token handle, caller must use care.")]
        [SecurityCritical]
        public void Release() 
        {
            if (IsImpersonated) 
            { 
                Fx.Assert(tokenHandle != null, "The token handle is incorrectly released earlier.");
                int currentCount = Interlocked.Decrement(ref refCount); 
                if (currentCount == 0)
                {
                    lock(tokenHandle)
                    { 
                        tokenHandle.Close();
                        tokenHandle = null; 
                    } 
                }
            } 
        }

        [Fx.Tag.SecurityNote(Critical = "Keeps track of impersonated user, caller must use with care and call Dispose at the appropriate time.")]
#pragma warning disable 618 // have not moved to the v4 security model yet 
        [SecurityCritical(SecurityCriticalScope.Everything)]
#pragma warning restore 618 
        class HostedInnerImpersonationContext : IDisposable 
        {
            IDisposable impersonatedContext; 

            HostedInnerImpersonationContext(IDisposable impersonatedContext)
            {
                if (impersonatedContext == null) 
                {
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_ImpersonationFailed)); 
                } 
                this.impersonatedContext = impersonatedContext;
            } 

            public static HostedInnerImpersonationContext UnsafeCreate(IntPtr token)
            {
                return new HostedInnerImpersonationContext(HostingEnvironmentWrapper.UnsafeImpersonate(token)); 
            }
 
            public void Dispose() 
            {
                if (impersonatedContext != null) 
                {
                    impersonatedContext.Dispose();
                    impersonatedContext = null;
                } 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK