Search in sources :

Example 11 with NetworkSend

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;
}
Also used : SaslAuthenticateRequest(org.apache.kafka.common.requests.SaslAuthenticateRequest) NetworkSend(org.apache.kafka.common.network.NetworkSend) ByteBuffer(java.nio.ByteBuffer)

Example 12 with NetworkSend

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;
        }
    }
}
Also used : SaslAuthenticateResponse(org.apache.kafka.common.requests.SaslAuthenticateResponse) NetworkSend(org.apache.kafka.common.network.NetworkSend) IllegalSaslStateException(org.apache.kafka.common.errors.IllegalSaslStateException) SaslException(javax.security.sasl.SaslException) ByteBuffer(java.nio.ByteBuffer) ApiKeys(org.apache.kafka.common.protocol.ApiKeys) SaslAuthenticateRequest(org.apache.kafka.common.requests.SaslAuthenticateRequest) RequestAndSize(org.apache.kafka.common.requests.RequestAndSize) RequestHeader(org.apache.kafka.common.requests.RequestHeader) RequestContext(org.apache.kafka.common.requests.RequestContext) SaslAuthenticationException(org.apache.kafka.common.errors.SaslAuthenticationException) UnsupportedVersionException(org.apache.kafka.common.errors.UnsupportedVersionException)

Example 13 with NetworkSend

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));
        }
    }
}
Also used : NetworkSend(org.apache.kafka.common.network.NetworkSend)

Example 14 with NetworkSend

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);
}
Also used : RequestHeader(org.apache.kafka.common.requests.RequestHeader) NetworkSend(org.apache.kafka.common.network.NetworkSend) ByteBuffer(java.nio.ByteBuffer)

Example 15 with NetworkSend

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");
}
Also used : SecurityProtocol(org.apache.kafka.common.security.auth.SecurityProtocol) RequestHeader(org.apache.kafka.common.requests.RequestHeader) NetworkSend(org.apache.kafka.common.network.NetworkSend) SaslHandshakeRequest(org.apache.kafka.common.requests.SaslHandshakeRequest) Test(org.junit.jupiter.api.Test)

Aggregations

NetworkSend (org.apache.kafka.common.network.NetworkSend)20 ByteBuffer (java.nio.ByteBuffer)10 SecurityProtocol (org.apache.kafka.common.security.auth.SecurityProtocol)10 RequestHeader (org.apache.kafka.common.requests.RequestHeader)9 Test (org.junit.jupiter.api.Test)8 ApiVersionsRequest (org.apache.kafka.common.requests.ApiVersionsRequest)4 SaslAuthenticateRequest (org.apache.kafka.common.requests.SaslAuthenticateRequest)4 ApiVersionsResponse (org.apache.kafka.common.requests.ApiVersionsResponse)3 Random (java.util.Random)2 SaslException (javax.security.sasl.SaslException)2 IllegalSaslStateException (org.apache.kafka.common.errors.IllegalSaslStateException)2 UnsupportedVersionException (org.apache.kafka.common.errors.UnsupportedVersionException)2 Test (org.junit.Test)2 IOException (java.io.IOException)1 PrivilegedActionException (java.security.PrivilegedActionException)1 KafkaException (org.apache.kafka.common.KafkaException)1 AuthenticationException (org.apache.kafka.common.errors.AuthenticationException)1 SaslAuthenticationException (org.apache.kafka.common.errors.SaslAuthenticationException)1 UnsupportedSaslMechanismException (org.apache.kafka.common.errors.UnsupportedSaslMechanismException)1 ApiVersionsRequestData (org.apache.kafka.common.message.ApiVersionsRequestData)1