SecureEnvironment.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / System / Security / RightsManagement / SecureEnvironment.cs / 1305600 / SecureEnvironment.cs

                            //------------------------------------------------------------------------------ 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description:  Secure Environment class is a starting point for Managed RM APIs 
//   It provides basic services of enumerating User Certificates, Initializing Environment 
//
// History: 
//  06/01/2005: IgorBel :   Initial Implementation
//
//-----------------------------------------------------------------------------
 
using System;
using System.Collections; 
using System.Collections.Generic; 
using System.Collections.ObjectModel;
using System.Diagnostics; 
using System.Globalization;
using System.Windows;
using MS.Internal.Security.RightsManagement;
using SecurityHelper=MS.Internal.WindowsBase.SecurityHelper; 
using MS.Internal;
using System.Security.Permissions; 
 
using SR=MS.Internal.WindowsBase.SR;
using SRID=MS.Internal.WindowsBase.SRID; 


namespace System.Security.RightsManagement
{ 
    /// 
    /// This class represent a client session, which used in activation, binding  and other function calls. 
    ///  
    /// 
    ///     Critical:    This class expose access to methods that eventually do one or more of the the following 
    ///             1. call into unmanaged code
    ///             2. affects state/data that will eventually cross over unmanaged code boundary
    ///             3. Return some RM related information which is considered private
    /// 
    ///     TreatAsSafe: This attrbiute automatically applied to all public entry points. All the public entry points have
    ///     Demands for RightsManagementPermission at entry to counter the possible attacks that do 
    ///     not lead to the unamanged code directly(which is protected by another Demand there) but rather leave 
    ///     some status/data behind which eventually might cross the unamanaged boundary.
    ///  
    [SecurityCritical(SecurityCriticalScope.Everything)]
    public class SecureEnvironment : IDisposable
    {
        ///  
        /// This static Method builds a new instance of a SecureEnvironment  for a given user that is already
        /// activated. If this method called with a user that isn't activated, and exception will be thrown. 
        /// The user that is passed into the function must have a well defined authentication type 
        /// AuthenticationType.Windows or AuthenticationType.Passport, all other Authentication
        /// types(AuthenticationType.WindowsPassport or AuthenticationType.Internal) are not allowed. 
        /// 
        public static SecureEnvironment Create(string applicationManifest,
                                               ContentUser user)
        { 
            SecurityHelper.DemandRightsManagementPermission();
 
            return CriticalCreate(applicationManifest, user); 
        }
 

        /// 
        /// This static method activates a user and creates a new instance of SecureEnvironment.
        /// The authentication type determines the type of user identity that will be activated. 
        /// If Permanent Windows activation is requested then the default currently logged on
        /// Windows Account identity will be activated. If Temporary Windows activation requested 
        /// then user will be prompted for Windows Domain credentials through a dialog, and the 
        /// user identified through those credentials will be activated.
        /// In case of Passport authentication, a Passport authentication dialog will always 
        /// appear regardless of temporary or permanent activation mode. The user that authenticatd
        /// through that Passport Authentication dialog will be activated.
        /// Regardless of Windows or Passport Authentication, all Temporary created activation will be
        /// destroyed when SecureEnvironment instance is Disposed or Finalized. 
        /// 
        public static SecureEnvironment Create(string applicationManifest, 
                                                                                        AuthenticationType authentication, 
                                                                                        UserActivationMode userActivationMode)
        { 
            SecurityHelper.DemandRightsManagementPermission();

            return CriticalCreate(applicationManifest,
                                            authentication, 
                                            userActivationMode);
        } 
 
        /// 
        /// This property verifies whether the current machine was prepared for consuming and producing RM protected content. 
        /// If property returns true it could be used as an indication that Init function call will not result in a network transaction.
        /// 
        public static bool IsUserActivated(ContentUser user)
        { 
            SecurityHelper.DemandRightsManagementPermission();
 
            if (user == null) 
            {
                throw new ArgumentNullException("user"); 
            }

            // we only let specifically identified users to be used here
            if ((user.AuthenticationType != AuthenticationType.Windows) && 
                 (user.AuthenticationType != AuthenticationType.Passport))
            { 
                throw new ArgumentOutOfRangeException("user", SR.Get(SRID.OnlyPassportOrWindowsAuthenticatedUsersAreAllowed)); 
            }
 
            using (ClientSession userClientSession = new ClientSession(user))
            {
                // if machine activation is not present we can return false right away
                return (userClientSession.IsMachineActivated() && userClientSession.IsUserActivated()); 
            }
        } 
 
