static private PermissionSet ResolvePolicy(Evidence evidence,
PermissionSet reqdPset,
PermissionSet optPset,
PermissionSet denyPset,
out PermissionSet denied,
bool checkExecutionPermission)
{
PermissionSet requested;
PermissionSet optional;
PermissionSet allowed;
Exception savedException = null;
// We don't want to recurse back into here as a result of a
// stackwalk during resolution. So simply assert full trust (this
// implies that custom permissions cannot use any permissions that
// don't implement IUnrestrictedPermission.
// PermissionSet.s_fullTrust.Assert();
// The requested set is the union of the minimal request and the
// optional request. Minimal request defaults to empty, optional
// is "AllPossible" (includes any permission that can be defined)
// which is symbolized by null.
optional = optPset;
if (reqdPset == null)
{
requested = optional;
}
else
{
// If optional is null, the requested set becomes null/"AllPossible".
requested = optional == null ? null : reqdPset.Union(optional);
}
// Make sure that the right to execute is requested (if this feature is
// enabled).
if (requested != null && !requested.IsUnrestricted() && CheckExecution())
{
requested.AddPermission(executionSecurityPermission);
}
if (InitPolicy())
{
// If we aren't passed any evidence, just make an empty object
// If we are passed evidence, copy it before passing it
// to the policy manager.
// Note: this is not a deep copy, the pieces of evidence within the
// Evidence object can still be altered and affect the originals.
if (evidence == null)
{
evidence = new Evidence();
}
else
{
evidence = evidence.ShallowCopy();
}
evidence.AddHost(new PermissionRequestEvidence(reqdPset, optPset, denyPset));
// We need to make sure that no stray exceptions come out of Resolve so
// we wrap it in a try block.
try
{
allowed = polmgr.Resolve(evidence, requested);
}
catch (Exception e)
{
#if _DEBUG
if (debug)
{
DEBUG_OUT("Exception during resolve");
DEBUG_OUT(e.GetType().FullName);
DEBUG_OUT(e.Message);
DEBUG_OUT(e.StackTrace);
}
#endif
// If we get a policy exception, we are done are we are going to fail to
// load no matter what.
if (e is PolicyException)
{
throw e;
}
// If we get any other kid of exception, we set the allowed set to the
// empty set and continue processing as normal. This allows assemblies
// that make no request to be loaded but blocks any assembly that
// makes a request from being loaded. This seems like a valid design to
// me -- gregfee 6/19/2000
savedException = e;
allowed = new PermissionSet();
}
}
else
{
denied = null;
return(null);
}
#if _DEBUG
if (debug)
{
DEBUG_OUT("ResolvePolicy:");
IEnumerator enumerator = evidence.GetEnumerator();
DEBUG_OUT("Evidence:");
while (enumerator.MoveNext())
{
Object obj = enumerator.Current;
if (obj is Site)
{
DEBUG_OUT(((Site)obj).ToXml().ToString());
}
else if (obj is Zone)
{
DEBUG_OUT(((Zone)obj).ToXml().ToString());
}
else if (obj is Url)
{
DEBUG_OUT(((Url)obj).ToXml().ToString());
}
else if (obj is Publisher)
{
DEBUG_OUT(((Publisher)obj).ToXml().ToString());
}
else if (obj is StrongName)
{
DEBUG_OUT(((StrongName)obj).ToXml().ToString());
}
else if (obj is PermissionRequestEvidence)
{
DEBUG_OUT(((PermissionRequestEvidence)obj).ToXml().ToString());
}
}
DEBUG_OUT("Required permissions:");
DEBUG_OUT(reqdPset != null ? reqdPset.ToString() : "<null>");
DEBUG_OUT("Optional permissions:");
DEBUG_OUT(optPset != null ? optPset.ToString() : "<null>");
DEBUG_OUT("Denied permissions:");
DEBUG_OUT(denyPset != null ? denyPset.ToString() : "<null>");
DEBUG_OUT("Requested permissions:");
DEBUG_OUT(requested != null ? requested.ToString() : "<null>");
DEBUG_OUT("Granted permissions:");
DEBUG_OUT(allowed != null ? allowed.ToString() : "<null>");
}
#endif
// Check that we were granted the right to execute.
if (!allowed.IsUnrestricted() && checkExecutionPermission && CheckExecution())
{
SecurityPermission secPerm = (SecurityPermission)allowed.GetPermission(securityPermissionType);
if (secPerm == null || !executionSecurityPermission.IsSubsetOf(secPerm))
{
#if _DEBUG
DEBUG_OUT("No execute permission");
#endif
throw new PolicyException(Environment.GetResourceString("Policy_NoExecutionPermission"),
System.__HResults.CORSEC_E_NO_EXEC_PERM,
savedException);
}
}
// Check that we were granted at least the minimal set we asked for. Do
// this before pruning away any overlap with the refused set so that
// users have the flexability of defining minimal permissions that are
// only expressable as set differences (e.g. allow access to "C:\" but
// disallow "C:\Windows").
if (reqdPset != null && !reqdPset.IsSubsetOf(allowed))
{
#if _DEBUG
DEBUG_OUT("Didn't get required permissions");
#endif
throw new PolicyException(Environment.GetResourceString("Policy_NoRequiredPermission"),
System.__HResults.CORSEC_E_MIN_GRANT_FAIL,
savedException);
}
// Remove any granted permissions that are safe subsets of some denied
// permission. The remaining denied permissions (if any) are returned
// along with the modified grant set for use in checks.
if (denyPset != null)
{
denied = denyPset.Copy();
allowed.MergeDeniedSet(denied);
if (denied.IsEmpty())
{
denied = null;
}
}
else
{
denied = null;
}
#if _DEBUG
if (debug)
{
DEBUG_OUT("Final denied permissions:");
DEBUG_OUT(denied != null ? denied.ToString() : "<null>");
}
#endif
return(allowed);
}