Skip to content

Commit

Permalink
merge: camunda#8786
Browse files Browse the repository at this point in the history
8786: Support to override authority in TLS handshake r=korthout a=korthout

## Description

<!-- Please explain the changes you made here. -->
Adds support to override the authority used in the TLS handshake. Specifically, to override the hostname used in the hostname verification.

It can be set using the `.overrideAuthority` on the `ZeebeClientBuilder` API, using the `ZEEBE_OVERRIDE_AUTHORITY` environment variable, or using the `zeebe.client.overrideauthority` configuration property.

## Related issues

<!-- Which issues are closed by this PR or are related -->

closes camunda#8707 



Co-authored-by: Nico Korthout <nico.korthout@camunda.com>
  • Loading branch information
zeebe-bors-cloud[bot] and korthout committed Feb 16, 2022
2 parents 849cacd + 53c7856 commit 67b0e3f
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,12 @@ public final class ClientProperties {
/** @see ZeebeClientBuilder#caCertificatePath(String) */
public static final String CA_CERTIFICATE_PATH = "zeebe.client.security.certpath";

/** @see io.camunda.zeebe.client.ZeebeClientBuilder#keepAlive(Duration) */
/** @see ZeebeClientBuilder#keepAlive(Duration) */
public static final String KEEP_ALIVE = "zeebe.client.keepalive";

/** @see ZeebeClientBuilder#overrideAuthority(String) */
public static final String OVERRIDE_AUTHORITY = "zeebe.client.overrideauthority";

/** @see ZeebeClientCloudBuilderStep1#withClusterId(java.lang.String) */
public static final String CLOUD_CLUSTER_ID = "zeebe.client.cloud.clusterId";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,22 @@ public interface ZeebeClientBuilder {

ZeebeClientBuilder withJsonMapper(JsonMapper jsonMapper);

/**
* Overrides the authority used with TLS virtual hosting. Specifically, to override hostname
* verification in the TLS handshake. It does not change what host is actually connected to.
*
* <p>This method is intended for testing, but may safely be used outside of tests as an
* alternative to DNS overrides.
*
* <p>This setting does nothing if a {@link #usePlaintext() plaintext} connection is used.
*
* @param authority The alternative authority to use, commonly in the form <code>host</code> or
* <code>host:port</code>
* @apiNote For the full definition of authority see [RFC 2396: Uniform Resource Identifiers
* (URI): Generic Syntax](http://www.ietf.org/rfc/rfc2396.txt)
*/
ZeebeClientBuilder overrideAuthority(String authority);

/** @return a new {@link ZeebeClient} with the provided configuration options. */
ZeebeClient build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,7 @@ public interface ZeebeClientConfiguration {

/** @see ZeebeClientBuilder#withJsonMapper(io.camunda.zeebe.client.api.JsonMapper) */
JsonMapper getJsonMapper();

/** @see ZeebeClientBuilder#overrideAuthority(String) */
String getOverrideAuthority();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static io.camunda.zeebe.client.ClientProperties.DEFAULT_MESSAGE_TIME_TO_LIVE;
import static io.camunda.zeebe.client.ClientProperties.DEFAULT_REQUEST_TIMEOUT;
import static io.camunda.zeebe.client.ClientProperties.KEEP_ALIVE;
import static io.camunda.zeebe.client.ClientProperties.OVERRIDE_AUTHORITY;
import static io.camunda.zeebe.client.ClientProperties.USE_PLAINTEXT_CONNECTION;
import static io.camunda.zeebe.client.impl.BuilderUtils.appendProperty;

Expand All @@ -41,6 +42,7 @@ public final class ZeebeClientBuilderImpl implements ZeebeClientBuilder, ZeebeCl
public static final String PLAINTEXT_CONNECTION_VAR = "ZEEBE_INSECURE_CONNECTION";
public static final String CA_CERTIFICATE_VAR = "ZEEBE_CA_CERTIFICATE_PATH";
public static final String KEEP_ALIVE_VAR = "ZEEBE_KEEP_ALIVE";
public static final String OVERRIDE_AUTHORITY_VAR = "ZEEBE_OVERRIDE_AUTHORITY";
public static final String DEFAULT_GATEWAY_ADDRESS = "0.0.0.0:26500";

private final List<ClientInterceptor> interceptors = new ArrayList<>();
Expand All @@ -57,6 +59,7 @@ public final class ZeebeClientBuilderImpl implements ZeebeClientBuilder, ZeebeCl
private CredentialsProvider credentialsProvider;
private Duration keepAlive = Duration.ofSeconds(45);
private JsonMapper jsonMapper = new ZeebeObjectMapper();
private String overrideAuthority;

@Override
public String getGatewayAddress() {
Expand Down Expand Up @@ -123,10 +126,16 @@ public List<ClientInterceptor> getInterceptors() {
return interceptors;
}

@Override
public JsonMapper getJsonMapper() {
return jsonMapper;
}

@Override
public String getOverrideAuthority() {
return overrideAuthority;
}

@Override
public ZeebeClientBuilder withProperties(final Properties properties) {

Expand Down Expand Up @@ -183,6 +192,9 @@ public ZeebeClientBuilder withProperties(final Properties properties) {
if (properties.containsKey(KEEP_ALIVE)) {
keepAlive(properties.getProperty(KEEP_ALIVE));
}
if (properties.containsKey(OVERRIDE_AUTHORITY)) {
overrideAuthority(properties.getProperty(OVERRIDE_AUTHORITY));
}
return this;
}

Expand Down Expand Up @@ -274,6 +286,12 @@ public ZeebeClientBuilder withJsonMapper(final JsonMapper jsonMapper) {
return this;
}

@Override
public ZeebeClientBuilder overrideAuthority(final String authority) {
overrideAuthority = authority;
return this;
}

@Override
public ZeebeClient build() {
applyOverrides();
Expand All @@ -298,6 +316,10 @@ private void applyOverrides() {
if (Environment.system().isDefined(KEEP_ALIVE_VAR)) {
keepAlive(Environment.system().get(KEEP_ALIVE_VAR));
}

if (Environment.system().isDefined(OVERRIDE_AUTHORITY_VAR)) {
overrideAuthority(Environment.system().get(OVERRIDE_AUTHORITY_VAR));
}
}

@Override
Expand All @@ -312,6 +334,7 @@ public String toString() {
appendProperty(sb, "defaultJobPollInterval", defaultJobPollInterval);
appendProperty(sb, "defaultMessageTimeToLive", defaultMessageTimeToLive);
appendProperty(sb, "defaultRequestTimeout", defaultRequestTimeout);
appendProperty(sb, "overrideAuthority", overrideAuthority);

return sb.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.camunda.zeebe.client.ClientProperties;
import io.camunda.zeebe.client.CredentialsProvider;
import io.camunda.zeebe.client.ZeebeClient;
import io.camunda.zeebe.client.ZeebeClientBuilder;
import io.camunda.zeebe.client.ZeebeClientCloudBuilderStep1;
import io.camunda.zeebe.client.ZeebeClientCloudBuilderStep1.ZeebeClientCloudBuilderStep2;
import io.camunda.zeebe.client.ZeebeClientCloudBuilderStep1.ZeebeClientCloudBuilderStep2.ZeebeClientCloudBuilderStep3;
Expand Down Expand Up @@ -74,25 +75,6 @@ public ZeebeClientCloudBuilderStep4 withRegion(final String region) {
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 gatewayAddress(final String gatewayAddress) {
innerBuilder.gatewayAddress(gatewayAddress);
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 usePlaintext() {
innerBuilder.usePlaintext();
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 credentialsProvider(
final CredentialsProvider credentialsProvider) {
innerBuilder.credentialsProvider(credentialsProvider);
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 withProperties(final Properties properties) {
if (properties.containsKey(ClientProperties.CLOUD_CLUSTER_ID)) {
Expand All @@ -108,6 +90,12 @@ public ZeebeClientCloudBuilderStep4 withProperties(final Properties properties)
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 gatewayAddress(final String gatewayAddress) {
innerBuilder.gatewayAddress(gatewayAddress);
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 defaultJobWorkerMaxJobsActive(final int maxJobsActive) {
innerBuilder.defaultJobWorkerMaxJobsActive(maxJobsActive);
Expand Down Expand Up @@ -150,12 +138,25 @@ public ZeebeClientCloudBuilderStep4 defaultRequestTimeout(final Duration request
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 usePlaintext() {
innerBuilder.usePlaintext();
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 caCertificatePath(final String certificatePath) {
innerBuilder.caCertificatePath(certificatePath);
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 credentialsProvider(
final CredentialsProvider credentialsProvider) {
innerBuilder.credentialsProvider(credentialsProvider);
return this;
}

@Override
public ZeebeClientCloudBuilderStep4 keepAlive(final Duration keepAlive) {
innerBuilder.keepAlive(keepAlive);
Expand All @@ -174,6 +175,12 @@ public ZeebeClientCloudBuilderStep4 withJsonMapper(final JsonMapper jsonMapper)
return this;
}

@Override
public ZeebeClientBuilder overrideAuthority(final String authority) {
innerBuilder.overrideAuthority(authority);
return this;
}

@Override
public ZeebeClient build() {
innerBuilder.gatewayAddress(determineGatewayAddress());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public ZeebeClientImpl(
final GatewayStub gatewayStub,
final ScheduledExecutorService executorService) {
this.config = config;
this.jsonMapper = config.getJsonMapper();
jsonMapper = config.getJsonMapper();
this.channel = channel;
asyncStub = gatewayStub;
this.executorService = executorService;
Expand Down Expand Up @@ -161,6 +161,9 @@ private static void configureConnectionSecurity(
}

channelBuilder.useTransportSecurity().sslContext(sslContext);
if (config.getOverrideAuthority() != null) {
channelBuilder.overrideAuthority(config.getOverrideAuthority());
}
} else {
channelBuilder.usePlaintext();
}
Expand Down Expand Up @@ -289,7 +292,7 @@ public UpdateRetriesJobCommandStep1 newUpdateRetriesCommand(final long jobKey) {
}

@Override
public UpdateRetriesJobCommandStep1 newUpdateRetriesCommand(ActivatedJob job) {
public UpdateRetriesJobCommandStep1 newUpdateRetriesCommand(final ActivatedJob job) {
return newUpdateRetriesCommand(job.getKey());
}

Expand Down Expand Up @@ -322,7 +325,7 @@ public CompleteJobCommandStep1 newCompleteCommand(final long jobKey) {
}

@Override
public CompleteJobCommandStep1 newCompleteCommand(ActivatedJob job) {
public CompleteJobCommandStep1 newCompleteCommand(final ActivatedJob job) {
return newCompleteCommand(job.getKey());
}

Expand All @@ -332,17 +335,17 @@ public FailJobCommandStep1 newFailCommand(final long jobKey) {
}

@Override
public FailJobCommandStep1 newFailCommand(ActivatedJob job) {
public FailJobCommandStep1 newFailCommand(final ActivatedJob job) {
return newFailCommand(job.getKey());
}

@Override
public ThrowErrorCommandStep1 newThrowErrorCommand(long jobKey) {
public ThrowErrorCommandStep1 newThrowErrorCommand(final long jobKey) {
return jobClient.newThrowErrorCommand(jobKey);
}

@Override
public ThrowErrorCommandStep1 newThrowErrorCommand(ActivatedJob job) {
public ThrowErrorCommandStep1 newThrowErrorCommand(final ActivatedJob job) {
return newThrowErrorCommand(job.getKey());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static io.camunda.zeebe.client.ClientProperties.USE_PLAINTEXT_CONNECTION;
import static io.camunda.zeebe.client.impl.ZeebeClientBuilderImpl.CA_CERTIFICATE_VAR;
import static io.camunda.zeebe.client.impl.ZeebeClientBuilderImpl.KEEP_ALIVE_VAR;
import static io.camunda.zeebe.client.impl.ZeebeClientBuilderImpl.OVERRIDE_AUTHORITY_VAR;
import static io.camunda.zeebe.client.impl.ZeebeClientBuilderImpl.PLAINTEXT_CONNECTION_VAR;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
Expand Down Expand Up @@ -61,6 +62,7 @@ public void shouldHaveDefaultValues() {
assertThat(configuration.getDefaultJobPollInterval()).isEqualTo(Duration.ofMillis(100));
assertThat(configuration.getDefaultMessageTimeToLive()).isEqualTo(Duration.ofHours(1));
assertThat(configuration.getDefaultRequestTimeout()).isEqualTo(Duration.ofSeconds(10));
assertThat(configuration.getOverrideAuthority()).isNull();
}
}

Expand Down Expand Up @@ -152,6 +154,33 @@ public void shouldOverrideKeepAliveWithEnvVar() {
assertThat(builder.getKeepAlive()).isEqualTo(Duration.ofSeconds(15));
}

@Test
public void shouldSetAuthority() {
// given
final ZeebeClientBuilderImpl builder = new ZeebeClientBuilderImpl();
builder.overrideAuthority("virtualhost");

// when
builder.build();

// then
assertThat(builder.getOverrideAuthority()).isEqualTo("virtualhost");
}

@Test
public void shouldOverrideAuthorityWithEnvVar() {
// given
final ZeebeClientBuilderImpl builder = new ZeebeClientBuilderImpl();
builder.overrideAuthority("localhost");
Environment.system().put(OVERRIDE_AUTHORITY_VAR, "virtualhost");

// when
builder.build();

// then
assertThat(builder.getOverrideAuthority()).isEqualTo("virtualhost");
}

@Test
public void shouldRejectUnsupportedTimeUnitWithEnvVar() {
// when/then
Expand Down
Loading

0 comments on commit 67b0e3f

Please sign in to comment.