GEODE-949: refactor and repackage security test code * move test security classes from security package to com.gemstone.gemfire.security.generator * move test security resources from lib package to com.gemstone.gemfire.security.generator * move test security classes from templates.security package to com.gemstone.gemfire.security.templates * fix places where security code ate exceptions * fix up javadocs * reformat and refactor code to be more readable and follow standards
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/8de59df1 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/8de59df1 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/8de59df1 Branch: refs/heads/feature/GEODE-17-3 Commit: 8de59df1853413fa1cc50dfbeba26325f85f8093 Parents: d72986b Author: Kirk Lund <kl...@apache.org> Authored: Thu Mar 17 14:17:38 2016 -0700 Committer: Kirk Lund <kl...@apache.org> Committed: Thu Mar 17 14:17:38 2016 -0700 ---------------------------------------------------------------------- .../membership/gms/auth/GMSAuthenticator.java | 98 +-- .../CacheServerSSLConnectionDUnitTest.java | 124 ++-- .../sockets/DurableClientBug39997DUnitTest.java | 6 + .../security/ClientAuthenticationDUnitTest.java | 7 +- .../security/ClientAuthorizationDUnitTest.java | 11 +- .../security/ClientAuthorizationTestBase.java | 20 +- .../security/ClientMultiUserAuthzDUnitTest.java | 5 +- .../DeltaClientAuthorizationDUnitTest.java | 5 +- .../DeltaClientPostAuthorizationDUnitTest.java | 5 +- .../security/P2PAuthenticationDUnitTest.java | 11 +- .../generator/AuthzCredentialGenerator.java | 446 ++++++++++++ .../security/generator/CredentialGenerator.java | 332 +++++++++ .../DummyAuthzCredentialGenerator.java | 129 ++++ .../generator/DummyCredentialGenerator.java | 89 +++ .../generator/LdapUserCredentialGenerator.java | 163 +++++ .../generator/PKCSCredentialGenerator.java | 115 ++++ .../generator/SSLCredentialGenerator.java | 121 ++++ .../UserPasswordWithExtraPropsAuthInit.java | 69 ++ .../generator/XmlAuthzCredentialGenerator.java | 257 +++++++ .../security/templates/DummyAuthenticator.java | 75 +++ .../security/templates/DummyAuthorization.java | 122 ++++ .../templates/FunctionSecurityPrmsHolder.java | 50 ++ .../templates/LdapUserAuthenticator.java | 106 +++ .../security/templates/PKCSAuthInit.java | 119 ++++ .../security/templates/PKCSAuthenticator.java | 157 +++++ .../security/templates/PKCSPrincipal.java | 40 ++ .../security/templates/PKCSPrincipalTest.java | 48 ++ .../templates/UserPasswordAuthInit.java | 75 +++ .../security/templates/UsernamePrincipal.java | 44 ++ .../templates/UsernamePrincipalTest.java | 48 ++ .../security/templates/XmlAuthorization.java | 614 +++++++++++++++++ .../security/templates/XmlErrorHandler.java | 74 ++ .../gemfire/test/dunit/NamedCallable.java | 1 - .../gemfire/test/dunit/NamedRunnable.java | 1 - .../java/security/AuthzCredentialGenerator.java | 462 ------------- .../test/java/security/CredentialGenerator.java | 340 ---------- .../security/DummyAuthzCredentialGenerator.java | 141 ---- .../java/security/DummyCredentialGenerator.java | 90 --- .../security/LdapUserCredentialGenerator.java | 156 ----- .../java/security/PKCSCredentialGenerator.java | 109 --- .../java/security/SSLCredentialGenerator.java | 116 ---- .../UserPasswordWithExtraPropsAuthInit.java | 74 -- .../security/XmlAuthzCredentialGenerator.java | 261 ------- .../templates/security/DummyAuthenticator.java | 84 --- .../templates/security/DummyAuthorization.java | 117 ---- .../security/FunctionSecurityPrmsHolder.java | 54 -- .../security/LdapUserAuthenticator.java | 118 ---- .../java/templates/security/PKCSAuthInit.java | 132 ---- .../templates/security/PKCSAuthenticator.java | 166 ----- .../java/templates/security/PKCSPrincipal.java | 43 -- .../templates/security/PKCSPrincipalTest.java | 48 -- .../security/UserPasswordAuthInit.java | 83 --- .../templates/security/UsernamePrincipal.java | 45 -- .../security/UsernamePrincipalTest.java | 48 -- .../templates/security/XmlAuthorization.java | 672 ------------------- .../templates/security/XmlErrorHandler.java | 81 --- .../gemfire/security/generator/authz-dummy.xml | 124 ++++ .../gemfire/security/generator/authz-ldap.xml | 83 +++ .../generator/authz-multiUser-dummy.xml | 104 +++ .../security/generator/authz-multiUser-ldap.xml | 81 +++ .../security/generator/keys/gemfire1.keystore | Bin 0 -> 1536 bytes .../security/generator/keys/gemfire10.keystore | Bin 0 -> 1546 bytes .../security/generator/keys/gemfire11.keystore | Bin 0 -> 1546 bytes .../security/generator/keys/gemfire2.keystore | Bin 0 -> 1536 bytes .../security/generator/keys/gemfire3.keystore | Bin 0 -> 1536 bytes .../security/generator/keys/gemfire4.keystore | Bin 0 -> 1536 bytes .../security/generator/keys/gemfire5.keystore | Bin 0 -> 1536 bytes .../security/generator/keys/gemfire6.keystore | Bin 0 -> 1536 bytes .../security/generator/keys/gemfire7.keystore | Bin 0 -> 1536 bytes .../security/generator/keys/gemfire8.keystore | Bin 0 -> 1536 bytes .../security/generator/keys/gemfire9.keystore | Bin 0 -> 1536 bytes .../generator/keys/ibm/gemfire1.keystore | Bin 0 -> 1426 bytes .../generator/keys/ibm/gemfire10.keystore | Bin 0 -> 1434 bytes .../generator/keys/ibm/gemfire11.keystore | Bin 0 -> 1434 bytes .../generator/keys/ibm/gemfire2.keystore | Bin 0 -> 1434 bytes .../generator/keys/ibm/gemfire3.keystore | Bin 0 -> 1426 bytes .../generator/keys/ibm/gemfire4.keystore | Bin 0 -> 1434 bytes .../generator/keys/ibm/gemfire5.keystore | Bin 0 -> 1434 bytes .../generator/keys/ibm/gemfire6.keystore | Bin 0 -> 1434 bytes .../generator/keys/ibm/gemfire7.keystore | Bin 0 -> 1426 bytes .../generator/keys/ibm/gemfire8.keystore | Bin 0 -> 1434 bytes .../generator/keys/ibm/gemfire9.keystore | Bin 0 -> 1426 bytes .../security/generator/keys/ibm/publickeyfile | Bin 0 -> 4535 bytes .../security/generator/keys/publickeyfile | Bin 0 -> 4535 bytes .../gemfire/security/templates/authz5_5.dtd | 105 +++ .../gemfire/security/templates/authz6_0.dtd | 110 +++ .../src/test/resources/lib/authz-dummy.xml | 126 ---- .../src/test/resources/lib/authz-ldap.xml | 85 --- .../resources/lib/authz-multiUser-dummy.xml | 106 --- .../test/resources/lib/authz-multiUser-ldap.xml | 83 --- .../test/resources/lib/keys/gemfire1.keystore | Bin 1536 -> 0 bytes .../test/resources/lib/keys/gemfire10.keystore | Bin 1546 -> 0 bytes .../test/resources/lib/keys/gemfire11.keystore | Bin 1546 -> 0 bytes .../test/resources/lib/keys/gemfire2.keystore | Bin 1536 -> 0 bytes .../test/resources/lib/keys/gemfire3.keystore | Bin 1536 -> 0 bytes .../test/resources/lib/keys/gemfire4.keystore | Bin 1536 -> 0 bytes .../test/resources/lib/keys/gemfire5.keystore | Bin 1536 -> 0 bytes .../test/resources/lib/keys/gemfire6.keystore | Bin 1536 -> 0 bytes .../test/resources/lib/keys/gemfire7.keystore | Bin 1536 -> 0 bytes .../test/resources/lib/keys/gemfire8.keystore | Bin 1536 -> 0 bytes .../test/resources/lib/keys/gemfire9.keystore | Bin 1536 -> 0 bytes .../resources/lib/keys/ibm/gemfire1.keystore | Bin 1426 -> 0 bytes .../resources/lib/keys/ibm/gemfire10.keystore | Bin 1434 -> 0 bytes .../resources/lib/keys/ibm/gemfire11.keystore | Bin 1434 -> 0 bytes .../resources/lib/keys/ibm/gemfire2.keystore | Bin 1434 -> 0 bytes .../resources/lib/keys/ibm/gemfire3.keystore | Bin 1426 -> 0 bytes .../resources/lib/keys/ibm/gemfire4.keystore | Bin 1434 -> 0 bytes .../resources/lib/keys/ibm/gemfire5.keystore | Bin 1434 -> 0 bytes .../resources/lib/keys/ibm/gemfire6.keystore | Bin 1434 -> 0 bytes .../resources/lib/keys/ibm/gemfire7.keystore | Bin 1426 -> 0 bytes .../resources/lib/keys/ibm/gemfire8.keystore | Bin 1434 -> 0 bytes .../resources/lib/keys/ibm/gemfire9.keystore | Bin 1426 -> 0 bytes .../test/resources/lib/keys/ibm/publickeyfile | Bin 4535 -> 0 bytes .../src/test/resources/lib/keys/publickeyfile | Bin 4535 -> 0 bytes .../resources/templates/security/authz5_5.dtd | 105 --- .../resources/templates/security/authz6_0.dtd | 110 --- .../security/ClientAuthzObjectModDUnitTest.java | 16 +- .../ClientCQPostAuthorizationDUnitTest.java | 5 +- .../ClientPostAuthorizationDUnitTest.java | 4 +- .../gemfire/security/MultiuserAPIDUnitTest.java | 6 +- .../MultiuserDurableCQAuthzDUnitTest.java | 7 +- 121 files changed, 4047 insertions(+), 4240 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java index ba35e46..741eb2c 100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java @@ -47,10 +47,13 @@ import static com.gemstone.gemfire.internal.i18n.LocalizedStrings.AUTH_FAILED_TO import static com.gemstone.gemfire.distributed.internal.DistributionConfig.SECURITY_PEER_AUTH_INIT_NAME; import static com.gemstone.gemfire.distributed.internal.DistributionConfig.SECURITY_PEER_AUTHENTICATOR_NAME; - public class GMSAuthenticator implements Authenticator { + private final static String secPrefix = "gemfire.sys.security-"; + private final static int gemfireSysPrefixLen = "gemfire.sys.".length(); + private Services services; + private Properties securityProps = getSecurityProps(); @Override public void init(Services s) { @@ -96,101 +99,113 @@ public class GMSAuthenticator implements Authenticator { /** * Authenticate peer member with authenticator class defined by property * "security-peer-authenticator". - * @param member the member to be authenticated - * @param credentials the credentials used in authentication + * + * @param member + * the member to be authenticated + * @param credentials + * the credentials used in authentication * @return null if authentication succeed (including no authenticator case), * otherwise, return failure message * @throws AuthenticationFailedException * this will be removed since return string is used for failure */ @Override - public String authenticate(InternalDistributedMember member, Object credentials) - throws AuthenticationFailedException { - return authenticate(member, credentials, securityProps, services.getJoinLeave().getMemberID()); + public String authenticate(InternalDistributedMember member, Object credentials) throws AuthenticationFailedException { + return authenticate(member, credentials, this.securityProps, this.services.getJoinLeave().getMemberID()); } - // for unit test - /* package */ String authenticate( - DistributedMember member, Object credentials, Properties secProps, DistributedMember localMember) - throws AuthenticationFailedException { + /** + * Method is package protected to be used in testing. + */ + String authenticate(DistributedMember member, Object credentials, Properties secProps, DistributedMember localMember) throws AuthenticationFailedException { String authMethod = secProps.getProperty(SECURITY_PEER_AUTHENTICATOR_NAME); if (authMethod == null || authMethod.length() == 0) { return null; } - InternalLogWriter securityLogWriter = services.getSecurityLogWriter(); + InternalLogWriter securityLogWriter = this.services.getSecurityLogWriter(); String failMsg = null; if (credentials != null) { try { invokeAuthenticator(authMethod, member, credentials); + } catch (Exception ex) { - securityLogWriter.warning( - AUTH_PEER_AUTHENTICATION_FAILED_WITH_EXCEPTION, - new Object[] {member, authMethod, ex.getLocalizedMessage()}, ex); + securityLogWriter.warning(AUTH_PEER_AUTHENTICATION_FAILED_WITH_EXCEPTION, new Object[] {member, authMethod, ex.getLocalizedMessage()}, ex); failMsg = AUTH_PEER_AUTHENTICATION_FAILED.toLocalizedString(localMember); } + } else { // No credentials - need to send failure message - securityLogWriter.warning( - AUTH_PEER_AUTHENTICATION_MISSING_CREDENTIALS, new Object[] {member, authMethod}); + securityLogWriter.warning(AUTH_PEER_AUTHENTICATION_MISSING_CREDENTIALS, new Object[] {member, authMethod}); failMsg = AUTH_PEER_AUTHENTICATION_MISSING_CREDENTIALS.toLocalizedString(member, authMethod); } + return failMsg; } - /* package */ Principal invokeAuthenticator(String authMethod, DistributedMember member, Object credentials) - throws AuthenticationFailedException { + /** + * Method is package protected to be used in testing. + */ + Principal invokeAuthenticator(String authMethod, DistributedMember member, Object credentials) throws AuthenticationFailedException { com.gemstone.gemfire.security.Authenticator auth = null; + try { Method getter = ClassLoadUtil.methodFromName(authMethod); auth = (com.gemstone.gemfire.security.Authenticator) getter.invoke(null, (Object[]) null); - if (auth == null) - throw new AuthenticationFailedException( - HandShake_AUTHENTICATOR_INSTANCE_COULD_NOT_BE_OBTAINED.toLocalizedString()); + if (auth == null) { + throw new AuthenticationFailedException(HandShake_AUTHENTICATOR_INSTANCE_COULD_NOT_BE_OBTAINED.toLocalizedString()); + } - LogWriter logWriter = services.getLogWriter(); - LogWriter securityLogWriter = services.getSecurityLogWriter(); - auth.init(securityProps, logWriter, securityLogWriter); + LogWriter logWriter = this.services.getLogWriter(); + LogWriter securityLogWriter = this.services.getSecurityLogWriter(); + + auth.init(this.securityProps, logWriter, securityLogWriter); // this.securityProps contains security-ldap-basedn but security-ldap-baseDomainName is expected return auth.authenticate((Properties) credentials, member); + } catch (GemFireSecurityException gse) { throw gse; + } catch (Exception ex) { - throw new AuthenticationFailedException( - HandShake_FAILED_TO_ACQUIRE_AUTHENTICATOR_OBJECT.toLocalizedString(), ex); + throw new AuthenticationFailedException(HandShake_FAILED_TO_ACQUIRE_AUTHENTICATOR_OBJECT.toLocalizedString(), ex); + } finally { if (auth != null) auth.close(); } } /** - * Get credential object for the given GemFire distributed member - * @param member the target distributed member + * Get credential object for the given GemFire distributed member. + * + * @param member + * the target distributed member * @return the credential object */ @Override public Object getCredentials(InternalDistributedMember member) { try { return getCredentials(member, securityProps); + } catch (Exception e) { String authMethod = securityProps.getProperty(SECURITY_PEER_AUTH_INIT_NAME); - services.getSecurityLogWriter().warning( - LocalizedStrings.AUTH_FAILED_TO_OBTAIN_CREDENTIALS_IN_0_USING_AUTHINITIALIZE_1_2, - new Object[] {authMethod, e.getLocalizedMessage()}); + services.getSecurityLogWriter().warning(LocalizedStrings.AUTH_FAILED_TO_OBTAIN_CREDENTIALS_IN_0_USING_AUTHINITIALIZE_1_2, new Object[] { authMethod, e.getLocalizedMessage() }); return null; } } - // for unit test + /** + * For testing only. + */ Properties getCredentials(DistributedMember member, Properties secProps) { Properties credentials = null; String authMethod = secProps.getProperty(SECURITY_PEER_AUTH_INIT_NAME); + try { if (authMethod != null && authMethod.length() > 0) { Method getter = ClassLoadUtil.methodFromName(authMethod); AuthInitialize auth = (AuthInitialize)getter.invoke(null, (Object[]) null); - if (auth == null) - throw new AuthenticationRequiredException( - AUTH_FAILED_TO_ACQUIRE_AUTHINITIALIZE_INSTANCE.toLocalizedString(authMethod)); + if (auth == null) { + throw new AuthenticationRequiredException(AUTH_FAILED_TO_ACQUIRE_AUTHINITIALIZE_INSTANCE.toLocalizedString(authMethod)); + } try { LogWriter logWriter = services.getLogWriter(); @@ -201,19 +216,17 @@ public class GMSAuthenticator implements Authenticator { auth.close(); } } + } catch (GemFireSecurityException gse) { throw gse; + } catch (Exception ex) { - throw new AuthenticationRequiredException( - HandShake_FAILED_TO_ACQUIRE_AUTHINITIALIZE_METHOD_0.toLocalizedString(authMethod), ex); + throw new AuthenticationRequiredException(HandShake_FAILED_TO_ACQUIRE_AUTHINITIALIZE_METHOD_0.toLocalizedString(authMethod), ex); } + return credentials; } - private final static String secPrefix = "gemfire.sys.security-"; - private final static int gemfireSysPrefixLen = "gemfire.sys.".length(); - private Properties securityProps = getSecurityProps(); - Properties getSecurityProps() { Properties props = new Properties(); Set keys = System.getProperties().keySet(); @@ -228,8 +241,5 @@ public class GMSAuthenticator implements Authenticator { @Override public void emergencyClose() { - // TODO Auto-generated method stub - } - } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/CacheServerSSLConnectionDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/CacheServerSSLConnectionDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/CacheServerSSLConnectionDUnitTest.java index 5fa4fc4..c59ed4f 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/CacheServerSSLConnectionDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/CacheServerSSLConnectionDUnitTest.java @@ -41,27 +41,25 @@ import com.gemstone.gemfire.util.test.TestUtil; /** * Tests cacheserver ssl support added. See https://svn.gemstone.com/trac/gemfire/ticket/48995 for details - * @author tushark - * */ public class CacheServerSSLConnectionDUnitTest extends DistributedTestCase { private static final long serialVersionUID = 1L; - private Cache cache; - private CacheServer cacheServer; - private ClientCache clientCache; - private int cacheServerPort; - private String hostName; - + private static final String TRUSTED_STORE = "trusted.keystore"; private static final String CLIENT_KEY_STORE = "client.keystore"; private static final String CLIENT_TRUST_STORE = "client.truststore"; private static final String SERVER_KEY_STORE = "cacheserver.keystore"; private static final String SERVER_TRUST_STORE = "cacheserver.truststore"; - + private static CacheServerSSLConnectionDUnitTest instance = new CacheServerSSLConnectionDUnitTest("CacheServerSSLConnectionDUnit"); - - + + private Cache cache; + private CacheServer cacheServer; + private ClientCache clientCache; + private int cacheServerPort; + private String hostName; + public void setUp() throws Exception { disconnectAllFromDS(); super.setUp(); @@ -224,7 +222,7 @@ public class CacheServerSSLConnectionDUnitTest extends DistributedTestCase { instance.doServerRegionTest(); } - public static Object[] getCacheServerEndPointTask() { + public static Object[] getCacheServerEndPointTask() { // TODO: avoid Object[] Object[] array = new Object[2]; array[0] = instance.getCacheServerHost(); array[1] = instance.getCacheServerPort(); @@ -252,23 +250,16 @@ public class CacheServerSSLConnectionDUnitTest extends DistributedTestCase { boolean cacheClientSslenabled = true; boolean cacheClientSslRequireAuth = true; - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.setUpServerVMTask(cacheServerSslenabled)); - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.createServerTask()); + serverVM.invoke(() -> setUpServerVMTask(cacheServerSslenabled)); + serverVM.invoke(() -> createServerTask()); - Object array[] = (Object[])serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.getCacheServerEndPointTask()); + Object array[] = (Object[])serverVM.invoke(() -> getCacheServerEndPointTask()); String hostName = (String)array[0]; int port = (Integer) array[1]; - Object params[] = new Object[6]; - params[0] = hostName; - params[1] = port; - params[2] = cacheClientSslenabled; - params[3] = cacheClientSslRequireAuth; - params[4] = CLIENT_KEY_STORE; - params[5] = CLIENT_TRUST_STORE; - //getLogWriter().info("Starting client with server endpoint " + hostName + ":" + port); - clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpClientVMTask", params); - clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doClientRegionTestTask()); - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doServerRegionTestTask()); + + clientVM.invoke(() -> setUpClientVMTask(hostName, port, cacheClientSslenabled, cacheClientSslRequireAuth, CLIENT_KEY_STORE, CLIENT_TRUST_STORE)); + clientVM.invoke(() -> doClientRegionTestTask()); + serverVM.invoke(() -> doServerRegionTestTask()); } @@ -282,27 +273,21 @@ public class CacheServerSSLConnectionDUnitTest extends DistributedTestCase { boolean cacheClientSslenabled = false; boolean cacheClientSslRequireAuth = true; - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.setUpServerVMTask(cacheServerSslenabled)); - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.createServerTask()); + serverVM.invoke(() -> setUpServerVMTask(cacheServerSslenabled)); + serverVM.invoke(() -> createServerTask()); - Object array[] = (Object[])serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.getCacheServerEndPointTask()); + Object array[] = (Object[])serverVM.invoke(() -> getCacheServerEndPointTask()); String hostName = (String)array[0]; int port = (Integer) array[1]; - Object params[] = new Object[6]; - params[0] = hostName; - params[1] = port; - params[2] = cacheClientSslenabled; - params[3] = cacheClientSslRequireAuth; - params[4] = TRUSTED_STORE; - params[5] = TRUSTED_STORE; + IgnoredException expect = IgnoredException.addIgnoredException("javax.net.ssl.SSLException", serverVM); IgnoredException expect2 = IgnoredException.addIgnoredException("IOException", serverVM); try{ - //getLogWriter().info("Starting client with server endpoint " + hostName + ":" + port); - clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpClientVMTaskNoSubscription", params); - clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doClientRegionTestTask()); - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doServerRegionTestTask()); + clientVM.invoke(() -> setUpClientVMTaskNoSubscription(hostName, port, cacheClientSslenabled, cacheClientSslRequireAuth, TRUSTED_STORE, TRUSTED_STORE)); + clientVM.invoke(() -> doClientRegionTestTask()); + serverVM.invoke(() -> doServerRegionTestTask()); fail("Test should fail as non-ssl client is trying to connect to ssl configured server"); + } catch (Exception rmiException) { Throwable e = rmiException.getCause(); //getLogWriter().info("ExceptionCause at clientVM " + e); @@ -330,24 +315,18 @@ public class CacheServerSSLConnectionDUnitTest extends DistributedTestCase { boolean cacheClientSslenabled = true; boolean cacheClientSslRequireAuth = false; - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.setUpServerVMTask(cacheServerSslenabled)); - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.createServerTask()); + serverVM.invoke(() -> setUpServerVMTask(cacheServerSslenabled)); + serverVM.invoke(() -> createServerTask()); - Object array[] = (Object[])serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.getCacheServerEndPointTask()); + Object array[] = (Object[])serverVM.invoke(() -> getCacheServerEndPointTask()); String hostName = (String)array[0]; int port = (Integer) array[1]; - Object params[] = new Object[6]; - params[0] = hostName; - params[1] = port; - params[2] = cacheClientSslenabled; - params[3] = cacheClientSslRequireAuth; - params[4] = CLIENT_KEY_STORE; - params[5] = CLIENT_TRUST_STORE; - //getLogWriter().info("Starting client with server endpoint " + hostName + ":" + port); + try { - clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpClientVMTask", params); + clientVM.invoke(() -> setUpClientVMTask(hostName, port, cacheClientSslenabled, cacheClientSslRequireAuth, CLIENT_KEY_STORE, CLIENT_TRUST_STORE)); clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doClientRegionTestTask()); serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doServerRegionTestTask()); + } catch (Exception rmiException) { Throwable e = rmiException.getCause(); //getLogWriter().info("ExceptionCause at clientVM " + e); @@ -372,41 +351,22 @@ public class CacheServerSSLConnectionDUnitTest extends DistributedTestCase { boolean cacheClientSslenabled = true; boolean cacheClientSslRequireAuth = true; - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.setUpServerVMTask(cacheServerSslenabled)); - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.createServerTask()); + serverVM.invoke(() -> setUpServerVMTask(cacheServerSslenabled)); + serverVM.invoke(() -> createServerTask()); - Object array[] = (Object[])serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.getCacheServerEndPointTask()); + Object array[] = (Object[])serverVM.invoke(() -> getCacheServerEndPointTask()); String hostName = (String)array[0]; int port = (Integer) array[1]; - Object params[] = new Object[6]; - params[0] = hostName; - params[1] = port; - params[2] = cacheClientSslenabled; - params[3] = cacheClientSslRequireAuth; - params[4] = TRUSTED_STORE; - params[5] = TRUSTED_STORE; + IgnoredException expect = IgnoredException.addIgnoredException("javax.net.ssl.SSLHandshakeException", serverVM); try{ - //getLogWriter().info("Starting client with server endpoint " + hostName + ":" + port); - clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpClientVMTask", params); - clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doClientRegionTestTask()); - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doServerRegionTestTask()); + clientVM.invoke(() -> setUpClientVMTask(hostName, port, cacheClientSslenabled, cacheClientSslRequireAuth, TRUSTED_STORE, TRUSTED_STORE)); + clientVM.invoke(() -> doClientRegionTestTask()); + serverVM.invoke(() -> doServerRegionTestTask()); fail("Test should fail as ssl client with ssl enabled is trying to connect to server with ssl disabled"); - }catch (Exception rmiException) { - + + } catch (Exception rmiException) { //ignore - - /*Throwable e = rmiException.getCause(); - getLogWriter().info("ExceptionCause at clientVM " + e); - if (e instanceof com.gemstone.gemfire.cache.client.ServerOperationException) { - Throwable t = e.getCause(); - getLogWriter().info("Cause is " + t); - assertTrue(t instanceof com.gemstone.gemfire.security.AuthenticationRequiredException); - } else { - getLogWriter().error("Unexpected exception ", e); - fail("Unexpected Exception...expected " - + AuthenticationRequiredException.class); - }*/ } finally { expect.remove(); } @@ -417,8 +377,8 @@ public class CacheServerSSLConnectionDUnitTest extends DistributedTestCase { final Host host = Host.getHost(0); VM serverVM = host.getVM(1); VM clientVM = host.getVM(2); - clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.closeClientCacheTask()); - serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.closeCacheTask()); + clientVM.invoke(() -> closeClientCacheTask()); + serverVM.invoke(() -> closeCacheTask()); } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/DurableClientBug39997DUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/DurableClientBug39997DUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/DurableClientBug39997DUnitTest.java index fb8fb3e..fb425c1 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/DurableClientBug39997DUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/DurableClientBug39997DUnitTest.java @@ -32,6 +32,7 @@ import com.gemstone.gemfire.cache30.CacheTestCase; import com.gemstone.gemfire.internal.AvailablePortHelper; import com.gemstone.gemfire.test.dunit.Assert; import com.gemstone.gemfire.test.dunit.Host; +import com.gemstone.gemfire.test.dunit.Invoke; import com.gemstone.gemfire.test.dunit.NetworkUtils; import com.gemstone.gemfire.test.dunit.SerializableRunnable; import com.gemstone.gemfire.test.dunit.VM; @@ -45,6 +46,10 @@ public class DurableClientBug39997DUnitTest extends CacheTestCase { public DurableClientBug39997DUnitTest(String name) { super(name); } + + public final void postTearDownCacheTestCase() { + Host.getHost(0) .getVM(0).invoke(() -> disconnectFromDS()); + } public void testNoServerAvailableOnStartup() { Host host = Host.getHost(0); @@ -120,6 +125,7 @@ public class DurableClientBug39997DUnitTest extends CacheTestCase { public Properties getClientProperties() { Properties props = new Properties(); props.setProperty("mcast-port", "0"); + props.setProperty("locators", ""); props.setProperty("durable-client-id", "my_id"); return props; } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthenticationDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthenticationDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthenticationDUnitTest.java index 8446eae..739dd42 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthenticationDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthenticationDUnitTest.java @@ -24,12 +24,13 @@ import java.util.Properties; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; -import security.CredentialGenerator; -import security.CredentialGenerator.ClassCode; +import com.gemstone.gemfire.security.generator.CredentialGenerator; +import com.gemstone.gemfire.security.generator.CredentialGenerator.ClassCode; import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.distributed.internal.DistributionConfig; import com.gemstone.gemfire.internal.AvailablePort; +import com.gemstone.gemfire.security.generator.DummyCredentialGenerator; import com.gemstone.gemfire.test.dunit.DistributedTestCase; import com.gemstone.gemfire.test.dunit.Host; import com.gemstone.gemfire.test.dunit.IgnoredException; @@ -37,8 +38,6 @@ import com.gemstone.gemfire.test.dunit.LogWriterUtils; import com.gemstone.gemfire.test.dunit.VM; import com.gemstone.gemfire.test.dunit.Wait; -import security.DummyCredentialGenerator; - /** * Test for authentication from client to server. This tests for both valid and * invalid credentials/modules. It also checks for authentication http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java index 1d0b481..e3d8ccf 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java @@ -26,19 +26,18 @@ import java.util.Iterator; import java.util.List; import java.util.Properties; -import security.AuthzCredentialGenerator; -import security.CredentialGenerator; -import security.DummyCredentialGenerator; -import security.XmlAuthzCredentialGenerator; - import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode; import com.gemstone.gemfire.internal.AvailablePort; +import com.gemstone.gemfire.security.generator.AuthzCredentialGenerator; +import com.gemstone.gemfire.security.generator.CredentialGenerator; +import com.gemstone.gemfire.security.generator.DummyCredentialGenerator; +import com.gemstone.gemfire.security.generator.XmlAuthzCredentialGenerator; import com.gemstone.gemfire.test.dunit.Host; import com.gemstone.gemfire.test.dunit.IgnoredException; import com.gemstone.gemfire.test.dunit.LogWriterUtils; import com.gemstone.gemfire.test.dunit.VM; -import templates.security.UserPasswordAuthInit; +import com.gemstone.gemfire.security.templates.UserPasswordAuthInit; /** * Tests for authorization from client to server. This tests for authorization http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationTestBase.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationTestBase.java b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationTestBase.java index 8476ae2..c7eed57 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationTestBase.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationTestBase.java @@ -1,6 +1,3 @@ - -package com.gemstone.gemfire.security; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -9,9 +6,9 @@ package com.gemstone.gemfire.security; * 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 @@ -19,7 +16,7 @@ package com.gemstone.gemfire.security; * specific language governing permissions and limitations * under the License. */ - +package com.gemstone.gemfire.security; import java.util.ArrayList; import java.util.HashMap; @@ -55,18 +52,17 @@ import com.gemstone.gemfire.internal.AvailablePort.Keeper; import com.gemstone.gemfire.internal.cache.AbstractRegionEntry; import com.gemstone.gemfire.internal.cache.LocalRegion; import com.gemstone.gemfire.internal.util.Callable; +import com.gemstone.gemfire.security.generator.AuthzCredentialGenerator; +import com.gemstone.gemfire.security.generator.AuthzCredentialGenerator.ClassCode; +import com.gemstone.gemfire.security.generator.CredentialGenerator; +import com.gemstone.gemfire.security.generator.DummyCredentialGenerator; +import com.gemstone.gemfire.security.generator.XmlAuthzCredentialGenerator; import com.gemstone.gemfire.test.dunit.Assert; import com.gemstone.gemfire.test.dunit.DistributedTestCase; import com.gemstone.gemfire.test.dunit.VM; import com.gemstone.gemfire.test.dunit.Wait; import com.gemstone.gemfire.test.dunit.WaitCriterion; -import security.AuthzCredentialGenerator; -import security.AuthzCredentialGenerator.ClassCode; -import security.CredentialGenerator; -import security.DummyCredentialGenerator; -import security.XmlAuthzCredentialGenerator; - /** * Base class for tests for authorization from client to server. It contains * utility functions for the authorization tests from client to server. http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java index dc03990..325f0bb 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java @@ -24,14 +24,13 @@ package com.gemstone.gemfire.security; import java.util.Iterator; import java.util.Properties; +import com.gemstone.gemfire.security.generator.AuthzCredentialGenerator; +import com.gemstone.gemfire.security.generator.CredentialGenerator; import com.gemstone.gemfire.test.dunit.VM; -import security.AuthzCredentialGenerator; -import security.CredentialGenerator; import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.execute.Function; import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode; -import com.gemstone.gemfire.internal.AvailablePort; import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; import com.gemstone.gemfire.internal.cache.execute.PRClientServerTestBase; import com.gemstone.gemfire.internal.cache.functions.TestFunction; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientAuthorizationDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientAuthorizationDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientAuthorizationDUnitTest.java index 5c184d1..a7d6131 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientAuthorizationDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientAuthorizationDUnitTest.java @@ -23,15 +23,14 @@ package com.gemstone.gemfire.security; import java.util.Properties; -import security.AuthzCredentialGenerator; -import security.CredentialGenerator; - import com.gemstone.gemfire.DeltaTestImpl; import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.client.NoAvailableServersException; import com.gemstone.gemfire.cache.client.ServerConnectivityException; import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode; import com.gemstone.gemfire.internal.cache.PartitionedRegionLocalMaxMemoryDUnitTest.TestObject1; +import com.gemstone.gemfire.security.generator.AuthzCredentialGenerator; +import com.gemstone.gemfire.security.generator.CredentialGenerator; import com.gemstone.gemfire.test.dunit.Assert; import com.gemstone.gemfire.test.dunit.Host; import com.gemstone.gemfire.test.dunit.LogWriterUtils; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientPostAuthorizationDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientPostAuthorizationDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientPostAuthorizationDUnitTest.java index ec1c692..090b96a 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientPostAuthorizationDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/DeltaClientPostAuthorizationDUnitTest.java @@ -28,9 +28,6 @@ import java.util.Map; import java.util.Properties; import java.util.Random; -import security.AuthzCredentialGenerator; -import security.CredentialGenerator; - import com.gemstone.gemfire.DeltaTestImpl; import com.gemstone.gemfire.cache.InterestResultPolicy; import com.gemstone.gemfire.cache.Region; @@ -40,6 +37,8 @@ import com.gemstone.gemfire.cache.query.CqException; import com.gemstone.gemfire.cache.query.QueryInvocationTargetException; import com.gemstone.gemfire.internal.AvailablePort; import com.gemstone.gemfire.internal.util.Callable; +import com.gemstone.gemfire.security.generator.AuthzCredentialGenerator; +import com.gemstone.gemfire.security.generator.CredentialGenerator; import com.gemstone.gemfire.test.dunit.Assert; import com.gemstone.gemfire.test.dunit.Host; import com.gemstone.gemfire.test.dunit.IgnoredException; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/P2PAuthenticationDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/P2PAuthenticationDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/P2PAuthenticationDUnitTest.java index d47b1c4..3af4e14 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/P2PAuthenticationDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/P2PAuthenticationDUnitTest.java @@ -26,10 +26,6 @@ import java.util.Properties; import javax.net.ssl.SSLHandshakeException; -import security.CredentialGenerator; -import security.DummyCredentialGenerator; -import security.LdapUserCredentialGenerator; - import com.gemstone.gemfire.LogWriter; import com.gemstone.gemfire.distributed.DistributedSystem; import com.gemstone.gemfire.distributed.Locator; @@ -38,6 +34,10 @@ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem; import com.gemstone.gemfire.distributed.internal.membership.MembershipManager; import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper; import com.gemstone.gemfire.internal.AvailablePort; +import com.gemstone.gemfire.security.generator.CredentialGenerator; +import com.gemstone.gemfire.security.generator.DummyCredentialGenerator; +import com.gemstone.gemfire.security.generator.LdapUserCredentialGenerator; +import com.gemstone.gemfire.security.generator.UserPasswordWithExtraPropsAuthInit; import com.gemstone.gemfire.test.dunit.DistributedTestCase; import com.gemstone.gemfire.test.dunit.Host; import com.gemstone.gemfire.test.dunit.IgnoredException; @@ -46,6 +46,7 @@ import com.gemstone.gemfire.test.dunit.NetworkUtils; import com.gemstone.gemfire.test.dunit.VM; import com.gemstone.gemfire.test.dunit.Wait; + /** * Tests peer to peer authentication in Gemfire * @@ -497,7 +498,7 @@ public class P2PAuthenticationDUnitTest extends DistributedTestCase { gen.init(); Properties extraProps = gen.getSystemProperties(); String authenticator = gen.getAuthenticator(); - String authInit = "security.UserPasswordWithExtraPropsAuthInit.create"; + String authInit = UserPasswordWithExtraPropsAuthInit.class.getName() + ".create"; if (extraProps == null) { extraProps = new Properties(); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/generator/AuthzCredentialGenerator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/generator/AuthzCredentialGenerator.java b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/AuthzCredentialGenerator.java new file mode 100755 index 0000000..f39fc84 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/AuthzCredentialGenerator.java @@ -0,0 +1,446 @@ +/* + * 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.security.generator; + +import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode; +import com.gemstone.gemfire.internal.logging.LogService; +import com.gemstone.gemfire.security.AccessControl; +import com.gemstone.gemfire.security.templates.DummyAuthorization; +import com.gemstone.gemfire.security.templates.XmlAuthorization; +import org.apache.logging.log4j.Logger; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Encapsulates obtaining authorized and unauthorized credentials for a given + * operation in a region. Implementations will be for different kinds of + * authorization scheme and authentication scheme combos. + * + * @since 5.5 + */ +public abstract class AuthzCredentialGenerator { + + private static final Logger logger = LogService.getLogger(); + + /** + * The {@link CredentialGenerator} being used. + */ + protected CredentialGenerator generator; + + /** + * A set of system properties that should be added to the gemfire system + * properties before using the authorization module. + */ + private Properties systemProperties; + + /** + * A factory method to create a new instance of an + * {@link AuthzCredentialGenerator} for the given {@link ClassCode}. Caller + * is supposed to invoke {@link AuthzCredentialGenerator#init} immediately + * after obtaining the instance. + * + * @param classCode + * the {@code ClassCode} of the {@code AuthzCredentialGenerator} + * implementation + * + * @return an instance of {@code AuthzCredentialGenerator} for the given + * class code + */ + public static AuthzCredentialGenerator create(final ClassCode classCode) { + switch (classCode.classType) { + case ClassCode.ID_DUMMY: + return new DummyAuthzCredentialGenerator(); + case ClassCode.ID_XML: + return new XmlAuthzCredentialGenerator(); + default: + return null; + } + } + + /** + * Initialize the authorized credential generator. + * + * @param generator + * an instance of {@link CredentialGenerator} of the credential + * implementation for which to obtain authorized/unauthorized + * credentials. + * + * @return false when the given {@link CredentialGenerator} is incompatible + * with this authorization module. + */ + public boolean init(final CredentialGenerator generator) { + this.generator = generator; + try { + this.systemProperties = init(); + } catch (IllegalArgumentException ex) { + return false; + } + return true; + } + + /** + * + * @return A set of extra properties that should be added to Gemfire system + * properties when not null. + */ + public Properties getSystemProperties() { + return this.systemProperties; + } + + /** + * Get the {@link CredentialGenerator} being used by this instance. + */ + public CredentialGenerator getCredentialGenerator() { + return this.generator; + } + + /** + * Initialize the authorized credential generator. + * + * Required to be implemented by concrete classes that implement this abstract + * class. + * + * @return A set of extra properties that should be added to Gemfire system + * properties when not null. + * + * @throws IllegalArgumentException when the {@link CredentialGenerator} is + * incompatible with this authorization module. + */ + protected abstract Properties init() throws IllegalArgumentException; + + /** + * The {@link ClassCode} of the particular implementation. + * + * @return the {@code ClassCode} + */ + public abstract ClassCode classCode(); + + /** + * The name of the {@link AccessControl} factory function that should be used + * as the authorization module on the server side. + * + * @return name of the {@code AccessControl} factory function + */ + public abstract String getAuthorizationCallback(); + + /** + * Get a set of credentials generated using the given index allowed to perform + * the given {@link OperationCode}s for the given regions. + * + * @param opCodes + * the list of {@link OperationCode}s of the operations requiring + * authorization; should not be null + * @param regionNames + * list of the region names requiring authorization; a value of + * null indicates all regions + * @param index + * used to generate multiple such credentials by passing different + * values for this + * + * @return the set of credentials authorized to perform the given operation in + * the given regions + */ + public Properties getAllowedCredentials(final OperationCode[] opCodes, final String[] regionNames, final int index) { + int numTries = getNumPrincipalTries(opCodes, regionNames); + if (numTries <= 0) { + numTries = 1; + } + + for (int tries = 0; tries < numTries; tries++) { + final Principal principal = getAllowedPrincipal(opCodes, regionNames, (index + tries) % numTries); + try { + return this.generator.getValidCredentials(principal); + } catch (IllegalArgumentException ex) { + } + } + return null; + } + + /** + * Get a set of credentials generated using the given index not allowed to + * perform the given {@link OperationCode}s for the given regions. The + * credentials are required to be valid for authentication. + * + * @param opCodes + * the {@link OperationCode}s of the operations requiring + * authorization failure; should not be null + * @param regionNames + * list of the region names requiring authorization failure; a value + * of null indicates all regions + * @param index + * used to generate multiple such credentials by passing different + * values for this + * + * @return the set of credentials that are not authorized to perform the given + * operation in the given region + */ + public Properties getDisallowedCredentials(final OperationCode[] opCodes, final String[] regionNames, final int index) { + // This may not be very correct since we use the value of + // getNumPrincipalTries() but is used to avoid adding another method. + // Also something like getNumDisallowedPrincipals() will be normally always + // infinite, and the number here is just to perform some number of tries + // before giving up. + + int numTries = getNumPrincipalTries(opCodes, regionNames); + if (numTries <= 0) { + numTries = 1; + } + + for (int tries = 0; tries < numTries; tries++) { + final Principal principal = getDisallowedPrincipal(opCodes, regionNames, (index + tries) % numTries); + try { + return this.generator.getValidCredentials(principal); + } catch (IllegalArgumentException ex) { + } + } + return null; + } + + /** + * Get the number of tries to be done for obtaining valid credentials for the + * given operations in the given region. It is required that + * {@link #getAllowedPrincipal} method returns valid principals for values of + * {@code index} from 0 through (n-1) where {@code n} is the + * value returned by this method. It is recommended that the principals so + * returned be unique for efficiency. + * + * This will be used by {@link #getAllowedCredentials} to step through + * different principals and obtain a set of valid credentials. + * + * Required to be implemented by concrete classes that implement this abstract + * class. + * + * @param opCodes + * the {@link OperationCode}s of the operations requiring + * authorization + * @param regionNames + * list of the region names requiring authorization; a value of null + * indicates all regions + * + * @return the number of principals allowed to perform the given operation in + * the given region + */ + protected abstract int getNumPrincipalTries(final OperationCode[] opCodes, final String[] regionNames); + + /** + * Get a {@link Principal} generated using the given index allowed to perform + * the given {@link OperationCode}s for the given region. + * + * Required to be implemented by concrete classes that implement this abstract + * class. + * + * @param opCodes + * the {@link OperationCode}s of the operations requiring + * authorization + * @param regionNames + * list of the region names requiring authorization; a value of null + * indicates all regions + * @param index + * used to generate multiple such principals by passing different + * values for this + * + * @return the {@link Principal} authorized to perform the given operation in + * the given region + */ + protected abstract Principal getAllowedPrincipal(final OperationCode[] opCodes, final String[] regionNames, final int index); + + /** + * Get a {@link Principal} generated using the given index not allowed to + * perform the given {@link OperationCode}s for the given region. + * + * Required to be implemented by concrete classes that implement this abstract + * class. + * + * @param opCodes + * the {@link OperationCode}s of the operations requiring + * authorization failure + * @param regionNames + * list of the region names requiring authorization failure; a value + * of null indicates all regions + * @param index + * used to generate multiple such principals by passing different + * values for this + * + * @return a {@link Principal} not authorized to perform the given operation + * in the given region + */ + protected abstract Principal getDisallowedPrincipal(final OperationCode[] opCodes, final String[] regionNames, final int index); + + /** + * Enumeration for various {@link AuthzCredentialGenerator} implementations. + * + * <p>The following schemes are supported as of now: + * <ul> + * <li>{@code DummyAuthorization} with {@code DummyAuthenticator}</li> + * <li>{@code XMLAuthorization} with {@code DummyAuthenticator}</li> + * <li>{@code XMLAuthorization} with {@code LDAPAuthenticator}</li> + * <li>{@code XMLAuthorization} with {@code PKCSAuthenticator}</li> + * <li>{@code XMLAuthorization} when using SSL sockets</li> + * </ul> + * + * <p>To add a new authorization scheme the following needs to be done: + * <ul> + * <li>Add implementation for {@link AccessControl}.</li> + * <li>Choose the authentication schemes that it shall work with from + * {@link CredentialGenerator.ClassCode}</li> + * <li>Add a new enumeration value for the scheme in this class. Notice the + * size of {@code VALUES} array and increase that if it is getting + * overflowed. Note the methods and fields for existing schemes and add for + * the new one in a similar manner.</li> + * <li>Add an implementation for {@link AuthzCredentialGenerator}. Note the + * {@link AuthzCredentialGenerator#init} method where different authentication + * schemes can be passed and initialize differently for the authentication + * schemes that shall be handled.</li> + * <li>Modify the {@link AuthzCredentialGenerator#create} method to add + * creation of an instance of the new implementation for the + * {@code ClassCode} enumeration value.</li> + * </ul> + * + * <p>All dunit tests will automagically start testing the new implementation + * after this. + * + * @since 5.5 + */ + public static final class ClassCode { + + private static byte nextOrdinal = 0; + + private static final byte ID_DUMMY = 1; + private static final byte ID_XML = 2; + + private static final ClassCode[] VALUES = new ClassCode[10]; + private static final Map CODE_NAME_MAP = new HashMap(); + + public static final ClassCode DUMMY = new ClassCode(DummyAuthorization.class.getName() + ".create", ID_DUMMY); + public static final ClassCode XML = new ClassCode(XmlAuthorization.class.getName() + ".create", ID_XML); + + /** The name of this class. */ + private final String name; + + /** byte used as ordinal to represent this class */ + private final byte ordinal; + + /** + * One of the following: ID_DUMMY, ID_LDAP, ID_PKI + */ + private final byte classType; + + /** Creates a new instance of class code. */ + private ClassCode(final String name, final byte classType) { + this.name = name; + this.classType = classType; + this.ordinal = nextOrdinal++; + VALUES[this.ordinal] = this; + CODE_NAME_MAP.put(name, this); + } + + public boolean isDummy() { + return this.classType == ID_DUMMY; + } + + public boolean isXml() { + return this.classType == ID_XML; + } + + /** + * Returns the {@code ClassCode} represented by specified ordinal. + */ + public static ClassCode fromOrdinal(final byte ordinal) { + return VALUES[ordinal]; + } + + /** + * Returns the {@code ClassCode} represented by specified string. + */ + public static ClassCode parse(final String operationName) { + return (ClassCode) CODE_NAME_MAP.get(operationName); + } + + /** + * Returns all the possible values. + */ + public static List getAll() { + final List codes = new ArrayList(); + for (Iterator iter = CODE_NAME_MAP.values().iterator(); iter.hasNext();) { + codes.add(iter.next()); + } + return codes; + } + + /** + * Returns the ordinal for this class code. + * + * @return the ordinal of this class code. + */ + public byte toOrdinal() { + return this.ordinal; + } + + /** + * Returns a string representation for this class code. + * + * @return the name of this class code. + */ + @Override + public final String toString() { + return this.name; + } + + /** + * Indicates whether other object is same as this one. + * + * @return true if other object is same as this one. + */ + @Override + public final boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ClassCode)) { + return false; + } + final ClassCode other = (ClassCode)obj; + return other.ordinal == this.ordinal; + } + + /** + * Indicates whether other {@code ClassCode} is same as this one. + * + * @return true if other {@code ClassCode} is same as this one. + */ + public final boolean equals(final ClassCode opCode) { + return opCode != null && opCode.ordinal == this.ordinal; + } + + /** + * Returns a hash code value for this {@code ClassCode} which is the + * same as its ordinal. + * + * @return the ordinal of this {@code ClassCode}. + */ + @Override + public final int hashCode() { + return this.ordinal; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/generator/CredentialGenerator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/generator/CredentialGenerator.java b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/CredentialGenerator.java new file mode 100755 index 0000000..aee7ebb --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/CredentialGenerator.java @@ -0,0 +1,332 @@ +/* + * 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.security.generator; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import com.gemstone.gemfire.internal.logging.LogService; +import com.gemstone.gemfire.security.AuthInitialize; +import com.gemstone.gemfire.security.Authenticator; +import com.gemstone.gemfire.security.templates.DummyAuthenticator; +import com.gemstone.gemfire.security.templates.LdapUserAuthenticator; +import com.gemstone.gemfire.security.templates.PKCSAuthenticator; +import org.apache.logging.log4j.Logger; + +/** + * Encapsulates obtaining valid and invalid credentials. Implementations will be + * for different kinds of authentication schemes. + * + * @since 5.5 + */ +public abstract class CredentialGenerator { + + private static final Logger logger = LogService.getLogger(); + + /** + * A set of properties that should be added to the Gemfire system properties + * before using the authentication module. + */ + private Properties systemProperties = null; + + /** + * A set of properties that should be added to the java system properties + * before using the authentication module. + */ + protected Properties javaProperties = null; + + /** + * A factory method to create a new instance of an {@link CredentialGenerator} + * for the given {@link ClassCode}. Caller is supposed to invoke + * {@link CredentialGenerator#init} immediately after obtaining the instance. + * + * @param classCode + * the {@code ClassCode} of the {@code CredentialGenerator} + * implementation + * + * @return an instance of {@code CredentialGenerator} for the given class + * code + */ + public static CredentialGenerator create(final ClassCode classCode) { + switch (classCode.classType) { + // Removing dummy one to reduce test run times + // case ClassCode.ID_DUMMY: + // return new DummyCredentialGenerator(); + case ClassCode.ID_LDAP: + return new LdapUserCredentialGenerator(); + // case ClassCode.ID_SSL:ø + // return new SSLCredentialGenerator(); + case ClassCode.ID_PKCS: + return new PKCSCredentialGenerator(); + default: + return null; + } + } + + /** + * Initialize the credential generator. + * + * @throws IllegalArgumentException when there is a problem during + * initialization + */ + public void init() throws IllegalArgumentException { + this.systemProperties = initialize(); + logger.info("Generating CredentialGenerator with {}", this.systemProperties); + } + + /** + * @return A set of extra properties that should be added to Gemfire system + * properties when not null. + */ + public Properties getSystemProperties() { + return this.systemProperties; + } + + /** + * @return A set of extra properties that should be added to Gemfire system + * properties when not null. + */ + public Properties getJavaProperties() { + return this.javaProperties; + } + + /** + * The {@link ClassCode} of this particular implementation. + * + * @return the {@code ClassCode} + */ + public abstract ClassCode classCode(); + + /** + * The name of the {@link AuthInitialize} factory function that should be used + * in conjunction with the credentials generated by this generator. + * + * @return name of the {@code AuthInitialize} factory function + */ + public abstract String getAuthInit(); + + /** + * The name of the {@link Authenticator} factory function that should be used + * in conjunction with the credentials generated by this generator. + * + * @return name of the {@code Authenticator} factory function + */ + public abstract String getAuthenticator(); + + /** + * Get a set of valid credentials generated using the given index. + */ + public abstract Properties getValidCredentials(final int index); + + /** + * Get a set of valid credentials for the given {@link Principal}. + * + * @return credentials for the given {@code Principal} or null if none + * possible. + */ + public abstract Properties getValidCredentials(final Principal principal); + + /** + * Get a set of invalid credentials generated using the given index. + */ + public abstract Properties getInvalidCredentials(final int index); + + /** + * Initialize the credential generator. This is provided separately from the + * {@link #init()} method for convenience of implementations so that they do not + * need to store in {@link #systemProperties}. The latter is convenient for the users + * who do not need to store these properties rather can obtain it later by + * invoking {@link #getSystemProperties()} + * + * <p>Required to be implemented by concrete classes that implement this abstract + * class. + * + * @return A set of extra properties that should be added to Gemfire system + * properties when not null. + * + * @throws IllegalArgumentException when there is a problem during + * initialization + */ + protected abstract Properties initialize() throws IllegalArgumentException; + + /** + * Enumeration for various {@link CredentialGenerator} implementations. + * + * <p>The following schemes are supported as of now: + * {@code DummyAuthenticator}, {@code LdapUserAuthenticator}, + * {@code PKCSAuthenticator}. In addition SSL socket mode with mutual + * authentication is also supported. + * + * <p>To add a new authentication scheme the following needs to be done: + * <ul> + * <li>Add implementations for {@link AuthInitialize} and + * {@link Authenticator} classes for clients/peers.</li> + * <li>Add a new enumeration value for the scheme in this class. Notice the + * size of {@code VALUES} array and increase that if it is getting + * overflowed. Note the methods and fields for existing schemes and add for + * the new one in a similar manner.</li> + * <li>Add an implementation for {@link CredentialGenerator}.</li> + * <li>Modify the CredentialGenerator.Factory#create [no such Factory exists] method to add + * creation of an instance of the new implementation for the + * {@code ClassCode} enumeration value.</li> + * </ul> + * + * <p>All security dunit tests will automagically start testing the new + * implementation after this. + * + * @since 5.5 + */ + public static final class ClassCode { + + private static byte nextOrdinal = 0; + + private static final byte ID_DUMMY = 1; + private static final byte ID_LDAP = 2; + private static final byte ID_PKCS = 3; + private static final byte ID_SSL = 4; + + private static final ClassCode[] VALUES = new ClassCode[10]; + private static final Map CODE_NAME_MAP = new HashMap(); + + public static final ClassCode DUMMY = new ClassCode(DummyAuthenticator.class.getName() + ".create", ID_DUMMY); + public static final ClassCode LDAP = new ClassCode(LdapUserAuthenticator.class.getName() + ".create", ID_LDAP); + public static final ClassCode PKCS = new ClassCode(PKCSAuthenticator.class.getName() + ".create", ID_PKCS); + public static final ClassCode SSL = new ClassCode("SSL", ID_SSL); + + /** The name of this class. */ + private final String name; + + /** byte used as ordinal to represent this class */ + private final byte ordinal; + + /** + * One of the following: ID_DUMMY, ID_LDAP, ID_PKCS + */ + private final byte classType; + + /** Creates a new instance of class code. */ + private ClassCode(final String name, final byte classType) { + this.name = name; + this.classType = classType; + this.ordinal = nextOrdinal++; + VALUES[this.ordinal] = this; + CODE_NAME_MAP.put(name, this); + } + + public boolean isDummy() { + return this.classType == ID_DUMMY; + } + + public boolean isLDAP() { + return this.classType == ID_LDAP; + } + + public boolean isPKCS() { + return this.classType == ID_PKCS; + } + + public boolean isSSL() { + return this.classType == ID_SSL; + } + + /** + * Returns the {@code ClassCode} represented by specified ordinal. + */ + public static ClassCode fromOrdinal(final byte ordinal) { + return VALUES[ordinal]; + } + + /** + * Returns the {@code ClassCode} represented by specified string. + */ + public static ClassCode parse(final String operationName) { + return (ClassCode) CODE_NAME_MAP.get(operationName); + } + + /** + * Returns all the possible values. + */ + public static List getAll() { + final List codes = new ArrayList(); + for (Iterator iter = CODE_NAME_MAP.values().iterator(); iter.hasNext();) { + codes.add(iter.next()); + } + return codes; + } + + /** + * Returns the ordinal for this operation code. + * + * @return the ordinal of this operation. + */ + public byte toOrdinal() { + return this.ordinal; + } + + /** + * Returns a string representation for this operation. + * + * @return the name of this operation. + */ + @Override + public final String toString() { + return this.name; + } + + /** + * Indicates whether other object is same as this one. + * + * @return true if other object is same as this one. + */ + @Override + public final boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ClassCode)) { + return false; + } + final ClassCode other = (ClassCode)obj; + return other.ordinal == this.ordinal; + } + + /** + * Indicates whether other {@code ClassCode} is same as this one. + * + * @return true if other {@code ClassCode} is same as this one. + */ + public final boolean equals(final ClassCode opCode) { + return opCode != null && opCode.ordinal == this.ordinal; + } + + /** + * Returns a hash code value for this {@code ClassCode} which is the + * same as its ordinal. + * + * @return the ordinal of this operation. + */ + @Override + public final int hashCode() { + return this.ordinal; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/generator/DummyAuthzCredentialGenerator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/generator/DummyAuthzCredentialGenerator.java b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/DummyAuthzCredentialGenerator.java new file mode 100755 index 0000000..64fb84a --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/DummyAuthzCredentialGenerator.java @@ -0,0 +1,129 @@ +/* + * 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.security.generator; + +import java.security.Principal; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode; +import com.gemstone.gemfire.security.templates.DummyAuthorization; +import com.gemstone.gemfire.security.templates.UsernamePrincipal; + +public class DummyAuthzCredentialGenerator extends AuthzCredentialGenerator { + + public static final byte READER_ROLE = 1; + public static final byte WRITER_ROLE = 2; + public static final byte ADMIN_ROLE = 3; + + private static Set readerOpsSet; + private static Set writerOpsSet; + + static { + readerOpsSet = new HashSet(); + for (int index = 0; index < DummyAuthorization.READER_OPS.length; index++) { + readerOpsSet.add(DummyAuthorization.READER_OPS[index]); + } + + writerOpsSet = new HashSet(); + for (int index = 0; index < DummyAuthorization.WRITER_OPS.length; index++) { + writerOpsSet.add(DummyAuthorization.WRITER_OPS[index]); + } + } + + public static byte getRequiredRole(final OperationCode[] opCodes) { + byte roleType = ADMIN_ROLE; + boolean requiresReader = true; + boolean requiresWriter = true; + + for (int opNum = 0; opNum < opCodes.length; opNum++) { + if (requiresReader && !readerOpsSet.contains(opCodes[opNum])) { + requiresReader = false; + } + if (requiresWriter && !writerOpsSet.contains(opCodes[opNum])) { + requiresWriter = false; + } + } + if (requiresReader) { + roleType = READER_ROLE; + } + else if (requiresWriter) { + roleType = WRITER_ROLE; + } + return roleType; + } + + @Override + protected Properties init() throws IllegalArgumentException { + if (!this.generator.classCode().isDummy()) { + throw new IllegalArgumentException("DummyAuthorization module only works with DummyAuthenticator"); + } + return null; + } + + @Override + public ClassCode classCode() { + return ClassCode.DUMMY; + } + + @Override + public String getAuthorizationCallback() { + return DummyAuthorization.class.getName() + ".create"; + } + + @Override + protected Principal getAllowedPrincipal(final OperationCode[] opCodes, final String[] regionNames, final int index) { + final byte roleType = getRequiredRole(opCodes); + return getPrincipal(roleType, index); + } + + @Override + protected Principal getDisallowedPrincipal(final OperationCode[] opCodes, final String[] regionNames, final int index) { + byte roleType = getRequiredRole(opCodes); + byte disallowedRoleType; + switch (roleType) { + case READER_ROLE: + disallowedRoleType = WRITER_ROLE; + break; + case WRITER_ROLE: + disallowedRoleType = READER_ROLE; + break; + default: + disallowedRoleType = READER_ROLE; + break; + } + return getPrincipal(disallowedRoleType, index); + } + + @Override + protected int getNumPrincipalTries(final OperationCode[] opCodes, final String[] regionNames) { + return 5; + } + + private Principal getPrincipal(final byte roleType, final int index) { + String[] admins = new String[] { "root", "admin", "administrator" }; + switch (roleType) { + case READER_ROLE: + return new UsernamePrincipal("reader" + index); + case WRITER_ROLE: + return new UsernamePrincipal("writer" + index); + default: + return new UsernamePrincipal(admins[index % admins.length]); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/generator/DummyCredentialGenerator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/generator/DummyCredentialGenerator.java b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/DummyCredentialGenerator.java new file mode 100755 index 0000000..b709dbc --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/DummyCredentialGenerator.java @@ -0,0 +1,89 @@ +/* + * 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.security.generator; + +import com.gemstone.gemfire.security.templates.DummyAuthenticator; +import com.gemstone.gemfire.security.templates.UserPasswordAuthInit; + +import java.security.Principal; +import java.util.Properties; + +public class DummyCredentialGenerator extends CredentialGenerator { + + @Override + protected Properties initialize() throws IllegalArgumentException { + return null; + } + + @Override + public ClassCode classCode() { + return ClassCode.DUMMY; + } + + @Override + public String getAuthInit() { + return UserPasswordAuthInit.class.getName() + ".create"; + } + + @Override + public String getAuthenticator() { + return DummyAuthenticator.class.getName() + ".create"; + } + + @Override + public Properties getValidCredentials(final int index) { + final String[] validGroups = new String[] { "admin", "user", "reader", "writer" }; + final String[] admins = new String[] { "root", "admin", "administrator" }; + + final Properties props = new Properties(); + final int groupNum = index % validGroups.length; + + String userName; + if (groupNum == 0) { + userName = admins[index % admins.length]; + } else { + userName = validGroups[groupNum] + (index / validGroups.length); + } + + props.setProperty(UserPasswordAuthInit.USER_NAME, userName); + props.setProperty(UserPasswordAuthInit.PASSWORD, userName); + return props; + } + + @Override + public Properties getValidCredentials(final Principal principal) { + final String userName = principal.getName(); + + if (DummyAuthenticator.checkValidName(userName)) { + Properties props = new Properties(); + props.setProperty(UserPasswordAuthInit.USER_NAME, userName); + props.setProperty(UserPasswordAuthInit.PASSWORD, userName); + return props; + + } else { + throw new IllegalArgumentException("Dummy: [" + userName + "] is not a valid user"); + } + } + + @Override + public Properties getInvalidCredentials(int index) { + Properties props = new Properties(); + props.setProperty(UserPasswordAuthInit.USER_NAME, "invalid" + index); + props.setProperty(UserPasswordAuthInit.PASSWORD, "none"); + return props; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8de59df1/geode-core/src/test/java/com/gemstone/gemfire/security/generator/LdapUserCredentialGenerator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/generator/LdapUserCredentialGenerator.java b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/LdapUserCredentialGenerator.java new file mode 100755 index 0000000..bbd9528 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/generator/LdapUserCredentialGenerator.java @@ -0,0 +1,163 @@ +/* + * 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.security.generator; + +import com.gemstone.gemfire.distributed.internal.DistributionConfig; +import com.gemstone.gemfire.internal.cache.tier.sockets.HandShake; +import com.gemstone.gemfire.internal.logging.LogService; +import com.gemstone.gemfire.test.dunit.Assert; +import com.gemstone.gemfire.util.test.TestUtil; +import com.gemstone.gemfire.security.templates.LdapUserAuthenticator; +import com.gemstone.gemfire.security.templates.UserPasswordAuthInit; +import org.apache.logging.log4j.Logger; + +import java.security.Principal; +import java.util.Properties; +import java.util.Random; + +public class LdapUserCredentialGenerator extends CredentialGenerator { + + private static final Logger logger = LogService.getLogger(); + + private static final String USER_PREFIX = "gemfire"; + private static final Random RANDOM = new Random(); + private static final String[] CIPHERS = new String[] { "", "DESede", "AES:128", "Blowfish:128" }; + + private static boolean enableServerAuthentication = false; + + private boolean serverAuthEnabled = false; + + public LdapUserCredentialGenerator() { + // Toggle server authentication enabled for each test + // This is done instead of running all the tests with both + // server auth enabled/disabled to reduce test run time. + enableServerAuthentication = !enableServerAuthentication; + this.serverAuthEnabled = enableServerAuthentication; + } + + @Override + protected Properties initialize() throws IllegalArgumentException { + final String ldapServer = System.getProperty("gf.ldap.server", "ldap"); + final String ldapBaseDN = System.getProperty("gf.ldap.basedn", "ou=ldapTesting,dc=pune,dc=gemstone,dc=com"); + final String ldapUseSSL = System.getProperty("gf.ldap.usessl"); + + final Properties extraProps = new Properties(); + extraProps.setProperty(LdapUserAuthenticator.LDAP_SERVER_NAME, ldapServer); + extraProps.setProperty(LdapUserAuthenticator.LDAP_BASEDN_NAME, ldapBaseDN); + + if (ldapUseSSL != null && ldapUseSSL.length() > 0) { + extraProps.setProperty(LdapUserAuthenticator.LDAP_SSL_NAME, ldapUseSSL); + } + + if (serverAuthEnabled) { + String keyStoreFile = TestUtil.getResourcePath(LdapUserCredentialGenerator.class, PKCSCredentialGenerator.keyStoreDir + "/gemfire1.keystore"); + extraProps.setProperty(HandShake.PRIVATE_KEY_FILE_PROP, keyStoreFile); + extraProps.setProperty(HandShake.PRIVATE_KEY_ALIAS_PROP, "gemfire1"); + extraProps.setProperty(HandShake.PRIVATE_KEY_PASSWD_PROP, "gemfire"); + } + + Assert.assertNotNull(extraProps.getProperty(LdapUserAuthenticator.LDAP_BASEDN_NAME)); + + logger.info("Generating LdapUserCredentialGenerator with {}", extraProps); + + return extraProps; + } + + @Override + public ClassCode classCode() { + return ClassCode.LDAP; + } + + @Override + public String getAuthInit() { + return UserPasswordAuthInit.class.getName() + ".create"; + } + + @Override + public String getAuthenticator() { + return LdapUserAuthenticator.class.getName() + ".create"; + } + + @Override + public Properties getValidCredentials(final int index) { + final Properties props = new Properties(); + props.setProperty(UserPasswordAuthInit.USER_NAME, USER_PREFIX + ((index % 10) + 1)); + props.setProperty(UserPasswordAuthInit.PASSWORD, USER_PREFIX + ((index % 10) + 1)); + props.setProperty(DistributionConfig.SECURITY_CLIENT_DHALGO_NAME, CIPHERS[RANDOM.nextInt(CIPHERS.length)]); + + if (serverAuthEnabled) { + final String keyStoreFile = TestUtil.getResourcePath(PKCSCredentialGenerator.class, PKCSCredentialGenerator.keyStoreDir + "/publickeyfile"); + props.setProperty(HandShake.PUBLIC_KEY_FILE_PROP, keyStoreFile); + props.setProperty(HandShake.PUBLIC_KEY_PASSWD_PROP, "gemfire"); + } + + return props; + } + + @Override + public Properties getValidCredentials(final Principal principal) { + Properties props = null; + final String userName = principal.getName(); + + if (userName != null && userName.startsWith(USER_PREFIX)) { + boolean isValid; + + try { + final int suffix = Integer.parseInt(userName.substring(USER_PREFIX.length())); + isValid = (suffix >= 1 && suffix <= 10); + } catch (Exception ex) { + isValid = false; + } + + if (isValid) { + props = new Properties(); + props.setProperty(UserPasswordAuthInit.USER_NAME, userName); + props.setProperty(UserPasswordAuthInit.PASSWORD, userName); + } + } + + if (props == null) { + throw new IllegalArgumentException("LDAP: [" + userName + "] not a valid user"); + } + + props.setProperty(DistributionConfig.SECURITY_CLIENT_DHALGO_NAME, CIPHERS[RANDOM.nextInt(CIPHERS.length)]); + + if (serverAuthEnabled) { + final String keyStoreFile = TestUtil.getResourcePath(PKCSCredentialGenerator.class, PKCSCredentialGenerator.keyStoreDir + "/publickeyfile"); + props.setProperty(HandShake.PUBLIC_KEY_FILE_PROP, keyStoreFile); + props.setProperty(HandShake.PUBLIC_KEY_PASSWD_PROP, "gemfire"); + } + + return props; + } + + @Override + public Properties getInvalidCredentials(final int index) { + final Properties props = new Properties(); + props.setProperty(UserPasswordAuthInit.USER_NAME, "invalid" + index); + props.setProperty(UserPasswordAuthInit.PASSWORD, "none"); + props.setProperty(DistributionConfig.SECURITY_CLIENT_DHALGO_NAME, CIPHERS[RANDOM.nextInt(CIPHERS.length)]); + + if (serverAuthEnabled) { + final String keyStoreFile = TestUtil.getResourcePath(PKCSCredentialGenerator.class, PKCSCredentialGenerator.keyStoreDir + "/publickeyfile"); + props.setProperty(HandShake.PUBLIC_KEY_FILE_PROP, keyStoreFile); + props.setProperty(HandShake.PUBLIC_KEY_PASSWD_PROP, "gemfire"); + } + + return props; + } +}