use of org.apache.kafka.common.network.NetworkSend in project apache-kafka-on-k8s by banzaicloud.
the class SaslClientAuthenticator method sendSaslClientToken.
/**
* Sends a SASL client token to server if required. This may be an initial token to start
* SASL token exchange or response to a challenge from the server.
* @return true if a token was sent to the server
*/
private boolean sendSaslClientToken(byte[] serverToken, boolean isInitial) throws IOException {
if (!saslClient.isComplete()) {
byte[] saslToken = createSaslToken(serverToken, isInitial);
if (saslToken != null) {
ByteBuffer tokenBuf = ByteBuffer.wrap(saslToken);
if (saslAuthenticateVersion != DISABLE_KAFKA_SASL_AUTHENTICATE_HEADER) {
SaslAuthenticateRequest request = new SaslAuthenticateRequest.Builder(tokenBuf).build(saslAuthenticateVersion);
tokenBuf = request.serialize(nextRequestHeader(ApiKeys.SASL_AUTHENTICATE, saslAuthenticateVersion));
}
send(new NetworkSend(node, tokenBuf));
return true;
}
}
return false;
}
use of org.apache.kafka.common.network.NetworkSend in project apache-kafka-on-k8s by banzaicloud.
the class SaslServerAuthenticator method handleSaslToken.
private void handleSaslToken(byte[] clientToken) throws IOException {
if (!enableKafkaSaslAuthenticateHeaders) {
byte[] response = saslServer.evaluateResponse(clientToken);
if (response != null) {
netOutBuffer = new NetworkSend(connectionId, ByteBuffer.wrap(response));
flushNetOutBufferAndUpdateInterestOps();
}
} else {
ByteBuffer requestBuffer = ByteBuffer.wrap(clientToken);
RequestHeader header = RequestHeader.parse(requestBuffer);
ApiKeys apiKey = header.apiKey();
short version = header.apiVersion();
RequestContext requestContext = new RequestContext(header, connectionId, clientAddress(), KafkaPrincipal.ANONYMOUS, listenerName, securityProtocol);
RequestAndSize requestAndSize = requestContext.parseRequest(requestBuffer);
if (apiKey != ApiKeys.SASL_AUTHENTICATE) {
IllegalSaslStateException e = new IllegalSaslStateException("Unexpected Kafka request of type " + apiKey + " during SASL authentication.");
sendKafkaResponse(requestContext, requestAndSize.request.getErrorResponse(e));
throw e;
}
if (!apiKey.isVersionSupported(version)) {
// This should not normally occur since clients typically check supported versions using ApiVersionsRequest
throw new UnsupportedVersionException("Version " + version + " is not supported for apiKey " + apiKey);
}
SaslAuthenticateRequest saslAuthenticateRequest = (SaslAuthenticateRequest) requestAndSize.request;
try {
byte[] responseToken = saslServer.evaluateResponse(Utils.readBytes(saslAuthenticateRequest.saslAuthBytes()));
// For versions with SASL_AUTHENTICATE header, send a response to SASL_AUTHENTICATE request even if token is empty.
ByteBuffer responseBuf = responseToken == null ? EMPTY_BUFFER : ByteBuffer.wrap(responseToken);
sendKafkaResponse(requestContext, new SaslAuthenticateResponse(Errors.NONE, null, responseBuf));
} catch (SaslAuthenticationException | SaslException e) {
String errorMessage = e instanceof SaslAuthenticationException ? e.getMessage() : "Authentication failed due to invalid credentials with SASL mechanism " + saslMechanism;
sendKafkaResponse(requestContext, new SaslAuthenticateResponse(Errors.SASL_AUTHENTICATION_FAILED, errorMessage));
throw e;
}
}
}
use of org.apache.kafka.common.network.NetworkSend in project kafka by apache.
the class NetworkClient method handleCompletedSends.
/**
* Handle any completed request send. In particular if no response is expected consider the request complete.
*
* @param responses The list of responses to update
* @param now The current time
*/
private void handleCompletedSends(List<ClientResponse> responses, long now) {
// if no response is expected then when the send is completed, return it
for (NetworkSend send : this.selector.completedSends()) {
InFlightRequest request = this.inFlightRequests.lastSent(send.destinationId());
if (!request.expectResponse) {
this.inFlightRequests.completeLastSent(send.destinationId());
responses.add(request.completed(null, now));
}
}
}
use of org.apache.kafka.common.network.NetworkSend in project kafka by apache.
the class SaslAuthenticatorTest method sendKafkaRequestReceiveResponse.
private AbstractResponse sendKafkaRequestReceiveResponse(String node, ApiKeys apiKey, AbstractRequest request) throws IOException {
RequestHeader header = new RequestHeader(apiKey, request.version(), "someclient", nextCorrelationId++);
NetworkSend send = new NetworkSend(node, request.toSend(header));
selector.send(send);
ByteBuffer responseBuffer = waitForResponse();
return NetworkClient.parseResponse(responseBuffer, header);
}
use of org.apache.kafka.common.network.NetworkSend in project kafka by apache.
the class SaslAuthenticatorTest method testSaslHandshakeRequestWithUnsupportedVersion.
/**
* Tests that unsupported version of SASL handshake request returns error
* response and fails authentication. This test is similar to
* {@link #testUnauthenticatedApiVersionsRequest(SecurityProtocol, short)}
* where a non-SASL client is used to send requests that are processed by
* {@link SaslServerAuthenticator} of the server prior to client authentication.
*/
@Test
public void testSaslHandshakeRequestWithUnsupportedVersion() throws Exception {
SecurityProtocol securityProtocol = SecurityProtocol.SASL_PLAINTEXT;
configureMechanisms("PLAIN", Arrays.asList("PLAIN"));
server = createEchoServer(securityProtocol);
// Send SaslHandshakeRequest and validate that connection is closed by server.
String node1 = "invalid1";
createClientConnection(SecurityProtocol.PLAINTEXT, node1);
SaslHandshakeRequest request = buildSaslHandshakeRequest("PLAIN", ApiKeys.SASL_HANDSHAKE.latestVersion());
RequestHeader header = new RequestHeader(ApiKeys.SASL_HANDSHAKE, Short.MAX_VALUE, "someclient", 2);
selector.send(new NetworkSend(node1, request.toSend(header)));
// This test uses a non-SASL PLAINTEXT client in order to do manual handshake.
// So the channel is in READY state.
NetworkTestUtils.waitForChannelClose(selector, node1, ChannelState.READY.state());
selector.close();
// Test good connection still works
createAndCheckClientConnection(securityProtocol, "good1");
}
Aggregations