Skip to content

Commit e4febe2

Browse files
committed
Apply verify-hostname consistently
Closes gh-50168
1 parent 2c2ffe5 commit e4febe2

3 files changed

Lines changed: 77 additions & 22 deletions

File tree

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitConnectionFactoryBeanConfigurer.java

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -132,25 +132,15 @@ public void configure(RabbitConnectionFactoryBean factory) {
132132
.to(factory::setRequestedHeartbeat);
133133
map.from(this.rabbitProperties::getRequestedChannelMax).to(factory::setRequestedChannelMax);
134134
SslBundle sslBundle = this.connectionDetails.getSslBundle();
135-
if (sslBundle != null) {
136-
applySslBundle(factory, sslBundle);
137-
}
138-
else {
139-
RabbitProperties.Ssl ssl = this.rabbitProperties.getSsl();
140-
if (ssl.determineEnabled()) {
141-
factory.setUseSSL(true);
142-
map.from(ssl::getAlgorithm).whenNonNull().to(factory::setSslAlgorithm);
143-
map.from(ssl::getKeyStoreType).to(factory::setKeyStoreType);
144-
map.from(ssl::getKeyStore).to(factory::setKeyStore);
145-
map.from(ssl::getKeyStorePassword).to(factory::setKeyStorePassphrase);
146-
map.from(ssl::getKeyStoreAlgorithm).whenNonNull().to(factory::setKeyStoreAlgorithm);
147-
map.from(ssl::getTrustStoreType).to(factory::setTrustStoreType);
148-
map.from(ssl::getTrustStore).to(factory::setTrustStore);
149-
map.from(ssl::getTrustStorePassword).to(factory::setTrustStorePassphrase);
150-
map.from(ssl::getTrustStoreAlgorithm).whenNonNull().to(factory::setTrustStoreAlgorithm);
151-
map.from(ssl::isValidateServerCertificate)
152-
.to((validate) -> factory.setSkipServerCertificateValidation(!validate));
153-
map.from(ssl::isVerifyHostname).to(factory::setEnableHostnameVerification);
135+
RabbitProperties.Ssl ssl = this.rabbitProperties.getSsl();
136+
if (sslBundle != null || ssl.determineEnabled()) {
137+
factory.setUseSSL(true);
138+
map.from(ssl::isVerifyHostname).to(factory::setEnableHostnameVerification);
139+
if (sslBundle != null) {
140+
applySslBundle(factory, sslBundle);
141+
}
142+
else {
143+
applySslProperties(factory, map, ssl);
154144
}
155145
}
156146
map.from(this.rabbitProperties::getConnectionTimeout)
@@ -169,11 +159,24 @@ public void configure(RabbitConnectionFactoryBean factory) {
169159
.to(factory::setMaxInboundMessageBodySize);
170160
}
171161

172-
private static void applySslBundle(RabbitConnectionFactoryBean factory, SslBundle bundle) {
173-
factory.setUseSSL(true);
162+
private void applySslBundle(RabbitConnectionFactoryBean factory, SslBundle bundle) {
174163
if (factory instanceof SslBundleRabbitConnectionFactoryBean sslFactory) {
175164
sslFactory.setSslBundle(bundle);
176165
}
177166
}
178167

168+
private void applySslProperties(RabbitConnectionFactoryBean factory, PropertyMapper map, RabbitProperties.Ssl ssl) {
169+
map.from(ssl::getAlgorithm).whenNonNull().to(factory::setSslAlgorithm);
170+
map.from(ssl::getKeyStoreType).to(factory::setKeyStoreType);
171+
map.from(ssl::getKeyStore).to(factory::setKeyStore);
172+
map.from(ssl::getKeyStorePassword).to(factory::setKeyStorePassphrase);
173+
map.from(ssl::getKeyStoreAlgorithm).whenNonNull().to(factory::setKeyStoreAlgorithm);
174+
map.from(ssl::getTrustStoreType).to(factory::setTrustStoreType);
175+
map.from(ssl::getTrustStore).to(factory::setTrustStore);
176+
map.from(ssl::getTrustStorePassword).to(factory::setTrustStorePassphrase);
177+
map.from(ssl::getTrustStoreAlgorithm).whenNonNull().to(factory::setTrustStoreAlgorithm);
178+
map.from(ssl::isValidateServerCertificate)
179+
.to((validate) -> factory.setSkipServerCertificateValidation(!validate));
180+
}
181+
179182
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SslBundleRabbitConnectionFactoryBean.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class SslBundleRabbitConnectionFactoryBean extends RabbitConnectionFactoryBean {
2929

3030
private SslBundle sslBundle;
3131

32-
private boolean enableHostnameVerification;
32+
private boolean enableHostnameVerification = true;
3333

3434
@Override
3535
protected void setUpSSL() {

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,21 @@
1616

1717
package org.springframework.boot.autoconfigure.amqp;
1818

19+
import java.io.IOException;
1920
import java.security.NoSuchAlgorithmException;
2021
import java.util.Collection;
2122
import java.util.List;
2223
import java.util.concurrent.ThreadFactory;
2324
import java.util.concurrent.atomic.AtomicInteger;
2425

26+
import javax.net.ssl.SSLEngine;
27+
import javax.net.ssl.SSLParameters;
2528
import javax.net.ssl.SSLSocketFactory;
2629

2730
import com.rabbitmq.client.Address;
2831
import com.rabbitmq.client.Connection;
2932
import com.rabbitmq.client.JDKSaslConfig;
33+
import com.rabbitmq.client.SslEngineConfigurator;
3034
import com.rabbitmq.client.impl.CredentialsProvider;
3135
import com.rabbitmq.client.impl.CredentialsRefreshService;
3236
import com.rabbitmq.client.impl.DefaultCredentialsProvider;
@@ -38,6 +42,7 @@
3842
import org.junit.jupiter.api.extension.ExtendWith;
3943
import org.junit.jupiter.params.ParameterizedTest;
4044
import org.junit.jupiter.params.provider.ValueSource;
45+
import org.mockito.ArgumentCaptor;
4146
import org.mockito.InOrder;
4247

4348
import org.springframework.amqp.core.AcknowledgeMode;
@@ -843,6 +848,20 @@ void enableSsl() {
843848
assertThat(rabbitConnectionFactory.isSSL()).isTrue();
844849
assertThat(rabbitConnectionFactory.getSocketFactory()).as("SocketFactory must use SSL")
845850
.isInstanceOf(SSLSocketFactory.class);
851+
assertThatHostnameVerificationIsEnabled(rabbitConnectionFactory);
852+
});
853+
}
854+
855+
@Test
856+
void enableSslWithoutHostnameVerification() {
857+
this.contextRunner.withUserConfiguration(TestConfiguration.class)
858+
.withPropertyValues("spring.rabbitmq.ssl.enabled:true", "spring.rabbitmq.ssl.verify-hostname:false")
859+
.run((context) -> {
860+
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(context);
861+
assertThat(rabbitConnectionFactory.isSSL()).isTrue();
862+
assertThat(rabbitConnectionFactory.getSocketFactory()).as("SocketFactory must use SSL")
863+
.isInstanceOf(SSLSocketFactory.class);
864+
assertThatHostnameVerificationIsDisabled(rabbitConnectionFactory);
846865
});
847866
}
848867

@@ -915,6 +934,20 @@ void enableSslWithBundle() {
915934
.run((context) -> {
916935
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(context);
917936
assertThat(rabbitConnectionFactory.isSSL()).isTrue();
937+
assertThatHostnameVerificationIsEnabled(rabbitConnectionFactory);
938+
});
939+
}
940+
941+
@Test
942+
void enableSslWithBundleAndWithoutHostnameVerification() {
943+
this.contextRunner.withUserConfiguration(TestConfiguration.class)
944+
.withPropertyValues("spring.rabbitmq.ssl.bundle=test-bundle", "spring.rabbitmq.ssl.verify-hostname=false",
945+
"spring.ssl.bundle.jks.test-bundle.keystore.location=classpath:org/springframework/boot/autoconfigure/amqp/test.jks",
946+
"spring.ssl.bundle.jks.test-bundle.keystore.password=secret")
947+
.run((context) -> {
948+
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(context);
949+
assertThat(rabbitConnectionFactory.isSSL()).isTrue();
950+
assertThatHostnameVerificationIsDisabled(rabbitConnectionFactory);
918951
});
919952
}
920953

@@ -1078,6 +1111,25 @@ void whenADirectContainerCustomizerIsDefinedThenItIsCalledToConfigureTheContaine
10781111
.configure(any(DirectMessageListenerContainer.class)));
10791112
}
10801113

1114+
private void assertThatHostnameVerificationIsEnabled(com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory)
1115+
throws IOException {
1116+
SslEngineConfigurator sslEngineConfigurator = rabbitConnectionFactory.getNioParams().getSslEngineConfigurator();
1117+
SSLEngine engine = mock(SSLEngine.class);
1118+
sslEngineConfigurator.configure(engine);
1119+
ArgumentCaptor<SSLParameters> sslParametersCaptor = ArgumentCaptor.forClass(SSLParameters.class);
1120+
then(engine).should().setSSLParameters(sslParametersCaptor.capture());
1121+
SSLParameters sslParameters = sslParametersCaptor.getValue();
1122+
assertThat(sslParameters.getEndpointIdentificationAlgorithm()).isEqualTo("HTTPS");
1123+
}
1124+
1125+
private void assertThatHostnameVerificationIsDisabled(com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory)
1126+
throws IOException {
1127+
SslEngineConfigurator sslEngineConfigurator = rabbitConnectionFactory.getNioParams().getSslEngineConfigurator();
1128+
SSLEngine engine = mock(SSLEngine.class);
1129+
sslEngineConfigurator.configure(engine);
1130+
then(engine).shouldHaveNoMoreInteractions();
1131+
}
1132+
10811133
private com.rabbitmq.client.ConnectionFactory getTargetConnectionFactory(AssertableApplicationContext context) {
10821134
CachingConnectionFactory connectionFactory = context.getBean(CachingConnectionFactory.class);
10831135
return connectionFactory.getRabbitConnectionFactory();

0 commit comments

Comments
 (0)