Search in sources :

Example 16 with RequestHeader

use of org.apache.kafka.common.requests.RequestHeader in project kafka by apache.

the class MetadataRequestBenchmark method buildAllTopicMetadataRequest.

private RequestChannel.Request buildAllTopicMetadataRequest() {
    MetadataRequest metadataRequest = MetadataRequest.Builder.allTopics().build();
    RequestHeader header = new RequestHeader(metadataRequest.apiKey(), metadataRequest.version(), "", 0);
    ByteBuffer bodyBuffer = metadataRequest.serialize();
    RequestContext context = new RequestContext(header, "1", null, principal, ListenerName.forSecurityProtocol(SecurityProtocol.PLAINTEXT), SecurityProtocol.PLAINTEXT, ClientInformation.EMPTY, false);
    return new RequestChannel.Request(1, context, 0, MemoryPool.NONE, bodyBuffer, requestChannelMetrics, Option.empty());
}
Also used : UpdateMetadataRequest(org.apache.kafka.common.requests.UpdateMetadataRequest) MetadataRequest(org.apache.kafka.common.requests.MetadataRequest) UpdateMetadataRequest(org.apache.kafka.common.requests.UpdateMetadataRequest) MetadataRequest(org.apache.kafka.common.requests.MetadataRequest) RequestHeader(org.apache.kafka.common.requests.RequestHeader) RequestContext(org.apache.kafka.common.requests.RequestContext) ByteBuffer(java.nio.ByteBuffer)

Example 17 with RequestHeader

use of org.apache.kafka.common.requests.RequestHeader in project kafka by apache.

the class SaslAuthenticatorTest method testApiVersionsRequestWithUnsupportedVersion.

