Return-Path: Delivered-To: apmail-avalon-cvs-archive@www.apache.org Received: (qmail 98691 invoked from network); 19 Jan 2004 21:43:02 -0000 Received: from daedalus.apache.org (HELO mail.apache.org) (208.185.179.12) by minotaur-2.apache.org with SMTP; 19 Jan 2004 21:43:02 -0000 Received: (qmail 47221 invoked by uid 500); 19 Jan 2004 21:42:50 -0000 Delivered-To: apmail-avalon-cvs-archive@avalon.apache.org Received: (qmail 47158 invoked by uid 500); 19 Jan 2004 21:42:50 -0000 Mailing-List: contact cvs-help@avalon.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Avalon CVS List" Reply-To: "Avalon Developers List" Delivered-To: mailing list cvs@avalon.apache.org Received: (qmail 47128 invoked from network); 19 Jan 2004 21:42:49 -0000 Received: from unknown (HELO minotaur.apache.org) (209.237.227.194) by daedalus.apache.org with SMTP; 19 Jan 2004 21:42:49 -0000 Received: (qmail 98667 invoked by uid 1774); 19 Jan 2004 21:43:01 -0000 Date: 19 Jan 2004 21:43:01 -0000 Message-ID: <20040119214301.98666.qmail@minotaur.apache.org> From: niclas@apache.org To: avalon-cvs@apache.org Subject: cvs commit: avalon/merlin/platform/xdocs/starting/advanced security.xml index.xml X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N niclas 2004/01/19 13:43:01 Modified: merlin/platform/xdocs/meta/block/classloader index.xml navigation.xml merlin/platform/xdocs/meta/kernel/parameters index.xml merlin/platform/xdocs/starting/advanced index.xml Added: merlin/platform/xdocs/meta/block/classloader/grant index.xml navigation.xml permission.xml merlin/platform/xdocs/starting/advanced security.xml Log: Documentation for the new security system. Needs plenty of touch up. Revision Changes Path 1.2 +16 -0 avalon/merlin/platform/xdocs/meta/block/classloader/index.xml Index: index.xml =================================================================== RCS file: /home/cvs/avalon/merlin/platform/xdocs/meta/block/classloader/index.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- index.xml 24 Sep 2003 09:34:46 -0000 1.1 +++ index.xml 19 Jan 2004 21:43:00 -0000 1.2 @@ -76,6 +76,12 @@ Jar file option extensions repository. + + grant0..1 + + Granting permissions to code level security. + + @@ -95,6 +101,16 @@ + + + + read + + + read + write + + ]]> 1.6 +1 -0 avalon/merlin/platform/xdocs/meta/block/classloader/navigation.xml Index: navigation.xml =================================================================== RCS file: /home/cvs/avalon/merlin/platform/xdocs/meta/block/classloader/navigation.xml,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- navigation.xml 23 Dec 2003 17:30:30 -0000 1.5 +++ navigation.xml 19 Jan 2004 21:43:00 -0000 1.6 @@ -73,6 +73,7 @@ + 1.1 avalon/merlin/platform/xdocs/meta/block/classloader/grant/index.xml Index: index.xml ===================================================================
Classloader
ElementOccuranceDescription
permission0..n The permission descriptor.

The Grant is somewhat similar to the standard Java Security policy files, except that it is assigned per container instead of for the code loading location. This allow for sharing central repositories of code, without necessary giving all the same level of security within a system.

read read write ]]>
1.1 avalon/merlin/platform/xdocs/meta/block/classloader/grant/navigation.xml Index: navigation.xml =================================================================== Merlin 1.1 avalon/merlin/platform/xdocs/meta/block/classloader/grant/permission.xml Index: permission.xml ===================================================================
Include Directive
ElementOccuranceDescription
action0..n The action descriptor.
AttributeRequiredDescription
classyes The name of the Permission class. This classname must be a subclass of the java.security.Permission class.
nameno This is the first argument passed into the constructor. Most Permission classes calls this the "name" argument, but the has other names for certain permission classes, e.g. FilePermission calls it "path".

A resource directive is a logical reference to a jar file within the enclosing repository. A repository implementation is responsible for the mapping of logical directives to physical jar URL.

The following example block.xml demonstrates the inclusion of three blocks within another enclosing block. In this example, the common shared API (containing service interfaces classes is declared in the containing block classloader).

read read write ]]>
1.7 +19 -1 avalon/merlin/platform/xdocs/meta/kernel/parameters/index.xml Index: index.xml =================================================================== RCS file: /home/cvs/avalon/merlin/platform/xdocs/meta/kernel/parameters/index.xml,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- index.xml 15 Jan 2004 13:32:51 -0000 1.6 +++ index.xml 19 Jan 2004 21:43:00 -0000 1.7 @@ -86,7 +86,7 @@ Parameters that are currently available is;

