FELIX-1827 Check permission to get and register services on behalf
of the component providing bundle
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@831005 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
index f10db78..e305094 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
@@ -18,6 +18,7 @@
*/
package org.apache.felix.scr.impl.manager;
+import java.security.Permission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Dictionary;
@@ -34,6 +35,7 @@
import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
import org.osgi.framework.Bundle;
import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServicePermission;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentConstants;
@@ -519,10 +521,40 @@
} );
}
- public String toString() {
+
+ public String toString()
+ {
return "Component: " + getName() + " (" + getId() + ")";
}
+
+ private boolean hasServiceRegistrationPermissions()
+ {
+ boolean allowed = true;
+ if ( System.getSecurityManager() != null )
+ {
+ final String[] services = getComponentMetadata().getServiceMetadata().getProvides();
+ if ( services != null && services.length > 0 )
+ {
+ final Bundle bundle = getBundle();
+ for ( int i = 0; i < services.length; i++ )
+ {
+ final Permission perm = new ServicePermission( services[i], ServicePermission.REGISTER );
+ if ( !bundle.hasPermission( perm ) )
+ {
+ log( LogService.LOG_INFO, "Permission to register service {0} is denied", new Object[]
+ { services[i] }, null );
+ allowed = false;
+ }
+ }
+ }
+ }
+
+ // no security manager or no services to register
+ return allowed;
+ }
+
+
private void loadDependencyManagers( ComponentMetadata metadata )
{
List depMgrList = new ArrayList();
@@ -563,15 +595,21 @@
Iterator it = getDependencyManagers();
while ( it.hasNext() )
{
- DependencyManager dm = (DependencyManager) it.next();
+ DependencyManager dm = ( DependencyManager ) it.next();
// ensure the target filter is correctly set
dm.setTargetFilter( properties );
- // check whether the service is satisfied
- if ( !dm.isSatisfied() )
+ if ( !dm.hasGetPermission() )
{
- // at least one dependency is not satisfied
+ // bundle has no service get permission
+ log( LogService.LOG_INFO, "No permission to get dependency: {0}", new Object[]
+ { dm.getName() }, null );
+ satisfied = false;
+ }
+ else if ( !dm.isSatisfied() )
+ {
+ // bundle would have permission but there are not enough services
log( LogService.LOG_INFO, "Dependency not satisfied: {0}", new Object[]
{ dm.getName() }, null );
satisfied = false;
@@ -926,6 +964,16 @@
return;
}
+ // Before creating the implementation object, we are going to
+ // test that the bundle has enough permissions to register services
+ if ( !acm.hasServiceRegistrationPermissions() )
+ {
+ acm.log( LogService.LOG_INFO, "Component is not permitted to register all services, cannot activate",
+ null );
+ acm.changeState( Unsatisfied.getInstance() );
+ return;
+ }
+
// 1. Load the component implementation class
// 2. Create the component instance and component context
// 3. Bind the target services
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index afb943a..1533833 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -19,6 +19,7 @@
package org.apache.felix.scr.impl.manager;
+import java.security.Permission;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
@@ -36,6 +37,7 @@
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServicePermission;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentConstants;
import org.osgi.service.log.LogService;
@@ -460,19 +462,32 @@
*/
void enable() throws InvalidSyntaxException
{
- // get the current number of registered services available
- ServiceReference refs[] = getFrameworkServiceReferences();
- m_size = ( refs == null ) ? 0 : refs.length;
+ if ( hasGetPermission() )
+ {
+ // get the current number of registered services available
+ ServiceReference refs[] = getFrameworkServiceReferences();
+ m_size = ( refs == null ) ? 0 : refs.length;
- // register the service listener
- String filterString = "(" + Constants.OBJECTCLASS + "=" + m_dependencyMetadata.getInterface() + ")";
- m_componentManager.getActivator().getBundleContext().addServiceListener( this, filterString );
+ // register the service listener
+ String filterString = "(" + Constants.OBJECTCLASS + "=" + m_dependencyMetadata.getInterface() + ")";
+ m_componentManager.getActivator().getBundleContext().addServiceListener( this, filterString );
- m_componentManager.log( LogService.LOG_DEBUG,
- "Registered for service events, currently {0} service(s) match the filter", new Object[]
- { new Integer( m_size ) }, null );
+ m_componentManager.log( LogService.LOG_DEBUG,
+ "Registered for service events, currently {0} service(s) match the filter", new Object[]
+ { new Integer( m_size ) }, null );
+ }
+ else
+ {
+ // no services available
+ m_size = 0;
+
+ m_componentManager.log( LogService.LOG_DEBUG,
+ "Not registered for service events since the bundle has no permission to get service {0}", new Object[]
+ { m_dependencyMetadata.getInterface() }, null );
+ }
}
+
/**
* Disposes off this dependency manager by removing as a service listener
* and ungetting all services, which are still kept in the list of our
@@ -536,17 +551,23 @@
private ServiceReference[] getFrameworkServiceReferences( String targetFilter )
{
- try
+ if ( hasGetPermission() )
{
- return m_componentManager.getActivator().getBundleContext().getServiceReferences(
- m_dependencyMetadata.getInterface(), targetFilter );
+ try
+ {
+ return m_componentManager.getActivator().getBundleContext().getServiceReferences(
+ m_dependencyMetadata.getInterface(), targetFilter );
+ }
+ catch ( InvalidSyntaxException ise )
+ {
+ m_componentManager.log( LogService.LOG_ERROR, "Unexpected problem with filter ''{0}''", new Object[]
+ { targetFilter }, ise );
+ return null;
+ }
}
- catch ( InvalidSyntaxException ise )
- {
- m_componentManager.log( LogService.LOG_ERROR, "Unexpected problem with filter ''{0}''", new Object[]
- { targetFilter }, ise );
- return null;
- }
+
+ m_componentManager.log( LogService.LOG_DEBUG, "No permission to access the services", null );
+ return null;
}
@@ -763,6 +784,23 @@
}
+ /**
+ * Returns <code>true</code> if the component providing bundle has permission
+ * to get the service described by this reference.
+ */
+ public boolean hasGetPermission()
+ {
+ if ( System.getSecurityManager() != null )
+ {
+ Permission perm = new ServicePermission( getServiceName(), ServicePermission.GET );
+ return m_componentManager.getBundle().hasPermission( perm );
+ }
+
+ // no security manager, hence permission given
+ return true;
+ }
+
+
boolean open( Object instance )
{
m_componentInstance = instance;