You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pa...@apache.org on 2010/05/31 00:06:19 UTC

svn commit: r949601 - in /felix/trunk/framework/src/main/java/org/apache/felix/framework: ExtensionManager.java FelixResolverState.java ModuleImpl.java

Author: pauls
Date: Sun May 30 22:06:19 2010
New Revision: 949601

URL: http://svn.apache.org/viewvc?rev=949601&view=rev
Log:
Do implicit bootdelegation in a doPriv and make extension manager openconnection use getresourcelocal to make security work again (FELIX-2273, FELIX-2271).

Modified:
    felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java?rev=949601&r1=949600&r2=949601&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java Sun May 30 22:06:19 2010
@@ -475,7 +475,7 @@ class ExtensionManager extends URLStream
         {
             try
             {
-                result = ((BundleImpl) extBundle).getCurrentModule().getResourceByDelegation(path);
+                result = ((ModuleImpl) ((BundleImpl) extBundle).getCurrentModule()).getResourceLocal(path);
             }
             catch (Exception ex)
             {
@@ -532,7 +532,7 @@ class ExtensionManager extends URLStream
                 _add(bundle.getSymbolicName(), bundle);
             }
             m_extensionsCache = (Bundle[])
-                m_extensions.toArray(new Bundle[m_extensions.size()]);            
+                m_extensions.toArray(new Bundle[m_extensions.size()]);
         }
     }
 

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java?rev=949601&r1=949600&r2=949601&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java Sun May 30 22:06:19 2010
@@ -39,6 +39,7 @@ import org.apache.felix.framework.resolv
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.R4Library;
 import org.osgi.framework.BundlePermission;
+import org.osgi.framework.PackagePermission;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 
@@ -420,7 +421,7 @@ public class FelixResolverState implemen
 
         // Create a list of all matching hosts for this fragment.
         SecurityManager sm = System.getSecurityManager();
-        if (sm != null)
+        if ((sm != null) && (fragment.getSymbolicName() != null))
         {
             if (!((BundleProtectionDomain) fragment.getSecurityContext()).impliesDirect(
                 new BundlePermission(fragment.getSymbolicName(), BundlePermission.FRAGMENT)))
@@ -446,7 +447,7 @@ public class FelixResolverState implemen
             {
                 it.remove();
             }
-            else if (sm != null)
+            else if ((sm != null) && (hostCap.getModule().getSymbolicName() != null))
             {
                 if (!((BundleProtectionDomain) hostCap.getModule()
                     .getSecurityContext()).impliesDirect(
@@ -554,7 +555,7 @@ public class FelixResolverState implemen
         // find ones that match.
         List<Module> fragmentList = new ArrayList<Module>();
         SecurityManager sm = System.getSecurityManager();
-        if (sm != null)
+        if ((sm != null) && (host.getSymbolicName() != null))
         {
             if (!((BundleProtectionDomain) host.getSecurityContext()).impliesDirect(
                 new BundlePermission(host.getSymbolicName(), BundlePermission.HOST)))
@@ -584,7 +585,7 @@ public class FelixResolverState implemen
                 continue;
             }
             
-            if (sm != null)
+            if ((sm != null) && (fragment.getSymbolicName() != null))
             {
                 if (!((BundleProtectionDomain) fragment.getSecurityContext()).impliesDirect(
                     new BundlePermission(fragment.getSymbolicName(), BundlePermission.FRAGMENT)))
@@ -719,7 +720,44 @@ public class FelixResolverState implemen
         CapabilitySet capSet = m_capSets.get(req.getNamespace());
         if (capSet != null)
         {
-            result.addAll(capSet.match(req.getFilter(), obeyMandatory));
+            Set<Capability> matches = capSet.match(req.getFilter(), obeyMandatory);
+            if (System.getSecurityManager() != null)
+            {
+                for (Capability cap : matches)
+                {
+                    if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE) && (
+                        !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
+                            new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(), 
+                            PackagePermission.EXPORTONLY)) ||
+                            !((module == null) ||
+                                ((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
+                                    new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(), 
+                                    cap.getModule().getBundle(),PackagePermission.IMPORT))
+                            )))
+                    {
+                        if (module != cap.getModule())
+                        {
+                            continue;
+                        }
+                    }
+                    if (req.getNamespace().equals(Capability.MODULE_NAMESPACE) && (
+                        !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
+                            new BundlePermission(cap.getModule().getSymbolicName(), BundlePermission.PROVIDE)) ||
+                            !((module == null) ||
+                                ((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
+                                    new BundlePermission(module.getSymbolicName(), BundlePermission.REQUIRE))
+                            )))
+                    {
+                        continue;
+                    }
+
+                    result.add(cap);
+                }
+            }
+            else 
+            {
+                result.addAll(matches);
+            }
         }
 
         return result;

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java?rev=949601&r1=949600&r2=949601&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java Sun May 30 22:06:19 2010
@@ -18,9 +18,6 @@
  */
 package org.apache.felix.framework;
 
-import org.apache.felix.framework.resolver.ResourceNotFoundException;
-import org.apache.felix.framework.resolver.Content;
-import org.apache.felix.framework.capabilityset.SimpleFilter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
@@ -29,11 +26,13 @@ import java.lang.reflect.Proxy;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLStreamHandler;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
 import java.security.SecureClassLoader;
 import java.util.ArrayList;
 import java.util.Collections;
-
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -41,15 +40,19 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
+
 import org.apache.felix.framework.Felix.FelixResolver;
 import org.apache.felix.framework.cache.JarContent;
 import org.apache.felix.framework.capabilityset.Attribute;
 import org.apache.felix.framework.capabilityset.Capability;
 import org.apache.felix.framework.capabilityset.Directive;
-import org.apache.felix.framework.resolver.Module;
 import org.apache.felix.framework.capabilityset.Requirement;
-import org.apache.felix.framework.resolver.Wire;
+import org.apache.felix.framework.capabilityset.SimpleFilter;
+import org.apache.felix.framework.resolver.Content;
+import org.apache.felix.framework.resolver.Module;
 import org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.framework.resolver.ResourceNotFoundException;
+import org.apache.felix.framework.resolver.Wire;
 import org.apache.felix.framework.resolver.WireImpl;
 import org.apache.felix.framework.resolver.WireModuleImpl;
 import org.apache.felix.framework.util.CompoundEnumeration;
@@ -777,7 +780,7 @@ public class ModuleImpl implements Modul
         return result;
     }
 
