Repository: cassandra Updated Branches: refs/heads/trunk 298416a74 -> ac1bb7586
Extend IAuthenticator to accept peer SSL certificates patch by Dinesh Joshi; reviewed by jasobrown for CASSANDRA-14652 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/ac1bb758 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/ac1bb758 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/ac1bb758 Branch: refs/heads/trunk Commit: ac1bb75867a9a878a86d9b659234f78772627287 Parents: 298416a Author: Dinesh A. Joshi <dinesh.jo...@apple.com> Authored: Thu Aug 16 15:01:20 2018 -0700 Committer: Jason Brown <jasedbr...@gmail.com> Committed: Fri Aug 17 06:43:45 2018 -0700 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../apache/cassandra/auth/IAuthenticator.java | 18 +++++++++++ .../cassandra/transport/ServerConnection.java | 33 +++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/ac1bb758/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 0e671b0..d906879 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.0 + * Extend IAuthenticator to accept peer SSL certificates (CASSANDRA-14652) * Incomplete handling of exceptions when decoding incoming messages (CASSANDRA-14574) * Add diagnostic events for user audit logging (CASSANDRA-13668) * Allow retrieving diagnostic events via JMX (CASSANDRA-14435) http://git-wip-us.apache.org/repos/asf/cassandra/blob/ac1bb758/src/java/org/apache/cassandra/auth/IAuthenticator.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/IAuthenticator.java b/src/java/org/apache/cassandra/auth/IAuthenticator.java index 9eb50a7..212e774 100644 --- a/src/java/org/apache/cassandra/auth/IAuthenticator.java +++ b/src/java/org/apache/cassandra/auth/IAuthenticator.java @@ -21,6 +21,8 @@ import java.net.InetAddress; import java.util.Map; import java.util.Set; +import javax.security.cert.X509Certificate; + import org.apache.cassandra.exceptions.AuthenticationException; import org.apache.cassandra.exceptions.ConfigurationException; @@ -65,6 +67,22 @@ public interface IAuthenticator SaslNegotiator newSaslNegotiator(InetAddress clientAddress); /** + * Provide a SASL handler to perform authentication for an single connection. SASL + * is a stateful protocol, so a new instance must be used for each authentication + * attempt. This method accepts certificates as well. Authentication strategies can + * override this method to gain access to client's certificate chain, if present. + * @param clientAddress the IP address of the client whom we wish to authenticate, or null + * if an internal client (one not connected over the remote transport). + * @param certificates the peer's X509 Certificate chain, if present. + * @return org.apache.cassandra.auth.IAuthenticator.SaslNegotiator implementation + * (see {@link org.apache.cassandra.auth.PasswordAuthenticator.PlainTextSaslAuthenticator}) + */ + default SaslNegotiator newSaslNegotiator(InetAddress clientAddress, X509Certificate[] certificates) + { + return newSaslNegotiator(clientAddress); + } + + /** * A legacy method that is still used by JMX authentication. * * You should implement this for having JMX authentication through your http://git-wip-us.apache.org/repos/asf/cassandra/blob/ac1bb758/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 d78b7c0..00e334c 100644 --- a/src/java/org/apache/cassandra/transport/ServerConnection.java +++ b/src/java/org/apache/cassandra/transport/ServerConnection.java @@ -20,8 +20,15 @@ package org.apache.cassandra.transport; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.security.cert.X509Certificate; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import io.netty.channel.Channel; import com.codahale.metrics.Counter; +import io.netty.handler.ssl.SslHandler; import org.apache.cassandra.auth.IAuthenticator; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.service.ClientState; @@ -29,6 +36,7 @@ import org.apache.cassandra.service.QueryState; public class ServerConnection extends Connection { + private static Logger logger = LoggerFactory.getLogger(ServerConnection.class); private volatile IAuthenticator.SaslNegotiator saslNegotiator; private final ClientState clientState; @@ -124,7 +132,30 @@ public class ServerConnection extends Connection public IAuthenticator.SaslNegotiator getSaslNegotiator(QueryState queryState) { if (saslNegotiator == null) - saslNegotiator = DatabaseDescriptor.getAuthenticator().newSaslNegotiator(queryState.getClientAddress()); + saslNegotiator = DatabaseDescriptor.getAuthenticator() + .newSaslNegotiator(queryState.getClientAddress(), certificates()); return saslNegotiator; } + + private X509Certificate[] certificates() + { + SslHandler sslHandler = (SslHandler) channel().pipeline() + .get("ssl"); + X509Certificate[] certificates = null; + + if (sslHandler != null) + { + try + { + certificates = sslHandler.engine() + .getSession() + .getPeerCertificateChain(); + } + catch (SSLPeerUnverifiedException e) + { + logger.error("Failed to get peer certificates for peer {}", channel().remoteAddress(), e); + } + } + return certificates; + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org