You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2008/04/22 00:37:19 UTC

svn commit: r650304 - in /geronimo/server/trunk/plugins: j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/ j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/security/ j2ee/geronimo...

Author: djencks
Date: Mon Apr 21 15:36:42 2008
New Revision: 650304

URL: http://svn.apache.org/viewvc?rev=650304&view=rev
Log:
GERONIMO-3964 Experiment with not using any excluded permissions by simply not granting them in the first place

Added:
    geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web3.xml
      - copied, changed from r649325, geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web2.xml
    geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web4.xml   (with props)
Modified:
    geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/HTTPMethods.java
    geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/SpecSecurityBuilder.java
    geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/URLPattern.java
    geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/security/SpecSecurityParsingTest.java
    geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/EjbDeploymentBuilder.java
    geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/SecurityBuilder.java

Modified: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/HTTPMethods.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/HTTPMethods.java?rev=650304&r1=650303&r2=650304&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/HTTPMethods.java (original)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/HTTPMethods.java Mon Apr 21 15:36:42 2008
@@ -78,11 +78,36 @@
         return this;
     }
 
+    public HTTPMethods remove(HTTPMethods httpMethods) {
+        if (isExcluded) {
+            if (httpMethods.isExcluded) {
+                //TODO questionable
+                isExcluded = false;
+                Set<String> toRemove = new HashSet<String>(methods);
+                methods.clear();
+                methods.addAll(httpMethods.methods);
+                methods.removeAll(toRemove);
+            } else {
+                methods.addAll(httpMethods.methods);
+            }
+        } else {
+            if (httpMethods.isExcluded) {
+                methods.retainAll(httpMethods.methods);
+            } else {
+                methods.removeAll(httpMethods.methods);
+            }
+        }
+        if (!isExcluded && methods.isEmpty()) {
+            return null;
+        }
+        return this;
+    }
+
     public String getHttpMethods() {
         return getHttpMethodsBuffer(isExcluded).toString();
     }
 
-    public StringBuffer getHttpMethodsBuffer() {
+    public StringBuilder getHttpMethodsBuffer() {
         return getHttpMethodsBuffer(isExcluded);
     }
 
@@ -90,8 +115,8 @@
         return getHttpMethodsBuffer(!isExcluded).toString();
     }
 
