Repository: geode Updated Branches: refs/heads/develop aef891296 -> 1c35f8665
GEODE-3121: ensure that the protobuf protocol works over SSL This just introduces a new test where we run the put/get integration test of the protocol module, but sets up a SSL cache and socket. Signed-off-by: Brian Rowe <br...@pivotal.io> Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/cb423ff8 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/cb423ff8 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/cb423ff8 Branch: refs/heads/develop Commit: cb423ff8aaefdd22e60ca29f6440319b1ba9d84a Parents: aef8912 Author: Hitesh Khamesra <hitesh...@yahoo.com> Authored: Wed Jun 28 16:10:31 2017 -0700 Committer: Udo Kohlmeyer <ukohlme...@pivotal.io> Committed: Tue Jul 11 15:40:47 2017 -0700 ---------------------------------------------------------------------- .../geode/internal/net/SocketCreator.java | 2 +- .../RoundTripCacheConnectionJUnitTest.java | 111 +++++++++++++++---- .../org/apache/geode/protocol/default.keystore | Bin 0 -> 1115 bytes 3 files changed, 89 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/cb423ff8/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java index 844b484..dbe18a9 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java +++ b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java @@ -264,7 +264,7 @@ public class SocketCreator { /** * Constructs new SocketCreator instance. */ - SocketCreator(final SSLConfig sslConfig) { + public SocketCreator(final SSLConfig sslConfig) { this.sslConfig = sslConfig; initialize(); } http://git-wip-us.apache.org/repos/asf/geode/blob/cb423ff8/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java index 3838648..c3d5616 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java @@ -20,8 +20,12 @@ import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionFactory; import org.apache.geode.cache.server.CacheServer; +import org.apache.geode.distributed.ConfigurationProperties; import org.apache.geode.internal.AvailablePortHelper; +import org.apache.geode.internal.admin.SSLConfig; import org.apache.geode.internal.cache.tier.sockets.GenericProtocolServerConnection; +import org.apache.geode.internal.net.SocketCreator; +import org.apache.geode.internal.net.SocketCreatorFactory; import org.apache.geode.protocol.exception.InvalidProtocolMessageException; import org.apache.geode.protocol.protobuf.BasicTypes; import org.apache.geode.protocol.protobuf.ClientProtocol; @@ -35,6 +39,7 @@ import org.apache.geode.serialization.exception.UnsupportedEncodingTypeException import org.apache.geode.serialization.registry.exception.CodecAlreadyRegisteredForTypeException; import org.apache.geode.serialization.registry.exception.CodecNotRegisteredForTypeException; import org.apache.geode.test.junit.categories.IntegrationTest; +import org.apache.geode.util.test.TestUtil; import org.awaitility.Awaitility; import org.junit.After; import org.junit.Before; @@ -42,12 +47,15 @@ import org.junit.Rule; import org.junit.Test; import org.junit.contrib.java.lang.system.RestoreSystemProperties; import org.junit.experimental.categories.Category; +import org.junit.rules.TestName; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; +import java.util.Properties; import java.util.concurrent.TimeUnit; +import static org.apache.geode.distributed.ConfigurationProperties.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -65,16 +73,33 @@ public class RoundTripCacheConnectionJUnitTest { public static final int TEST_GET_CORRELATION_ID = 68451; public static final int TEST_REMOVE_CORRELATION_ID = 51; + private static final String DEFAULT_STORE = "default.keystore"; + private static final String SSL_PROTOCOLS = "any"; + private static final String SSL_CIPHERS = "any"; + private Cache cache; private int cacheServerPort; private SerializationService serializationService; + private Socket socket; + private OutputStream outputStream; @Rule public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(); + @Rule + public TestName testName = new TestName(); + @Before public void setup() throws Exception { - CacheFactory cacheFactory = new CacheFactory(); + // Test names prefixed with useSSL_ will setup the cache and socket to use SSL transport + boolean useSSL = testName.getMethodName().startsWith("useSSL_"); + + Properties properties = new Properties(); + if (useSSL) { + updatePropertiesForSSLCache(properties); + } + + CacheFactory cacheFactory = new CacheFactory(properties); cacheFactory.set("mcast-port", "0"); // sometimes it isn't due to other tests. cache = cacheFactory.create(); @@ -85,23 +110,30 @@ public class RoundTripCacheConnectionJUnitTest { RegionFactory<Object, Object> regionFactory = cache.createRegionFactory(); Region<Object, Object> testRegion = regionFactory.create(TEST_REGION); + + System.setProperty("geode.feature-protobuf-protocol", "true"); + + if (useSSL) { + socket = getSSLSocket(); + } else { + socket = new Socket("localhost", cacheServerPort); + } + Awaitility.await().atMost(5, TimeUnit.SECONDS).until(socket::isConnected); + outputStream = socket.getOutputStream(); + outputStream.write(110); + serializationService = new ProtobufSerializationService(); } @After - public void cleanup() { + public void cleanup() throws IOException { cache.close(); + socket.close(); + SocketCreatorFactory.close(); } @Test public void testNewProtocolHeaderLeadsToNewProtocolServerConnection() throws Exception { - System.setProperty("geode.feature-protobuf-protocol", "true"); - - Socket socket = new Socket("localhost", cacheServerPort); - Awaitility.await().atMost(5, TimeUnit.SECONDS).until(socket::isConnected); - OutputStream outputStream = socket.getOutputStream(); - outputStream.write(110); - ProtobufProtocolSerializer protobufProtocolSerializer = new ProtobufProtocolSerializer(); ClientProtocol.Message putMessage = MessageUtil.makePutRequestMessage(serializationService, TEST_KEY, TEST_VALUE, TEST_REGION, @@ -124,13 +156,6 @@ public class RoundTripCacheConnectionJUnitTest { @Test public void testNullResponse() throws Exception { - System.setProperty("geode.feature-protobuf-protocol", "true"); - - Socket socket = new Socket("localhost", cacheServerPort); - Awaitility.await().atMost(5, TimeUnit.SECONDS).until(socket::isConnected); - OutputStream outputStream = socket.getOutputStream(); - outputStream.write(110); - // Get request without any data set must return a null ProtobufProtocolSerializer protobufProtocolSerializer = new ProtobufProtocolSerializer(); ClientProtocol.Message getMessage = MessageUtil.makeGetRequestMessage(serializationService, @@ -155,12 +180,6 @@ public class RoundTripCacheConnectionJUnitTest { @Test public void testNewProtocolGetRegionNamesCallSucceeds() throws Exception { - System.setProperty("geode.feature-protobuf-protocol", "true"); - - Socket socket = new Socket("localhost", cacheServerPort); - Awaitility.await().atMost(5, TimeUnit.SECONDS).until(socket::isConnected); - OutputStream outputStream = socket.getOutputStream(); - outputStream.write(110); int correlationId = TEST_GET_CORRELATION_ID; // reuse this value for this test ProtobufProtocolSerializer protobufProtocolSerializer = new ProtobufProtocolSerializer(); @@ -171,6 +190,11 @@ public class RoundTripCacheConnectionJUnitTest { validateGetRegionNamesResponse(socket, correlationId, protobufProtocolSerializer); } + @Test + public void useSSL_testNewProtocolHeaderLeadsToNewProtocolServerConnection() throws Exception { + testNewProtocolHeaderLeadsToNewProtocolServerConnection(); + } + private void validatePutResponse(Socket socket, ProtobufProtocolSerializer protobufProtocolSerializer) throws Exception { ClientProtocol.Message message = @@ -217,7 +241,7 @@ public class RoundTripCacheConnectionJUnitTest { } private void validateRemoveResponse(Socket socket, - ProtobufProtocolSerializer protobufProtocolSerializer) throws Exception { + ProtobufProtocolSerializer protobufProtocolSerializer) throws Exception { ClientProtocol.Message message = protobufProtocolSerializer.deserialize(socket.getInputStream()); assertEquals(TEST_REMOVE_CORRELATION_ID, message.getMessageHeader().getCorrelationId()); @@ -226,4 +250,45 @@ public class RoundTripCacheConnectionJUnitTest { assertEquals(ClientProtocol.Response.ResponseAPICase.REMOVERESPONSE, response.getResponseAPICase()); } + + private void updatePropertiesForSSLCache(Properties properties) { + String keyStore = + TestUtil.getResourcePath(RoundTripCacheConnectionJUnitTest.class, DEFAULT_STORE); + String trustStore = + TestUtil.getResourcePath(RoundTripCacheConnectionJUnitTest.class, DEFAULT_STORE); + + properties.put(SSL_ENABLED_COMPONENTS, "server"); + properties.put(ConfigurationProperties.SSL_PROTOCOLS, SSL_PROTOCOLS); + properties.put(ConfigurationProperties.SSL_CIPHERS, SSL_CIPHERS); + properties.put(SSL_REQUIRE_AUTHENTICATION, String.valueOf(true)); + + properties.put(SSL_KEYSTORE_TYPE, "jks"); + properties.put(SSL_KEYSTORE, keyStore); + properties.put(SSL_KEYSTORE_PASSWORD, "password"); + properties.put(SSL_TRUSTSTORE, trustStore); + properties.put(SSL_TRUSTSTORE_PASSWORD, "password"); + } + + private Socket getSSLSocket() throws IOException { + String keyStorePath = + TestUtil.getResourcePath(RoundTripCacheConnectionJUnitTest.class, DEFAULT_STORE); + String trustStorePath = + TestUtil.getResourcePath(RoundTripCacheConnectionJUnitTest.class, DEFAULT_STORE); + + SSLConfig sslConfig = new SSLConfig(); + sslConfig.setEnabled(true); + sslConfig.setCiphers(SSL_CIPHERS); + sslConfig.setProtocols(SSL_PROTOCOLS); + sslConfig.setRequireAuth(true); + sslConfig.setKeystoreType("jks"); + sslConfig.setKeystore(keyStorePath); + sslConfig.setKeystorePassword("password"); + sslConfig.setTruststore(trustStorePath); + sslConfig.setKeystorePassword("password"); + + SocketCreator socketCreator = new SocketCreator(sslConfig); + return socketCreator.connectForClient("localhost", cacheServerPort, 5000); + } + + } http://git-wip-us.apache.org/repos/asf/geode/blob/cb423ff8/geode-protobuf/src/test/resources/org/apache/geode/protocol/default.keystore ---------------------------------------------------------------------- diff --git a/geode-protobuf/src/test/resources/org/apache/geode/protocol/default.keystore b/geode-protobuf/src/test/resources/org/apache/geode/protocol/default.keystore new file mode 100644 index 0000000..8dce373 Binary files /dev/null and b/geode-protobuf/src/test/resources/org/apache/geode/protocol/default.keystore differ