Search in sources :

Example 6 with InvalidRequestException

use of org.apache.kafka.common.errors.InvalidRequestException 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 7 with InvalidRequestException

use of org.apache.kafka.common.errors.InvalidRequestException in project apache-kafka-on-k8s by banzaicloud.

the class RequestContext method parseRequest.

public RequestAndSize parseRequest(ByteBuffer buffer) {
    if (isUnsupportedApiVersionsRequest()) {
        // Unsupported ApiVersion requests are treated as v0 requests and are not parsed
        ApiVersionsRequest apiVersionsRequest = new ApiVersionsRequest((short) 0, header.apiVersion());
        return new RequestAndSize(apiVersionsRequest, 0);
    } else {
        ApiKeys apiKey = header.apiKey();
        try {
            short apiVersion = header.apiVersion();
            Struct struct = apiKey.parseRequest(apiVersion, buffer);
            AbstractRequest body = AbstractRequest.parseRequest(apiKey, apiVersion, struct);
            return new RequestAndSize(body, struct.sizeOf());
        } catch (Throwable ex) {
            throw new InvalidRequestException("Error getting request for apiKey: " + apiKey + ", apiVersion: " + header.apiVersion() + ", connectionId: " + connectionId + ", listenerName: " + listenerName + ", principal: " + principal, ex);
        }
    }
}
Also used : ApiKeys(org.apache.kafka.common.protocol.ApiKeys) InvalidRequestException(org.apache.kafka.common.errors.InvalidRequestException) Struct(org.apache.kafka.common.protocol.types.Struct)

Example 8 with InvalidRequestException

use of org.apache.kafka.common.errors.InvalidRequestException in project apache-kafka-on-k8s by banzaicloud.

the class RequestHeader method parse.

public static RequestHeader parse(ByteBuffer buffer) {
    try {
        short apiKey = buffer.getShort();
        short apiVersion = buffer.getShort();
        Schema schema = schema(apiKey, apiVersion);
        buffer.rewind();
        return new RequestHeader(schema.read(buffer));
    } catch (InvalidRequestException e) {
        throw e;
    } catch (Throwable ex) {
        throw new InvalidRequestException("Error parsing request header. Our best guess of the apiKey is: " + buffer.getShort(0), ex);
    }
}
Also used : Schema(org.apache.kafka.common.protocol.types.Schema) InvalidRequestException(org.apache.kafka.common.errors.InvalidRequestException)

Example 9 with InvalidRequestException

use of org.apache.kafka.common.errors.InvalidRequestException in project kafka by apache.

the class RequestHeader method parse.

public static RequestHeader parse(ByteBuffer buffer) {
    short apiKey = -1;
    try {
        // We derive the header version from the request api version, so we read that first.
        // The request api version is part of `RequestHeaderData`, so we reset the buffer position after the read.
        int position = buffer.position();
        apiKey = buffer.getShort();
        short apiVersion = buffer.getShort();
        short headerVersion = ApiKeys.forId(apiKey).requestHeaderVersion(apiVersion);
        buffer.position(position);
        RequestHeaderData headerData = new RequestHeaderData(new ByteBufferAccessor(buffer), headerVersion);
        // However, we treat a null client ID as equivalent to an empty client ID.
        if (headerData.clientId() == null) {
            headerData.setClientId("");
        }
        return new RequestHeader(headerData, headerVersion);
    } catch (UnsupportedVersionException e) {
        throw new InvalidRequestException("Unknown API key " + apiKey, e);
    } catch (Throwable ex) {
        throw new InvalidRequestException("Error parsing request header. Our best guess of the apiKey is: " + apiKey, ex);
    }
}
Also used : RequestHeaderData(org.apache.kafka.common.message.RequestHeaderData) InvalidRequestException(org.apache.kafka.common.errors.InvalidRequestException) ByteBufferAccessor(org.apache.kafka.common.protocol.ByteBufferAccessor) UnsupportedVersionException(org.apache.kafka.common.errors.UnsupportedVersionException)

Example 10 with InvalidRequestException

use of org.apache.kafka.common.errors.InvalidRequestException in project kafka by apache.

the class AclControlManagerTest method testCreateAclDeleteAcl.

