Search in sources :

Example 1 with SaslHandshakeRequest

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

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 requestHeader = RequestHeader.parse(requestBuffer);
        ApiKeys apiKey = ApiKeys.forId(requestHeader.apiKey());
        // A valid Kafka request header was received. SASL authentication tokens are now expected only
        // following a SaslHandshakeRequest since this is not a GSSAPI client token from a Kafka 0.9.0.x client.
        setSaslState(SaslState.HANDSHAKE_REQUEST);
        isKafkaRequest = true;
        if (!Protocol.apiVersionSupported(requestHeader.apiKey(), requestHeader.apiVersion())) {
            if (apiKey == ApiKeys.API_VERSIONS)
                sendKafkaResponse(ApiVersionsResponse.unsupportedVersionSend(node, requestHeader));
            else
                throw new UnsupportedVersionException("Version " + requestHeader.apiVersion() + " is not supported for apiKey " + apiKey);
        } else {
            AbstractRequest request = AbstractRequest.getRequest(requestHeader.apiKey(), requestHeader.apiVersion(), requestBuffer).request;
            LOG.debug("Handle Kafka request {}", apiKey);
            switch(apiKey) {
                case API_VERSIONS:
                    handleApiVersionsRequest(requestHeader);
                    break;
                case SASL_HANDSHAKE:
                    clientMechanism = handleHandshakeRequest(requestHeader, (SaslHandshakeRequest) request);
                    break;
                default:
                    throw new IllegalSaslStateException("Unexpected Kafka request of type " + apiKey + " during SASL handshake.");
            }
        }
    } catch (SchemaException | IllegalArgumentException e) {
        if (saslState == SaslState.GSSAPI_OR_HANDSHAKE_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 : SchemaException(org.apache.kafka.common.protocol.types.SchemaException) AbstractRequest(org.apache.kafka.common.requests.AbstractRequest) UnsupportedSaslMechanismException(org.apache.kafka.common.errors.UnsupportedSaslMechanismException) IllegalSaslStateException(org.apache.kafka.common.errors.IllegalSaslStateException) ByteBuffer(java.nio.ByteBuffer) ApiKeys(org.apache.kafka.common.protocol.ApiKeys) RequestHeader(org.apache.kafka.common.requests.RequestHeader) SaslHandshakeRequest(org.apache.kafka.common.requests.SaslHandshakeRequest) UnsupportedVersionException(org.apache.kafka.common.errors.UnsupportedVersionException)

Example 2 with SaslHandshakeRequest

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

the class SaslAuthenticatorTest method sendHandshakeRequestReceiveResponse.

private SaslHandshakeResponse sendHandshakeRequestReceiveResponse(String node) throws Exception {
    SaslHandshakeRequest handshakeRequest = new SaslHandshakeRequest("PLAIN");
    SaslHandshakeResponse response = (SaslHandshakeResponse) sendKafkaRequestReceiveResponse(node, ApiKeys.SASL_HANDSHAKE, handshakeRequest);
    assertEquals(Errors.NONE, response.error());
    return response;
}
Also used : SaslHandshakeResponse(org.apache.kafka.common.requests.SaslHandshakeResponse) SaslHandshakeRequest(org.apache.kafka.common.requests.SaslHandshakeRequest)

Example 3 with SaslHandshakeRequest

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

the class SaslClientAuthenticator method authenticate.

/**
     * Sends an empty message to the server to initiate the authentication process. It then evaluates server challenges
     * via `SaslClient.evaluateChallenge` and returns client responses until authentication succeeds or fails.
     *
     * The messages are sent and received as size delimited bytes that consists of a 4 byte network-ordered size N
     * followed by N bytes representing the opaque payload.
     */
public void authenticate() throws IOException {
    if (netOutBuffer != null && !flushNetOutBufferAndUpdateInterestOps())
        return;
    switch(saslState) {
        case SEND_HANDSHAKE_REQUEST:
            // When multiple versions of SASL_HANDSHAKE_REQUEST are to be supported,
            // API_VERSIONS_REQUEST must be sent prior to sending SASL_HANDSHAKE_REQUEST to
            // fetch supported versions.
            String clientId = (String) configs.get(CommonClientConfigs.CLIENT_ID_CONFIG);
            SaslHandshakeRequest handshakeRequest = new SaslHandshakeRequest(mechanism);
            currentRequestHeader = new RequestHeader(ApiKeys.SASL_HANDSHAKE.id, handshakeRequest.version(), clientId, correlationId++);
            send(handshakeRequest.toSend(node, currentRequestHeader));
            setSaslState(SaslState.RECEIVE_HANDSHAKE_RESPONSE);
            break;
        case RECEIVE_HANDSHAKE_RESPONSE:
            byte[] responseBytes = receiveResponseOrToken();
            if (responseBytes == null)
                break;
            else {
                try {
                    handleKafkaResponse(currentRequestHeader, responseBytes);
                    currentRequestHeader = null;
                } catch (Exception e) {
                    setSaslState(SaslState.FAILED);
                    throw e;
                }
                setSaslState(SaslState.INITIAL);
            // Fall through and start SASL authentication using the configured client mechanism
            }
        case INITIAL:
            sendSaslToken(new byte[0], true);
            setSaslState(SaslState.INTERMEDIATE);
            break;
        case INTERMEDIATE:
            byte[] serverToken = receiveResponseOrToken();
            if (serverToken != null) {
                sendSaslToken(serverToken, false);
            }
            if (saslClient.isComplete()) {
                setSaslState(SaslState.COMPLETE);
                transportLayer.removeInterestOps(SelectionKey.OP_WRITE);
            }
            break;
        case COMPLETE:
            break;
        case FAILED:
            throw new IOException("SASL handshake failed");
    }
}
Also used : RequestHeader(org.apache.kafka.common.requests.RequestHeader) IOException(java.io.IOException) SaslHandshakeRequest(org.apache.kafka.common.requests.SaslHandshakeRequest) KafkaException(org.apache.kafka.common.KafkaException) SaslException(javax.security.sasl.SaslException) SchemaException(org.apache.kafka.common.protocol.types.SchemaException) IllegalSaslStateException(org.apache.kafka.common.errors.IllegalSaslStateException) PrivilegedActionException(java.security.PrivilegedActionException) IOException(java.io.IOException) UnsupportedSaslMechanismException(org.apache.kafka.common.errors.UnsupportedSaslMechanismException) AuthenticationException(org.apache.kafka.common.errors.AuthenticationException)

Example 4 with SaslHandshakeRequest

use of org.apache.kafka.common.requests.SaslHandshakeRequest 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)}
     * 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 ApiVersionsRequest and validate error response.
    String node1 = "invalid1";
    createClientConnection(SecurityProtocol.PLAINTEXT, node1);
    SaslHandshakeRequest request = new SaslHandshakeRequest("PLAIN");
    RequestHeader header = new RequestHeader(ApiKeys.SASL_HANDSHAKE.id, Short.MAX_VALUE, "someclient", 2);
    selector.send(request.toSend(node1, header));
    NetworkTestUtils.waitForChannelClose(selector, node1);
    selector.close();
    // Test good connection still works
    createAndCheckClientConnection(securityProtocol, "good1");
}
Also used : SecurityProtocol(org.apache.kafka.common.protocol.SecurityProtocol) RequestHeader(org.apache.kafka.common.requests.RequestHeader) SaslHandshakeRequest(org.apache.kafka.common.requests.SaslHandshakeRequest) Test(org.junit.Test)

