The Labs \ Source Viewer \ SSCLI \ System.Security.Policy \ ApplicationTrustEnumerator

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. //
  16. // ApplicationTrust.cs
  17. //
  18. // This class encapsulates security decisions about an application.
  19. //
  20. namespace System.Security.Policy
  21. {
  22.     using System.Collections;
  23.     using System.Deployment.Internal.Isolation;
  24.     using System.Deployment.Internal.Isolation.Manifest;
  25.     using System.Globalization;
  26.     using System.IO;
  27.     using System.Runtime.InteropServices;
  28.     using System.Runtime.Serialization.Formatters.Binary;
  29.     using System.Security.Permissions;
  30.     using System.Security.Util;
  31.     using System.Text;
  32.     using System.Threading;
  33.    
  34.     [System.Runtime.InteropServices.ComVisible(true)]
  35.     public enum ApplicationVersionMatch
  36.     {
  37.         MatchExactVersion,
  38.         MatchAllVersions
  39.     }
  40.    
  41.     [System.Runtime.InteropServices.ComVisible(true)]
  42.     public sealed class ApplicationTrust : ISecurityEncodable
  43.     {
  44.         private ApplicationIdentity m_appId;
  45.         private bool m_appTrustedToRun;
  46.         private bool m_persist;
  47.         private object m_extraInfo;
  48.         private SecurityElement m_elExtraInfo;
  49.         private PolicyStatement m_psDefaultGrant;
  50.         private StrongName[] m_fullTrustAssemblies;
  51.        
  52.         public ApplicationTrust(ApplicationIdentity applicationIdentity) : this()
  53.         {
  54.             ApplicationIdentity = applicationIdentity;
  55.         }
  56.        
  57.         public ApplicationTrust() : this(new PermissionSet(PermissionState.None))
  58.         {
  59.         }
  60.         internal ApplicationTrust(PermissionSet defaultGrantSet) : this(defaultGrantSet, null)
  61.         {
  62.         }
  63.         internal ApplicationTrust(PermissionSet defaultGrantSet, StrongName[] fullTrustAssemblies)
  64.         {
  65.             DefaultGrantSet = new PolicyStatement(defaultGrantSet);
  66.             FullTrustAssemblies = fullTrustAssemblies;
  67.         }
  68.        
  69.         public ApplicationIdentity ApplicationIdentity {
  70.             get { return m_appId; }
  71.             set {
  72.                 if (value == null)
  73.                     throw new ArgumentNullException(Environment.GetResourceString("Argument_InvalidAppId"));
  74.                 m_appId = value;
  75.             }
  76.         }
  77.        
  78.         public PolicyStatement DefaultGrantSet {
  79.             get {
  80.                 if (m_psDefaultGrant == null)
  81.                     return new PolicyStatement(new PermissionSet(PermissionState.None));
  82.                 return m_psDefaultGrant;
  83.             }
  84.             set {
  85.                 if (value == null)
  86.                     m_psDefaultGrant = null;
  87.                 else
  88.                     m_psDefaultGrant = value;
  89.             }
  90.         }
  91.        
  92.         internal StrongName[] FullTrustAssemblies {
  93.             get { return m_fullTrustAssemblies; }
  94.             set { m_fullTrustAssemblies = value; }
  95.         }
  96.        
  97.         public bool IsApplicationTrustedToRun {
  98.             get { return m_appTrustedToRun; }
  99.             set { m_appTrustedToRun = value; }
  100.         }
  101.        
  102.         public bool Persist {
  103.             get { return m_persist; }
  104.             set { m_persist = value; }
  105.         }
  106.        
  107.         public object ExtraInfo {
  108.             get {
  109.                 if (m_elExtraInfo != null) {
  110.                     m_extraInfo = ObjectFromXml(m_elExtraInfo);
  111.                     m_elExtraInfo = null;
  112.                 }
  113.                 return m_extraInfo;
  114.             }
  115.             set {
  116.                 m_elExtraInfo = null;
  117.                 m_extraInfo = value;
  118.             }
  119.         }
  120.        
  121.         public SecurityElement ToXml()
  122.         {
  123.             SecurityElement elRoot = new SecurityElement("ApplicationTrust");
  124.             elRoot.AddAttribute("version", "1");
  125.            
  126.             if (m_appId != null)
  127.                 elRoot.AddAttribute("FullName", SecurityElement.Escape(m_appId.FullName));
  128.             if (m_appTrustedToRun)
  129.                 elRoot.AddAttribute("TrustedToRun", "true");
  130.             if (m_persist)
  131.                 elRoot.AddAttribute("Persist", "true");
  132.            
  133.             if (m_psDefaultGrant != null) {
  134.                 SecurityElement elDefaultGrant = new SecurityElement("DefaultGrant");
  135.                 elDefaultGrant.AddChild(m_psDefaultGrant.ToXml());
  136.                 elRoot.AddChild(elDefaultGrant);
  137.             }
  138.             if (m_fullTrustAssemblies != null) {
  139.                 SecurityElement elFullTrustAssemblies = new SecurityElement("FullTrustAssemblies");
  140.                 for (int index = 0; index < m_fullTrustAssemblies.Length; index++) {
  141.                     if (m_fullTrustAssemblies[index] != null)
  142.                         elFullTrustAssemblies.AddChild(m_fullTrustAssemblies[index].ToXml());
  143.                 }
  144.                 elRoot.AddChild(elFullTrustAssemblies);
  145.             }
  146.             if (ExtraInfo != null)
  147.                 elRoot.AddChild(ObjectToXml("ExtraInfo", ExtraInfo));
  148.            
  149.             return elRoot;
  150.         }
  151.        
  152.         public void FromXml(SecurityElement element)
  153.         {
  154.             if (element == null)
  155.                 throw new ArgumentNullException("element");
  156.             if (String.Compare(element.Tag, "ApplicationTrust", StringComparison.Ordinal) != 0)
  157.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXML"));
  158.            
  159.             m_psDefaultGrant = null;
  160.             m_fullTrustAssemblies = null;
  161.             m_appTrustedToRun = false;
  162.            
  163.             string isAppTrustedToRun = element.Attribute("TrustedToRun");
  164.             if (isAppTrustedToRun != null && String.Compare(isAppTrustedToRun, "true", StringComparison.Ordinal) == 0)
  165.                 m_appTrustedToRun = true;
  166.             string persist = element.Attribute("Persist");
  167.             if (persist != null && String.Compare(persist, "true", StringComparison.Ordinal) == 0)
  168.                 m_persist = true;
  169.            
  170.             string fullName = element.Attribute("FullName");
  171.             if (fullName != null && fullName.Length > 0)
  172.                 m_appId = new ApplicationIdentity(fullName);
  173.            
  174.             SecurityElement elDefaultGrant = element.SearchForChildByTag("DefaultGrant");
  175.             if (elDefaultGrant != null) {
  176.                 SecurityElement elDefaultGrantPS = elDefaultGrant.SearchForChildByTag("PolicyStatement");
  177.                 if (elDefaultGrantPS != null) {
  178.                     PolicyStatement ps = new PolicyStatement(null);
  179.                     ps.FromXml(elDefaultGrantPS);
  180.                     m_psDefaultGrant = ps;
  181.                 }
  182.             }
  183.            
  184.             SecurityElement elFullTrustAssemblies = element.SearchForChildByTag("FullTrustAssemblies");
  185.             if (elFullTrustAssemblies != null && elFullTrustAssemblies.InternalChildren != null) {
  186.                 m_fullTrustAssemblies = new StrongName[elFullTrustAssemblies.Children.Count];
  187.                 IEnumerator enumerator = elFullTrustAssemblies.Children.GetEnumerator();
  188.                 int index = 0;
  189.                 while (enumerator.MoveNext()) {
  190.                     m_fullTrustAssemblies[index] = new StrongName();
  191.                     m_fullTrustAssemblies[index].FromXml(enumerator.Current as SecurityElement);
  192.                     index++;
  193.                 }
  194.             }
  195.            
  196.             m_elExtraInfo = element.SearchForChildByTag("ExtraInfo");
  197.         }
  198.        
  199.         private static SecurityElement ObjectToXml(string tag, object obj)
  200.         {
  201.             BCLDebug.Assert(obj != null, "You need to pass in an object");
  202.            
  203.             ISecurityEncodable encodableObj = obj as ISecurityEncodable;
  204.            
  205.             SecurityElement elObject;
  206.             if (encodableObj != null) {
  207.                 elObject = encodableObj.ToXml();
  208.                 if (!elObject.Tag.Equals(tag))
  209.                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXML"));
  210.             }
  211.            
  212.             MemoryStream stream = new MemoryStream();
  213.             BinaryFormatter formatter = new BinaryFormatter();
  214.             formatter.Serialize(stream, obj);
  215.             byte[] array = stream.ToArray();
  216.            
  217.             elObject = new SecurityElement(tag);
  218.             elObject.AddAttribute("Data", Hex.EncodeHexString(array));
  219.             return elObject;
  220.         }
  221.        
  222.        
  223.         private static object ObjectFromXml(SecurityElement elObject)
  224.         {
  225.             BCLDebug.Assert(elObject != null, "You need to pass in a security element");
  226.            
  227.             if (elObject.Attribute("class") != null) {
  228.                 ISecurityEncodable encodableObj = XMLUtil.CreateCodeGroup(elObject) as ISecurityEncodable;
  229.                 if (encodableObj != null) {
  230.                     encodableObj.FromXml(elObject);
  231.                     return encodableObj;
  232.                 }
  233.             }
  234.            
  235.             string objectData = elObject.Attribute("Data");
  236.             MemoryStream stream = new MemoryStream(Hex.DecodeHexString(objectData));
  237.             BinaryFormatter formatter = new BinaryFormatter();
  238.             return formatter.Deserialize(stream);
  239.         }
  240.     }
  241.    
  242.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.ControlPolicy)]
  243.     [System.Runtime.InteropServices.ComVisible(true)]
  244.     public sealed class ApplicationTrustCollection : ICollection
  245.     {
  246.         private const string ApplicationTrustProperty = "ApplicationTrust";
  247.         private const string InstallerIdentifier = "{60051b8f-4f12-400a-8e50-dd05ebd438d1}";
  248.         private static Guid ClrPropertySet = new Guid("c989bb7a-8385-4715-98cf-a741a8edb823");
  249.        
  250.         // The CLR specific constant install reference.
  251.         private static object s_installReference = null;
  252.         private static StoreApplicationReference InstallReference {
  253.             get {
  254.                 if (s_installReference == null) {
  255.                     Interlocked.CompareExchange(ref s_installReference, new StoreApplicationReference(IsolationInterop.GUID_SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING, InstallerIdentifier, null), null);
  256.                 }
  257.                 return (StoreApplicationReference)s_installReference;
  258.             }
  259.         }
  260.        
  261.         private readonly object m_syncRoot = new object();
  262.        
  263.         private object m_appTrusts = null;
  264.         private ArrayList AppTrusts {
  265.             get {
  266.                 if (m_appTrusts == null) {
  267.                     ArrayList appTrusts = new ArrayList();
  268.                     if (m_storeBounded) {
  269.                         RefreshStorePointer();
  270.                         // enumerate the user store and populate the collection
  271.                         StoreDeploymentMetadataEnumeration deplEnum = m_pStore.EnumInstallerDeployments(IsolationInterop.GUID_SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING, InstallerIdentifier, ApplicationTrustProperty, null);
  272.                         foreach (IDefinitionAppId defAppId in deplEnum) {
  273.                             StoreDeploymentMetadataPropertyEnumeration metadataEnum = m_pStore.EnumInstallerDeploymentProperties(IsolationInterop.GUID_SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING, InstallerIdentifier, ApplicationTrustProperty, defAppId);
  274.                             foreach (StoreOperationMetadataProperty appTrustProperty in metadataEnum) {
  275.                                 string appTrustXml = appTrustProperty.Value;
  276.                                 if (appTrustXml != null && appTrustXml.Length > 0) {
  277.                                     SecurityElement seTrust = SecurityElement.FromString(appTrustXml);
  278.                                     ApplicationTrust appTrust = new ApplicationTrust();
  279.                                     appTrust.FromXml(seTrust);
  280.                                     appTrusts.Add(appTrust);
  281.                                 }
  282.                             }
  283.                         }
  284.                     }
  285.                     Interlocked.CompareExchange(ref m_appTrusts, appTrusts, null);
  286.                 }
  287.                 return m_appTrusts as ArrayList;
  288.             }
  289.         }
  290.        
  291.         private bool m_storeBounded = false;
  292.         private Store m_pStore = null;
  293.         // Component store interface pointer.
  294.         // Only internal constructors are exposed.
  295.         internal ApplicationTrustCollection() : this(false)
  296.         {
  297.         }
  298.         internal ApplicationTrustCollection(bool storeBounded)
  299.         {
  300.             m_storeBounded = storeBounded;
  301.         }
  302.        
  303.         private void RefreshStorePointer()
  304.         {
  305.             // Refresh store pointer.
  306.             if (m_pStore != null)
  307.                 Marshal.ReleaseComObject(m_pStore.InternalStore);
  308.             m_pStore = IsolationInterop.GetUserStore();
  309.         }
  310.        
  311.         public int Count {
  312.             get { return AppTrusts.Count; }
  313.         }
  314.        
  315.         public ApplicationTrust this[int index]
  316.         {
  317.             get { return AppTrusts[index] as ApplicationTrust; }
  318.         }
  319.        
  320.         public ApplicationTrust this[string appFullName]
  321.         {
  322.             get {
  323.                 ApplicationIdentity identity = new ApplicationIdentity(appFullName);
  324.                 ApplicationTrustCollection appTrusts = Find(identity, ApplicationVersionMatch.MatchExactVersion);
  325.                 if (appTrusts.Count > 0)
  326.                     return appTrusts[0];
  327.                 return null;
  328.             }
  329.         }
  330.        
  331.         private void CommitApplicationTrust(ApplicationIdentity applicationIdentity, string trustXml)
  332.         {
  333.             StoreOperationMetadataProperty[] properties = new StoreOperationMetadataProperty[] {new StoreOperationMetadataProperty(ClrPropertySet, ApplicationTrustProperty, trustXml)};
  334.            
  335.             IEnumDefinitionIdentity idenum = applicationIdentity.Identity.EnumAppPath();
  336.             IDefinitionIdentity[] asbId = new IDefinitionIdentity[1];
  337.             IDefinitionIdentity deplId = null;
  338.             if (idenum.Next(1, asbId) == 1)
  339.                 deplId = asbId[0];
  340.            
  341.             IDefinitionAppId defAppId = IsolationInterop.AppIdAuthority.CreateDefinition();
  342.             defAppId.SetAppPath(1, new IDefinitionIdentity[] {deplId});
  343.             defAppId.put_Codebase(applicationIdentity.CodeBase);
  344.            
  345.             using (StoreTransaction storeTxn = new StoreTransaction()) {
  346.                 storeTxn.Add(new StoreOperationSetDeploymentMetadata(defAppId, InstallReference, properties));
  347.                 RefreshStorePointer();
  348.                 m_pStore.Transact(storeTxn.Operations);
  349.             }
  350.            
  351.             m_appTrusts = null;
  352.             // reset the app trusts in the collection.
  353.         }
  354.        
  355.         public int Add(ApplicationTrust trust)
  356.         {
  357.             if (trust == null)
  358.                 throw new ArgumentNullException("trust");
  359.             if (trust.ApplicationIdentity == null)
  360.                 throw new ArgumentException(Environment.GetResourceString("Argument_ApplicationTrustShouldHaveIdentity"));
  361.            
  362.             // Add the trust decision of the application to the fusion store.
  363.             if (m_storeBounded) {
  364.                 CommitApplicationTrust(trust.ApplicationIdentity, trust.ToXml().ToString());
  365.                 return -1;
  366.             }
  367.             else {
  368.                 return AppTrusts.Add(trust);
  369.             }
  370.         }
  371.        
  372.         public void AddRange(ApplicationTrust[] trusts)
  373.         {
  374.             if (trusts == null)
  375.                 throw new ArgumentNullException("trusts");
  376.            
  377.             int i = 0;
  378.             try {
  379.                 for (; i < trusts.Length; i++) {
  380.                     Add(trusts[i]);
  381.                 }
  382.             }
  383.             catch {
  384.                 for (int j = 0; j < i; j++) {
  385.                     Remove(trusts[j]);
  386.                 }
  387.                 throw;
  388.             }
  389.         }
  390.        
  391.         public void AddRange(ApplicationTrustCollection trusts)
  392.         {
  393.             if (trusts == null)
  394.                 throw new ArgumentNullException("trusts");
  395.            
  396.             int i = 0;
  397.             try {
  398.                 foreach (ApplicationTrust trust in trusts) {
  399.                     Add(trust);
  400.                     i++;
  401.                 }
  402.             }
  403.             catch {
  404.                 for (int j = 0; j < i; j++) {
  405.                     Remove(trusts[j]);
  406.                 }
  407.                 throw;
  408.             }
  409.         }
  410.        
  411.         public ApplicationTrustCollection Find(ApplicationIdentity applicationIdentity, ApplicationVersionMatch versionMatch)
  412.         {
  413.             ApplicationTrustCollection collection = new ApplicationTrustCollection(false);
  414.             foreach (ApplicationTrust trust in this) {
  415.                 if (CmsUtils.CompareIdentities(trust.ApplicationIdentity, applicationIdentity, versionMatch))
  416.                     collection.Add(trust);
  417.             }
  418.             return collection;
  419.         }
  420.        
  421.         public void Remove(ApplicationIdentity applicationIdentity, ApplicationVersionMatch versionMatch)
  422.         {
  423.             ApplicationTrustCollection collection = Find(applicationIdentity, versionMatch);
  424.             RemoveRange(collection);
  425.         }
  426.        
  427.         public void Remove(ApplicationTrust trust)
  428.         {
  429.             if (trust == null)
  430.                 throw new ArgumentNullException("trust");
  431.             if (trust.ApplicationIdentity == null)
  432.                 throw new ArgumentException(Environment.GetResourceString("Argument_ApplicationTrustShouldHaveIdentity"));
  433.            
  434.             // Remove the trust decision of the application from the fusion store.
  435.             if (m_storeBounded) {
  436.                 CommitApplicationTrust(trust.ApplicationIdentity, null);
  437.             }
  438.             else {
  439.                 AppTrusts.Remove(trust);
  440.             }
  441.         }
  442.        
  443.         public void RemoveRange(ApplicationTrust[] trusts)
  444.         {
  445.             if (trusts == null)
  446.                 throw new ArgumentNullException("trusts");
  447.            
  448.             int i = 0;
  449.             try {
  450.                 for (; i < trusts.Length; i++) {
  451.                     Remove(trusts[i]);
  452.                 }
  453.             }
  454.             catch {
  455.                 for (int j = 0; j < i; j++) {
  456.                     Add(trusts[j]);
  457.                 }
  458.                 throw;
  459.             }
  460.         }
  461.        
  462.         public void RemoveRange(ApplicationTrustCollection trusts)
  463.         {
  464.             if (trusts == null)
  465.                 throw new ArgumentNullException("trusts");
  466.            
  467.             int i = 0;
  468.             try {
  469.                 foreach (ApplicationTrust trust in trusts) {
  470.                     Remove(trust);
  471.                     i++;
  472.                 }
  473.             }
  474.             catch {
  475.                 for (int j = 0; j < i; j++) {
  476.                     Add(trusts[j]);
  477.                 }
  478.                 throw;
  479.             }
  480.         }
  481.        
  482.         public void Clear()
  483.         {
  484.             // remove all trust decisions in the collection.
  485.             ArrayList trusts = this.AppTrusts;
  486.             if (m_storeBounded) {
  487.                 foreach (ApplicationTrust trust in trusts) {
  488.                     if (trust.ApplicationIdentity == null)
  489.                         throw new ArgumentException(Environment.GetResourceString("Argument_ApplicationTrustShouldHaveIdentity"));
  490.                    
  491.                     // Remove the trust decision of the application from the fusion store.
  492.                     CommitApplicationTrust(trust.ApplicationIdentity, null);
  493.                 }
  494.             }
  495.             trusts.Clear();
  496.         }
  497.        
  498.         public ApplicationTrustEnumerator GetEnumerator()
  499.         {
  500.             return new ApplicationTrustEnumerator(this);
  501.         }
  502.        
  503.         /// <internalonly/>
  504.         IEnumerator IEnumerable.GetEnumerator()
  505.         {
  506.             return new ApplicationTrustEnumerator(this);
  507.         }
  508.        
  509.         /// <internalonly/>
  510.         void ICollection.CopyTo(Array array, int index)
  511.         {
  512.             if (array == null)
  513.                 throw new ArgumentNullException("array");
  514.             if (array.Rank != 1)
  515.                 throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
  516.             if (index < 0 || index >= array.Length)
  517.                 throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
  518.             if (array.Length - index < this.Count)
  519.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
  520.            
  521.             for (int i = 0; i < this.Count; i++) {
  522.                 array.SetValue(this[i], index++);
  523.             }
  524.         }
  525.        
  526.         public void CopyTo(ApplicationTrust[] array, int index)
  527.         {
  528.             ((ICollection)this).CopyTo(array, index);
  529.         }
  530.        
  531.         public bool IsSynchronized {
  532.             get { return false; }
  533.         }
  534.        
  535.         public object SyncRoot {
  536.             get { return this; }
  537.         }
  538.     }
  539.    
  540.     [System.Runtime.InteropServices.ComVisible(true)]
  541.     public sealed class ApplicationTrustEnumerator : IEnumerator
  542.     {
  543.         private ApplicationTrustCollection m_trusts;
  544.         private int m_current;
  545.        
  546.         private ApplicationTrustEnumerator()
  547.         {
  548.         }
  549.         internal ApplicationTrustEnumerator(ApplicationTrustCollection trusts)
  550.         {
  551.             m_trusts = trusts;
  552.             m_current = -1;
  553.         }
  554.        
  555.         public ApplicationTrust Current {
  556.             get { return m_trusts[m_current]; }
  557.         }
  558.        
  559.         /// <internalonly/>
  560.         object IEnumerator.Current {
  561.             get { return (object)m_trusts[m_current]; }
  562.         }
  563.        
  564.         public bool MoveNext()
  565.         {
  566.             if (m_current == ((int)m_trusts.Count - 1))
  567.                 return false;
  568.             m_current++;
  569.             return true;
  570.         }
  571.        
  572.         public void Reset()
  573.         {
  574.             m_current = -1;
  575.         }
  576.     }
  577. }

Developer Fusion