Re: [Off Topic] SecurityManager XML Policy questions/recommendations
Hi Jean-Francois, My comments are intermixed below. Jean-Francois Arcand wrote: Hi Glenn, here is a couple of questions regarding your SecurityManager XML works: (1) All permissions seems to be stored in class SecurityPolicyBase. The Map used to store permission is static, meaning all permissions will be stored in (why all? doing permissions.implies will browse every permissions instead of application-scope permission). This can be very slow. I'm not sure I follow this. Could you expand on this? Or give me an example of a better way to return the permissions for a CodeSource? There likely is a better way to get the permissions than the code I wrote which uses an Iterator. I followed the XP method of first getting it to work, then determine what is worth optimizing. I haven't profiled this code yet. The getPermissions() method is only a one time performance hit for each individual java class load. (2) Child scope will always have parent scope permissions. It there a reason? Can it be optional? Its the other way around, a parent will inherit the permissions configured for a child. This is done to make configuring your security policy easier. This is because all classes on the stack are required to have the permission (Unless a doPrivileged was invoked) for the permission to be granted. It is easier to define a specific permission just once rather than having to define it for every codebase. How you nest your SecurityPolicy elements determines the inheritance. If you nest them similar to how they get invoked in a stack trace inheritance makes the policy configuration easier. (3) I didn't see any 'doPrivilege', 'Subject.doAsPrivilege' etc. in your code. I think we need to think about a notion of Tomcat Principal/Subject to only allow Tomcat doing those kind of operations (adding/removing permissions). This is usefull not only for your stuff, but for all security related call. The policy code is in package org.apache.catalina.policy, this package has both package.access and package.definition restrictions. Only code that has been granted the Runtime accessClassInPackage.org.apache.catalina.* can use the code. In the normal policy config that is only the catalina core. (4) There is a class called sun.security.provider.PolicyFile where the unmarshalling' of policy statement are made. Your XML Policy file do not define any Policy.implies method. meaning if XMLPolicy.implies is invoked, the call will be delegated to PolicyFile.implies, who doesn't know anything about the permission. This method will return false for every policy.xml permission sinde they are created outside the defaut Policy scope. If a Servlet try accessing a file that is not granted in the policy.xml file, right now, the permission will be allowed since the AccesController will call the Policy.implies..IMBW... sun.security.provider.PolicyFile is just an implementation of a Policy. Which is a SUN specific implementation and not part of the java.security API. My XMLPolicy class extends the abstract Policy class which does not have an implies() method. XMLPolicy is put in place at runtime using SecurityManager.setPolicy(), at that point XMLPolicy is in control of determining what permissions have been granted to a CodeSource. Whether a servlet has permission depends on the Permissions assigned to it by the Catalina WebappClassLoader when the class is instantiated. It then uses the Policy implemenation, in this case XMLPolicy. (5) I did not see any statement about replacing the policy.provider=sun.security.provider.PolicyFile (using the -Djavax.security.jacc.policy.provider= ) ? The property javax.security.jacc.policy.provider is specific to JSR 115. I though of using the policy.provider config in $JAVA_HOME/jre/lib/security/java.security. But that requires installing the all of the required jar files to implement XMLPolicy in $JAVA_HOME/jre/lib/ext. This could be a frequent tomcat support problem. So instead I designed it to replace the default PolicyFile implemenation at runtime using SecurityManager.setPolicy(). (6) Your code define the policy configuration parts (permissions creation). What about the policy decision part? Which classes will enforce the permission created? The WebappClassLoader/ServletPolicyBase have a getPermissions() method, but I was unable to make the link between this method and the SecurityManager...Here is probably my inexperience with Tomcat. The standard implementation of the SecurityManager enforces the permissions. I didn't have to do anything. The SecurityManager and ClassLoaders are closely related. You might look at the catalina WebappClassLoader. (7) The security defined in the Deployment Descriptor may contredict the security defined in the policy.xml file. Which one will be applied? Ex: Access to folder X is denied by the policy.xml file, but granted to principal A in the deployment descriptor.
Re: [Off Topic] SecurityManager XML Policy questions/recommendations
Hi Glenn, see below... Glenn Nielsen wrote: Hi Jean-Francois, My comments are intermixed below. Jean-Francois Arcand wrote: Hi Glenn, here is a couple of questions regarding your SecurityManager XML works: (1) All permissions seems to be stored in class SecurityPolicyBase. The Map used to store permission is static, meaning all permissions will be stored in (why all? doing permissions.implies will browse every permissions instead of application-scope permission). This can be very slow. I'm not sure I follow this. Could you expand on this? Or give me an example of a better way to return the permissions for a CodeSource? My mistake. I did not properly analyse the inner class CodeSourcePermission. Your approach is fast enough. There likely is a better way to get the permissions than the code I wrote which uses an Iterator. I followed the XP method of first getting it to work, then determine what is worth optimizing. I haven't profiled this code yet. The getPermissions() method is only a one time performance hit for each individual java class load. ...except when the refreshPolicy is invoked. You can get permissions from the CodeSourcePermission's collection instead of re-creating all the permissions (I doubt the permission file will change entirely). You will pay the price of an ifBut I'm not sure you can do that since Castor is in the picture. Can you check if a permission exists before you create it? (2) Child scope will always have parent scope permissions. It there a reason? Can it be optional? Its the other way around, a parent will inherit the permissions configured for a child. This is done to make configuring your security policy easier. This is because all classes on the stack are required to have the permission (Unless a doPrivileged was invoked) for the permission to be granted. It is easier to define a specific permission just once rather than having to define it for every codebase. How you nest your SecurityPolicy elements determines the inheritance. If you nest them similar to how they get invoked in a stack trace inheritance makes the policy configuration easier. OK. (3) I didn't see any 'doPrivilege', 'Subject.doAsPrivilege' etc. in your code. I think we need to think about a notion of Tomcat Principal/Subject to only allow Tomcat doing those kind of operations (adding/removing permissions). This is usefull not only for your stuff, but for all security related call. The policy code is in package org.apache.catalina.policy, this package has both package.access and package.definition restrictions. Only code that has been granted the Runtime accessClassInPackage.org.apache.catalina.* can use the code. In the normal policy config that is only the catalina core. OK, but when Tomcat is embedded in another container (JBOSS, J2EE), the AccessControlContext will not be associated with a principal/subject. It's not a problem, but might be an improvement. (4) There is a class called sun.security.provider.PolicyFile where the unmarshalling' of policy statement are made. Your XML Policy file do not define any Policy.implies method. meaning if XMLPolicy.implies is invoked, the call will be delegated to PolicyFile.implies, who doesn't know anything about the permission. This method will return false for every policy.xml permission sinde they are created outside the defaut Policy scope. If a Servlet try accessing a file that is not granted in the policy.xml file, right now, the permission will be allowed since the AccesController will call the Policy.implies..IMBW... sun.security.provider.PolicyFile is just an implementation of a Policy. Which is a SUN specific implementation and not part of the java.security API. My XMLPolicy class extends the abstract Policy class which does not have an implies() method. XMLPolicy is put in place at runtime using SecurityManager.setPolicy(), at that point XMLPolicy is in control of determining what permissions have been granted to a CodeSource. For whatever reason,. I was under the impression you where extending that class.Maybe because I'm reading in english and thinking in french ;-) Whether a servlet has permission depends on the Permissions assigned to it by the Catalina WebappClassLoader when the class is instantiated. It then uses the Policy implemenation, in this case XMLPolicy. (5) I did not see any statement about replacing the policy.provider=sun.security.provider.PolicyFile (using the -Djavax.security.jacc.policy.provider= ) ? The property javax.security.jacc.policy.provider is specific to JSR 115. I though of using the policy.provider config in $JAVA_HOME/jre/lib/security/java.security. But that requires installing the all of the required jar files to implement XMLPolicy in $JAVA_HOME/jre/lib/ext. This could be a frequent tomcat support problem. So instead I designed it to replace