Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 565FD200B62 for ; Sat, 13 Aug 2016 00:01:08 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 55272160AB0; Fri, 12 Aug 2016 22:01:08 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 759C6160A85 for ; Sat, 13 Aug 2016 00:01:06 +0200 (CEST) Received: (qmail 73759 invoked by uid 500); 12 Aug 2016 22:01:05 -0000 Mailing-List: contact commits-help@geode.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.incubator.apache.org Delivered-To: mailing list commits@geode.incubator.apache.org Received: (qmail 73749 invoked by uid 99); 12 Aug 2016 22:01:05 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd3-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 12 Aug 2016 22:01:05 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd3-us-west.apache.org (ASF Mail Server at spamd3-us-west.apache.org) with ESMTP id 209B4180617 for ; Fri, 12 Aug 2016 22:01:05 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd3-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.646 X-Spam-Level: X-Spam-Status: No, score=-4.646 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd3-us-west.apache.org [10.40.0.10]) (amavisd-new, port 10024) with ESMTP id AaYdvUgWCRc5 for ; Fri, 12 Aug 2016 22:00:54 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with SMTP id A95575F1E3 for ; Fri, 12 Aug 2016 22:00:52 +0000 (UTC) Received: (qmail 73439 invoked by uid 99); 12 Aug 2016 22:00:51 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 12 Aug 2016 22:00:51 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id BAB35DFBAA; Fri, 12 Aug 2016 22:00:51 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: klund@apache.org To: commits@geode.incubator.apache.org Message-Id: <833ba3869c02433e8df38f5a5ca7c789@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: incubator-geode git commit: GEODE-1648: Introduce security-enabled-components and tests Date: Fri, 12 Aug 2016 22:00:51 +0000 (UTC) archived-at: Fri, 12 Aug 2016 22:01:08 -0000 Repository: incubator-geode Updated Branches: refs/heads/develop a75c59a33 -> 1a5a6fe65 GEODE-1648: Introduce security-enabled-components and tests Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/1a5a6fe6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/1a5a6fe6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/1a5a6fe6 Branch: refs/heads/develop Commit: 1a5a6fe6565779577d5cd9054e0846d8e98189b0 Parents: a75c59a Author: gmeilen Authored: Fri Aug 12 14:07:18 2016 -0700 Committer: gmeilen Committed: Fri Aug 12 14:07:18 2016 -0700 ---------------------------------------------------------------------- .../distributed/ConfigurationProperties.java | 10 ++ .../gemfire/distributed/DistributedSystem.java | 15 +- .../internal/AbstractDistributionConfig.java | 28 ++++ .../internal/DistributionConfig.java | 29 ++++ .../internal/DistributionConfigImpl.java | 28 +++- .../cache/tier/sockets/AcceptorImpl.java | 5 +- .../gemfire/internal/i18n/LocalizedStrings.java | 10 ++ .../internal/security/GeodeSecurityUtil.java | 55 ++++++- .../security/IntegratedSecurityService.java | 15 ++ .../internal/security/SecurableComponent.java | 53 +++++++ .../internal/security/SecurityService.java | 3 + .../management/internal/ManagementAgent.java | 8 +- .../geode/security/SecurableComponents.java | 57 +++++++ .../AbstractDistributionConfigTest.java | 78 ++++++++++ .../internal/DistributionConfigJUnitTest.java | 82 +++++++++- .../security/GeodeSecurityUtilTest.java | 156 ++++++++++++++++++- .../security/SecurityConfigIntegrationTest.java | 56 +++++++ ...edSecurityCacheLifecycleDistributedTest.java | 51 ++++-- .../gemfire/codeAnalysis/excludedClasses.txt | 1 + 19 files changed, 692 insertions(+), 48 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/distributed/ConfigurationProperties.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/ConfigurationProperties.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/ConfigurationProperties.java index 59700fb..3157020 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/ConfigurationProperties.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/ConfigurationProperties.java @@ -18,6 +18,7 @@ package com.gemstone.gemfire.distributed; import org.apache.geode.redis.GeodeRedisServer; +import org.apache.geode.security.SecurableComponents; /** * This interface defines all the configuration properties that can be used. @@ -1226,6 +1227,15 @@ public interface ConfigurationProperties { */ String SECURITY_PEER_VERIFY_MEMBER_TIMEOUT = SECURITY_PREFIX + "peer-verifymember-timeout"; /** + * The static String definition of the "ssl-enabled-components" property + *

+ * Description: This setting is a comma delimited fields which works in conjunction with the {@link #SECURITY_PREFIX} properties. + * This property will determine which components will use SSL for their communications.

+ * Options: "all","server","cluster","gateway","http","jmx" -- As described {@link SecurableComponents} + * Since: Geode 1.0 + */ + String SECURITY_ENABLED_COMPONENTS = SECURITY_PREFIX + "enabled-components"; + /** * The static String definition of the "server-bind-address" property *

* Description: The IP address that this distributed system's http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java index 46feef9..cb6851f 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java @@ -233,17 +233,10 @@ public abstract class DistributedSystem implements StatisticsFactory { } // Make a new connection to the distributed system - try { - InternalDistributedSystem newSystem = - InternalDistributedSystem.newInstance(config); - addSystem(newSystem); - return newSystem; - - } - catch (GemFireSecurityException ex) { - ex.fillInStackTrace(); // Make it harder to figure out where jgroups code lives. - throw ex; - } + InternalDistributedSystem newSystem = + InternalDistributedSystem.newInstance(config); + addSystem(newSystem); + return newSystem; } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java index 601818e..cc544f6 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java @@ -29,6 +29,8 @@ import java.util.Map; import java.util.Set; import java.util.StringTokenizer; +import org.apache.commons.lang.StringUtils; + import com.gemstone.gemfire.InternalGemFireException; import com.gemstone.gemfire.InvalidValueException; import com.gemstone.gemfire.UnmodifiableException; @@ -38,6 +40,7 @@ import com.gemstone.gemfire.internal.SocketCreator; import com.gemstone.gemfire.internal.admin.remote.DistributionLocatorId; import com.gemstone.gemfire.internal.i18n.LocalizedStrings; import com.gemstone.gemfire.internal.logging.LogWriterImpl; +import com.gemstone.gemfire.internal.security.SecurableComponent; import com.gemstone.gemfire.memcached.GemFireMemcachedServer; /** @@ -498,6 +501,29 @@ public abstract class AbstractDistributionConfig return value; } + /** + * First check if sslComponents are in the list of valid components. If so, check that no other *-ssl-* properties other than cluster-ssl-* are set. + * This would mean one is mixing the "old" with the "new" + */ + @ConfigAttributeChecker(name=SECURITY_ENABLED_COMPONENTS) + protected String checkSecurityEnabledComponents(String value) { + // value with no commas + // empty value + // null + if (StringUtils.isEmpty(value) || SecurableComponent.NONE.name().equalsIgnoreCase(value)) { + return value; + } + if (!value.contains(",")) { + SecurableComponent.getEnum(value); + return value; + } + StringTokenizer stringTokenizer = new StringTokenizer(value, ","); + while (stringTokenizer.hasMoreTokens()){ + SecurableComponent.getEnum(stringTokenizer.nextToken()); + } + return value; + } + // AbstractConfig overriding methods @Override @@ -1137,6 +1163,8 @@ public abstract class AbstractDistributionConfig m.put(SECURITY_MANAGER, "User defined fully qualified class name implementing SecurityManager interface for integrated security. Defaults to \"{0}\". Legal values can be any \"class name\" implementing SecurityManager that is present in the classpath."); m.put(SECURITY_POST_PROCESSOR, "User defined fully qualified class name implementing PostProcessor interface for integrated security. Defaults to \"{0}\". Legal values can be any \"class name\" implementing PostProcessor that is present in the classpath."); + m.put(SECURITY_ENABLED_COMPONENTS, "A comma delimited list of components that should be secured"); + dcAttDescriptions = Collections.unmodifiableMap(m); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java index fda9582..2ff6540 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java @@ -3985,6 +3985,35 @@ public interface DistributionConfig extends Config, LogConfig { @ConfigAttributeGetter(name = SECURITY_SHIRO_INIT) String getShiroInit(); + /** + * Returns the value of the {@link ConfigurationProperties#SECURITY_ENABLED_COMPONENTS} + * property. + * @since Geode 1.0 + */ + @ConfigAttributeGetter(name = SECURITY_ENABLED_COMPONENTS) + String getSecurityEnabledComponents(); + + /** + * Sets the value of the {@link ConfigurationProperties#SECURITY_ENABLED_COMPONENTS} + * property. + * @since Geode 1.0 + */ + @ConfigAttributeSetter(name = SECURITY_ENABLED_COMPONENTS) + void setSecurityEnabledComponents(String securityEnabledComponents); + + /** + * The name of the {@link ConfigurationProperties#SECURITY_ENABLED_COMPONENTS} property + * @since Geode 1.0 + */ + @ConfigAttribute(type = String.class) + String SECURITY_ENABLED_COMPONENTS_NAME = SECURITY_ENABLED_COMPONENTS; + + /** + * The default ssl enabled components + * @since Geode 1.0 + */ + String DEFAULT_SECURITY_ENABLED_COMPONENTS = "all"; + //*************** Initializers to gather all the annotations in this class ************************ Map attributes = new HashMap<>(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java index 6ac100c..72e53ff 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java @@ -39,6 +39,7 @@ import org.apache.geode.redis.GeodeRedisServer; import com.gemstone.gemfire.GemFireConfigException; import com.gemstone.gemfire.GemFireIOException; import com.gemstone.gemfire.distributed.DistributedSystem; +import org.apache.geode.security.SecurableComponents; import com.gemstone.gemfire.internal.ConfigSource; import com.gemstone.gemfire.internal.SocketCreator; import com.gemstone.gemfire.internal.i18n.LocalizedStrings; @@ -398,7 +399,9 @@ public class DistributionConfigImpl private Map sourceMap = Collections.synchronizedMap(new HashMap()); protected String userCommandPackages = DEFAULT_USER_COMMAND_PACKAGES; - + + private String securityEnabledComponents = DEFAULT_SECURITY_ENABLED_COMPONENTS; + /** "off-heap-memory-size" with value of "" or "[g|m]" */ protected String offHeapMemorySize = DEFAULT_OFF_HEAP_MEMORY_SIZE; @@ -588,6 +591,8 @@ public class DistributionConfigImpl this.shiroInit = other.getShiroInit(); this.securityManager = other.getSecurityManager(); this.postProcessor = other.getPostProcessor(); + + this.securityEnabledComponents = ((DistributionConfigImpl) other).securityEnabledComponents; } /** @@ -1088,7 +1093,7 @@ public class DistributionConfigImpl private void copyClusterSSLPropsToGatewaySSLProps() { boolean gatewaySSLOverriden = this.sourceMap.get(GATEWAY_SSL_ENABLED)!=null; boolean clusterSSLOverRidden = this.sourceMap.get(CLUSTER_SSL_ENABLED)!=null; - + if(clusterSSLOverRidden && !gatewaySSLOverriden) { this.gatewaySSLEnabled = this.clusterSSLEnabled; this.sourceMap.put(GATEWAY_SSL_ENABLED,this.sourceMap.get(CLUSTER_SSL_ENABLED)); @@ -2023,6 +2028,9 @@ public class DistributionConfigImpl } public Properties getSecurityProps() { + if(security.containsKey(SECURITY_MANAGER) && !security.containsKey(SECURITY_ENABLED_COMPONENTS)){ + security.setProperty(SECURITY_ENABLED_COMPONENTS, SecurableComponents.ALL); + } return security; } @@ -2314,9 +2322,19 @@ public class DistributionConfigImpl return this.shiroInit; } + @Override + public String getSecurityEnabledComponents() { + return securityEnabledComponents; + } + + @Override + public void setSecurityEnabledComponents(final String securityEnabledComponents) { + this.securityEnabledComponents = (String) checkAttribute(SECURITY_ENABLED_COMPONENTS, securityEnabledComponents); + } + /////////////////////// Utility Methods /////////////////////// /** - * Two instances of DistributedConfigImpl are equal if all of + * Two instances of DistributedConfigImpl are equal if all of * their configuration properties are the same. Be careful if you need to * remove final and override this. See bug #50939. */ @@ -2842,6 +2860,9 @@ public class DistributionConfigImpl return false; } else if (!userDefinedProps.equals(other.userDefinedProps)) return false; + if (securityEnabledComponents != other.securityEnabledComponents) { + return false; + } return true; } @@ -3123,6 +3144,7 @@ public class DistributionConfigImpl + ((userCommandPackages == null) ? 0 : userCommandPackages.hashCode()); result = prime * result + ((userDefinedProps == null) ? 0 : userDefinedProps.hashCode()); + result = prime * result + ((securityEnabledComponents == null) ? 0 : securityEnabledComponents.hashCode()); return result; } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/AcceptorImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/AcceptorImpl.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/AcceptorImpl.java index 56a8c9b..7422e16 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/AcceptorImpl.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/AcceptorImpl.java @@ -275,7 +275,7 @@ public class AcceptorImpl extends Acceptor implements Runnable private boolean isGatewayReceiver; private List gatewayTransportFilters; - private final SocketCreator socketCreator; + private final SocketCreator socketCreator; private SecurityService securityService = IntegratedSecurityService.getSecurityService(); @@ -642,7 +642,8 @@ public class AcceptorImpl extends Acceptor implements Runnable this.hsPool = tmp_hsPool; } - isAuthenticationRequired = this.securityService.isClientSecurityRequired(); + isAuthenticationRequired = (this.isGatewayReceiver && this.securityService.isGatewaySecurityRequired()) || + (! this.isGatewayReceiver && this.securityService.isClientSecurityRequired()); isIntegratedSecurity = this.securityService.isIntegratedSecurity(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/internal/i18n/LocalizedStrings.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/i18n/LocalizedStrings.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/i18n/LocalizedStrings.java index 2254a89..e9bbed9 100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/i18n/LocalizedStrings.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/i18n/LocalizedStrings.java @@ -3760,6 +3760,16 @@ public class LocalizedStrings { public static final StringId LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_ANALYZER_2_ON_FIELD_3_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_NO_ANALYZER_ON_THAT_FIELD = new StringId(6630, "Cannot create Lucene index {0} on region {1} with analyzer {2} on field {3} because another member defines the same index with no analyzer on that field."); public static final StringId LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_ANALYZER_2_ON_FIELD_3_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_ANALYZER_4_ON_THAT_FIELD = new StringId(6631, "Cannot create Lucene index {0} on region {1} with analyzer {2} on field {3} because another member defines the same index with analyzer {4} on that field."); + public static final StringId AbstractDistributionConfig_CLUSTER_SSL_ALIAS_0 = new StringId(6633,"SSL communication uses the this alias when determining the key to use from the keystore for SSL. Defaults to \"{0}\"."); + public static final StringId AbstractDistributionConfig_GATEWAY_SSL_ALIAS_0 = new StringId(6634,"SSL gateway communication uses the this alias when determining the key to use from the keystore for SSL. Defaults to \"{0}\"."); + public static final StringId AbstractDistributionConfig_SERVER_SSL_ALIAS_0 = new StringId(6635,"SSL inter-server communication (peer-to-peer) uses the this alias when determining the key to use from the keystore for SSL. Defaults to \"{0}\"."); + public static final StringId AbstractDistributionConfig_HTTP_SERVICE_SSL_ALIAS_0 = new StringId(6636,"SSL http service communication uses the this alias when determining the key to use from the keystore for SSL. Defaults to \"{0}\"."); + public static final StringId AbstractDistributionConfig_JMX_MANAGER_SSL_ALIAS_0 = new StringId(6637,"SSL jmx communication uses the this alias when determining the key to use from the keystore for SSL. Defaults to \"{0}\"."); + + public static final StringId AbstractDistributionConfig_SSL_ENABLED_COMPONENTS_0_INVALID_TRY_1 = new StringId(6638,"\"{0}\" is not in the valid set of options \"{1}\""); + + public static final StringId AbstractDistributionConfig_SSL_ENABLED_COMPONENTS_SET_INVALID_DEPRECATED_SSL_SET = new StringId(6639,"When using ssl-enabled-components one cannot use any other SSL properties other than cluster-ssl-* or the corresponding aliases"); + /** Testing strings, messageId 90000-99999 **/ /** These are simple messages for testing, translated with Babelfish. **/ http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java index f73790b..5fa5564 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java @@ -47,6 +47,8 @@ import org.apache.shiro.util.ThreadContext; import org.apache.shiro.util.ThreadState; import com.gemstone.gemfire.GemFireIOException; +import org.apache.geode.security.SecurableComponents; +import com.gemstone.gemfire.distributed.internal.DistributionConfig; import com.gemstone.gemfire.internal.ClassLoadUtil; import com.gemstone.gemfire.internal.cache.EntryEventImpl; import com.gemstone.gemfire.internal.logging.LogService; @@ -64,9 +66,17 @@ public class GeodeSecurityUtil { private static PostProcessor postProcessor; private static SecurityManager securityManager; + private static boolean isIntegratedSecurity; - private static boolean isClientAuthenticator; - private static boolean isPeerAuthenticator; + + private static boolean isClientAuthenticator; // is there a SECURITY_CLIENT_AUTHENTICATOR + private static boolean isPeerAuthenticator; // is there a SECURITY_PEER_AUTHENTICATOR + + private static boolean isJmxSecurityRequired; + private static boolean isHttpSecurityRequired; + private static boolean isGatewaySecurityRequired; + private static boolean isClusterSecurityRequired; + private static boolean isServerSecurityRequired; /** * It first looks the shiro subject in AccessControlContext since JMX will @@ -288,6 +298,17 @@ public class GeodeSecurityUtil { return; } + String enabledComponentsString = securityProps.getProperty(SECURITY_ENABLED_COMPONENTS); + if (enabledComponentsString == null) { + enabledComponentsString = DistributionConfig.DEFAULT_SECURITY_ENABLED_COMPONENTS; + } + + boolean isClusterSecured = enabledComponentsString.contains(SecurableComponents.ALL) || enabledComponentsString.contains(SecurableComponents.CLUSTER); + boolean isGatewaySecured = enabledComponentsString.contains(SecurableComponents.ALL) || enabledComponentsString.contains(SecurableComponents.GATEWAY); + boolean isHttpSecured = enabledComponentsString.contains(SecurableComponents.ALL) || enabledComponentsString.contains(SecurableComponents.HTTP_SERVICE); + boolean isJmxSecured = enabledComponentsString.contains(SecurableComponents.ALL) || enabledComponentsString.contains(SecurableComponents.JMX); + boolean isServerSecured = enabledComponentsString.contains(SecurableComponents.ALL) || enabledComponentsString.contains(SecurableComponents.SERVER); + String shiroConfig = securityProps.getProperty(SECURITY_SHIRO_INIT); String securityConfig = securityProps.getProperty(SECURITY_MANAGER); String clientAuthenticatorConfig = securityProps.getProperty(SECURITY_CLIENT_AUTHENTICATOR); @@ -328,6 +349,13 @@ public class GeodeSecurityUtil { isPeerAuthenticator = false; } + isServerSecurityRequired = isClientAuthenticator || (isIntegratedSecurity && isServerSecured); + isClusterSecurityRequired = isPeerAuthenticator || (isIntegratedSecurity && isClusterSecured); + + isGatewaySecurityRequired = isClientAuthenticator || (isIntegratedSecurity && isGatewaySecured); + isHttpSecurityRequired = isIntegratedSecurity && isHttpSecured; + isJmxSecurityRequired = isIntegratedSecurity && isJmxSecured; + // this initializes the post processor String customPostProcessor = securityProps.getProperty(SECURITY_POST_PROCESSOR); if( !StringUtils.isBlank(customPostProcessor)) { @@ -477,16 +505,27 @@ public class GeodeSecurityUtil { return postProcessor; } - public static boolean isClientSecurityRequired() { - return isClientAuthenticator || isIntegratedSecurity; + public static boolean isIntegratedSecurity(){ + return isIntegratedSecurity; } - public static boolean isPeerSecurityRequired() { - return isPeerAuthenticator || isIntegratedSecurity; + public static boolean isClientSecurityRequired() { // TODO: rename as isServerSecurityRequired + return isServerSecurityRequired; } - public static boolean isIntegratedSecurity(){ - return isIntegratedSecurity; + public static boolean isPeerSecurityRequired() { // TODO: rename as isClusterSecurityRequired + return isClusterSecurityRequired; + } + + public static boolean isJmxSecurityRequired() { + return isJmxSecurityRequired; + } + + public static boolean isGatewaySecurityRequired() { + return isGatewaySecurityRequired; } + public static boolean isHttpServiceSecurityRequired() { + return isHttpSecurityRequired; + } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java index 30da9bf..a6ec7fa 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java @@ -180,6 +180,21 @@ public class IntegratedSecurityService implements SecurityService, Serializable } @Override + public boolean isJmxSecurityRequired() { + return GeodeSecurityUtil.isJmxSecurityRequired(); + } + + @Override + public boolean isGatewaySecurityRequired() { + return GeodeSecurityUtil.isGatewaySecurityRequired(); + } + + @Override + public boolean isHttpSecurityRequired() { + return GeodeSecurityUtil.isHttpServiceSecurityRequired(); + } + + @Override public boolean isPeerSecurityRequired() { return GeodeSecurityUtil.isPeerSecurityRequired(); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurableComponent.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurableComponent.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurableComponent.java new file mode 100644 index 0000000..ff78b9e --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurableComponent.java @@ -0,0 +1,53 @@ +/* + * 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. + */ +package com.gemstone.gemfire.internal.security; + +import org.springframework.util.StringUtils; + +import com.gemstone.gemfire.GemFireConfigException; +import org.apache.geode.security.SecurableComponents; + +public enum SecurableComponent { + ALL(SecurableComponents.ALL), + CLUSTER(SecurableComponents.CLUSTER), + SERVER(SecurableComponents.SERVER), + JMX(SecurableComponents.JMX), + HTTP_SERVICE(SecurableComponents.HTTP_SERVICE), + GATEWAY(SecurableComponents.GATEWAY), + NONE("NO_COMPONENT"); + + private final String constant; + + SecurableComponent(final String constant) { + this.constant = constant; + } + + public static SecurableComponent getEnum(String enumString) { + for (SecurableComponent securableComponent : SecurableComponent.values()) { + if (!StringUtils.isEmpty(enumString)) { + if (securableComponent.constant.equals(enumString)) { + return securableComponent; + } + } + } + throw new GemFireConfigException("There is no registered component for the name: " + enumString); + } + + public String getConstant() { + return constant; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java index b562892..dd8c69b 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java @@ -55,6 +55,9 @@ public interface SecurityService { Object postProcess(String regionPath, Object key, Object value, boolean valueIsSerialized); Object postProcess(Serializable principal, String regionPath, Object key, Object value, boolean valueIsSerialized); boolean isClientSecurityRequired(); + boolean isJmxSecurityRequired(); + boolean isGatewaySecurityRequired(); + boolean isHttpSecurityRequired(); boolean isPeerSecurityRequired(); boolean isIntegratedSecurity(); SecurityManager getSecurityManager(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java index 1e23279..f3c771f 100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java @@ -58,6 +58,7 @@ import com.gemstone.gemfire.internal.SocketCreator; import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; import com.gemstone.gemfire.internal.lang.StringUtils; import com.gemstone.gemfire.internal.logging.LogService; +import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; import com.gemstone.gemfire.internal.security.shiro.JMXShiroAuthenticator; import com.gemstone.gemfire.internal.tcp.TCPConduit; import com.gemstone.gemfire.management.ManagementException; @@ -92,6 +93,7 @@ public class ManagementAgent { private JMXConnectorServer cs; private JMXShiroAuthenticator shiroAuthenticator; private final DistributionConfig config; + // TODO: add this -- private boolean isSecured; private boolean isHttpServiceRunning = false; /** @@ -451,8 +453,7 @@ public class ManagementAgent { } }; - String shiroConfig = this.config.getShiroInit(); - if (! StringUtils.isBlank(shiroConfig) || isIntegratedSecurity()) { + if (isIntegratedSecurity()) { shiroAuthenticator = new JMXShiroAuthenticator(); env.put(JMXConnectorServer.AUTHENTICATOR, shiroAuthenticator); cs.addNotificationListener(shiroAuthenticator, null, cs.getAttributes()); @@ -513,8 +514,7 @@ public class ManagementAgent { private boolean isIntegratedSecurity() { - String factoryName = config.getSecurityManager(); - return factoryName != null && !factoryName.isEmpty(); + return GeodeSecurityUtil.isJmxSecurityRequired(); } private static class GemFireRMIClientSocketFactory implements RMIClientSocketFactory, http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/main/java/org/apache/geode/security/SecurableComponents.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/security/SecurableComponents.java b/geode-core/src/main/java/org/apache/geode/security/SecurableComponents.java new file mode 100644 index 0000000..a7ae766 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/security/SecurableComponents.java @@ -0,0 +1,57 @@ +/* + * 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. + */ +package org.apache.geode.security; + +import com.gemstone.gemfire.distributed.ConfigurationProperties; + +/** + * This class defines all the static definitions for the {@link ConfigurationProperties#SECURITY_ENABLED_COMPONENTS} + * Since: Geode 1.0 + */ +public interface SecurableComponents { + + /** + * This determines that all components will be secured. + * Since: Geode 1.0 + */ + String ALL = "all"; + /** + * This determines that the client-server communication will be secured. + * Since: Geode 1.0 + */ + String SERVER = "server"; + /** + * This determines that the inter-server (or server-to-server) communication will be secured. + * Since: Geode 1.0 + */ + String CLUSTER = "cluster"; + /** + * This determines that test jmx communication will be secured. + * Since: Geode 1.0 + */ + String JMX = "jmx"; + /** + * This determines that the http service communcation will be secured. + * Since: Geode 1.0 + */ + String HTTP_SERVICE = "http"; + /** + * This determines that the gateway communication will be secured. + * Since: Geode 1.0 + */ + String GATEWAY = "gateway"; +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfigTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfigTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfigTest.java new file mode 100644 index 0000000..fd2fb34 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfigTest.java @@ -0,0 +1,78 @@ +/* + * 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. + */ +package com.gemstone.gemfire.distributed.internal; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Answers.*; + +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.gemstone.gemfire.GemFireConfigException; +import org.apache.geode.security.SecurableComponents; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +@Category(UnitTest.class) +@RunWith(MockitoJUnitRunner.class) +public class AbstractDistributionConfigTest { + + @Mock(answer = CALLS_REAL_METHODS) + private AbstractDistributionConfig abstractDistributionConfig; + + @Test + public void testNoCommaInvalidStringThrows() { + assertThatThrownBy(() -> abstractDistributionConfig.checkSecurityEnabledComponents("This has no commas in it")).isExactlyInstanceOf(GemFireConfigException.class); + } + + @Test + public void testOneSecurityEnabledComponents() { + String returnValue = abstractDistributionConfig.checkSecurityEnabledComponents(SecurableComponents.JMX); + assertThat(returnValue).isEqualTo(SecurableComponents.JMX); + } + + @Test + public void testEmptySecurityEnabledComponents() { + String returnValue = abstractDistributionConfig.checkSecurityEnabledComponents(""); + assertThat(returnValue).isEqualTo(""); + } + + @Test + public void testNoneSecurityEnabledComponents() { + String returnValue = abstractDistributionConfig.checkSecurityEnabledComponents("none"); + assertThat(returnValue).isEqualTo("none"); + } + + @Test + public void testNullSecurityEnabledComponents() { + String returnValue = abstractDistributionConfig.checkSecurityEnabledComponents(null); + assertThat(returnValue).isEqualTo(null); + } + + @Test + public void testTwoSecurityEnabledComponents() { + String returnValue = abstractDistributionConfig.checkSecurityEnabledComponents(SecurableComponents.JMX + "," + SecurableComponents.SERVER); + assertThat(returnValue).isEqualTo(SecurableComponents.JMX + "," + SecurableComponents.SERVER); + } + + @Test + public void testOneValidSecurityEnabledComponentAndOneInvalid() { + assertThatThrownBy(() -> abstractDistributionConfig.checkSecurityEnabledComponents(SecurableComponents.JMX + "," + SecurableComponents.SERVER + "," + "this should throw")).isExactlyInstanceOf(GemFireConfigException.class); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/DistributionConfigJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/DistributionConfigJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/DistributionConfigJUnitTest.java index 36783ed..6d6f36d 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/DistributionConfigJUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/DistributionConfigJUnitTest.java @@ -17,6 +17,7 @@ package com.gemstone.gemfire.distributed.internal; import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; +import static org.assertj.core.api.Assertions.*; import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; @@ -36,8 +37,10 @@ import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; +import com.gemstone.gemfire.GemFireConfigException; import com.gemstone.gemfire.InternalGemFireException; import com.gemstone.gemfire.UnmodifiableException; +import org.apache.geode.security.SecurableComponents; import com.gemstone.gemfire.internal.ConfigSource; import com.gemstone.gemfire.test.junit.categories.UnitTest; @@ -78,7 +81,7 @@ public class DistributionConfigJUnitTest { @Test public void testGetAttributeNames() { String[] attNames = AbstractDistributionConfig._getAttNames(); - assertEquals(attNames.length, 143); + assertEquals(attNames.length, 144); List boolList = new ArrayList(); List intList = new ArrayList(); @@ -112,7 +115,7 @@ public class DistributionConfigJUnitTest { assertEquals(boolList.size(), 30); assertEquals(intList.size(), 33); - assertEquals(stringList.size(), 72); + assertEquals(stringList.size(), 73); assertEquals(fileList.size(), 5); assertEquals(otherList.size(), 3); } @@ -336,7 +339,8 @@ public class DistributionConfigJUnitTest { props.put(ACK_WAIT_THRESHOLD, 2); DistributionConfig config = new DistributionConfigImpl(props); - assertEquals(config.getSecurityProps().size(), 3); + // SECURITY_ENABLED_COMPONENTS is automatically added to getSecurityProps + assertEquals(config.getSecurityProps().size(), 4); } @Test @@ -350,6 +354,76 @@ public class DistributionConfigJUnitTest { props.put("security-username", "testName"); DistributionConfig config = new DistributionConfigImpl(props); - assertEquals(config.getSecurityProps().size(), 4); + // SECURITY_ENABLED_COMPONENTS is automatically added to getSecurityProps + assertEquals(config.getSecurityProps().size(), 5); + } + + @Test + public void securityEnabledComponentsDefaultShouldBeAll() throws Exception { + Properties props = new Properties(); + props.put(SECURITY_MANAGER, SampleSecurityManager.class.getName()); + + DistributionConfig config = new DistributionConfigImpl(props); + + assertThat(config.getSecurityEnabledComponents()).contains(SecurableComponents.ALL); + } + + @Test + public void oneSecurityEnabledComponent() throws Exception { + Properties props = new Properties(); + props.put(SECURITY_MANAGER, SampleSecurityManager.class.getName()); + props.put(SECURITY_ENABLED_COMPONENTS, SecurableComponents.JMX); + + DistributionConfig config = new DistributionConfigImpl(props); + + assertThat(config.getSecurityEnabledComponents()) + .doesNotContain(SecurableComponents.ALL) + .doesNotContain(SecurableComponents.GATEWAY) + .doesNotContain(SecurableComponents.SERVER) + .doesNotContain(SecurableComponents.HTTP_SERVICE) + .doesNotContain(SecurableComponents.CLUSTER) + .contains(SecurableComponents.JMX); + } + + @Test + public void twoSecurityEnabledComponents() throws Exception { + Properties props = new Properties(); + props.put(SECURITY_MANAGER, SampleSecurityManager.class.getName()); + props.put(SECURITY_ENABLED_COMPONENTS, SecurableComponents.JMX + "," + SecurableComponents.CLUSTER); + + DistributionConfig config = new DistributionConfigImpl(props); + + assertThat(config.getSecurityEnabledComponents()) + .doesNotContain(SecurableComponents.ALL) + .doesNotContain(SecurableComponents.GATEWAY) + .doesNotContain(SecurableComponents.SERVER) + .doesNotContain(SecurableComponents.HTTP_SERVICE) + .contains(SecurableComponents.CLUSTER) + .contains(SecurableComponents.JMX); + } + + @Test + public void multipleSecurityEnabledComponents() throws Exception { + Properties props = new Properties(); + props.put(SECURITY_MANAGER, SampleSecurityManager.class.getName()); + props.put(SECURITY_ENABLED_COMPONENTS, SecurableComponents.JMX + "," + SecurableComponents.CLUSTER+ "," + SecurableComponents.HTTP_SERVICE); + + DistributionConfig config = new DistributionConfigImpl(props); + + assertThat(config.getSecurityEnabledComponents()) + .doesNotContain(SecurableComponents.ALL) + .doesNotContain(SecurableComponents.GATEWAY) + .doesNotContain(SecurableComponents.SERVER) + .contains(SecurableComponents.HTTP_SERVICE) + .contains(SecurableComponents.CLUSTER) + .contains(SecurableComponents.JMX); + } + + @Test + public void nonExistentSecurityEnabledComponentShouldThrow() throws Exception { + Properties props = new Properties(); + props.put(SECURITY_ENABLED_COMPONENTS, "notapplicable"); + + assertThatThrownBy(() -> new DistributionConfigImpl(props)).isExactlyInstanceOf(GemFireConfigException.class); } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java index bdd1ec6..23d0d99 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java @@ -27,6 +27,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.apache.geode.security.SecurableComponents; import com.gemstone.gemfire.security.GemFireSecurityException; import com.gemstone.gemfire.test.junit.categories.UnitTest; @@ -45,6 +46,7 @@ public class GeodeSecurityUtilTest { public void testGetObjectFromConstructor() { String string = GeodeSecurityUtil.getObjectOfType(String.class.getName(), String.class); assertNotNull(string); + CharSequence charSequence = GeodeSecurityUtil.getObjectOfType(String.class.getName(), CharSequence.class); assertNotNull(charSequence); @@ -63,6 +65,7 @@ public class GeodeSecurityUtilTest { public void testGetObjectFromFactoryMethod() { String string = GeodeSecurityUtil.getObjectOfType(Factories.class.getName()+".getString", String.class); assertNotNull(string); + CharSequence charSequence = GeodeSecurityUtil.getObjectOfType(Factories.class.getName()+".getString", String.class); assertNotNull(charSequence); @@ -76,8 +79,12 @@ public class GeodeSecurityUtilTest { @Test public void testInitialSecurityFlags() { // initial state of GeodeSecurityUtil - assertFalse(GeodeSecurityUtil.isClientSecurityRequired()); assertFalse(GeodeSecurityUtil.isIntegratedSecurity()); + + assertFalse(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertFalse(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertFalse(GeodeSecurityUtil.isJmxSecurityRequired()); assertFalse(GeodeSecurityUtil.isPeerSecurityRequired()); } @@ -85,36 +92,177 @@ public class GeodeSecurityUtilTest { public void testInitWithSecurityManager() { properties.setProperty(SECURITY_MANAGER, "org.apache.geode.security.templates.SampleSecurityManager"); properties.setProperty(SampleSecurityManager.SECURITY_JSON, "org/apache/geode/security/templates/security.json"); + GeodeSecurityUtil.initSecurity(properties); - assertTrue(GeodeSecurityUtil.isClientSecurityRequired()); + assertTrue(GeodeSecurityUtil.isIntegratedSecurity()); + + assertTrue(GeodeSecurityUtil.isClientSecurityRequired()); + assertTrue(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertTrue(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertTrue(GeodeSecurityUtil.isJmxSecurityRequired()); assertTrue(GeodeSecurityUtil.isPeerSecurityRequired()); } @Test public void testInitWithClientAuthenticator() { properties.setProperty(SECURITY_CLIENT_AUTHENTICATOR, "org.abc.test"); + GeodeSecurityUtil.initSecurity(properties); - assertTrue(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isIntegratedSecurity()); + + assertTrue(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertFalse(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertFalse(GeodeSecurityUtil.isJmxSecurityRequired()); assertFalse(GeodeSecurityUtil.isPeerSecurityRequired()); } @Test public void testInitWithPeerAuthenticator() { properties.setProperty(SECURITY_PEER_AUTHENTICATOR, "org.abc.test"); + GeodeSecurityUtil.initSecurity(properties); - assertFalse(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isIntegratedSecurity()); + + assertFalse(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertFalse(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertFalse(GeodeSecurityUtil.isJmxSecurityRequired()); assertTrue(GeodeSecurityUtil.isPeerSecurityRequired()); } @Test public void testInitWithShiroAuthenticator() { properties.setProperty(SECURITY_SHIRO_INIT, "shiro.ini"); + GeodeSecurityUtil.initSecurity(properties); + + assertTrue(GeodeSecurityUtil.isIntegratedSecurity()); + assertTrue(GeodeSecurityUtil.isClientSecurityRequired()); + assertTrue(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertTrue(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertTrue(GeodeSecurityUtil.isJmxSecurityRequired()); + assertTrue(GeodeSecurityUtil.isPeerSecurityRequired()); + } + + @Test + public void allEnabledWithSecurityManager() { + properties.setProperty(SECURITY_MANAGER, "org.apache.geode.security.templates.SampleSecurityManager"); + properties.setProperty(SampleSecurityManager.SECURITY_JSON, "org/apache/geode/security/templates/security.json"); + properties.setProperty(SECURITY_ENABLED_COMPONENTS, SecurableComponents.ALL); + + GeodeSecurityUtil.initSecurity(properties); + + assertTrue(GeodeSecurityUtil.isIntegratedSecurity()); + + assertTrue(GeodeSecurityUtil.isClientSecurityRequired()); + assertTrue(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertTrue(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertTrue(GeodeSecurityUtil.isJmxSecurityRequired()); + assertTrue(GeodeSecurityUtil.isPeerSecurityRequired()); + } + + @Test + public void emptyEnabledWithSecurityManager() { + properties.setProperty(SECURITY_MANAGER, "org.apache.geode.security.templates.SampleSecurityManager"); + properties.setProperty(SampleSecurityManager.SECURITY_JSON, "org/apache/geode/security/templates/security.json"); + properties.setProperty(SECURITY_ENABLED_COMPONENTS,""); + + GeodeSecurityUtil.initSecurity(properties); + assertTrue(GeodeSecurityUtil.isIntegratedSecurity()); + + assertFalse(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertFalse(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertFalse(GeodeSecurityUtil.isJmxSecurityRequired()); + assertFalse(GeodeSecurityUtil.isPeerSecurityRequired()); + } + + @Test + public void noneEnabledWithSecurityManager() { + properties.setProperty(SECURITY_MANAGER, "org.apache.geode.security.templates.SampleSecurityManager"); + properties.setProperty(SampleSecurityManager.SECURITY_JSON, "org/apache/geode/security/templates/security.json"); + properties.setProperty(SECURITY_ENABLED_COMPONENTS,"none"); + + GeodeSecurityUtil.initSecurity(properties); + + assertTrue(GeodeSecurityUtil.isIntegratedSecurity()); + + assertFalse(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertFalse(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertFalse(GeodeSecurityUtil.isJmxSecurityRequired()); + assertFalse(GeodeSecurityUtil.isPeerSecurityRequired()); + } + + @Test + public void allSecurableComponentsWithoutAnySecurity() { + properties.setProperty(SECURITY_ENABLED_COMPONENTS, SecurableComponents.ALL); + + GeodeSecurityUtil.initSecurity(properties); + + assertFalse(GeodeSecurityUtil.isIntegratedSecurity()); + + assertFalse(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertFalse(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertFalse(GeodeSecurityUtil.isJmxSecurityRequired()); + assertFalse(GeodeSecurityUtil.isPeerSecurityRequired()); + } + + @Test + public void oneSecurableComponentEnabledWithSecurityManager() { + properties.setProperty(SECURITY_MANAGER, "org.apache.geode.security.templates.SampleSecurityManager"); + properties.setProperty(SampleSecurityManager.SECURITY_JSON, "org/apache/geode/security/templates/security.json"); + properties.setProperty(SECURITY_ENABLED_COMPONENTS, SecurableComponents.JMX); + + GeodeSecurityUtil.initSecurity(properties); + + assertTrue(GeodeSecurityUtil.isIntegratedSecurity()); + + assertFalse(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertFalse(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertTrue(GeodeSecurityUtil.isJmxSecurityRequired()); + assertFalse(GeodeSecurityUtil.isPeerSecurityRequired()); + } + + @Test + public void twoSecurableComponentEnabledWithSecurityManager() { + properties.setProperty(SECURITY_MANAGER, "org.apache.geode.security.templates.SampleSecurityManager"); + properties.setProperty(SampleSecurityManager.SECURITY_JSON, "org/apache/geode/security/templates/security.json"); + properties.setProperty(SECURITY_ENABLED_COMPONENTS, SecurableComponents.JMX + "," + SecurableComponents.SERVER); + + GeodeSecurityUtil.initSecurity(properties); + + assertTrue(GeodeSecurityUtil.isIntegratedSecurity()); + + assertTrue(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertFalse(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertTrue(GeodeSecurityUtil.isJmxSecurityRequired()); + assertFalse(GeodeSecurityUtil.isPeerSecurityRequired()); + } + + @Test + public void manySecurableComponentEnabledWithSecurityManager() { + properties.setProperty(SECURITY_MANAGER, "org.apache.geode.security.templates.SampleSecurityManager"); + properties.setProperty(SampleSecurityManager.SECURITY_JSON, "org/apache/geode/security/templates/security.json"); + properties.setProperty(SECURITY_ENABLED_COMPONENTS, SecurableComponents.JMX + "," + SecurableComponents.SERVER + "," + SecurableComponents.CLUSTER); + + GeodeSecurityUtil.initSecurity(properties); + + assertTrue(GeodeSecurityUtil.isIntegratedSecurity()); + + assertTrue(GeodeSecurityUtil.isClientSecurityRequired()); + assertFalse(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertFalse(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + assertTrue(GeodeSecurityUtil.isJmxSecurityRequired()); assertTrue(GeodeSecurityUtil.isPeerSecurityRequired()); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/test/java/com/gemstone/gemfire/internal/security/SecurityConfigIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/security/SecurityConfigIntegrationTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/security/SecurityConfigIntegrationTest.java new file mode 100644 index 0000000..d0a2130 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/security/SecurityConfigIntegrationTest.java @@ -0,0 +1,56 @@ +/* + * 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. + */ +package com.gemstone.gemfire.internal.security; + +import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.Properties; + +import org.apache.geode.security.templates.SampleSecurityManager; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.security.SecurableComponents; +import com.gemstone.gemfire.distributed.internal.DistributionConfig; +import com.gemstone.gemfire.distributed.internal.DistributionConfigImpl; +import com.gemstone.gemfire.test.junit.categories.IntegrationTest; + +@Category(IntegrationTest.class) +public class SecurityConfigIntegrationTest { + + @Test + public void securityEnabledComponentsDefaultShouldBeAll() throws Exception { + Properties props = new Properties(); + props.put(SECURITY_MANAGER, SampleSecurityManager.class.getName()); + props.put(SampleSecurityManager.SECURITY_JSON, "org/apache/geode/security/templates/security.json"); + + DistributionConfig config = new DistributionConfigImpl(props); + Properties securityProps = config.getSecurityProps(); + + assertThat(securityProps).containsKeys(SECURITY_MANAGER, SECURITY_ENABLED_COMPONENTS); + assertThat(securityProps.getProperty(SECURITY_ENABLED_COMPONENTS)).isEqualTo(SecurableComponents.ALL); + + GeodeSecurityUtil.initSecurity(securityProps); + + assertThat(GeodeSecurityUtil.isClientSecurityRequired()); + assertThat(GeodeSecurityUtil.isGatewaySecurityRequired()); + assertThat(GeodeSecurityUtil.isPeerSecurityRequired()); + assertThat(GeodeSecurityUtil.isJmxSecurityRequired()); + assertThat(GeodeSecurityUtil.isHttpServiceSecurityRequired()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleDistributedTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleDistributedTest.java index a37c1c2..2920fd5 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleDistributedTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleDistributedTest.java @@ -19,6 +19,7 @@ package com.gemstone.gemfire.security; import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; import static org.assertj.core.api.Assertions.*; +import java.io.IOException; import java.util.Properties; import org.apache.geode.security.templates.SampleSecurityManager; @@ -30,6 +31,8 @@ import com.gemstone.gemfire.cache.server.CacheServer; import com.gemstone.gemfire.internal.AvailablePort; import com.gemstone.gemfire.internal.security.IntegratedSecurityService; import com.gemstone.gemfire.internal.security.SecurityService; +import com.gemstone.gemfire.internal.AvailablePortHelper; +import com.gemstone.gemfire.management.ManagementService; import com.gemstone.gemfire.test.dunit.DistributedTestUtils; import com.gemstone.gemfire.test.dunit.Host; import com.gemstone.gemfire.test.dunit.NetworkUtils; @@ -42,6 +45,7 @@ import com.gemstone.gemfire.test.junit.categories.SecurityTest; @Category({DistributedTest.class, SecurityTest.class}) public class IntegratedSecurityCacheLifecycleDistributedTest extends JUnit4CacheTestCase { + private String locators; private VM locator; private SecurityService securityService; @@ -52,29 +56,61 @@ public class IntegratedSecurityCacheLifecycleDistributedTest extends JUnit4Cache securityService = IntegratedSecurityService.getSecurityService(); - int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET); - String locators = NetworkUtils.getServerHostName(host) + "[" + locatorPort + "]"; + int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2); + int locatorPort = ports[0]; + int managerPort = ports[1]; + + locators = NetworkUtils.getServerHostName(host) + "[" + locatorPort + "]"; locator.invoke(() -> { DistributedTestUtils.deleteLocatorStateFile(locatorPort); final Properties properties = new Properties(); properties.setProperty(SampleSecurityManager.SECURITY_JSON, "com/gemstone/gemfire/management/internal/security/clientServer.json"); -// properties.setProperty(LOCATORS, locators); + properties.setProperty(LOCATORS, locators); properties.setProperty(MCAST_PORT, "0"); + properties.setProperty(SECURITY_ENABLED_COMPONENTS, ""); properties.setProperty(SECURITY_MANAGER, SpySecurityManager.class.getName()); properties.setProperty(START_LOCATOR, locators); + properties.setProperty(JMX_MANAGER, "true"); + properties.setProperty(JMX_MANAGER_START, "true"); + properties.setProperty(JMX_MANAGER_PORT, String.valueOf(managerPort)); properties.setProperty(USE_CLUSTER_CONFIGURATION, "false"); getSystem(properties); getCache(); }); + } + + @Test + public void initAndCloseTest() throws Exception { + connect(); + + { + ManagementService ms = ManagementService.getExistingManagementService(getCache()); + assertThat(ms).isNotNull(); + assertThat(ms.isManager()).isFalse(); + verifyInitCloseInvoked(); + } + + locator.invoke(() -> { + ManagementService ms = ManagementService.getExistingManagementService(getCache()); + assertThat(ms).isNotNull(); + assertThat(ms.isManager()).isTrue(); + + verifyInitCloseInvoked(); + }); + } + + private void connect() throws IOException { final Properties properties = new Properties(); properties.setProperty(SampleSecurityManager.SECURITY_JSON, "com/gemstone/gemfire/management/internal/security/clientServer.json"); properties.setProperty(LOCATORS, locators); properties.setProperty(MCAST_PORT, "0"); + properties.setProperty(SECURITY_ENABLED_COMPONENTS, ""); properties.setProperty(SECURITY_MANAGER, SpySecurityManager.class.getName()); properties.setProperty(USE_CLUSTER_CONFIGURATION, "false"); + getSystem(properties); CacheServer server1 = getCache().addCacheServer(); @@ -84,15 +120,6 @@ public class IntegratedSecurityCacheLifecycleDistributedTest extends JUnit4Cache getCache(); } - @Test - public void initAndCloseTest () { - verifyInitCloseInvoked(); - - locator.invoke(() -> { - verifyInitCloseInvoked(); - }); - } - @Override public void postTearDownCacheTestCase() throws Exception { closeAllCache(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a5a6fe6/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt ---------------------------------------------------------------------- diff --git a/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt b/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt index ac707b6..9d880f5 100644 --- a/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt +++ b/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt @@ -116,6 +116,7 @@ com/gemstone/gemfire/internal/process/ClusterConfigurationNotAvailableException com/gemstone/gemfire/internal/security/GeodeSecurityUtil com/gemstone/gemfire/internal/security/IntegratedSecurityService com/gemstone/gemfire/internal/security/IntegratedSecurityService$SerializationProxy +com/gemstone/gemfire/internal/security/SecurableComponent com/gemstone/gemfire/internal/security/SecurityService com/gemstone/org/apache/logging/log4j/core/config/xml/GemFireXmlConfiguration com/gemstone/org/apache/logging/log4j/core/config/xml/GemFireXmlConfiguration$ErrorType