Assembly Level Declarative Security


Assembly level declarative security comes in three forms, RequestMinimum, RequestOptional, and RequestRefuse.  The three can be briefly defined as:

  • RequestMinimum — the set of permissions that are absolutely required for this assembly to run
  • RequestOptional — the set of permissions that would be nice to run with, but are not required
  • RequestRefuse — a set of permissions that should never be granted to the assembly

Each of these actions can be applied on multiple attributes in each assembly, the final set of permissions in the action will be the union of all of the attributes with the given action.

Most people intuitively understand RequestRefuse.  Any permissions that are in this set are added to the assembly’s refused set, and the assembly will never execute with these permissions granted.  The other two can become a bit dicey however, especially in their side effects.  In order to demonstrate RequestMinimum and RequestOptional, I’ll use the following sample code, and apply different assembly-level declarative security to it.

public static class DeclarativeSecurity
{
    public static void Main()
    {
        Console.WriteLine(“In Main”);
        if(HaveFileIO())
            Console.WriteLine(“Have full FileIO permission”);
        else
            Console.WriteLine(“Do not have full FileIO permission”);
    }

    private static bool HaveFileIO()
    {
        try
        {
            new FileIOPermission(PermissionState.Unrestricted).Demand();
        }
        catch(SecurityException)
        {
            return false;
        }

        return true;
    }
}

RequestMinimum tells the CLR that your code cannot run without the given set of permissions.  So, if I were to attach the following attribute to my assembly:

[assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted = true)]

And run it from the Intranet zone, the code would never execute.  Since the CLR sees that this assembly cannot run without unrestricted FileIO permission, and the Intranet permission set won’t grant it that permission set, the loader refuses to even load the assembly.  Instead, you’ll see a FileLoadException with an inner PolicyException:

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly ‘ReqMin, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null’ or one of itsdependencies. HRESULT 0x80131417 (CORSEC_E_MIN_GRANT_FAIL) Failed to grant minimum permission requests.
File name: ‘ReqMin, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null’ —>
System.Security.Policy.PolicyException: Required permissions cannot be acquired.

at System.Security.SecurityManager.ResolvePolicy(Evidence evidence, PermissionSet reqdPset, PermissionSet optPset, PermissionSet denyPset, PermissionSet& denied, Boolean checkExecutionPermission)
at System.Security.SecurityManager.ResolvePolicy(Evidence evidence, PermissionSet reqdPset, PermissionSet optPset, PermissionSet denyPset, PermissionSet& denied, Int32& grantedIsUnrestricted, Boolean checkExecutionPermission)

RequestOptional has a different effect.  Changing the security attribute to:

[assembly: FileIOPermission(SecurityAction.RequestOptional, Unrestricted = true)]

And running from the Intranet zone, I’ll now see:

In Main
Do not have full FileIO permission

So the application loaded and ran, but was not granted FileIO permission.  This is what I would expect, since Intranet assemblies are not granted unrestricted FileIO, however the RequestOptional action told the CLR that my code would still be able to run without these permissions.  Generally code that works with RequestOptional tends to try a privileged operation in a try … catch(SecurityException) block, and fall back to alternate behavior if the optional permissions are not granted.

So far, so good.  However, now we come to the interesting side effect, one that oftentimes confuses people new to assembly level declarative security.  Namely, using any declarative security at all has the potential to decrease the permission set that your assembly is running with.  This is obvious in the case of RequestRefuse, however with RequestMinimum and RequestOptional, the reasoning is far less clear.

Internally, the CLR takes the union of the RequestMinimum and RequestOptional sets (and adds to that execution permission), and that resulting set is the only set of permissions that your application will have when it’s running.  For instance, demanding unrestricted Registry permission will fail if either of the above declarative requests are in place.

The reasoning behind this is that the CLR takes RequestMinimum and RequestOptional to be the complete set of permissions that your assembly requires to run.  If you think about what you’re saying to the runtime, this makes a lot of sense.  In effect you’re saying “here’s the minimum set of permissions I require to run, but I’ll also provide enhanced behavior with these other permissions.”  The combination of those sets should result in every permission your assembly requires.  Limiting the set of permissions that an assembly is running with increases the security of your application, since there’s now no way that your code can access resources that it doesn’t need access to.  In the above example, there would be no way for an attacker to trick my code into, say, accessing the registry.