-    private StringBuffer getHttpMethodsBuffer( boolean excluded) {
-        StringBuffer buffer = new StringBuffer();
+    private StringBuilder getHttpMethodsBuffer( boolean excluded) {
+        StringBuilder buffer = new StringBuilder();
         if (excluded) {
             buffer.append("!");
         }

Modified: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/SpecSecurityBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/SpecSecurityBuilder.java?rev=650304&r1=650303&r2=650304&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/SpecSecurityBuilder.java (original)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/SpecSecurityBuilder.java Mon Apr 21 15:36:42 2008
@@ -43,7 +43,7 @@
 import org.apache.geronimo.xbeans.javaee.SecurityRoleRefType;
 
 /**
- * @version $Rev:$ $Date:$
+ * @version $Rev$ $Date$
  */
 public class SpecSecurityBuilder {
     private final Set<String> securityRoles = new HashSet<String>();
@@ -55,6 +55,8 @@
     private final Map<String, URLPattern> rolesPatterns = new HashMap<String, URLPattern>();
     private final Set<URLPattern> allSet = new HashSet<URLPattern>();   // == allMap.values()
     private final Map<String, URLPattern> allMap = new HashMap<String, URLPattern>();   //uncheckedPatterns union excludedPatterns union rolesPatterns.
+//    private boolean useExcluded = false;
+    private boolean useExcluded = true;
 
     public ComponentPermissions buildSpecSecurityConfig(WebAppType webApp) {
         collectRoleNames(webApp.getSecurityRoleArray());
@@ -66,6 +68,9 @@
         addUnmappedJSPPermissions();
 
         analyzeSecurityConstraints(webApp.getSecurityConstraintArray());
+//        if (!useExcluded) {
+            removeExcludedDups();
+//        }
 
         return buildComponentPermissions();
     }
@@ -137,16 +142,36 @@
         }
     }
 
+    public void removeExcludedDups() {
+        for (Map.Entry<String, URLPattern> excluded: excludedPatterns.entrySet()) {
+            String url = excluded.getKey();
+            URLPattern pattern = excluded.getValue();
+            removeExcluded(url, pattern, uncheckedPatterns);
+            removeExcluded(url, pattern, rolesPatterns);
+        }
+    }
+
+    private void removeExcluded(String url, URLPattern pattern, Map<String, URLPattern> patterns) {
+        URLPattern testPattern = patterns.get(url);
+        if (testPattern != null) {
+            if (!testPattern.removeMethods(pattern)) {
+                patterns.remove(url);
+            }
+        }
+    }
+
     public ComponentPermissions buildComponentPermissions() {
         PermissionCollection excludedPermissions = new Permissions();
         PermissionCollection uncheckedPermissions = new Permissions();
 
-        for (URLPattern pattern : excludedPatterns.values()) {
-            String name = pattern.getQualifiedPattern(allSet);
-            String actions = pattern.getMethods();
+        if (useExcluded) {
+            for (URLPattern pattern : excludedPatterns.values()) {
+                String name = pattern.getQualifiedPattern(allSet);
+                String actions = pattern.getMethods();
 
-            excludedPermissions.add(new WebResourcePermission(name, actions));
-            excludedPermissions.add(new WebUserDataPermission(name, actions));
+                excludedPermissions.add(new WebResourcePermission(name, actions));
+                excludedPermissions.add(new WebUserDataPermission(name, actions));
+            }
         }
 
         for (URLPattern pattern : rolesPatterns.values()) {

Modified: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/URLPattern.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/URLPattern.java?rev=650304&r1=650303&r2=650304&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/URLPattern.java (original)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/security/URLPattern.java Mon Apr 21 15:36:42 2008
@@ -103,6 +103,10 @@
         httpMethods.add(method);
     }
 
+    public boolean removeMethods(URLPattern other) {
+        return httpMethods.remove(other.getHTTPMethods()) != null;
+    }
+
     /**
      * Return the set of HTTP methods that have been associated with this URL pattern.
      *
@@ -130,7 +134,7 @@
     }
 
     public static String getMethodsWithTransport(HTTPMethods methods, int transport) {
-        StringBuffer buffer = methods.getHttpMethodsBuffer();
+        StringBuilder buffer = methods.getHttpMethodsBuffer();
 
 
         if (transport != NA) {

Modified: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/security/SpecSecurityParsingTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/security/SpecSecurityParsingTest.java?rev=650304&r1=650303&r2=650304&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/security/SpecSecurityParsingTest.java (original)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/security/SpecSecurityParsingTest.java Mon Apr 21 15:36:42 2008
@@ -29,6 +29,7 @@
 import java.util.Collections;
 import java.util.jar.JarFile;
 import java.security.PermissionCollection;
+import java.security.Permission;
 
 import javax.security.jacc.WebResourcePermission;
 
@@ -79,10 +80,78 @@
         WebAppType webAppType = webAppDoc.getWebApp();
         SpecSecurityBuilder builder = new SpecSecurityBuilder();
         ComponentPermissions permissions = builder.buildSpecSecurityConfig(webAppType);
+        Permission p = new WebResourcePermission("/Test/Foo", "GET,POST");
+        assertTrue(implies(p, permissions, "Admin"));
+        assertFalse(implies(new WebResourcePermission("/Test", ""), permissions, null));
+        assertFalse(implies(new WebResourcePermission("/Test", "!"), permissions, null));
+    }
+    
+    public void testExcludedConstraint() throws Exception {
+        URL srcXml = classLoader.getResource("security/web3.xml");
+        WebAppDocument webAppDoc = WebAppDocument.Factory.parse(srcXml, options);
+        WebAppType webAppType = webAppDoc.getWebApp();
+        SpecSecurityBuilder builder = new SpecSecurityBuilder();
+        ComponentPermissions permissions = builder.buildSpecSecurityConfig(webAppType);
+        Permission p = new WebResourcePermission("/Test/Foo", "GET,POST");
+        assertTrue(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, null));
+        p = new WebResourcePermission("/Test/Bar/Foo", "GET,POST");
+        assertFalse(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, null));
+        // check only GET method excluded here.
+        p = new WebResourcePermission("/Test/Baz/Foo", "GET");
+        assertFalse(implies(p, permissions, "Admin"));
+        p = new WebResourcePermission("/Test/Baz/Foo", "POST");
+        assertTrue(implies(p, permissions, "Admin"));
+        // test excluding longer path than allowed
+        p = new WebResourcePermission("/Foo/Baz", "GET");
+        assertTrue(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, "Peon"));
+        p = new WebResourcePermission("/Foo/Bar/Foo", "POST");
+        assertTrue(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, "Peon"));
+        p = new WebResourcePermission("/Foo/Bar/Foo", "GET");
+        assertFalse(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, "Peon"));
+    }
+    public void testExcludedRemovesRoleConstraint() throws Exception {
+        URL srcXml = classLoader.getResource("security/web4.xml");
+        WebAppDocument webAppDoc = WebAppDocument.Factory.parse(srcXml, options);
+        WebAppType webAppType = webAppDoc.getWebApp();
+        SpecSecurityBuilder builder = new SpecSecurityBuilder();
+        ComponentPermissions permissions = builder.buildSpecSecurityConfig(webAppType);
+        // test excluding longer path than allowed
+        Permission p = new WebResourcePermission("/Foo/Baz", "GET");
+        assertTrue(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, "Peon"));
+        p = new WebResourcePermission("/Foo/Bar/Foo", "POST");
+        assertTrue(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, "Peon"));
+        p = new WebResourcePermission("/Foo/Bar/Foo", "GET");
+        assertFalse(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, "Peon"));
+        // test excluding longer path allows unchecked access to other http methods
+        p = new WebResourcePermission("/Bar/Baz", "GET");
+        assertTrue(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, "Peon"));
+        p = new WebResourcePermission("/Bar/Bar/Bar", "POST");
+        assertTrue(implies(p, permissions, "Admin"));
+        //This one is false unless excluded constraint allows other https methods unchecked access
+//        assertFalse(implies(p, permissions, "Peon"));
+        assertTrue(implies(p, permissions, "Peon"));
+        p = new WebResourcePermission("/Bar/Bar/Bar", "GET");
+        assertFalse(implies(p, permissions, "Admin"));
+        assertFalse(implies(p, permissions, "Peon"));
+    }
+
+    private boolean implies(Permission p, ComponentPermissions permissions, String role) {
+        PermissionCollection excluded = permissions.getExcludedPermissions();
+        if (excluded.implies(p)) return false;
         PermissionCollection unchecked = permissions.getUncheckedPermissions();
-        assertFalse(unchecked.implies(new WebResourcePermission("/Test", "!")));
-        PermissionCollection adminPermissions = permissions.getRolePermissions().get("Admin");
-        assertTrue(adminPermissions.implies(new WebResourcePermission("/Test", "GET,POST")));
+        if (unchecked.implies(p)) return true;
+        if (role == null) return false;
+        PermissionCollection rolePermissions = permissions.getRolePermissions().get(role);
+        return rolePermissions != null && rolePermissions.implies(p);
     }
 
 }

Copied: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web3.xml (from r649325, geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web2.xml)
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web3.xml?p2=geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web3.xml&p1=geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web2.xml&r1=649325&r2=650304&rev=650304&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web2.xml (original)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web3.xml Mon Apr 21 15:36:42 2008
@@ -19,15 +19,37 @@
          version="2.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee">
     <security-constraint>
         <web-resource-collection>
-            <web-resource-name>uncheckedtest1</web-resource-name>
-            <url-pattern>/Test</url-pattern>
+            <web-resource-name>wr1</web-resource-name>
+            <url-pattern>/Test/Foo</url-pattern>
+            <url-pattern>/Test/Bar/*</url-pattern>
+            <url-pattern>/Test/Baz/*</url-pattern>
+            <url-pattern>/Foo/*</url-pattern>
+            <url-pattern>/Foo/Bar/*</url-pattern>
         </web-resource-collection>
         <auth-constraint>
             <role-name>Admin</role-name>
         </auth-constraint>
     </security-constraint>
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>wr2</web-resource-name>
+            <url-pattern>/Test/*</url-pattern>
+            <url-pattern>/Test/Bar/*</url-pattern>
+        </web-resource-collection>
+        <web-resource-collection>
+            <web-resource-name>wr3</web-resource-name>
+            <url-pattern>/Test/*</url-pattern>
+            <url-pattern>/Test/Baz/*</url-pattern>
+            <url-pattern>/Foo/Bar/*</url-pattern>
+            <http-method>GET</http-method>
+        </web-resource-collection>
+        <auth-constraint/>
+    </security-constraint>
     <security-role>
         <role-name>Admin</role-name>
+    </security-role>
+    <security-role>
+        <role-name>Peon</role-name>
     </security-role>
  
 </web-app>

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web4.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web4.xml?rev=650304&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web4.xml (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web4.xml Mon Apr 21 15:36:42 2008
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<web-app xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         version="2.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee">
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>wr1</web-resource-name>
+            <url-pattern>/Foo/*</url-pattern>
+            <url-pattern>/Foo/Bar/*</url-pattern>
+            <url-pattern>/Bar/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>Admin</role-name>
+        </auth-constraint>
+    </security-constraint>
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>wr3</web-resource-name>
+            <url-pattern>/Foo/Bar/*</url-pattern>
+            <url-pattern>/Bar/Bar/*</url-pattern>
+            <http-method>GET</http-method>
+        </web-resource-collection>
+        <auth-constraint/>
+    </security-constraint>
+    <security-role>
+        <role-name>Admin</role-name>
+    </security-role>
+    <security-role>
+        <role-name>Peon</role-name>
+    </security-role>
+ 
+</web-app>

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web4.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web4.xml
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/resources/security/web4.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Modified: geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/EjbDeploymentBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/EjbDeploymentBuilder.java?rev=650304&r1=650303&r2=650304&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/EjbDeploymentBuilder.java (original)
+++ geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/EjbDeploymentBuilder.java Mon Apr 21 15:36:42 2008
@@ -17,11 +17,15 @@
  */
 package org.apache.geronimo.openejb.deployment;
 
+import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.Permissions;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
@@ -185,30 +189,30 @@
                 RemoteBean remoteBean = (RemoteBean) enterpriseBean;
 
                 SecurityBuilder securityBuilder = new SecurityBuilder();
-                PermissionCollection permissions = new Permissions();
+                Collection<Permission> allPermissions = new HashSet<Permission>();
 
-                securityBuilder.addToPermissions(permissions,
+                securityBuilder.addToPermissions(allPermissions,
                         remoteBean.getEjbName(),
                         EjbInterface.HOME.getJaccInterfaceName(),
                         remoteBean.getHome(),
                         ejbModule.getClassLoader());
-                securityBuilder.addToPermissions(permissions,
+                securityBuilder.addToPermissions(allPermissions,
                         remoteBean.getEjbName(),
                         EjbInterface.REMOTE.getJaccInterfaceName(),
                         remoteBean.getRemote(),
                         ejbModule.getClassLoader());
-                securityBuilder.addToPermissions(permissions,
+                securityBuilder.addToPermissions(allPermissions,
                         remoteBean.getEjbName(),
                         EjbInterface.LOCAL.getJaccInterfaceName(),
                         remoteBean.getLocal(),
                         ejbModule.getClassLoader());
-                securityBuilder.addToPermissions(permissions,
+                securityBuilder.addToPermissions(allPermissions,
                         remoteBean.getEjbName(),
                         EjbInterface.LOCAL_HOME.getJaccInterfaceName(),
                         remoteBean.getLocalHome(),
                         ejbModule.getClassLoader());
                 if (remoteBean instanceof SessionBean) {
-                    securityBuilder.addToPermissions(permissions,
+                    securityBuilder.addToPermissions(allPermissions,
                             remoteBean.getEjbName(),
                             EjbInterface.SERVICE_ENDPOINT.getJaccInterfaceName(),
                             ((SessionBean) remoteBean).getServiceEndpoint(),
@@ -216,13 +220,13 @@
                 }
                 if (remoteBean.getBusinessRemote() != null && !remoteBean.getBusinessRemote().isEmpty()) {
                     for (String businessRemote : remoteBean.getBusinessRemote()) {
-                        securityBuilder.addToPermissions(permissions,
+                        securityBuilder.addToPermissions(allPermissions,
                                 remoteBean.getEjbName(),
                                 EjbInterface.REMOTE.getJaccInterfaceName(),
                                 businessRemote,
                                 ejbModule.getClassLoader());
                     }
-                    securityBuilder.addToPermissions(componentPermissions.getUncheckedPermissions(),
+                    securityBuilder.addToPermissions(new PermissionCollectionAdapter(componentPermissions.getUncheckedPermissions()),
                             remoteBean.getEjbName(),
                             EjbInterface.HOME.getJaccInterfaceName(),
                             DeploymentInfo.BusinessRemoteHome.class.getName(),
@@ -230,13 +234,13 @@
                 }
                 if (remoteBean.getBusinessLocal() != null && !remoteBean.getBusinessLocal().isEmpty()) {
                     for (String businessLocal : remoteBean.getBusinessLocal()) {
-                        securityBuilder.addToPermissions(permissions,
+                        securityBuilder.addToPermissions(allPermissions,
                                 remoteBean.getEjbName(),
                                 EjbInterface.LOCAL.getJaccInterfaceName(),
                                 businessLocal,
                                 ejbModule.getClassLoader());
                     }
-                    securityBuilder.addToPermissions(componentPermissions.getUncheckedPermissions(),
+                    securityBuilder.addToPermissions(new PermissionCollectionAdapter(componentPermissions.getUncheckedPermissions()),
                             remoteBean.getEjbName(),
                             EjbInterface.LOCAL_HOME.getJaccInterfaceName(),
                             DeploymentInfo.BusinessLocalHome.class.getName(),
@@ -245,7 +249,7 @@
 
                 String defaultRole = securityConfiguration.getDefaultRole();
                 securityBuilder.addComponentPermissions(defaultRole,
-                        permissions,
+                        allPermissions,
                         ejbModule.getEjbJar().getAssemblyDescriptor(),
                         enterpriseBean.getEjbName(),
                         remoteBean.getSecurityRoleRef(),
@@ -263,6 +267,68 @@
 
             gbean.setAttribute("securityEnabled", true);
             gbean.setReferencePattern("RunAsSource", earContext.getJaccManagerName());
+        }
+    }
+
+    private static class PermissionCollectionAdapter implements Collection<Permission> {
+        private final PermissionCollection p;
+
+        private PermissionCollectionAdapter(PermissionCollection p) {
+            this.p = p;
+        }
+
+        public int size() {
+            throw new RuntimeException("not implemented");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("not implemented");
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException("not implemented");
+        }
+
+        public Iterator<Permission> iterator() {
+            throw new RuntimeException("not implemented");
+        }
+
+        public Object[] toArray() {
+            throw new RuntimeException("not implemented");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("not implemented");
+        }
+
+        public boolean add(Permission o) {
+            if (p.implies(o)) return false;
+            p.add(o);
+            return true;
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException("not implemented");
+        }
+
+        public boolean containsAll(Collection<?> c) {
+            throw new RuntimeException("not implemented");
+        }
+
+        public boolean addAll(Collection<? extends Permission> c) {
+            throw new RuntimeException("not implemented");
+        }
+
+        public boolean removeAll(Collection<?> c) {
+            throw new RuntimeException("not implemented");
+        }
+
+        public boolean retainAll(Collection<?> c) {
+            throw new RuntimeException("not implemented");
+        }
+
+        public void clear() {
+            throw new RuntimeException("not implemented");
         }
     }
 

Modified: geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/SecurityBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/SecurityBuilder.java?rev=650304&r1=650303&r2=650304&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/SecurityBuilder.java (original)
+++ geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/SecurityBuilder.java Mon Apr 21 15:36:42 2008
@@ -20,9 +20,14 @@
 import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.Permissions;
-import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
 
 import javax.security.jacc.EJBMethodPermission;
 import javax.security.jacc.EJBRoleRefPermission;
@@ -53,7 +58,7 @@
      * @throws DeploymentException if any constraints are violated
      */
     public void addComponentPermissions(String defaultRole,
-            PermissionCollection notAssigned,
+            Collection<Permission> notAssigned,
             AssemblyDescriptor assemblyDescriptor,
             String ejbName,
             List<SecurityRoleRef> securityRoleRefs,
@@ -62,28 +67,23 @@
         PermissionCollection uncheckedPermissions = componentPermissions.getUncheckedPermissions();
         PermissionCollection excludedPermissions = componentPermissions.getExcludedPermissions();
         Map<String, PermissionCollection> rolePermissions = componentPermissions.getRolePermissions();
+        Set<Permission> allExcludedPermissions = new HashSet<Permission>();
 
         //this can occur in an ear when one ejb module has security and one doesn't.  In this case we still need
         //to make the non-secure one completely unchecked.
         if (assemblyDescriptor != null) {
             /**
-             * JACC v1.0 section 3.1.5.1
+             * JACC v1.0 section 3.1.5.2
              */
-            for (MethodPermission methodPermission : assemblyDescriptor.getMethodPermission()) {
-                List<String> roleNames = methodPermission.getRoleName();
-                boolean unchecked = methodPermission.getUnchecked();
-
-                for (Method method : methodPermission.getMethod()) {
+            ExcludeList excludeList = assemblyDescriptor.getExcludeList();
+            if (excludeList != null) {
+                for (Method method : excludeList.getMethod()) {
                     if (!ejbName.equals(method.getEjbName())) {
                         continue;
                     }
 
                     // method name
                     String methodName = method.getMethodName();
-                    if ("*".equals(methodName)) {
-                        // jacc uses null instead of *
-                        methodName = null;
-                    }
                     // method interface
                     String methodIntf = method.getMethodIntf() == null? null: method.getMethodIntf().toString();
 
@@ -98,37 +98,29 @@
 
                     // create the permission object
                     EJBMethodPermission permission = new EJBMethodPermission(ejbName, methodName, methodIntf, methodParams);
-                    notAssigned = cullPermissions(notAssigned, permission);
 
-                    // if this is unchecked, mark it as unchecked; otherwise assign the roles
-                    if (unchecked) {
-                        uncheckedPermissions.add(permission);
-                    } else {
-                        for (String roleName : roleNames) {
-                            Permissions permissions = (Permissions) rolePermissions.get(roleName);
-                            if (permissions == null) {
-                                permissions = new Permissions();
-                                rolePermissions.put(roleName, permissions);
-                            }
-                            permissions.add(permission);
-                        }
-                    }
+                    excludedPermissions.add(permission);
+                    allExcludedPermissions.addAll(intersectPermissions(notAssigned, permission, false));
                 }
-
             }
-
             /**
-             * JACC v1.0 section 3.1.5.2
+             * JACC v1.0 section 3.1.5.1
              */
-            ExcludeList excludeList = assemblyDescriptor.getExcludeList();
-            if (excludeList != null) {
-                for (Method method : excludeList.getMethod()) {
+            for (MethodPermission methodPermission : assemblyDescriptor.getMethodPermission()) {
+                List<String> roleNames = methodPermission.getRoleName();
+                boolean unchecked = methodPermission.getUnchecked();
+
+                for (Method method : methodPermission.getMethod()) {
                     if (!ejbName.equals(method.getEjbName())) {
                         continue;
                     }
 
                     // method name
                     String methodName = method.getMethodName();
+                    if ("*".equals(methodName)) {
+                        // jacc uses null instead of *
+                        methodName = null;
+                    }
                     // method interface
                     String methodIntf = method.getMethodIntf() == null? null: method.getMethodIntf().toString();
 
@@ -143,12 +135,38 @@
 
                     // create the permission object
                     EJBMethodPermission permission = new EJBMethodPermission(ejbName, methodName, methodIntf, methodParams);
+                    Collection<Permission> culled = intersectPermissions(notAssigned, permission, true);
+                    //does this intersect the excluded permissions?
+                    int size = culled.size();
+                    culled.removeAll(allExcludedPermissions);
+                    if (size == culled.size()) {
+                        //no intersection, just use actually specified permission
+                        culled = Collections.<Permission>singletonList(permission);
+                    }
+                    //otherwise, use the individual permissions that are not excluded
 
-                    excludedPermissions.add(permission);
-                    notAssigned = cullPermissions(notAssigned, permission);
+                    // if this is unchecked, mark it as unchecked; otherwise assign the roles
+                    if (unchecked) {
+                        for (Permission p: culled) {
+                            uncheckedPermissions.add(p);
+                        }
+                    } else if (culled.size() > 0) {
+                        for (String roleName : roleNames) {
+                            Permissions permissions = (Permissions) rolePermissions.get(roleName);
+                            if (permissions == null) {
+                                permissions = new Permissions();
+                                rolePermissions.put(roleName, permissions);
+                            }
+                            for (Permission p: culled) {
+                                permissions.add(p);
+                            }
+                        }
+                    }
                 }
+
             }
 
+
             /**
              * JACC v1.0 section 3.1.5.3
              */
@@ -186,9 +204,8 @@
             }
         }
 
-        Enumeration e = notAssigned.elements();
-        while (e.hasMoreElements()) {
-            Permission p = (Permission) e.nextElement();
+        notAssigned.removeAll(allExcludedPermissions);
+        for (Permission p: notAssigned) {
             permissions.add(p);
         }
 
@@ -211,7 +228,7 @@
      * @param classLoader the class loader to be used in obtaining the interface class
      * @throws org.apache.geronimo.common.DeploymentException in case a class could not be found
      */
-    public void addToPermissions(PermissionCollection permissions,
+    public void addToPermissions(Collection<Permission> permissions,
             String ejbName,
             String methodInterface,
             String interfaceClass,
@@ -238,14 +255,17 @@
      *
      * @param toBeChecked the permissions that are to be checked and possibly culled
      * @param permission the permission that is to be used for culling
-     * @return the culled set of permissions that are not implied by <code>permission</code>
+     * @param remove  whether to remove the matched permission
+     * @return the set of permissions that are implied by <code>permission</code>
      */
-    private Permissions cullPermissions(PermissionCollection toBeChecked, Permission permission) {
-        Permissions result = new Permissions();
-
-        for (Enumeration e = toBeChecked.elements(); e.hasMoreElements();) {
-            Permission test = (Permission) e.nextElement();
-            if (!permission.implies(test)) {
+    private Collection<Permission> intersectPermissions(Collection<Permission> toBeChecked, Permission permission, boolean remove) {
+        Collection<Permission> result = new ArrayList<Permission>();
+        for (Iterator<Permission> it = toBeChecked.iterator(); it.hasNext();) {
+            Permission test = it.next();
+            if (permission.implies(test)) {
+                if (remove) {
+                    it.remove();
+                }
                 result.add(test);
             }
         }