Repository: incubator-geode Updated Branches: refs/heads/feature/GEODE-1883 [created] d54080aa4
GEODE-1883: make auth-init optional * Failed Tests: CQClientAuthDunitTest. testPostProcess ClientCQPostAuthorizationDUnitTest. testAllowCQForAllMultiusers ClientCQPostAuthorizationDUnitTest. testAllowCQForAllMultiusersWithFailover ClientCQPostAuthorizationDUnitTest. testDisallowCQForAllMultiusers ClientCQPostAuthorizationDUnitTest. testDisallowCQForSomeMultiusers ClientMultiUserAuthzDUnitTest. testOps1 ClientMultiUserAuthzDUnitTest. testOps2 ClientMultiUserAuthzDUnitTest. testOpsWithClientsInDifferentModes MultiUserDurableCQAuthzDUnitTest. testCQForDurableClientsWithCloseKeepAliveFalse MultiUserDurableCQAuthzDUnitTest. testCQForDurableClientsWithCloseKeepAliveTrue MultiUserDurableCQAuthzDUnitTest. testCQForDurableClientsWithDefaultClose Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/d54080aa Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/d54080aa Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/d54080aa Branch: refs/heads/feature/GEODE-1883 Commit: d54080aa48194e6861d1e463b6ab5e70c39a80e6 Parents: 5907e98 Author: Jinmei Liao <jil...@pivotal.io> Authored: Sun Oct 16 12:19:25 2016 -0700 Committer: Jinmei Liao <jil...@pivotal.io> Committed: Wed Nov 9 08:16:09 2016 -0800 ---------------------------------------------------------------------- .../cache/tier/sockets/CacheClientUpdater.java | 67 ++++++++++++----- .../internal/cache/tier/sockets/HandShake.java | 47 ++++++------ .../geode/security/ClientAuthDUnitTest.java | 79 ++++++++++++++++++++ .../security/ClientAuthenticationTestCase.java | 10 +-- .../dunit/rules/LocatorServerStartupRule.java | 8 +- 5 files changed, 160 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d54080aa/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java index b4a6bed..324e240 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java @@ -15,21 +15,65 @@ package org.apache.geode.internal.cache.tier.sockets; -import org.apache.geode.*; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.io.OutputStream; +import java.net.ConnectException; +import java.net.Socket; +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.net.ssl.SSLException; + +import org.apache.logging.log4j.Logger; + +import org.apache.geode.CancelException; +import org.apache.geode.DataSerializer; +import org.apache.geode.InvalidDeltaException; +import org.apache.geode.StatisticDescriptor; +import org.apache.geode.Statistics; +import org.apache.geode.StatisticsType; +import org.apache.geode.StatisticsTypeFactory; +import org.apache.geode.SystemFailure; import org.apache.geode.cache.EntryNotFoundException; import org.apache.geode.cache.InterestResultPolicy; import org.apache.geode.cache.Operation; import org.apache.geode.cache.RegionDestroyedException; import org.apache.geode.cache.client.ServerRefusedConnectionException; -import org.apache.geode.cache.client.internal.*; +import org.apache.geode.cache.client.internal.ClientUpdater; +import org.apache.geode.cache.client.internal.Endpoint; +import org.apache.geode.cache.client.internal.EndpointManager; +import org.apache.geode.cache.client.internal.GetEventValueOp; +import org.apache.geode.cache.client.internal.PoolImpl; +import org.apache.geode.cache.client.internal.QueueManager; import org.apache.geode.cache.query.internal.cq.CqService; import org.apache.geode.distributed.DistributedSystem; -import org.apache.geode.distributed.internal.*; +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.DistributionManager; +import org.apache.geode.distributed.internal.DistributionStats; +import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.distributed.internal.InternalDistributedSystem.DisconnectListener; +import org.apache.geode.distributed.internal.ServerLocation; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.distributed.internal.membership.MemberAttributes; -import org.apache.geode.internal.*; -import org.apache.geode.internal.cache.*; +import org.apache.geode.internal.Assert; +import org.apache.geode.internal.InternalDataSerializer; +import org.apache.geode.internal.InternalInstantiator; +import org.apache.geode.internal.Version; +import org.apache.geode.internal.cache.ClientServerObserver; +import org.apache.geode.internal.cache.ClientServerObserverHolder; +import org.apache.geode.internal.cache.EntryEventImpl; +import org.apache.geode.internal.cache.EventID; +import org.apache.geode.internal.cache.GemFireCacheImpl; +import org.apache.geode.internal.cache.LocalRegion; import org.apache.geode.internal.cache.tier.CachedRegionHelper; import org.apache.geode.internal.cache.tier.MessageType; import org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException; @@ -48,19 +92,6 @@ import org.apache.geode.internal.statistics.StatisticsTypeFactoryImpl; import org.apache.geode.security.AuthenticationFailedException; import org.apache.geode.security.AuthenticationRequiredException; import org.apache.geode.security.GemFireSecurityException; -import org.apache.logging.log4j.Logger; - -import javax.net.ssl.SSLException; -import java.io.*; -import java.net.ConnectException; -import java.net.Socket; -import java.net.SocketException; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; /** * <code>CacheClientUpdater</code> is a thread that processes update messages from a cache server http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d54080aa/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/HandShake.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/HandShake.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/HandShake.java index c0db945..997bd0e 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/HandShake.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/HandShake.java @@ -46,7 +46,6 @@ import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Properties; @@ -58,6 +57,8 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.SSLSocket; +import org.apache.logging.log4j.Logger; + import org.apache.geode.CancelCriterion; import org.apache.geode.DataSerializer; import org.apache.geode.InternalGemFireException; @@ -95,7 +96,6 @@ import org.apache.geode.security.AuthenticationFailedException; import org.apache.geode.security.AuthenticationRequiredException; import org.apache.geode.security.Authenticator; import org.apache.geode.security.GemFireSecurityException; -import org.apache.logging.log4j.Logger; public class HandShake implements ClientHandShake { private static final Logger logger = LogService.getLogger(); @@ -228,7 +228,7 @@ public class HandShake implements ClientHandShake { /** * Test hooks for per client conflation - * + * * @since GemFire 5.7 */ public static byte clientConflationForTesting = 0; @@ -236,7 +236,7 @@ public class HandShake implements ClientHandShake { /** * Test hook for client version support - * + * * @since GemFire 5.7 */ private static Version currentClientVersion = ConnectionProxy.VERSION; @@ -450,7 +450,7 @@ public class HandShake implements ClientHandShake { } public byte write(DataOutputStream dos, DataInputStream dis, byte communicationMode, - int replyCode, int readTimeout, List ports, Properties p_credentials, + int replyCode, int readTimeout, boolean isNotification, Properties p_credentials, DistributedMember member, boolean isCallbackConnection) throws IOException { HeapDataOutputStream hdos = new HeapDataOutputStream(32, Version.CURRENT); byte acceptanceCode = -1; @@ -464,11 +464,8 @@ public class HandShake implements ClientHandShake { } hdos.writeByte(replyCode); - if (ports != null) { - hdos.writeInt(ports.size()); - for (int i = 0; i < ports.size(); i++) { - hdos.writeInt(Integer.parseInt((String) ports.get(i))); - } + if (isNotification) { + hdos.writeInt(0); } else { hdos.writeInt(readTimeout); } @@ -491,19 +488,19 @@ public class HandShake implements ClientHandShake { } } - if (isCallbackConnection || communicationMode == Acceptor.GATEWAY_TO_GATEWAY) { - if (isCallbackConnection && this.multiuserSecureMode - && communicationMode != Acceptor.GATEWAY_TO_GATEWAY) { + if (communicationMode == Acceptor.GATEWAY_TO_GATEWAY) { + writeCredentials(dos, dis, p_credentials, isNotification, member, hdos); + } else if (isCallbackConnection) { + if (this.multiuserSecureMode) { hdos.writeByte(SECURITY_MULTIUSER_NOTIFICATIONCHANNEL); hdos.flush(); dos.write(hdos.toByteArray()); dos.flush(); } else { - writeCredentials(dos, dis, p_credentials, ports != null, member, hdos); + writeCredentials(dos, dis, p_credentials, isNotification, member, hdos); } } else { - String authInitMethod = this.system.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT); - acceptanceCode = writeCredential(dos, dis, authInitMethod, ports != null, member, hdos); + acceptanceCode = writeCredential(dos, dis, p_credentials, isNotification, member, hdos); } } finally { hdos.close(); @@ -663,18 +660,18 @@ public class HandShake implements ClientHandShake { * * @param dos * @param dis - * @param authInit + * @param credentials * @param isNotification * @param member * @param heapdos * @throws IOException * @throws GemFireSecurityException */ - public byte writeCredential(DataOutputStream dos, DataInputStream dis, String authInit, + public byte writeCredential(DataOutputStream dos, DataInputStream dis, Properties credentials, boolean isNotification, DistributedMember member, HeapDataOutputStream heapdos) throws IOException, GemFireSecurityException { - if (!this.multiuserSecureMode && (authInit == null || authInit.length() == 0)) { + if (!this.multiuserSecureMode && credentials == null) { // No credentials indicator heapdos.writeByte(CREDENTIALS_NONE); heapdos.flush(); @@ -1214,16 +1211,18 @@ public class HandShake implements ClientHandShake { updateProxyID(dm.getDistributionManagerId()); } } + + Properties credentials = getCredentials(member); if (communicationMode == Acceptor.GATEWAY_TO_GATEWAY) { - this.credentials = getCredentials(member); + this.credentials = credentials; } + byte intermediateAcceptanceCode = write(dos, dis, communicationMode, REPLY_OK, - this.clientReadTimeout, null, this.credentials, member, false); + this.clientReadTimeout, false, credentials, member, false); String authInit = this.system.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT); if (communicationMode != Acceptor.GATEWAY_TO_GATEWAY - && intermediateAcceptanceCode != REPLY_AUTH_NOT_REQUIRED - && (authInit != null && authInit.length() != 0)) { + && intermediateAcceptanceCode != REPLY_AUTH_NOT_REQUIRED && credentials != null) { location.compareAndSetRequiresCredentials(true); } // Read the acceptance code @@ -1311,7 +1310,7 @@ public class HandShake implements ClientHandShake { } byte mode = isPrimary ? Acceptor.PRIMARY_SERVER_TO_CLIENT : Acceptor.SECONDARY_SERVER_TO_CLIENT; - write(dos, dis, mode, REPLY_OK, 0, new ArrayList(), this.credentials, member, true); + write(dos, dis, mode, REPLY_OK, 0, true, this.credentials, member, true); // Wait here for a reply before continuing. This ensures that the client // updater is registered with the server before continuing. http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d54080aa/geode-core/src/test/java/org/apache/geode/security/ClientAuthDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/ClientAuthDUnitTest.java b/geode-core/src/test/java/org/apache/geode/security/ClientAuthDUnitTest.java new file mode 100644 index 0000000..6a4c33e --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/ClientAuthDUnitTest.java @@ -0,0 +1,79 @@ +/* + * 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 static com.googlecode.catchexception.CatchException.catchException; +import static com.googlecode.catchexception.apis.BDDCatchException.caughtException; +import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER; +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.security.templates.SimpleSecurityManager; +import org.apache.geode.security.templates.UserPasswordAuthInit; +import org.apache.geode.test.dunit.IgnoredException; +import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase; +import org.apache.geode.test.dunit.rules.LocatorServerStartupRule; +import org.apache.geode.test.junit.categories.DistributedTest; +import org.apache.geode.test.junit.categories.SecurityTest; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.util.Properties; + +@Category({DistributedTest.class, SecurityTest.class}) +public class ClientAuthDUnitTest extends JUnit4DistributedTestCase { + + @Rule + public LocatorServerStartupRule lsRule = new LocatorServerStartupRule(); + + @Before + public void before() throws Exception { + IgnoredException.addIgnoredException("org.apache.geode.security.AuthenticationFailedException"); + lsRule.getServerVM(0, new Properties() { + { + setProperty(SECURITY_MANAGER, SimpleSecurityManager.class.getName()); + } + }); + } + + @Test + public void authWithCorrectPasswordShouldPass() { + ClientCache cache = new ClientCacheFactory(createClientProperties("user", "user")) + .setPoolSubscriptionEnabled(true).addPoolServer("localhost", lsRule.getPort(0)).create(); + } + + @Test + public void authWithIncorrectPasswordShouldFail() { + catchException(new ClientCacheFactory(createClientProperties("user", "wrong")) + .setPoolSubscriptionEnabled(true).addPoolServer("localhost", lsRule.getPort(0))).create(); + assertThat((Throwable) caughtException()).isInstanceOf(AuthenticationFailedException.class); + } + + private static Properties createClientProperties(String userName, String password) { + Properties props = new Properties(); + props.setProperty(UserPasswordAuthInit.USER_NAME, userName); + props.setProperty(UserPasswordAuthInit.PASSWORD, password); + // props.setProperty(SECURITY_CLIENT_AUTH_INIT, UserPasswordAuthInit.class.getName()); + props.setProperty(LOCATORS, ""); + props.setProperty(MCAST_PORT, "0"); + return props; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d54080aa/geode-core/src/test/java/org/apache/geode/security/ClientAuthenticationTestCase.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/ClientAuthenticationTestCase.java b/geode-core/src/test/java/org/apache/geode/security/ClientAuthenticationTestCase.java index d1eddbb..bcb4bab 100644 --- a/geode-core/src/test/java/org/apache/geode/security/ClientAuthenticationTestCase.java +++ b/geode-core/src/test/java/org/apache/geode/security/ClientAuthenticationTestCase.java @@ -261,9 +261,9 @@ public abstract class ClientAuthenticationTestCase extends JUnit4DistributedTest + credentials2 + " : " + javaProps2); client1.invoke(() -> createCacheClient(null, credentials1, javaProps1, port1, port2, 0, - multiUser, AUTHREQ_EXCEPTION)); + multiUser, NO_EXCEPTION)); client2.invoke(() -> createCacheClient(null, credentials2, javaProps2, port1, port2, 0, - multiUser, AUTHREQ_EXCEPTION)); + multiUser, NO_EXCEPTION)); client2.invoke(() -> closeCache()); // Now also try with invalid credentials @@ -271,7 +271,7 @@ public abstract class ClientAuthenticationTestCase extends JUnit4DistributedTest Properties javaProps3 = gen.getJavaProperties(); client2.invoke(() -> createCacheClient(null, credentials3, javaProps3, port1, port2, 0, - multiUser, AUTHREQ_EXCEPTION)); + multiUser, AUTHFAIL_EXCEPTION)); } /** @@ -525,7 +525,7 @@ public abstract class ClientAuthenticationTestCase extends JUnit4DistributedTest final int p2 = server2.invoke( () -> createCacheServer(locPort2, locString, 0, authenticator, extraProps, javaProps)); client1.invoke(() -> createCacheClient(null, credentials1, javaProps1, p1, p2, 0, multiUser, - AUTHREQ_EXCEPTION)); + NO_EXCEPTION)); createClient2AuthReqException(multiUser, p1, p2, credentials2, javaProps2, zeroConns); createClient2AuthReqException(multiUser, p1, p2, credentials2, javaProps2, zeroConns); @@ -593,7 +593,7 @@ public abstract class ClientAuthenticationTestCase extends JUnit4DistributedTest final int port2, final Properties credentials2, final Properties javaProps2, final int zeroConns) { client2.invoke(() -> createCacheClient(null, credentials2, javaProps2, port1, port2, zeroConns, - multiUser, AUTHREQ_EXCEPTION)); + multiUser, AUTHFAIL_EXCEPTION)); } private void createClient1WithException(final boolean multiUser, final String authInit, http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d54080aa/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java index 6053e1e..ec578f8 100644 --- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java +++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java @@ -55,7 +55,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial /** * Returns getHost(0).getVM(0) as a locator instance with the given configuration properties. - * + * * @param locatorProperties * * @return VM locator vm @@ -76,7 +76,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial /** * starts a cache server that does not connect to a locator - * + * * @return VM node vm */ @@ -86,7 +86,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial /** * starts a cache server that connect to the locator running at the given port. - * + * * @param index * @param properties * @param locatorPort @@ -108,7 +108,7 @@ public class LocatorServerStartupRule extends ExternalResource implements Serial /** * this will simply returns the node - * + * * @param index * @return */