Aggregations

SaslHandshakeRequest (org.apache.kafka.common.requests.SaslHandshakeRequest)4 RequestHeader (org.apache.kafka.common.requests.RequestHeader)3 IllegalSaslStateException (org.apache.kafka.common.errors.IllegalSaslStateException)2 UnsupportedSaslMechanismException (org.apache.kafka.common.errors.UnsupportedSaslMechanismException)2 SchemaException (org.apache.kafka.common.protocol.types.SchemaException)2 IOException (java.io.IOException)1 ByteBuffer (java.nio.ByteBuffer)1 PrivilegedActionException (java.security.PrivilegedActionException)1 SaslException (javax.security.sasl.SaslException)1 KafkaException (org.apache.kafka.common.KafkaException)1 AuthenticationException (org.apache.kafka.common.errors.AuthenticationException)1 UnsupportedVersionException (org.apache.kafka.common.errors.UnsupportedVersionException)1 ApiKeys (org.apache.kafka.common.protocol.ApiKeys)1 SecurityProtocol (org.apache.kafka.common.protocol.SecurityProtocol)1 AbstractRequest (org.apache.kafka.common.requests.AbstractRequest)1 SaslHandshakeResponse (org.apache.kafka.common.requests.SaslHandshakeResponse)1 Test (org.junit.Test)1