From 1ae426eb3c908ba1cebb66878b90c0152c408ef4 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Sat, 23 Feb 2019 20:58:44 +0800 Subject: [PATCH 01/13] interface and mutual authn --- .../AuthenticationDataSource.java | 32 +++- .../AuthenticationProvider.java | 14 +- .../authentication/AuthenticationService.java | 4 + .../authentication/AuthenticationState.java | 47 ++++++ .../OneStageAuthenticationState.java | 59 +++++++ .../pulsar/broker/service/ServerCnx.java | 65 ++++++-- .../pulsar/client/api/Authentication.java | 20 ++- .../api/AuthenticationDataProvider.java | 28 +++- .../apache/pulsar/client/impl/ClientCnx.java | 60 ++++++- .../apache/pulsar/common/api/Commands.java | 57 +++++++ .../pulsar/common/api/proto/PulsarApi.java | 154 ++++++++++++++++++ pulsar-common/src/main/proto/PulsarApi.proto | 4 + 12 files changed, 507 insertions(+), 37 deletions(-) create mode 100644 pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java create mode 100644 pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java index 9fc6cbe532b3d..89c5129c424e8 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java @@ -18,6 +18,7 @@ */ package org.apache.pulsar.broker.authentication; +import java.io.IOException; import java.net.SocketAddress; import java.security.cert.Certificate; @@ -31,7 +32,7 @@ public interface AuthenticationDataSource { /** * Check if data from TLS are available. - * + * * @return true if this authentication data contain data from TLS */ default boolean hasDataFromTls() { @@ -39,7 +40,7 @@ default boolean hasDataFromTls() { } /** - * + * * @return a client certificate chain, or null if the data are not available */ default Certificate[] getTlsCertificates() { @@ -52,7 +53,7 @@ default Certificate[] getTlsCertificates() { /** * Check if data from HTTP are available. - * + * * @return true if this authentication data contain data from HTTP */ default boolean hasDataFromHttp() { @@ -60,7 +61,7 @@ default boolean hasDataFromHttp() { } /** - * + * * @return a authentication scheme, or null if the request is not be authenticated */ default String getHttpAuthType() { @@ -68,7 +69,7 @@ default String getHttpAuthType() { } /** - * + * * @return a String containing the value of the specified header, or null if the header * does not exist. */ @@ -82,7 +83,7 @@ default String getHttpHeader(String name) { /** * Check if data from Pulsar protocol are available. - * + * * @return true if this authentication data contain data from Pulsar protocol */ default boolean hasDataFromCommand() { @@ -90,20 +91,31 @@ default boolean hasDataFromCommand() { } /** - * + * * @return authentication data which is stored in a command */ default String getCommandData() { return null; } + /** + * For mutual authentication, This method use passed in `data` to evaluate and challenge, + * then returns null if authentication has completed; + * returns authenticated data back to client side, if authentication has not completed. + * + * used for mutual authentication like sasl. + */ + default byte[] authenticate(byte[] data) throws IOException { + throw new UnsupportedOperationException(); + } + /* * Peer */ /** * Check if data from peer are available. - * + * * @return true if this authentication data contain data from peer */ default boolean hasDataFromPeer() { @@ -111,10 +123,12 @@ default boolean hasDataFromPeer() { } /** - * + * * @return a String containing the IP address of the client */ default SocketAddress getPeerAddress() { return null; } + + } diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java index 6b957bac46486..eaf4cc89c25c7 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java @@ -47,7 +47,7 @@ public interface AuthenticationProvider extends Closeable { /** * Validate the authentication for the given credentials with the specified authentication data - * + * * @param authData * provider specific authentication data * @return the "role" string for the authenticated connection, if the authentication was successful @@ -56,4 +56,16 @@ public interface AuthenticationProvider extends Closeable { */ String authenticate(AuthenticationDataSource authData) throws AuthenticationException; + /** + * Get/Create an authentication data provider which provides the data that this broker will be sent to the client. + * Some authentication method need to auth between each client channel. + */ + default AuthenticationDataSource getAuthDataSource() throws IOException { + throw new UnsupportedOperationException(); + } + + default AuthenticationState newAuthState(AuthenticationDataSource authenticationDataSource) { + return new OneStageAuthenticationState(authenticationDataSource, this); + } + } diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java index 930f3d2e56f0d..33e336a820fa7 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java @@ -105,6 +105,10 @@ public String authenticateHttpRequest(HttpServletRequest request) throws Authent } } + public AuthenticationProvider getAuthenticationProvider(String authMethodName) { + return providers.get(authMethodName); + } + @Override public void close() throws IOException { for (AuthenticationProvider provider : providers.values()) { diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java new file mode 100644 index 0000000000000..552cfad78de92 --- /dev/null +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java @@ -0,0 +1,47 @@ +/** + * 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.pulsar.broker.authentication; + +import java.io.IOException; +import javax.naming.AuthenticationException; + +/** + * Interface for authentication state. + * + * It is basically holding the the authentication state. + * It tell broker whether the authentication is completed or not, + * if completed, what is the AuthRole is. + */ +public interface AuthenticationState { + AuthenticationDataSource getAuthData(); + + /** + * After the authentication between client and broker completed, + * get authentication role represent for the client. + * + */ + String getAuthRole() throws AuthenticationException; + + /** + * Returns null if authentication has completed, and no auth data is required to send back to client. + * Do auth and Returns the auth data back to client, if authentication has not completed. + */ + byte[] authenticate(byte[] authData) throws IOException; +} diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java new file mode 100644 index 0000000000000..e95e41d57ee21 --- /dev/null +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java @@ -0,0 +1,59 @@ +/** + * 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.pulsar.broker.authentication; + +import javax.naming.AuthenticationException; + +/** + * Interface for authentication state. + * + * It is basically holding the the authentication state. + * It tell broker whether the authentication is completed or not, + * if completed, what is the AuthRole is. + */ +public class OneStageAuthenticationState implements AuthenticationState { + + private AuthenticationDataSource authenticationDataSource; + AuthenticationProvider provider; + + public OneStageAuthenticationState(AuthenticationDataSource authenticationDataSource, + AuthenticationProvider provider) { + this.authenticationDataSource = authenticationDataSource; + this.provider = provider; + } + + @Override + public String getAuthRole() throws AuthenticationException { + return provider.authenticate(authenticationDataSource); + } + + @Override + public AuthenticationDataSource getAuthData() { + return authenticationDataSource; + } + + /** + * Returns null if authentication has completed, and no auth data is required to send back to client. + * Do auth and Returns the auth data back to client, if authentication has not completed. + */ + public byte[] authenticate(byte[] authData) { + return null; + } +} diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index 69db0165f556d..3b4196c7c764e 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -33,7 +33,9 @@ import io.netty.channel.ChannelOption; import io.netty.handler.ssl.SslHandler; +import java.io.IOException; import java.net.SocketAddress; +import java.nio.charset.Charset; import java.util.List; import java.util.Map; import java.util.Set; @@ -53,6 +55,8 @@ import org.apache.pulsar.broker.PulsarService; import org.apache.pulsar.broker.authentication.AuthenticationDataCommand; import org.apache.pulsar.broker.authentication.AuthenticationDataSource; +import org.apache.pulsar.broker.authentication.AuthenticationProvider; +import org.apache.pulsar.broker.authentication.AuthenticationState; import org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException; import org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException; import org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException; @@ -115,6 +119,8 @@ public class ServerCnx extends PulsarHandler { private volatile boolean isActive = true; String authRole = null; AuthenticationDataSource authenticationData; + AuthenticationProvider authenticationProvider; + AuthenticationState authState; // Max number of pending requests per connections. If multiple producers are sharing the same connection the flow // control done by a single producer might not be enough to prevent write spikes on the broker. @@ -129,6 +135,7 @@ public class ServerCnx extends PulsarHandler { private Set proxyRoles; private boolean authenticateOriginalAuthData; private final boolean schemaValidationEnforced; + private String authMethod = "none"; enum State { Start, Connected, Failed @@ -446,12 +453,15 @@ private String getOriginalPrincipal(String originalAuthData, String originalAuth return originalPrincipal; } + private boolean isMutualAuthenticationMethod() { + return false; + } + @Override protected void handleConnect(CommandConnect connect) { checkArgument(state == State.Start); if (service.isAuthenticationEnabled()) { try { - String authMethod = "none"; if (connect.hasAuthMethodName()) { authMethod = connect.getAuthMethodName(); } else if (connect.hasAuthMethod()) { @@ -459,23 +469,52 @@ protected void handleConnect(CommandConnect connect) { authMethod = connect.getAuthMethod().name().substring(10).toLowerCase(); } - String authData = connect.getAuthData().toStringUtf8(); - ChannelHandler sslHandler = ctx.channel().pipeline().get(PulsarChannelInitializer.TLS_HANDLER); - SSLSession sslSession = null; - if (sslHandler != null) { - sslSession = ((SslHandler) sslHandler).engine().getSession(); - } - originalPrincipal = getOriginalPrincipal( + byte[] clientData = connect.getAuthData().toByteArray(); + + // init authenticationState. + if (authState == null) { + ChannelHandler sslHandler = ctx.channel().pipeline().get(PulsarChannelInitializer.TLS_HANDLER); + SSLSession sslSession = null; + if (sslHandler != null) { + sslSession = ((SslHandler) sslHandler).engine().getSession(); + } + originalPrincipal = getOriginalPrincipal( connect.hasOriginalAuthData() ? connect.getOriginalAuthData() : null, connect.hasOriginalAuthMethod() ? connect.getOriginalAuthMethod() : null, connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null, sslSession); - authenticationData = new AuthenticationDataCommand(authData, remoteAddress, sslSession); - authRole = getBrokerService().getAuthenticationService() - .authenticate(authenticationData, authMethod); - log.info("[{}] Client successfully authenticated with {} role {} and originalPrincipal {}", remoteAddress, authMethod, authRole, originalPrincipal); - } catch (AuthenticationException e) { + authenticationProvider = getBrokerService() + .getAuthenticationService() + .getAuthenticationProvider(authMethod); + + if (isMutualAuthenticationMethod()) { + authenticationData = authenticationProvider.getAuthDataSource(); + } else { + authenticationData = new AuthenticationDataCommand( + new String(clientData, Charset.forName("UTF-8")), remoteAddress, sslSession); + } + authState = authenticationProvider.newAuthState(authenticationData); + } + + byte[] brokerData = authState.authenticate(clientData); + if (brokerData == null) { + // authentication has completed, will send newConnected command. + authRole = authState.getAuthRole(); + if (log.isDebugEnabled()) { + log.debug("[{}] Client successfully authenticated with {} role {} and originalPrincipal {}", + remoteAddress, authMethod, authRole, originalPrincipal); + } + } else { + // auth not complete, continue auth with client side. + ctx.writeAndFlush(Commands.newConnecting(authMethod, brokerData)); + if (log.isDebugEnabled()) { + log.debug("[{}] Client authenticated with {} continue auth with client.", + remoteAddress, authMethod); + } + return; + } + } catch (AuthenticationException | IOException e) { String msg = "Unable to authenticate"; log.warn("[{}] {}: {}", remoteAddress, msg, e.getMessage()); ctx.writeAndFlush(Commands.newError(-1, ServerError.AuthenticationError, msg)); diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Authentication.java b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Authentication.java index b3a2172677310..d3f83f9848a92 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Authentication.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Authentication.java @@ -21,6 +21,8 @@ import java.io.Closeable; import java.io.Serializable; import java.util.Map; +import javax.naming.AuthenticationException; +import org.apache.pulsar.client.api.PulsarClientException.UnsupportedAuthenticationException; /** * Interface of authentication providers. @@ -40,7 +42,23 @@ public interface Authentication extends Closeable, Serializable { * @throws PulsarClientException * any other error */ - AuthenticationDataProvider getAuthData() throws PulsarClientException; + default AuthenticationDataProvider getAuthData() throws PulsarClientException { + throw new UnsupportedAuthenticationException("Method not implemented!"); + } + + /** + * + * Get/Create an authentication data provider which provides the data that this client will be sent to the broker. + * Some authentication method need to auth between each client channel. So it need the broker, who it will talk to. + * + * @param brokerHostName + * target broker host name + * + * @return The authentication data provider + */ + default AuthenticationDataProvider getAuthData(String brokerHostName) throws PulsarClientException { + throw new UnsupportedAuthenticationException("Method not implemented!"); + } /** * Configure the authentication plugins with the supplied parameters diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java index e841d4e6832ce..a71d8c3fcd651 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java @@ -18,6 +18,7 @@ */ package org.apache.pulsar.client.api; +import java.io.IOException; import java.io.Serializable; import java.security.PrivateKey; import java.security.cert.Certificate; @@ -34,7 +35,7 @@ public interface AuthenticationDataProvider extends Serializable { /** * Check if data for TLS are available. - * + * * @return true if this authentication data contain data for TLS */ default boolean hasDataForTls() { @@ -42,7 +43,7 @@ default boolean hasDataForTls() { } /** - * + * * @return a client certificate chain, or null if the data are not available */ default Certificate[] getTlsCertificates() { @@ -50,7 +51,7 @@ default Certificate[] getTlsCertificates() { } /** - * + * * @return a private key for the client certificate, or null if the data are not available */ default PrivateKey getTlsPrivateKey() { @@ -63,7 +64,7 @@ default PrivateKey getTlsPrivateKey() { /** * Check if data for HTTP are available. - * + * * @return true if this authentication data contain data for HTTP */ default boolean hasDataForHttp() { @@ -71,7 +72,7 @@ default boolean hasDataForHttp() { } /** - * + * * @return a authentication scheme, or null if the request will not be authenticated */ default String getHttpAuthType() { @@ -79,7 +80,7 @@ default String getHttpAuthType() { } /** - * + * * @return an enumeration of all the header names */ default Set> getHttpHeaders() { @@ -92,7 +93,7 @@ default Set> getHttpHeaders() { /** * Check if data from Pulsar protocol are available. - * + * * @return true if this authentication data contain data from Pulsar protocol */ default boolean hasDataFromCommand() { @@ -100,11 +101,22 @@ default boolean hasDataFromCommand() { } /** - * + * * @return authentication data which will be stored in a command */ default String getCommandData() { return null; } + /** + * For mutual authentication, This method use passed in `data` to evaluate and challenge, + * then returns null if authentication has completed; + * returns authenticated data back to server side, if authentication has not completed. + * + * used for mutual authentication like sasl. + */ + default byte[] authenticate(byte[] data) throws IOException { + throw new UnsupportedOperationException(); + } + } diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java index bb8b98d0da0c7..430cdb7e8c9c9 100644 --- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java +++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java @@ -19,11 +19,14 @@ package org.apache.pulsar.client.impl; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static org.apache.pulsar.client.impl.HttpClient.getPulsarClientVersion; +import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.channels.ClosedChannelException; +import java.nio.charset.Charset; import java.util.List; import java.util.Optional; import java.util.concurrent.BlockingQueue; @@ -39,6 +42,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.http.conn.ssl.DefaultHostnameVerifier; import org.apache.pulsar.client.api.Authentication; +import org.apache.pulsar.client.api.AuthenticationDataProvider; import org.apache.pulsar.client.api.PulsarClientException; import org.apache.pulsar.client.api.PulsarClientException.TimeoutException; import org.apache.pulsar.client.impl.BinaryProtoLookupService.LookupDataResult; @@ -125,6 +129,9 @@ public class ClientCnx extends PulsarHandler { private final ScheduledFuture timeoutTask; + // Added for mutual authentication. + private AuthenticationDataProvider authenticationDataProvider; + enum State { None, SentConnectFrame, Ready, Failed } @@ -187,13 +194,32 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception { }); } - protected ByteBuf newConnectCommand() throws PulsarClientException { - String authData = ""; - if (authentication.getAuthData().hasDataFromCommand()) { + private boolean isMutualAuthenticationMethod() { + return false; + } + + protected ByteBuf newConnectCommand() throws IOException { + // mutual authentication is to auth between `remoteHostName` and this client for this channel. + // each channel will have a mutual client/server pair, mutual client evaluateChallenge with init data, + // and return authData to server. + if (isMutualAuthenticationMethod()) { + authenticationDataProvider = authentication.getAuthData(remoteHostName); + // this is the init evaluateChallenge. + byte[] authData = authenticationDataProvider.authenticate("init".getBytes()); + + return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, + getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); + + } else if (authentication.getAuthData().hasDataFromCommand()) { + String authData = ""; authData = authentication.getAuthData().getCommandData(); - } - return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, + return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); + } + + return Commands.newConnect(authentication.getAuthMethodName(), "", this.protocolVersion, + getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); + } @Override @@ -265,6 +291,30 @@ protected void handleConnected(CommandConnected connected) { return; } + // mutual authn. If auth not complete, continue auth; if auth complete, complete connectionFuture. + if (isMutualAuthenticationMethod()) { + try { + byte[] authData = authenticationDataProvider.authenticate(connected.getAuthData().toByteArray()); + + ByteBuf request = Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, + getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); + + ctx.writeAndFlush(request).addListener(writeFuture -> { + if (!writeFuture.isSuccess()) { + log.warn("{} Failed to send request for mutual auth to broker: {}", ctx.channel(), + writeFuture.cause().getMessage()); + connectionFuture.completeExceptionally(writeFuture.cause()); + } + }); + + return; + } catch (IOException e) { + log.error("{} Error mutual verify: {}", ctx.channel(), e); + connectionFuture.completeExceptionally(e); + return; + } + } + checkArgument(state == State.SentConnectFrame); if (log.isDebugEnabled()) { diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java index b047b56aa7665..61edc853c0796 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java @@ -150,6 +150,48 @@ public static ByteBuf newConnect(String authMethodName, String authData, int pro return res; } + public static ByteBuf newConnect(String authMethodName, byte[] authData, int protocolVersion, String libVersion, + String targetBroker, String originalPrincipal, String originalAuthData, + String originalAuthMethod) { + CommandConnect.Builder connectBuilder = CommandConnect.newBuilder(); + connectBuilder.setClientVersion(libVersion != null ? libVersion : "Pulsar Client"); + connectBuilder.setAuthMethodName(authMethodName); + + if ("ycav1".equals(authMethodName)) { + // Handle the case of a client that gets updated before the broker and starts sending the string auth method + // name. An example would be in broker-to-broker replication. We need to make sure the clients are still + // passing both the enum and the string until all brokers are upgraded. + connectBuilder.setAuthMethod(AuthMethod.AuthMethodYcaV1); + } + + if (targetBroker != null) { + // When connecting through a proxy, we need to specify which broker do we want to be proxied through + connectBuilder.setProxyToBrokerUrl(targetBroker); + } + + if (authData != null) { + connectBuilder.setAuthData(ByteString.copyFrom(authData)); + } + + if (originalPrincipal != null) { + connectBuilder.setOriginalPrincipal(originalPrincipal); + } + + if (originalAuthData != null) { + connectBuilder.setOriginalAuthData(originalAuthData); + } + + if (originalAuthMethod != null) { + connectBuilder.setOriginalAuthMethod(originalAuthMethod); + } + connectBuilder.setProtocolVersion(protocolVersion); + CommandConnect connect = connectBuilder.build(); + ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.CONNECT).setConnect(connect)); + connect.recycle(); + connectBuilder.recycle(); + return res; + } + public static ByteBuf newConnected(int clientProtocolVersion) { CommandConnected.Builder connectedBuilder = CommandConnected.newBuilder(); connectedBuilder.setServerVersion("Pulsar Server"); @@ -168,6 +210,21 @@ public static ByteBuf newConnected(int clientProtocolVersion) { return res; } + public static ByteBuf newConnecting(String authMethod, byte[] authData) { + CommandConnected.Builder connectedBuilder = CommandConnected.newBuilder(); + connectedBuilder.setServerVersion("Pulsar Server Mutual Authn"); + + CommandConnected connected = connectedBuilder + .setProtocolVersion(getCurrentProtocolVersion()) + .setAuthMethodName(authMethod) + .setAuthData(ByteString.copyFrom(authData)).build(); + + ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.CONNECTED).setConnected(connected)); + connected.recycle(); + connectedBuilder.recycle(); + return res; + } + public static ByteBuf newSuccess(long requestId) { CommandSuccess.Builder successBuilder = CommandSuccess.newBuilder(); successBuilder.setRequestId(requestId); diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java index 2940a99a508b1..884e94d446feb 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java @@ -6374,6 +6374,14 @@ public interface CommandConnectedOrBuilder // optional int32 protocol_version = 2 [default = 0]; boolean hasProtocolVersion(); int getProtocolVersion(); + + // optional string auth_method_name = 3; + boolean hasAuthMethodName(); + String getAuthMethodName(); + + // optional bytes auth_data = 4; + boolean hasAuthData(); + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthData(); } public static final class CommandConnected extends org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite @@ -6452,9 +6460,53 @@ public int getProtocolVersion() { return protocolVersion_; } + // optional string auth_method_name = 3; + public static final int AUTH_METHOD_NAME_FIELD_NUMBER = 3; + private java.lang.Object authMethodName_; + public boolean hasAuthMethodName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + public String getAuthMethodName() { + java.lang.Object ref = authMethodName_; + if (ref instanceof String) { + return (String) ref; + } else { + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString bs = + (org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref; + String s = bs.toStringUtf8(); + if (org.apache.pulsar.shaded.com.google.protobuf.v241.Internal.isValidUtf8(bs)) { + authMethodName_ = s; + } + return s; + } + } + private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthMethodNameBytes() { + java.lang.Object ref = authMethodName_; + if (ref instanceof String) { + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString b = + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.copyFromUtf8((String) ref); + authMethodName_ = b; + return b; + } else { + return (org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref; + } + } + + // optional bytes auth_data = 4; + public static final int AUTH_DATA_FIELD_NUMBER = 4; + private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString authData_; + public boolean hasAuthData() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + public org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthData() { + return authData_; + } + private void initFields() { serverVersion_ = ""; protocolVersion_ = 0; + authMethodName_ = ""; + authData_ = org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.EMPTY; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -6483,6 +6535,12 @@ public void writeTo(org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStr if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeInt32(2, protocolVersion_); } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getAuthMethodNameBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(4, authData_); + } } private int memoizedSerializedSize = -1; @@ -6499,6 +6557,14 @@ public int getSerializedSize() { size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream .computeInt32Size(2, protocolVersion_); } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeBytesSize(3, getAuthMethodNameBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeBytesSize(4, authData_); + } memoizedSerializedSize = size; return size; } @@ -6616,6 +6682,10 @@ public Builder clear() { bitField0_ = (bitField0_ & ~0x00000001); protocolVersion_ = 0; bitField0_ = (bitField0_ & ~0x00000002); + authMethodName_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + authData_ = org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000008); return this; } @@ -6657,6 +6727,14 @@ public org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected buildPartia to_bitField0_ |= 0x00000002; } result.protocolVersion_ = protocolVersion_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.authMethodName_ = authMethodName_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.authData_ = authData_; result.bitField0_ = to_bitField0_; return result; } @@ -6669,6 +6747,12 @@ public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandCon if (other.hasProtocolVersion()) { setProtocolVersion(other.getProtocolVersion()); } + if (other.hasAuthMethodName()) { + setAuthMethodName(other.getAuthMethodName()); + } + if (other.hasAuthData()) { + setAuthData(other.getAuthData()); + } return this; } @@ -6712,6 +6796,16 @@ public Builder mergeFrom( protocolVersion_ = input.readInt32(); break; } + case 26: { + bitField0_ |= 0x00000004; + authMethodName_ = input.readBytes(); + break; + } + case 34: { + bitField0_ |= 0x00000008; + authData_ = input.readBytes(); + break; + } } } } @@ -6775,6 +6869,66 @@ public Builder clearProtocolVersion() { return this; } + // optional string auth_method_name = 3; + private java.lang.Object authMethodName_ = ""; + public boolean hasAuthMethodName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + public String getAuthMethodName() { + java.lang.Object ref = authMethodName_; + if (!(ref instanceof String)) { + String s = ((org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref).toStringUtf8(); + authMethodName_ = s; + return s; + } else { + return (String) ref; + } + } + public Builder setAuthMethodName(String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + authMethodName_ = value; + + return this; + } + public Builder clearAuthMethodName() { + bitField0_ = (bitField0_ & ~0x00000004); + authMethodName_ = getDefaultInstance().getAuthMethodName(); + + return this; + } + void setAuthMethodName(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString value) { + bitField0_ |= 0x00000004; + authMethodName_ = value; + + } + + // optional bytes auth_data = 4; + private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString authData_ = org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.EMPTY; + public boolean hasAuthData() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + public org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthData() { + return authData_; + } + public Builder setAuthData(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + authData_ = value; + + return this; + } + public Builder clearAuthData() { + bitField0_ = (bitField0_ & ~0x00000008); + authData_ = getDefaultInstance().getAuthData(); + + return this; + } + // @@protoc_insertion_point(builder_scope:pulsar.proto.CommandConnected) } diff --git a/pulsar-common/src/main/proto/PulsarApi.proto b/pulsar-common/src/main/proto/PulsarApi.proto index 3f10d494671b3..4d14bc43043ab 100644 --- a/pulsar-common/src/main/proto/PulsarApi.proto +++ b/pulsar-common/src/main/proto/PulsarApi.proto @@ -197,6 +197,10 @@ message CommandConnect { message CommandConnected { required string server_version = 1; optional int32 protocol_version = 2 [default = 0]; + + // To support mutual authentication type, such as Sasl, reuse this command to mutual auth. + optional string auth_method_name = 3; + optional bytes auth_data = 4; } message CommandSubscribe { From f40b5fc9101b347da35152e2813dba9f80bd8d65 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Tue, 26 Feb 2019 19:58:22 +0800 Subject: [PATCH 02/13] align code in client/server.cnx --- .../AuthenticationProvider.java | 10 ++++--- .../authentication/AuthenticationState.java | 6 +++-- .../pulsar/broker/service/ServerCnx.java | 11 +------- .../pulsar/client/api/Authentication.java | 2 +- .../api/AuthenticationDataProvider.java | 3 ++- .../apache/pulsar/client/impl/ClientCnx.java | 26 +++---------------- 6 files changed, 19 insertions(+), 39 deletions(-) diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java index eaf4cc89c25c7..8ecd623d8ec02 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java @@ -21,8 +21,11 @@ import java.io.Closeable; import java.io.IOException; +import java.net.SocketAddress; +import java.nio.charset.Charset; import javax.naming.AuthenticationException; +import javax.net.ssl.SSLSession; import org.apache.pulsar.broker.ServiceConfiguration; /** @@ -58,10 +61,11 @@ public interface AuthenticationProvider extends Closeable { /** * Get/Create an authentication data provider which provides the data that this broker will be sent to the client. - * Some authentication method need to auth between each client channel. */ - default AuthenticationDataSource getAuthDataSource() throws IOException { - throw new UnsupportedOperationException(); + default AuthenticationDataSource getAuthDataSource(byte[] authData, SocketAddress remoteAddress, SSLSession sslSession) + throws IOException { + return new AuthenticationDataCommand( + new String(authData, Charset.forName("UTF-8")), remoteAddress, sslSession); } default AuthenticationState newAuthState(AuthenticationDataSource authenticationDataSource) { diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java index 552cfad78de92..841925d2cdf76 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java @@ -25,17 +25,19 @@ /** * Interface for authentication state. * - * It is basically holding the the authentication state. + * It is basically holding the authentication state. * It tell broker whether the authentication is completed or not, * if completed, what is the AuthRole is. */ public interface AuthenticationState { + /** + * Get AuthenticationDataSource for this authentication state. + */ AuthenticationDataSource getAuthData(); /** * After the authentication between client and broker completed, * get authentication role represent for the client. - * */ String getAuthRole() throws AuthenticationException; diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index 3b4196c7c764e..0e87844490b5a 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -453,10 +453,6 @@ private String getOriginalPrincipal(String originalAuthData, String originalAuth return originalPrincipal; } - private boolean isMutualAuthenticationMethod() { - return false; - } - @Override protected void handleConnect(CommandConnect connect) { checkArgument(state == State.Start); @@ -488,12 +484,7 @@ protected void handleConnect(CommandConnect connect) { .getAuthenticationService() .getAuthenticationProvider(authMethod); - if (isMutualAuthenticationMethod()) { - authenticationData = authenticationProvider.getAuthDataSource(); - } else { - authenticationData = new AuthenticationDataCommand( - new String(clientData, Charset.forName("UTF-8")), remoteAddress, sslSession); - } + authenticationData = authenticationProvider.getAuthDataSource(clientData, remoteAddress, sslSession); authState = authenticationProvider.newAuthState(authenticationData); } diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Authentication.java b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Authentication.java index d3f83f9848a92..8cb440722bb63 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Authentication.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Authentication.java @@ -57,7 +57,7 @@ default AuthenticationDataProvider getAuthData() throws PulsarClientException { * @return The authentication data provider */ default AuthenticationDataProvider getAuthData(String brokerHostName) throws PulsarClientException { - throw new UnsupportedAuthenticationException("Method not implemented!"); + return this.getAuthData(); } /** diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java index a71d8c3fcd651..3cc84968e0468 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.Serializable; +import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.cert.Certificate; import java.util.Map; @@ -116,7 +117,7 @@ default String getCommandData() { * used for mutual authentication like sasl. */ default byte[] authenticate(byte[] data) throws IOException { - throw new UnsupportedOperationException(); + return (hasDataFromCommand() ? this.getCommandData() : "").getBytes("UTF-8"); } } diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java index 430cdb7e8c9c9..07e6be6898ccd 100644 --- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java +++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java @@ -194,32 +194,14 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception { }); } - private boolean isMutualAuthenticationMethod() { - return false; - } - protected ByteBuf newConnectCommand() throws IOException { // mutual authentication is to auth between `remoteHostName` and this client for this channel. // each channel will have a mutual client/server pair, mutual client evaluateChallenge with init data, // and return authData to server. - if (isMutualAuthenticationMethod()) { - authenticationDataProvider = authentication.getAuthData(remoteHostName); - // this is the init evaluateChallenge. - byte[] authData = authenticationDataProvider.authenticate("init".getBytes()); - - return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, - getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); - - } else if (authentication.getAuthData().hasDataFromCommand()) { - String authData = ""; - authData = authentication.getAuthData().getCommandData(); - return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, - getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); - } - - return Commands.newConnect(authentication.getAuthMethodName(), "", this.protocolVersion, + authenticationDataProvider = authentication.getAuthData(remoteHostName); + byte[] authData = authenticationDataProvider.authenticate("init".getBytes("UTF-8")); + return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); - } @Override @@ -292,7 +274,7 @@ protected void handleConnected(CommandConnected connected) { } // mutual authn. If auth not complete, continue auth; if auth complete, complete connectionFuture. - if (isMutualAuthenticationMethod()) { + if (connected.hasAuthData()) { try { byte[] authData = authenticationDataProvider.authenticate(connected.getAuthData().toByteArray()); From 6bb065f113bcf6236e15e3c63630173b042c7f25 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Wed, 27 Feb 2019 20:35:21 +0800 Subject: [PATCH 03/13] wrap char[] into AuthData, fix error ut --- .../AuthenticationDataSource.java | 5 +- .../AuthenticationProvider.java | 8 +- .../authentication/AuthenticationService.java | 8 ++ .../authentication/AuthenticationState.java | 3 +- .../OneStageAuthenticationState.java | 3 +- .../pulsar/broker/service/ServerCnx.java | 136 ++++++++++-------- .../pulsar/broker/service/ServerCnxTest.java | 24 +++- .../api/AuthenticationDataProvider.java | 10 +- .../apache/pulsar/common/api/AuthData.java | 26 ++++ .../apache/pulsar/client/impl/ClientCnx.java | 8 +- .../apache/pulsar/common/api/Commands.java | 9 +- 11 files changed, 159 insertions(+), 81 deletions(-) create mode 100644 pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java index 89c5129c424e8..39b492201037e 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.net.SocketAddress; import java.security.cert.Certificate; +import org.apache.pulsar.common.api.AuthData; /** * Interface for accessing data which are used in variety of authentication schemes on server side @@ -105,7 +106,7 @@ default String getCommandData() { * * used for mutual authentication like sasl. */ - default byte[] authenticate(byte[] data) throws IOException { + default AuthData authenticate(AuthData data) throws IOException { throw new UnsupportedOperationException(); } @@ -129,6 +130,4 @@ default boolean hasDataFromPeer() { default SocketAddress getPeerAddress() { return null; } - - } diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java index 8ecd623d8ec02..44e609d243d17 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java @@ -27,6 +27,7 @@ import javax.net.ssl.SSLSession; import org.apache.pulsar.broker.ServiceConfiguration; +import org.apache.pulsar.common.api.AuthData; /** * Provider of authentication mechanism @@ -62,10 +63,11 @@ public interface AuthenticationProvider extends Closeable { /** * Get/Create an authentication data provider which provides the data that this broker will be sent to the client. */ - default AuthenticationDataSource getAuthDataSource(byte[] authData, SocketAddress remoteAddress, SSLSession sslSession) - throws IOException { + default AuthenticationDataSource getAuthDataSource(AuthData authData, + SocketAddress remoteAddress, + SSLSession sslSession) throws IOException { return new AuthenticationDataCommand( - new String(authData, Charset.forName("UTF-8")), remoteAddress, sslSession); + new String(authData.getBytes(), Charset.forName("UTF-8")), remoteAddress, sslSession); } default AuthenticationState newAuthState(AuthenticationDataSource authenticationDataSource) { diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java index 33e336a820fa7..b2628fce16d53 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java @@ -109,6 +109,14 @@ public AuthenticationProvider getAuthenticationProvider(String authMethodName) { return providers.get(authMethodName); } + public String getAnonymousUserRole() throws AuthenticationException { + if (StringUtils.isNotBlank(anonymousUserRole)) { + return anonymousUserRole; + } + // If at least a provider was configured, then the authentication needs to be provider + throw new AuthenticationException("Authentication required"); + } + @Override public void close() throws IOException { for (AuthenticationProvider provider : providers.values()) { diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java index 841925d2cdf76..a8bfcf9c95e68 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java @@ -21,6 +21,7 @@ import java.io.IOException; import javax.naming.AuthenticationException; +import org.apache.pulsar.common.api.AuthData; /** * Interface for authentication state. @@ -45,5 +46,5 @@ public interface AuthenticationState { * Returns null if authentication has completed, and no auth data is required to send back to client. * Do auth and Returns the auth data back to client, if authentication has not completed. */ - byte[] authenticate(byte[] authData) throws IOException; + AuthData authenticate(AuthData authData) throws IOException; } diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java index e95e41d57ee21..18693f8f7d052 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java @@ -20,6 +20,7 @@ package org.apache.pulsar.broker.authentication; import javax.naming.AuthenticationException; +import org.apache.pulsar.common.api.AuthData; /** * Interface for authentication state. @@ -53,7 +54,7 @@ public AuthenticationDataSource getAuthData() { * Returns null if authentication has completed, and no auth data is required to send back to client. * Do auth and Returns the auth data back to client, if authentication has not completed. */ - public byte[] authenticate(byte[] authData) { + public AuthData authenticate(AuthData authData) { return null; } } diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index 0e87844490b5a..1636a79cd903d 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -19,6 +19,7 @@ package org.apache.pulsar.broker.service; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.getPartitionedTopicMetadata; import static org.apache.pulsar.broker.lookup.TopicLookupBase.lookupTopicAsync; @@ -35,7 +36,6 @@ import java.io.IOException; import java.net.SocketAddress; -import java.nio.charset.Charset; import java.util.List; import java.util.Map; import java.util.Set; @@ -67,6 +67,7 @@ import org.apache.pulsar.client.impl.BatchMessageIdImpl; import org.apache.pulsar.client.impl.ClientCnx; import org.apache.pulsar.client.impl.MessageIdImpl; +import org.apache.pulsar.common.api.AuthData; import org.apache.pulsar.common.api.CommandUtils; import org.apache.pulsar.common.api.Commands; import org.apache.pulsar.common.api.PulsarHandler; @@ -138,7 +139,7 @@ public class ServerCnx extends PulsarHandler { private String authMethod = "none"; enum State { - Start, Connected, Failed + Start, Connected, Failed, Connecting } public ServerCnx(PulsarService pulsar) { @@ -453,75 +454,98 @@ private String getOriginalPrincipal(String originalAuthData, String originalAuth return originalPrincipal; } + // called in handleConnect method below. + private void completeConnect(CommandConnect connect) { + ctx.writeAndFlush(Commands.newConnected(connect.getProtocolVersion())); + state = State.Connected; + remoteEndpointProtocolVersion = connect.getProtocolVersion(); + String version = connect.hasClientVersion() ? connect.getClientVersion() : null; + if (isNotBlank(version) && !version.contains(" ") /* ignore default version: pulsar client */) { + this.clientVersion = version.intern(); + } + } + @Override protected void handleConnect(CommandConnect connect) { - checkArgument(state == State.Start); - if (service.isAuthenticationEnabled()) { - try { + checkArgument(state == State.Start || state == State.Connecting); + + if (log.isDebugEnabled()) { + log.debug("Received CONNECT from {}, auth enabled: {}", + remoteAddress, service.isAuthenticationEnabled()); + } + + if (!service.isAuthenticationEnabled()) { + completeConnect(connect); + return; + } + + try { + AuthData clientData = AuthData.of(connect.getAuthData().toByteArray()); + + // init authentication + if (state == State.Start) { if (connect.hasAuthMethodName()) { authMethod = connect.getAuthMethodName(); } else if (connect.hasAuthMethod()) { // Legacy client is passing enum authMethod = connect.getAuthMethod().name().substring(10).toLowerCase(); + } else { + authMethod = "none"; } - byte[] clientData = connect.getAuthData().toByteArray(); + authenticationProvider = getBrokerService() + .getAuthenticationService() + .getAuthenticationProvider(authMethod); - // init authenticationState. - if (authState == null) { - ChannelHandler sslHandler = ctx.channel().pipeline().get(PulsarChannelInitializer.TLS_HANDLER); - SSLSession sslSession = null; - if (sslHandler != null) { - sslSession = ((SslHandler) sslHandler).engine().getSession(); - } - originalPrincipal = getOriginalPrincipal( - connect.hasOriginalAuthData() ? connect.getOriginalAuthData() : null, - connect.hasOriginalAuthMethod() ? connect.getOriginalAuthMethod() : null, - connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null, - sslSession); - - authenticationProvider = getBrokerService() - .getAuthenticationService() - .getAuthenticationProvider(authMethod); - - authenticationData = authenticationProvider.getAuthDataSource(clientData, remoteAddress, sslSession); - authState = authenticationProvider.newAuthState(authenticationData); + // Not find provider named authMethod. Most used for tests. + // In AuthenticationDisabled, it will set authMethod "none". + if (authenticationProvider == null) { + authRole = getBrokerService().getAuthenticationService().getAnonymousUserRole(); + completeConnect(connect); + return; } - byte[] brokerData = authState.authenticate(clientData); - if (brokerData == null) { - // authentication has completed, will send newConnected command. - authRole = authState.getAuthRole(); - if (log.isDebugEnabled()) { - log.debug("[{}] Client successfully authenticated with {} role {} and originalPrincipal {}", - remoteAddress, authMethod, authRole, originalPrincipal); - } - } else { - // auth not complete, continue auth with client side. - ctx.writeAndFlush(Commands.newConnecting(authMethod, brokerData)); - if (log.isDebugEnabled()) { - log.debug("[{}] Client authenticated with {} continue auth with client.", - remoteAddress, authMethod); - } - return; + // init authState and other var + ChannelHandler sslHandler = ctx.channel().pipeline().get(PulsarChannelInitializer.TLS_HANDLER); + SSLSession sslSession = null; + if (sslHandler != null) { + sslSession = ((SslHandler) sslHandler).engine().getSession(); } - } catch (AuthenticationException | IOException e) { - String msg = "Unable to authenticate"; - log.warn("[{}] {}: {}", remoteAddress, msg, e.getMessage()); - ctx.writeAndFlush(Commands.newError(-1, ServerError.AuthenticationError, msg)); - close(); + originalPrincipal = getOriginalPrincipal( + connect.hasOriginalAuthData() ? connect.getOriginalAuthData() : null, + connect.hasOriginalAuthMethod() ? connect.getOriginalAuthMethod() : null, + connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null, + sslSession); + + authenticationData = authenticationProvider.getAuthDataSource(clientData, remoteAddress, sslSession); + authState = authenticationProvider.newAuthState(authenticationData); + } + + AuthData brokerData = authState.authenticate(clientData); + // authentication has completed, will send newConnected command. + if (brokerData == null || brokerData.getBytes() == null) { + authRole = authState.getAuthRole(); + if (log.isDebugEnabled()) { + log.debug("[{}] Client successfully authenticated with {} role {} and originalPrincipal {}", + remoteAddress, authMethod, authRole, originalPrincipal); + } + completeConnect(connect); return; } - } - if (log.isDebugEnabled()) { - log.debug("Received CONNECT from {}", remoteAddress); - } - ctx.writeAndFlush(Commands.newConnected(connect.getProtocolVersion())); - state = State.Connected; - remoteEndpointProtocolVersion = connect.getProtocolVersion(); - String version = connect.hasClientVersion() ? connect.getClientVersion() : null; - if (isNotBlank(version) && !version.contains(" ") /* ignore default version: pulsar client */) { - this.clientVersion = version.intern(); + + // auth not complete, continue auth with client side. + ctx.writeAndFlush(Commands.newConnecting(authMethod, brokerData)); + if (log.isDebugEnabled()) { + log.debug("[{}] Client authenticated with {} continue auth with client.", + remoteAddress, authMethod); + } + state = State.Connecting; + return; + } catch (Exception e) { + String msg = "Unable to authenticate"; + log.warn("[{}] {} ", remoteAddress, msg, e); + ctx.writeAndFlush(Commands.newError(-1, ServerError.AuthenticationError, msg)); + close(); } } diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java index 545817f8a5ffe..6298bbd0a4157 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java @@ -68,7 +68,10 @@ import org.apache.pulsar.broker.ServiceConfiguration; import org.apache.pulsar.broker.admin.AdminResource; import org.apache.pulsar.broker.authentication.AuthenticationDataCommand; +import org.apache.pulsar.broker.authentication.AuthenticationDataSource; +import org.apache.pulsar.broker.authentication.AuthenticationProvider; import org.apache.pulsar.broker.authentication.AuthenticationService; +import org.apache.pulsar.broker.authentication.AuthenticationState; import org.apache.pulsar.broker.authorization.AuthorizationService; import org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider; import org.apache.pulsar.broker.cache.ConfigurationCacheService; @@ -78,6 +81,7 @@ import org.apache.pulsar.broker.service.persistent.PersistentTopic; import org.apache.pulsar.broker.service.schema.DefaultSchemaRegistryService; import org.apache.pulsar.broker.service.utils.ClientChannelHelper; +import org.apache.pulsar.common.api.AuthData; import org.apache.pulsar.common.api.ByteBufPair; import org.apache.pulsar.common.api.Commands; import org.apache.pulsar.common.api.Commands.ChecksumType; @@ -334,9 +338,22 @@ public void testKeepAliveBeforeHandshake() throws Exception { @Test(timeOut = 30000) public void testConnectCommandWithAuthenticationPositive() throws Exception { AuthenticationService authenticationService = mock(AuthenticationService.class); + AuthenticationProvider authenticationProvider = mock(AuthenticationProvider.class); + AuthenticationState authenticationState = mock(AuthenticationState.class); + AuthenticationDataSource authenticationDataSource = mock(AuthenticationDataSource.class); + AuthData authData = AuthData.of(null); + doReturn(authenticationService).when(brokerService).getAuthenticationService(); - doReturn("appid1").when(authenticationService).authenticate(new AuthenticationDataCommand(Mockito.anyString()), - Mockito.anyString()); + doReturn(authenticationProvider).when(authenticationService).getAuthenticationProvider(Mockito.anyString()); + doReturn(authenticationDataSource).when(authenticationProvider) + .getAuthDataSource(Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject()); + doReturn(authenticationState).when(authenticationProvider) + .newAuthState(authenticationDataSource); + doReturn(authData).when(authenticationState) + .authenticate(authData); + doReturn("appid1").when(authenticationState) + .getAuthRole(); + doReturn(true).when(brokerService).isAuthenticationEnabled(); resetChannel(); @@ -357,8 +374,7 @@ public void testConnectCommandWithAuthenticationNegative() throws Exception { AuthenticationException e = new AuthenticationException(); AuthenticationService authenticationService = mock(AuthenticationService.class); doReturn(authenticationService).when(brokerService).getAuthenticationService(); - doThrow(e).when(authenticationService).authenticate(new AuthenticationDataCommand(Mockito.anyString()), - Mockito.anyString()); + doThrow(e).when(authenticationService).getAnonymousUserRole(); doReturn(true).when(brokerService).isAuthenticationEnabled(); resetChannel(); diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java index 3cc84968e0468..5aa37f4079d94 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java @@ -20,11 +20,11 @@ import java.io.IOException; import java.io.Serializable; -import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.cert.Certificate; import java.util.Map; import java.util.Set; +import org.apache.pulsar.common.api.AuthData; /** * Interface for accessing data which are used in variety of authentication schemes on client side @@ -114,10 +114,10 @@ default String getCommandData() { * then returns null if authentication has completed; * returns authenticated data back to server side, if authentication has not completed. * - * used for mutual authentication like sasl. + * Mainly used for mutual authentication like sasl. */ - default byte[] authenticate(byte[] data) throws IOException { - return (hasDataFromCommand() ? this.getCommandData() : "").getBytes("UTF-8"); + default AuthData authenticate(AuthData data) throws IOException { + byte[] bytes = (hasDataFromCommand() ? this.getCommandData() : "").getBytes("UTF-8"); + return AuthData.of(bytes); } - } diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java new file mode 100644 index 0000000000000..f99595a3706f7 --- /dev/null +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java @@ -0,0 +1,26 @@ +/** + * 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.pulsar.common.api; + +import lombok.Data; + +@Data(staticConstructor="of") +public class AuthData { + private final byte[] bytes; +} diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java index 07e6be6898ccd..cd5eb5de87ee1 100644 --- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java +++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java @@ -19,14 +19,12 @@ package org.apache.pulsar.client.impl; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; import static org.apache.pulsar.client.impl.HttpClient.getPulsarClientVersion; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.channels.ClosedChannelException; -import java.nio.charset.Charset; import java.util.List; import java.util.Optional; import java.util.concurrent.BlockingQueue; @@ -47,6 +45,7 @@ import org.apache.pulsar.client.api.PulsarClientException.TimeoutException; import org.apache.pulsar.client.impl.BinaryProtoLookupService.LookupDataResult; import org.apache.pulsar.client.impl.conf.ClientConfigurationData; +import org.apache.pulsar.common.api.AuthData; import org.apache.pulsar.common.api.Commands; import org.apache.pulsar.common.api.PulsarHandler; import org.apache.pulsar.common.api.proto.PulsarApi.CommandActiveConsumerChange; @@ -199,7 +198,7 @@ protected ByteBuf newConnectCommand() throws IOException { // each channel will have a mutual client/server pair, mutual client evaluateChallenge with init data, // and return authData to server. authenticationDataProvider = authentication.getAuthData(remoteHostName); - byte[] authData = authenticationDataProvider.authenticate("init".getBytes("UTF-8")); + AuthData authData = authenticationDataProvider.authenticate(AuthData.of("init".getBytes("UTF-8"))); return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); } @@ -276,7 +275,8 @@ protected void handleConnected(CommandConnected connected) { // mutual authn. If auth not complete, continue auth; if auth complete, complete connectionFuture. if (connected.hasAuthData()) { try { - byte[] authData = authenticationDataProvider.authenticate(connected.getAuthData().toByteArray()); + AuthData authData = authenticationDataProvider + .authenticate(AuthData.of(connected.getAuthData().toByteArray())); ByteBuf request = Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java index 61edc853c0796..c62ace39e3967 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java @@ -36,6 +36,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import lombok.Data; import org.apache.commons.lang3.tuple.Pair; import org.apache.pulsar.common.api.proto.PulsarApi; import org.apache.pulsar.common.api.proto.PulsarApi.AuthMethod; @@ -150,7 +151,7 @@ public static ByteBuf newConnect(String authMethodName, String authData, int pro return res; } - public static ByteBuf newConnect(String authMethodName, byte[] authData, int protocolVersion, String libVersion, + public static ByteBuf newConnect(String authMethodName, AuthData authData, int protocolVersion, String libVersion, String targetBroker, String originalPrincipal, String originalAuthData, String originalAuthMethod) { CommandConnect.Builder connectBuilder = CommandConnect.newBuilder(); @@ -170,7 +171,7 @@ public static ByteBuf newConnect(String authMethodName, byte[] authData, int pro } if (authData != null) { - connectBuilder.setAuthData(ByteString.copyFrom(authData)); + connectBuilder.setAuthData(ByteString.copyFrom(authData.getBytes())); } if (originalPrincipal != null) { @@ -210,14 +211,14 @@ public static ByteBuf newConnected(int clientProtocolVersion) { return res; } - public static ByteBuf newConnecting(String authMethod, byte[] authData) { + public static ByteBuf newConnecting(String authMethod, AuthData authData) { CommandConnected.Builder connectedBuilder = CommandConnected.newBuilder(); connectedBuilder.setServerVersion("Pulsar Server Mutual Authn"); CommandConnected connected = connectedBuilder .setProtocolVersion(getCurrentProtocolVersion()) .setAuthMethodName(authMethod) - .setAuthData(ByteString.copyFrom(authData)).build(); + .setAuthData(ByteString.copyFrom(authData.getBytes())).build(); ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.CONNECTED).setConnected(connected)); connected.recycle(); From ad35bfce82ef304dc790a63b08004cbbf281e6fa Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Thu, 28 Feb 2019 20:28:06 +0800 Subject: [PATCH 04/13] change following @ivankelly 's comments --- .../authentication/AuthenticationProvider.java | 4 ++-- .../authentication/AuthenticationState.java | 13 ++++++------- .../OneStageAuthenticationState.java | 18 +++++++++--------- .../pulsar/broker/service/ServerCnx.java | 5 ++--- .../pulsar/broker/service/ServerCnxTest.java | 6 ++++-- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java index 44e609d243d17..78148736bc543 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java @@ -61,9 +61,9 @@ public interface AuthenticationProvider extends Closeable { String authenticate(AuthenticationDataSource authData) throws AuthenticationException; /** - * Get/Create an authentication data provider which provides the data that this broker will be sent to the client. + * Create an authentication data provider which provides the data that this broker will be sent to the client. */ - default AuthenticationDataSource getAuthDataSource(AuthData authData, + default AuthenticationDataSource newAuthDataSource(AuthData authData, SocketAddress remoteAddress, SSLSession sslSession) throws IOException { return new AuthenticationDataCommand( diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java index a8bfcf9c95e68..e1acf8f47d9bc 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java @@ -31,11 +31,6 @@ * if completed, what is the AuthRole is. */ public interface AuthenticationState { - /** - * Get AuthenticationDataSource for this authentication state. - */ - AuthenticationDataSource getAuthData(); - /** * After the authentication between client and broker completed, * get authentication role represent for the client. @@ -43,8 +38,12 @@ public interface AuthenticationState { String getAuthRole() throws AuthenticationException; /** - * Returns null if authentication has completed, and no auth data is required to send back to client. - * Do auth and Returns the auth data back to client, if authentication has not completed. + * Challenge passed in auth data and get response data. */ AuthData authenticate(AuthData authData) throws IOException; + + /** + * Whether the authentication is completed or not + */ + boolean isComplete(); } diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java index 18693f8f7d052..7528bebdd2c84 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java @@ -31,8 +31,8 @@ */ public class OneStageAuthenticationState implements AuthenticationState { - private AuthenticationDataSource authenticationDataSource; - AuthenticationProvider provider; + private final AuthenticationDataSource authenticationDataSource; + private final AuthenticationProvider provider; public OneStageAuthenticationState(AuthenticationDataSource authenticationDataSource, AuthenticationProvider provider) { @@ -45,16 +45,16 @@ public String getAuthRole() throws AuthenticationException { return provider.authenticate(authenticationDataSource); } - @Override - public AuthenticationDataSource getAuthData() { - return authenticationDataSource; - } - /** - * Returns null if authentication has completed, and no auth data is required to send back to client. - * Do auth and Returns the auth data back to client, if authentication has not completed. + * Challenge passed in auth data and get response data. */ + @Override public AuthData authenticate(AuthData authData) { return null; } + + @Override + public boolean isComplete() { + return true; + } } diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index 1636a79cd903d..62e3240caa153 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -34,7 +34,6 @@ import io.netty.channel.ChannelOption; import io.netty.handler.ssl.SslHandler; -import java.io.IOException; import java.net.SocketAddress; import java.util.List; import java.util.Map; @@ -517,13 +516,13 @@ protected void handleConnect(CommandConnect connect) { connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null, sslSession); - authenticationData = authenticationProvider.getAuthDataSource(clientData, remoteAddress, sslSession); + authenticationData = authenticationProvider.newAuthDataSource(clientData, remoteAddress, sslSession); authState = authenticationProvider.newAuthState(authenticationData); } AuthData brokerData = authState.authenticate(clientData); // authentication has completed, will send newConnected command. - if (brokerData == null || brokerData.getBytes() == null) { + if (authState.isComplete()) { authRole = authState.getAuthRole(); if (log.isDebugEnabled()) { log.debug("[{}] Client successfully authenticated with {} role {} and originalPrincipal {}", diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java index 6298bbd0a4157..f3d58980dbb06 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java @@ -67,7 +67,6 @@ import org.apache.pulsar.broker.PulsarService; import org.apache.pulsar.broker.ServiceConfiguration; import org.apache.pulsar.broker.admin.AdminResource; -import org.apache.pulsar.broker.authentication.AuthenticationDataCommand; import org.apache.pulsar.broker.authentication.AuthenticationDataSource; import org.apache.pulsar.broker.authentication.AuthenticationProvider; import org.apache.pulsar.broker.authentication.AuthenticationService; @@ -346,11 +345,14 @@ public void testConnectCommandWithAuthenticationPositive() throws Exception { doReturn(authenticationService).when(brokerService).getAuthenticationService(); doReturn(authenticationProvider).when(authenticationService).getAuthenticationProvider(Mockito.anyString()); doReturn(authenticationDataSource).when(authenticationProvider) - .getAuthDataSource(Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject()); + .newAuthDataSource(Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject()); doReturn(authenticationState).when(authenticationProvider) .newAuthState(authenticationDataSource); doReturn(authData).when(authenticationState) .authenticate(authData); + doReturn(true).when(authenticationState) + .isComplete(); + doReturn("appid1").when(authenticationState) .getAuthRole(); From 12612f24c7169139c0505ab563203606e39933a9 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Fri, 1 Mar 2019 15:04:10 +0800 Subject: [PATCH 05/13] add CommandAuthChallenge/CommandAuthResponse for mutual authn --- .../pulsar/broker/service/ServerCnx.java | 153 +- .../apache/pulsar/common/api/AuthData.java | 4 + .../apache/pulsar/client/impl/ClientCnx.java | 67 +- .../apache/pulsar/common/api/Commands.java | 54 +- .../pulsar/common/api/PulsarDecoder.java | 22 + .../pulsar/common/api/proto/PulsarApi.java | 1852 +++++++++++++++-- pulsar-common/src/main/proto/PulsarApi.proto | 28 +- 7 files changed, 1914 insertions(+), 266 deletions(-) diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index 62e3240caa153..851a6652cf6f5 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -72,6 +72,7 @@ import org.apache.pulsar.common.api.PulsarHandler; import org.apache.pulsar.common.api.proto.PulsarApi; import org.apache.pulsar.common.api.proto.PulsarApi.CommandAck; +import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseProducer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandConnect; @@ -453,28 +454,56 @@ private String getOriginalPrincipal(String originalAuthData, String originalAuth return originalPrincipal; } - // called in handleConnect method below. - private void completeConnect(CommandConnect connect) { - ctx.writeAndFlush(Commands.newConnected(connect.getProtocolVersion())); + // complete the connect and sent newConnected command + private void completeConnect(int clientProtoVersion, String clientVersion) { + ctx.writeAndFlush(Commands.newConnected(clientProtoVersion)); state = State.Connected; - remoteEndpointProtocolVersion = connect.getProtocolVersion(); - String version = connect.hasClientVersion() ? connect.getClientVersion() : null; - if (isNotBlank(version) && !version.contains(" ") /* ignore default version: pulsar client */) { - this.clientVersion = version.intern(); + remoteEndpointProtocolVersion = clientProtoVersion; + if (isNotBlank(clientVersion) && !clientVersion.contains(" ") /* ignore default version: pulsar client */) { + this.clientVersion = clientVersion.intern(); } } + // According to auth result, send newConnected or newAuthResponse command. + private void doingAuthentication(AuthData clientData, + int clientProtocolVersion, + String clientVersion) throws Exception { + AuthData brokerData = authState.authenticate(clientData); + // authentication has completed, will send newConnected command. + if (authState.isComplete()) { + authRole = authState.getAuthRole(); + if (log.isDebugEnabled()) { + log.debug("[{}] Client successfully authenticated with {} role {} and originalPrincipal {}", + remoteAddress, authMethod, authRole, originalPrincipal); + } + completeConnect(clientProtocolVersion, clientVersion); + return; + } + + // auth not complete, continue auth with client side. + ctx.writeAndFlush(Commands.newAuthResponse(authMethod, brokerData, clientProtocolVersion)); + if (log.isDebugEnabled()) { + log.debug("[{}] Client authenticated with {} continue auth with client.", + remoteAddress, authMethod); + } + state = State.Connecting; + return; + } + @Override protected void handleConnect(CommandConnect connect) { - checkArgument(state == State.Start || state == State.Connecting); + checkArgument(state == State.Start); if (log.isDebugEnabled()) { log.debug("Received CONNECT from {}, auth enabled: {}", remoteAddress, service.isAuthenticationEnabled()); } + String clientVersion = connect.getClientVersion(); + int clientProtocolVersion = connect.getProtocolVersion(); + if (!service.isAuthenticationEnabled()) { - completeConnect(connect); + completeConnect(clientProtocolVersion, clientVersion); return; } @@ -482,64 +511,44 @@ protected void handleConnect(CommandConnect connect) { AuthData clientData = AuthData.of(connect.getAuthData().toByteArray()); // init authentication - if (state == State.Start) { - if (connect.hasAuthMethodName()) { - authMethod = connect.getAuthMethodName(); - } else if (connect.hasAuthMethod()) { - // Legacy client is passing enum - authMethod = connect.getAuthMethod().name().substring(10).toLowerCase(); - } else { - authMethod = "none"; - } - - authenticationProvider = getBrokerService() - .getAuthenticationService() - .getAuthenticationProvider(authMethod); - - // Not find provider named authMethod. Most used for tests. - // In AuthenticationDisabled, it will set authMethod "none". - if (authenticationProvider == null) { - authRole = getBrokerService().getAuthenticationService().getAnonymousUserRole(); - completeConnect(connect); - return; - } - - // init authState and other var - ChannelHandler sslHandler = ctx.channel().pipeline().get(PulsarChannelInitializer.TLS_HANDLER); - SSLSession sslSession = null; - if (sslHandler != null) { - sslSession = ((SslHandler) sslHandler).engine().getSession(); - } - originalPrincipal = getOriginalPrincipal( - connect.hasOriginalAuthData() ? connect.getOriginalAuthData() : null, - connect.hasOriginalAuthMethod() ? connect.getOriginalAuthMethod() : null, - connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null, - sslSession); - - authenticationData = authenticationProvider.newAuthDataSource(clientData, remoteAddress, sslSession); - authState = authenticationProvider.newAuthState(authenticationData); + if (connect.hasAuthMethodName()) { + authMethod = connect.getAuthMethodName(); + } else if (connect.hasAuthMethod()) { + // Legacy client is passing enum + authMethod = connect.getAuthMethod().name().substring(10).toLowerCase(); + } else { + authMethod = "none"; } - AuthData brokerData = authState.authenticate(clientData); - // authentication has completed, will send newConnected command. - if (authState.isComplete()) { - authRole = authState.getAuthRole(); - if (log.isDebugEnabled()) { - log.debug("[{}] Client successfully authenticated with {} role {} and originalPrincipal {}", - remoteAddress, authMethod, authRole, originalPrincipal); - } - completeConnect(connect); + authenticationProvider = getBrokerService() + .getAuthenticationService() + .getAuthenticationProvider(authMethod); + + // Not find provider named authMethod. Most used for tests. + // In AuthenticationDisabled, it will set authMethod "none". + if (authenticationProvider == null) { + authRole = getBrokerService().getAuthenticationService().getAnonymousUserRole(); + completeConnect(clientProtocolVersion, clientVersion); return; } - // auth not complete, continue auth with client side. - ctx.writeAndFlush(Commands.newConnecting(authMethod, brokerData)); - if (log.isDebugEnabled()) { - log.debug("[{}] Client authenticated with {} continue auth with client.", - remoteAddress, authMethod); + // init authState and other var + ChannelHandler sslHandler = ctx.channel().pipeline().get(PulsarChannelInitializer.TLS_HANDLER); + SSLSession sslSession = null; + if (sslHandler != null) { + sslSession = ((SslHandler) sslHandler).engine().getSession(); } - state = State.Connecting; - return; + originalPrincipal = getOriginalPrincipal( + connect.hasOriginalAuthData() ? connect.getOriginalAuthData() : null, + connect.hasOriginalAuthMethod() ? connect.getOriginalAuthMethod() : null, + connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null, + sslSession); + + authenticationData = authenticationProvider.newAuthDataSource(clientData, remoteAddress, sslSession); + authState = authenticationProvider.newAuthState(authenticationData); + + + doingAuthentication(clientData, clientProtocolVersion, clientVersion); } catch (Exception e) { String msg = "Unable to authenticate"; log.warn("[{}] {} ", remoteAddress, msg, e); @@ -548,6 +557,28 @@ protected void handleConnect(CommandConnect connect) { } } + @Override + protected void handleAuthChallenge(CommandAuthChallenge authChallenge) { + checkArgument(state == State.Connecting); + checkArgument(authChallenge.hasChallenge()); + checkArgument(authChallenge.getChallenge().hasAuthData() && authChallenge.getChallenge().hasAuthMethodName()); + + if (log.isDebugEnabled()) { + log.debug("Received AuthChallenge from {}, auth method: {}", + remoteAddress, authChallenge.getChallenge().getAuthMethodName()); + } + + try { + AuthData clientData = AuthData.of(authChallenge.getChallenge().getAuthData().toByteArray()); + doingAuthentication(clientData, authChallenge.getProtocolVersion(), authChallenge.getClientVersion()); + } catch (Exception e) { + String msg = "Unable to handleAuthChallenge"; + log.warn("[{}] {} ", remoteAddress, msg, e); + ctx.writeAndFlush(Commands.newError(-1, ServerError.AuthenticationError, msg)); + close(); + } + } + @Override protected void handleSubscribe(final CommandSubscribe subscribe) { checkArgument(state == State.Connected); diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java index f99595a3706f7..6a2578fddf619 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java @@ -23,4 +23,8 @@ @Data(staticConstructor="of") public class AuthData { private final byte[] bytes; + + public boolean isComplete() { + return bytes == null; + } } diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java index cd5eb5de87ee1..de381a0dc0cb8 100644 --- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java +++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java @@ -19,6 +19,7 @@ package org.apache.pulsar.client.impl; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static org.apache.pulsar.client.impl.HttpClient.getPulsarClientVersion; import java.io.IOException; @@ -49,6 +50,7 @@ import org.apache.pulsar.common.api.Commands; import org.apache.pulsar.common.api.PulsarHandler; import org.apache.pulsar.common.api.proto.PulsarApi.CommandActiveConsumerChange; +import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseProducer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected; @@ -132,7 +134,7 @@ public class ClientCnx extends PulsarHandler { private AuthenticationDataProvider authenticationDataProvider; enum State { - None, SentConnectFrame, Ready, Failed + None, SentConnectFrame, Ready, Failed, Connecting } static class RequestTime { @@ -272,32 +274,7 @@ protected void handleConnected(CommandConnected connected) { return; } - // mutual authn. If auth not complete, continue auth; if auth complete, complete connectionFuture. - if (connected.hasAuthData()) { - try { - AuthData authData = authenticationDataProvider - .authenticate(AuthData.of(connected.getAuthData().toByteArray())); - - ByteBuf request = Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, - getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); - - ctx.writeAndFlush(request).addListener(writeFuture -> { - if (!writeFuture.isSuccess()) { - log.warn("{} Failed to send request for mutual auth to broker: {}", ctx.channel(), - writeFuture.cause().getMessage()); - connectionFuture.completeExceptionally(writeFuture.cause()); - } - }); - - return; - } catch (IOException e) { - log.error("{} Error mutual verify: {}", ctx.channel(), e); - connectionFuture.completeExceptionally(e); - return; - } - } - - checkArgument(state == State.SentConnectFrame); + checkArgument(state == State.SentConnectFrame || state == State.Connecting); if (log.isDebugEnabled()) { log.debug("{} Connection is ready", ctx.channel()); @@ -308,6 +285,42 @@ protected void handleConnected(CommandConnected connected) { state = State.Ready; } + @Override + protected void handleAuthResponse(CommandAuthResponse authResponse) { + checkArgument(authResponse.hasResponse()); + checkArgument(authResponse.getResponse().hasAuthData() && authResponse.getResponse().hasAuthData()); + + // mutual authn. If auth not complete, continue auth; if auth complete, complete connectionFuture. + try { + AuthData authData = authenticationDataProvider + .authenticate(AuthData.of(authResponse.getResponse().getAuthData().toByteArray())); + + checkState(!authData.isComplete()); + + ByteBuf request = Commands.newAuthChallenge(authentication.getAuthMethodName(), + authData, + this.protocolVersion, + getPulsarClientVersion()); + + if (log.isDebugEnabled()) { + log.debug("{} Mutual auth {}", ctx.channel(), authentication.getAuthMethodName()); + } + + ctx.writeAndFlush(request).addListener(writeFuture -> { + if (!writeFuture.isSuccess()) { + log.warn("{} Failed to send request for mutual auth to broker: {}", ctx.channel(), + writeFuture.cause().getMessage()); + connectionFuture.completeExceptionally(writeFuture.cause()); + } + }); + state = State.Connecting; + } catch (IOException e) { + log.error("{} Error mutual verify: {}", ctx.channel(), e); + connectionFuture.completeExceptionally(e); + return; + } + } + @Override protected void handleSendReceipt(CommandSendReceipt sendReceipt) { checkArgument(state == State.Ready); diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java index c62ace39e3967..0c9eb1cf1cb22 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java @@ -36,7 +36,6 @@ import java.util.Optional; import java.util.stream.Collectors; -import lombok.Data; import org.apache.commons.lang3.tuple.Pair; import org.apache.pulsar.common.api.proto.PulsarApi; import org.apache.pulsar.common.api.proto.PulsarApi.AuthMethod; @@ -46,6 +45,8 @@ import org.apache.pulsar.common.api.proto.PulsarApi.CommandAck.AckType; import org.apache.pulsar.common.api.proto.PulsarApi.CommandAck.ValidationError; import org.apache.pulsar.common.api.proto.PulsarApi.CommandActiveConsumerChange; +import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge; +import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseProducer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandConnect; @@ -211,18 +212,49 @@ public static ByteBuf newConnected(int clientProtocolVersion) { return res; } - public static ByteBuf newConnecting(String authMethod, AuthData authData) { - CommandConnected.Builder connectedBuilder = CommandConnected.newBuilder(); - connectedBuilder.setServerVersion("Pulsar Server Mutual Authn"); + public static ByteBuf newAuthResponse(String authMethod, AuthData brokerData, int clientProtocolVersion) { + CommandAuthResponse.Builder responseBuilder = CommandAuthResponse.newBuilder(); - CommandConnected connected = connectedBuilder - .setProtocolVersion(getCurrentProtocolVersion()) - .setAuthMethodName(authMethod) - .setAuthData(ByteString.copyFrom(authData.getBytes())).build(); + // If the broker supports a newer version of the protocol, it will anyway advertise the max version that the + // client supports, to avoid confusing the client. + int currentProtocolVersion = getCurrentProtocolVersion(); + int versionToAdvertise = Math.min(currentProtocolVersion, clientProtocolVersion); - ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.CONNECTED).setConnected(connected)); - connected.recycle(); - connectedBuilder.recycle(); + responseBuilder.setProtocolVersion(versionToAdvertise); + responseBuilder.setServerVersion("Pulsar Server"); + + CommandAuthResponse response = responseBuilder + .setResponse(PulsarApi.AuthData.newBuilder() + .setAuthData(copyFrom(brokerData.getBytes())) + .setAuthMethodName(authMethod) + .build()) + .build(); + + ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_RESPONSE).setAuthResponse(response)); + response.recycle(); + responseBuilder.recycle(); + return res; + } + + public static ByteBuf newAuthChallenge(String authMethod, + AuthData clientData, + int clientProtocolVersion, + String clientVersion) { + CommandAuthChallenge.Builder challengeBuilder = CommandAuthChallenge.newBuilder(); + + challengeBuilder.setClientVersion(clientVersion != null ? clientVersion : "Pulsar Client"); + challengeBuilder.setProtocolVersion(clientProtocolVersion); + + CommandAuthChallenge challenge = challengeBuilder + .setChallenge(PulsarApi.AuthData.newBuilder() + .setAuthData(copyFrom(clientData.getBytes())) + .setAuthMethodName(authMethod) + .build()) + .build(); + + ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_CHALLENGE).setAuthChallenge(challenge)); + challenge.recycle(); + challengeBuilder.recycle(); return res; } diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/PulsarDecoder.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/PulsarDecoder.java index f8c2d61e3c252..0e1ea73c45eeb 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/PulsarDecoder.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/PulsarDecoder.java @@ -28,6 +28,8 @@ import org.apache.pulsar.common.api.proto.PulsarApi.BaseCommand; import org.apache.pulsar.common.api.proto.PulsarApi.CommandAck; import org.apache.pulsar.common.api.proto.PulsarApi.CommandActiveConsumerChange; +import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge; +import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseProducer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandConnect; @@ -303,6 +305,18 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception handleGetSchemaResponse(cmd.getGetSchemaResponse()); cmd.getGetSchemaResponse().recycle(); break; + + case AUTH_CHALLENGE: + checkArgument(cmd.hasAuthChallenge()); + handleAuthChallenge(cmd.getAuthChallenge()); + cmd.getAuthChallenge().recycle(); + break; + + case AUTH_RESPONSE: + checkArgument(cmd.hasAuthResponse()); + handleAuthResponse(cmd.getAuthResponse()); + cmd.getAuthResponse().recycle(); + break; } } finally { if (cmdBuilder != null) { @@ -454,5 +468,13 @@ protected void handleGetSchemaResponse(CommandGetSchemaResponse commandGetSchema throw new UnsupportedOperationException(); } + protected void handleAuthResponse(CommandAuthResponse commandAuthResponse) { + throw new UnsupportedOperationException(); + } + + protected void handleAuthChallenge(CommandAuthChallenge commandAuthChallenge) { + throw new UnsupportedOperationException(); + } + private static final Logger log = LoggerFactory.getLogger(PulsarDecoder.class); } diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java index 884e94d446feb..a03436e777033 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java @@ -207,6 +207,7 @@ public enum ProtocolVersion v11(11, 11), v12(12, 12), v13(13, 13), + v14(14, 14), ; public static final int v0_VALUE = 0; @@ -223,6 +224,7 @@ public enum ProtocolVersion public static final int v11_VALUE = 11; public static final int v12_VALUE = 12; public static final int v13_VALUE = 13; + public static final int v14_VALUE = 14; public final int getNumber() { return value; } @@ -243,6 +245,7 @@ public static ProtocolVersion valueOf(int value) { case 11: return v11; case 12: return v12; case 13: return v13; + case 14: return v14; default: return null; } } @@ -6374,14 +6377,6 @@ public interface CommandConnectedOrBuilder // optional int32 protocol_version = 2 [default = 0]; boolean hasProtocolVersion(); int getProtocolVersion(); - - // optional string auth_method_name = 3; - boolean hasAuthMethodName(); - String getAuthMethodName(); - - // optional bytes auth_data = 4; - boolean hasAuthData(); - org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthData(); } public static final class CommandConnected extends org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite @@ -6456,15 +6451,1439 @@ private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getServerVe public boolean hasProtocolVersion() { return ((bitField0_ & 0x00000002) == 0x00000002); } - public int getProtocolVersion() { - return protocolVersion_; + public int getProtocolVersion() { + return protocolVersion_; + } + + private void initFields() { + serverVersion_ = ""; + protocolVersion_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasServerVersion()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream output) + throws java.io.IOException { + throw new RuntimeException("Cannot use CodedOutputStream"); + } + + public void writeTo(org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getServerVersionBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeInt32(2, protocolVersion_); + } + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeBytesSize(1, getServerVersionBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeInt32Size(2, protocolVersion_); + } + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + throw new RuntimeException("Disabled"); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + throw new RuntimeException("Disabled"); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom(byte[] data) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data).buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + byte[] data, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data, extensionRegistry) + .buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom(java.io.InputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + java.io.InputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseDelimitedFrom( + java.io.InputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input, extensionRegistry)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + public static final class Builder extends + org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite.Builder< + org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected, Builder> + implements org.apache.pulsar.common.api.proto.PulsarApi.CommandConnectedOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder { + // Construct using org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected.newBuilder() + private final io.netty.util.Recycler.Handle handle; + private Builder(io.netty.util.Recycler.Handle handle) { + this.handle = handle; + maybeForceBuilderInitialization(); + } + private final static io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { + protected Builder newObject(io.netty.util.Recycler.Handle handle) { + return new Builder(handle); + } + }; + + public void recycle() { + clear(); + if (handle != null) {RECYCLER.recycle(this, handle);} + } + + private void maybeForceBuilderInitialization() { + } + private static Builder create() { + return RECYCLER.get(); + } + + public Builder clear() { + super.clear(); + serverVersion_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + protocolVersion_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected getDefaultInstanceForType() { + return org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected.getDefaultInstance(); + } + + public org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected build() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + private org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected buildParsed() + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException( + result).asInvalidProtocolBufferException(); + } + return result; + } + + public org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected buildPartial() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected result = org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected.RECYCLER.get(); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.serverVersion_ = serverVersion_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.protocolVersion_ = protocolVersion_; + result.bitField0_ = to_bitField0_; + return result; + } + + public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected other) { + if (other == org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected.getDefaultInstance()) return this; + if (other.hasServerVersion()) { + setServerVersion(other.getServerVersion()); + } + if (other.hasProtocolVersion()) { + setProtocolVersion(other.getProtocolVersion()); + } + return this; + } + + public final boolean isInitialized() { + if (!hasServerVersion()) { + + return false; + } + return true; + } + + public Builder mergeFrom(org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + throw new java.io.IOException("Merge from CodedInputStream is disabled"); + } + public Builder mergeFrom( + org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + + return this; + default: { + if (!input.skipField(tag)) { + + return this; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + serverVersion_ = input.readBytes(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + protocolVersion_ = input.readInt32(); + break; + } + } + } + } + + private int bitField0_; + + // required string server_version = 1; + private java.lang.Object serverVersion_ = ""; + public boolean hasServerVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + public String getServerVersion() { + java.lang.Object ref = serverVersion_; + if (!(ref instanceof String)) { + String s = ((org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref).toStringUtf8(); + serverVersion_ = s; + return s; + } else { + return (String) ref; + } + } + public Builder setServerVersion(String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + serverVersion_ = value; + + return this; + } + public Builder clearServerVersion() { + bitField0_ = (bitField0_ & ~0x00000001); + serverVersion_ = getDefaultInstance().getServerVersion(); + + return this; + } + void setServerVersion(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString value) { + bitField0_ |= 0x00000001; + serverVersion_ = value; + + } + + // optional int32 protocol_version = 2 [default = 0]; + private int protocolVersion_ ; + public boolean hasProtocolVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + public int getProtocolVersion() { + return protocolVersion_; + } + public Builder setProtocolVersion(int value) { + bitField0_ |= 0x00000002; + protocolVersion_ = value; + + return this; + } + public Builder clearProtocolVersion() { + bitField0_ = (bitField0_ & ~0x00000002); + protocolVersion_ = 0; + + return this; + } + + // @@protoc_insertion_point(builder_scope:pulsar.proto.CommandConnected) + } + + static { + defaultInstance = new CommandConnected(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandConnected) + } + + public interface CommandAuthChallengeOrBuilder + extends org.apache.pulsar.shaded.com.google.protobuf.v241.MessageLiteOrBuilder { + + // required string client_version = 1; + boolean hasClientVersion(); + String getClientVersion(); + + // required .pulsar.proto.AuthData challenge = 2; + boolean hasChallenge(); + org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge(); + + // optional int32 protocol_version = 3 [default = 0]; + boolean hasProtocolVersion(); + int getProtocolVersion(); + } + public static final class CommandAuthChallenge extends + org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite + implements CommandAuthChallengeOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage { + // Use CommandAuthChallenge.newBuilder() to construct. + private io.netty.util.Recycler.Handle handle; + private CommandAuthChallenge(io.netty.util.Recycler.Handle handle) { + this.handle = handle; + } + + private static final io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { + protected CommandAuthChallenge newObject(Handle handle) { + return new CommandAuthChallenge(handle); + } + }; + + public void recycle() { + this.initFields(); + this.memoizedIsInitialized = -1; + this.bitField0_ = 0; + this.memoizedSerializedSize = -1; + if (handle != null) { RECYCLER.recycle(this, handle); } + } + + private CommandAuthChallenge(boolean noInit) {} + + private static final CommandAuthChallenge defaultInstance; + public static CommandAuthChallenge getDefaultInstance() { + return defaultInstance; + } + + public CommandAuthChallenge getDefaultInstanceForType() { + return defaultInstance; + } + + private int bitField0_; + // required string client_version = 1; + public static final int CLIENT_VERSION_FIELD_NUMBER = 1; + private java.lang.Object clientVersion_; + public boolean hasClientVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + public String getClientVersion() { + java.lang.Object ref = clientVersion_; + if (ref instanceof String) { + return (String) ref; + } else { + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString bs = + (org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref; + String s = bs.toStringUtf8(); + if (org.apache.pulsar.shaded.com.google.protobuf.v241.Internal.isValidUtf8(bs)) { + clientVersion_ = s; + } + return s; + } + } + private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getClientVersionBytes() { + java.lang.Object ref = clientVersion_; + if (ref instanceof String) { + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString b = + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.copyFromUtf8((String) ref); + clientVersion_ = b; + return b; + } else { + return (org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref; + } + } + + // required .pulsar.proto.AuthData challenge = 2; + public static final int CHALLENGE_FIELD_NUMBER = 2; + private org.apache.pulsar.common.api.proto.PulsarApi.AuthData challenge_; + public boolean hasChallenge() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge() { + return challenge_; + } + + // optional int32 protocol_version = 3 [default = 0]; + public static final int PROTOCOL_VERSION_FIELD_NUMBER = 3; + private int protocolVersion_; + public boolean hasProtocolVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + public int getProtocolVersion() { + return protocolVersion_; + } + + private void initFields() { + clientVersion_ = ""; + challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + protocolVersion_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasClientVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasChallenge()) { + memoizedIsInitialized = 0; + return false; + } + if (!getChallenge().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream output) + throws java.io.IOException { + throw new RuntimeException("Cannot use CodedOutputStream"); + } + + public void writeTo(org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getClientVersionBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, challenge_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeInt32(3, protocolVersion_); + } + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeBytesSize(1, getClientVersionBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeMessageSize(2, challenge_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeInt32Size(3, protocolVersion_); + } + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + throw new RuntimeException("Disabled"); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + throw new RuntimeException("Disabled"); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom(byte[] data) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data).buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + byte[] data, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data, extensionRegistry) + .buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom(java.io.InputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + java.io.InputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseDelimitedFrom( + java.io.InputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input, extensionRegistry)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + public static final class Builder extends + org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite.Builder< + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge, Builder> + implements org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallengeOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder { + // Construct using org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.newBuilder() + private final io.netty.util.Recycler.Handle handle; + private Builder(io.netty.util.Recycler.Handle handle) { + this.handle = handle; + maybeForceBuilderInitialization(); + } + private final static io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { + protected Builder newObject(io.netty.util.Recycler.Handle handle) { + return new Builder(handle); + } + }; + + public void recycle() { + clear(); + if (handle != null) {RECYCLER.recycle(this, handle);} + } + + private void maybeForceBuilderInitialization() { + } + private static Builder create() { + return RECYCLER.get(); + } + + public Builder clear() { + super.clear(); + clientVersion_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + bitField0_ = (bitField0_ & ~0x00000002); + protocolVersion_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge getDefaultInstanceForType() { + return org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance(); + } + + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge build() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge buildParsed() + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException( + result).asInvalidProtocolBufferException(); + } + return result; + } + + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge buildPartial() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge result = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.RECYCLER.get(); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.clientVersion_ = clientVersion_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.challenge_ = challenge_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.protocolVersion_ = protocolVersion_; + result.bitField0_ = to_bitField0_; + return result; + } + + public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge other) { + if (other == org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance()) return this; + if (other.hasClientVersion()) { + setClientVersion(other.getClientVersion()); + } + if (other.hasChallenge()) { + mergeChallenge(other.getChallenge()); + } + if (other.hasProtocolVersion()) { + setProtocolVersion(other.getProtocolVersion()); + } + return this; + } + + public final boolean isInitialized() { + if (!hasClientVersion()) { + + return false; + } + if (!hasChallenge()) { + + return false; + } + if (!getChallenge().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom(org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + throw new java.io.IOException("Merge from CodedInputStream is disabled"); + } + public Builder mergeFrom( + org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + + return this; + default: { + if (!input.skipField(tag)) { + + return this; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + clientVersion_ = input.readBytes(); + break; + } + case 18: { + org.apache.pulsar.common.api.proto.PulsarApi.AuthData.Builder subBuilder = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(); + if (hasChallenge()) { + subBuilder.mergeFrom(getChallenge()); + } + input.readMessage(subBuilder, extensionRegistry); + setChallenge(subBuilder.buildPartial()); + subBuilder.recycle(); + break; + } + case 24: { + bitField0_ |= 0x00000004; + protocolVersion_ = input.readInt32(); + break; + } + } + } + } + + private int bitField0_; + + // required string client_version = 1; + private java.lang.Object clientVersion_ = ""; + public boolean hasClientVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + public String getClientVersion() { + java.lang.Object ref = clientVersion_; + if (!(ref instanceof String)) { + String s = ((org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref).toStringUtf8(); + clientVersion_ = s; + return s; + } else { + return (String) ref; + } + } + public Builder setClientVersion(String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + clientVersion_ = value; + + return this; + } + public Builder clearClientVersion() { + bitField0_ = (bitField0_ & ~0x00000001); + clientVersion_ = getDefaultInstance().getClientVersion(); + + return this; + } + void setClientVersion(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString value) { + bitField0_ |= 0x00000001; + clientVersion_ = value; + + } + + // required .pulsar.proto.AuthData challenge = 2; + private org.apache.pulsar.common.api.proto.PulsarApi.AuthData challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + public boolean hasChallenge() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge() { + return challenge_; + } + public Builder setChallenge(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { + if (value == null) { + throw new NullPointerException(); + } + challenge_ = value; + + bitField0_ |= 0x00000002; + return this; + } + public Builder setChallenge( + org.apache.pulsar.common.api.proto.PulsarApi.AuthData.Builder builderForValue) { + challenge_ = builderForValue.build(); + + bitField0_ |= 0x00000002; + return this; + } + public Builder mergeChallenge(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + challenge_ != org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance()) { + challenge_ = + org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(challenge_).mergeFrom(value).buildPartial(); + } else { + challenge_ = value; + } + + bitField0_ |= 0x00000002; + return this; + } + public Builder clearChallenge() { + challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + // optional int32 protocol_version = 3 [default = 0]; + private int protocolVersion_ ; + public boolean hasProtocolVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + public int getProtocolVersion() { + return protocolVersion_; + } + public Builder setProtocolVersion(int value) { + bitField0_ |= 0x00000004; + protocolVersion_ = value; + + return this; + } + public Builder clearProtocolVersion() { + bitField0_ = (bitField0_ & ~0x00000004); + protocolVersion_ = 0; + + return this; + } + + // @@protoc_insertion_point(builder_scope:pulsar.proto.CommandAuthChallenge) + } + + static { + defaultInstance = new CommandAuthChallenge(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandAuthChallenge) + } + + public interface CommandAuthResponseOrBuilder + extends org.apache.pulsar.shaded.com.google.protobuf.v241.MessageLiteOrBuilder { + + // required string server_version = 1; + boolean hasServerVersion(); + String getServerVersion(); + + // required .pulsar.proto.AuthData response = 2; + boolean hasResponse(); + org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse(); + + // optional int32 protocol_version = 3 [default = 0]; + boolean hasProtocolVersion(); + int getProtocolVersion(); + } + public static final class CommandAuthResponse extends + org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite + implements CommandAuthResponseOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage { + // Use CommandAuthResponse.newBuilder() to construct. + private io.netty.util.Recycler.Handle handle; + private CommandAuthResponse(io.netty.util.Recycler.Handle handle) { + this.handle = handle; + } + + private static final io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { + protected CommandAuthResponse newObject(Handle handle) { + return new CommandAuthResponse(handle); + } + }; + + public void recycle() { + this.initFields(); + this.memoizedIsInitialized = -1; + this.bitField0_ = 0; + this.memoizedSerializedSize = -1; + if (handle != null) { RECYCLER.recycle(this, handle); } + } + + private CommandAuthResponse(boolean noInit) {} + + private static final CommandAuthResponse defaultInstance; + public static CommandAuthResponse getDefaultInstance() { + return defaultInstance; + } + + public CommandAuthResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private int bitField0_; + // required string server_version = 1; + public static final int SERVER_VERSION_FIELD_NUMBER = 1; + private java.lang.Object serverVersion_; + public boolean hasServerVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + public String getServerVersion() { + java.lang.Object ref = serverVersion_; + if (ref instanceof String) { + return (String) ref; + } else { + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString bs = + (org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref; + String s = bs.toStringUtf8(); + if (org.apache.pulsar.shaded.com.google.protobuf.v241.Internal.isValidUtf8(bs)) { + serverVersion_ = s; + } + return s; + } + } + private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getServerVersionBytes() { + java.lang.Object ref = serverVersion_; + if (ref instanceof String) { + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString b = + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.copyFromUtf8((String) ref); + serverVersion_ = b; + return b; + } else { + return (org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref; + } + } + + // required .pulsar.proto.AuthData response = 2; + public static final int RESPONSE_FIELD_NUMBER = 2; + private org.apache.pulsar.common.api.proto.PulsarApi.AuthData response_; + public boolean hasResponse() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse() { + return response_; + } + + // optional int32 protocol_version = 3 [default = 0]; + public static final int PROTOCOL_VERSION_FIELD_NUMBER = 3; + private int protocolVersion_; + public boolean hasProtocolVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + public int getProtocolVersion() { + return protocolVersion_; + } + + private void initFields() { + serverVersion_ = ""; + response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + protocolVersion_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasServerVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasResponse()) { + memoizedIsInitialized = 0; + return false; + } + if (!getResponse().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream output) + throws java.io.IOException { + throw new RuntimeException("Cannot use CodedOutputStream"); + } + + public void writeTo(org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getServerVersionBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, response_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeInt32(3, protocolVersion_); + } + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeBytesSize(1, getServerVersionBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeMessageSize(2, response_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeInt32Size(3, protocolVersion_); + } + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + throw new RuntimeException("Disabled"); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + throw new RuntimeException("Disabled"); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom(byte[] data) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data).buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + byte[] data, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data, extensionRegistry) + .buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + java.io.InputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseDelimitedFrom( + java.io.InputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input, extensionRegistry)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + public static final class Builder extends + org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite.Builder< + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse, Builder> + implements org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponseOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder { + // Construct using org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.newBuilder() + private final io.netty.util.Recycler.Handle handle; + private Builder(io.netty.util.Recycler.Handle handle) { + this.handle = handle; + maybeForceBuilderInitialization(); + } + private final static io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { + protected Builder newObject(io.netty.util.Recycler.Handle handle) { + return new Builder(handle); + } + }; + + public void recycle() { + clear(); + if (handle != null) {RECYCLER.recycle(this, handle);} + } + + private void maybeForceBuilderInitialization() { + } + private static Builder create() { + return RECYCLER.get(); + } + + public Builder clear() { + super.clear(); + serverVersion_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + bitField0_ = (bitField0_ & ~0x00000002); + protocolVersion_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse getDefaultInstanceForType() { + return org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance(); + } + + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse build() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse buildParsed() + throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException( + result).asInvalidProtocolBufferException(); + } + return result; + } + + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse buildPartial() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse result = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.RECYCLER.get(); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.serverVersion_ = serverVersion_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.response_ = response_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.protocolVersion_ = protocolVersion_; + result.bitField0_ = to_bitField0_; + return result; + } + + public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse other) { + if (other == org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance()) return this; + if (other.hasServerVersion()) { + setServerVersion(other.getServerVersion()); + } + if (other.hasResponse()) { + mergeResponse(other.getResponse()); + } + if (other.hasProtocolVersion()) { + setProtocolVersion(other.getProtocolVersion()); + } + return this; + } + + public final boolean isInitialized() { + if (!hasServerVersion()) { + + return false; + } + if (!hasResponse()) { + + return false; + } + if (!getResponse().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom(org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + throw new java.io.IOException("Merge from CodedInputStream is disabled"); + } + public Builder mergeFrom( + org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream input, + org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + + return this; + default: { + if (!input.skipField(tag)) { + + return this; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + serverVersion_ = input.readBytes(); + break; + } + case 18: { + org.apache.pulsar.common.api.proto.PulsarApi.AuthData.Builder subBuilder = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(); + if (hasResponse()) { + subBuilder.mergeFrom(getResponse()); + } + input.readMessage(subBuilder, extensionRegistry); + setResponse(subBuilder.buildPartial()); + subBuilder.recycle(); + break; + } + case 24: { + bitField0_ |= 0x00000004; + protocolVersion_ = input.readInt32(); + break; + } + } + } + } + + private int bitField0_; + + // required string server_version = 1; + private java.lang.Object serverVersion_ = ""; + public boolean hasServerVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + public String getServerVersion() { + java.lang.Object ref = serverVersion_; + if (!(ref instanceof String)) { + String s = ((org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref).toStringUtf8(); + serverVersion_ = s; + return s; + } else { + return (String) ref; + } + } + public Builder setServerVersion(String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + serverVersion_ = value; + + return this; + } + public Builder clearServerVersion() { + bitField0_ = (bitField0_ & ~0x00000001); + serverVersion_ = getDefaultInstance().getServerVersion(); + + return this; + } + void setServerVersion(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString value) { + bitField0_ |= 0x00000001; + serverVersion_ = value; + + } + + // required .pulsar.proto.AuthData response = 2; + private org.apache.pulsar.common.api.proto.PulsarApi.AuthData response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + public boolean hasResponse() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse() { + return response_; + } + public Builder setResponse(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { + if (value == null) { + throw new NullPointerException(); + } + response_ = value; + + bitField0_ |= 0x00000002; + return this; + } + public Builder setResponse( + org.apache.pulsar.common.api.proto.PulsarApi.AuthData.Builder builderForValue) { + response_ = builderForValue.build(); + + bitField0_ |= 0x00000002; + return this; + } + public Builder mergeResponse(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + response_ != org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance()) { + response_ = + org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(response_).mergeFrom(value).buildPartial(); + } else { + response_ = value; + } + + bitField0_ |= 0x00000002; + return this; + } + public Builder clearResponse() { + response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + // optional int32 protocol_version = 3 [default = 0]; + private int protocolVersion_ ; + public boolean hasProtocolVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + public int getProtocolVersion() { + return protocolVersion_; + } + public Builder setProtocolVersion(int value) { + bitField0_ |= 0x00000004; + protocolVersion_ = value; + + return this; + } + public Builder clearProtocolVersion() { + bitField0_ = (bitField0_ & ~0x00000004); + protocolVersion_ = 0; + + return this; + } + + // @@protoc_insertion_point(builder_scope:pulsar.proto.CommandAuthResponse) + } + + static { + defaultInstance = new CommandAuthResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandAuthResponse) + } + + public interface AuthDataOrBuilder + extends org.apache.pulsar.shaded.com.google.protobuf.v241.MessageLiteOrBuilder { + + // required string auth_method_name = 1; + boolean hasAuthMethodName(); + String getAuthMethodName(); + + // required bytes auth_data = 2; + boolean hasAuthData(); + org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthData(); + } + public static final class AuthData extends + org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite + implements AuthDataOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage { + // Use AuthData.newBuilder() to construct. + private io.netty.util.Recycler.Handle handle; + private AuthData(io.netty.util.Recycler.Handle handle) { + this.handle = handle; + } + + private static final io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { + protected AuthData newObject(Handle handle) { + return new AuthData(handle); + } + }; + + public void recycle() { + this.initFields(); + this.memoizedIsInitialized = -1; + this.bitField0_ = 0; + this.memoizedSerializedSize = -1; + if (handle != null) { RECYCLER.recycle(this, handle); } + } + + private AuthData(boolean noInit) {} + + private static final AuthData defaultInstance; + public static AuthData getDefaultInstance() { + return defaultInstance; + } + + public AuthData getDefaultInstanceForType() { + return defaultInstance; } - // optional string auth_method_name = 3; - public static final int AUTH_METHOD_NAME_FIELD_NUMBER = 3; + private int bitField0_; + // required string auth_method_name = 1; + public static final int AUTH_METHOD_NAME_FIELD_NUMBER = 1; private java.lang.Object authMethodName_; public boolean hasAuthMethodName() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000001) == 0x00000001); } public String getAuthMethodName() { java.lang.Object ref = authMethodName_; @@ -6492,19 +7911,17 @@ private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthMeth } } - // optional bytes auth_data = 4; - public static final int AUTH_DATA_FIELD_NUMBER = 4; + // required bytes auth_data = 2; + public static final int AUTH_DATA_FIELD_NUMBER = 2; private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString authData_; public boolean hasAuthData() { - return ((bitField0_ & 0x00000008) == 0x00000008); + return ((bitField0_ & 0x00000002) == 0x00000002); } public org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthData() { return authData_; } private void initFields() { - serverVersion_ = ""; - protocolVersion_ = 0; authMethodName_ = ""; authData_ = org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.EMPTY; } @@ -6513,7 +7930,11 @@ public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized != -1) return isInitialized == 1; - if (!hasServerVersion()) { + if (!hasAuthMethodName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAuthData()) { memoizedIsInitialized = 0; return false; } @@ -6530,16 +7951,10 @@ public void writeTo(org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStr throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, getServerVersionBytes()); + output.writeBytes(1, getAuthMethodNameBytes()); } if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeInt32(2, protocolVersion_); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - output.writeBytes(3, getAuthMethodNameBytes()); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - output.writeBytes(4, authData_); + output.writeBytes(2, authData_); } } @@ -6551,19 +7966,11 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream - .computeBytesSize(1, getServerVersionBytes()); + .computeBytesSize(1, getAuthMethodNameBytes()); } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream - .computeInt32Size(2, protocolVersion_); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream - .computeBytesSize(3, getAuthMethodNameBytes()); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream - .computeBytesSize(4, authData_); + .computeBytesSize(2, authData_); } memoizedSerializedSize = size; return size; @@ -6576,40 +7983,40 @@ protected java.lang.Object writeReplace() return super.writeReplace(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { throw new RuntimeException("Disabled"); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { throw new RuntimeException("Disabled"); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom(byte[] data) + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseFrom(byte[] data) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { return newBuilder().mergeFrom(data).buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseFrom( byte[] data, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { return newBuilder().mergeFrom(data, extensionRegistry) .buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom(java.io.InputStream input) + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseFrom(java.io.InputStream input) throws java.io.IOException { return newBuilder().mergeFrom(input).buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseFrom( java.io.InputStream input, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return newBuilder().mergeFrom(input, extensionRegistry) .buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseDelimitedFrom(java.io.InputStream input) + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { Builder builder = newBuilder(); if (builder.mergeDelimitedFrom(input)) { @@ -6618,7 +8025,7 @@ public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected pars return null; } } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseDelimitedFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseDelimitedFrom( java.io.InputStream input, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -6629,12 +8036,12 @@ public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected pars return null; } } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input) throws java.io.IOException { return newBuilder().mergeFrom(input).buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.AuthData parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -6644,16 +8051,16 @@ public static org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected pars public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected prototype) { + public static Builder newBuilder(org.apache.pulsar.common.api.proto.PulsarApi.AuthData prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } public static final class Builder extends org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite.Builder< - org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected, Builder> - implements org.apache.pulsar.common.api.proto.PulsarApi.CommandConnectedOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder { - // Construct using org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected.newBuilder() + org.apache.pulsar.common.api.proto.PulsarApi.AuthData, Builder> + implements org.apache.pulsar.common.api.proto.PulsarApi.AuthDataOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder { + // Construct using org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder() private final io.netty.util.Recycler.Handle handle; private Builder(io.netty.util.Recycler.Handle handle) { this.handle = handle; @@ -6678,14 +8085,10 @@ private static Builder create() { public Builder clear() { super.clear(); - serverVersion_ = ""; - bitField0_ = (bitField0_ & ~0x00000001); - protocolVersion_ = 0; - bitField0_ = (bitField0_ & ~0x00000002); authMethodName_ = ""; - bitField0_ = (bitField0_ & ~0x00000004); + bitField0_ = (bitField0_ & ~0x00000001); authData_ = org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000008); + bitField0_ = (bitField0_ & ~0x00000002); return this; } @@ -6693,21 +8096,21 @@ public Builder clone() { return create().mergeFrom(buildPartial()); } - public org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected getDefaultInstanceForType() { - return org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected.getDefaultInstance(); + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getDefaultInstanceForType() { + return org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); } - public org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected build() { - org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected result = buildPartial(); + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData build() { + org.apache.pulsar.common.api.proto.PulsarApi.AuthData result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } - private org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected buildParsed() + private org.apache.pulsar.common.api.proto.PulsarApi.AuthData buildParsed() throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { - org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected result = buildPartial(); + org.apache.pulsar.common.api.proto.PulsarApi.AuthData result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException( result).asInvalidProtocolBufferException(); @@ -6715,38 +8118,24 @@ private org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected buildParse return result; } - public org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected buildPartial() { - org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected result = org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected.RECYCLER.get(); + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData buildPartial() { + org.apache.pulsar.common.api.proto.PulsarApi.AuthData result = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.RECYCLER.get(); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { to_bitField0_ |= 0x00000001; } - result.serverVersion_ = serverVersion_; + result.authMethodName_ = authMethodName_; if (((from_bitField0_ & 0x00000002) == 0x00000002)) { to_bitField0_ |= 0x00000002; } - result.protocolVersion_ = protocolVersion_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { - to_bitField0_ |= 0x00000004; - } - result.authMethodName_ = authMethodName_; - if (((from_bitField0_ & 0x00000008) == 0x00000008)) { - to_bitField0_ |= 0x00000008; - } result.authData_ = authData_; result.bitField0_ = to_bitField0_; return result; } - public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected other) { - if (other == org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected.getDefaultInstance()) return this; - if (other.hasServerVersion()) { - setServerVersion(other.getServerVersion()); - } - if (other.hasProtocolVersion()) { - setProtocolVersion(other.getProtocolVersion()); - } + public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.AuthData other) { + if (other == org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance()) return this; if (other.hasAuthMethodName()) { setAuthMethodName(other.getAuthMethodName()); } @@ -6757,7 +8146,11 @@ public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandCon } public final boolean isInitialized() { - if (!hasServerVersion()) { + if (!hasAuthMethodName()) { + + return false; + } + if (!hasAuthData()) { return false; } @@ -6788,21 +8181,11 @@ public Builder mergeFrom( } case 10: { bitField0_ |= 0x00000001; - serverVersion_ = input.readBytes(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - protocolVersion_ = input.readInt32(); - break; - } - case 26: { - bitField0_ |= 0x00000004; authMethodName_ = input.readBytes(); break; } - case 34: { - bitField0_ |= 0x00000008; + case 18: { + bitField0_ |= 0x00000002; authData_ = input.readBytes(); break; } @@ -6812,67 +8195,10 @@ public Builder mergeFrom( private int bitField0_; - // required string server_version = 1; - private java.lang.Object serverVersion_ = ""; - public boolean hasServerVersion() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - public String getServerVersion() { - java.lang.Object ref = serverVersion_; - if (!(ref instanceof String)) { - String s = ((org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString) ref).toStringUtf8(); - serverVersion_ = s; - return s; - } else { - return (String) ref; - } - } - public Builder setServerVersion(String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - serverVersion_ = value; - - return this; - } - public Builder clearServerVersion() { - bitField0_ = (bitField0_ & ~0x00000001); - serverVersion_ = getDefaultInstance().getServerVersion(); - - return this; - } - void setServerVersion(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString value) { - bitField0_ |= 0x00000001; - serverVersion_ = value; - - } - - // optional int32 protocol_version = 2 [default = 0]; - private int protocolVersion_ ; - public boolean hasProtocolVersion() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - public int getProtocolVersion() { - return protocolVersion_; - } - public Builder setProtocolVersion(int value) { - bitField0_ |= 0x00000002; - protocolVersion_ = value; - - return this; - } - public Builder clearProtocolVersion() { - bitField0_ = (bitField0_ & ~0x00000002); - protocolVersion_ = 0; - - return this; - } - - // optional string auth_method_name = 3; + // required string auth_method_name = 1; private java.lang.Object authMethodName_ = ""; public boolean hasAuthMethodName() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000001) == 0x00000001); } public String getAuthMethodName() { java.lang.Object ref = authMethodName_; @@ -6888,27 +8214,27 @@ public Builder setAuthMethodName(String value) { if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00000004; + bitField0_ |= 0x00000001; authMethodName_ = value; return this; } public Builder clearAuthMethodName() { - bitField0_ = (bitField0_ & ~0x00000004); + bitField0_ = (bitField0_ & ~0x00000001); authMethodName_ = getDefaultInstance().getAuthMethodName(); return this; } void setAuthMethodName(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString value) { - bitField0_ |= 0x00000004; + bitField0_ |= 0x00000001; authMethodName_ = value; } - // optional bytes auth_data = 4; + // required bytes auth_data = 2; private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString authData_ = org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.EMPTY; public boolean hasAuthData() { - return ((bitField0_ & 0x00000008) == 0x00000008); + return ((bitField0_ & 0x00000002) == 0x00000002); } public org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthData() { return authData_; @@ -6917,27 +8243,27 @@ public Builder setAuthData(org.apache.pulsar.shaded.com.google.protobuf.v241.Byt if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00000008; + bitField0_ |= 0x00000002; authData_ = value; return this; } public Builder clearAuthData() { - bitField0_ = (bitField0_ & ~0x00000008); + bitField0_ = (bitField0_ & ~0x00000002); authData_ = getDefaultInstance().getAuthData(); return this; } - // @@protoc_insertion_point(builder_scope:pulsar.proto.CommandConnected) + // @@protoc_insertion_point(builder_scope:pulsar.proto.AuthData) } static { - defaultInstance = new CommandConnected(true); + defaultInstance = new AuthData(true); defaultInstance.initFields(); } - // @@protoc_insertion_point(class_scope:pulsar.proto.CommandConnected) + // @@protoc_insertion_point(class_scope:pulsar.proto.AuthData) } public interface CommandSubscribeOrBuilder @@ -25252,6 +26578,14 @@ public interface BaseCommandOrBuilder // optional .pulsar.proto.CommandGetSchemaResponse getSchemaResponse = 35; boolean hasGetSchemaResponse(); org.apache.pulsar.common.api.proto.PulsarApi.CommandGetSchemaResponse getGetSchemaResponse(); + + // optional .pulsar.proto.CommandAuthChallenge authChallenge = 36; + boolean hasAuthChallenge(); + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge getAuthChallenge(); + + // optional .pulsar.proto.CommandAuthResponse authResponse = 37; + boolean hasAuthResponse(); + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse getAuthResponse(); } public static final class BaseCommand extends org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite @@ -25324,6 +26658,8 @@ public enum Type GET_TOPICS_OF_NAMESPACE_RESPONSE(31, 33), GET_SCHEMA(32, 34), GET_SCHEMA_RESPONSE(33, 35), + AUTH_CHALLENGE(34, 36), + AUTH_RESPONSE(35, 37), ; public static final int CONNECT_VALUE = 2; @@ -25360,6 +26696,8 @@ public enum Type public static final int GET_TOPICS_OF_NAMESPACE_RESPONSE_VALUE = 33; public static final int GET_SCHEMA_VALUE = 34; public static final int GET_SCHEMA_RESPONSE_VALUE = 35; + public static final int AUTH_CHALLENGE_VALUE = 36; + public static final int AUTH_RESPONSE_VALUE = 37; public final int getNumber() { return value; } @@ -25400,6 +26738,8 @@ public static Type valueOf(int value) { case 33: return GET_TOPICS_OF_NAMESPACE_RESPONSE; case 34: return GET_SCHEMA; case 35: return GET_SCHEMA_RESPONSE; + case 36: return AUTH_CHALLENGE; + case 37: return AUTH_RESPONSE; default: return null; } } @@ -25777,6 +27117,26 @@ public org.apache.pulsar.common.api.proto.PulsarApi.CommandGetSchemaResponse get return getSchemaResponse_; } + // optional .pulsar.proto.CommandAuthChallenge authChallenge = 36; + public static final int AUTHCHALLENGE_FIELD_NUMBER = 36; + private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge authChallenge_; + public boolean hasAuthChallenge() { + return ((bitField1_ & 0x00000008) == 0x00000008); + } + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge getAuthChallenge() { + return authChallenge_; + } + + // optional .pulsar.proto.CommandAuthResponse authResponse = 37; + public static final int AUTHRESPONSE_FIELD_NUMBER = 37; + private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse authResponse_; + public boolean hasAuthResponse() { + return ((bitField1_ & 0x00000010) == 0x00000010); + } + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse getAuthResponse() { + return authResponse_; + } + private void initFields() { type_ = org.apache.pulsar.common.api.proto.PulsarApi.BaseCommand.Type.CONNECT; connect_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandConnect.getDefaultInstance(); @@ -25813,6 +27173,8 @@ private void initFields() { getTopicsOfNamespaceResponse_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandGetTopicsOfNamespaceResponse.getDefaultInstance(); getSchema_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandGetSchema.getDefaultInstance(); getSchemaResponse_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandGetSchemaResponse.getDefaultInstance(); + authChallenge_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance(); + authResponse_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -26015,6 +27377,18 @@ public final boolean isInitialized() { return false; } } + if (hasAuthChallenge()) { + if (!getAuthChallenge().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasAuthResponse()) { + if (!getAuthResponse().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } memoizedIsInitialized = 1; return true; } @@ -26132,6 +27506,12 @@ public void writeTo(org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStr if (((bitField1_ & 0x00000004) == 0x00000004)) { output.writeMessage(35, getSchemaResponse_); } + if (((bitField1_ & 0x00000008) == 0x00000008)) { + output.writeMessage(36, authChallenge_); + } + if (((bitField1_ & 0x00000010) == 0x00000010)) { + output.writeMessage(37, authResponse_); + } } private int memoizedSerializedSize = -1; @@ -26280,6 +27660,14 @@ public int getSerializedSize() { size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream .computeMessageSize(35, getSchemaResponse_); } + if (((bitField1_ & 0x00000008) == 0x00000008)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeMessageSize(36, authChallenge_); + } + if (((bitField1_ & 0x00000010) == 0x00000010)) { + size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream + .computeMessageSize(37, authResponse_); + } memoizedSerializedSize = size; return size; } @@ -26463,6 +27851,10 @@ public Builder clear() { bitField1_ = (bitField1_ & ~0x00000002); getSchemaResponse_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandGetSchemaResponse.getDefaultInstance(); bitField1_ = (bitField1_ & ~0x00000004); + authChallenge_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance(); + bitField1_ = (bitField1_ & ~0x00000008); + authResponse_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance(); + bitField1_ = (bitField1_ & ~0x00000010); return this; } @@ -26638,6 +28030,14 @@ public org.apache.pulsar.common.api.proto.PulsarApi.BaseCommand buildPartial() { to_bitField1_ |= 0x00000004; } result.getSchemaResponse_ = getSchemaResponse_; + if (((from_bitField1_ & 0x00000008) == 0x00000008)) { + to_bitField1_ |= 0x00000008; + } + result.authChallenge_ = authChallenge_; + if (((from_bitField1_ & 0x00000010) == 0x00000010)) { + to_bitField1_ |= 0x00000010; + } + result.authResponse_ = authResponse_; result.bitField0_ = to_bitField0_; result.bitField1_ = to_bitField1_; return result; @@ -26750,6 +28150,12 @@ public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.BaseComman if (other.hasGetSchemaResponse()) { mergeGetSchemaResponse(other.getGetSchemaResponse()); } + if (other.hasAuthChallenge()) { + mergeAuthChallenge(other.getAuthChallenge()); + } + if (other.hasAuthResponse()) { + mergeAuthResponse(other.getAuthResponse()); + } return this; } @@ -26950,6 +28356,18 @@ public final boolean isInitialized() { return false; } } + if (hasAuthChallenge()) { + if (!getAuthChallenge().isInitialized()) { + + return false; + } + } + if (hasAuthResponse()) { + if (!getAuthResponse().isInitialized()) { + + return false; + } + } return true; } @@ -27324,6 +28742,26 @@ public Builder mergeFrom( subBuilder.recycle(); break; } + case 290: { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.Builder subBuilder = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.newBuilder(); + if (hasAuthChallenge()) { + subBuilder.mergeFrom(getAuthChallenge()); + } + input.readMessage(subBuilder, extensionRegistry); + setAuthChallenge(subBuilder.buildPartial()); + subBuilder.recycle(); + break; + } + case 298: { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.Builder subBuilder = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.newBuilder(); + if (hasAuthResponse()) { + subBuilder.mergeFrom(getAuthResponse()); + } + input.readMessage(subBuilder, extensionRegistry); + setAuthResponse(subBuilder.buildPartial()); + subBuilder.recycle(); + break; + } } } } @@ -28817,6 +30255,92 @@ public Builder clearGetSchemaResponse() { return this; } + // optional .pulsar.proto.CommandAuthChallenge authChallenge = 36; + private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge authChallenge_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance(); + public boolean hasAuthChallenge() { + return ((bitField1_ & 0x00000008) == 0x00000008); + } + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge getAuthChallenge() { + return authChallenge_; + } + public Builder setAuthChallenge(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge value) { + if (value == null) { + throw new NullPointerException(); + } + authChallenge_ = value; + + bitField1_ |= 0x00000008; + return this; + } + public Builder setAuthChallenge( + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.Builder builderForValue) { + authChallenge_ = builderForValue.build(); + + bitField1_ |= 0x00000008; + return this; + } + public Builder mergeAuthChallenge(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge value) { + if (((bitField1_ & 0x00000008) == 0x00000008) && + authChallenge_ != org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance()) { + authChallenge_ = + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.newBuilder(authChallenge_).mergeFrom(value).buildPartial(); + } else { + authChallenge_ = value; + } + + bitField1_ |= 0x00000008; + return this; + } + public Builder clearAuthChallenge() { + authChallenge_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance(); + + bitField1_ = (bitField1_ & ~0x00000008); + return this; + } + + // optional .pulsar.proto.CommandAuthResponse authResponse = 37; + private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse authResponse_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance(); + public boolean hasAuthResponse() { + return ((bitField1_ & 0x00000010) == 0x00000010); + } + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse getAuthResponse() { + return authResponse_; + } + public Builder setAuthResponse(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse value) { + if (value == null) { + throw new NullPointerException(); + } + authResponse_ = value; + + bitField1_ |= 0x00000010; + return this; + } + public Builder setAuthResponse( + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.Builder builderForValue) { + authResponse_ = builderForValue.build(); + + bitField1_ |= 0x00000010; + return this; + } + public Builder mergeAuthResponse(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse value) { + if (((bitField1_ & 0x00000010) == 0x00000010) && + authResponse_ != org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance()) { + authResponse_ = + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.newBuilder(authResponse_).mergeFrom(value).buildPartial(); + } else { + authResponse_ = value; + } + + bitField1_ |= 0x00000010; + return this; + } + public Builder clearAuthResponse() { + authResponse_ = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance(); + + bitField1_ = (bitField1_ & ~0x00000010); + return this; + } + // @@protoc_insertion_point(builder_scope:pulsar.proto.BaseCommand) } diff --git a/pulsar-common/src/main/proto/PulsarApi.proto b/pulsar-common/src/main/proto/PulsarApi.proto index 4d14bc43043ab..40e7f20d45eaf 100644 --- a/pulsar-common/src/main/proto/PulsarApi.proto +++ b/pulsar-common/src/main/proto/PulsarApi.proto @@ -168,6 +168,7 @@ enum ProtocolVersion { // Added CommandActiveConsumerChange // Added CommandGetTopicsOfNamespace v13 = 13; // Schema-registry : added avro schema format for json + v14 = 14; // Add CommandAuthChallenge and CommandAuthResponse for mutual auth } message CommandConnect { @@ -197,10 +198,24 @@ message CommandConnect { message CommandConnected { required string server_version = 1; optional int32 protocol_version = 2 [default = 0]; +} + +message CommandAuthChallenge { + required string client_version = 1; + required AuthData challenge = 2; + optional int32 protocol_version = 3 [default = 0]; +} + +message CommandAuthResponse { + required string server_version = 1; + required AuthData response = 2; + optional int32 protocol_version = 3 [default = 0]; +} - // To support mutual authentication type, such as Sasl, reuse this command to mutual auth. - optional string auth_method_name = 3; - optional bytes auth_data = 4; +// To support mutual authentication type, such as Sasl, reuse this command to mutual auth. +message AuthData { + required string auth_method_name = 1; + required bytes auth_data = 2; } message CommandSubscribe { @@ -602,6 +617,9 @@ message BaseCommand { GET_SCHEMA = 34; GET_SCHEMA_RESPONSE = 35; + + AUTH_CHALLENGE = 36; + AUTH_RESPONSE = 37; } @@ -654,4 +672,8 @@ message BaseCommand { optional CommandGetSchema getSchema = 34; optional CommandGetSchemaResponse getSchemaResponse = 35; + + optional CommandAuthChallenge authChallenge = 36; + optional CommandAuthResponse authResponse = 37; + } From a51c9287604ec5cdb4da7e04ae7c0f7aaa976dc2 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Fri, 1 Mar 2019 16:34:06 +0800 Subject: [PATCH 06/13] fix cpp build error --- pulsar-client-cpp/lib/Commands.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pulsar-client-cpp/lib/Commands.cc b/pulsar-client-cpp/lib/Commands.cc index 726939f4c0c80..06b96f9032b7d 100644 --- a/pulsar-client-cpp/lib/Commands.cc +++ b/pulsar-client-cpp/lib/Commands.cc @@ -515,6 +515,12 @@ std::string Commands::messageType(BaseCommand_Type type) { case BaseCommand::GET_SCHEMA_RESPONSE: return "GET_SCHEMA_RESPONSE"; break; + case BaseCommand::AUTH_CHALLENGE: + return "AUTH_CHALLENGE"; + break; + case BaseCommand::AUTH_RESPONSE: + return "AUTH_RESPONSE"; + break; }; } From b33791ea4d8aeea039b907b53fc97b10be7ce28a Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Fri, 1 Mar 2019 20:59:49 +0800 Subject: [PATCH 07/13] change following enrico's comments --- .../broker/authentication/AuthenticationDataSource.java | 7 ++----- .../broker/authentication/AuthenticationService.java | 2 +- .../java/org/apache/pulsar/broker/service/ServerCnx.java | 2 +- .../main/java/org/apache/pulsar/common/api/AuthData.java | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java index 39b492201037e..fcc6dda28ee5c 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataSource.java @@ -100,11 +100,8 @@ default String getCommandData() { } /** - * For mutual authentication, This method use passed in `data` to evaluate and challenge, - * then returns null if authentication has completed; - * returns authenticated data back to client side, if authentication has not completed. - * - * used for mutual authentication like sasl. + * Evaluate and challenge the data that passed in, and return processed data back. + * It is used for mutual authentication like SASL. */ default AuthData authenticate(AuthData data) throws IOException { throw new UnsupportedOperationException(); diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java index b2628fce16d53..0a40c66160859 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java @@ -113,7 +113,7 @@ public String getAnonymousUserRole() throws AuthenticationException { if (StringUtils.isNotBlank(anonymousUserRole)) { return anonymousUserRole; } - // If at least a provider was configured, then the authentication needs to be provider + // If at least a provider was configured, then the authentication needs to be provided throw new AuthenticationException("Authentication required"); } diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index 851a6652cf6f5..7a04e6c704216 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -483,7 +483,7 @@ private void doingAuthentication(AuthData clientData, // auth not complete, continue auth with client side. ctx.writeAndFlush(Commands.newAuthResponse(authMethod, brokerData, clientProtocolVersion)); if (log.isDebugEnabled()) { - log.debug("[{}] Client authenticated with {} continue auth with client.", + log.debug("[{}] Authentication in progress client by method {}.", remoteAddress, authMethod); } state = State.Connecting; diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java index 6a2578fddf619..1f060e405b1ab 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java @@ -21,7 +21,7 @@ import lombok.Data; @Data(staticConstructor="of") -public class AuthData { +public final class AuthData { private final byte[] bytes; public boolean isComplete() { From 7c6ffae680a0c403e208fe26b0a3d2e3a5a6cda4 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Sat, 2 Mar 2019 14:23:00 +0800 Subject: [PATCH 08/13] change following ivan's comments --- .../pulsar/broker/service/ServerCnx.java | 23 +- .../apache/pulsar/client/impl/ClientCnx.java | 12 +- .../apache/pulsar/common/api/Commands.java | 36 +- .../pulsar/common/api/proto/PulsarApi.java | 312 +++++++++--------- pulsar-common/src/main/proto/PulsarApi.proto | 8 +- 5 files changed, 195 insertions(+), 196 deletions(-) diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index 7a04e6c704216..89281f2cd4800 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -19,7 +19,6 @@ package org.apache.pulsar.broker.service; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.getPartitionedTopicMetadata; import static org.apache.pulsar.broker.lookup.TopicLookupBase.lookupTopicAsync; @@ -72,7 +71,7 @@ import org.apache.pulsar.common.api.PulsarHandler; import org.apache.pulsar.common.api.proto.PulsarApi; import org.apache.pulsar.common.api.proto.PulsarApi.CommandAck; -import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge; +import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseProducer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandConnect; @@ -464,7 +463,7 @@ private void completeConnect(int clientProtoVersion, String clientVersion) { } } - // According to auth result, send newConnected or newAuthResponse command. + // According to auth result, send newConnected or newAuthChallenge command. private void doingAuthentication(AuthData clientData, int clientProtocolVersion, String clientVersion) throws Exception { @@ -481,7 +480,7 @@ private void doingAuthentication(AuthData clientData, } // auth not complete, continue auth with client side. - ctx.writeAndFlush(Commands.newAuthResponse(authMethod, brokerData, clientProtocolVersion)); + ctx.writeAndFlush(Commands.newAuthChallenge(authMethod, brokerData, clientProtocolVersion)); if (log.isDebugEnabled()) { log.debug("[{}] Authentication in progress client by method {}.", remoteAddress, authMethod); @@ -558,21 +557,21 @@ protected void handleConnect(CommandConnect connect) { } @Override - protected void handleAuthChallenge(CommandAuthChallenge authChallenge) { + protected void handleAuthResponse(CommandAuthResponse authResponse) { checkArgument(state == State.Connecting); - checkArgument(authChallenge.hasChallenge()); - checkArgument(authChallenge.getChallenge().hasAuthData() && authChallenge.getChallenge().hasAuthMethodName()); + checkArgument(authResponse.hasResponse()); + checkArgument(authResponse.getResponse().hasAuthData() && authResponse.getResponse().hasAuthMethodName()); if (log.isDebugEnabled()) { - log.debug("Received AuthChallenge from {}, auth method: {}", - remoteAddress, authChallenge.getChallenge().getAuthMethodName()); + log.debug("Received AuthResponse from {}, auth method: {}", + remoteAddress, authResponse.getResponse().getAuthMethodName()); } try { - AuthData clientData = AuthData.of(authChallenge.getChallenge().getAuthData().toByteArray()); - doingAuthentication(clientData, authChallenge.getProtocolVersion(), authChallenge.getClientVersion()); + AuthData clientData = AuthData.of(authResponse.getResponse().getAuthData().toByteArray()); + doingAuthentication(clientData, authResponse.getProtocolVersion(), authResponse.getClientVersion()); } catch (Exception e) { - String msg = "Unable to handleAuthChallenge"; + String msg = "Unable to handleAuthResponse"; log.warn("[{}] {} ", remoteAddress, msg, e); ctx.writeAndFlush(Commands.newError(-1, ServerError.AuthenticationError, msg)); close(); diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java index de381a0dc0cb8..ce9efd67cefd9 100644 --- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java +++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java @@ -50,7 +50,7 @@ import org.apache.pulsar.common.api.Commands; import org.apache.pulsar.common.api.PulsarHandler; import org.apache.pulsar.common.api.proto.PulsarApi.CommandActiveConsumerChange; -import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse; +import org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseProducer; import org.apache.pulsar.common.api.proto.PulsarApi.CommandConnected; @@ -286,18 +286,18 @@ protected void handleConnected(CommandConnected connected) { } @Override - protected void handleAuthResponse(CommandAuthResponse authResponse) { - checkArgument(authResponse.hasResponse()); - checkArgument(authResponse.getResponse().hasAuthData() && authResponse.getResponse().hasAuthData()); + protected void handleAuthChallenge(CommandAuthChallenge authChallenge) { + checkArgument(authChallenge.hasChallenge()); + checkArgument(authChallenge.getChallenge().hasAuthData() && authChallenge.getChallenge().hasAuthData()); // mutual authn. If auth not complete, continue auth; if auth complete, complete connectionFuture. try { AuthData authData = authenticationDataProvider - .authenticate(AuthData.of(authResponse.getResponse().getAuthData().toByteArray())); + .authenticate(AuthData.of(authChallenge.getChallenge().getAuthData().toByteArray())); checkState(!authData.isComplete()); - ByteBuf request = Commands.newAuthChallenge(authentication.getAuthMethodName(), + ByteBuf request = Commands.newAuthResponse(authentication.getAuthMethodName(), authData, this.protocolVersion, getPulsarClientVersion()); diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java index 0c9eb1cf1cb22..7cfce9ff58aff 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java @@ -212,49 +212,49 @@ public static ByteBuf newConnected(int clientProtocolVersion) { return res; } - public static ByteBuf newAuthResponse(String authMethod, AuthData brokerData, int clientProtocolVersion) { - CommandAuthResponse.Builder responseBuilder = CommandAuthResponse.newBuilder(); + public static ByteBuf newAuthChallenge(String authMethod, AuthData brokerData, int clientProtocolVersion) { + CommandAuthChallenge.Builder challengeBuilder = CommandAuthChallenge.newBuilder(); // If the broker supports a newer version of the protocol, it will anyway advertise the max version that the // client supports, to avoid confusing the client. int currentProtocolVersion = getCurrentProtocolVersion(); int versionToAdvertise = Math.min(currentProtocolVersion, clientProtocolVersion); - responseBuilder.setProtocolVersion(versionToAdvertise); - responseBuilder.setServerVersion("Pulsar Server"); + challengeBuilder.setProtocolVersion(versionToAdvertise); + challengeBuilder.setServerVersion("Pulsar Server"); - CommandAuthResponse response = responseBuilder - .setResponse(PulsarApi.AuthData.newBuilder() + CommandAuthChallenge challenge = challengeBuilder + .setChallenge(PulsarApi.AuthData.newBuilder() .setAuthData(copyFrom(brokerData.getBytes())) .setAuthMethodName(authMethod) .build()) .build(); - ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_RESPONSE).setAuthResponse(response)); - response.recycle(); - responseBuilder.recycle(); + ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_RESPONSE).setAuthChallenge(challenge)); + challenge.recycle(); + challengeBuilder.recycle(); return res; } - public static ByteBuf newAuthChallenge(String authMethod, + public static ByteBuf newAuthResponse(String authMethod, AuthData clientData, int clientProtocolVersion, String clientVersion) { - CommandAuthChallenge.Builder challengeBuilder = CommandAuthChallenge.newBuilder(); + CommandAuthResponse.Builder responseBuilder = CommandAuthResponse.newBuilder(); - challengeBuilder.setClientVersion(clientVersion != null ? clientVersion : "Pulsar Client"); - challengeBuilder.setProtocolVersion(clientProtocolVersion); + responseBuilder.setClientVersion(clientVersion != null ? clientVersion : "Pulsar Client"); + responseBuilder.setProtocolVersion(clientProtocolVersion); - CommandAuthChallenge challenge = challengeBuilder - .setChallenge(PulsarApi.AuthData.newBuilder() + CommandAuthResponse response = responseBuilder + .setResponse(PulsarApi.AuthData.newBuilder() .setAuthData(copyFrom(clientData.getBytes())) .setAuthMethodName(authMethod) .build()) .build(); - ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_CHALLENGE).setAuthChallenge(challenge)); - challenge.recycle(); - challengeBuilder.recycle(); + ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_CHALLENGE).setAuthResponse(response)); + response.recycle(); + responseBuilder.recycle(); return res; } diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java index a03436e777033..40bd3c5493c99 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java @@ -6789,33 +6789,33 @@ public Builder clearProtocolVersion() { // @@protoc_insertion_point(class_scope:pulsar.proto.CommandConnected) } - public interface CommandAuthChallengeOrBuilder + public interface CommandAuthResponseOrBuilder extends org.apache.pulsar.shaded.com.google.protobuf.v241.MessageLiteOrBuilder { // required string client_version = 1; boolean hasClientVersion(); String getClientVersion(); - // required .pulsar.proto.AuthData challenge = 2; - boolean hasChallenge(); - org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge(); + // required .pulsar.proto.AuthData response = 2; + boolean hasResponse(); + org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse(); // optional int32 protocol_version = 3 [default = 0]; boolean hasProtocolVersion(); int getProtocolVersion(); } - public static final class CommandAuthChallenge extends + public static final class CommandAuthResponse extends org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite - implements CommandAuthChallengeOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage { - // Use CommandAuthChallenge.newBuilder() to construct. + implements CommandAuthResponseOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage { + // Use CommandAuthResponse.newBuilder() to construct. private io.netty.util.Recycler.Handle handle; - private CommandAuthChallenge(io.netty.util.Recycler.Handle handle) { + private CommandAuthResponse(io.netty.util.Recycler.Handle handle) { this.handle = handle; } - private static final io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { - protected CommandAuthChallenge newObject(Handle handle) { - return new CommandAuthChallenge(handle); + private static final io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { + protected CommandAuthResponse newObject(Handle handle) { + return new CommandAuthResponse(handle); } }; @@ -6827,14 +6827,14 @@ public void recycle() { if (handle != null) { RECYCLER.recycle(this, handle); } } - private CommandAuthChallenge(boolean noInit) {} + private CommandAuthResponse(boolean noInit) {} - private static final CommandAuthChallenge defaultInstance; - public static CommandAuthChallenge getDefaultInstance() { + private static final CommandAuthResponse defaultInstance; + public static CommandAuthResponse getDefaultInstance() { return defaultInstance; } - public CommandAuthChallenge getDefaultInstanceForType() { + public CommandAuthResponse getDefaultInstanceForType() { return defaultInstance; } @@ -6871,14 +6871,14 @@ private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getClientVe } } - // required .pulsar.proto.AuthData challenge = 2; - public static final int CHALLENGE_FIELD_NUMBER = 2; - private org.apache.pulsar.common.api.proto.PulsarApi.AuthData challenge_; - public boolean hasChallenge() { + // required .pulsar.proto.AuthData response = 2; + public static final int RESPONSE_FIELD_NUMBER = 2; + private org.apache.pulsar.common.api.proto.PulsarApi.AuthData response_; + public boolean hasResponse() { return ((bitField0_ & 0x00000002) == 0x00000002); } - public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge() { - return challenge_; + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse() { + return response_; } // optional int32 protocol_version = 3 [default = 0]; @@ -6893,7 +6893,7 @@ public int getProtocolVersion() { private void initFields() { clientVersion_ = ""; - challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); protocolVersion_ = 0; } private byte memoizedIsInitialized = -1; @@ -6905,11 +6905,11 @@ public final boolean isInitialized() { memoizedIsInitialized = 0; return false; } - if (!hasChallenge()) { + if (!hasResponse()) { memoizedIsInitialized = 0; return false; } - if (!getChallenge().isInitialized()) { + if (!getResponse().isInitialized()) { memoizedIsInitialized = 0; return false; } @@ -6929,7 +6929,7 @@ public void writeTo(org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStr output.writeBytes(1, getClientVersionBytes()); } if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeMessage(2, challenge_); + output.writeMessage(2, response_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeInt32(3, protocolVersion_); @@ -6948,7 +6948,7 @@ public int getSerializedSize() { } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream - .computeMessageSize(2, challenge_); + .computeMessageSize(2, response_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream @@ -6965,40 +6965,40 @@ protected java.lang.Object writeReplace() return super.writeReplace(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { throw new RuntimeException("Disabled"); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { throw new RuntimeException("Disabled"); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom(byte[] data) + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom(byte[] data) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { return newBuilder().mergeFrom(data).buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( byte[] data, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { return newBuilder().mergeFrom(data, extensionRegistry) .buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom(java.io.InputStream input) + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom(java.io.InputStream input) throws java.io.IOException { return newBuilder().mergeFrom(input).buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( java.io.InputStream input, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return newBuilder().mergeFrom(input, extensionRegistry) .buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseDelimitedFrom(java.io.InputStream input) + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { Builder builder = newBuilder(); if (builder.mergeDelimitedFrom(input)) { @@ -7007,7 +7007,7 @@ public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge return null; } } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseDelimitedFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseDelimitedFrom( java.io.InputStream input, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -7018,12 +7018,12 @@ public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge return null; } } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input) throws java.io.IOException { return newBuilder().mergeFrom(input).buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -7033,16 +7033,16 @@ public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge prototype) { + public static Builder newBuilder(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } public static final class Builder extends org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite.Builder< - org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge, Builder> - implements org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallengeOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder { - // Construct using org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.newBuilder() + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse, Builder> + implements org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponseOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder { + // Construct using org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.newBuilder() private final io.netty.util.Recycler.Handle handle; private Builder(io.netty.util.Recycler.Handle handle) { this.handle = handle; @@ -7069,7 +7069,7 @@ public Builder clear() { super.clear(); clientVersion_ = ""; bitField0_ = (bitField0_ & ~0x00000001); - challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000002); protocolVersion_ = 0; bitField0_ = (bitField0_ & ~0x00000004); @@ -7080,21 +7080,21 @@ public Builder clone() { return create().mergeFrom(buildPartial()); } - public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge getDefaultInstanceForType() { - return org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance(); + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse getDefaultInstanceForType() { + return org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance(); } - public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge build() { - org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge result = buildPartial(); + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse build() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } - private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge buildParsed() + private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse buildParsed() throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { - org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge result = buildPartial(); + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException( result).asInvalidProtocolBufferException(); @@ -7102,8 +7102,8 @@ private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge buildP return result; } - public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge buildPartial() { - org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge result = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.RECYCLER.get(); + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse buildPartial() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse result = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.RECYCLER.get(); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { @@ -7113,7 +7113,7 @@ public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge buildPa if (((from_bitField0_ & 0x00000002) == 0x00000002)) { to_bitField0_ |= 0x00000002; } - result.challenge_ = challenge_; + result.response_ = response_; if (((from_bitField0_ & 0x00000004) == 0x00000004)) { to_bitField0_ |= 0x00000004; } @@ -7122,13 +7122,13 @@ public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge buildPa return result; } - public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge other) { - if (other == org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance()) return this; + public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse other) { + if (other == org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance()) return this; if (other.hasClientVersion()) { setClientVersion(other.getClientVersion()); } - if (other.hasChallenge()) { - mergeChallenge(other.getChallenge()); + if (other.hasResponse()) { + mergeResponse(other.getResponse()); } if (other.hasProtocolVersion()) { setProtocolVersion(other.getProtocolVersion()); @@ -7141,11 +7141,11 @@ public final boolean isInitialized() { return false; } - if (!hasChallenge()) { + if (!hasResponse()) { return false; } - if (!getChallenge().isInitialized()) { + if (!getResponse().isInitialized()) { return false; } @@ -7181,11 +7181,11 @@ public Builder mergeFrom( } case 18: { org.apache.pulsar.common.api.proto.PulsarApi.AuthData.Builder subBuilder = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(); - if (hasChallenge()) { - subBuilder.mergeFrom(getChallenge()); + if (hasResponse()) { + subBuilder.mergeFrom(getResponse()); } input.readMessage(subBuilder, extensionRegistry); - setChallenge(subBuilder.buildPartial()); + setResponse(subBuilder.buildPartial()); subBuilder.recycle(); break; } @@ -7236,44 +7236,44 @@ void setClientVersion(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteStri } - // required .pulsar.proto.AuthData challenge = 2; - private org.apache.pulsar.common.api.proto.PulsarApi.AuthData challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); - public boolean hasChallenge() { + // required .pulsar.proto.AuthData response = 2; + private org.apache.pulsar.common.api.proto.PulsarApi.AuthData response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + public boolean hasResponse() { return ((bitField0_ & 0x00000002) == 0x00000002); } - public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge() { - return challenge_; + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse() { + return response_; } - public Builder setChallenge(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { + public Builder setResponse(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { if (value == null) { throw new NullPointerException(); } - challenge_ = value; + response_ = value; bitField0_ |= 0x00000002; return this; } - public Builder setChallenge( + public Builder setResponse( org.apache.pulsar.common.api.proto.PulsarApi.AuthData.Builder builderForValue) { - challenge_ = builderForValue.build(); + response_ = builderForValue.build(); bitField0_ |= 0x00000002; return this; } - public Builder mergeChallenge(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { + public Builder mergeResponse(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { if (((bitField0_ & 0x00000002) == 0x00000002) && - challenge_ != org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance()) { - challenge_ = - org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(challenge_).mergeFrom(value).buildPartial(); + response_ != org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance()) { + response_ = + org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(response_).mergeFrom(value).buildPartial(); } else { - challenge_ = value; + response_ = value; } bitField0_ |= 0x00000002; return this; } - public Builder clearChallenge() { - challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + public Builder clearResponse() { + response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000002); return this; @@ -7300,44 +7300,44 @@ public Builder clearProtocolVersion() { return this; } - // @@protoc_insertion_point(builder_scope:pulsar.proto.CommandAuthChallenge) + // @@protoc_insertion_point(builder_scope:pulsar.proto.CommandAuthResponse) } static { - defaultInstance = new CommandAuthChallenge(true); + defaultInstance = new CommandAuthResponse(true); defaultInstance.initFields(); } - // @@protoc_insertion_point(class_scope:pulsar.proto.CommandAuthChallenge) + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandAuthResponse) } - public interface CommandAuthResponseOrBuilder + public interface CommandAuthChallengeOrBuilder extends org.apache.pulsar.shaded.com.google.protobuf.v241.MessageLiteOrBuilder { // required string server_version = 1; boolean hasServerVersion(); String getServerVersion(); - // required .pulsar.proto.AuthData response = 2; - boolean hasResponse(); - org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse(); + // required .pulsar.proto.AuthData challenge = 2; + boolean hasChallenge(); + org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge(); // optional int32 protocol_version = 3 [default = 0]; boolean hasProtocolVersion(); int getProtocolVersion(); } - public static final class CommandAuthResponse extends + public static final class CommandAuthChallenge extends org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite - implements CommandAuthResponseOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage { - // Use CommandAuthResponse.newBuilder() to construct. + implements CommandAuthChallengeOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage { + // Use CommandAuthChallenge.newBuilder() to construct. private io.netty.util.Recycler.Handle handle; - private CommandAuthResponse(io.netty.util.Recycler.Handle handle) { + private CommandAuthChallenge(io.netty.util.Recycler.Handle handle) { this.handle = handle; } - private static final io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { - protected CommandAuthResponse newObject(Handle handle) { - return new CommandAuthResponse(handle); + private static final io.netty.util.Recycler RECYCLER = new io.netty.util.Recycler() { + protected CommandAuthChallenge newObject(Handle handle) { + return new CommandAuthChallenge(handle); } }; @@ -7349,14 +7349,14 @@ public void recycle() { if (handle != null) { RECYCLER.recycle(this, handle); } } - private CommandAuthResponse(boolean noInit) {} + private CommandAuthChallenge(boolean noInit) {} - private static final CommandAuthResponse defaultInstance; - public static CommandAuthResponse getDefaultInstance() { + private static final CommandAuthChallenge defaultInstance; + public static CommandAuthChallenge getDefaultInstance() { return defaultInstance; } - public CommandAuthResponse getDefaultInstanceForType() { + public CommandAuthChallenge getDefaultInstanceForType() { return defaultInstance; } @@ -7393,14 +7393,14 @@ private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getServerVe } } - // required .pulsar.proto.AuthData response = 2; - public static final int RESPONSE_FIELD_NUMBER = 2; - private org.apache.pulsar.common.api.proto.PulsarApi.AuthData response_; - public boolean hasResponse() { + // required .pulsar.proto.AuthData challenge = 2; + public static final int CHALLENGE_FIELD_NUMBER = 2; + private org.apache.pulsar.common.api.proto.PulsarApi.AuthData challenge_; + public boolean hasChallenge() { return ((bitField0_ & 0x00000002) == 0x00000002); } - public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse() { - return response_; + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge() { + return challenge_; } // optional int32 protocol_version = 3 [default = 0]; @@ -7415,7 +7415,7 @@ public int getProtocolVersion() { private void initFields() { serverVersion_ = ""; - response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); protocolVersion_ = 0; } private byte memoizedIsInitialized = -1; @@ -7427,11 +7427,11 @@ public final boolean isInitialized() { memoizedIsInitialized = 0; return false; } - if (!hasResponse()) { + if (!hasChallenge()) { memoizedIsInitialized = 0; return false; } - if (!getResponse().isInitialized()) { + if (!getChallenge().isInitialized()) { memoizedIsInitialized = 0; return false; } @@ -7451,7 +7451,7 @@ public void writeTo(org.apache.pulsar.common.util.protobuf.ByteBufCodedOutputStr output.writeBytes(1, getServerVersionBytes()); } if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeMessage(2, response_); + output.writeMessage(2, challenge_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeInt32(3, protocolVersion_); @@ -7470,7 +7470,7 @@ public int getSerializedSize() { } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream - .computeMessageSize(2, response_); + .computeMessageSize(2, challenge_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += org.apache.pulsar.shaded.com.google.protobuf.v241.CodedOutputStream @@ -7487,40 +7487,40 @@ protected java.lang.Object writeReplace() return super.writeReplace(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { throw new RuntimeException("Disabled"); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString data, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { throw new RuntimeException("Disabled"); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom(byte[] data) + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom(byte[] data) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { return newBuilder().mergeFrom(data).buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( byte[] data, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { return newBuilder().mergeFrom(data, extensionRegistry) .buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom(java.io.InputStream input) + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom(java.io.InputStream input) throws java.io.IOException { return newBuilder().mergeFrom(input).buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( java.io.InputStream input, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return newBuilder().mergeFrom(input, extensionRegistry) .buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseDelimitedFrom(java.io.InputStream input) + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { Builder builder = newBuilder(); if (builder.mergeDelimitedFrom(input)) { @@ -7529,7 +7529,7 @@ public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse p return null; } } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseDelimitedFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseDelimitedFrom( java.io.InputStream input, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -7540,12 +7540,12 @@ public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse p return null; } } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input) throws java.io.IOException { return newBuilder().mergeFrom(input).buildParsed(); } - public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse parseFrom( + public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge parseFrom( org.apache.pulsar.shaded.com.google.protobuf.v241.CodedInputStream input, org.apache.pulsar.shaded.com.google.protobuf.v241.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -7555,16 +7555,16 @@ public static org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse p public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse prototype) { + public static Builder newBuilder(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } public static final class Builder extends org.apache.pulsar.shaded.com.google.protobuf.v241.GeneratedMessageLite.Builder< - org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse, Builder> - implements org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponseOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder { - // Construct using org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.newBuilder() + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge, Builder> + implements org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallengeOrBuilder, org.apache.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder { + // Construct using org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.newBuilder() private final io.netty.util.Recycler.Handle handle; private Builder(io.netty.util.Recycler.Handle handle) { this.handle = handle; @@ -7591,7 +7591,7 @@ public Builder clear() { super.clear(); serverVersion_ = ""; bitField0_ = (bitField0_ & ~0x00000001); - response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000002); protocolVersion_ = 0; bitField0_ = (bitField0_ & ~0x00000004); @@ -7602,21 +7602,21 @@ public Builder clone() { return create().mergeFrom(buildPartial()); } - public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse getDefaultInstanceForType() { - return org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance(); + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge getDefaultInstanceForType() { + return org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance(); } - public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse build() { - org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse result = buildPartial(); + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge build() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } - private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse buildParsed() + private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge buildParsed() throws org.apache.pulsar.shaded.com.google.protobuf.v241.InvalidProtocolBufferException { - org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse result = buildPartial(); + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException( result).asInvalidProtocolBufferException(); @@ -7624,8 +7624,8 @@ private org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse buildPa return result; } - public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse buildPartial() { - org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse result = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.RECYCLER.get(); + public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge buildPartial() { + org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge result = org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.RECYCLER.get(); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { @@ -7635,7 +7635,7 @@ public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse buildPar if (((from_bitField0_ & 0x00000002) == 0x00000002)) { to_bitField0_ |= 0x00000002; } - result.response_ = response_; + result.challenge_ = challenge_; if (((from_bitField0_ & 0x00000004) == 0x00000004)) { to_bitField0_ |= 0x00000004; } @@ -7644,13 +7644,13 @@ public org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse buildPar return result; } - public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse other) { - if (other == org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthResponse.getDefaultInstance()) return this; + public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge other) { + if (other == org.apache.pulsar.common.api.proto.PulsarApi.CommandAuthChallenge.getDefaultInstance()) return this; if (other.hasServerVersion()) { setServerVersion(other.getServerVersion()); } - if (other.hasResponse()) { - mergeResponse(other.getResponse()); + if (other.hasChallenge()) { + mergeChallenge(other.getChallenge()); } if (other.hasProtocolVersion()) { setProtocolVersion(other.getProtocolVersion()); @@ -7663,11 +7663,11 @@ public final boolean isInitialized() { return false; } - if (!hasResponse()) { + if (!hasChallenge()) { return false; } - if (!getResponse().isInitialized()) { + if (!getChallenge().isInitialized()) { return false; } @@ -7703,11 +7703,11 @@ public Builder mergeFrom( } case 18: { org.apache.pulsar.common.api.proto.PulsarApi.AuthData.Builder subBuilder = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(); - if (hasResponse()) { - subBuilder.mergeFrom(getResponse()); + if (hasChallenge()) { + subBuilder.mergeFrom(getChallenge()); } input.readMessage(subBuilder, extensionRegistry); - setResponse(subBuilder.buildPartial()); + setChallenge(subBuilder.buildPartial()); subBuilder.recycle(); break; } @@ -7758,44 +7758,44 @@ void setServerVersion(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteStri } - // required .pulsar.proto.AuthData response = 2; - private org.apache.pulsar.common.api.proto.PulsarApi.AuthData response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); - public boolean hasResponse() { + // required .pulsar.proto.AuthData challenge = 2; + private org.apache.pulsar.common.api.proto.PulsarApi.AuthData challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + public boolean hasChallenge() { return ((bitField0_ & 0x00000002) == 0x00000002); } - public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse() { - return response_; + public org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge() { + return challenge_; } - public Builder setResponse(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { + public Builder setChallenge(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { if (value == null) { throw new NullPointerException(); } - response_ = value; + challenge_ = value; bitField0_ |= 0x00000002; return this; } - public Builder setResponse( + public Builder setChallenge( org.apache.pulsar.common.api.proto.PulsarApi.AuthData.Builder builderForValue) { - response_ = builderForValue.build(); + challenge_ = builderForValue.build(); bitField0_ |= 0x00000002; return this; } - public Builder mergeResponse(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { + public Builder mergeChallenge(org.apache.pulsar.common.api.proto.PulsarApi.AuthData value) { if (((bitField0_ & 0x00000002) == 0x00000002) && - response_ != org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance()) { - response_ = - org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(response_).mergeFrom(value).buildPartial(); + challenge_ != org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance()) { + challenge_ = + org.apache.pulsar.common.api.proto.PulsarApi.AuthData.newBuilder(challenge_).mergeFrom(value).buildPartial(); } else { - response_ = value; + challenge_ = value; } bitField0_ |= 0x00000002; return this; } - public Builder clearResponse() { - response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); + public Builder clearChallenge() { + challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000002); return this; @@ -7822,15 +7822,15 @@ public Builder clearProtocolVersion() { return this; } - // @@protoc_insertion_point(builder_scope:pulsar.proto.CommandAuthResponse) + // @@protoc_insertion_point(builder_scope:pulsar.proto.CommandAuthChallenge) } static { - defaultInstance = new CommandAuthResponse(true); + defaultInstance = new CommandAuthChallenge(true); defaultInstance.initFields(); } - // @@protoc_insertion_point(class_scope:pulsar.proto.CommandAuthResponse) + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandAuthChallenge) } public interface AuthDataOrBuilder diff --git a/pulsar-common/src/main/proto/PulsarApi.proto b/pulsar-common/src/main/proto/PulsarApi.proto index 40e7f20d45eaf..a60289377b230 100644 --- a/pulsar-common/src/main/proto/PulsarApi.proto +++ b/pulsar-common/src/main/proto/PulsarApi.proto @@ -200,15 +200,15 @@ message CommandConnected { optional int32 protocol_version = 2 [default = 0]; } -message CommandAuthChallenge { +message CommandAuthResponse { required string client_version = 1; - required AuthData challenge = 2; + required AuthData response = 2; optional int32 protocol_version = 3 [default = 0]; } -message CommandAuthResponse { +message CommandAuthChallenge { required string server_version = 1; - required AuthData response = 2; + required AuthData challenge = 2; optional int32 protocol_version = 3 [default = 0]; } From 22c5d9894a30ad08edb712c33fbee87dd15ca240 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Tue, 5 Mar 2019 09:27:40 +0800 Subject: [PATCH 09/13] change follow ivan's comments --- .../AuthenticationProvider.java | 6 +++++- .../authentication/AuthenticationService.java | 4 ++-- .../authentication/AuthenticationState.java | 7 ++++++- .../OneStageAuthenticationState.java | 19 ++++++++++--------- .../pulsar/broker/service/ServerCnx.java | 16 ++++++++-------- .../apache/pulsar/common/api/Commands.java | 11 ++--------- 6 files changed, 33 insertions(+), 30 deletions(-) diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java index 78148736bc543..8c69ca4d0730a 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java @@ -70,7 +70,11 @@ default AuthenticationDataSource newAuthDataSource(AuthData authData, new String(authData.getBytes(), Charset.forName("UTF-8")), remoteAddress, sslSession); } - default AuthenticationState newAuthState(AuthenticationDataSource authenticationDataSource) { + /** + * Create an authentication data State use passed in AuthenticationDataSource. + */ + default AuthenticationState newAuthState(AuthenticationDataSource authenticationDataSource) + throws AuthenticationException{ return new OneStageAuthenticationState(authenticationDataSource, this); } diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java index 0a40c66160859..9ed610a5094ba 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java @@ -109,12 +109,12 @@ public AuthenticationProvider getAuthenticationProvider(String authMethodName) { return providers.get(authMethodName); } + // called when authn enabled, but no authentication provided public String getAnonymousUserRole() throws AuthenticationException { if (StringUtils.isNotBlank(anonymousUserRole)) { return anonymousUserRole; } - // If at least a provider was configured, then the authentication needs to be provided - throw new AuthenticationException("Authentication required"); + throw new AuthenticationException("Authentication method required"); } @Override diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java index e1acf8f47d9bc..c41e47bd22af9 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java @@ -26,7 +26,6 @@ /** * Interface for authentication state. * - * It is basically holding the authentication state. * It tell broker whether the authentication is completed or not, * if completed, what is the AuthRole is. */ @@ -34,6 +33,7 @@ public interface AuthenticationState { /** * After the authentication between client and broker completed, * get authentication role represent for the client. + * It should throw exception if auth not complete. */ String getAuthRole() throws AuthenticationException; @@ -42,6 +42,11 @@ public interface AuthenticationState { */ AuthData authenticate(AuthData authData) throws IOException; + /** + * Return AuthenticationDataSource. + */ + AuthenticationDataSource getAuthDataSource(); + /** * Whether the authentication is completed or not */ diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java index 7528bebdd2c84..b959c7d68a5ff 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java @@ -25,29 +25,30 @@ /** * Interface for authentication state. * - * It is basically holding the the authentication state. * It tell broker whether the authentication is completed or not, * if completed, what is the AuthRole is. */ public class OneStageAuthenticationState implements AuthenticationState { private final AuthenticationDataSource authenticationDataSource; - private final AuthenticationProvider provider; + private final String authRole; public OneStageAuthenticationState(AuthenticationDataSource authenticationDataSource, - AuthenticationProvider provider) { + AuthenticationProvider provider) throws AuthenticationException { this.authenticationDataSource = authenticationDataSource; - this.provider = provider; + this.authRole = provider.authenticate(authenticationDataSource); } @Override - public String getAuthRole() throws AuthenticationException { - return provider.authenticate(authenticationDataSource); + public String getAuthRole() { + return authRole; + } + + @Override + public AuthenticationDataSource getAuthDataSource() { + return authenticationDataSource; } - /** - * Challenge passed in auth data and get response data. - */ @Override public AuthData authenticate(AuthData authData) { return null; diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index 89281f2cd4800..c8743013767c3 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -260,7 +260,7 @@ protected void handleLookup(CommandLookupTopic lookup) { CompletableFuture isProxyAuthorizedFuture; if (service.isAuthorizationEnabled() && originalPrincipal != null) { isProxyAuthorizedFuture = service.getAuthorizationService().canLookupAsync(topicName, authRole, - authenticationData); + authState.getAuthDataSource()); } else { isProxyAuthorizedFuture = CompletableFuture.completedFuture(true); } @@ -464,9 +464,9 @@ private void completeConnect(int clientProtoVersion, String clientVersion) { } // According to auth result, send newConnected or newAuthChallenge command. - private void doingAuthentication(AuthData clientData, - int clientProtocolVersion, - String clientVersion) throws Exception { + private void doAuthentication(AuthData clientData, + int clientProtocolVersion, + String clientVersion) throws Exception { AuthData brokerData = authState.authenticate(clientData); // authentication has completed, will send newConnected command. if (authState.isComplete()) { @@ -543,11 +543,11 @@ protected void handleConnect(CommandConnect connect) { connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null, sslSession); - authenticationData = authenticationProvider.newAuthDataSource(clientData, remoteAddress, sslSession); + AuthenticationDataSource authenticationData = authenticationProvider + .newAuthDataSource(clientData, remoteAddress, sslSession); authState = authenticationProvider.newAuthState(authenticationData); - - doingAuthentication(clientData, clientProtocolVersion, clientVersion); + doAuthentication(clientData, clientProtocolVersion, clientVersion); } catch (Exception e) { String msg = "Unable to authenticate"; log.warn("[{}] {} ", remoteAddress, msg, e); @@ -569,7 +569,7 @@ protected void handleAuthResponse(CommandAuthResponse authResponse) { try { AuthData clientData = AuthData.of(authResponse.getResponse().getAuthData().toByteArray()); - doingAuthentication(clientData, authResponse.getProtocolVersion(), authResponse.getClientVersion()); + doAuthentication(clientData, authResponse.getProtocolVersion(), authResponse.getClientVersion()); } catch (Exception e) { String msg = "Unable to handleAuthResponse"; log.warn("[{}] {} ", remoteAddress, msg, e); diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java index 7cfce9ff58aff..6133c9a650320 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java @@ -159,13 +159,6 @@ public static ByteBuf newConnect(String authMethodName, AuthData authData, int p connectBuilder.setClientVersion(libVersion != null ? libVersion : "Pulsar Client"); connectBuilder.setAuthMethodName(authMethodName); - if ("ycav1".equals(authMethodName)) { - // Handle the case of a client that gets updated before the broker and starts sending the string auth method - // name. An example would be in broker-to-broker replication. We need to make sure the clients are still - // passing both the enum and the string until all brokers are upgraded. - connectBuilder.setAuthMethod(AuthMethod.AuthMethodYcaV1); - } - if (targetBroker != null) { // When connecting through a proxy, we need to specify which broker do we want to be proxied through connectBuilder.setProxyToBrokerUrl(targetBroker); @@ -230,7 +223,7 @@ public static ByteBuf newAuthChallenge(String authMethod, AuthData brokerData, i .build()) .build(); - ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_RESPONSE).setAuthChallenge(challenge)); + ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_CHALLENGE).setAuthChallenge(challenge)); challenge.recycle(); challengeBuilder.recycle(); return res; @@ -252,7 +245,7 @@ public static ByteBuf newAuthResponse(String authMethod, .build()) .build(); - ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_CHALLENGE).setAuthResponse(response)); + ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.AUTH_RESPONSE).setAuthResponse(response)); response.recycle(); responseBuilder.recycle(); return res; From b639edda4c1a0e733f4ca3f0fc1e907359ea4d73 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Wed, 6 Mar 2019 15:39:08 +0800 Subject: [PATCH 10/13] change following ivan's comments --- .../AuthenticationProvider.java | 17 +- .../authentication/AuthenticationService.java | 7 +- .../OneStageAuthenticationState.java | 10 +- .../pulsar/broker/service/ServerCnx.java | 9 +- .../pulsar/broker/service/ServerCnxTest.java | 9 +- .../client/api/MutualAuthenticationTest.java | 225 ++++++++++++++++++ .../apache/pulsar/common/api/Commands.java | 1 - .../pulsar/common/api/proto/PulsarApi.java | 124 ++-------- pulsar-common/src/main/proto/PulsarApi.proto | 12 +- 9 files changed, 272 insertions(+), 142 deletions(-) create mode 100644 pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java index 8c69ca4d0730a..78bdfafc0109a 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.net.SocketAddress; -import java.nio.charset.Charset; import javax.naming.AuthenticationException; import javax.net.ssl.SSLSession; @@ -60,22 +59,14 @@ public interface AuthenticationProvider extends Closeable { */ String authenticate(AuthenticationDataSource authData) throws AuthenticationException; - /** - * Create an authentication data provider which provides the data that this broker will be sent to the client. - */ - default AuthenticationDataSource newAuthDataSource(AuthData authData, - SocketAddress remoteAddress, - SSLSession sslSession) throws IOException { - return new AuthenticationDataCommand( - new String(authData.getBytes(), Charset.forName("UTF-8")), remoteAddress, sslSession); - } - /** * Create an authentication data State use passed in AuthenticationDataSource. */ - default AuthenticationState newAuthState(AuthenticationDataSource authenticationDataSource) + default AuthenticationState newAuthState(AuthData authData, + SocketAddress remoteAddress, + SSLSession sslSession) throws AuthenticationException{ - return new OneStageAuthenticationState(authenticationDataSource, this); + return new OneStageAuthenticationState(authData, remoteAddress, sslSession, this); } } diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java index 9ed610a5094ba..28225176eeacc 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.Map; +import java.util.Optional; import javax.naming.AuthenticationException; import javax.servlet.http.HttpServletRequest; @@ -110,11 +111,11 @@ public AuthenticationProvider getAuthenticationProvider(String authMethodName) { } // called when authn enabled, but no authentication provided - public String getAnonymousUserRole() throws AuthenticationException { + public Optional getAnonymousUserRole() { if (StringUtils.isNotBlank(anonymousUserRole)) { - return anonymousUserRole; + return Optional.of(anonymousUserRole); } - throw new AuthenticationException("Authentication method required"); + return Optional.empty(); } @Override diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java index b959c7d68a5ff..b248b50238ed0 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java @@ -19,7 +19,10 @@ package org.apache.pulsar.broker.authentication; +import java.net.SocketAddress; +import java.nio.charset.Charset; import javax.naming.AuthenticationException; +import javax.net.ssl.SSLSession; import org.apache.pulsar.common.api.AuthData; /** @@ -33,9 +36,12 @@ public class OneStageAuthenticationState implements AuthenticationState { private final AuthenticationDataSource authenticationDataSource; private final String authRole; - public OneStageAuthenticationState(AuthenticationDataSource authenticationDataSource, + public OneStageAuthenticationState(AuthData authData, + SocketAddress remoteAddress, + SSLSession sslSession, AuthenticationProvider provider) throws AuthenticationException { - this.authenticationDataSource = authenticationDataSource; + this.authenticationDataSource = new AuthenticationDataCommand( + new String(authData.getBytes(), Charset.forName("UTF-8")), remoteAddress, sslSession);; this.authRole = provider.authenticate(authenticationDataSource); } diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index c8743013767c3..01895e2022bee 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -260,7 +260,7 @@ protected void handleLookup(CommandLookupTopic lookup) { CompletableFuture isProxyAuthorizedFuture; if (service.isAuthorizationEnabled() && originalPrincipal != null) { isProxyAuthorizedFuture = service.getAuthorizationService().canLookupAsync(topicName, authRole, - authState.getAuthDataSource()); + authenticationData); } else { isProxyAuthorizedFuture = CompletableFuture.completedFuture(true); } @@ -526,7 +526,7 @@ protected void handleConnect(CommandConnect connect) { // Not find provider named authMethod. Most used for tests. // In AuthenticationDisabled, it will set authMethod "none". if (authenticationProvider == null) { - authRole = getBrokerService().getAuthenticationService().getAnonymousUserRole(); + authRole = getBrokerService().getAuthenticationService().getAnonymousUserRole().get(); completeConnect(clientProtocolVersion, clientVersion); return; } @@ -543,10 +543,7 @@ protected void handleConnect(CommandConnect connect) { connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null, sslSession); - AuthenticationDataSource authenticationData = authenticationProvider - .newAuthDataSource(clientData, remoteAddress, sslSession); - authState = authenticationProvider.newAuthState(authenticationData); - + authState = authenticationProvider.newAuthState(clientData, remoteAddress, sslSession); doAuthentication(clientData, clientProtocolVersion, clientVersion); } catch (Exception e) { String msg = "Unable to authenticate"; diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java index f3d58980dbb06..84d29526a8d08 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java @@ -344,10 +344,10 @@ public void testConnectCommandWithAuthenticationPositive() throws Exception { doReturn(authenticationService).when(brokerService).getAuthenticationService(); doReturn(authenticationProvider).when(authenticationService).getAuthenticationProvider(Mockito.anyString()); - doReturn(authenticationDataSource).when(authenticationProvider) - .newAuthDataSource(Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject()); + //doReturn(authenticationDataSource).when(authenticationProvider) + // .newAuthDataSource(Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject()); doReturn(authenticationState).when(authenticationProvider) - .newAuthState(authenticationDataSource); + .newAuthState(Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject()); doReturn(authData).when(authenticationState) .authenticate(authData); doReturn(true).when(authenticationState) @@ -373,10 +373,9 @@ public void testConnectCommandWithAuthenticationPositive() throws Exception { @Test(timeOut = 30000) public void testConnectCommandWithAuthenticationNegative() throws Exception { - AuthenticationException e = new AuthenticationException(); AuthenticationService authenticationService = mock(AuthenticationService.class); doReturn(authenticationService).when(brokerService).getAuthenticationService(); - doThrow(e).when(authenticationService).getAnonymousUserRole(); + doReturn(Optional.empty()).when(authenticationService).getAnonymousUserRole(); doReturn(true).when(brokerService).isAuthenticationEnabled(); resetChannel(); diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java new file mode 100644 index 0000000000000..cab19f22628a4 --- /dev/null +++ b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java @@ -0,0 +1,225 @@ +/** + * 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.pulsar.client.api; + +import com.google.common.collect.Sets; +import java.io.IOException; +import java.net.SocketAddress; +import java.net.URI; +import java.nio.charset.Charset; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import javax.naming.AuthenticationException; +import javax.net.ssl.SSLSession; +import org.apache.pulsar.broker.ServiceConfiguration; +import org.apache.pulsar.broker.authentication.AuthenticationDataSource; +import org.apache.pulsar.broker.authentication.AuthenticationProvider; +import org.apache.pulsar.broker.authentication.AuthenticationState; +import org.apache.pulsar.common.api.AuthData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +/** + * Test Mutual Authentication. + * Test connect set success, and producer consumer works well. + */ +public class MutualAuthenticationTest extends ProducerConsumerBase { + private static final Logger log = LoggerFactory.getLogger(MutualAuthenticationTest.class); + + private static String[] clientAuthStrings = { + "MutualClientAuthInit", // step 0 + "MutualClientStep1" // step 1 + }; + + private static String[] serverAuthStrings = { + "ResponseMutualClientAuthInit", // step 0 + "ResponseMutualClientStep1" // step 1 + }; + + private static int authStep = 0; + + public static class MutualAuthenticationDataProvider implements AuthenticationDataProvider { + @Override + public boolean hasDataFromCommand() { + return true; + } + + @Override + public AuthData authenticate(AuthData data) throws IOException { + String dataString = new String(data.getBytes(), Charset.forName("UTF-8")); + if (!dataString.equalsIgnoreCase("init")) { + assertEquals(dataString, serverAuthStrings[authStep - 1]); + } + log.debug("authenticate in client. passed in :{}, send: clientAuthStrings[{}]: {}", + dataString, authStep, clientAuthStrings[authStep]); + return AuthData.of(clientAuthStrings[authStep].getBytes()); + } + } + + public static class MutualAuthentication implements Authentication { + @Override + public void close() throws IOException { + // noop + } + + @Override + public String getAuthMethodName() { + return "MutualAuthentication"; + } + + @Override + public AuthenticationDataProvider getAuthData(String broker) throws PulsarClientException { + try { + return new MutualAuthenticationDataProvider(); + } catch (Exception e) { + throw new PulsarClientException(e); + } + } + + @Override + public void configure(Map authParams) { + // noop + } + + @Override + public void start() throws PulsarClientException { + // noop + } + } + + + public static class MutualAuthenticationState implements AuthenticationState { + @Override + public String getAuthRole() throws AuthenticationException { + return "admin"; + } + + @Override + public AuthData authenticate(AuthData authData) throws IOException { + String clientData = new String(authData.getBytes(), Charset.forName("UTF-8")); + assertEquals(clientData, clientAuthStrings[authStep]); + log.debug("authenticate in server. passed in :{}, send: serverAuthStrings[{}]: {}", + clientData, authStep, serverAuthStrings[authStep]); + AuthData serverData = AuthData.of(serverAuthStrings[authStep ++].getBytes()); + return serverData; + } + + @Override + public AuthenticationDataSource getAuthDataSource() { + return null; + } + + @Override + public boolean isComplete() { + return authStep > 1; + } + } + + public static class MutualAuthenticationProvider implements AuthenticationProvider { + @Override + public void close() throws IOException { + } + + @Override + public void initialize(ServiceConfiguration config) throws IOException { + } + + @Override + public String getAuthMethodName() { + return "MutualAuthentication"; + } + + @Override + public String authenticate(AuthenticationDataSource authData) throws AuthenticationException { + return "admin"; + } + + @Override + public AuthenticationState newAuthState(AuthData authData, + SocketAddress remoteAddress, + SSLSession sslSession) { + return new MutualAuthenticationState(); + } + } + + @BeforeMethod + @Override + protected void setup() throws Exception { + Set superUserRoles = new HashSet(); + superUserRoles.add("admin"); + conf.setSuperUserRoles(superUserRoles); + + conf.setAuthorizationEnabled(true); + conf.setAuthenticationEnabled(true); + Set providersClassNames = Sets.newHashSet(MutualAuthenticationProvider.class.getName()); + conf.setAuthenticationProviders(providersClassNames); + + super.init(); + URI brokerServiceUrl = new URI("pulsar://localhost:" + BROKER_PORT); + pulsarClient = PulsarClient.builder().serviceUrl(brokerServiceUrl.toString()) + .authentication(new MutualAuthentication()) + .build(); + super.producerBaseSetup(); + } + + @AfterMethod + @Override + protected void cleanup() throws Exception { + super.internalCleanup(); + } + + @Test + public void testAuthentication() throws Exception { + log.info("-- Starting {} test --", methodName); + + Consumer consumer = pulsarClient.newConsumer().topic("persistent://my-property/my-ns/my-topic1") + .subscriptionName("my-subscriber-name") + .subscribe(); + Producer producer = pulsarClient.newProducer(Schema.BYTES) + .topic("persistent://my-property/my-ns/my-topic1") + .create(); + + for (int i = 0; i < 10; i++) { + String message = "my-message-" + i; + producer.send(message.getBytes()); + } + Message msg = null; + Set messageSet = Sets.newHashSet(); + for (int i = 0; i < 10; i++) { + msg = consumer.receive(5, TimeUnit.SECONDS); + String receivedMessage = new String(msg.getData()); + log.debug("Received message: [{}]", receivedMessage); + String expectedMessage = "my-message-" + i; + testMessageOrderAndDuplicates(messageSet, receivedMessage, expectedMessage); + } + consumer.acknowledgeCumulative(msg); + + // mutual auth happened. + assertEquals(authStep, 2); + + log.info("-- Exiting {} test --", methodName); + } +} diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java index 6133c9a650320..afaec8c9b1662 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/Commands.java @@ -214,7 +214,6 @@ public static ByteBuf newAuthChallenge(String authMethod, AuthData brokerData, i int versionToAdvertise = Math.min(currentProtocolVersion, clientProtocolVersion); challengeBuilder.setProtocolVersion(versionToAdvertise); - challengeBuilder.setServerVersion("Pulsar Server"); CommandAuthChallenge challenge = challengeBuilder .setChallenge(PulsarApi.AuthData.newBuilder() diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java b/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java index 40bd3c5493c99..57dd32fd6e98b 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/api/proto/PulsarApi.java @@ -6792,11 +6792,11 @@ public Builder clearProtocolVersion() { public interface CommandAuthResponseOrBuilder extends org.apache.pulsar.shaded.com.google.protobuf.v241.MessageLiteOrBuilder { - // required string client_version = 1; + // optional string client_version = 1; boolean hasClientVersion(); String getClientVersion(); - // required .pulsar.proto.AuthData response = 2; + // optional .pulsar.proto.AuthData response = 2; boolean hasResponse(); org.apache.pulsar.common.api.proto.PulsarApi.AuthData getResponse(); @@ -6839,7 +6839,7 @@ public CommandAuthResponse getDefaultInstanceForType() { } private int bitField0_; - // required string client_version = 1; + // optional string client_version = 1; public static final int CLIENT_VERSION_FIELD_NUMBER = 1; private java.lang.Object clientVersion_; public boolean hasClientVersion() { @@ -6871,7 +6871,7 @@ private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getClientVe } } - // required .pulsar.proto.AuthData response = 2; + // optional .pulsar.proto.AuthData response = 2; public static final int RESPONSE_FIELD_NUMBER = 2; private org.apache.pulsar.common.api.proto.PulsarApi.AuthData response_; public boolean hasResponse() { @@ -6901,18 +6901,6 @@ public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized != -1) return isInitialized == 1; - if (!hasClientVersion()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasResponse()) { - memoizedIsInitialized = 0; - return false; - } - if (!getResponse().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } memoizedIsInitialized = 1; return true; } @@ -7137,18 +7125,6 @@ public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandAut } public final boolean isInitialized() { - if (!hasClientVersion()) { - - return false; - } - if (!hasResponse()) { - - return false; - } - if (!getResponse().isInitialized()) { - - return false; - } return true; } @@ -7200,7 +7176,7 @@ public Builder mergeFrom( private int bitField0_; - // required string client_version = 1; + // optional string client_version = 1; private java.lang.Object clientVersion_ = ""; public boolean hasClientVersion() { return ((bitField0_ & 0x00000001) == 0x00000001); @@ -7236,7 +7212,7 @@ void setClientVersion(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteStri } - // required .pulsar.proto.AuthData response = 2; + // optional .pulsar.proto.AuthData response = 2; private org.apache.pulsar.common.api.proto.PulsarApi.AuthData response_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); public boolean hasResponse() { return ((bitField0_ & 0x00000002) == 0x00000002); @@ -7314,11 +7290,11 @@ public Builder clearProtocolVersion() { public interface CommandAuthChallengeOrBuilder extends org.apache.pulsar.shaded.com.google.protobuf.v241.MessageLiteOrBuilder { - // required string server_version = 1; + // optional string server_version = 1; boolean hasServerVersion(); String getServerVersion(); - // required .pulsar.proto.AuthData challenge = 2; + // optional .pulsar.proto.AuthData challenge = 2; boolean hasChallenge(); org.apache.pulsar.common.api.proto.PulsarApi.AuthData getChallenge(); @@ -7361,7 +7337,7 @@ public CommandAuthChallenge getDefaultInstanceForType() { } private int bitField0_; - // required string server_version = 1; + // optional string server_version = 1; public static final int SERVER_VERSION_FIELD_NUMBER = 1; private java.lang.Object serverVersion_; public boolean hasServerVersion() { @@ -7393,7 +7369,7 @@ private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getServerVe } } - // required .pulsar.proto.AuthData challenge = 2; + // optional .pulsar.proto.AuthData challenge = 2; public static final int CHALLENGE_FIELD_NUMBER = 2; private org.apache.pulsar.common.api.proto.PulsarApi.AuthData challenge_; public boolean hasChallenge() { @@ -7423,18 +7399,6 @@ public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized != -1) return isInitialized == 1; - if (!hasServerVersion()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasChallenge()) { - memoizedIsInitialized = 0; - return false; - } - if (!getChallenge().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } memoizedIsInitialized = 1; return true; } @@ -7659,18 +7623,6 @@ public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.CommandAut } public final boolean isInitialized() { - if (!hasServerVersion()) { - - return false; - } - if (!hasChallenge()) { - - return false; - } - if (!getChallenge().isInitialized()) { - - return false; - } return true; } @@ -7722,7 +7674,7 @@ public Builder mergeFrom( private int bitField0_; - // required string server_version = 1; + // optional string server_version = 1; private java.lang.Object serverVersion_ = ""; public boolean hasServerVersion() { return ((bitField0_ & 0x00000001) == 0x00000001); @@ -7758,7 +7710,7 @@ void setServerVersion(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteStri } - // required .pulsar.proto.AuthData challenge = 2; + // optional .pulsar.proto.AuthData challenge = 2; private org.apache.pulsar.common.api.proto.PulsarApi.AuthData challenge_ = org.apache.pulsar.common.api.proto.PulsarApi.AuthData.getDefaultInstance(); public boolean hasChallenge() { return ((bitField0_ & 0x00000002) == 0x00000002); @@ -7836,11 +7788,11 @@ public Builder clearProtocolVersion() { public interface AuthDataOrBuilder extends org.apache.pulsar.shaded.com.google.protobuf.v241.MessageLiteOrBuilder { - // required string auth_method_name = 1; + // optional string auth_method_name = 1; boolean hasAuthMethodName(); String getAuthMethodName(); - // required bytes auth_data = 2; + // optional bytes auth_data = 2; boolean hasAuthData(); org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthData(); } @@ -7879,7 +7831,7 @@ public AuthData getDefaultInstanceForType() { } private int bitField0_; - // required string auth_method_name = 1; + // optional string auth_method_name = 1; public static final int AUTH_METHOD_NAME_FIELD_NUMBER = 1; private java.lang.Object authMethodName_; public boolean hasAuthMethodName() { @@ -7911,7 +7863,7 @@ private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString getAuthMeth } } - // required bytes auth_data = 2; + // optional bytes auth_data = 2; public static final int AUTH_DATA_FIELD_NUMBER = 2; private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString authData_; public boolean hasAuthData() { @@ -7930,14 +7882,6 @@ public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized != -1) return isInitialized == 1; - if (!hasAuthMethodName()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasAuthData()) { - memoizedIsInitialized = 0; - return false; - } memoizedIsInitialized = 1; return true; } @@ -8146,14 +8090,6 @@ public Builder mergeFrom(org.apache.pulsar.common.api.proto.PulsarApi.AuthData o } public final boolean isInitialized() { - if (!hasAuthMethodName()) { - - return false; - } - if (!hasAuthData()) { - - return false; - } return true; } @@ -8195,7 +8131,7 @@ public Builder mergeFrom( private int bitField0_; - // required string auth_method_name = 1; + // optional string auth_method_name = 1; private java.lang.Object authMethodName_ = ""; public boolean hasAuthMethodName() { return ((bitField0_ & 0x00000001) == 0x00000001); @@ -8231,7 +8167,7 @@ void setAuthMethodName(org.apache.pulsar.shaded.com.google.protobuf.v241.ByteStr } - // required bytes auth_data = 2; + // optional bytes auth_data = 2; private org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString authData_ = org.apache.pulsar.shaded.com.google.protobuf.v241.ByteString.EMPTY; public boolean hasAuthData() { return ((bitField0_ & 0x00000002) == 0x00000002); @@ -27377,18 +27313,6 @@ public final boolean isInitialized() { return false; } } - if (hasAuthChallenge()) { - if (!getAuthChallenge().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - } - if (hasAuthResponse()) { - if (!getAuthResponse().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - } memoizedIsInitialized = 1; return true; } @@ -28356,18 +28280,6 @@ public final boolean isInitialized() { return false; } } - if (hasAuthChallenge()) { - if (!getAuthChallenge().isInitialized()) { - - return false; - } - } - if (hasAuthResponse()) { - if (!getAuthResponse().isInitialized()) { - - return false; - } - } return true; } diff --git a/pulsar-common/src/main/proto/PulsarApi.proto b/pulsar-common/src/main/proto/PulsarApi.proto index a60289377b230..b3e6f0f46232a 100644 --- a/pulsar-common/src/main/proto/PulsarApi.proto +++ b/pulsar-common/src/main/proto/PulsarApi.proto @@ -201,21 +201,21 @@ message CommandConnected { } message CommandAuthResponse { - required string client_version = 1; - required AuthData response = 2; + optional string client_version = 1; + optional AuthData response = 2; optional int32 protocol_version = 3 [default = 0]; } message CommandAuthChallenge { - required string server_version = 1; - required AuthData challenge = 2; + optional string server_version = 1; + optional AuthData challenge = 2; optional int32 protocol_version = 3 [default = 0]; } // To support mutual authentication type, such as Sasl, reuse this command to mutual auth. message AuthData { - required string auth_method_name = 1; - required bytes auth_data = 2; + optional string auth_method_name = 1; + optional bytes auth_data = 2; } message CommandSubscribe { From aa162d2c9e63b356f703f1d711a71b497e9804de Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Wed, 6 Mar 2019 22:46:13 +0800 Subject: [PATCH 11/13] change following ivan's comments --- .../AuthenticationProvider.java | 9 ++++-- .../authentication/AuthenticationState.java | 2 +- .../OneStageAuthenticationState.java | 5 ++-- .../pulsar/broker/service/ServerCnx.java | 4 ++- .../pulsar/broker/service/ServerCnxTest.java | 2 -- .../client/api/MutualAuthenticationTest.java | 29 ++++++++++++------- .../api/AuthenticationDataProvider.java | 3 +- .../apache/pulsar/client/impl/ClientCnx.java | 4 +-- 8 files changed, 36 insertions(+), 22 deletions(-) diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java index 78bdfafc0109a..4c778b53b6281 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java @@ -27,6 +27,7 @@ import javax.net.ssl.SSLSession; import org.apache.pulsar.broker.ServiceConfiguration; import org.apache.pulsar.common.api.AuthData; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; /** * Provider of authentication mechanism @@ -49,7 +50,9 @@ public interface AuthenticationProvider extends Closeable { String getAuthMethodName(); /** - * Validate the authentication for the given credentials with the specified authentication data + * Validate the authentication for the given credentials with the specified authentication data. + * This method is useful in one stage authn, if you're not doing one stage or if you're providing + * your own state implementation for one stage authn, it should throw an exception. * * @param authData * provider specific authentication data @@ -57,7 +60,9 @@ public interface AuthenticationProvider extends Closeable { * @throws AuthenticationException * if the credentials are not valid */ - String authenticate(AuthenticationDataSource authData) throws AuthenticationException; + default String authenticate(AuthenticationDataSource authData) throws AuthenticationException { + throw new UnsupportedOperationException(); + } /** * Create an authentication data State use passed in AuthenticationDataSource. diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java index c41e47bd22af9..2a3157150d13e 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java @@ -40,7 +40,7 @@ public interface AuthenticationState { /** * Challenge passed in auth data and get response data. */ - AuthData authenticate(AuthData authData) throws IOException; + AuthData authenticate(AuthData authData) throws IOException, AuthenticationException; /** * Return AuthenticationDataSource. diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java index b248b50238ed0..06b17496b5189 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/OneStageAuthenticationState.java @@ -20,11 +20,12 @@ package org.apache.pulsar.broker.authentication; import java.net.SocketAddress; -import java.nio.charset.Charset; import javax.naming.AuthenticationException; import javax.net.ssl.SSLSession; import org.apache.pulsar.common.api.AuthData; +import static java.nio.charset.StandardCharsets.UTF_8; + /** * Interface for authentication state. * @@ -41,7 +42,7 @@ public OneStageAuthenticationState(AuthData authData, SSLSession sslSession, AuthenticationProvider provider) throws AuthenticationException { this.authenticationDataSource = new AuthenticationDataCommand( - new String(authData.getBytes(), Charset.forName("UTF-8")), remoteAddress, sslSession);; + new String(authData.getBytes(), UTF_8), remoteAddress, sslSession);; this.authRole = provider.authenticate(authenticationDataSource); } diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java index 01895e2022bee..bcd739f8006cb 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java @@ -526,7 +526,9 @@ protected void handleConnect(CommandConnect connect) { // Not find provider named authMethod. Most used for tests. // In AuthenticationDisabled, it will set authMethod "none". if (authenticationProvider == null) { - authRole = getBrokerService().getAuthenticationService().getAnonymousUserRole().get(); + authRole = getBrokerService().getAuthenticationService().getAnonymousUserRole() + .orElseThrow(() -> + new AuthenticationException("No anonymous role, and no authentication provider configured")); completeConnect(clientProtocolVersion, clientVersion); return; } diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java index 84d29526a8d08..b98cd72bc2d3f 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxTest.java @@ -344,8 +344,6 @@ public void testConnectCommandWithAuthenticationPositive() throws Exception { doReturn(authenticationService).when(brokerService).getAuthenticationService(); doReturn(authenticationProvider).when(authenticationService).getAuthenticationProvider(Mockito.anyString()); - //doReturn(authenticationDataSource).when(authenticationProvider) - // .newAuthDataSource(Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject()); doReturn(authenticationState).when(authenticationProvider) .newAuthState(Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject()); doReturn(authData).when(authenticationState) diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java index cab19f22628a4..66ec4bf73d01f 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java @@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit; import javax.naming.AuthenticationException; import javax.net.ssl.SSLSession; +import lombok.Getter; import org.apache.pulsar.broker.ServiceConfiguration; import org.apache.pulsar.broker.authentication.AuthenticationDataSource; import org.apache.pulsar.broker.authentication.AuthenticationProvider; @@ -49,6 +50,8 @@ public class MutualAuthenticationTest extends ProducerConsumerBase { private static final Logger log = LoggerFactory.getLogger(MutualAuthenticationTest.class); + private MutualAuthentication mutualAuth; + private static String[] clientAuthStrings = { "MutualClientAuthInit", // step 0 "MutualClientStep1" // step 1 @@ -59,23 +62,25 @@ public class MutualAuthenticationTest extends ProducerConsumerBase { "ResponseMutualClientStep1" // step 1 }; - private static int authStep = 0; - public static class MutualAuthenticationDataProvider implements AuthenticationDataProvider { + private int authStep = 0; + @Override public boolean hasDataFromCommand() { return true; } @Override - public AuthData authenticate(AuthData data) throws IOException { + public AuthData authenticate(AuthData data) throws AuthenticationException { String dataString = new String(data.getBytes(), Charset.forName("UTF-8")); if (!dataString.equalsIgnoreCase("init")) { - assertEquals(dataString, serverAuthStrings[authStep - 1]); + if (!dataString.equals(serverAuthStrings[authStep - 1])) { + throw new AuthenticationException(); + } } log.debug("authenticate in client. passed in :{}, send: clientAuthStrings[{}]: {}", dataString, authStep, clientAuthStrings[authStep]); - return AuthData.of(clientAuthStrings[authStep].getBytes()); + return AuthData.of(clientAuthStrings[authStep ++].getBytes()); } } @@ -112,15 +117,19 @@ public void start() throws PulsarClientException { public static class MutualAuthenticationState implements AuthenticationState { + private int authStep = 0; + @Override public String getAuthRole() throws AuthenticationException { return "admin"; } @Override - public AuthData authenticate(AuthData authData) throws IOException { + public AuthData authenticate(AuthData authData) throws AuthenticationException { String clientData = new String(authData.getBytes(), Charset.forName("UTF-8")); - assertEquals(clientData, clientAuthStrings[authStep]); + if (!clientData.equals(clientAuthStrings[authStep])) { + throw new AuthenticationException(); + } log.debug("authenticate in server. passed in :{}, send: serverAuthStrings[{}]: {}", clientData, authStep, serverAuthStrings[authStep]); AuthData serverData = AuthData.of(serverAuthStrings[authStep ++].getBytes()); @@ -168,6 +177,7 @@ public AuthenticationState newAuthState(AuthData authData, @BeforeMethod @Override protected void setup() throws Exception { + mutualAuth = new MutualAuthentication(); Set superUserRoles = new HashSet(); superUserRoles.add("admin"); conf.setSuperUserRoles(superUserRoles); @@ -180,7 +190,7 @@ protected void setup() throws Exception { super.init(); URI brokerServiceUrl = new URI("pulsar://localhost:" + BROKER_PORT); pulsarClient = PulsarClient.builder().serviceUrl(brokerServiceUrl.toString()) - .authentication(new MutualAuthentication()) + .authentication(mutualAuth) .build(); super.producerBaseSetup(); } @@ -217,9 +227,6 @@ public void testAuthentication() throws Exception { } consumer.acknowledgeCumulative(msg); - // mutual auth happened. - assertEquals(authStep, 2); - log.info("-- Exiting {} test --", methodName); } } diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java index 5aa37f4079d94..f5c0a9872b0f8 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java @@ -24,6 +24,7 @@ import java.security.cert.Certificate; import java.util.Map; import java.util.Set; +import javax.naming.AuthenticationException; import org.apache.pulsar.common.api.AuthData; /** @@ -116,7 +117,7 @@ default String getCommandData() { * * Mainly used for mutual authentication like sasl. */ - default AuthData authenticate(AuthData data) throws IOException { + default AuthData authenticate(AuthData data) throws IOException, AuthenticationException { byte[] bytes = (hasDataFromCommand() ? this.getCommandData() : "").getBytes("UTF-8"); return AuthData.of(bytes); } diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java index ce9efd67cefd9..5b18114718bb7 100644 --- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java +++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java @@ -195,7 +195,7 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception { }); } - protected ByteBuf newConnectCommand() throws IOException { + protected ByteBuf newConnectCommand() throws Exception { // mutual authentication is to auth between `remoteHostName` and this client for this channel. // each channel will have a mutual client/server pair, mutual client evaluateChallenge with init data, // and return authData to server. @@ -314,7 +314,7 @@ protected void handleAuthChallenge(CommandAuthChallenge authChallenge) { } }); state = State.Connecting; - } catch (IOException e) { + } catch (Exception e) { log.error("{} Error mutual verify: {}", ctx.channel(), e); connectionFuture.completeExceptionally(e); return; From 61bdfee48b650cce47e01d0a69ac37444c0ac806 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Tue, 12 Mar 2019 13:08:58 +0800 Subject: [PATCH 12/13] change follow ivan's comments --- .../AuthenticationProvider.java | 3 +- .../authentication/AuthenticationState.java | 3 +- .../client/api/MutualAuthenticationTest.java | 52 +++++++++++-------- .../api/AuthenticationDataProvider.java | 4 +- .../apache/pulsar/common/api/AuthData.java | 4 ++ .../apache/pulsar/client/impl/ClientCnx.java | 2 +- 6 files changed, 40 insertions(+), 28 deletions(-) diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java index 4c778b53b6281..755fe8643857e 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProvider.java @@ -27,7 +27,6 @@ import javax.net.ssl.SSLSession; import org.apache.pulsar.broker.ServiceConfiguration; import org.apache.pulsar.common.api.AuthData; -import sun.reflect.generics.reflectiveObjects.NotImplementedException; /** * Provider of authentication mechanism @@ -61,7 +60,7 @@ public interface AuthenticationProvider extends Closeable { * if the credentials are not valid */ default String authenticate(AuthenticationDataSource authData) throws AuthenticationException { - throw new UnsupportedOperationException(); + throw new AuthenticationException("Not supported"); } /** diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java index 2a3157150d13e..4248b6b8a9e8a 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationState.java @@ -19,7 +19,6 @@ package org.apache.pulsar.broker.authentication; -import java.io.IOException; import javax.naming.AuthenticationException; import org.apache.pulsar.common.api.AuthData; @@ -40,7 +39,7 @@ public interface AuthenticationState { /** * Challenge passed in auth data and get response data. */ - AuthData authenticate(AuthData authData) throws IOException, AuthenticationException; + AuthData authenticate(AuthData authData) throws AuthenticationException; /** * Return AuthenticationDataSource. diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java index 66ec4bf73d01f..b2476229dcc28 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/MutualAuthenticationTest.java @@ -22,14 +22,13 @@ import java.io.IOException; import java.net.SocketAddress; import java.net.URI; -import java.nio.charset.Charset; +import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.naming.AuthenticationException; import javax.net.ssl.SSLSession; -import lombok.Getter; import org.apache.pulsar.broker.ServiceConfiguration; import org.apache.pulsar.broker.authentication.AuthenticationDataSource; import org.apache.pulsar.broker.authentication.AuthenticationProvider; @@ -41,7 +40,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; +import static java.nio.charset.StandardCharsets.UTF_8; /** * Test Mutual Authentication. @@ -59,12 +58,9 @@ public class MutualAuthenticationTest extends ProducerConsumerBase { private static String[] serverAuthStrings = { "ResponseMutualClientAuthInit", // step 0 - "ResponseMutualClientStep1" // step 1 }; public static class MutualAuthenticationDataProvider implements AuthenticationDataProvider { - private int authStep = 0; - @Override public boolean hasDataFromCommand() { return true; @@ -72,15 +68,20 @@ public boolean hasDataFromCommand() { @Override public AuthData authenticate(AuthData data) throws AuthenticationException { - String dataString = new String(data.getBytes(), Charset.forName("UTF-8")); - if (!dataString.equalsIgnoreCase("init")) { - if (!dataString.equals(serverAuthStrings[authStep - 1])) { - throw new AuthenticationException(); - } + String dataString = new String(data.getBytes(), UTF_8); + AuthData toSend; + + if (Arrays.equals(dataString.getBytes(), AuthData.INIT_AUTH_DATA)) { + toSend = AuthData.of(clientAuthStrings[0].getBytes(UTF_8)); + } else if (Arrays.equals(dataString.getBytes(), serverAuthStrings[0].getBytes(UTF_8))) { + toSend = AuthData.of(clientAuthStrings[1].getBytes(UTF_8)); + } else { + throw new AuthenticationException(); } - log.debug("authenticate in client. passed in :{}, send: clientAuthStrings[{}]: {}", - dataString, authStep, clientAuthStrings[authStep]); - return AuthData.of(clientAuthStrings[authStep ++].getBytes()); + + log.debug("authenticate in client. passed in :{}, send: {}", + dataString, new String(toSend.getBytes(), UTF_8)); + return toSend; } } @@ -117,7 +118,7 @@ public void start() throws PulsarClientException { public static class MutualAuthenticationState implements AuthenticationState { - private int authStep = 0; + private boolean isComplete = false; @Override public String getAuthRole() throws AuthenticationException { @@ -126,14 +127,21 @@ public String getAuthRole() throws AuthenticationException { @Override public AuthData authenticate(AuthData authData) throws AuthenticationException { - String clientData = new String(authData.getBytes(), Charset.forName("UTF-8")); - if (!clientData.equals(clientAuthStrings[authStep])) { + String dataString = new String(authData.getBytes(), UTF_8); + AuthData toSend; + + if (Arrays.equals(dataString.getBytes(), clientAuthStrings[0].getBytes(UTF_8))) { + toSend = AuthData.of(serverAuthStrings[0].getBytes(UTF_8)); + } else if (Arrays.equals(dataString.getBytes(), clientAuthStrings[1].getBytes(UTF_8))) { + isComplete = true; + toSend = AuthData.of(null); + } else { throw new AuthenticationException(); } - log.debug("authenticate in server. passed in :{}, send: serverAuthStrings[{}]: {}", - clientData, authStep, serverAuthStrings[authStep]); - AuthData serverData = AuthData.of(serverAuthStrings[authStep ++].getBytes()); - return serverData; + + log.debug("authenticate in server. passed in :{}, send: {}", + dataString, toSend.getBytes() == null ? "null" : new String(toSend.getBytes(), UTF_8)); + return toSend; } @Override @@ -143,7 +151,7 @@ public AuthenticationDataSource getAuthDataSource() { @Override public boolean isComplete() { - return authStep > 1; + return isComplete; } } diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java index f5c0a9872b0f8..ecf3d3f5b3929 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/AuthenticationDataProvider.java @@ -27,6 +27,8 @@ import javax.naming.AuthenticationException; import org.apache.pulsar.common.api.AuthData; +import static java.nio.charset.StandardCharsets.UTF_8; + /** * Interface for accessing data which are used in variety of authentication schemes on client side */ @@ -118,7 +120,7 @@ default String getCommandData() { * Mainly used for mutual authentication like sasl. */ default AuthData authenticate(AuthData data) throws IOException, AuthenticationException { - byte[] bytes = (hasDataFromCommand() ? this.getCommandData() : "").getBytes("UTF-8"); + byte[] bytes = (hasDataFromCommand() ? this.getCommandData() : "").getBytes(UTF_8); return AuthData.of(bytes); } } diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java index 1f060e405b1ab..be6f0e6589a91 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java @@ -20,8 +20,12 @@ import lombok.Data; +import static java.nio.charset.StandardCharsets.UTF_8; + @Data(staticConstructor="of") public final class AuthData { + public static byte[] INIT_AUTH_DATA = "init".getBytes(UTF_8); + private final byte[] bytes; public boolean isComplete() { diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java index 5b18114718bb7..5f2dae0bc7ca3 100644 --- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java +++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java @@ -200,7 +200,7 @@ protected ByteBuf newConnectCommand() throws Exception { // each channel will have a mutual client/server pair, mutual client evaluateChallenge with init data, // and return authData to server. authenticationDataProvider = authentication.getAuthData(remoteHostName); - AuthData authData = authenticationDataProvider.authenticate(AuthData.of("init".getBytes("UTF-8"))); + AuthData authData = authenticationDataProvider.authenticate(AuthData.of(AuthData.INIT_AUTH_DATA)); return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, getPulsarClientVersion(), proxyToTargetBrokerAddress, null, null, null); } From 6edd19b6cf709e7ba144bb0cb16baef5e5acee08 Mon Sep 17 00:00:00 2001 From: Jia Zhai Date: Tue, 12 Mar 2019 22:43:41 +0800 Subject: [PATCH 13/13] change following ivan's comments --- .../src/main/java/org/apache/pulsar/common/api/AuthData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java index be6f0e6589a91..ccf1e7f770822 100644 --- a/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java +++ b/pulsar-client-api/src/main/java/org/apache/pulsar/common/api/AuthData.java @@ -24,7 +24,7 @@ @Data(staticConstructor="of") public final class AuthData { - public static byte[] INIT_AUTH_DATA = "init".getBytes(UTF_8); + public static byte[] INIT_AUTH_DATA = "PulsarAuthInit".getBytes(UTF_8); private final byte[] bytes;