        /// 
        /// Removes activation for a given user. User must have Windows or Passport authnetication 
        /// 
        public static void RemoveActivatedUser(ContentUser user)
        {
            SecurityHelper.DemandRightsManagementPermission(); 

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

            // we only let specifically identifyed users to be used here
            if ((user.AuthenticationType != AuthenticationType.Windows) &&
                 (user.AuthenticationType != AuthenticationType.Passport)) 
            {
                throw new ArgumentOutOfRangeException("user", SR.Get(SRID.OnlyPassportOrWindowsAuthenticatedUsersAreAllowed)); 
            } 

            // Generic client session to enumerate user certificates 
            using (ClientSession userClientSession = new ClientSession(user))
            {
                // Remove Licensor certificastes first
                List userClientLicensorCertificateIds = 
                                userClientSession.EnumerateUsersCertificateIds(user, EnumerateLicenseFlags.ClientLicensor);
 
                // and now we can remove certificates that have been enumerated 
                foreach(string licenseId in userClientLicensorCertificateIds)
                { 
                    userClientSession.DeleteLicense(licenseId);
                }

                // Remove User's identity certificastes second 
                List userGroupIdentityCertificateIds =
                                userClientSession.EnumerateUsersCertificateIds(user, EnumerateLicenseFlags.GroupIdentity); 
 
                // and now we can remove certificates that have been enumerated
                foreach(string licenseId in userGroupIdentityCertificateIds) 
                {
                    userClientSession.DeleteLicense(licenseId);
                }
            } 
        }
 
        ///  
        /// This function returns a read only collection of the activated users.
        ///  
        static public  ReadOnlyCollection  GetActivatedUsers()
        {
            SecurityHelper.DemandRightsManagementPermission();
 
            //build user with the default authentication type and a default name
            // neither name not authentication type is important in this case 
            //ContentUser tempUser = new ContentUser(_defaultUserName, AuthenticationType.Windows); 

            // Generic client session to enumerate user certificates 
            using(ClientSession genericClientSession =
                ClientSession.DefaultUserClientSession(AuthenticationType.Windows))
            {
                List userList = new List(); 

                // if machine activation is not present we can return empty list right away 
                if (genericClientSession.IsMachineActivated()) 
                {
                    int index =0; 
                    while(true)
                    {
                        // we get a string which can be parsed to get the ID and type
                        string userCertificate = genericClientSession.EnumerateLicense(EnumerateLicenseFlags.GroupIdentity, index); 

                        if (userCertificate == null) 
                            break; 

                        // we need to parse the information out of the string 
                        ContentUser user = ClientSession.ExtractUserFromCertificateChain(userCertificate);

                        // User specific client session to check it's status
                        using(ClientSession userClientSession = new ClientSession(user)) 
                        {
                            if (userClientSession.IsUserActivated()) 
                            { 
                                userList.Add(user);
                            } 
                        }

                        index ++;
                    } 
                }
 
                return new ReadOnlyCollection(userList); 
            }
        } 

        /// 
        /// This method is responsible for tearing down secure environment that was built as a result of Init call.
        ///  
        public void Dispose()
        { 
            SecurityHelper.DemandRightsManagementPermission(); 

            Dispose(true); 
            GC.SuppressFinalize(this);
        }

        ///  
        /// Read only property which returns the User provided in the constructor.
        ///  
        public ContentUser User 
        {
            get 
            {
                SecurityHelper.DemandRightsManagementPermission();

                CheckDisposed(); 
                return _user;
            } 
        } 

        ///  
        /// Read only property which returns the Application Manifest provided in the constructor.
        /// 
        public string ApplicationManifest
        { 
            get
            { 
                SecurityHelper.DemandRightsManagementPermission(); 

                CheckDisposed(); 
                return _applicationManifest;
            }
        }
 
        /// 
        /// Dispose(bool) 
        ///  
        /// 
        protected virtual void Dispose(bool disposing) 
        {
            try
            {
                if (disposing && (_clientSession != null)) 
                {
                    _clientSession.Dispose(); 
                } 
            }
            finally 
            {
                _clientSession = null;
            }
        } 