- + @@ -99,6 +99,23 @@ deployed. If the interrupt() fails, the whole JVM must be considered unstable, and should terminate. + + + + + + +
NameDefaultDescription
NameDefaultDescriptionSince
urn:composition:deployment.timeout 5000 + 3.2.5 +
urn:composition:security.enabledfalse + This is a global switch for turning the code level security + on or off. For compatibility reasons, the default is false, + but any production system should have this true. In the + kernel.xml it is set to true, and for the debug.xml it is + set to false. + + 3.3 +
@@ -113,6 +130,7 @@ any component or container to start-up, before interrupting or failing. --> + ]]> 1.8 +8 -0 avalon/merlin/platform/xdocs/starting/advanced/index.xml Index: index.xml =================================================================== RCS file: /home/cvs/avalon/merlin/platform/xdocs/starting/advanced/index.xml,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- index.xml 25 Oct 2003 15:27:07 -0000 1.7 +++ index.xml 19 Jan 2004 21:43:00 -0000 1.8 @@ -83,6 +83,14 @@ it provides. + Container Security + + Starting from Merlin 3.3, it is possible to grant permission per + container, similarily to the standard Java feature of granting + permissions to the code based on where it was loaded from. + + + Unit Tests Setting up unit tests that leverage merlin as the component factory. 1.1 avalon/merlin/platform/xdocs/starting/advanced/security.xml Index: security.xml ===================================================================
Using Merlin

Starting from Merlin 3.3, it is possible to grant permissions to classes within a container. This is done by the declaration of a <grant> element in the classloader definition section in the block descriptor (e.g. block.xml).

In the example below you should be able to see the mechanism. The multiple <action> elements, instead of a single String value as is more common, was chosen for easier tool support while still allowing you to place multiple comma separated actions into a single <action> element, passed to the Permission constructor as-is.

read write read read write ]]>

There can only be a single <grant> for each <classloader> and any number of <permission> elements within.

If you are only looking for basic security, similar to any typical stand-alone application, that would depend on a Java Security Policy file, you don't need to do anything special. All classes in Java will perform the security checks behind the scenes, protecting files, network connection and many other system resources. Please refer to your Java Security documentation for full details.

If you want to guard some resource or a section of code, you will need to;

  • Create a subclass of java.security.Permission, or one of its subclasses such as java.lang.BasicPermission, and override the implies(), equals() and hashCode() methods.
  • Insert a AccessController.checkPermission() at the relevant points in your code. (See examples below.)

This first example uses a simple named RuntimePermission.

In this example, we utilizes the existing java.lang.RuntimePermission to do a very simple check, i.e is the current protection domain allowed to use the SuperGlue.

And to make this work in your Merlin application, you would need to insert the appropriate permission in the <grant> element.

]]>

If you need something more complicated that can not be fulfilled with the existing Permission classes, you will need to create your own. This can be rather tricky, depending on what you are actually trying to do.

In the example below, we have a Permission class that ensures that an amount is within its boundaries, for instance for a banking application. The semantics are;

  • The name argument for a granted permission (declared) contains a minimum value, followed by a dash and then followed by a maximum value.
  • The name argument for a required permission (programmatically) only contains a single value, which is the requested amount. The amount is expressed in cent, and no fractional numbers needed.
  • If any of the two values are missing, the default is used. The default is 1000000 for each.
  • The action argument contains either "deposit" or "withdrawal".
  • The granted permission must contain the action of the required permission, and the required permission's amount must be within the limits of the granted permission.

As we can see it is a fairly straight forward algorithm, but a bit hard to put in words, and I hope I haven't missed something. To do this with Java Security permissions is fairly easy.

0 ) return false; if( requesting.m_Minimum < m_Minimum ) return false; if( requesting.m_Minimum > m_Maximum ) return false; return true; } private void parseAmount( String amount ) { m_Minimum = 1000000; m_Maximum = 1000000; if( amount == null || "".equals( amount ) ) return; int dash = amount.indexOf( '-' ); if( dash < 0 ) { try { m_Minimum = Long.parseLong( amount ); } catch( NumberFormatException e ) {} // ignore, use default } else { String am1 = amount.substring( 0, dash ); String am2 = amount.substring( dash + 1 ); try { m_Minimum = Long.parseLong( am1 ); } catch( NumberFormatException e ) {} // ignore, use default try { m_Maximum = Long.parseLong( am2 ); } catch( NumberFormatException e ) {} // ignore, use default } } private void parseActions( String actions ) { // This should probably be done differently. m_Actions = 0; if( actions.indexOf( "withdrawal" ) ) m_Actions = 1; if( actions.indexOf( "deposit" ) ) m_Actions += 2; } } ]]>

Please note that the code has not yet been tested. If you do please post any mistake to dev@avalon.apache.org. Thank you.

Then in the actual code, we would do something like this;

Wasn't that easy? Well, it would have been if we could tie the principal customer/client/user to the protection domain that is checked. This is currently on the drawing board for Avalon Merlin, and will probably not be ready until version 4.0, somewhere mid or late 2004. While awaiting this Subject-based, generic, pluggable security system, you can hack the above example a little bit, for some basic subject driven security.

In the implies() method, you reach out and detect who is executing the current thread, for instance through a ThreadLocal variable, ask some authoritive object instance for the amounts allowed and perform the check. This is NOT the recommended method for larger and more complex system (such as banks), but can work as a temporary solution for the time being.

--------------------------------------------------------------------- To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org For additional commands, e-mail: cvs-help@avalon.apache.org