CAS Policy on 64-bit Machines

Well it’s been quite a while since my last post. I hope you all had a happy holiday season!

Today I’m going to talk about an issue I saw recently with a 64-bit machine and the partial trust tests for the Entity Framework. Even though .NET 4 disables CAS policy, it is more interesting for the Entity Framework to test with CAS policy enabled, because this allows us to configure security permissions on a per-assembly basis instead of per-AppDomain. The workflow for the tests is similar to the following:

  1. Enable CAS policy.
  2. Use the System.Security.Policy APIs to configure the correct set of permissions for the test assemblies. (Some have ReflectionPermission, some don’t, etc.) This is a separate EXE from the next step.
  3. Initialize the test harness and run the test cases.

When running in our lab recently, a few test cases failed for reasons I could not explain. Further analysis revealed that the tests were running in full trust, and so these negative test cases failed because the expected exceptions were not thrown. How did this happen?

Diagnosis

The first thing I did was to experiment with the command line switches of caspol.exe. I started a new command prompt and ran the following command. The –rsp switch stands for resolve permission set. System.Data.Test.PartialTrust.Caller.dll is the name of one of the assemblies that needs a custom permission set.

caspol.exe –rsp System.Data.Test.PartialTrust.Caller.dll

Microsoft (R) .NET Framework CasPol 4.0.21006.1
Copyright (c) Microsoft Corporation.  All rights reserved.

WARNING: The .NET Framework does not apply CAS policy by default. Any settings
shown or modified by CasPol will only affect applications that opt into using
CAS policy.

Please see http://go.microsoft.com/fwlink/?LinkId=131738 for more information.

Resolving permissions for level = Enterprise
Resolving permissions for level = Machine
Resolving permissions for level = User

Grant =
<PermissionSet class="System.Security.PermissionSet"
version="1"
Unrestricted="true"/>

Success

This had at least confirmed my suspicions that the tests were running in full trust. I looked back at the original executable code that configures the policy for the assemblies. It did not seem out of the ordinary, and besides, it had worked in many previous test runs.

C#

static void SetPermissions()

{

    // Find the machine policy level

    PolicyLevel machinePolicyLevel = null;

    IEnumerator ph = SecurityManager.PolicyHierarchy();

 

    while (ph.MoveNext())

    {

        PolicyLevel pl = (PolicyLevel)ph.Current;

        if (pl.Label == "Machine")

        {

            machinePolicyLevel = pl;

            break;

        }

    }

 

    NamedPermissionSet ps = new NamedPermissionSet("CallerPermSet", PermissionState.None);

 

    // Add permissions (omitted)

 

    StrongNamePublicKeyBlob key = typeof(Caller).Assembly.Evidence

      .OfType<StrongName>().First().PublicKey;

    IMembershipCondition mc = new StrongNameMembershipCondition(key, null, null);

 

    // Create the code group

    PolicyStatement policy = new PolicyStatement(ps, PolicyStatementAttribute.Exclusive);

 

    CodeGroup codeGroup = new UnionCodeGroup(mc, policy);

 

    codeGroup.Description = "Permissions for PT Caller";

    codeGroup.Name = "CallerGroup";

 

    // Add the code group

    machinePolicyLevel.RootCodeGroup.AddChild(codeGroup);

 

    // Save changes

    SecurityManager.SavePolicy();

}

VB

Sub SetPermissions()

    ‘ Find the machine policy level

    Dim machinePolicyLevel As PolicyLevel = Nothing

    Dim ph As IEnumerator = SecurityManager.PolicyHierarchy()

 

    While ph.MoveNext()

        Dim pl As PolicyLevel = DirectCast(ph.Current, PolicyLevel)

        If pl.Label = "Machine" Then

            machinePolicyLevel = pl

            Exit While

        End If

    End While

 

    Dim ps As NamedPermissionSet = New NamedPermissionSet("CallerPermSet", PermissionState.None)

 

    ‘ Add permissions (omitted)

    Dim key As StrongNamePublicKeyBlob = GetType(Caller).Assembly.Evidence _

        .OfType(Of StrongName)().First().PublicKey()

    Dim mc As IMembershipCondition = New StrongNameMembershipCondition(key, Nothing, Nothing)

 

    ‘ Create the code group

    Dim policy As PolicyStatement = New PolicyStatement(ps, PolicyStatementAttribute.Exclusive)

 

    Dim codeGroup As CodeGroup = New UnionCodeGroup(mc, policy)

 

    codeGroup.Description = "Permissions for PT Caller"

    codeGroup.Name = "CallerGroup"

 

    ‘ Add the code group

    machinePolicyLevel.RootCodeGroup.AddChild(codeGroup)

 

    ‘ Save changes

    SecurityManager.SavePolicy()

End Sub

My next plan of attack was to determine whether the changes to security policy were really being made. Even though no exceptions were thrown, I couldn’t understand why caspol –rsp would tell me that the framework would run our test assembly in full trust. i tried listing all the code groups from caspol under the Machine level:

caspol –m –lg

Microsoft (R) .NET Framework CasPol 4.0.21006.1
Copyright (c) Microsoft Corporation.  All rights reserved.

WARNING: The .NET Framework does not apply CAS policy by default. Any settings
shown or modified by CasPol will only affect applications that opt into using
CAS policy.

Please see http://go.microsoft.com/fwlink/?LinkId=131738 for more information.

Policy change prompt is ON

Level = Machine

Code Groups:

1.  All code: Nothing
   1.1.  Zone – MyComputer: FullTrust
      1.1.1.  StrongName – 00240000048000009400000006020000002400005253413100040
0000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE
79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E82
1C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8
A12436518206DC093344D5AD293: FullTrust
      1.1.2.  StrongName – 00000000000000000400000000000000: FullTrust
   1.2.  Zone – Intranet: LocalIntranet
      1.2.1.  All code: Same site Web
      1.2.2.  All code: Same directory FileIO – ‘Read, PathDiscovery’
   1.3.  Zone – Internet: Internet
      1.3.1.  All code: Same site Web
   1.4.  Zone – Untrusted: Nothing
   1.5.  Zone – Trusted: Internet
      1.5.1.  All code: Same site Web
Success

The custom code groups weren’t there! But if I inspected the code groups in code after running the setup executable, then they did appear.

Resolution

Eventually I just got frustrated and pulled out procmon to figure out what caspol.exe was doing under the covers. I saw it reading and writing from configuration files in the .NET Framework directory, and that’s when it hit me. The setup executable that writes to security policy was compiled as AnyCPU and thus any security policy edits were flushed to the configuration files in the %WINDIR%Microsoft.NETFramework64 directory. Our test harness was erroneously running as a 32-bit application on a 64-bit machine, which means the security policy it read was actually from the %WINDIR%Microsoft.NETFramework directory!

There are two versions of caspol.exe on 64-bit machines! One is for 32-bit applications, and the other is for 64-bit. As you can probably infer, I was incorrectly using the 32-bit one in my diagnosis above, which is why I never saw any of the custom code groups added to security policy.

It took a couple hours to figure this out, so I hope this post can help save you some time if you ever run into a similar situation!

 

Referenced from: http://davedewinter.com/2010/01/10/cas-policy-on-64-bit-machines-19/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值