Add protection domains to modules and classes plus check PackagePermission.EXPORT (FELIX-21).
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@434385 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
index 650ca4e..3db92cf 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
@@ -17,12 +17,10 @@
package org.apache.felix.framework.searchpolicy;
import java.net.URL;
-import java.security.CodeSource;
+import java.security.ProtectionDomain;
import java.security.SecureClassLoader;
-import java.security.cert.Certificate;
import java.util.Enumeration;
-import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.Util;
import org.apache.felix.moduleloader.IContentLoader;
import org.apache.felix.moduleloader.ResourceNotFoundException;
@@ -30,10 +28,13 @@
public class ContentClassLoader extends SecureClassLoader
{
private ContentLoaderImpl m_contentLoader = null;
+ private ProtectionDomain m_protectionDomain = null;
- public ContentClassLoader(ContentLoaderImpl contentLoader)
+ public ContentClassLoader(ContentLoaderImpl contentLoader,
+ ProtectionDomain protectionDomain)
{
m_contentLoader = contentLoader;
+ m_protectionDomain = protectionDomain;
}
public IContentLoader getContentLoader()
@@ -131,24 +132,13 @@
}
}
- // Get the code source URL for this class. For concurrency
- // purposes, we are performing this call outside of the
- // synchronized block below since we call out to application
- // code, which might in turn need to call back into the
- // module loader code. Because of this, it is better to
- // not be holding any locks before making the call.
- URL url = null;
-// TODO: ML - FIX CODE SOURCE URL
-// URL url = m_mgr.getURLPolicy().createCodeSourceURL(
-// m_mgr, m_module);
-
- // If we have a valid code source URL, then use it to
- // define the class for security purposes, otherwise
- // define the class without a code source.
- if (url != null)
+ // If we have a security context, then use it to
+ // define the class with it for security purposes,
+ // otherwise define the class without a protection domain.
+ if (m_protectionDomain != null)
{
- CodeSource cs = new CodeSource(url, (Certificate[]) null);
- clazz = defineClass(name, bytes, 0, bytes.length, cs);
+ clazz = defineClass(name, bytes, 0, bytes.length,
+ m_protectionDomain);
}
else
{
@@ -157,12 +147,7 @@
}
}
- if (clazz != null)
- {
- return clazz;
- }
-
- return null;
+ return clazz;
}
public URL getResourceFromModule(String name)
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
index ccebe16..1c96ea0 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
@@ -19,6 +19,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.security.ProtectionDomain;
import java.util.Enumeration;
import java.util.Vector;
@@ -34,13 +35,22 @@
private ISearchPolicy m_searchPolicy = null;
private IURLPolicy m_urlPolicy = null;
private ContentClassLoader m_classLoader = null;
+ private ProtectionDomain m_protectionDomain = null;
private static SecureAction m_secureAction = new SecureAction();
- public ContentLoaderImpl(Logger logger, IContent content, IContent[] contentPath)
+ public ContentLoaderImpl(Logger logger, IContent content,
+ IContent[] contentPath)
+ {
+ this(logger, content, contentPath, null);
+ }
+
+ public ContentLoaderImpl(Logger logger, IContent content,
+ IContent[] contentPath, ProtectionDomain protectionDomain)
{
m_logger = logger;
m_content = content;
m_contentPath = contentPath;
+ m_protectionDomain = protectionDomain;
}
public Logger getLogger()
@@ -100,7 +110,8 @@
{
if (m_classLoader == null)
{
- m_classLoader = m_secureAction.createContentClassLoader(this);
+ m_classLoader = m_secureAction.createContentClassLoader(this,
+ m_protectionDomain);
}
try
@@ -182,7 +193,7 @@
{
name = name.substring(1);
}
-
+
// Check the module content.
if (getContent().hasEntry(name))
{
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
index 53c9681..fcee6be 100755
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
@@ -17,12 +17,14 @@
package org.apache.felix.framework.searchpolicy;
import java.net.URL;
+import java.security.ProtectionDomain;
import java.util.*;
import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.*;
import org.apache.felix.moduleloader.*;
import org.osgi.framework.Constants;
+import org.osgi.framework.PackagePermission;
import org.osgi.framework.Version;
public class R4SearchPolicyCore implements ModuleListener
@@ -160,7 +162,7 @@
{
throw ex;
}
-
+
// We should never reach this point.
return null;
}
@@ -196,7 +198,7 @@
{
return url;
}
-
+
// We need to throw a resource not found exception.
throw new ResourceNotFoundException(
name + ": cannot resolve package "
@@ -254,7 +256,7 @@
result = searchDynamicImports(module, name, pkgName, isClass);
}
}
-
+
if (result == null)
{
if (isClass)
@@ -266,7 +268,7 @@
throw new ResourceNotFoundException(name);
}
}
-
+
return result;
}
@@ -524,8 +526,33 @@
// modules are added, removed, or resolved.
synchronized (m_factory)
{
- return getCompatibleExporters(
+ IModule[] exporters = getCompatibleExporters(
(IModule[]) m_availPkgMap.get(pkg.getName()), pkg, includeRemovalPending);
+
+ if ((exporters != null) && (System.getSecurityManager() != null))
+ {
+ PackagePermission perm = new PackagePermission(pkg.getName(),
+ PackagePermission.EXPORT);
+
+ for (int i = 0;i < exporters.length;i++)
+ {
+ if (exporters[i] != null)
+ {
+ if (!((ProtectionDomain) exporters[i].getSecurityContext()).implies(perm))
+ {
+ m_logger.log(Logger.LOG_DEBUG,
+ "PackagePermission.EXPORT denied for " + pkg +
+ "from " + exporters[i].getId());
+
+ exporters[i] = null;
+ }
+ }
+ }
+
+ exporters = shrinkModuleArray(exporters);
+ }
+
+ return exporters;
}
}
@@ -1538,7 +1565,7 @@
// First, get the bundle ID of the module doing the class loader.
long impId = Util.getBundleIdFromModuleId(module.getId());
-
+
// Next, check to see if the module imports the package.
IWire[] wires = module.getWires();
for (int i = 0; (wires != null) && (i < wires.length); i++)
@@ -1675,9 +1702,9 @@
{
// Ignore
}
-
+
long expId = Util.getBundleIdFromModuleId(exporters[0].getId());
-
+
StringBuffer sb = new StringBuffer("*** Class '");
sb.append(name);
sb.append("' was not found because bundle ");