diff --git a/core/runtime/src/main/java/io/quarkus/runtime/TlsConfig.java b/core/runtime/src/main/java/io/quarkus/runtime/TlsConfig.java new file mode 100644 index 00000000000000..9b4409fb540e94 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/runtime/TlsConfig.java @@ -0,0 +1,19 @@ +package io.quarkus.runtime; + +import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.runtime.annotations.ConfigPhase; +import io.quarkus.runtime.annotations.ConfigRoot; + +/** + * Configuration class allowing to globally set TLS properties. + */ +@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) +public class TlsConfig { + + /** + * Enable trusting all certificates. Disable by default. + */ + @ConfigItem(defaultValue = "false") + public boolean trustAll; + +} \ No newline at end of file diff --git a/extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/KubernetesClientBuildStep.java b/extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/KubernetesClientBuildStep.java index 202cbab8a04809..a65b82da207aec 100644 --- a/extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/KubernetesClientBuildStep.java +++ b/extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/KubernetesClientBuildStep.java @@ -5,13 +5,14 @@ import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.kubernetes.client.runtime.KubernetesClientBuildConfig; import io.quarkus.kubernetes.client.spi.KubernetesClientBuildItem; +import io.quarkus.runtime.TlsConfig; public class KubernetesClientBuildStep { private KubernetesClientBuildConfig buildConfig; @BuildStep - public KubernetesClientBuildItem process() { - return new KubernetesClientBuildItem(createClient(buildConfig)); + public KubernetesClientBuildItem process(TlsConfig tlsConfig) { + return new KubernetesClientBuildItem(createClient(buildConfig, tlsConfig)); } } diff --git a/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientProducer.java b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientProducer.java index 0e3eb8fed69816..d4129a4c561cc3 100644 --- a/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientProducer.java +++ b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientProducer.java @@ -8,6 +8,7 @@ import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; import io.quarkus.arc.DefaultBean; +import io.quarkus.runtime.TlsConfig; @Singleton public class KubernetesClientProducer { @@ -17,8 +18,8 @@ public class KubernetesClientProducer { @DefaultBean @Singleton @Produces - public Config config(KubernetesClientBuildConfig buildConfig) { - return KubernetesClientUtils.createConfig(buildConfig); + public Config config(KubernetesClientBuildConfig buildConfig, TlsConfig tlsConfig) { + return KubernetesClientUtils.createConfig(buildConfig, tlsConfig); } @DefaultBean diff --git a/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientUtils.java b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientUtils.java index 1429c17453a440..47a77458f8d703 100644 --- a/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientUtils.java +++ b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientUtils.java @@ -8,15 +8,16 @@ import io.fabric8.kubernetes.client.ConfigBuilder; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; +import io.quarkus.runtime.TlsConfig; public class KubernetesClientUtils { private static final String PREFIX = "quarkus.kubernetes-client."; - public static Config createConfig(KubernetesClientBuildConfig buildConfig) { + public static Config createConfig(KubernetesClientBuildConfig buildConfig, TlsConfig tlsConfig) { Config base = Config.autoConfigure(null); return new ConfigBuilder() - .withTrustCerts(buildConfig.trustCerts) + .withTrustCerts(buildConfig.trustCerts || tlsConfig.trustAll) .withWatchReconnectInterval((int) buildConfig.watchReconnectInterval.toMillis()) .withWatchReconnectLimit(buildConfig.watchReconnectLimit) .withConnectionTimeout((int) buildConfig.connectionTimeout.toMillis()) @@ -43,8 +44,8 @@ public static Config createConfig(KubernetesClientBuildConfig buildConfig) { .build(); } - public static KubernetesClient createClient(KubernetesClientBuildConfig buildConfig) { - return new DefaultKubernetesClient(createConfig(buildConfig)); + public static KubernetesClient createClient(KubernetesClientBuildConfig buildConfig, TlsConfig tlsConfig) { + return new DefaultKubernetesClient(createConfig(buildConfig, tlsConfig)); } public static KubernetesClient createClient() { diff --git a/extensions/kubernetes-config/deployment/src/main/java/io/quarkus/kubernetes/config/deployment/KubernetesConfigProcessor.java b/extensions/kubernetes-config/deployment/src/main/java/io/quarkus/kubernetes/config/deployment/KubernetesConfigProcessor.java index c08aae468ce951..b2703311dab709 100644 --- a/extensions/kubernetes-config/deployment/src/main/java/io/quarkus/kubernetes/config/deployment/KubernetesConfigProcessor.java +++ b/extensions/kubernetes-config/deployment/src/main/java/io/quarkus/kubernetes/config/deployment/KubernetesConfigProcessor.java @@ -17,6 +17,7 @@ import io.quarkus.kubernetes.client.runtime.KubernetesConfigSourceConfig; import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem; +import io.quarkus.runtime.TlsConfig; public class KubernetesConfigProcessor { @@ -24,9 +25,10 @@ public class KubernetesConfigProcessor { @Record(ExecutionTime.RUNTIME_INIT) public RunTimeConfigurationSourceValueBuildItem configure(KubernetesConfigRecorder recorder, KubernetesConfigSourceConfig config, KubernetesConfigBuildTimeConfig buildTimeConfig, - KubernetesClientBuildConfig clientConfig) { + KubernetesClientBuildConfig clientConfig, + TlsConfig tlsConfig) { return new RunTimeConfigurationSourceValueBuildItem( - recorder.configSources(config, buildTimeConfig, clientConfig)); + recorder.configSources(config, buildTimeConfig, clientConfig, tlsConfig)); } @BuildStep diff --git a/extensions/kubernetes-config/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesConfigRecorder.java b/extensions/kubernetes-config/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesConfigRecorder.java index 0e4aa5bd011e24..37aed2a4f786e2 100644 --- a/extensions/kubernetes-config/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesConfigRecorder.java +++ b/extensions/kubernetes-config/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesConfigRecorder.java @@ -9,6 +9,7 @@ import org.jboss.logging.Logger; import io.quarkus.runtime.RuntimeValue; +import io.quarkus.runtime.TlsConfig; import io.quarkus.runtime.annotations.Recorder; import io.quarkus.runtime.configuration.AbstractRawDefaultConfigSource; @@ -21,7 +22,8 @@ public class KubernetesConfigRecorder { public RuntimeValue configSources(KubernetesConfigSourceConfig kubernetesConfigSourceConfig, KubernetesConfigBuildTimeConfig buildTimeConfig, - KubernetesClientBuildConfig clientConfig) { + KubernetesClientBuildConfig clientConfig, + TlsConfig tlsConfig) { if ((!kubernetesConfigSourceConfig.enabled && !buildTimeConfig.secretsEnabled) || isExplicitlyDisabled()) { log.debug( "No attempt will be made to obtain configuration from the Kubernetes API server because the functionality has been disabled via configuration"); @@ -29,7 +31,7 @@ public RuntimeValue configSources(KubernetesConfigSourceCo } return new RuntimeValue<>(new KubernetesConfigSourceProvider(kubernetesConfigSourceConfig, buildTimeConfig, - KubernetesClientUtils.createClient(clientConfig))); + KubernetesClientUtils.createClient(clientConfig, tlsConfig))); } // We don't want to enable the reading of anything if 'quarkus.kubernetes-config.enabled' is EXPLICITLY set to false diff --git a/extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MailClientProducer.java b/extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MailClientProducer.java index c588e8fd00590d..af970dc48b4fca 100644 --- a/extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MailClientProducer.java +++ b/extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MailClientProducer.java @@ -7,6 +7,7 @@ import org.jboss.logging.Logger; +import io.quarkus.runtime.TlsConfig; import io.vertx.core.Vertx; import io.vertx.ext.mail.LoginOption; import io.vertx.ext.mail.MailClient; @@ -23,8 +24,8 @@ public class MailClientProducer { private final io.vertx.mutiny.ext.mail.MailClient mutinyClient; private final MailClient client; - public MailClientProducer(Vertx vertx, MailConfig config) { - this.client = mailClient(vertx, config); + public MailClientProducer(Vertx vertx, MailConfig config, TlsConfig tlsConfig) { + this.client = mailClient(vertx, config, tlsConfig); this.mutinyClient = io.vertx.mutiny.ext.mail.MailClient.newInstance(this.client); } @@ -65,12 +66,12 @@ public void stop() { client.close(); } - private MailClient mailClient(Vertx vertx, MailConfig config) { - io.vertx.ext.mail.MailConfig cfg = toVertxMailConfig(config); + private MailClient mailClient(Vertx vertx, MailConfig config, TlsConfig tlsConfig) { + io.vertx.ext.mail.MailConfig cfg = toVertxMailConfig(config, tlsConfig); return MailClient.createShared(vertx, cfg); } - private io.vertx.ext.mail.MailConfig toVertxMailConfig(MailConfig config) { + private io.vertx.ext.mail.MailConfig toVertxMailConfig(MailConfig config, TlsConfig tlsConfig) { io.vertx.ext.mail.MailConfig cfg = new io.vertx.ext.mail.MailConfig(); if (config.authMethods.isPresent()) { cfg.setAuthMethods(config.authMethods.get()); @@ -106,7 +107,7 @@ private io.vertx.ext.mail.MailConfig toVertxMailConfig(MailConfig config) { if (config.startTLS.isPresent()) { cfg.setStarttls(StartTLSOptions.valueOf(config.startTLS.get().toUpperCase())); } - cfg.setTrustAll(config.trustAll); + cfg.setTrustAll(config.trustAll || tlsConfig.trustAll); return cfg; } diff --git a/extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MutinyMailerImpl.java b/extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MutinyMailerImpl.java index 213a1594c70735..38aeb241638a14 100644 --- a/extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MutinyMailerImpl.java +++ b/extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MutinyMailerImpl.java @@ -51,7 +51,7 @@ public class MutinyMailerImpl implements ReactiveMailer { public Void apply(List results) { return null; } - };; + }; @Override public Uni send(Mail... mails) { diff --git a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/OidcBuildStep.java b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/OidcBuildStep.java index d0f930b354d8f9..fe7ba790e86ccf 100644 --- a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/OidcBuildStep.java +++ b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/OidcBuildStep.java @@ -35,6 +35,7 @@ import io.quarkus.oidc.runtime.OidcRecorder; import io.quarkus.oidc.runtime.OidcTokenCredentialProducer; import io.quarkus.oidc.runtime.TenantConfigBean; +import io.quarkus.runtime.TlsConfig; import io.quarkus.vertx.core.deployment.CoreVertxBuildItem; import io.smallrye.jwt.auth.cdi.ClaimValueProducer; import io.smallrye.jwt.auth.cdi.CommonJwtProducer; @@ -92,9 +93,10 @@ EnableAllSecurityServicesBuildItem security() { public SyntheticBeanBuildItem setup( OidcConfig config, OidcRecorder recorder, - CoreVertxBuildItem vertxBuildItem) { + CoreVertxBuildItem vertxBuildItem, + TlsConfig tlsConfig) { return SyntheticBeanBuildItem.configure(TenantConfigBean.class).unremovable().types(TenantConfigBean.class) - .supplier(recorder.setup(config, vertxBuildItem.getVertx())) + .supplier(recorder.setup(config, vertxBuildItem.getVertx(), tlsConfig)) .scope(Singleton.class) .setRuntimeInit() .done(); diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java index c9939db7ae1c78..55e557bd031a49 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java @@ -21,6 +21,7 @@ import io.quarkus.oidc.OidcTenantConfig.Tls.Verification; import io.quarkus.runtime.BlockingOperationControl; import io.quarkus.runtime.ExecutorRecorder; +import io.quarkus.runtime.TlsConfig; import io.quarkus.runtime.annotations.Recorder; import io.quarkus.runtime.configuration.ConfigurationException; import io.smallrye.mutiny.Uni; @@ -44,7 +45,7 @@ public class OidcRecorder { private static final Map dynamicTenantsConfig = new ConcurrentHashMap<>(); - public Supplier setup(OidcConfig config, Supplier vertx) { + public Supplier setup(OidcConfig config, Supplier vertx, TlsConfig tlsConfig) { final Vertx vertxValue = vertx.get(); Map staticTenantsConfig = new HashMap<>(); @@ -57,10 +58,12 @@ public Supplier setup(OidcConfig config, Supplier vertx throw new OIDCException("Configuration has 2 different tenant-id values: '" + tenant.getKey() + "' and '" + tenant.getValue().getTenantId().get() + "'"); } - staticTenantsConfig.put(tenant.getKey(), createTenantContext(vertxValue, tenant.getValue(), tenant.getKey())); + staticTenantsConfig.put(tenant.getKey(), + createTenantContext(vertxValue, tenant.getValue(), tlsConfig, tenant.getKey())); } - TenantConfigContext tenantContext = createTenantContext(vertxValue, config.defaultTenant, "Default"); + TenantConfigContext tenantContext = createTenantContext(vertxValue, config.defaultTenant, tlsConfig, "Default"); + return new Supplier() { @Override public TenantConfigBean get() { @@ -70,7 +73,7 @@ public TenantConfigBean get() { public Uni apply(OidcTenantConfig config) { if (BlockingOperationControl.isBlockingAllowed()) { try { - return Uni.createFrom().item(createDynamicTenantContext(vertxValue, config, + return Uni.createFrom().item(createDynamicTenantContext(vertxValue, config, tlsConfig, config.getTenantId().get())); } catch (Throwable t) { return Uni.createFrom().failure(t); @@ -83,8 +86,9 @@ public void accept(UniEmitter uniEmitter) { @Override public void run() { try { - uniEmitter.complete(createDynamicTenantContext(vertxValue, config, - config.getTenantId().get())); + uniEmitter.complete( + createDynamicTenantContext(vertxValue, config, tlsConfig, + config.getTenantId().get())); } catch (Throwable t) { uniEmitter.fail(t); } @@ -99,14 +103,16 @@ public void run() { }; } - private TenantConfigContext createDynamicTenantContext(Vertx vertx, OidcTenantConfig oidcConfig, String tenantId) { + private TenantConfigContext createDynamicTenantContext(Vertx vertx, OidcTenantConfig oidcConfig, TlsConfig tlsConfig, + String tenantId) { if (!dynamicTenantsConfig.containsKey(tenantId)) { - dynamicTenantsConfig.putIfAbsent(tenantId, createTenantContext(vertx, oidcConfig, tenantId)); + dynamicTenantsConfig.putIfAbsent(tenantId, createTenantContext(vertx, oidcConfig, tlsConfig, tenantId)); } return dynamicTenantsConfig.get(tenantId); } - private TenantConfigContext createTenantContext(Vertx vertx, OidcTenantConfig oidcConfig, String tenantId) { + private TenantConfigContext createTenantContext(Vertx vertx, OidcTenantConfig oidcConfig, TlsConfig tlsConfig, + String tenantId) { if (!oidcConfig.tenantId.isPresent()) { oidcConfig.tenantId = Optional.of(tenantId); } @@ -234,7 +240,7 @@ private TenantConfigContext createTenantContext(Vertx vertx, OidcTenantConfig oi options.setProxyOptions(proxyOpt.get()); } - if (oidcConfig.tls.verification == Verification.NONE) { + if (oidcConfig.tls.verification == Verification.NONE || tlsConfig.trustAll) { options.setTrustAll(true); options.setVerifyHost(false); } diff --git a/extensions/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/RestClientBase.java b/extensions/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/RestClientBase.java index 9d402bb45f1e19..c44691cab83167 100644 --- a/extensions/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/RestClientBase.java +++ b/extensions/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/RestClientBase.java @@ -44,6 +44,8 @@ public class RestClientBase { public static final String REST_KEY_STORE_PASSWORD = "%s/" + MP_REST + "/keyStorePassword"; public static final String REST_KEY_STORE_TYPE = "%s/" + MP_REST + "/keyStoreType"; public static final String REST_HOSTNAME_VERIFIER = "%s/" + MP_REST + "/hostnameVerifier"; + public static final String REST_NOOP_HOSTNAME_VERIFIER = "io.quarkus.restclient.NoopHostnameVerifier"; + public static final String TLS_TRUST_ALL = "quarkus.tls.trust-all"; private final Class proxyType; private final String baseUriFromAnnotation; @@ -72,17 +74,23 @@ public Object create() { } private void configureSsl(RestClientBuilder builder) { - Optional maybeTrustStore = getOptionalProperty(REST_TRUST_STORE, String.class); + + Optional trustAll = getOptionalProperty(TLS_TRUST_ALL, Boolean.class); + if (trustAll.isPresent() && trustAll.get()) { + registerHostnameVerifier(REST_NOOP_HOSTNAME_VERIFIER, builder); + } + + Optional maybeTrustStore = getOptionalDynamicProperty(REST_TRUST_STORE, String.class); if (maybeTrustStore.isPresent()) { registerTrustStore(maybeTrustStore.get(), builder); } - Optional maybeKeyStore = getOptionalProperty(REST_KEY_STORE, String.class); + Optional maybeKeyStore = getOptionalDynamicProperty(REST_KEY_STORE, String.class); if (maybeKeyStore.isPresent()) { registerKeyStore(maybeKeyStore.get(), builder); } - Optional maybeHostnameVerifier = getOptionalProperty(REST_HOSTNAME_VERIFIER, String.class); + Optional maybeHostnameVerifier = getOptionalDynamicProperty(REST_HOSTNAME_VERIFIER, String.class); if (maybeHostnameVerifier.isPresent()) { registerHostnameVerifier(maybeHostnameVerifier.get(), builder); } @@ -115,8 +123,8 @@ private void registerHostnameVerifier(String verifier, RestClientBuilder builder } private void registerKeyStore(String keyStorePath, RestClientBuilder builder) { - Optional keyStorePassword = getOptionalProperty(REST_KEY_STORE_PASSWORD, String.class); - Optional keyStoreType = getOptionalProperty(REST_KEY_STORE_TYPE, String.class); + Optional keyStorePassword = getOptionalDynamicProperty(REST_KEY_STORE_PASSWORD, String.class); + Optional keyStoreType = getOptionalDynamicProperty(REST_KEY_STORE_TYPE, String.class); try { KeyStore keyStore = KeyStore.getInstance(keyStoreType.orElse("JKS")); @@ -139,8 +147,8 @@ private void registerKeyStore(String keyStorePath, RestClientBuilder builder) { } private void registerTrustStore(String trustStorePath, RestClientBuilder builder) { - Optional maybeTrustStorePassword = getOptionalProperty(REST_TRUST_STORE_PASSWORD, String.class); - Optional maybeTrustStoreType = getOptionalProperty(REST_TRUST_STORE_TYPE, String.class); + Optional maybeTrustStorePassword = getOptionalDynamicProperty(REST_TRUST_STORE_PASSWORD, String.class); + Optional maybeTrustStoreType = getOptionalDynamicProperty(REST_TRUST_STORE_TYPE, String.class); try { KeyStore trustStore = KeyStore.getInstance(maybeTrustStoreType.orElse("JKS")); @@ -188,7 +196,7 @@ private InputStream locateStream(String path) throws FileNotFoundException { } private void configureProviders(RestClientBuilder builder) { - Optional maybeProviders = getOptionalProperty(REST_PROVIDERS, String.class); + Optional maybeProviders = getOptionalDynamicProperty(REST_PROVIDERS, String.class); if (maybeProviders.isPresent()) { registerProviders(builder, maybeProviders.get()); } @@ -209,21 +217,21 @@ private Class providerClassForName(String name) { } private void configureTimeouts(RestClientBuilder builder) { - Optional connectTimeout = getOptionalProperty(REST_CONNECT_TIMEOUT_FORMAT, Long.class); + Optional connectTimeout = getOptionalDynamicProperty(REST_CONNECT_TIMEOUT_FORMAT, Long.class); if (connectTimeout.isPresent()) { builder.connectTimeout(connectTimeout.get(), TimeUnit.MILLISECONDS); } - Optional readTimeout = getOptionalProperty(REST_READ_TIMEOUT_FORMAT, Long.class); + Optional readTimeout = getOptionalDynamicProperty(REST_READ_TIMEOUT_FORMAT, Long.class); if (readTimeout.isPresent()) { builder.readTimeout(readTimeout.get(), TimeUnit.MILLISECONDS); } } private void configureBaseUrl(RestClientBuilder builder) { - Optional propertyOptional = getOptionalProperty(REST_URI_FORMAT, String.class); + Optional propertyOptional = getOptionalDynamicProperty(REST_URI_FORMAT, String.class); if (!propertyOptional.isPresent()) { - propertyOptional = getOptionalProperty(REST_URL_FORMAT, String.class); + propertyOptional = getOptionalDynamicProperty(REST_URL_FORMAT, String.class); } if (((baseUriFromAnnotation == null) || baseUriFromAnnotation.isEmpty()) && !propertyOptional.isPresent()) { @@ -250,10 +258,16 @@ private void configureBaseUrl(RestClientBuilder builder) { } } - private Optional getOptionalProperty(String propertyFormat, Class type) { + private Optional getOptionalDynamicProperty(String propertyFormat, Class type) { final Config config = ConfigProvider.getConfig(); Optional interfaceNameValue = config.getOptionalValue(String.format(propertyFormat, proxyType.getName()), type); return interfaceNameValue.isPresent() ? interfaceNameValue : config.getOptionalValue(String.format(propertyFormat, propertyPrefix), type); } + + private Optional getOptionalProperty(String propertyName, Class type) { + final Config config = ConfigProvider.getConfig(); + return config.getOptionalValue(propertyName, type); + } + } diff --git a/extensions/vault/deployment/src/main/java/io/quarkus/vault/VaultProcessor.java b/extensions/vault/deployment/src/main/java/io/quarkus/vault/VaultProcessor.java index cf21623dd2f5be..28d88c86b16aa5 100644 --- a/extensions/vault/deployment/src/main/java/io/quarkus/vault/VaultProcessor.java +++ b/extensions/vault/deployment/src/main/java/io/quarkus/vault/VaultProcessor.java @@ -17,6 +17,7 @@ import io.quarkus.deployment.builditem.RunTimeConfigurationSourceBuildItem; import io.quarkus.deployment.builditem.SslNativeConfigBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; +import io.quarkus.runtime.TlsConfig; import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; import io.quarkus.vault.runtime.Base64StringDeserializer; import io.quarkus.vault.runtime.Base64StringSerializer; @@ -73,8 +74,9 @@ AdditionalBeanBuildItem registerAdditionalBeans() { @Record(ExecutionTime.RUNTIME_INIT) @BuildStep - void configure(VaultRecorder recorder, VaultBuildTimeConfig buildTimeConfig, VaultRuntimeConfig serverConfig) { - recorder.configureRuntimeProperties(buildTimeConfig, serverConfig); + void configure(VaultRecorder recorder, VaultBuildTimeConfig buildTimeConfig, VaultRuntimeConfig serverConfig, + TlsConfig tlsConfig) { + recorder.configureRuntimeProperties(buildTimeConfig, serverConfig, tlsConfig); } @BuildStep diff --git a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultManager.java b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultManager.java index 1e16877d988bd5..c2db3bd6768738 100644 --- a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultManager.java +++ b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultManager.java @@ -1,5 +1,6 @@ package io.quarkus.vault.runtime; +import io.quarkus.runtime.TlsConfig; import io.quarkus.vault.runtime.client.OkHttpVaultClient; import io.quarkus.vault.runtime.client.VaultClient; import io.quarkus.vault.runtime.config.VaultBuildTimeConfig; @@ -11,6 +12,7 @@ public class VaultManager { private VaultRuntimeConfig serverConfig; private VaultBuildTimeConfig buildTimeConfig; + private TlsConfig tlsConfig; private VaultClient vaultClient; private VaultAuthManager vaultAuthManager; @@ -26,9 +28,9 @@ public static VaultManager getInstance() { return instance; } - public static void init(VaultBuildTimeConfig buildTimeConfig, VaultRuntimeConfig serverConfig) { + public static void init(VaultBuildTimeConfig buildTimeConfig, VaultRuntimeConfig serverConfig, TlsConfig tlsConfig) { if (instance == null) { - instance = new VaultManager(buildTimeConfig, serverConfig); + instance = new VaultManager(buildTimeConfig, serverConfig, tlsConfig); } } @@ -36,14 +38,16 @@ public static void reset() { instance = null; } - public VaultManager(VaultBuildTimeConfig vaultBuildTimeConfig, VaultRuntimeConfig serverConfig) { - this(vaultBuildTimeConfig, serverConfig, new OkHttpVaultClient(serverConfig)); + public VaultManager(VaultBuildTimeConfig vaultBuildTimeConfig, VaultRuntimeConfig serverConfig, TlsConfig tlsConfig) { + this(vaultBuildTimeConfig, serverConfig, new OkHttpVaultClient(serverConfig, tlsConfig), tlsConfig); } - public VaultManager(VaultBuildTimeConfig vaultBuildTimeConfig, VaultRuntimeConfig serverConfig, VaultClient vaultClient) { + public VaultManager(VaultBuildTimeConfig vaultBuildTimeConfig, VaultRuntimeConfig serverConfig, VaultClient vaultClient, + TlsConfig tlsConfig) { this.serverConfig = serverConfig; this.vaultClient = vaultClient; this.buildTimeConfig = vaultBuildTimeConfig; + this.tlsConfig = tlsConfig; this.vaultAuthManager = new VaultAuthManager(this.vaultClient, serverConfig); this.vaultKvManager = new VaultKvManager(this.vaultAuthManager, this.vaultClient, serverConfig); this.vaultDbManager = new VaultDbManager(this.vaultAuthManager, this.vaultClient, serverConfig); @@ -91,6 +95,10 @@ public VaultBuildTimeConfig getBuildTimeConfig() { return buildTimeConfig; } + public TlsConfig getTlsConfig() { + return tlsConfig; + } + public VaultSystemBackendManager getVaultSystemBackendManager() { return vaultSystemBackendManager; } diff --git a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultRecorder.java b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultRecorder.java index 1578de99956f7a..bc25e869776a22 100644 --- a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultRecorder.java +++ b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultRecorder.java @@ -3,6 +3,7 @@ import org.jboss.logging.Logger; import io.quarkus.arc.Arc; +import io.quarkus.runtime.TlsConfig; import io.quarkus.runtime.annotations.Recorder; import io.quarkus.vault.runtime.config.VaultBuildTimeConfig; import io.quarkus.vault.runtime.config.VaultRuntimeConfig; @@ -12,11 +13,12 @@ public class VaultRecorder { private static final Logger log = Logger.getLogger(VaultRecorder.class); - public void configureRuntimeProperties(VaultBuildTimeConfig vaultBuildTimeConfig, VaultRuntimeConfig vaultRuntimeConfig) { + public void configureRuntimeProperties(VaultBuildTimeConfig vaultBuildTimeConfig, VaultRuntimeConfig vaultRuntimeConfig, + TlsConfig tlsConfig) { if (vaultRuntimeConfig.url.isPresent()) { VaultServiceProducer producer = Arc.container().instance(VaultServiceProducer.class).get(); - producer.setVaultConfigs(vaultBuildTimeConfig, vaultRuntimeConfig); + producer.setVaultConfigs(vaultBuildTimeConfig, vaultRuntimeConfig, tlsConfig); } } diff --git a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultServiceProducer.java b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultServiceProducer.java index 06e4c5a40ed1a2..0c98c37bd6718a 100644 --- a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultServiceProducer.java +++ b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultServiceProducer.java @@ -6,6 +6,7 @@ import javax.inject.Named; import io.quarkus.credentials.CredentialsProvider; +import io.quarkus.runtime.TlsConfig; import io.quarkus.vault.VaultKVSecretEngine; import io.quarkus.vault.VaultSystemBackendEngine; import io.quarkus.vault.VaultTOTPSecretEngine; @@ -58,7 +59,7 @@ public void close() { VaultManager.reset(); } - public void setVaultConfigs(VaultBuildTimeConfig buildTimeConfig, VaultRuntimeConfig serverConfig) { - VaultManager.init(buildTimeConfig, serverConfig); + public void setVaultConfigs(VaultBuildTimeConfig buildTimeConfig, VaultRuntimeConfig serverConfig, TlsConfig tlsConfig) { + VaultManager.init(buildTimeConfig, serverConfig, tlsConfig); } } diff --git a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/client/OkHttpClientFactory.java b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/client/OkHttpClientFactory.java index b1f9a896ffb6c9..7e40e50c1dfd72 100644 --- a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/client/OkHttpClientFactory.java +++ b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/client/OkHttpClientFactory.java @@ -17,6 +17,7 @@ import org.jboss.logging.Logger; +import io.quarkus.runtime.TlsConfig; import io.quarkus.runtime.util.JavaVersionUtil; import io.quarkus.vault.VaultException; import io.quarkus.vault.runtime.config.VaultRuntimeConfig; @@ -27,7 +28,7 @@ public class OkHttpClientFactory { private static final Logger log = Logger.getLogger(OkHttpClientFactory.class.getName()); - public static OkHttpClient createHttpClient(VaultRuntimeConfig serverConfig) { + public static OkHttpClient createHttpClient(VaultRuntimeConfig serverConfig, TlsConfig tlsConfig) { OkHttpClient.Builder builder = new OkHttpClient.Builder() .connectTimeout(serverConfig.connectTimeout) @@ -40,7 +41,7 @@ public static OkHttpClient createHttpClient(VaultRuntimeConfig serverConfig) { } try { - if (serverConfig.tls.skipVerify) { + if (serverConfig.tls.skipVerify || tlsConfig.trustAll) { skipVerify(builder); } else if (serverConfig.tls.caCert.isPresent()) { cacert(builder, serverConfig.tls.caCert.get()); diff --git a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/client/OkHttpVaultClient.java b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/client/OkHttpVaultClient.java index 24f8682e9f4590..74fcc4757b40bb 100644 --- a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/client/OkHttpVaultClient.java +++ b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/client/OkHttpVaultClient.java @@ -16,6 +16,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import io.quarkus.runtime.TlsConfig; import io.quarkus.vault.VaultException; import io.quarkus.vault.runtime.client.dto.auth.VaultAppRoleAuth; import io.quarkus.vault.runtime.client.dto.auth.VaultAppRoleAuthBody; @@ -83,8 +84,8 @@ public class OkHttpVaultClient implements VaultClient { private String kubernetesAuthMountPath; private ObjectMapper mapper = new ObjectMapper(); - public OkHttpVaultClient(VaultRuntimeConfig serverConfig) { - this.client = createHttpClient(serverConfig); + public OkHttpVaultClient(VaultRuntimeConfig serverConfig, TlsConfig tlsConfig) { + this.client = createHttpClient(serverConfig, tlsConfig); this.url = serverConfig.url.get(); this.mapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); this.mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); diff --git a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/config/VaultConfigSource.java b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/config/VaultConfigSource.java index decd992ee5ffe5..974538bf368213 100644 --- a/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/config/VaultConfigSource.java +++ b/extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/config/VaultConfigSource.java @@ -43,6 +43,7 @@ import org.eclipse.microprofile.config.spi.ConfigSource; import org.jboss.logging.Logger; +import io.quarkus.runtime.TlsConfig; import io.quarkus.runtime.configuration.DurationConverter; import io.quarkus.vault.VaultException; import io.quarkus.vault.runtime.LogConfidentialityLevel; @@ -62,6 +63,7 @@ public class VaultConfigSource implements ConfigSource { private AtomicReference>> cache = new AtomicReference<>(null); private AtomicReference serverConfig = new AtomicReference<>(null); private AtomicReference buildServerConfig = new AtomicReference<>(null); + private AtomicReference tlsConfig = new AtomicReference<>(null); private AtomicBoolean init = new AtomicBoolean(false); private int ordinal; @@ -155,10 +157,11 @@ private VaultManager getVaultManager() { VaultBuildTimeConfig buildTimeConfig = getBuildtimeConfig(); VaultRuntimeConfig serverConfig = getRuntimeConfig(); + TlsConfig tlsConfig = getTlsConfig(); // init at most once if (init.compareAndSet(false, true)) { - VaultManager.init(buildTimeConfig, serverConfig); + VaultManager.init(buildTimeConfig, serverConfig, tlsConfig); } return VaultManager.getInstance(); @@ -172,6 +175,10 @@ private VaultBuildTimeConfig getBuildtimeConfig() { return getConfig(this.buildServerConfig, () -> loadBuildtimeConfig(), "buildtime"); } + private TlsConfig getTlsConfig() { + return getConfig(this.tlsConfig, () -> loadTlsConfig(), "tls"); + } + private T getConfig(AtomicReference ref, Supplier supplier, String name) { T config = ref.get(); if (config != null) { @@ -251,6 +258,12 @@ private VaultRuntimeConfig loadRuntimeConfig() { return serverConfig; } + private TlsConfig loadTlsConfig() { + TlsConfig tlsConfig = new TlsConfig(); + tlsConfig.trustAll = Boolean.parseBoolean(getProperty("quarkus.tls.trust-all", "false", 0)); + return tlsConfig; + } + private VaultMapConfigParser createCredentialProviderConfigParser() { return new VaultMapConfigParser<>(CREDENTIALS_PATTERN, this::getCredentialsProviderConfig, getConfigSourceStream()); } diff --git a/extensions/vault/runtime/src/test/java/io/quarkus/vault/runtime/VaultAuthManagerTest.java b/extensions/vault/runtime/src/test/java/io/quarkus/vault/runtime/VaultAuthManagerTest.java index 6dea66650bcf09..bfdb11beb8d20b 100644 --- a/extensions/vault/runtime/src/test/java/io/quarkus/vault/runtime/VaultAuthManagerTest.java +++ b/extensions/vault/runtime/src/test/java/io/quarkus/vault/runtime/VaultAuthManagerTest.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test; +import io.quarkus.runtime.TlsConfig; import io.quarkus.vault.runtime.client.OkHttpVaultClient; import io.quarkus.vault.runtime.client.VaultClientException; import io.quarkus.vault.runtime.client.dto.auth.VaultLookupSelf; @@ -28,6 +29,7 @@ public class VaultAuthManagerTest { VaultRuntimeConfig config = createConfig(); + TlsConfig tlsConfig = new TlsConfig(); AtomicBoolean lookupSelfShouldReturn403 = new AtomicBoolean(false); OkHttpVaultClient vaultClient = createVaultClient(); VaultAuthManager vaultAuthManager = new VaultAuthManager(vaultClient, config); @@ -117,7 +119,7 @@ private VaultRuntimeConfig createConfig() { } private OkHttpVaultClient createVaultClient() { - return new OkHttpVaultClient(config) { + return new OkHttpVaultClient(config, tlsConfig) { @Override public VaultUserPassAuth loginUserPass(String user, String password) { return vaultUserPassAuth; diff --git a/extensions/vault/runtime/src/test/java/io/quarkus/vault/runtime/VaultDbManagerTest.java b/extensions/vault/runtime/src/test/java/io/quarkus/vault/runtime/VaultDbManagerTest.java index 2487eac9d33c87..3897991bf44016 100644 --- a/extensions/vault/runtime/src/test/java/io/quarkus/vault/runtime/VaultDbManagerTest.java +++ b/extensions/vault/runtime/src/test/java/io/quarkus/vault/runtime/VaultDbManagerTest.java @@ -14,6 +14,7 @@ import org.junit.jupiter.api.Test; +import io.quarkus.runtime.TlsConfig; import io.quarkus.vault.runtime.client.OkHttpVaultClient; import io.quarkus.vault.runtime.client.VaultClientException; import io.quarkus.vault.runtime.client.dto.database.VaultDatabaseCredentials; @@ -30,6 +31,7 @@ public class VaultDbManagerTest { VaultRuntimeConfig config = createConfig(); + TlsConfig tlsConfig = new TlsConfig(); VaultDatabaseCredentials credentials = new VaultDatabaseCredentials(); VaultLeasesLookup vaultLeasesLookup = new VaultLeasesLookup(); AtomicBoolean lookupLeaseShouldReturn400 = new AtomicBoolean(false); @@ -123,7 +125,7 @@ private VaultRuntimeConfig createConfig() { } private OkHttpVaultClient createVaultClient() { - return new OkHttpVaultClient(config) { + return new OkHttpVaultClient(config, tlsConfig) { @Override public VaultDatabaseCredentials generateDatabaseCredentials(String token, String databaseCredentialsRole) { return credentials; diff --git a/integration-tests/rest-client/src/test/java/io/quarkus/it/rest/client/trustall/ExternalTlsTrustAllIT.java b/integration-tests/rest-client/src/test/java/io/quarkus/it/rest/client/trustall/ExternalTlsTrustAllIT.java new file mode 100644 index 00000000000000..d359a08de548b5 --- /dev/null +++ b/integration-tests/rest-client/src/test/java/io/quarkus/it/rest/client/trustall/ExternalTlsTrustAllIT.java @@ -0,0 +1,7 @@ +package io.quarkus.it.rest.client.trustall; + +import io.quarkus.test.junit.NativeImageTest; + +@NativeImageTest +public class ExternalTlsTrustAllIT extends ExternalTlsTrustAllTestCase { +} diff --git a/integration-tests/rest-client/src/test/java/io/quarkus/it/rest/client/trustall/ExternalTlsTrustAllTestCase.java b/integration-tests/rest-client/src/test/java/io/quarkus/it/rest/client/trustall/ExternalTlsTrustAllTestCase.java new file mode 100644 index 00000000000000..ba89527182f5d7 --- /dev/null +++ b/integration-tests/rest-client/src/test/java/io/quarkus/it/rest/client/trustall/ExternalTlsTrustAllTestCase.java @@ -0,0 +1,23 @@ +package io.quarkus.it.rest.client.trustall; + +import static io.restassured.RestAssured.when; +import static org.hamcrest.Matchers.is; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(ExternalTlsTrustAllTestResource.class) +public class ExternalTlsTrustAllTestCase { + + @Test + public void restClient() { + when() + .get("/wrong-host") + .then() + .statusCode(200) + .body(is("200")); + } +} diff --git a/integration-tests/rest-client/src/test/java/io/quarkus/it/rest/client/trustall/ExternalTlsTrustAllTestResource.java b/integration-tests/rest-client/src/test/java/io/quarkus/it/rest/client/trustall/ExternalTlsTrustAllTestResource.java new file mode 100644 index 00000000000000..2a55b750ba3f76 --- /dev/null +++ b/integration-tests/rest-client/src/test/java/io/quarkus/it/rest/client/trustall/ExternalTlsTrustAllTestResource.java @@ -0,0 +1,23 @@ +package io.quarkus.it.rest.client.trustall; + +import java.util.HashMap; +import java.util.Map; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; + +public class ExternalTlsTrustAllTestResource implements QuarkusTestResourceLifecycleManager { + + @Override + public Map start() { + Map result = new HashMap<>(); + result.put("wrong-host/mp-rest/trustStore", System.getProperty("rest-client.trustStore")); + result.put("wrong-host/mp-rest/trustStorePassword", System.getProperty("rest-client.trustStorePassword")); + result.put("quarkus.tls.trust-all", "true"); + return result; + } + + @Override + public void stop() { + + } +} diff --git a/integration-tests/vault/src/test/resources/application-vault-multi-path.properties b/integration-tests/vault/src/test/resources/application-vault-multi-path.properties index 8a2452d1fc34f2..54fc75776fd26e 100644 --- a/integration-tests/vault/src/test/resources/application-vault-multi-path.properties +++ b/integration-tests/vault/src/test/resources/application-vault-multi-path.properties @@ -4,7 +4,7 @@ quarkus.vault.authentication.userpass.password=sinclair quarkus.vault.secret-config-kv-path=multi/default1,multi/default2 quarkus.vault.secret-config-kv-path.singer=multi/singer1,multi/singer2 -quarkus.vault.tls.skip-verify=true +quarkus.tls.trust-all=true # CI can sometimes be slow, there is no need to fail a test if Vault doesn't respond in 1 second which is the default quarkus.vault.read-timeout=5S diff --git a/test-framework/vault/src/main/java/io/quarkus/vault/test/VaultTestExtension.java b/test-framework/vault/src/main/java/io/quarkus/vault/test/VaultTestExtension.java index a14138d37b1e1a..b16a9135db2c61 100644 --- a/test-framework/vault/src/main/java/io/quarkus/vault/test/VaultTestExtension.java +++ b/test-framework/vault/src/main/java/io/quarkus/vault/test/VaultTestExtension.java @@ -46,6 +46,7 @@ import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.output.OutputFrame; +import io.quarkus.runtime.TlsConfig; import io.quarkus.vault.VaultException; import io.quarkus.vault.VaultKVSecretEngine; import io.quarkus.vault.runtime.VaultManager; @@ -177,8 +178,9 @@ private static VaultManager createVaultManager() { VaultBuildTimeConfig buildTimeConfig = new VaultBuildTimeConfig(); buildTimeConfig.health = new HealthConfig(); + TlsConfig tlsConfig = new TlsConfig(); - return new VaultManager(buildTimeConfig, serverConfig, new TestVaultClient(serverConfig)); + return new VaultManager(buildTimeConfig, serverConfig, new TestVaultClient(serverConfig, tlsConfig), tlsConfig); } private static Optional getVaultUrl() { diff --git a/test-framework/vault/src/main/java/io/quarkus/vault/test/client/TestVaultClient.java b/test-framework/vault/src/main/java/io/quarkus/vault/test/client/TestVaultClient.java index 89ba776c051305..bfd3fd71adf488 100644 --- a/test-framework/vault/src/main/java/io/quarkus/vault/test/client/TestVaultClient.java +++ b/test-framework/vault/src/main/java/io/quarkus/vault/test/client/TestVaultClient.java @@ -1,5 +1,6 @@ package io.quarkus.vault.test.client; +import io.quarkus.runtime.TlsConfig; import io.quarkus.vault.runtime.VaultManager; import io.quarkus.vault.runtime.client.OkHttpVaultClient; import io.quarkus.vault.runtime.client.dto.transit.VaultTransitRandomBody; @@ -13,11 +14,11 @@ public class TestVaultClient extends OkHttpVaultClient { public TestVaultClient() { - this(VaultManager.getInstance().getServerConfig()); + this(VaultManager.getInstance().getServerConfig(), VaultManager.getInstance().getTlsConfig()); } - public TestVaultClient(VaultRuntimeConfig serverConfig) { - super(serverConfig); + public TestVaultClient(VaultRuntimeConfig serverConfig, TlsConfig tlsConfig) { + super(serverConfig, tlsConfig); } public VaultAppRoleSecretId generateAppRoleSecretId(String token, String roleName) {