GlobalAclOperationRequirement.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 / TransactionBridge / Microsoft / Transactions / Wsat / Messaging / GlobalAclOperationRequirement.cs / 1 / GlobalAclOperationRequirement.cs

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

// Enforce the global ACLs for Windows and X509 identities 

using System; 
using System.ServiceModel.Channels; 
using System.ServiceModel.Description;
using System.Collections; 
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IdentityModel.Claims; 
using System.IdentityModel.Policy;
using System.Security.Principal; 
using System.ServiceModel; 
using Microsoft.Transactions.Wsat.Protocol;
 
using DiagnosticUtility = Microsoft.Transactions.Bridge.DiagnosticUtility;

namespace Microsoft.Transactions.Wsat.Messaging
{ 
    class GlobalAclOperationRequirement : ServiceAuthorizationManager
    { 
        Dictionary sids; 
        Dictionary thumbprints;
        ProtocolVersion protocolVersion; 

        public GlobalAclOperationRequirement(List windowsIdentities, List x509Thumbprints, ProtocolVersion protocolVersion)
        {
            BuildSidDictionary(windowsIdentities != null ? windowsIdentities : new List()); 
            BuildThumbprintDictionary(x509Thumbprints != null ? x509Thumbprints : new List());
            this.protocolVersion = protocolVersion; 
        } 

        protected override bool CheckAccessCore(OperationContext operationContext) 
        {
            return AccessCheck(operationContext.ServiceSecurityContext.AuthorizationContext,
                               operationContext.IncomingMessageProperties,
                               operationContext.EndpointDispatcher.ChannelDispatcher.BindingName); 
        }
 
        public bool AccessCheckReply(Message reply, string binding) 
        {
            return AccessCheck(reply.Properties.Security.ServiceSecurityContext.AuthorizationContext, 
                               reply.Properties,
                               binding);
        }
 
        bool AccessCheck(AuthorizationContext authzContext,
                         MessageProperties messageProperties, 
                         string binding) 
        {
            bool result = false; 

            if (DebugTrace.Verbose)
                DebugTrace.Trace(TraceLevel.Verbose, "AccessCheck for binding {0}", binding);
 
            if (string.Compare(binding, BindingStrings.InteropBindingQName(this.protocolVersion), StringComparison.Ordinal) == 0)
            { 
                result = AccessCheck(authzContext, 
                                     messageProperties,
                                     ClaimTypes.Thumbprint, 
                                     this.thumbprints);
            }
            else if (string.Compare(binding, BindingStrings.NamedPipeBindingQName, StringComparison.Ordinal) == 0 ||
                     string.Compare(binding, BindingStrings.WindowsBindingQName, StringComparison.Ordinal) == 0) 
            {
                result = AccessCheck(authzContext, 
                                     messageProperties, 
                                     ClaimTypes.Sid,
                                     this.sids); 
            }
            else
            {
                // Will not run against a binding that the WSAT protocol is unaware of. 
                // This is assumed early on when the ServiceHost and endpoint
                // is setup for WS-AT. 
                DiagnosticUtility.FailFast("Unknown binding " + binding); 
            }
 
            TraceAccessCheckResult(result, messageProperties);
            return result;
        }
 
        bool AccessCheck(AuthorizationContext authzContext,
                         MessageProperties messageProperties, 
                         string claimType, 
                         Dictionary dictionary)
        { 
            if (authzContext != null)
            {
                foreach (ClaimSet claimSet in authzContext.ClaimSets)
                { 
                    IEnumerable claims = claimSet.FindClaims(claimType, Rights.PossessProperty);
                    foreach (Claim claim in claims) 
                    { 
                        if (dictionary.ContainsKey(claim))
                            return true; 
                    }
                }
            }
            else 
            {
                if (DebugTrace.Info) 
                { 
                    DebugTrace.Trace(TraceLevel.Info,
                                     "No authzContext was passed into AccessCheck"); 
                }
            }

            return false; 
        }
 
