3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>Microsoft</OWNER>
10 // ApplicationTrust.cs
12 // This class encapsulates security decisions about an application.
15 namespace System.Security.Policy {
16 using System.Collections;
17 using System.Collections.Generic;
19 using System.Deployment.Internal.Isolation;
20 using System.Deployment.Internal.Isolation.Manifest;
22 using System.Globalization;
24 using System.Runtime.InteropServices;
25 #if FEATURE_SERIALIZATION
26 using System.Runtime.Serialization;
27 using System.Runtime.Serialization.Formatters.Binary;
28 #endif // FEATURE_SERIALIZATION
29 using System.Runtime.Versioning;
30 using System.Security.Permissions;
31 using System.Security.Util;
33 using System.Threading;
34 using System.Diagnostics.Contracts;
36 [System.Runtime.InteropServices.ComVisible(true)]
37 public enum ApplicationVersionMatch {
42 [System.Runtime.InteropServices.ComVisible(true)]
44 public sealed class ApplicationTrust : EvidenceBase, ISecurityEncodable
47 private ApplicationIdentity m_appId;
48 private bool m_appTrustedToRun;
49 private bool m_persist;
51 private object m_extraInfo;
52 private SecurityElement m_elExtraInfo;
54 private PolicyStatement m_psDefaultGrant;
55 private IList<StrongName> m_fullTrustAssemblies;
57 // Permission special flags for the default grant set in this ApplicationTrust. This should be
58 // updated in sync with any updates to the default grant set.
60 // In the general case, these values cannot be trusted - we only store a reference to the
61 // DefaultGrantSet, and return the reference directly, which means that code can update the
62 // permission set without our knowledge. That would lead to the flags getting out of sync with the
65 // However, we only care about these flags when we're creating a homogenous AppDomain, and in that
66 // case we control the ApplicationTrust object end-to-end, and know that the permission set will not
67 // change after the flags are calculated.
69 private int m_grantSetSpecialFlags;
72 public ApplicationTrust (ApplicationIdentity applicationIdentity) : this () {
73 ApplicationIdentity = applicationIdentity;
76 public ApplicationTrust () : this (new PermissionSet(PermissionState.None))
80 internal ApplicationTrust (PermissionSet defaultGrantSet)
82 InitDefaultGrantSet(defaultGrantSet);
84 m_fullTrustAssemblies = new List<StrongName>().AsReadOnly();
87 public ApplicationTrust(PermissionSet defaultGrantSet, IEnumerable<StrongName> fullTrustAssemblies) {
88 if (fullTrustAssemblies == null) {
89 throw new ArgumentNullException("fullTrustAssemblies");
92 InitDefaultGrantSet(defaultGrantSet);
94 List<StrongName> fullTrustList = new List<StrongName>();
95 foreach (StrongName strongName in fullTrustAssemblies) {
96 if (strongName == null) {
97 throw new ArgumentException(Environment.GetResourceString("Argument_NullFullTrustAssembly"));
100 fullTrustList.Add(new StrongName(strongName.PublicKey, strongName.Name, strongName.Version));
103 m_fullTrustAssemblies = fullTrustList.AsReadOnly();
106 // Sets up the default grant set for all constructors. Extracted to avoid the cost of
107 // IEnumerable virtual dispatches on startup when there are no fullTrustAssemblies (CoreCLR)
108 private void InitDefaultGrantSet(PermissionSet defaultGrantSet) {
109 if (defaultGrantSet == null) {
110 throw new ArgumentNullException("defaultGrantSet");
113 // Creating a PolicyStatement copies the incoming permission set, so we don't have to worry
114 // about the PermissionSet parameter changing underneath us after we've calculated the
115 // permisison flags in the DefaultGrantSet setter.
116 DefaultGrantSet = new PolicyStatement(defaultGrantSet);
119 #if FEATURE_CLICKONCE
120 public ApplicationIdentity ApplicationIdentity {
126 throw new ArgumentNullException(Environment.GetResourceString("Argument_InvalidAppId"));
127 Contract.EndContractBlock();
132 public PolicyStatement DefaultGrantSet {
134 if (m_psDefaultGrant == null)
135 return new PolicyStatement(new PermissionSet(PermissionState.None));
136 return m_psDefaultGrant;
140 m_psDefaultGrant = null;
141 m_grantSetSpecialFlags = 0;
144 m_psDefaultGrant = value;
145 m_grantSetSpecialFlags = SecurityManager.GetSpecialFlags(m_psDefaultGrant.PermissionSet, null);
150 public IList<StrongName> FullTrustAssemblies {
152 return m_fullTrustAssemblies;
155 #if FEATURE_CLICKONCE
156 public bool IsApplicationTrustedToRun {
158 return m_appTrustedToRun;
161 m_appTrustedToRun = value;
165 public bool Persist {
174 public object ExtraInfo {
176 if (m_elExtraInfo != null) {
177 m_extraInfo = ObjectFromXml(m_elExtraInfo);
178 m_elExtraInfo = null;
183 m_elExtraInfo = null;
187 #endif //FEATURE_CLICKONCE
189 #if FEATURE_CAS_POLICY
190 public SecurityElement ToXml () {
191 SecurityElement elRoot = new SecurityElement("ApplicationTrust");
192 elRoot.AddAttribute("version", "1");
194 #if FEATURE_CLICKONCE
195 if (m_appId != null) {
196 elRoot.AddAttribute("FullName", SecurityElement.Escape(m_appId.FullName));
198 if (m_appTrustedToRun) {
199 elRoot.AddAttribute("TrustedToRun", "true");
202 elRoot.AddAttribute("Persist", "true");
204 #endif // FEATURE_CLICKONCE
206 if (m_psDefaultGrant != null) {
207 SecurityElement elDefaultGrant = new SecurityElement("DefaultGrant");
208 elDefaultGrant.AddChild(m_psDefaultGrant.ToXml());
209 elRoot.AddChild(elDefaultGrant);
211 if (m_fullTrustAssemblies.Count > 0) {
212 SecurityElement elFullTrustAssemblies = new SecurityElement("FullTrustAssemblies");
213 foreach (StrongName fullTrustAssembly in m_fullTrustAssemblies) {
214 elFullTrustAssemblies.AddChild(fullTrustAssembly.ToXml());
216 elRoot.AddChild(elFullTrustAssemblies);
219 #if FEATURE_CLICKONCE
220 if (ExtraInfo != null) {
221 elRoot.AddChild(ObjectToXml("ExtraInfo", ExtraInfo));
223 #endif // FEATURE_CLICKONCE
227 public void FromXml (SecurityElement element) {
229 throw new ArgumentNullException("element");
230 if (String.Compare(element.Tag, "ApplicationTrust", StringComparison.Ordinal) != 0)
231 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXML"));
233 #if FEATURE_CLICKONCE
234 m_appTrustedToRun = false;
235 string isAppTrustedToRun = element.Attribute("TrustedToRun");
236 if (isAppTrustedToRun != null && String.Compare(isAppTrustedToRun, "true", StringComparison.Ordinal) == 0) {
237 m_appTrustedToRun = true;
241 string persist = element.Attribute("Persist");
242 if (persist != null && String.Compare(persist, "true", StringComparison.Ordinal) == 0) {
247 string fullName = element.Attribute("FullName");
248 if (fullName != null && fullName.Length > 0) {
249 m_appId = new ApplicationIdentity(fullName);
251 #endif // FEATURE_CLICKONCE
253 m_psDefaultGrant = null;
254 m_grantSetSpecialFlags = 0;
255 SecurityElement elDefaultGrant = element.SearchForChildByTag("DefaultGrant");
256 if (elDefaultGrant != null) {
257 SecurityElement elDefaultGrantPS = elDefaultGrant.SearchForChildByTag("PolicyStatement");
258 if (elDefaultGrantPS != null) {
259 PolicyStatement ps = new PolicyStatement(null);
260 ps.FromXml(elDefaultGrantPS);
261 m_psDefaultGrant = ps;
262 m_grantSetSpecialFlags = SecurityManager.GetSpecialFlags(ps.PermissionSet, null);
266 List<StrongName> fullTrustAssemblies = new List<StrongName>();
267 SecurityElement elFullTrustAssemblies = element.SearchForChildByTag("FullTrustAssemblies");
268 if (elFullTrustAssemblies != null && elFullTrustAssemblies.InternalChildren != null) {
269 IEnumerator enumerator = elFullTrustAssemblies.Children.GetEnumerator();
270 while (enumerator.MoveNext()) {
271 StrongName fullTrustAssembly = new StrongName();
272 fullTrustAssembly.FromXml(enumerator.Current as SecurityElement);
273 fullTrustAssemblies.Add(fullTrustAssembly);
277 m_fullTrustAssemblies = fullTrustAssemblies.AsReadOnly();
279 #if FEATURE_CLICKONCE
280 m_elExtraInfo = element.SearchForChildByTag("ExtraInfo");
281 #endif // FEATURE_CLICKONCE
284 #if FEATURE_CLICKONCE
285 private static SecurityElement ObjectToXml (string tag, Object obj) {
286 BCLDebug.Assert(obj != null, "You need to pass in an object");
288 ISecurityEncodable encodableObj = obj as ISecurityEncodable;
290 SecurityElement elObject;
291 if (encodableObj != null) {
292 elObject = encodableObj.ToXml();
293 if (!elObject.Tag.Equals(tag))
294 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXML"));
297 MemoryStream stream = new MemoryStream();
298 BinaryFormatter formatter = new BinaryFormatter();
299 formatter.Serialize(stream, obj);
300 byte[] array = stream.ToArray();
302 elObject = new SecurityElement(tag);
303 elObject.AddAttribute("Data", Hex.EncodeHexString(array));
307 private static Object ObjectFromXml (SecurityElement elObject) {
308 BCLDebug.Assert(elObject != null, "You need to pass in a security element");
310 if (elObject.Attribute("class") != null) {
311 ISecurityEncodable encodableObj = XMLUtil.CreateCodeGroup(elObject) as ISecurityEncodable;
312 if (encodableObj != null) {
313 encodableObj.FromXml(elObject);
318 string objectData = elObject.Attribute("Data");
319 MemoryStream stream = new MemoryStream(Hex.DecodeHexString(objectData));
320 BinaryFormatter formatter = new BinaryFormatter();
321 return formatter.Deserialize(stream);
323 #endif // FEATURE_CLICKONCE
324 #endif // FEATURE_CAS_POLICY
326 #pragma warning disable 618
327 [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
328 #pragma warning restore 618
329 [SecuritySafeCritical]
330 public override EvidenceBase Clone()
336 #if FEATURE_CLICKONCE
337 [System.Security.SecurityCritical] // auto-generated_required
338 [System.Runtime.InteropServices.ComVisible(true)]
339 public sealed class ApplicationTrustCollection : ICollection {
340 private const string ApplicationTrustProperty = "ApplicationTrust";
341 private const string InstallerIdentifier = "{60051b8f-4f12-400a-8e50-dd05ebd438d1}";
342 private static Guid ClrPropertySet = new Guid("c989bb7a-8385-4715-98cf-a741a8edb823");
344 // The CLR specific constant install reference.
345 private static object s_installReference = null;
346 private static StoreApplicationReference InstallReference {
348 if (s_installReference == null) {
349 Interlocked.CompareExchange(ref s_installReference,
350 new StoreApplicationReference(
351 IsolationInterop.GUID_SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING,
356 return (StoreApplicationReference) s_installReference;
360 private object m_appTrusts = null;
361 private ArrayList AppTrusts {
362 [System.Security.SecurityCritical] // auto-generated
364 if (m_appTrusts == null) {
365 ArrayList appTrusts = new ArrayList();
366 if (m_storeBounded) {
367 RefreshStorePointer();
368 // enumerate the user store and populate the collection
369 StoreDeploymentMetadataEnumeration deplEnum = m_pStore.EnumInstallerDeployments(IsolationInterop.GUID_SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING, InstallerIdentifier, ApplicationTrustProperty, null);
370 foreach (IDefinitionAppId defAppId in deplEnum) {
371 StoreDeploymentMetadataPropertyEnumeration metadataEnum = m_pStore.EnumInstallerDeploymentProperties(IsolationInterop.GUID_SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING, InstallerIdentifier, ApplicationTrustProperty, defAppId);
372 foreach (StoreOperationMetadataProperty appTrustProperty in metadataEnum) {
373 string appTrustXml = appTrustProperty.Value;
374 if (appTrustXml != null && appTrustXml.Length > 0) {
375 SecurityElement seTrust = SecurityElement.FromString(appTrustXml);
376 ApplicationTrust appTrust = new ApplicationTrust();
377 appTrust.FromXml(seTrust);
378 appTrusts.Add(appTrust);
383 Interlocked.CompareExchange(ref m_appTrusts, appTrusts, null);
385 return m_appTrusts as ArrayList;
389 private bool m_storeBounded = false;
390 private Store m_pStore = null; // Component store interface pointer.
392 // Only internal constructors are exposed.
393 [System.Security.SecurityCritical] // auto-generated
394 internal ApplicationTrustCollection () : this(false) {}
395 internal ApplicationTrustCollection (bool storeBounded) {
396 m_storeBounded = storeBounded;
399 [System.Security.SecurityCritical] // auto-generated
400 private void RefreshStorePointer () {
401 // Refresh store pointer.
402 if (m_pStore != null)
403 Marshal.ReleaseComObject(m_pStore.InternalStore);
404 m_pStore = IsolationInterop.GetUserStore();
409 [System.Security.SecuritySafeCritical] // overrides public transparent member
411 return AppTrusts.Count;
415 public ApplicationTrust this[int index] {
416 [System.Security.SecurityCritical] // auto-generated
418 return AppTrusts[index] as ApplicationTrust;
422 public ApplicationTrust this[string appFullName] {
423 [System.Security.SecurityCritical] // auto-generated
425 ApplicationIdentity identity = new ApplicationIdentity(appFullName);
426 ApplicationTrustCollection appTrusts = Find(identity, ApplicationVersionMatch.MatchExactVersion);
427 if (appTrusts.Count > 0)
433 [System.Security.SecurityCritical] // auto-generated
434 [ResourceExposure(ResourceScope.None)]
435 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
436 private void CommitApplicationTrust(ApplicationIdentity applicationIdentity, string trustXml) {
437 StoreOperationMetadataProperty[] properties = new StoreOperationMetadataProperty[] {
438 new StoreOperationMetadataProperty(ClrPropertySet, ApplicationTrustProperty, trustXml)
441 IEnumDefinitionIdentity idenum = applicationIdentity.Identity.EnumAppPath();
442 IDefinitionIdentity[] asbId = new IDefinitionIdentity[1];
443 IDefinitionIdentity deplId = null;
444 if (idenum.Next(1, asbId) == 1)
447 IDefinitionAppId defAppId = IsolationInterop.AppIdAuthority.CreateDefinition();
448 defAppId.SetAppPath(1, new IDefinitionIdentity[] {deplId});
449 defAppId.put_Codebase(applicationIdentity.CodeBase);
451 using (StoreTransaction storeTxn = new StoreTransaction()) {
452 storeTxn.Add(new StoreOperationSetDeploymentMetadata(defAppId, InstallReference, properties));
453 RefreshStorePointer();
454 m_pStore.Transact(storeTxn.Operations);
457 m_appTrusts = null; // reset the app trusts in the collection.
460 [System.Security.SecurityCritical] // auto-generated
461 public int Add (ApplicationTrust trust) {
463 throw new ArgumentNullException("trust");
464 if (trust.ApplicationIdentity == null)
465 throw new ArgumentException(Environment.GetResourceString("Argument_ApplicationTrustShouldHaveIdentity"));
466 Contract.EndContractBlock();
468 // Add the trust decision of the application to the fusion store.
469 if (m_storeBounded) {
470 CommitApplicationTrust(trust.ApplicationIdentity, trust.ToXml().ToString());
473 return AppTrusts.Add(trust);
477 [System.Security.SecurityCritical] // auto-generated
478 public void AddRange (ApplicationTrust[] trusts) {
480 throw new ArgumentNullException("trusts");
481 Contract.EndContractBlock();
485 for (; i<trusts.Length; i++) {
489 for (int j=0; j<i; j++) {
496 [System.Security.SecurityCritical] // auto-generated
497 public void AddRange (ApplicationTrustCollection trusts) {
499 throw new ArgumentNullException("trusts");
500 Contract.EndContractBlock();
504 foreach (ApplicationTrust trust in trusts) {
509 for (int j=0; j<i; j++) {
516 [System.Security.SecurityCritical] // auto-generated
517 public ApplicationTrustCollection Find (ApplicationIdentity applicationIdentity, ApplicationVersionMatch versionMatch) {
518 ApplicationTrustCollection collection = new ApplicationTrustCollection(false);
519 foreach (ApplicationTrust trust in this) {
520 if (CmsUtils.CompareIdentities(trust.ApplicationIdentity, applicationIdentity, versionMatch))
521 collection.Add(trust);
526 [System.Security.SecurityCritical] // auto-generated
527 public void Remove (ApplicationIdentity applicationIdentity, ApplicationVersionMatch versionMatch) {
528 ApplicationTrustCollection collection = Find(applicationIdentity, versionMatch);
529 RemoveRange(collection);
532 [System.Security.SecurityCritical] // auto-generated
533 public void Remove (ApplicationTrust trust) {
535 throw new ArgumentNullException("trust");
536 if (trust.ApplicationIdentity == null)
537 throw new ArgumentException(Environment.GetResourceString("Argument_ApplicationTrustShouldHaveIdentity"));
538 Contract.EndContractBlock();
540 // Remove the trust decision of the application from the fusion store.
541 if (m_storeBounded) {
542 CommitApplicationTrust(trust.ApplicationIdentity, null);
544 AppTrusts.Remove(trust);
548 [System.Security.SecurityCritical] // auto-generated
549 public void RemoveRange (ApplicationTrust[] trusts) {
551 throw new ArgumentNullException("trusts");
552 Contract.EndContractBlock();
556 for (; i<trusts.Length; i++) {
560 for (int j=0; j<i; j++) {
567 [System.Security.SecurityCritical] // auto-generated
568 public void RemoveRange (ApplicationTrustCollection trusts) {
570 throw new ArgumentNullException("trusts");
571 Contract.EndContractBlock();
575 foreach (ApplicationTrust trust in trusts) {
580 for (int j=0; j<i; j++) {
587 [System.Security.SecurityCritical] // auto-generated
588 public void Clear() {
589 // remove all trust decisions in the collection.
590 ArrayList trusts = this.AppTrusts;
591 if (m_storeBounded) {
592 foreach (ApplicationTrust trust in trusts) {
593 if (trust.ApplicationIdentity == null)
594 throw new ArgumentException(Environment.GetResourceString("Argument_ApplicationTrustShouldHaveIdentity"));
596 // Remove the trust decision of the application from the fusion store.
597 CommitApplicationTrust(trust.ApplicationIdentity, null);
603 public ApplicationTrustEnumerator GetEnumerator() {
604 return new ApplicationTrustEnumerator(this);
608 [System.Security.SecuritySafeCritical] // overrides public transparent member
609 IEnumerator IEnumerable.GetEnumerator()
611 return new ApplicationTrustEnumerator(this);
615 [System.Security.SecuritySafeCritical] // overrides public transparent member
616 void ICollection.CopyTo(Array array, int index) {
618 throw new ArgumentNullException("array");
620 throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
621 if (index < 0 || index >= array.Length)
622 throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
623 if (array.Length - index < this.Count)
624 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
625 Contract.EndContractBlock();
627 for (int i=0; i < this.Count; i++) {
628 array.SetValue(this[i], index++);
632 public void CopyTo (ApplicationTrust[] array, int index) {
633 ((ICollection)this).CopyTo(array, index);
636 public bool IsSynchronized {
637 [System.Security.SecuritySafeCritical] // overrides public transparent member
644 public object SyncRoot {
645 [System.Security.SecuritySafeCritical] // overrides public transparent member
653 [System.Runtime.InteropServices.ComVisible(true)]
654 public sealed class ApplicationTrustEnumerator : IEnumerator {
655 [System.Security.SecurityCritical] // auto-generated
656 private ApplicationTrustCollection m_trusts;
657 private int m_current;
659 private ApplicationTrustEnumerator() {}
660 [System.Security.SecurityCritical] // auto-generated
661 internal ApplicationTrustEnumerator(ApplicationTrustCollection trusts) {
666 public ApplicationTrust Current {
667 [System.Security.SecuritySafeCritical] // auto-generated
669 return m_trusts[m_current];
674 object IEnumerator.Current {
675 [System.Security.SecuritySafeCritical] // auto-generated
677 return (object) m_trusts[m_current];
681 [System.Security.SecuritySafeCritical] // auto-generated
682 public bool MoveNext() {
683 if (m_current == ((int) m_trusts.Count - 1))
689 public void Reset() {
693 #endif // FEATURE_CLICKONCE