Return-Path: X-Original-To: apmail-cassandra-commits-archive@www.apache.org Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4753310486 for ; Fri, 31 May 2013 11:25:47 +0000 (UTC) Received: (qmail 68776 invoked by uid 500); 31 May 2013 11:25:47 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 68549 invoked by uid 500); 31 May 2013 11:25:45 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 68519 invoked by uid 99); 31 May 2013 11:25:44 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 31 May 2013 11:25:44 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 9102489E922; Fri, 31 May 2013 11:25:43 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: slebresne@apache.org To: commits@cassandra.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: git commit: Adds AUTH_SUCCESS message as follow up to #5545 Date: Fri, 31 May 2013 11:25:43 +0000 (UTC) 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 Authored: Fri May 31 11:49:39 2013 +0200 Committer: Sylvain Lebresne 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 codec = new Message.Codec() + { + @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 {