KerberosReceiverSecurityToken.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / IdentityModel / System / IdentityModel / Tokens / KerberosReceiverSecurityToken.cs / 1 / KerberosReceiverSecurityToken.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.IdentityModel.Tokens 
{
    using System.Collections.Generic; 
    using System.Collections.ObjectModel; 
    using System.ComponentModel;
    using System.Runtime.InteropServices; 
    using System.Security.Cryptography;
    using System.Security.Principal;

    public class KerberosReceiverSecurityToken : WindowsSecurityToken 
    {
        string id; 
        byte[] request; 
        SymmetricSecurityKey symmetricSecurityKey = null;
        ReadOnlyCollection securityKeys = null; 
        bool isAuthenticated = false;

        public KerberosReceiverSecurityToken(byte[] request)
            : this(request, SecurityUniqueId.Create().Value) 
        { }
 
        public KerberosReceiverSecurityToken(byte[] request, string id) 
            : this(request, id, true)
        { 
        }

        internal KerberosReceiverSecurityToken(byte[] request, string id, bool doAuthenticate)
        { 
            if (request == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("request")); 
            if (id == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("id"));
 
            this.id = id;
            this.request = request;

            if (doAuthenticate) 
            {
                Initialize(null); 
            } 
        }
 
        public override ReadOnlyCollection SecurityKeys
        {
            get
            { 
                if (this.securityKeys == null)
                { 
                    List temp = new List(1); 
                    temp.Add(this.SecurityKey);
                    this.securityKeys = temp.AsReadOnly(); 
                }
                return this.securityKeys;
            }
        } 

        public SymmetricSecurityKey SecurityKey 
        { 
            get
            { 
                if (!this.isAuthenticated)
                {
                    Initialize(null);
                } 
                return this.symmetricSecurityKey;
            } 
        } 

        public override DateTime ValidFrom 
        {
            get
            {
                if (!this.isAuthenticated) 
                {
                    Initialize(null); 
                } 
                return base.ValidFrom;
            } 
        }

        public override DateTime ValidTo
        { 
            get
            { 
                if (!this.isAuthenticated) 
                {
                    Initialize(null); 
                }
                return base.ValidTo;
            }
        } 

        public override WindowsIdentity WindowsIdentity 
        { 
            get
            { 
                ThrowIfDisposed();
                if (!this.isAuthenticated)
                {
                    Initialize(null); 
                }
                return base.WindowsIdentity; 
            } 
        }
 

        public byte[] GetRequest()
        {
            return SecurityUtils.CloneBuffer(this.request); 
        }
 
        // This internal API is not thread-safe.  It is acceptable since .. 
        // 1) From public OM, Initialize happens at ctor time.
        // 2) From internal OM (Sfx), Initialize happens right after ctor (single thread env). 
        //    i.e. ReadToken and then AuthenticateToken.
        internal void Initialize(SafeFreeCredentials credentialsHandle)
        {
            if (this.isAuthenticated) 
            {
                return; 
            } 
            bool ownCredentialsHandle = false;
            SafeDeleteContext securityContext = null; 
            SafeCloseHandle tokenHandle = null;

#if RECOMPUTEGSS
            int tokenSize = DEREncoding.TokenSize(this.request.Length); 
            byte[] rawRequest = new byte[tokenSize];
            int offset = 0; 
            int len = this.request.Length; 
            DEREncoding.MakeTokenHeader(this.request.Length, rawRequest, ref offset, ref len);
            System.Buffer.BlockCopy(this.request, 0, rawRequest, offset, this.request.Length); 
#else
            byte[] rawRequest = this.request;
#endif
 
            try
            { 
                if (credentialsHandle == null) 
                {
                    credentialsHandle = SspiWrapper.AcquireDefaultCredential( 
                        "Kerberos", CredentialUse.Inbound);
                    ownCredentialsHandle = true;
                }
 
                SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality
                    | SspiContextFlags.ReplayDetect | SspiContextFlags.SequenceDetect; 
 
                SspiContextFlags contextFlags = SspiContextFlags.Zero;
                SecurityBuffer inSecurityBuffer = new SecurityBuffer(rawRequest, BufferType.Token); 
                SecurityBuffer outSecurityBuffer = new SecurityBuffer(0, BufferType.Token);

                int statusCode = SspiWrapper.AcceptSecurityContext(credentialsHandle,
                    ref securityContext, 
                    fContextReq, Endianness.Native,
                    inSecurityBuffer, outSecurityBuffer, 
                    ref contextFlags); 

                if (statusCode != (int)SecurityStatus.OK) 
                {
                    if (statusCode == (int)SecurityStatus.ContinueNeeded)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode)));
                    } 
                    else if (statusCode == (int)SecurityStatus.OutOfMemory) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            new SecurityTokenException(SR.GetString(SR.KerberosApReqInvalidOrOutOfMemory), new Win32Exception(statusCode)));
                    }
                    else
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                            new SecurityTokenException(SR.GetString(SR.FailAcceptSecurityContext), new Win32Exception(statusCode))); 
                    } 
                }
 
                // Expiration
                LifeSpan lifeSpan = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext,
                    ContextAttribute.Lifespan);
                DateTime effectiveTime = lifeSpan.EffectiveTimeUtc; 
                DateTime expirationTime = lifeSpan.ExpiryTimeUtc;
 
                // SessionKey 
                SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext,
                    ContextAttribute.SessionKey); 
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey);

                // WindowsSecurityToken
                statusCode = SspiWrapper.QuerySecurityContextToken(securityContext, out tokenHandle); 
                if (statusCode != (int)SecurityStatus.OK)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode)); 
                }
 
                WindowsIdentity windowsIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle());
                Initialize(this.id, effectiveTime, expirationTime, windowsIdentity, false);

                // Authenticated 
                this.isAuthenticated = true;
            } 
            finally 
            {
                if (tokenHandle != null) 
                    tokenHandle.Close();

                if (securityContext != null)
                    securityContext.Close(); 

                if (ownCredentialsHandle && credentialsHandle != null) 
                    credentialsHandle.Close(); 
            }
        } 

        public override bool CanCreateKeyIdentifierClause()
        {
            if (typeof(T) == typeof(KerberosTicketHashKeyIdentifierClause)) 
                return true;
 
            return base.CanCreateKeyIdentifierClause(); 
        }
 
        public override T CreateKeyIdentifierClause()
        {
            if (typeof(T) == typeof(KerberosTicketHashKeyIdentifierClause))
                return new KerberosTicketHashKeyIdentifierClause(CryptoHelper.ComputeHash(this.request), false, null, 0) as T; 

            return base.CreateKeyIdentifierClause(); 
        } 

        public override bool MatchesKeyIdentifierClause(SecurityKeyIdentifierClause keyIdentifierClause) 
        {
            KerberosTicketHashKeyIdentifierClause kerbKeyIdentifierClause = keyIdentifierClause as KerberosTicketHashKeyIdentifierClause;
            if (kerbKeyIdentifierClause != null)
                return kerbKeyIdentifierClause.Matches(CryptoHelper.ComputeHash(this.request)); 

            return base.MatchesKeyIdentifierClause(keyIdentifierClause); 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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