You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2013/05/31 13:25:43 UTC

git commit: Adds AUTH_SUCCESS message as follow up to #5545

Updated Branches:
  refs/heads/trunk 401b46bb3 -> 1a70df0c0


Adds AUTH_SUCCESS message as follow up to #5545


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/1a70df0c
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/1a70df0c
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/1a70df0c

Branch: refs/heads/trunk
Commit: 1a70df0c0eaf301117ba78600e1ebc2727f52167
Parents: 401b46b
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Fri May 31 11:49:39 2013 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Fri May 31 11:50:11 2013 +0200

----------------------------------------------------------------------
 doc/native_protocol_v2.spec                        |   29 +++++--
 .../org/apache/cassandra/transport/CBUtil.java     |    8 ++
 .../org/apache/cassandra/transport/Message.java    |    5 +-
 .../cassandra/transport/ServerConnection.java      |    2 +-
 .../cassandra/transport/messages/AuthSuccess.java  |   66 +++++++++++++++
 .../transport/messages/SaslChallenge.java          |    6 +-
 .../cassandra/transport/messages/SaslResponse.java |   10 +-
 7 files changed, 107 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/1a70df0c/doc/native_protocol_v2.spec
----------------------------------------------------------------------
diff --git a/doc/native_protocol_v2.spec b/doc/native_protocol_v2.spec
index 92d6ebd..8d83d3b 100644
--- a/doc/native_protocol_v2.spec
+++ b/doc/native_protocol_v2.spec
@@ -35,6 +35,7 @@ Table of Contents
         4.2.5.5. Schema_change
       4.2.6. EVENT
       4.2.7. AUTH_CHALLENGE
+      4.2.8. AUTH_SUCCESS
   5. Compression
   6. Collection types
   7. Error codes
@@ -163,6 +164,7 @@ Table of Contents
     0x0D    BATCH
     0x0E    AUTH_CHALLENGE
     0x0F    AUTH_RESPONSE
+    0x10    AUTH_SUCCESS
 
   Messages are described in Section 4.
 
@@ -250,9 +252,9 @@ Table of Contents
   Answers a server authentication challenge.
 
   Authentication in the protocol is SASL based. The server sends authentication
-  challenge (a bytes token) to which the client answer with this message. Those
+  challenges (a bytes token) to which the client answer with this message. Those
   exchanges continue until the server accepts the authentication by sending a
-  READY message after a client AUTH_RESPONSE. It is however that client that
+  AUTH_SUCCESS message after a client AUTH_RESPONSE. It is however that client that
   initiate the exchange by sending an initial AUTH_RESPONSE in response to a
   server AUTHENTICATE request.
 
@@ -261,7 +263,7 @@ Table of Contents
   authenticator used.
 
   The response to a AUTH_RESPONSE is either a follow-up AUTH_CHALLENGE message,
-  a READY message or an ERROR message.
+  an AUTH_SUCCESS message or an ERROR message.
 
 
 4.1.3. OPTIONS
@@ -387,15 +389,16 @@ Table of Contents
   Indicates that the server require authentication, and which authentication
   mechanism to use.
 
-  The authentication is SASL based and thus consist on a number of server
-  challenge (AUTH_CHALLENGE, Section 4.2.7) followed by client response
+  The authentication is SASL based and thus consists on a number of server
+  challenges (AUTH_CHALLENGE, Section 4.2.7) followed by client responses
   (AUTH_RESPONSE, Section 4.1.2). The Initial exchange is however boostrapped
   by an initial client response. The details of that exchange (including how
   much challenge-response pair are required) are specific to the authenticator
-  in use.
+  in use. The exchange ends when the server sends an AUTH_SUCCESS message or
+  an ERROR message.
 
-  This will be sent following a STARTUP message if authentication is required
-  and must be answered by a AUTH_RESPONSE message from the client.
+  This message will be sent following a STARTUP message if authentication is
+  required and must be answered by a AUTH_RESPONSE message from the client.
 
   The body consists of a single [string] indicating the full class name of the
   IAuthenticator in use.
