Search in sources :

Example 16 with ApiVersionsResponse

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

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

the class NetworkClientTest method setExpectedApiVersionsResponse.

private void setExpectedApiVersionsResponse() {
    ApiVersionsResponse response = ApiVersionsResponse.defaultApiVersionsResponse();
    short apiVersionsResponseVersion = response.apiVersion(ApiKeys.API_VERSIONS.id).maxVersion;
    ByteBuffer buffer = response.serialize(apiVersionsResponseVersion, new ResponseHeader(0));
    selector.delayedReceive(new DelayedReceive(node.idString(), new NetworkReceive(node.idString(), buffer)));
}
Also used : ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) ResponseHeader(org.apache.kafka.common.requests.ResponseHeader) NetworkReceive(org.apache.kafka.common.network.NetworkReceive) DelayedReceive(org.apache.kafka.test.DelayedReceive) ByteBuffer(java.nio.ByteBuffer)

Example 18 with ApiVersionsResponse

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

the class SaslAuthenticatorTest method sendVersionRequestReceiveResponse.

private ApiVersionsResponse sendVersionRequestReceiveResponse(String node) throws Exception {
    ApiVersionsRequest handshakeRequest = createApiVersionsRequestV0();
    ApiVersionsResponse response = (ApiVersionsResponse) sendKafkaRequestReceiveResponse(node, ApiKeys.API_VERSIONS, handshakeRequest);
    assertEquals(Errors.NONE, response.error());
    return response;
}
Also used : ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) ApiVersionsRequest(org.apache.kafka.common.requests.ApiVersionsRequest)

Example 19 with ApiVersionsResponse

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

the class SaslAuthenticatorTest method startServerWithoutSaslAuthenticateHeader.

private NioEchoServer startServerWithoutSaslAuthenticateHeader(final SecurityProtocol securityProtocol, String saslMechanism) throws Exception {
    final ListenerName listenerName = ListenerName.forSecurityProtocol(securityProtocol);
    final Map<String, ?> configs = Collections.emptyMap();
    final JaasContext jaasContext = JaasContext.loadServerContext(listenerName, saslMechanism, configs);
    final Map<String, JaasContext> jaasContexts = Collections.singletonMap(saslMechanism, jaasContext);
    boolean isScram = ScramMechanism.isScram(saslMechanism);
    if (isScram)
        ScramCredentialUtils.createCache(credentialCache, Arrays.asList(saslMechanism));
    SaslChannelBuilder serverChannelBuilder = new SaslChannelBuilder(Mode.SERVER, jaasContexts, securityProtocol, listenerName, false, saslMechanism, true, credentialCache, null) {

        @Override
        protected SaslServerAuthenticator buildServerAuthenticator(Map<String, ?> configs, String id, TransportLayer transportLayer, Map<String, Subject> subjects) throws IOException {
            return new SaslServerAuthenticator(configs, id, jaasContexts, subjects, null, credentialCache, listenerName, securityProtocol, transportLayer, null) {

                @Override
                protected ApiVersionsResponse apiVersionsResponse() {
                    List<ApiVersion> apiVersions = new ArrayList<>(ApiVersionsResponse.defaultApiVersionsResponse().apiVersions());
                    for (Iterator<ApiVersion> it = apiVersions.iterator(); it.hasNext(); ) {
                        ApiVersion apiVersion = it.next();
                        if (apiVersion.apiKey == ApiKeys.SASL_AUTHENTICATE.id) {
                            it.remove();
                            break;
                        }
                    }
                    return new ApiVersionsResponse(0, Errors.NONE, apiVersions);
                }

                @Override
                protected void enableKafkaSaslAuthenticateHeaders(boolean flag) {
                // Don't enable Kafka SASL_AUTHENTICATE headers
                }
            };
        }
    };
    serverChannelBuilder.configure(saslServerConfigs);
    server = new NioEchoServer(listenerName, securityProtocol, new TestSecurityConfig(saslServerConfigs), "localhost", serverChannelBuilder, credentialCache);
    server.start();
    return server;
}
Also used : ApiVersion(org.apache.kafka.common.requests.ApiVersionsResponse.ApiVersion) ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) ArrayList(java.util.ArrayList) ListenerName(org.apache.kafka.common.network.ListenerName) TransportLayer(org.apache.kafka.common.network.TransportLayer) JaasContext(org.apache.kafka.common.security.JaasContext) NioEchoServer(org.apache.kafka.common.network.NioEchoServer) TestSecurityConfig(org.apache.kafka.common.security.TestSecurityConfig) SaslChannelBuilder(org.apache.kafka.common.network.SaslChannelBuilder) Map(java.util.Map) HashMap(java.util.HashMap)

Example 20 with ApiVersionsResponse

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

the class SaslAuthenticatorTest method testUnauthenticatedApiVersionsRequest.

