Skip to content

Commit

Permalink
Upgrade Jetty from 9.4.x to 11.0.2 to fix CVE-2020-27218
Browse files Browse the repository at this point in the history
1. Change Java EE dependencies for Jetty 11

  - javax.activation:activation:1.1.1 → com.sun.activation:javax.activation:1.2.0
  - javax.ws.rs:javax.ws.rs-api 2.1.1 → jakarta.ws.rs:jakarta.ws.rs-api 3.0.0.
  - javax.xml.bind:jaxb-api:2.3.0 → jakarta.xml.bind:jakarta.xml.bind-api:2.3.0
  - Change all javax.ws.rs.* imports into jakarta.ws.rs.*.

2. Upgrade jackson from 2.10.5 to 2.12.1 + Add jakarta classifier to jackson-jaxrs-json-provider for compatibility with jakarta.ws.rs-api

  - Update jackson-databind dependency: now it uses the same version with the other jackson dependencies.
  - Add '@JsonIgnoreProperties(ignoreUnknown = true)' annotation to ErrorResponse: Prevent 'com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "servlet"'.
  - Remove ScalaObjectMapper from ConsumerGroupCommand: deprecated from jackson-module-scala 2.12.1.
  - Mark Empty with @JsonSerialize, @JsonDeserialize: now serializable with Jetty 11.

3. Upgrade jersey from 2.31 to 3.0.1

4. Add additional dependencies for Jetty 11

  - javax.ws.rs:jsr311-api:1.1.1
  - jakarta.servlet:jakarta.servlet-api:5.0.0
  - org.glassfish.jersey.media:jersey-media-json-jackson:3.0.1: Required to register jackson as a MessageBodyWriter.

5. Upgrade Jetty from 9.4.x to 11.0.2

  - Exclude org.slf4j:slf4j-api:2.0.0-alpha1 dependency.
  - Fix deprecated method calls in RestClient#httpRequest, InternalRequestSignature#addToRequest
  - Update InternalRequestSignatureTest#addToRequestShouldThrowExceptionOnInvalidSignatureAlgorithm

    Since Request is an Interface from Jetty 11, mocking without when..then.. clause does not work. So it is now replaced to real instance.

  - Update SSLUtils

    From Jetty 11, SslContextFactory is separated into SslContextFactory.Server and SslContextFactory.Client subtypes; So, the return types of SSLUtils#[createServerSideSslContextFactory, createClientSideSslContextFactory] are now changed. Since SslContextFactory.Client does not have getNeedClientAuth, getWantClientAuth methods so SSLUtilsTest is also updated accordingly.

  - Increase JsonRestServer#GRACEFUL_SHUTDOWN_TIMEOUT_MS from 100 to 3000

    Jetty 11 requires more time to tear down their resources than Jetty 9.4.x; without this modification, TimeoutException is thrown during shutdown in AgentTest, CoordinatorTest.
  • Loading branch information