/**
     * Tests that unsupported version of ApiVersionsRequest before SASL handshake request
     * returns error response and does not result in authentication failure. This test
     * is similar to {@link #testUnauthenticatedApiVersionsRequest(SecurityProtocol)}
     * 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 testApiVersionsRequestWithUnsupportedVersion() throws Exception {
    SecurityProtocol securityProtocol = SecurityProtocol.SASL_PLAINTEXT;
    configureMechanisms("PLAIN", Arrays.asList("PLAIN"));
    server = createEchoServer(securityProtocol);
    // Send ApiVersionsRequest with unsupported version and validate error response.
    String node = "1";
    createClientConnection(SecurityProtocol.PLAINTEXT, node);
    RequestHeader header = new RequestHeader(ApiKeys.API_VERSIONS.id, Short.MAX_VALUE, "someclient", 1);
    ApiVersionsRequest request = new ApiVersionsRequest.Builder().build();
    selector.send(request.toSend(node, header));
    ByteBuffer responseBuffer = waitForResponse();
    ResponseHeader.parse(responseBuffer);
    ApiVersionsResponse response = ApiVersionsResponse.parse(responseBuffer, (short) 0);
    assertEquals(Errors.UNSUPPORTED_VERSION, response.error());
    // Send ApiVersionsRequest with a supported version. This should succeed.
    sendVersionRequestReceiveResponse(node);
    // Test that client can authenticate successfully
    sendHandshakeRequestReceiveResponse(node);
    authenticateUsingSaslPlainAndCheckConnection(node);
}
Also used : ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) SecurityProtocol(org.apache.kafka.common.protocol.SecurityProtocol) RequestHeader(org.apache.kafka.common.requests.RequestHeader) ApiVersionsRequest(org.apache.kafka.common.requests.ApiVersionsRequest) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Example 18 with RequestHeader

use of org.apache.kafka.common.requests.RequestHeader 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 19 with RequestHeader

use of org.apache.kafka.common.requests.RequestHeader in project apache-kafka-on-k8s by banzaicloud.

the class SaslServerAuthenticator method handleKafkaRequest.

private boolean handleKafkaRequest(byte[] requestBytes) throws IOException, AuthenticationException {
    boolean isKafkaRequest = false;
    String clientMechanism = null;
    try {
        ByteBuffer requestBuffer = ByteBuffer.wrap(requestBytes);
        RequestHeader header = RequestHeader.parse(requestBuffer);
        ApiKeys apiKey = header.apiKey();
        // following a SaslHandshakeRequest since this is not a GSSAPI client token from a Kafka 0.9.0.x client.
        if (saslState == SaslState.INITIAL_REQUEST)
            setSaslState(SaslState.HANDSHAKE_OR_VERSIONS_REQUEST);
        isKafkaRequest = true;
        // unnecessary exposure to some of the more complex schema types.
        if (apiKey != ApiKeys.API_VERSIONS && apiKey != ApiKeys.SASL_HANDSHAKE)
            throw new IllegalSaslStateException("Unexpected Kafka request of type " + apiKey + " during SASL handshake.");
        LOG.debug("Handling Kafka request {}", apiKey);
        RequestContext requestContext = new RequestContext(header, connectionId, clientAddress(), KafkaPrincipal.ANONYMOUS, listenerName, securityProtocol);
        RequestAndSize requestAndSize = requestContext.parseRequest(requestBuffer);
        if (apiKey == ApiKeys.API_VERSIONS)
            handleApiVersionsRequest(requestContext, (ApiVersionsRequest) requestAndSize.request);
        else
            clientMechanism = handleHandshakeRequest(requestContext, (SaslHandshakeRequest) requestAndSize.request);
    } catch (InvalidRequestException e) {
        if (saslState == SaslState.INITIAL_REQUEST) {
            // starting with 0x60, revert to GSSAPI for both these exceptions.
            if (LOG.isDebugEnabled()) {
                StringBuilder tokenBuilder = new StringBuilder();
                for (byte b : requestBytes) {
                    tokenBuilder.append(String.format("%02x", b));
                    if (tokenBuilder.length() >= 20)
                        break;
                }
                LOG.debug("Received client packet of length {} starting with bytes 0x{}, process as GSSAPI packet", requestBytes.length, tokenBuilder);
            }
            if (enabledMechanisms.contains(SaslConfigs.GSSAPI_MECHANISM)) {
                LOG.debug("First client packet is not a SASL mechanism request, using default mechanism GSSAPI");
                clientMechanism = SaslConfigs.GSSAPI_MECHANISM;
            } else
                throw new UnsupportedSaslMechanismException("Exception handling first SASL packet from client, GSSAPI is not supported by server", e);
        } else
            throw e;
    }
    if (clientMechanism != null) {
        createSaslServer(clientMechanism);
        setSaslState(SaslState.AUTHENTICATE);
    }
    return isKafkaRequest;
}
Also used : ApiKeys(org.apache.kafka.common.protocol.ApiKeys) RequestAndSize(org.apache.kafka.common.requests.RequestAndSize) UnsupportedSaslMechanismException(org.apache.kafka.common.errors.UnsupportedSaslMechanismException) RequestHeader(org.apache.kafka.common.requests.RequestHeader) InvalidRequestException(org.apache.kafka.common.errors.InvalidRequestException) IllegalSaslStateException(org.apache.kafka.common.errors.IllegalSaslStateException) RequestContext(org.apache.kafka.common.requests.RequestContext) ByteBuffer(java.nio.ByteBuffer) ApiVersionsRequest(org.apache.kafka.common.requests.ApiVersionsRequest)

Example 20 with RequestHeader

use of org.apache.kafka.common.requests.RequestHeader in project apache-kafka-on-k8s by banzaicloud.

the class SaslAuthenticatorTest method testInvalidApiVersionsRequestSequence.

/**
 * Tests that ApiVersionsRequest after Kafka SASL handshake request flow,
 * but prior to actual SASL authentication, results in authentication failure.
 * This 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 testInvalidApiVersionsRequestSequence() throws Exception {
    SecurityProtocol securityProtocol = SecurityProtocol.SASL_PLAINTEXT;
    configureMechanisms("PLAIN", Arrays.asList("PLAIN"));
    server = createEchoServer(securityProtocol);
    // Send handshake request followed by ApiVersionsRequest
    String node1 = "invalid1";
    createClientConnection(SecurityProtocol.PLAINTEXT, node1);
    sendHandshakeRequestReceiveResponse(node1, (short) 1);
    ApiVersionsRequest request = createApiVersionsRequestV0();
    RequestHeader versionsHeader = new RequestHeader(ApiKeys.API_VERSIONS, request.version(), "someclient", 2);
    selector.send(request.toSend(node1, versionsHeader));
    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) ApiVersionsRequest(org.apache.kafka.common.requests.ApiVersionsRequest) Test(org.junit.Test)

Aggregations

RequestHeader (org.apache.kafka.common.requests.RequestHeader)35 ByteBuffer (java.nio.ByteBuffer)19 SecurityProtocol (org.apache.kafka.common.security.auth.SecurityProtocol)12 Test (org.junit.jupiter.api.Test)12 ApiVersionsRequest (org.apache.kafka.common.requests.ApiVersionsRequest)11 NetworkSend (org.apache.kafka.common.network.NetworkSend)10 ApiVersionsResponse (org.apache.kafka.common.requests.ApiVersionsResponse)10 ApiKeys (org.apache.kafka.common.protocol.ApiKeys)7 IllegalSaslStateException (org.apache.kafka.common.errors.IllegalSaslStateException)6 RequestContext (org.apache.kafka.common.requests.RequestContext)6 Test (org.junit.Test)5 Collections (java.util.Collections)4 MetadataRequest (org.apache.kafka.common.requests.MetadataRequest)4 IOException (java.io.IOException)3 InetAddress (java.net.InetAddress)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ApiVersionsResponseData (org.apache.kafka.common.message.ApiVersionsResponseData)3 ApiVersion (org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion)3 TransportLayer (org.apache.kafka.common.network.TransportLayer)3