/**
 * Tests that Kafka ApiVersionsRequests are handled by the SASL server authenticator
 * prior to SASL handshake flow and that subsequent authentication succeeds
 * when transport layer is PLAINTEXT/SSL. This test uses a non-SASL client that simulates
 * SASL authentication after ApiVersionsRequest.
 * <p>
 * Test sequence (using <tt>securityProtocol=PLAINTEXT</tt> as an example):
 * <ol>
 *   <li>Starts a SASL_PLAINTEXT test server that simply echoes back client requests after authentication.</li>
 *   <li>A (non-SASL) PLAINTEXT test client connects to the SASL server port. Client is now unauthenticated.<./li>
 *   <li>The unauthenticated non-SASL client sends an ApiVersionsRequest and validates the response.
 *       A valid response indicates that {@link SaslServerAuthenticator} of the test server responded to
 *       the ApiVersionsRequest even though the client is not yet authenticated.</li>
 *   <li>The unauthenticated non-SASL client sends a SaslHandshakeRequest and validates the response. A valid response
 *       indicates that {@link SaslServerAuthenticator} of the test server responded to the SaslHandshakeRequest
 *       after processing ApiVersionsRequest.</li>
 *   <li>The unauthenticated non-SASL client sends the SASL/PLAIN packet containing username/password to authenticate
 *       itself. The client is now authenticated by the server. At this point this test client is at the
 *       same state as a regular SASL_PLAINTEXT client that is <tt>ready</tt>.</li>
 *   <li>The authenticated client sends random data to the server and checks that the data is echoed
 *       back by the test server (ie, not Kafka request-response) to ensure that the client now
 *       behaves exactly as a regular SASL_PLAINTEXT client that has completed authentication.</li>
 * </ol>
 */
private void testUnauthenticatedApiVersionsRequest(SecurityProtocol securityProtocol, short saslHandshakeVersion) throws Exception {
    configureMechanisms("PLAIN", Arrays.asList("PLAIN"));
    server = createEchoServer(securityProtocol);
    // Create non-SASL connection to manually authenticate after ApiVersionsRequest
    String node = "1";
    SecurityProtocol clientProtocol;
    switch(securityProtocol) {
        case SASL_PLAINTEXT:
            clientProtocol = SecurityProtocol.PLAINTEXT;
            break;
        case SASL_SSL:
            clientProtocol = SecurityProtocol.SSL;
            break;
        default:
            throw new IllegalArgumentException("Server protocol " + securityProtocol + " is not SASL");
    }
    createClientConnection(clientProtocol, node);
    NetworkTestUtils.waitForChannelReady(selector, node);
    // Send ApiVersionsRequest and check response
    ApiVersionsResponse versionsResponse = sendVersionRequestReceiveResponse(node);
    assertEquals(ApiKeys.SASL_HANDSHAKE.oldestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_HANDSHAKE.id).minVersion);
    assertEquals(ApiKeys.SASL_HANDSHAKE.latestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_HANDSHAKE.id).maxVersion);
    assertEquals(ApiKeys.SASL_AUTHENTICATE.oldestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_AUTHENTICATE.id).minVersion);
    assertEquals(ApiKeys.SASL_AUTHENTICATE.latestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_AUTHENTICATE.id).maxVersion);
    // Send SaslHandshakeRequest and check response
    SaslHandshakeResponse handshakeResponse = sendHandshakeRequestReceiveResponse(node, saslHandshakeVersion);
    assertEquals(Collections.singletonList("PLAIN"), handshakeResponse.enabledMechanisms());
    // Complete manual authentication and check send/receive succeed
    authenticateUsingSaslPlainAndCheckConnection(node, saslHandshakeVersion > 0);
}
Also used : ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) SaslHandshakeResponse(org.apache.kafka.common.requests.SaslHandshakeResponse) SecurityProtocol(org.apache.kafka.common.security.auth.SecurityProtocol)

Aggregations

ApiVersionsResponse (org.apache.kafka.common.requests.ApiVersionsResponse)30 ApiVersionsRequest (org.apache.kafka.common.requests.ApiVersionsRequest)11 ByteBuffer (java.nio.ByteBuffer)10 Test (org.junit.jupiter.api.Test)8 RequestHeader (org.apache.kafka.common.requests.RequestHeader)7 ApiVersion (org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion)6 NetworkReceive (org.apache.kafka.common.network.NetworkReceive)6 SecurityProtocol (org.apache.kafka.common.security.auth.SecurityProtocol)6 ApiVersionsResponseData (org.apache.kafka.common.message.ApiVersionsResponseData)5 ListenerName (org.apache.kafka.common.network.ListenerName)5 SaslHandshakeResponse (org.apache.kafka.common.requests.SaslHandshakeResponse)5 HashMap (java.util.HashMap)4 SaslChannelBuilder (org.apache.kafka.common.network.SaslChannelBuilder)4 JaasContext (org.apache.kafka.common.security.JaasContext)4 Map (java.util.Map)3 ClientRequest (org.apache.kafka.clients.ClientRequest)3 ApiVersionCollection (org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersionCollection)3 NetworkSend (org.apache.kafka.common.network.NetworkSend)3 NioEchoServer (org.apache.kafka.common.network.NioEchoServer)3 TransportLayer (org.apache.kafka.common.network.TransportLayer)3