geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bschucha...@apache.org
Subject geode git commit: GEODE-3285: New protocol authentication with SASL
Date Thu, 27 Jul 2017 16:25:53 GMT
Repository: geode
Updated Branches:
  refs/heads/feature/GEODE-3285 [created] 7bdd362be


GEODE-3285: New protocol authentication with SASL

work in progress


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

Branch: refs/heads/feature/GEODE-3285
Commit: 7bdd362be5788c51336b09dd0f062415dd97d139
Parents: e7515f5
Author: Bruce Schuchardt <bschuchardt@pivotal.io>
Authored: Thu Jul 27 09:25:01 2017 -0700
Committer: Bruce Schuchardt <bschuchardt@pivotal.io>
Committed: Thu Jul 27 09:25:01 2017 -0700

----------------------------------------------------------------------
 .../GenericProtocolServerConnection.java        |   2 +-
 .../cache/tier/sockets/ServerConnection.java    |   2 +-
 .../tier/sockets/sasl/SaslAuthenticator.java    |  61 +++++++++++
 .../tier/sockets/sasl/SaslCallbackHandler.java  |  35 +++++++
 .../cache/tier/sockets/sasl/SaslMessage.java    |  32 ++++++
 .../cache/tier/sockets/sasl/SaslMessenger.java  |  17 ++++
 .../sockets/sasl/SaslAuthenticatorTest.java     | 100 +++++++++++++++++++
 .../tier/sockets/sasl/SaslMessengerTest.java    |   8 ++
 .../sockets/ClientServerMiscBCDUnitTest.java    |   5 +
 9 files changed, 260 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode/blob/7bdd362b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