@@ -577,6 +580,16 @@ Table of Contents
   Clients are expected to answer the server challenge by an AUTH_RESPONSE
   message.
 
+4.2.7. AUTH_SUCCESS
+
+  Indicate the success of the authentication phase. See Section 4.2.3 for more
+  details.
+
+  The body of this message is a single [bytes] token holding final information
+  from the server that the client may require to finish the authentication
+  process. What that token contains and whether it can be null depends on the
+  actual authenticator used.
+
 
 5. Compression
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/1a70df0c/src/java/org/apache/cassandra/transport/CBUtil.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/CBUtil.java b/src/java/org/apache/cassandra/transport/CBUtil.java
index 897a3d9..218e684 100644
--- a/src/java/org/apache/cassandra/transport/CBUtil.java
+++ b/src/java/org/apache/cassandra/transport/CBUtil.java
@@ -250,6 +250,14 @@ public abstract class CBUtil
         }
     }
 
+    public static ChannelBuffer valueToCB(byte[] bytes)
+    {
+        if (bytes == null || bytes.length == 0)
+            return intToCB(0);
+
+        return ChannelBuffers.wrappedBuffer(intToCB(bytes.length), ChannelBuffers.wrappedBuffer(bytes));
+    }
+
     public static ByteBuffer readValue(ChannelBuffer cb)
     {
         int length = cb.readInt();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/1a70df0c/src/java/org/apache/cassandra/transport/Message.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/Message.java b/src/java/org/apache/cassandra/transport/Message.java
index 9cb20e8..1a3afa1 100644
--- a/src/java/org/apache/cassandra/transport/Message.java
+++ b/src/java/org/apache/cassandra/transport/Message.java
@@ -71,8 +71,9 @@ public abstract class Message
         REGISTER       (11, Direction.REQUEST,  RegisterMessage.codec),
         EVENT          (12, Direction.RESPONSE, EventMessage.codec),
         BATCH          (13, Direction.REQUEST,  BatchMessage.codec),
-        SASL_CHALLENGE (14, Direction.RESPONSE, SaslChallenge.codec),
-        SASL_RESPONSE  (15, Direction.REQUEST,  SaslResponse.codec);
+        AUTH_CHALLENGE (14, Direction.RESPONSE, SaslChallenge.codec),
+        AUTH_RESPONSE  (15, Direction.REQUEST,  SaslResponse.codec),
+        AUTH_SUCCESS   (16, Direction.RESPONSE, AuthSuccess.codec);
 
         public final int opcode;
         public final Direction direction;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/1a70df0c/src/java/org/apache/cassandra/transport/ServerConnection.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/ServerConnection.java b/src/java/org/apache/cassandra/transport/ServerConnection.java
index 3e55dcb..bb43934 100644
--- a/src/java/org/apache/cassandra/transport/ServerConnection.java
+++ b/src/java/org/apache/cassandra/transport/ServerConnection.java
@@ -105,7 +105,7 @@ public class ServerConnection extends Connection
                 // Support both SASL auth from protocol v2 and the older style Credentials auth from v1
                 assert requestType == Message.Type.SASL_RESPONSE || requestType == Message.Type.CREDENTIALS;
 
-                if (responseType == Message.Type.READY)
+                if (responseType == Message.Type.READY || responseType == Message.Type.AUTH_SUCCESS)
                 {
                     state = State.READY;
                     // we won't use the authenticator again, null it so that it can be GC'd

http://git-wip-us.apache.org/repos/asf/cassandra/blob/1a70df0c/src/java/org/apache/cassandra/transport/messages/AuthSuccess.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/messages/AuthSuccess.java b/src/java/org/apache/cassandra/transport/messages/AuthSuccess.java
new file mode 100644
index 0000000..e923e6f
--- /dev/null
+++ b/src/java/org/apache/cassandra/transport/messages/AuthSuccess.java
@@ -0,0 +1,66 @@
+/*
+ * 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.cassandra.transport.messages;
+
+import org.apache.cassandra.transport.CBUtil;
+import org.apache.cassandra.transport.Message;
+import org.jboss.netty.buffer.ChannelBuffer;
+
+/**
+ * Indicates to the client that authentication has succeeded.
+ *
+ * Optionally ships some final informations from the server (as mandated by
+ * SASL).
+ */
+public class AuthSuccess extends Message.Response
+{
+    public static final Message.Codec<AuthSuccess> codec = new Message.Codec<AuthSuccess>()
+    {
+        @Override
+        public AuthSuccess decode(ChannelBuffer body, int version)
+        {
+            return new AuthSuccess(CBUtil.readValue(body));
+        }
+
+        @Override
+        public ChannelBuffer encode(AuthSuccess success)
+        {
+            return CBUtil.valueToCB(success.token);
+        }
+    };
+
+    private byte[] token;
+
+    public AuthSuccess(byte[] token)
+    {
+        super(Message.Type.AUTH_SUCCESS);
+        this.token = token;
+    }
+
+    @Override
+    public ChannelBuffer encode()
+    {
+        return codec.encode(this);
+    }
+
+    public byte[] getToken()
+    {
+        return token;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/cassandra/blob/1a70df0c/src/java/org/apache/cassandra/transport/messages/SaslChallenge.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/messages/SaslChallenge.java b/src/java/org/apache/cassandra/transport/messages/SaslChallenge.java
index f95596d..ca76c2a 100644
--- a/src/java/org/apache/cassandra/transport/messages/SaslChallenge.java
+++ b/src/java/org/apache/cassandra/transport/messages/SaslChallenge.java
@@ -31,13 +31,13 @@ public class SaslChallenge extends Message.Response
         @Override
         public SaslChallenge decode(ChannelBuffer body, int version)
         {
-            return new SaslChallenge(CBUtil.readBytes(body));
+            return new SaslChallenge(CBUtil.readValue(body));
         }
 
         @Override
         public ChannelBuffer encode(SaslChallenge challenge)
         {
-            return CBUtil.bytesToCB(challenge.token);
+            return CBUtil.valueToCB(challenge.token);
         }
     };
 
@@ -45,7 +45,7 @@ public class SaslChallenge extends Message.Response
 
     public SaslChallenge(byte[] token)
     {
-        super(Message.Type.SASL_CHALLENGE);
+        super(Message.Type.AUTH_CHALLENGE);
         this.token = token;
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/1a70df0c/src/java/org/apache/cassandra/transport/messages/SaslResponse.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/messages/SaslResponse.java b/src/java/org/apache/cassandra/transport/messages/SaslResponse.java
index 604788e..9787ac5 100644
--- a/src/java/org/apache/cassandra/transport/messages/SaslResponse.java
+++ b/src/java/org/apache/cassandra/transport/messages/SaslResponse.java
@@ -43,13 +43,13 @@ public class SaslResponse extends Message.Request
             if (version == 1)
                 throw new ProtocolException("SASL Authentication is not supported in version 1 of the protocol");
 
-            return new SaslResponse(CBUtil.readBytes(body));
+            return new SaslResponse(CBUtil.readValue(body));
         }
 
         @Override
         public ChannelBuffer encode(SaslResponse response)
         {
-            return CBUtil.bytesToCB(response.token);
+            return CBUtil.valueToCB(response.token);
         }
     };
 
@@ -57,7 +57,7 @@ public class SaslResponse extends Message.Request
 
     public SaslResponse(byte[] token)
     {
-        super(Message.Type.SASL_RESPONSE);
+        super(Message.Type.AUTH_RESPONSE);
         this.token = token;
     }
 
@@ -73,13 +73,13 @@ public class SaslResponse extends Message.Request
         try
         {
             SaslAuthenticator authenticator = ((ServerConnection) connection).getAuthenticator();
-            byte[] challenge = authenticator.evaluateResponse(token);
+            byte[] challenge = authenticator.evaluateResponse(token == null ? new byte[0] : token);
             if (authenticator.isComplete())
             {
                 AuthenticatedUser user = authenticator.getAuthenticatedUser();
                 queryState.getClientState().login(user);
                 // authentication is complete, send a ready message to the client
-                return new ReadyMessage();
+                return new AuthSuccess(challenge);
             }
             else
             {