Because of the above, its often better to over-estimate the permissions you need (ask for Unrestricted FileIO rather than just FileIO to a specific path), since if you under-estimate users of your application will run into SecurityExceptions.  In fact, the FileIO case mentioned above is one instance where you often do have to over-estimate, because generally your application won’t know what the full path to the file it wants to work with is until runtime.  Additionally, it’s important to note that these restrictions are per-assembly.  The only way that the restricted grant to this assembly could affect other assemblies in my application is if a method from this assembly happened to be on a call stack when a demand took place.

As if this wasn’t getting confusing enough already, there’s one more sticky point that can trap you.  It’s important to realize that the defaults for the various permission sets are:

  • RequestMinimum — Nothing
  • RequestOptional — FullTrust
  • RequestRefuse — Nothing

Since the permission set restriction is calculated by taking the minimum request and unioning with the optional request, and the default optional request is FullTrust, unless an Optional request is made, the union of the minimum request and the FullTrust request will result in a FullTrust set.  What this boils down to is that unless you specify a RequestOptional set, the permissions your application runs under will not be limited in the fashion stated above.

A common question that arises after people start to understand that they don’t get any more permissions than they specifically ask for is what use is RequestRefuse?  It seems silly for me to RequestRefuse RegistryPermission if I do a RequestOptional on FileIO permission since the refusal will have no net effect.  Generally, RequestRefuse is there for the times when it’s easier to say what permissions you don’t need than it is to specifically call out the permissions that you do need.

Update: Added information about defaults in order to clarify the example.

