@Override public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { LOG.debug("send/recv time (ms): {}", (System.currentTimeMillis() - start_time)); // examine the response message from server if (message instanceof ControlMessage) { handleControlMessage(ctx, (ControlMessage) message); } else if (message instanceof SaslMessageToken) { handleSaslMessageToken(ctx, (SaslMessageToken) message); } else { LOG.error("Unexpected message from server: {}", message); } }
@Override protected void initChannel(Channel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("encoder", new ThriftEncoder()); pipeline.addLast("decoder", new ThriftDecoder(thriftMessageMaxSize)); if (authMethod == AuthMethod.KERBEROS) { try { LOG.debug("Adding KerberosSaslClientHandler to pacemaker client pipeline."); pipeline.addLast(KERBEROS_HANDLER, new KerberosSaslClientHandler(client, topoConf, ClientAuthUtils.LOGIN_CONTEXT_PACEMAKER_CLIENT, host)); } catch (IOException e) { throw new RuntimeException(e); } } else if (authMethod == AuthMethod.DIGEST) { try { LOG.debug("Adding SaslStormClientHandler to pacemaker client pipeline."); pipeline.addLast(SASL_HANDLER, new SaslStormClientHandler(client)); } catch (IOException e) { throw new RuntimeException(e); } } else { client.channelReady(ch); } pipeline.addLast("PacemakerClientHandler", new PacemakerClientHandler(client)); }
private void handleControlMessage(ChannelHandlerContext ctx, ControlMessage controlMessage) throws Exception { Channel channel = ctx.channel(); KerberosSaslNettyClient saslNettyClient = getChannelSaslClient(channel); if (controlMessage == ControlMessage.SASL_COMPLETE_REQUEST) { LOG.debug("Server has sent us the SaslComplete message. Allowing normal work to proceed."); if (!saslNettyClient.isComplete()) { String errorMessage = "Server returned a Sasl-complete message, but as far as we can tell, we are not authenticated yet."; LOG.error(errorMessage); throw new Exception(errorMessage); } ctx.pipeline().remove(this); this.client.channelReady(channel); // We call fireChannelRead since the client is allowed to // perform this request. The client's request will now proceed // to the next pipeline component namely StormClientHandler. ctx.fireChannelRead(controlMessage); } else { LOG.warn("Unexpected control message: {}", controlMessage); } }
LOG.debug("Adding KerberosSaslClientHandler to pacemaker client pipeline."); pipeline.addLast(KERBEROS_HANDLER, new KerberosSaslClientHandler(client, storm_conf, AuthUtils.LOGIN_CONTEXT_PACEMAKER_CLIENT,
private void handleSaslMessageToken(ChannelHandlerContext ctx, SaslMessageToken saslMessageToken) throws Exception { Channel channel = ctx.channel(); KerberosSaslNettyClient saslNettyClient = getChannelSaslClient(channel); LOG.debug("Responding to server's token of length: {}", saslMessageToken.getSaslToken().length); // Generate SASL response (but we only actually send the response if // it's non-null. byte[] responseToServer = saslNettyClient.saslResponse(saslMessageToken); if (responseToServer == null) { // If we generate a null response, then authentication has completed // (if not, warn), and return without sending a response back to the // server. LOG.debug("Response to server is null: authentication should now be complete."); if (!saslNettyClient.isComplete()) { LOG.warn("Generated a null response, but authentication is not complete."); throw new Exception("Our reponse to the server is null, but as far as we can tell, we are not authenticated yet."); } this.client.channelReady(channel); } else { LOG.debug("Response to server token has length: {}", responseToServer.length); // Construct a message containing the SASL response and send it to the server. SaslMessageToken saslResponse = new SaslMessageToken(responseToServer); channel.writeAndFlush(saslResponse, channel.voidPromise()); } }