        internal ClientSession ClientSession 
        { 
            get
            { 
                Invariant.Assert(_clientSession != null);

                return _clientSession;
            } 
        }
 
        ///  
        /// This static Method builds a new instance of a secure environment for a given user that is assumed to be already activated.
        /// client Application can use GetActivatedUsers property to enumerate Activated users. 
        /// 
        private static SecureEnvironment CriticalCreate(string applicationManifest, ContentUser user)
        {
            if (applicationManifest == null) 
            {
                throw new ArgumentNullException("applicationManifest"); 
            } 

            if (user == null) 
            {
                throw new  ArgumentNullException("user");
            }
 
            // we only let specifically identifyed users to be used here
            if ((user.AuthenticationType != AuthenticationType.Windows) && 
                 (user.AuthenticationType != AuthenticationType.Passport)) 
            {
                throw new ArgumentOutOfRangeException("user"); 
            }

            if (!IsUserActivated(user))
            { 
                throw new RightsManagementException(RightsManagementFailureCode.NeedsGroupIdentityActivation);
            } 
 
            ClientSession clientSession = new ClientSession(user);
 
            try
            {
                clientSession.BuildSecureEnvironment(applicationManifest);
 
                return new SecureEnvironment(applicationManifest, user, clientSession);
            } 
            catch 
            {
                clientSession.Dispose(); 
                throw;
            }
        }
 
        private static SecureEnvironment CriticalCreate(
            string applicationManifest, 
            AuthenticationType authentication, 
            UserActivationMode userActivationMode)
        { 
            if (applicationManifest == null)
            {
                throw new ArgumentNullException("applicationManifest");
            } 

            if ((authentication != AuthenticationType.Windows) && 
                 (authentication != AuthenticationType.Passport)) 
            {
                throw new ArgumentOutOfRangeException("authentication"); 
            }

            if ((userActivationMode != UserActivationMode.Permanent) &&
                 (userActivationMode != UserActivationMode.Temporary)) 
            {
                throw new ArgumentOutOfRangeException("userActivationMode"); 
            } 

            //build user with the given authnetication type and a default name 
            // only authentication type is critical in this case
            ContentUser user;

            using (ClientSession tempClientSession = 
                ClientSession.DefaultUserClientSession(authentication))
            { 
                //Activate Machine if neccessary 
                if (!tempClientSession.IsMachineActivated())
                { 
                    // activate Machine
                    tempClientSession.ActivateMachine(authentication);
                }
 
                //Activate User (we will force start activation at this point)
                // at this point we should have a real user name 
                user = tempClientSession.ActivateUser(authentication, userActivationMode); 
            }
 
            Debug.Assert(IsUserActivated(user));

            ClientSession clientSession = new ClientSession(user, userActivationMode);
 
            try
            { 
                try 
                {
                    // make sure we have a Client Licensor Certificate 
                    clientSession.AcquireClientLicensorCertificate();
                }
                catch (RightsManagementException)
                { 
                    // In case of the RightsMnaagement exception we are willing to proceed
                    // as ClientLicensorCertificate only required for publishing not for consumption 
                    // and therefore it is optional to have one. 
                }
 
                clientSession.BuildSecureEnvironment(applicationManifest);

                return new SecureEnvironment(applicationManifest, user, clientSession);
            } 
            catch
            { 
                clientSession.Dispose(); 
                throw;
            } 
        }

        /// 
        /// Private Constructor for the SecureEnvironment. 
        /// 
        private SecureEnvironment(string applicationManifest, 
                                                         ContentUser user, 
                                                         ClientSession clientSession)
        { 
            Invariant.Assert(applicationManifest != null);
            Invariant.Assert(user != null);
            Invariant.Assert(clientSession != null);
 
            _user = user;
            _applicationManifest = applicationManifest; 
            _clientSession = clientSession; 
        }
 
        /// 
        /// Call this before accepting any API call
        /// 
        private void CheckDisposed() 
        {
            if (_clientSession == null) 
                throw new ObjectDisposedException("SecureEnvironment"); 
        }
 
        private ContentUser _user;
        private string _applicationManifest;
        private ClientSession _clientSession;       // if null we are disposed
    } 
}

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