Comments (20)

  1. Nicole Calinoiu says:

    The example in your last paragraph is a wee bit off. Use of at least one RequestOptional will result in tacit refusal most(*) permissions not explicitly requested by the assembly, but this is not true of RequestMinimum. Therefore, a RequestMinimum for FileIOPermission is not, by itself, sufficient for refusal of RegistryPermission.

    (*) Exceptions include SecurityPermission.Execution and identity permissions (e.g.: StrongNameIdentityPermission).

  2. Shawn says:

    Good catch — I was actually in the process of updating the entry when you posted this. I’d forgotten to point out the default values of each set, which can lead to the confusion that you mention.

    -Shawn

  3. Fred says:

    if I understand well:

    PermissionSet = (RequestOptional + RequestMinimum+ Execution + IdentityPermission) – RequestRefuse?

    But what happened with permission set provided par the evidences from code groups?

    Fred

  4. Fred says:

    OK, I think I understand.

    In fact the "Request" security actions act as a filter on the code group policy.

    Everythink that don’t pass the filter is ignore. So I can’t grant myself permissions that security policy would refuse me.

  5. <Quote>

    Internally, the CLR takes the union of the RequestMinimum and RequestOptional sets (and adds to that execution permission), and that resulting set is the only set of permissions that your application will have when it’s running. For instance, demanding unrestricted Registry permission will fail if either of the above declarative requests are in place.

    </Quote>

    [assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted = true)] by it’s own, will not cause RegistryPermission(..).Demand() to fail.

    For more information:

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconcomputingallowedpermissionset.asp

  6. Shawn says:

    Hi Alfred,

    Sorry for the confusing code snippet above, I’ll update it. You’re right that without a RequestOptional your RequestRefuse will have no affect. I’ve covered that in my section about defaults:

    <Quote>Since the permission set restriction is calculated by taking the minimum request and unioning with the optional request, and the default optional request is FullTrust, unless an Optional request is made, the union of the minimum request and the FullTrust request will result in a FullTrust set. What this boils down to is that unless you specify a RequestOptional set, the permissions your application runs under will not be limited in the fashion stated above.</Quote>

    You’re also right that this does not provide a way to increase your security. If you say RequestMinimum for FullTrust, and the CLR won’t grant you FullTrust through the CAS policy, your assembly won’t even load. This is only a way to restrict your permission sets.

    -Shawn

  7. Hi Shawn,

    <Quote>So far, so good. However, now we come to the interesting side effect, one that oftentimes confuses people new to assembly level declarative security. Namely, using any declarative security at all has the potential to decrease the permission set that your assembly is running with. This is obvious in the case of RequestRefuse, however with RequestMinimum and RequestOptional, the reasoning is far less clear.

    Internally, the CLR takes the union of the RequestMinimum and RequestOptional sets (and adds to that execution permission), and that resulting set is the only set of permissions that your application will have when it’s running. For instance, demanding unrestricted Registry permission will fail if either of the above declarative requests are in place.</Quote>

    RequestMinimum does *not* have the potential to decrease the permisssion set. Only RequestOptionl does.

    This behavior can be confirmed in http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpcondetermininggrantedpermissions.asp

    I’ve created an alternate version of your code to run in a Windows Forms application.

    On the form I putted a label, a button and added the following code to it’s Click event handler:

    private void button1_Click(object sender, System.EventArgs e)

    {

    try

    {

    new System.Security.Permissions.FileIOPermission(System.Security.Permissions.PermissionState.Unrestricted).Demand();

    this.label1.Text = "Have full FileIO permission";

    }

    catch

    {

    this.label1.Text = "Do not have full FileIO permission";

    }

    }

    To run this example, your code will need FileIOPermission and UIPermission so let’s make some tests.

    First add:

    [assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted=true)]

    and run the code on your local machine. "Have full FileIO permission" is displayed in the Console Window.

    This happens because the assembly is granted FileIOPermission and whatever other permisssions the PolicyManager grants it based on evidence provided by the host and security policies in effect.

    Now change the request to Optional:

    [assembly: FileIOPermission(SecurityAction.RequestOptional, Unrestricted=true)]

    This time the code throws a SecurityException because RequestOptional has the effect you stated in your post.

    The assembly only has permissions to execute and to do File IO. It does not have permission to do UI.

    If you run the application from any zone other than Local Machine, it will return "Do not have full FileIO permission" with RequestMininum and an exception with RequestOptional.

  8. Shawn says:

    Hi Alfred,

    RequestMinimum actually does have the potential to reduce your permission set. Like I said above, the set that you’ll get is basically:

    (Grant intersect (RequestMinimum union RequestOptional) ) minus RequestRefuse

    Now, we need to add in the default values of each item to see how things really work. By default RequestMinimum is empty, and RequestOptional is the FullTrust set. Therefore that union produces FullTrust, intersected with the granted set produces the same grant set. Subtract out the refused set (by default the emtpy set), and you can see how by default we end up with the granted set by default.

    Now, lets move on to your sample. You keep RequestRefuse empty, so we can drop that part of the equation. Next, you up RequestMinimum to FileIO, but don’t touch RequestOptional which stays at FullTrust. The union of FileIO and FullTrust is FullTrust. Intersect that with the grant set, and you’ll get the grant set back.

    In the second part of your sample you reduce the RequestOptional set to be FileIO, and keep RequestMinimum at its default empty state. Now the union of FileIO and empty is FileIO. Intersect that with the granted set, and you’ll end up with just FileIO.

    Does that help clarify things a bit? If you want to further demonstrate this, change your sample to RequestMinimum for UI, and RequestOptional for something unrelated, say Registry. You’ll see that you get an exception when you demand the FileIO permissions.

    -Shawn

  9. Hi Shawn,

    <Quote>RequestMinimum actually does have the potential to reduce your permission set. Like I said above, the set that you’ll get is basically:</Quote>

    We agree in all but the statement above.

    Since the default value of RequestMinimum is Nothing anything you put there (except Nothing) will be *more* than Nothing.

    Since RequestOptional defaults to FullTrust, anything you put there (except FullTrust it self) will be *less* than FullTrust.

    Alfred

  10. Shawn says:

    Looks like we’re down to semmantics now :-) What you say above is completely true. However, if I have some code that contains:

    [assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]

    [assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted = true)]

    [assembly: RegistryPermission(SecurityAction.RequestMinimum, Unrestricted = true)]

    [assembly: UIPermission(SecurityAction.RequestOptional, Unrestricted = true)]

    Now this code will only be allowed to execute, read files, read the registry, and do UI related work. If I remove the RequestMinimum line for RegistryPermission, I’ve done nothing to modfiy the optional set, however my code will no longer be able to access the registry. I’ve used the RequestMinimum set to limit the permissions that I’ve recieved.

    The confusing point is that since minimum and optional are unioned, and since optional defaults to FullTrust, you need to specify an optional set before the minimum set will start affecting your grant set. However, both are unioned together, so once that optional set is created both have the same affect on your resulting permission set. (Assuming that you would have been granted more than what you’re declaratively requesting).

    -Shawn

  11. Speaking of dynamic IL generation …

    Before Whidbey, the framework supplied two ways of creating code…

  12. Another interesting question arose today.&amp;nbsp; An assembly was granted FullTrust by policy, which was…

  13. Rajesh Shori says:

    I am getting following error when using the fileIO permisson

    See the end of this message for details on invoking

    just-in-time (JIT) debugging instead of this dialog box.

    ************** Exception Text **************

    System.Security.SecurityException: Request failed.

      at Act.Framework.ActFramework.FailLogOn(Exception ex, TraceCategory tCat, TraceLevel tLevel)

      at Act.Framework.ActFramework.LogOn(String userName, String password, String databaseType, String databaseHost, String databaseName, Boolean fireEvents, Boolean suppressTierCheck, Boolean suppressSchemaCheck, Boolean suppressLicenseCheck, Boolean allowTrialModeDeparture)

      at Act.Framework.ActFramework.LogOn(String userName, String password, String databaseType, String databaseHost, String databaseName, Boolean fireEvents)

      at Act.Framework.ActFramework.LogOn(String userName, String password, String databaseType, String databaseHost, String databaseName)

      at Act.Framework.ActFramework.LogOn(String xmlPADFile, String userName, String password)

      at UserControl.UserControl1.LoginToACTDatabase()

      at UserControl.UserControl1.button1_Click(Object sender, EventArgs e)

      at System.Windows.Forms.Control.OnClick(EventArgs e)

      at System.Windows.Forms.Button.OnClick(EventArgs e)

      at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)

      at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)

      at System.Windows.Forms.Control.WndProc(Message& m)

      at System.Windows.Forms.ButtonBase.WndProc(Message& m)

      at System.Windows.Forms.Button.WndProc(Message& m)

      at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)

      at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)

      at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    The granted set of the failing assembly was:

    <PermissionSet class="System.Security.PermissionSet"

                  version="1">

      <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Security.Permissions.FileDialogPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Security.Permissions.IsolatedStorageFilePermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Security.Permissions.ReflectionPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Security.Permissions.RegistryPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Flags="Assertion, UnmanagedCode, Execution, ControlThread, ControlEvidence, ControlPolicy, SerializationFormatter, ControlDomainPolicy, ControlPrincipal, ControlAppDomain, RemotingConfiguration, Infrastructure, BindingRedirects"/>

      <IPermission class="System.Security.Permissions.UIPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Net.DnsPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Drawing.Printing.PrintingPermission, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Diagnostics.EventLogPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Net.SocketPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Net.WebPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.DirectoryServices.DirectoryServicesPermission, System.DirectoryServices, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Messaging.MessageQueuePermission, System.Messaging, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.ServiceProcess.ServiceControllerPermission, System.ServiceProcess, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Data.OleDb.OleDbPermission, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Data.SqlClient.SqlClientPermission, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Unrestricted="true"/>

      <IPermission class="System.Security.Permissions.SiteIdentityPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Site="localhost"/>

      <IPermission class="System.Security.Permissions.UrlIdentityPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Url="http://localhost/"/&gt;

      <IPermission class="System.Security.Permissions.ZoneIdentityPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                   version="1"

                   Zone="Trusted"/>

    </PermissionSet>

    ************** Loaded Assemblies **************

    mscorlib

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/microsoft.net/framework/v1.1.4322/mscorlib.dll

    —————————————-

    System

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/assembly/gac/system/1.0.5000.0__b77a5c561934e089/system.dll

    —————————————-

    System.Drawing

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/assembly/gac/system.drawing/1.0.5000.0__b03f5f7f11d50a3a/system.drawing.dll

    —————————————-

    System.DirectoryServices

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/assembly/gac/system.directoryservices/1.0.5000.0__b03f5f7f11d50a3a/system.directoryservices.dll

    —————————————-

    System.Messaging

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/assembly/gac/system.messaging/1.0.5000.0__b03f5f7f11d50a3a/system.messaging.dll

    —————————————-

    System.ServiceProcess

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/assembly/gac/system.serviceprocess/1.0.5000.0__b03f5f7f11d50a3a/system.serviceprocess.dll

    —————————————-

    System.Data

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/assembly/gac/system.data/1.0.5000.0__b77a5c561934e089/system.data.dll

    —————————————-

    RegexAssembly18_0

       Assembly Version: 0.0.0.0

       Win32 Version: n/a

       CodeBase:

    —————————————-

    UserControl

       Assembly Version: 1.0.0.0

       Win32 Version: n/a

       CodeBase: http://localhost/ActiveXTestWeb/UserControl.dll

    —————————————-

    System.Windows.Forms

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/assembly/gac/system.windows.forms/1.0.5000.0__b77a5c561934e089/system.windows.forms.dll

    —————————————-

    Act.Framework

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.framework/8.2.82.0__ebf6b2ff4d0a08aa/act.framework.dll

    —————————————-

    Act.Shared.Diagnostics

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.shared.diagnostics/8.2.82.0__ebf6b2ff4d0a08aa/act.shared.diagnostics.dll

    —————————————-

    Act.Shared.Utilities

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.shared.utilities/8.2.82.0__ebf6b2ff4d0a08aa/act.shared.utilities.dll

    —————————————-

    Act.Shared.Config

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.shared.config/8.2.82.0__ebf6b2ff4d0a08aa/act.shared.config.dll

    —————————————-

    System.Xml

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/assembly/gac/system.xml/1.0.5000.0__b77a5c561934e089/system.xml.dll

    —————————————-

    Microsoft.mshtml

       Assembly Version: 7.0.3300.0

       Win32 Version: 7.0.3300.0

       CodeBase: file:///c:/windows/assembly/gac/microsoft.mshtml/7.0.3300.0__b03f5f7f11d50a3a/microsoft.mshtml.dll

    —————————————-

    Accessibility

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.573

       CodeBase: file:///c:/windows/assembly/gac/accessibility/1.0.5000.0__b03f5f7f11d50a3a/accessibility.dll

    —————————————-

    Act.Shared.Licensing

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.shared.licensing/8.2.82.0__ebf6b2ff4d0a08aa/act.shared.licensing.dll

    —————————————-

    Act.Data

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.data/8.2.82.0__ebf6b2ff4d0a08aa/act.data.dll

    —————————————-

    Act.Data.ActDb

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.data.actdb/8.2.82.0__ebf6b2ff4d0a08aa/act.data.actdb.dll

    —————————————-

    Act.Data.Resources

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.data.resources/8.2.82.0__ebf6b2ff4d0a08aa/act.data.resources.dll

    —————————————-

    System.EnterpriseServices

       Assembly Version: 1.0.5000.0

       Win32 Version: 1.1.4322.2032

       CodeBase: file:///c:/windows/assembly/gac/system.enterpriseservices/1.0.5000.0__b03f5f7f11d50a3a/system.enterpriseservices.dll

    —————————————-

    Act.Shared.LicProvider

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.shared.licprovider/8.2.82.0__ebf6b2ff4d0a08aa/act.shared.licprovider.dll

    —————————————-

    Act.Shared.Windows.Forms

       Assembly Version: 8.2.82.0

       Win32 Version: 8.2.82.0

       CodeBase: file:///c:/windows/assembly/gac/act.shared.windows.forms/8.2.82.0__ebf6b2ff4d0a08aa/act.shared.windows.forms.dll

    —————————————-

    ************** JIT Debugging **************

    To enable just in time (JIT) debugging, the config file for this

    application or machine (machine.config) must have the

    jitDebugging value set in the system.windows.forms section.

    The application must also be compiled with debugging

    enabled.

    For example:

    <configuration>

       <system.windows.forms jitDebugging="true" />

    </configuration>

    When JIT debugging is enabled, any unhandled exception

    will be sent to the JIT debugger registered on the machine

    rather than being handled by this dialog.

  14. Graham S says:

    I’ve read ( http://www.bluevisionsoftware.com/WebSite/TipsAndTricksDetails.aspx?Name=PermissionRequests ) that the following attribute means

       "… makes an optional request for no permission set. This means that no permission set will be granted to the code by the code access security policy. All permissions that should be granted must be requested using additional assembly-level attributes.":

    [assembly: PermissionSet(SecurityAction.RequestOptional, Unrestricted = false)]

    I’m having a hard time seeing why it has that effect.  Likewise with each of the other variations (as applied individually to an assembly); I can’t figure out what they mean and why:

    [assembly: PermissionSet(SecurityAction.RequestOptional, Unrestricted = true)]

    [assembly: PermissionSet(SecurityAction.RequestMinimum, Unrestricted = false)]

    [assembly: PermissionSet(SecurityAction.RequestMinimum, Unrestricted = true)]

    [assembly: PermissionSet(SecurityAction.RequestRefuse, Unrestricted = false)]

    [assembly: PermissionSet(SecurityAction.RequestRefuse, Unrestricted = true)]

    I’d be very grateful for some enlightenment on this – it’s been puzzling me for months.  There seems to be lots of information about using RequestOptional/Minimimum/Refuse with Unrestricted/true/false on specific permissions but not on "no permission sets".

  15. shawnfa says:

    Hi Graham,

    PermissionSet(Unrestricted = true) means FullTrust, so that’s esentially doing the declarative action on *every* permission.

    If you were to do it on PermissionSet(Unrestricted = false), that’s the empty permission set, so you can translate it to doing the corresponding action on *no* permissions.

    The only action that PermissionSet(Unrestricted = false) will have an affect on is RequestOptional since that defaults to FullTrust, and you’re overriding it with Nothing.

    -Shawn

  16. Graham S says:

    Hi Shawn, thank you so much for clearing that up for me.

    Graham.

  17. The story so far … And now for more of the adventures of Jack Bauer! ;). So since I posted the first