dongjinleekr committed Apr 20, 2021
1 parent fbdd8e7 commit 3710267
Show file tree
Hide file tree
Showing 44 changed files with 328 additions and 267 deletions.
38 changes: 29 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -1525,11 +1525,20 @@ project(':trogdor') {
implementation libs.jacksonJaxrsJsonProvider
implementation libs.jerseyContainerServlet
implementation libs.jerseyHk2
implementation libs.jerseyMediaJsonJackson
implementation libs.jaxbApi // Jersey dependency that was available in the JDK before Java 9
implementation libs.activation // Jersey dependency that was available in the JDK before Java 9
implementation libs.jettyServer
implementation libs.jettyServlet
implementation libs.jettyServlets
implementation (libs.jettyServer) {
exclude group: 'org.slf4j', module: 'slf4j-api'
}
implementation (libs.jettyServlet) {
exclude group: 'org.slf4j', module: 'slf4j-api'
}
implementation (libs.jettyServlets) {
exclude group: 'org.slf4j', module: 'slf4j-api'
}
implementation libs.jakartaServletApi
implementation libs.jsr311Api

testImplementation project(':clients')
testImplementation libs.junitJupiter
Expand Down Expand Up @@ -2120,7 +2129,7 @@ project(':connect:api') {
dependencies {
api project(':clients')
implementation libs.slf4jApi
implementation libs.jaxrsApi
implementation libs.jakartaRsApi

testImplementation libs.junitJupiter
testRuntimeOnly libs.slf4jlog4j
Expand Down Expand Up @@ -2245,12 +2254,23 @@ project(':connect:runtime') {
implementation libs.jacksonJaxrsJsonProvider
implementation libs.jerseyContainerServlet
implementation libs.jerseyHk2
implementation libs.jerseyMediaJsonJackson
implementation libs.jaxbApi // Jersey dependency that was available in the JDK before Java 9
implementation libs.activation // Jersey dependency that was available in the JDK before Java 9
implementation libs.jettyServer
implementation libs.jettyServlet
implementation libs.jettyServlets
implementation libs.jettyClient
implementation (libs.jettyServer) {
exclude group: 'org.slf4j', module: 'slf4j-api'
}
implementation (libs.jettyServlet) {
exclude group: 'org.slf4j', module: 'slf4j-api'
}
implementation (libs.jettyServlets) {
exclude group: 'org.slf4j', module: 'slf4j-api'
}
implementation (libs.jettyClient) {
exclude group: 'org.slf4j', module: 'slf4j-api'
}
implementation libs.jakartaServletApi
implementation libs.jsr311Api
implementation libs.reflections
implementation libs.mavenArtifact

Expand Down Expand Up @@ -2377,7 +2397,7 @@ project(':connect:basic-auth-extension') {
dependencies {
implementation project(':connect:api')
implementation libs.slf4jApi
implementation libs.jaxrsApi
implementation libs.jakartaRsApi

testImplementation libs.bcpkix
testImplementation libs.easymock
Expand Down
16 changes: 8 additions & 8 deletions checkstyle/import-control.xml
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@

<subpackage name="trogdor">
<allow pkg="com.fasterxml.jackson" />
<allow pkg="javax.servlet" />
<allow pkg="javax.ws.rs" />
<allow pkg="jakarta.servlet" />
<allow pkg="jakarta.ws.rs" />
<allow pkg="net.sourceforge.argparse4j" />
<allow pkg="org.apache.kafka.clients" />
<allow pkg="org.apache.kafka.clients.admin" />
Expand Down Expand Up @@ -451,7 +451,7 @@

<subpackage name="rest">
<allow pkg="org.apache.kafka.connect.health" />
<allow pkg="javax.ws.rs" />
<allow pkg="jakarta.ws.rs" />
<allow pkg= "javax.security.auth"/>
<subpackage name="basic">
<allow pkg="org.apache.kafka.connect.rest"/>
Expand Down Expand Up @@ -484,8 +484,8 @@

<subpackage name="rest">
<allow pkg="org.eclipse.jetty" />
<allow pkg="javax.ws.rs" />
<allow pkg="javax.servlet" />
<allow pkg="jakarta.ws.rs" />
<allow pkg="jakarta.servlet" />
<allow pkg="org.glassfish.jersey" />
<allow pkg="com.fasterxml.jackson" />
<allow pkg="org.apache.http"/>
Expand All @@ -501,7 +501,7 @@
</subpackage>

<subpackage name="distributed">
<allow pkg="javax.ws.rs.core" />
<allow pkg="jakarta.ws.rs.core" />
</subpackage>
</subpackage>

Expand Down Expand Up @@ -530,7 +530,7 @@
<allow pkg="kafka.zk" />
<allow pkg="kafka.utils" />
<allow class="javax.servlet.http.HttpServletResponse" />
<allow class="javax.ws.rs.core.Response" />
<allow class="jakarta.ws.rs.core.Response" />
<allow pkg="com.fasterxml.jackson.core.type" />
<allow pkg="org.apache.kafka.metadata" />
</subpackage>
Expand All @@ -540,7 +540,7 @@
<allow pkg="org.apache.kafka.connect.util.clusters" />
<allow pkg="org.apache.kafka.connect" />
<allow pkg="org.apache.kafka.tools" />
<allow pkg="javax.ws.rs" />
<allow pkg="jakarta.ws.rs" />
</subpackage>

<subpackage name="json">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public interface ConnectRestExtension extends Configurable, Versioned, Closeable
* method. The Connect framework will invoke this method after registering the default Connect resources. If the implementations attempt
* to re-register any of the Connect resources, it will be be ignored and will be logged.
*
* @param restPluginContext The context provides access to JAX-RS {@link javax.ws.rs.core.Configurable} and {@link
* @param restPluginContext The context provides access to JAX-RS {@link jakarta.ws.rs.core.Configurable} and {@link
* ConnectClusterState}.The custom JAX-RS resources can be registered via the {@link
* ConnectRestExtensionContext#configurable()}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@

import org.apache.kafka.connect.health.ConnectClusterState;

import javax.ws.rs.core.Configurable;
import jakarta.ws.rs.core.Configurable;

/**
* The interface provides the ability for {@link ConnectRestExtension} implementations to access the JAX-RS
* {@link javax.ws.rs.core.Configurable} and cluster state {@link ConnectClusterState}. The implementation for the interface is provided
* {@link jakarta.ws.rs.core.Configurable} and cluster state {@link ConnectClusterState}. The implementation for the interface is provided
* by the Connect framework.
*/
public interface ConnectRestExtensionContext {

/**
* Provides an implementation of {@link javax.ws.rs.core.Configurable} that be used to register JAX-RS resources.
* Provides an implementation of {@link jakarta.ws.rs.core.Configurable} that be used to register JAX-RS resources.
*
* @return @return the JAX-RS {@link javax.ws.rs.core.Configurable}; never {@code null}
* @return @return the JAX-RS {@link jakarta.ws.rs.core.Configurable}; never {@code null}
*/
Configurable<? extends Configurable> configurable();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@
import org.apache.kafka.connect.errors.ConnectException;
import org.apache.kafka.connect.rest.ConnectRestExtension;
import org.apache.kafka.connect.rest.ConnectRestExtensionContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.security.auth.login.Configuration;
import java.io.IOException;
import java.util.Map;
import java.util.function.Supplier;
import javax.security.auth.login.Configuration;

/**
* Provides the ability to authenticate incoming BasicAuth credentials using the configured JAAS {@link
Expand All @@ -50,7 +51,7 @@
*</Pre>
*
* <p>This is a reference implementation of the {@link ConnectRestExtension} interface. It registers an implementation of {@link
* javax.ws.rs.container.ContainerRequestFilter} that does JAAS based authentication of incoming Basic Auth credentials. {@link
* jakarta.ws.rs.container.ContainerRequestFilter} that does JAAS based authentication of incoming Basic Auth credentials. {@link
* ConnectRestExtension} implementations are loaded via the plugin class loader using {@link java.util.ServiceLoader} mechanism and hence
* the packaged jar includes {@code META-INF/services/org.apache.kafka.connect.rest.extension.ConnectRestExtension} with the entry
* {@code org.apache.kafka.connect.extension.auth.jaas.BasicAuthSecurityRestExtension}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,31 @@

package org.apache.kafka.connect.rest.basic.auth.extension;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.security.auth.login.Configuration;
import javax.ws.rs.HttpMethod;
import org.apache.kafka.common.config.ConfigException;
import org.apache.kafka.connect.errors.ConnectException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;

import java.util.List;
import java.util.regex.Pattern;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;

import jakarta.ws.rs.HttpMethod;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.core.Response;

public class JaasBasicAuthFilter implements ContainerRequestFilter {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,26 @@

import org.apache.kafka.connect.errors.ConnectException;
import org.apache.kafka.connect.rest.ConnectRestExtensionContext;

import org.easymock.Capture;
import org.easymock.EasyMock;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javax.security.auth.login.Configuration;
import javax.ws.rs.core.Configurable;

import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import javax.security.auth.login.Configuration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import jakarta.ws.rs.core.Configurable;

public class BasicAuthSecurityRestExtensionTest {

Configuration priorConfiguration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,9 @@

package org.apache.kafka.connect.rest.basic.auth.extension;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.ChoiceCallback;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.UriInfo;

import org.apache.kafka.common.security.authenticator.TestJaasConfig;
import org.apache.kafka.connect.errors.ConnectException;

import org.easymock.EasyMock;
import org.junit.jupiter.api.Test;

Expand All @@ -37,13 +32,18 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.Response;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.ChoiceCallback;

import static org.easymock.EasyMock.replay;
import static org.junit.jupiter.api.Assertions.assertThrows;

import jakarta.ws.rs.HttpMethod;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;

public class JaasBasicAuthFilterTest {

private static final String LOGIN_MODULE =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,9 @@
import org.apache.kafka.connect.util.Callback;
import org.apache.kafka.connect.util.ConnectorTaskId;
import org.apache.kafka.connect.util.SinkUtils;

import org.slf4j.Logger;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand All @@ -90,13 +88,17 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

import static org.apache.kafka.connect.runtime.WorkerConfig.TOPIC_TRACKING_ENABLE_CONFIG;
import static org.apache.kafka.connect.runtime.distributed.ConnectProtocol.CONNECT_PROTOCOL_V0;
import static org.apache.kafka.connect.runtime.distributed.ConnectProtocolCompatibility.EAGER;
import static org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V1;
import static org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V2;

import jakarta.ws.rs.core.Response;

/**
* <p>
* Distributed "herder" that coordinates with other workers to spread work across multiple processes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import java.util.Map;
import java.util.Objects;

import javax.ws.rs.core.Configurable;
import javax.ws.rs.core.Configuration;
import jakarta.ws.rs.core.Configurable;
import jakarta.ws.rs.core.Configuration;

/**
* The implementation delegates to {@link ResourceConfig} so that we can handle duplicate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.apache.kafka.connect.health.ConnectClusterState;
import org.apache.kafka.connect.rest.ConnectRestExtensionContext;

import javax.ws.rs.core.Configurable;
import jakarta.ws.rs.core.Configurable;

public class ConnectRestExtensionContextImpl implements ConnectRestExtensionContext {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@

import org.apache.kafka.connect.errors.ConnectException;
import org.apache.kafka.connect.runtime.rest.errors.BadRequestException;

import org.eclipse.jetty.client.api.Request;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.ws.rs.core.HttpHeaders;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import java.util.Objects;
import javax.crypto.Mac;
import javax.crypto.SecretKey;

import jakarta.ws.rs.core.HttpHeaders;
import org.eclipse.jetty.http.HttpFields;

public class InternalRequestSignature {

Expand All @@ -53,8 +56,10 @@ public static void addToRequest(SecretKey key, byte[] requestBody, String signat
throw new ConnectException(e);
}
byte[] requestSignature = sign(mac, key, requestBody);
request.header(InternalRequestSignature.SIGNATURE_HEADER, Base64.getEncoder().encodeToString(requestSignature))
.header(InternalRequestSignature.SIGNATURE_ALGORITHM_HEADER, signatureAlgorithm);
request.headers((HttpFields.Mutable field) -> {
field.add(InternalRequestSignature.SIGNATURE_HEADER, Base64.getEncoder().encodeToString(requestSignature));
field.add(InternalRequestSignature.SIGNATURE_ALGORITHM_HEADER, signatureAlgorithm);
});
}

/**
Expand Down
Loading

0 comments on commit 3710267

Please sign in to comment.