-    private URL getResourceLocal(String name)
+    URL getResourceLocal(String name)
     {
         URL url = null;
 
@@ -1352,7 +1355,7 @@ public class ModuleImpl implements Modul
     }
 
     private Object searchDynamicImports(
-        String name, String pkgName, boolean isClass)
+        final String name, String pkgName, final boolean isClass)
         throws ClassNotFoundException, ResourceNotFoundException
     {
         // At this point, the module's imports were searched and so was the
@@ -1404,66 +1407,105 @@ public class ModuleImpl implements Modul
             // for the bundle and throw an exception.
 
             // Get the class context to see the classes on the stack.
-            Class[] classes = m_sm.getClassContext();
-            // Start from 1 to skip security manager class.
-            for (int i = 1; i < classes.length; i++)
-            {
-                // Find the first class on the call stack that is not from
-                // the class loader that loaded the Felix classes or is not
-                // a class loader or class itself, because we want to ignore
-                // calls to ClassLoader.loadClass() and Class.forName() since
-                // we are trying to find out who instigated the class load.
-                // Also ignore inner classes of class loaders, since we can
-                // assume they are a class loader too.
-
-// TODO: FRAMEWORK - This check is a hack and we should see if we can think
-// of another way to do it, since it won't necessarily work in all situations.
-                // Since Felix uses threads for changing the start level
-                // and refreshing packages, it is possible that there is no
-                // module classes on the call stack; therefore, as soon as we
-                // see Thread on the call stack we exit this loop. Other cases
-                // where modules actually use threads are not an issue because
-                // the module classes will be on the call stack before the
-                // Thread class.
-                if (Thread.class.equals(classes[i]))
-                {
-                    break;
-                }
-                else if (isClassNotLoadedFromBundle(classes[i]))
-                {
-                    // If the instigating class was not from a bundle,
-                    // then delegate to the parent class loader; otherwise,
-                    // break out of loop and return null.
-                    boolean delegate = true;
-                    ClassLoader last = null;
-                    for (ClassLoader cl = classes[i].getClassLoader(); (cl != null) && (last != cl); cl = cl.getClass().getClassLoader())
-                    {
-                        last = cl;
-                        if (ModuleClassLoader.class.isInstance(cl))
+            final Class[] classes = m_sm.getClassContext();
+            try
+            {
+                if (System.getSecurityManager() != null)
+                {
+                    return AccessController
+                        .doPrivileged(new PrivilegedExceptionAction()
                         {
-                            delegate = false;
-                            break;
-                        }
+                            public Object run() throws Exception
+                            {
+                                return doImplicitBootDelegation(classes, name,
+                                    isClass);
+                            }
+                        });
+                }
+                else
+                {
+                    return doImplicitBootDelegation(classes, name, isClass);
+                }
+            }
+            catch (PrivilegedActionException ex)
+            {
+                Exception cause = ex.getException();
+                if (cause instanceof ClassNotFoundException)
+                {
+                    throw (ClassNotFoundException) cause;
+                }
+                else
+                {
+                    throw (ResourceNotFoundException) cause;
+                }
+            }
+        }
+        return null;
+    }
+
+    private Object doImplicitBootDelegation(Class[] classes, String name, boolean isClass)
+    throws ClassNotFoundException, ResourceNotFoundException
+    {
+        // Start from 1 to skip security manager class.
+        for (int i = 1; i < classes.length; i++)
+        {
+            // Find the first class on the call stack that is not from
+            // the class loader that loaded the Felix classes or is not
+            // a class loader or class itself, because we want to ignore
+            // calls to ClassLoader.loadClass() and Class.forName() since
+            // we are trying to find out who instigated the class load.
+            // Also ignore inner classes of class loaders, since we can
+            // assume they are a class loader too.
+
+            // TODO: FRAMEWORK - This check is a hack and we should see if we can think
+            // of another way to do it, since it won't necessarily work in all situations.
+            // Since Felix uses threads for changing the start level
+            // and refreshing packages, it is possible that there is no
+            // module classes on the call stack; therefore, as soon as we
+            // see Thread on the call stack we exit this loop. Other cases
+            // where modules actually use threads are not an issue because
+            // the module classes will be on the call stack before the
+            // Thread class.
+            if (Thread.class.equals(classes[i]))
+            {
+                break;
+            }
+            else if (isClassNotLoadedFromBundle(classes[i]))
+            {
+                // If the instigating class was not from a bundle,
+                // then delegate to the parent class loader; otherwise,
+                // break out of loop and return null.
+                boolean delegate = true;
+                ClassLoader last = null;
+                for (ClassLoader cl = classes[i].getClassLoader(); 
+                (cl != null) && (last != cl); 
+                cl = cl.getClass().getClassLoader())
+                {
+                    last = cl;
+                    if (ModuleClassLoader.class.isInstance(cl))
+                    {
+                        delegate = false;
+                        break;
+                    }
+                }
+                // Delegate to the parent class loader unless this call
+                // is due to outside code calling a method on the bundle
+                // interface (e.g., Bundle.loadClass()).
+                if (delegate && !Bundle.class.isAssignableFrom(classes[i - 1]))
+                {
+                    try
+                    {
+                        // Return the class or resource from the parent class loader.
+                        return (isClass)
+                        ? (Object) this.getClass().getClassLoader().loadClass(name)
+                            : (Object) this.getClass().getClassLoader().getResource(name);
                     }
-                    // Delegate to the parent class loader unless this call
-                    // is due to outside code calling a method on the bundle
-                    // interface (e.g., Bundle.loadClass()).
-                    if (delegate && !Bundle.class.isAssignableFrom(classes[i - 1]))
+                    catch (NoClassDefFoundError ex)
                     {
-                        try
-                        {
-                            // Return the class or resource from the parent class loader.
-                            return (isClass)
-                                ? (Object) this.getClass().getClassLoader().loadClass(name)
-                                : (Object) this.getClass().getClassLoader().getResource(name);
-                        }
-                        catch (NoClassDefFoundError ex)
-                        {
-                            // Ignore, will return null
-                        }
+                        // Ignore, will return null
                     }
-                    break;
                 }
+                break;
             }
         }