@Test
public void testCreateAclDeleteAcl() {
    SnapshotRegistry snapshotRegistry = new SnapshotRegistry(new LogContext());
    AclControlManager manager = new AclControlManager(snapshotRegistry, Optional.empty());
    MockClusterMetadataAuthorizer authorizer = new MockClusterMetadataAuthorizer();
    authorizer.loadSnapshot(manager.idToAcl());
    List<AclBinding> toCreate = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        toCreate.add(TEST_ACLS.get(i).toBinding());
    }
    toCreate.add(new AclBinding(new ResourcePattern(TOPIC, "*", PatternType.UNKNOWN), new AccessControlEntry("User:*", "*", ALTER, ALLOW)));
    ControllerResult<List<AclCreateResult>> createResult = manager.createAcls(toCreate);
    List<AclCreateResult> expectedResults = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        expectedResults.add(AclCreateResult.SUCCESS);
    }
    expectedResults.add(new AclCreateResult(new InvalidRequestException("Invalid patternType UNKNOWN")));
    for (int i = 0; i < expectedResults.size(); i++) {
        AclCreateResult expectedResult = expectedResults.get(i);
        if (expectedResult.exception().isPresent()) {
            assertEquals(expectedResult.exception().get().getMessage(), createResult.response().get(i).exception().get().getMessage());
        } else {
            assertFalse(createResult.response().get(i).exception().isPresent());
        }
    }
    RecordTestUtils.replayAll(manager, createResult.records());
    assertTrue(manager.iterator(Long.MAX_VALUE).hasNext());
    ControllerResult<List<AclDeleteResult>> deleteResult = manager.deleteAcls(Arrays.asList(new AclBindingFilter(new ResourcePatternFilter(ResourceType.ANY, null, LITERAL), AccessControlEntryFilter.ANY), new AclBindingFilter(new ResourcePatternFilter(ResourceType.UNKNOWN, null, LITERAL), AccessControlEntryFilter.ANY)));
    assertEquals(2, deleteResult.response().size());
    Set<AclBinding> deleted = new HashSet<>();
    for (AclDeleteResult.AclBindingDeleteResult result : deleteResult.response().get(0).aclBindingDeleteResults()) {
        assertEquals(Optional.empty(), result.exception());
        deleted.add(result.aclBinding());
    }
    assertEquals(new HashSet<>(Arrays.asList(TEST_ACLS.get(0).toBinding(), TEST_ACLS.get(2).toBinding())), deleted);
    assertEquals(InvalidRequestException.class, deleteResult.response().get(1).exception().get().getClass());
    RecordTestUtils.replayAll(manager, deleteResult.records());
    Iterator<List<ApiMessageAndVersion>> iterator = manager.iterator(Long.MAX_VALUE);
    assertTrue(iterator.hasNext());
    List<ApiMessageAndVersion> list = iterator.next();
    assertEquals(1, list.size());
    assertEquals(TEST_ACLS.get(1).toBinding(), StandardAcl.fromRecord((AccessControlEntryRecord) list.get(0).message()).toBinding());
    assertFalse(iterator.hasNext());
}
Also used : ResourcePatternFilter(org.apache.kafka.common.resource.ResourcePatternFilter) ResourcePattern(org.apache.kafka.common.resource.ResourcePattern) ArrayList(java.util.ArrayList) AclDeleteResult(org.apache.kafka.server.authorizer.AclDeleteResult) AclCreateResult(org.apache.kafka.server.authorizer.AclCreateResult) ApiMessageAndVersion(org.apache.kafka.server.common.ApiMessageAndVersion) List(java.util.List) ArrayList(java.util.ArrayList) InvalidRequestException(org.apache.kafka.common.errors.InvalidRequestException) AclBinding(org.apache.kafka.common.acl.AclBinding) HashSet(java.util.HashSet) AclBindingFilter(org.apache.kafka.common.acl.AclBindingFilter) LogContext(org.apache.kafka.common.utils.LogContext) AccessControlEntry(org.apache.kafka.common.acl.AccessControlEntry) Endpoint(org.apache.kafka.common.Endpoint) SnapshotRegistry(org.apache.kafka.timeline.SnapshotRegistry) StandardAclWithIdTest(org.apache.kafka.metadata.authorizer.StandardAclWithIdTest) StandardAclTest(org.apache.kafka.metadata.authorizer.StandardAclTest) Test(org.junit.jupiter.api.Test)

Aggregations

InvalidRequestException (org.apache.kafka.common.errors.InvalidRequestException)13 List (java.util.List)5 Test (org.junit.jupiter.api.Test)4 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 AclBinding (org.apache.kafka.common.acl.AclBinding)3 KafkaFutureImpl (org.apache.kafka.common.internals.KafkaFutureImpl)3 ChannelBuilder (org.apache.kafka.common.network.ChannelBuilder)3 ApiKeys (org.apache.kafka.common.protocol.ApiKeys)3 AbstractResponse (org.apache.kafka.common.requests.AbstractResponse)3 ByteBuffer (java.nio.ByteBuffer)2 HashSet (java.util.HashSet)2 Iterator (java.util.Iterator)2 LinkedList (java.util.LinkedList)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 IllegalSaslStateException (org.apache.kafka.common.errors.IllegalSaslStateException)2 UnknownServerException (org.apache.kafka.common.errors.UnknownServerException)2 UnsupportedSaslMechanismException (org.apache.kafka.common.errors.UnsupportedSaslMechanismException)2 UnsupportedVersionException (org.apache.kafka.common.errors.UnsupportedVersionException)2 ApiVersionsRequest (org.apache.kafka.common.requests.ApiVersionsRequest)2