Repository: incubator-geode
Updated Branches:
  refs/heads/develop a00a2ff29 -> 4265fa593


GEODE-2059 client SSL handshake attempts do not time out

Client SSL connection attempts are now configured to be able to
time out during the SSL handshake


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/4265fa59
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/4265fa59
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/4265fa59

Branch: refs/heads/develop
Commit: 4265fa59346d3730b98a5949e04822512a0aa6c8
Parents: a00a2ff
Author: Bruce Schuchardt <[email protected]>
Authored: Wed Nov 2 12:26:12 2016 -0700
Committer: Bruce Schuchardt <[email protected]>
Committed: Wed Nov 2 12:28:05 2016 -0700

----------------------------------------------------------------------
 .../cache/server/internal/LoadMonitor.java      |  2 +-
 .../geode/internal/net/SocketCreator.java       |  7 +-
 .../internal/net/SSLSocketIntegrationTest.java  | 78 +++++++++++++++++++-
 3 files changed, 83 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4265fa59/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java
 
b/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java
index 496dbc8..1c571a9 100644
--- 
a/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java
+++ 
b/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java
@@ -146,7 +146,7 @@ public class LoadMonitor implements ConnectionListener {
     private int skippedLoadUpdates;
 
     public PollingThread(long pollInterval, int forceUpdateFrequency) {
-      super("BridgeServer-LoadPollingThread");
+      super("Cache Server Load Polling Thread");
       this.pollInterval = pollInterval;
       this.forceUpdateFrequency = forceUpdateFrequency;
       this.setDaemon(true);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4265fa59/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 a3ba102..742e7f3 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
@@ -964,7 +964,7 @@ public class SocketCreator {
           optionalWatcher.beforeConnect(socket);
         }
         socket.connect(sockaddr, Math.max(timeout, 0));
-        configureClientSSLSocket(socket);
+        configureClientSSLSocket(socket, timeout);
         return socket;
       } else {
         if (clientSide && this.clientSocketFactory != null) {
@@ -1063,7 +1063,7 @@ public class SocketCreator {
    * When a socket is accepted from a server socket, it should be passed to 
this method for SSL
    * configuration.
    */
-  private void configureClientSSLSocket(Socket socket) throws IOException {
+  private void configureClientSSLSocket(Socket socket, int timeout) throws 
IOException {
     if (socket instanceof SSLSocket) {
       SSLSocket sslSocket = (SSLSocket) socket;
 
@@ -1082,6 +1082,9 @@ public class SocketCreator {
       }
 
       try {
+        if (timeout > 0) {
+          sslSocket.setSoTimeout(timeout);
+        }
         sslSocket.startHandshake();
         SSLSession session = sslSocket.getSession();
         Certificate[] peer = session.getPeerCertificates();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4265fa59/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java
 
b/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java
index d5a947c..5746d9b 100755
--- 
a/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java
@@ -19,18 +19,25 @@ import static 
org.apache.geode.distributed.ConfigurationProperties.*;
 import static 
org.apache.geode.internal.security.SecurableCommunicationChannel.*;
 import static org.assertj.core.api.Assertions.*;
 
+import com.jayway.awaitility.Awaitility;
+import com.sun.tools.hat.internal.model.StackTrace;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.util.Properties;
+import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.geode.internal.security.SecurableCommunicationChannel;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -51,7 +58,7 @@ import org.apache.geode.test.junit.categories.IntegrationTest;
  * <p>
  * <p>
  * Renamed from {@code JSSESocketJUnitTest}.
- *
+ * 
  * @see ClientSocketFactoryIntegrationTest
  */
 @Category(IntegrationTest.class)
@@ -140,6 +147,75 @@ public class SSLSocketIntegrationTest {
         .until(() -> 
assertThat(this.messageFromClient.get()).isEqualTo(MESSAGE));
   }
 
+  @Test
+  public void configureClientSSLSocketCanTimeOut() throws Exception {
+    final Semaphore serverCoordination = new Semaphore(0);
+
+    // configure a non-SSL server socket. We will connect
+    // a client SSL socket to it and demonstrate that the
+    // handshake times out
+    final ServerSocket serverSocket = new ServerSocket();
+    serverSocket.bind(new InetSocketAddress(SocketCreator.getLocalHost(), 0));
+    Thread serverThread = new Thread() {
+      public void run() {
+        serverCoordination.release();
+        try (Socket clientSocket = serverSocket.accept()) {
+          System.out.println("server thread accepted a connection");
+          serverCoordination.acquire();
+        } catch (Exception e) {
+          System.err.println("accept failed");
+          e.printStackTrace();
+        }
+        try {
+          serverSocket.close();
+        } catch (IOException e) {
+          // ignored
+        }
+        System.out.println("server thread is exiting");
+      }
+    };
+    serverThread.setName("SocketCreatorJUnitTest serverSocket thread");
+    serverThread.setDaemon(true);
+    serverThread.start();
+
+    serverCoordination.acquire();
+
+    SocketCreator socketCreator =
+        
SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.SERVER);
+
+    int serverSocketPort = serverSocket.getLocalPort();
+    try {
+      Awaitility.await("connect to server socket").atMost(30, 
TimeUnit.SECONDS).until(() -> {
+        try {
+          Socket clientSocket = socketCreator.connectForClient(
+              SocketCreator.getLocalHost().getHostAddress(), serverSocketPort, 
2000);
+          clientSocket.close();
+          System.err.println(
+              "client successfully connected to server but should not have 
been able to do so");
+          return false;
+        } catch (SocketTimeoutException e) {
+          // we need to verify that this timed out in the handshake
+          // code
+          System.out.println("client connect attempt timed out - checking 
stack trace");
+          StackTraceElement[] trace = e.getStackTrace();
+          for (StackTraceElement element : trace) {
+            if (element.getMethodName().equals("configureClientSSLSocket")) {
+              System.out.println("client connect attempt timed out in the 
appropriate method");
+              return true;
+            }
+          }
+          // it wasn't in the configuration method so we need to try again
+        } catch (IOException e) {
+          // server socket may not be in accept() yet, causing a 
connection-refused
+          // exception
+        }
+        return false;
+      });
+    } finally {
+      serverCoordination.release();
+    }
+  }
+
   private File findTestKeystore() throws IOException {
     return copyKeystoreResourceToFile("/ssl/trusted.keystore");
   }

Reply via email to