[Mono-devel-list] Code Access Security Latest!

Sebastien Pouliot spouliot at videotron.ca
Wed Jan 28 23:11:51 EST 2004


Hello Ben,

Nice plan. Some comments inline.
Please include the content into the CAS bugzilla entry (#52606)!

Sebastien Pouliot
home: spouliot at videotron.ca
blog: http://pages.infinit.net/ctech/poupou.html

  -----Original Message-----
  From: mono-devel-list-admin at lists.ximian.com
[mailto:mono-devel-list-admin at lists.ximian.com]On Behalf Of Benjamin Wootton
  Sent: 28 janvier 2004 18:12
  To: lupus at ximian.com; duncan at ximian.com; ndrochak at gol.com;
spouliot at motus.com
  Cc: mono-devel-list at lists.ximian.com
  Subject: [Mono-devel-list] Code Access Security Latest!


  Apologies for the wordy email, but Paolo asked for an update earlier.  The
text below explains how I understand the problem and the decisions that I
think need to be made.  Any feedback would be very, very much appreciated.



  So far:

  I have decided to cut the problem down for the purposes of my thesis to
the following 5 items, representing the core of CAS.



  .         A basic caspol.exe.  This writes out a default security policy,
and allows the user to add or remove permissions to a given code group.  It'
s not going to be fully complete, but it will be in C# so it's completely
extensible.
  [Sebastien Pouliot] If you're doing a CLI version please try to keep the
command line options compatible with MS version. This should help for both
documentation and scripting.

  .         Runtime loading of security policy and calculation of final
policy taking into account the policy levels.

  .         Calculating final grants to assemblies based on local policy and
evidence, and assigning these grants to the assembly objects as XML.
  [Sebastien Pouliot] Note that the Mono runtime doesn't supply any
evidences when loading assembly - but this should be relatively easy to add.
I'll fill a bug entry (with sample) for this tomorrow morning.

  .         CodeAccessPermission.Demand(), CodeAccessPermission.Deny() and
CodeAccessPermission.Assert().
  [Sebastien Pouliot] PermitOnly ?

  .         Declarative RequestMinimum, RequestOptional etc.



  I will add more as time allows, and may carry on working on this after my
deadline.  Either way I hope to leave something useful, along with some
useful documentation so that someone else can continue my work.  For the
purposes of my thesis though (which has to be finished in 2 months!) it's
important that I have a useful subset which is achievable.
  [Sebastien Pouliot] You'll be a busy bee ;-)



  Something I won't be attempting as part of this project:



  .         Declarative security demands.  They are going to involve hacking
the JIT, albeit in a simple way as described at the bottom of [4].



  Plan:

  Essentially, here is what I think has to happen.  The decisions have quite
a bit of consequence, and even if I don't end up completing this it would be
nice if they were made in the best way early on so I at least offer a good
base for someone to continue the work.



  .         There are three security policy levels - enterprise, machine and
user.  Policies set across the enterprise supersede those for the machine
and user.  Each level has an XML .config file associated with it [1] that
describes local policy.  Caspol and the management console provide a nice
way of manipulating these files.
  [Sebastien Pouliot] Actually there's also the AppDomain policy level - the
only one you can create at runtime.

  .         At the runtime start, there is a check to see if CAS is off, or
if full trust is assigned.
  [Sebastien Pouliot] This cannot (only) be done at startup. The
SecurityManager can be turn on/off by the application. Also this shouldn't
disabled role-based security (see SecurityManager.SecurityEnabled).

     If either of those is true then we need to toggle CAS off to prevent
any overhead.  In any other situation the configuration files have to be
parsed and stored *somewhere* in the runtime.
  [Sebastien Pouliot] Because CAS can be turned on/off at runtime you may
have to keep the config along (or resolve it again when CAS is turned on).
Anyway in most cases different assemblies will have different permissions -
some may have FullTrust others not. Having an "assembly flag" may be better
than a "global flag".

     There are managed classes representing code groups and permission sets,
but I'm not sure if the intention is to make use of these to reflect what
was in the config files, or if we should store some representation of this
in the C.  (One point of confusion - does this occur at startup, or do we
call into SecurityManager.ResolvePolicy() which can call
LoadPolicyFromFile() - The guys who wrote PolicyLevel.cs may be able to help
here.)
  [Sebastien Pouliot] Not 100% sure (I'll read that part again) but my guess
would be once* per AppDomain - unless some action are taken into an existing
AppDomain (like PolicyLevel.Reset).



  So, at this point the runtime knows all about local policy.



  .         Assemblies have evidence [0] attached to them.

  .         The goal of CAS is to use evidence to determine if any
membership conditions are met.  If any are met, then the assembly will be
added to a specific code group.  If none are met then they fall into a
default code group.

  .         Associated with each code group is a permission set.  An example
of this might be code that has been Microsoft Strong Named meeting the
Strong Name membership condition, being assigned to the Strong Name group
which has associated with it a very flexible set of permissions.

  .         An assembly can also request or deny certain permissions
declaratively.

  .         The logic for calculating the final grant set from the requests,
denials, and evidence all seem to be encapsulated in the
SecurityManager.ResolvePolicy() method [3].  I think this needs to be called
indirectly at assembly load time.
  [Sebastien Pouliot] Probably not only called at load time - as the
PermissionSet (requested, optional and denied) can change for each method
called (e.g. before with declarative or during with imperative).

   This method returns a final grant set.
  [Sebastien Pouliot] The effective granted permissions are the permission
returned (return value) minus the permission denied (out parameter).

  .         The final grant set can be extracted as XML [2], and stored with
the assembly.
  [Sebastien Pouliot] It may be better to keep* the resulting sets
(granted/denied) as PermissionSet between invocations to avoid To/FromXml
conversions. *Unless evidences or input PermissionSet are modified...



  At this point each assembly knows it's grant set.  At this point we can
actually start to use CAS.



  .         Developers can demand permissions.  This triggers a stack walk.
  [Sebastien Pouliot] except in some special cases, like PrincipalPermission
[4]

    For each item in the stack we get the assembly, get its associated
permission set as XML, and recreate the permission set.
  [Sebastien Pouliot] better (performance-wise) to keep it as a
PermissionSet object

     We then ask if the demanded permission is a subset of the associated
permission set.  For all items in the stack this has to be true, else a
SecurityException is thrown.

  .         LinkDemands are similar - we just only walk one step of the
stack.
  [Sebastien Pouliot] LinkDemand should be done during JIT compilation (no
need to repeat the same check each time as linking won't change). However
this requires to some JIT hacking...

  .         I'm not sure how to handle Deny()'s and Assertions at the
moment.
  [Sebastien Pouliot] Assert -> stop the stack walk without throwing a
SecurityException (get out of jail card). Deny -> stop the stack walk and
throw a SecurityException (go to jail, do not pass go and do not collect
200$ ;-).

  .         Class libraries need to have Demands() placed throughout.
  [Sebastien Pouliot] This will requires a complete review of the class
library.

  Unfortunately Microsoft seem to use imperative demands
  [Sebastien Pouliot] You cannot use security attributes from the assembly
they are defined - so corlib must use imperative demands everywhere
required.

   - I tried to use reflection to look for security attributes, but none are
listed.  This means that we can't automate this process
  [Sebastien Pouliot] Hopefully most of them seems to be documented on MSDN.



  Most of this last part is completed.[Sebastien Pouliot] Hmm... almost no
Demands are currently present in the class library. However most the
Permission/Policy class are present and about half have their unit tests.



  Thanks

  Ben



  [0]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconsecuritypolicyadministrationoverview.asp

  [1]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconsecurityconfigurationfiles.asp

  [2]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfSystemSecurityPermissionSetClassToXmlTopic.asp

  [3]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfsystemsecuritysecuritymanagerclassresolvepolicytopic2.asp

  [4] http://bugzilla.ximian.com/show_bug.cgi?id=52693






-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20040128/33bdffed/attachment.html 


More information about the Mono-devel-list mailing list