[KARAF-3823]introduce karaf.secured.command.compulsory.roles system property (cherry picked from commit 648f860b3da95a2d8d06923130af06b5f41775a0) (cherry picked from commit 01a1f2b691dde3858ab157e4739714ac32ff3714)
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/773290cd Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/773290cd Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/773290cd Branch: refs/heads/master Commit: 773290cdbcde1d5ef9a1221e7ebce182354711c7 Parents: 1954bf9 Author: Freeman Fang <[email protected]> Authored: Thu Jul 2 13:56:48 2015 +0800 Committer: Freeman Fang <[email protected]> Committed: Thu Jul 2 18:03:36 2015 +0800 ---------------------------------------------------------------------- .../resources/resources/etc/system.properties | 9 +++++++- .../service/guard/impl/GuardProxyCatalog.java | 24 +++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/773290cd/assemblies/features/base/src/main/resources/resources/etc/system.properties ---------------------------------------------------------------------- diff --git a/assemblies/features/base/src/main/resources/resources/etc/system.properties b/assemblies/features/base/src/main/resources/resources/etc/system.properties index cff4250..8e3cb68 100644 --- a/assemblies/features/base/src/main/resources/resources/etc/system.properties +++ b/assemblies/features/base/src/main/resources/resources/etc/system.properties @@ -115,6 +115,13 @@ org.apache.aries.proxy.weaving.disabled = org.objectweb.asm.*,org.slf4j.*,org.ap karaf.secured.services = (&(osgi.command.scope=*)(osgi.command.function=*)) # +# By default, if there's no ACL policy for a certain karaf command, this command is allowed to access +# without the RBAC. We can change this behavior by enable the following property, which means +# if a karaf command has no corresponding ACL then access it must have one of the karaf.secured.command.compulsory.roles +# +#karaf.secured.command.compulsory.roles=admin + +# # Security properties # # To enable OSGi security, uncomment the properties below, @@ -135,4 +142,4 @@ karaf.secured.services = (&(osgi.command.scope=*)(osgi.command.function=*)) # Even using a single instance, Karaf creates the lock file # You can specify the location of the lock file using the # karaf.lock.dir=/path/to/the/directory/containing/the/lock -# \ No newline at end of file +# http://git-wip-us.apache.org/repos/asf/karaf/blob/773290cd/service/guard/src/main/java/org/apache/karaf/service/guard/impl/GuardProxyCatalog.java ---------------------------------------------------------------------- diff --git a/service/guard/src/main/java/org/apache/karaf/service/guard/impl/GuardProxyCatalog.java b/service/guard/src/main/java/org/apache/karaf/service/guard/impl/GuardProxyCatalog.java index 4883126..b64451a 100644 --- a/service/guard/src/main/java/org/apache/karaf/service/guard/impl/GuardProxyCatalog.java +++ b/service/guard/src/main/java/org/apache/karaf/service/guard/impl/GuardProxyCatalog.java @@ -62,6 +62,7 @@ import org.slf4j.LoggerFactory; public class GuardProxyCatalog implements ServiceListener { public static final String KARAF_SECURED_SERVICES_SYSPROP = "karaf.secured.services"; public static final String SERVICE_GUARD_ROLES_PROPERTY = "org.apache.karaf.service.guard.roles"; + public static final String KARAF_SECURED_COMMAND_COMPULSORY_ROLES_PROPERTY = "karaf.secured.command.compulsory.roles"; static final String PROXY_CREATOR_THREAD_NAME = "Secure OSGi Service Proxy Creator"; static final String PROXY_SERVICE_KEY = "." + GuardProxyCatalog.class.getName(); // The only currently used value is Boolean.TRUE @@ -79,15 +80,24 @@ public class GuardProxyCatalog implements ServiceListener { final ServiceTracker<ProxyManager, ProxyManager> proxyManagerTracker; final ConcurrentMap<Long, ServiceRegistrationHolder> proxyMap = new ConcurrentHashMap<Long, ServiceRegistrationHolder>(); final BlockingQueue<CreateProxyRunnable> createProxyQueue = new LinkedBlockingQueue<CreateProxyRunnable>(); + final String compulsoryRoles; // These two variables control the proxy creator thread, which is started as soon as a ProxyManager Service // becomes available. volatile boolean runProxyCreator = true; volatile Thread proxyCreatorThread = null; + + GuardProxyCatalog(BundleContext bc) throws Exception { LOG.trace("Starting GuardProxyCatalog"); myBundleContext = bc; + + compulsoryRoles = System.getProperty(GuardProxyCatalog.KARAF_SECURED_COMMAND_COMPULSORY_ROLES_PROPERTY); + if (compulsoryRoles == null) { + //default behavior as before, no compulsory roles for a karaf command without the ACL + LOG.info("No compulsory roles for a karaf command without the ACL as its system property is not set: {}", GuardProxyCatalog.KARAF_SECURED_COMMAND_COMPULSORY_ROLES_PROPERTY); + } // The service listener is used to update/unregister proxies if the backing service changes/goes away bc.addServiceListener(this); @@ -461,8 +471,9 @@ public class GuardProxyCatalog implements ServiceListener { // This can probably be optimized. Maybe we can cache the config object relevant instead of // walking through all of the ones that have 'service.guard'. + Object guardFilter = null; for (Configuration config : getServiceGuardConfigs()) { - Object guardFilter = config.getProperties().get(SERVICE_GUARD_KEY); + guardFilter = config.getProperties().get(SERVICE_GUARD_KEY); if (guardFilter instanceof String) { Filter filter = myBundleContext.createFilter((String) guardFilter); if (filter.match(serviceReference)) { @@ -482,8 +493,15 @@ public class GuardProxyCatalog implements ServiceListener { } if (!foundMatchingConfig) { - // No mappings for this service, anyone can invoke - return null; + if (compulsoryRoles != null && (guardFilter instanceof String) + && ((String)guardFilter).indexOf("osgi.command.scope") > 0 + && ((String)guardFilter).indexOf("osgi.command.functio") > 0) { + //use compulsoryRoles roles for those karaf command without any ACL + roleMappings.put(Specificity.NAME_MATCH, ACLConfigurationParser.parseRoles(compulsoryRoles)); + } else { + // No mappings for this service, anyone can invoke + return null; + } } if (roleMappings.size() == 0) {