        void TraceAccessCheckResult(bool result, MessageProperties messageProperties) 
        {
            if (result) 
            {
                if (DebugTrace.Info)
                {
                    if (DebugTrace.Pii) 
                    {
                        DebugTrace.TracePii(TraceLevel.Info, 
                                            "Access granted to {0} by global ACL", 
                                            CoordinationServiceSecurity.GetSenderName(messageProperties));
                    } 
                    else
                    {
                        DebugTrace.Trace(TraceLevel.Info, "Access granted by global ACL");
                    } 
                }
            } 
            else 
            {
                if (DebugTrace.Warning) 
                {
                    if (DebugTrace.Pii)
                    {
                        DebugTrace.TracePii(TraceLevel.Warning, 
                                            "Access denied to {0} by global ACL",
                                            CoordinationServiceSecurity.GetSenderName(messageProperties)); 
                    } 
                    else
                    { 
                        DebugTrace.Trace(TraceLevel.Warning, "Access denied by global ACL");
                    }
                }
            } 
        }
 
        void BuildSidDictionary(List windowsIdentities) 
        {
            this.sids = new Dictionary(windowsIdentities.Count, Claim.DefaultComparer); 

            foreach (string identity in windowsIdentities)
            {
                Exception failed = null; 
                try
                { 
                    NTAccount account = new NTAccount(identity); 
                    SecurityIdentifier sid = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));
                    Claim claim = Claim.CreateWindowsSidClaim(sid); 
                    if (!this.sids.ContainsKey(claim))
                    {
                        this.sids.Add(claim, claim);
                    } 
                }
                catch (ArgumentException e) 
                { 
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Warning);
                    failed = e; 
                }
                catch (IdentityNotMappedException e)
                {
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Warning); 
                    failed = e;
                } 
                catch(SystemException e) 
                {
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Warning); 
                    failed = e;
                }

                if (failed != null && DebugTrace.Warning) 
                {
                    if (DebugTrace.Pii) 
                    { 
                        DebugTrace.Trace(TraceLevel.Warning,
                                         "Could not add account {0} to SID table: {1}", 
                                         identity, failed.Message);
                    }
                    else
                    { 
                        DebugTrace.Trace(TraceLevel.Warning,
                                         "Could not add account to SID table: {0}", 
                                         failed.GetType().Name); 
                    }
                } 
            }
        }

        void BuildThumbprintDictionary(List x509Thumbprints) 
        {
            this.thumbprints = new Dictionary(x509Thumbprints.Count, Claim.DefaultComparer); 
 
            foreach (string thumbprint in x509Thumbprints)
            { 
                if (!string.IsNullOrEmpty(thumbprint))
                {
                    byte[] thumbprintBytes = DecodeThumbprint(thumbprint);
                    if (thumbprintBytes == null) 
                    {
                        DebugTrace.Trace(TraceLevel.Warning, 
                                         "Could not decode thumbprint {0}", 
                                         thumbprint);
                    } 
                    else
                    {
                        Claim claim = Claim.CreateThumbprintClaim(thumbprintBytes);
                        if (!this.thumbprints.ContainsKey(claim)) 
                        {
                            this.thumbprints.Add(claim, claim); 
                        } 
                    }
                } 
            }
        }

        // 
        // The format of thumbprint is hex characters in a string
        // According to MSDN, X509Certificate2.Thumbprint is generated using SHA-1. 
        // SHA-1 produces a 160-bit message digest. e.g. "697E8279D4E189CB774083C7C7AA22B6916418B5" 
        //
        static byte[] DecodeThumbprint(string thumbprint) 
        {
            const int ThumbprintSize = 40;
            if (string.IsNullOrEmpty(thumbprint) || thumbprint.Length != ThumbprintSize)
            { 
                return null;
            } 
 
            byte[] bytes = new byte[ThumbprintSize / 2];
            for (int i = 0; i < bytes.Length; ++i) 
            {
                if (!byte.TryParse(thumbprint.Substring(i * 2, 2),
                                   NumberStyles.HexNumber,
                                   CultureInfo.InvariantCulture, 
                                   out bytes[i]))
                { 
                    return null; 
                }
            } 
            return bytes;
        }
    }
} 

// 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