index 76b3b7e..c5c413a 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
@@ -61,7 +61,7 @@ public class GenericProtocolServerConnection extends ServerConnection {
 
   @Override
   protected boolean doHandShake(byte epType, int qSize) {
-    // no handshake for new client protocol.
+//    return (new SaslAuthenticator(theSocket, securityService)).authenticateClient();
     return true;
   }
 

http://git-wip-us.apache.org/repos/asf/geode/blob/7bdd362b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
index 870d0ff..05abf09 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
@@ -86,7 +86,7 @@ public abstract class ServerConnection implements Runnable {
 
   private Map commands;
 
-  private final SecurityService securityService;
+  protected final SecurityService securityService;
 
   final protected CacheServerStats stats;
 

http://git-wip-us.apache.org/repos/asf/geode/blob/7bdd362b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslAuthenticator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslAuthenticator.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslAuthenticator.java
new file mode 100644
index 0000000..2be0848
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslAuthenticator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.internal.cache.tier.sockets.sasl;
+
+import java.net.Socket;
+import java.security.Security;
+
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.internal.security.SecurityService;
+
+/**
+ * SaslAuthenticator performs simple authentication using SASL
+ */
+public class SaslAuthenticator {
+  protected static final Logger logger = LogService.getLogger();
+
+  private final SecurityService securityService;
+  private final SaslServer saslServer;
+  private final SaslMessenger saslMessenger;
+
+  public SaslAuthenticator(SecurityService securityService, SaslServer saslServer, SaslMessenger
saslMessenger) {
+    this.securityService = securityService;
+    this.saslServer = saslServer;
+    this.saslMessenger = saslMessenger;
+  }
+
+  public boolean authenticateClient() {
+    try {
+      byte[] challenge = saslServer.evaluateResponse(new byte[0]);
+
+      while(!saslServer.isComplete()) {
+        saslMessenger.sendMessage(challenge);
+        byte[] response = saslMessenger.readMessage();
+        challenge = saslServer.evaluateResponse(response);
+      }
+
+      return true;
+    } catch (SaslException e) {
+      logger.warn("client authentication failed", e);
+      return false;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/7bdd362b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslCallbackHandler.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslCallbackHandler.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslCallbackHandler.java
new file mode 100644
index 0000000..8fe1193
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslCallbackHandler.java
@@ -0,0 +1,35 @@
+/*
+ * 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.internal.cache.tier.sockets.sasl;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+/**
+ * SASL invokes a callback handler during authentication
+ */
+public class SaslCallbackHandler implements CallbackHandler {
+
+  @Override
+  public void handle(Callback[] callbacks)
+      throws IOException, UnsupportedCallbackException {
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/7bdd362b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessage.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessage.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessage.java
new file mode 100644
index 0000000..ddc6e97
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessage.java
@@ -0,0 +1,32 @@
+package org.apache.geode.internal.cache.tier.sockets.sasl;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+class SaslMessage {
+
+  byte[] contents;
+
+  public SaslMessage(byte[] contents) {
+    this.contents = contents;
+  }
+
+  public SaslMessage(DataInputStream dataInputStream) throws IOException {
+    int length = dataInputStream.readInt();
+    if (length > 1000000) {
+      throw new IllegalStateException("invalid length read from stream");
+    }
+    this.contents = new byte[length];
+    dataInputStream.readFully(this.contents);
+  }
+
+  public void writeTo(DataOutputStream dataOutputStream) throws IOException {
+    dataOutputStream.writeInt(this.contents.length);
+    dataOutputStream.write(this.contents);
+  }
+
+  public byte[] getContents() {
+    return this.contents;
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/7bdd362b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessenger.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessenger.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessenger.java
new file mode 100644
index 0000000..99d6c23
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessenger.java
@@ -0,0 +1,17 @@
+package org.apache.geode.internal.cache.tier.sockets.sasl;
+
+/**
+ * Created by bschuchardt on 7/26/17.
+ */
+class SaslMessenger {
+
+  public void sendMessage(byte[] capture) {
+    // TODO - send the message
+  }
+
+  public byte[] readMessage() {
+    // TODO - read a message
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/7bdd362b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslAuthenticatorTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslAuthenticatorTest.java
b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslAuthenticatorTest.java
new file mode 100644
index 0000000..ecf427a
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslAuthenticatorTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.internal.cache.tier.sockets.sasl;
+
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.ArgumentCaptor;
+
+import org.apache.geode.internal.security.SecurityService;
+import org.apache.geode.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class SaslAuthenticatorTest {
+  @Test
+  public void authenticateClientPassesResponsesToSaslServerTillComplete() throws Exception
{
+    SecurityService securityServiceStub = mock(SecurityService.class);
+    SaslServer saslServerMock = mock(SaslServer.class);
+    SaslMessenger saslMessengerStub = mock(SaslMessenger.class);
+    SaslAuthenticator
+        saslServer = new SaslAuthenticator(securityServiceStub, saslServerMock, saslMessengerStub);
+    ArgumentCaptor<byte[]> saslServerArgumentCaptor = ArgumentCaptor.forClass(byte[].class);
+    ArgumentCaptor<byte[]> messengerArgumentCaptor = ArgumentCaptor.forClass(byte[].class);
+    byte[][] challengesFromServer = {
+        new byte[] {0, 1, 2},
+        new byte[0],
+    };
+    when(saslServerMock.evaluateResponse(isA(byte[].class))).thenReturn(challengesFromServer[0],
+        challengesFromServer[1]);
+    when(saslServerMock.isComplete()).thenReturn(false, true);
+    when(saslMessengerStub.readMessage()).thenReturn(new byte[] {6, 7, 8});
+
+    boolean authenticateClient = saslServer.authenticateClient();
+
+    verify(saslServerMock, times(challengesFromServer.length)).evaluateResponse(saslServerArgumentCaptor.capture());
+    verify(saslMessengerStub, times(1)).sendMessage(messengerArgumentCaptor.capture());
+    assertTrue(authenticateClient);
+
+    List<byte[]> sentMessages = messengerArgumentCaptor.getAllValues();
+    assertEquals(1, sentMessages.size());
+    assertArrayEquals(challengesFromServer[0], sentMessages.get(0));
+
+    List<byte[]> passedResponses = saslServerArgumentCaptor.getAllValues();
+    assertEquals(2, passedResponses.size());
+    assertArrayEquals(new byte[0], passedResponses.get(0));
+    assertArrayEquals(new byte[] {6, 7, 8}, passedResponses.get(1)); // response from client
+
+    verify(saslMessengerStub, times(1)).readMessage();
+  }
+
+  @Test
+  public void authenticateClientReturnsFalseIfCredentialsAreWrong() throws SaslException
{
+    SecurityService securityServiceStub = mock(SecurityService.class);
+    SaslServer saslServerMock = mock(SaslServer.class);
+    SaslMessenger saslMessengerStub = mock(SaslMessenger.class);
+    SaslAuthenticator
+        saslServer = new SaslAuthenticator(securityServiceStub, saslServerMock, saslMessengerStub);
+    ArgumentCaptor<byte[]> saslServerArgumentCaptor = ArgumentCaptor.forClass(byte[].class);
+    ArgumentCaptor<byte[]> messengerArgumentCaptor = ArgumentCaptor.forClass(byte[].class);
+    byte[][] challengesFromServer = {
+        new byte[] {0, 1, 2},
+        new byte[0],
+    };
+    when(saslServerMock.evaluateResponse(isA(byte[].class))).thenReturn(challengesFromServer[0]).thenThrow(new
SaslException("Invalid response"));
+    when(saslServerMock.isComplete()).thenReturn(false);
+    when(saslMessengerStub.readMessage()).thenReturn(new byte[] {6, 7, 8});
+
+    boolean authenticateClient = saslServer.authenticateClient();
+
+    verify(saslServerMock, times(challengesFromServer.length)).evaluateResponse(saslServerArgumentCaptor.capture());
+    verify(saslMessengerStub, times(1)).sendMessage(messengerArgumentCaptor.capture());
+    assertFalse(authenticateClient);
+  }
+
+  @Test
+  public void authenticateClientReturnsFalseIfClientStopsResponding(){}
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/7bdd362b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessengerTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessengerTest.java
b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessengerTest.java
new file mode 100644
index 0000000..4cfc244
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/sasl/SaslMessengerTest.java
@@ -0,0 +1,8 @@
+import static org.junit.Assert.*;
+
+/**
+ * Created by bschuchardt on 7/27/17.
+ */
+public class SaslMessengerTest {
+
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/7bdd362b/geode-cq/src/test/java/org/apache/geode/internal/cache/tier/sockets/ClientServerMiscBCDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-cq/src/test/java/org/apache/geode/internal/cache/tier/sockets/ClientServerMiscBCDUnitTest.java
b/geode-cq/src/test/java/org/apache/geode/internal/cache/tier/sockets/ClientServerMiscBCDUnitTest.java
index 37aeaa4..907fbb5 100755
--- a/geode-cq/src/test/java/org/apache/geode/internal/cache/tier/sockets/ClientServerMiscBCDUnitTest.java
+++ b/geode-cq/src/test/java/org/apache/geode/internal/cache/tier/sockets/ClientServerMiscBCDUnitTest.java
@@ -301,6 +301,11 @@ public class ClientServerMiscBCDUnitTest extends ClientServerMiscDUnitTest
{
   }
 
   @Test
+  public void testConcurrentOperationsWithDRandPR() throws Exception {
+    super.testConcurrentOperationsWithDRandPR();
+  }
+
+    @Test
   public void testDistributedMemberBytesWithCurrentServerAndOldClient() throws Exception
{
     // Start current version server
     int serverPort = initServerCache(true);


Mime
View raw message