1 // ==++== 2 // 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // 5 // ==--== 6 // <OWNER>Microsoft</OWNER> 7 // 8 9 // 10 // ApplicationSecurityInfo.cs 11 // 12 // The application security info holds all the security related information pertinent 13 // to the application. In some sense, it is the CLR public representation of the security 14 // information held in the manifest. 15 // 16 17 namespace System.Security.Policy { 18 using System.Collections; 19 using System.Deployment.Internal.Isolation; 20 using System.Deployment.Internal.Isolation.Manifest; 21 using System.Globalization; 22 using System.Runtime.InteropServices; 23 using System.Security.Cryptography; 24 using System.Security.Permissions; 25 using System.Security.Policy; 26 using System.Security.Util; 27 using System.Threading; 28 using System.Runtime.Versioning; 29 using System.Runtime.Hosting; 30 using System.Diagnostics.Contracts; 31 32 [System.Security.SecurityCritical] // auto-generated 33 [SecurityPermissionAttribute(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)] 34 [System.Runtime.InteropServices.ComVisible(true)] 35 public sealed class ApplicationSecurityInfo { 36 private ActivationContext m_context; 37 private object m_appId; 38 private object m_deployId; 39 private object m_defaultRequest; 40 private object m_appEvidence; 41 ApplicationSecurityInfo()42 internal ApplicationSecurityInfo () {} 43 44 // 45 // Public. 46 // 47 ApplicationSecurityInfo(ActivationContext activationContext)48 public ApplicationSecurityInfo (ActivationContext activationContext) { 49 if (activationContext == null) 50 throw new ArgumentNullException("activationContext"); 51 Contract.EndContractBlock(); 52 m_context = activationContext; 53 } 54 55 public ApplicationId ApplicationId { 56 get { 57 if (m_appId == null && m_context != null) { 58 ICMS appManifest = m_context.ApplicationComponentManifest; 59 ApplicationId appId = ParseApplicationId(appManifest); 60 Interlocked.CompareExchange(ref m_appId, appId, null); 61 } 62 return m_appId as ApplicationId; 63 } 64 set { 65 if (value == null) 66 throw new ArgumentNullException("value"); 67 Contract.EndContractBlock(); 68 m_appId = value; 69 } 70 } 71 72 public ApplicationId DeploymentId { 73 get { 74 if (m_deployId == null && m_context != null) { 75 ICMS deplManifest = m_context.DeploymentComponentManifest; 76 ApplicationId deplId = ParseApplicationId(deplManifest); 77 Interlocked.CompareExchange(ref m_deployId, deplId, null); 78 } 79 return m_deployId as ApplicationId; 80 } 81 set { 82 if (value == null) 83 throw new ArgumentNullException("value"); 84 Contract.EndContractBlock(); 85 m_deployId = value; 86 } 87 } 88 89 public PermissionSet DefaultRequestSet { 90 [ResourceExposure(ResourceScope.None)] 91 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 92 get { 93 if (m_defaultRequest == null) { 94 PermissionSet defaultRequest = new PermissionSet(PermissionState.None); 95 if (m_context != null) { 96 // read the default request from the app manifest. 97 ICMS appManifest = m_context.ApplicationComponentManifest; 98 string defaultPSetId = ((IMetadataSectionEntry) appManifest.MetadataSectionEntry).defaultPermissionSetID; 99 object permissionSetObj = null; 100 if (defaultPSetId != null && defaultPSetId.Length > 0) { 101 ((ISectionWithStringKey) appManifest.PermissionSetSection).Lookup(defaultPSetId, out permissionSetObj); 102 IPermissionSetEntry defaultPSet = permissionSetObj as IPermissionSetEntry; 103 if (defaultPSet != null) { 104 SecurityElement seDefaultPS = SecurityElement.FromString(defaultPSet.AllData.XmlSegment); 105 string unrestricted = seDefaultPS.Attribute("temp:Unrestricted"); 106 if (unrestricted != null) 107 seDefaultPS.AddAttribute("Unrestricted", unrestricted); 108 109 // Look for "SameSite" request. 110 string sameSite = seDefaultPS.Attribute("SameSite"); 111 if (String.Compare(sameSite, "Site", StringComparison.OrdinalIgnoreCase) == 0) { 112 Url url = new Url(m_context.Identity.CodeBase); 113 URLString urlString = url.GetURLString(); 114 115 // Create a same site web permission for HTTP deployed applications. We'll 116 // always use a v2.0 WebPermission for this because this XML is loadable 117 // on all versions of the framework that support ClickOnce. This allows 118 // newer versions of the framework to create ApplicationSecurityInfo objects 119 // that may eventually be used by applications running against older versions 120 // of the framework. 121 NetCodeGroup netCodeGroup = new NetCodeGroup(new AllMembershipCondition()); 122 SecurityElement webPermission = 123 netCodeGroup.CreateWebPermission(urlString.Host, 124 urlString.Scheme, 125 urlString.Port, 126 "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken); 127 128 if (webPermission != null) { 129 seDefaultPS.AddChild(webPermission); 130 } 131 132 if (String.Compare("file:", 0, m_context.Identity.CodeBase, 0, 5, StringComparison.OrdinalIgnoreCase) == 0) { 133 FileCodeGroup fileCodeGroup = new FileCodeGroup(new AllMembershipCondition(), FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery); 134 PolicyStatement ps = fileCodeGroup.CalculatePolicy(url); 135 if (ps != null) { 136 PermissionSet filePermissionSet = ps.PermissionSet; 137 if (filePermissionSet != null) { 138 seDefaultPS.AddChild(filePermissionSet.GetPermission(typeof(FileIOPermission)).ToXml()); 139 } 140 } 141 } 142 } 143 144 // We need to use a ReadOnlyPermissionSet to ensure that any permissions in 145 // the manifest which were created on a previous runtime are stored back to 146 // the application store in a format that the previous runtime can understand. 147 defaultRequest = new ReadOnlyPermissionSet(seDefaultPS); 148 } 149 } 150 } 151 Interlocked.CompareExchange(ref m_defaultRequest, defaultRequest, null); 152 } 153 return m_defaultRequest as PermissionSet; 154 } 155 set { 156 if (value == null) 157 throw new ArgumentNullException("value"); 158 Contract.EndContractBlock(); 159 m_defaultRequest = value; 160 } 161 } 162 163 public Evidence ApplicationEvidence { 164 [ResourceExposure(ResourceScope.None)] 165 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 166 get { 167 if (m_appEvidence == null) { 168 Evidence appEvidence = new Evidence(); 169 if (m_context != null) { 170 appEvidence = new Evidence(); 171 Url deploymentUrl = new Url(m_context.Identity.CodeBase); 172 appEvidence.AddHostEvidence(deploymentUrl); 173 appEvidence.AddHostEvidence(Zone.CreateFromUrl(m_context.Identity.CodeBase)); 174 if (String.Compare("file:", 0, m_context.Identity.CodeBase, 0, 5, StringComparison.OrdinalIgnoreCase) != 0) { 175 appEvidence.AddHostEvidence(Site.CreateFromUrl(m_context.Identity.CodeBase)); 176 } 177 appEvidence.AddHostEvidence(new StrongName(new StrongNamePublicKeyBlob(DeploymentId.m_publicKeyToken), 178 DeploymentId.Name, 179 DeploymentId.Version)); 180 appEvidence.AddHostEvidence(new ActivationArguments(m_context)); 181 } 182 Interlocked.CompareExchange(ref m_appEvidence, appEvidence, null); 183 } 184 return m_appEvidence as Evidence; 185 } 186 set { 187 if (value == null) 188 throw new ArgumentNullException("value"); 189 Contract.EndContractBlock(); 190 m_appEvidence = value; 191 } 192 } 193 194 // 195 // Internal. 196 // 197 ParseApplicationId(ICMS manifest)198 private static ApplicationId ParseApplicationId (ICMS manifest) { 199 if (manifest.Identity == null) 200 return null; 201 202 return new ApplicationId(Hex.DecodeHexString(manifest.Identity.GetAttribute("", "publicKeyToken")), 203 manifest.Identity.GetAttribute("", "name"), 204 new Version(manifest.Identity.GetAttribute("", "version")), 205 manifest.Identity.GetAttribute("", "processorArchitecture"), 206 manifest.Identity.GetAttribute("", "culture")); 207 } 208 } 209 } 210