Skip to content

Commit 69fad2a

Browse files
committed
Add support for hostname verification
1 parent b488df6 commit 69fad2a

File tree

24 files changed

+157
-46
lines changed

24 files changed

+157
-46
lines changed

activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/AmqpTestSupport.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ protected void addTranportConnectors() throws Exception {
185185
}
186186
if (isUseSslConnector()) {
187187
connector = brokerService.addConnector(
188-
"amqp+ssl://0.0.0.0:" + amqpSslPort + "?transport.tcpNoDelay=true&transport.transformer=" + getAmqpTransformer() + getAdditionalConfig());
188+
"amqp+ssl://0.0.0.0:" + amqpSslPort + "?transport.verifyHostName=false&transport.tcpNoDelay=true&transport.transformer=" + getAmqpTransformer() + getAdditionalConfig());
189189
amqpSslPort = connector.getConnectUri().getPort();
190190
amqpSslURI = connector.getPublishableConnectURI();
191191
LOG.debug("Using amqp+ssl port " + amqpSslPort);
@@ -199,7 +199,7 @@ protected void addTranportConnectors() throws Exception {
199199
}
200200
if (isUseNioPlusSslConnector()) {
201201
connector = brokerService.addConnector(
202-
"amqp+nio+ssl://0.0.0.0:" + amqpNioPlusSslPort + "?transport.tcpNoDelay=true&transport.transformer=" + getAmqpTransformer() + getAdditionalConfig());
202+
"amqp+nio+ssl://0.0.0.0:" + amqpNioPlusSslPort + "?transport.verifyHostName=false&transport.tcpNoDelay=true&transport.transformer=" + getAmqpTransformer() + getAdditionalConfig());
203203
amqpNioPlusSslPort = connector.getConnectUri().getPort();
204204
amqpNioPlusSslURI = connector.getPublishableConnectURI();
205205
LOG.debug("Using amqp+nio+ssl port " + amqpNioPlusSslPort);

activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/auto/JMSClientAutoSslAuthTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ protected URI getBrokerURI() {
7979

8080
@Override
8181
protected String getAdditionalConfig() {
82-
return "?transport.needClientAuth=true";
82+
return "?transport.needClientAuth=true&transport.verifyHostName=false";
8383
}
8484

8585

activemq-broker/src/main/java/org/apache/activemq/transport/nio/AutoInitNioSSLTransport.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import javax.net.ssl.SSLContext;
3131
import javax.net.ssl.SSLEngine;
3232
import javax.net.ssl.SSLEngineResult;
33+
import javax.net.ssl.SSLParameters;
3334

3435
import org.apache.activemq.thread.TaskRunnerFactory;
3536
import org.apache.activemq.util.IOExceptionSupport;
@@ -89,6 +90,12 @@ protected void initializeStreams() throws IOException {
8990
sslEngine = sslContext.createSSLEngine();
9091
}
9192

93+
if (verifyHostName) {
94+
SSLParameters sslParams = new SSLParameters();
95+
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
96+
sslEngine.setSSLParameters(sslParams);
97+
}
98+
9299
sslEngine.setUseClientMode(false);
93100
if (enabledCipherSuites != null) {
94101
sslEngine.setEnabledCipherSuites(enabledCipherSuites);

activemq-client/src/main/java/org/apache/activemq/transport/nio/NIOSSLTransport.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import javax.net.ssl.SSLEngine;
3737
import javax.net.ssl.SSLEngineResult;
3838
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
39+
import javax.net.ssl.SSLParameters;
3940
import javax.net.ssl.SSLPeerUnverifiedException;
4041
import javax.net.ssl.SSLSession;
4142

@@ -56,6 +57,7 @@ public class NIOSSLTransport extends NIOTransport {
5657
protected boolean wantClientAuth;
5758
protected String[] enabledCipherSuites;
5859
protected String[] enabledProtocols;
60+
protected boolean verifyHostName = true;
5961

6062
protected SSLContext sslContext;
6163
protected SSLEngine sslEngine;
@@ -119,6 +121,12 @@ protected void initializeStreams() throws IOException {
119121
sslEngine = sslContext.createSSLEngine();
120122
}
121123

124+
if (verifyHostName) {
125+
SSLParameters sslParams = new SSLParameters();
126+
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
127+
sslEngine.setSSLParameters(sslParams);
128+
}
129+
122130
sslEngine.setUseClientMode(false);
123131
if (enabledCipherSuites != null) {
124132
sslEngine.setEnabledCipherSuites(enabledCipherSuites);
@@ -543,4 +551,12 @@ public String[] getEnabledProtocols() {
543551
public void setEnabledProtocols(String[] enabledProtocols) {
544552
this.enabledProtocols = enabledProtocols;
545553
}
554+
555+
public boolean isVerifyHostName() {
556+
return verifyHostName;
557+
}
558+
559+
public void setVerifyHostName(boolean verifyHostName) {
560+
this.verifyHostName = verifyHostName;
561+
}
546562
}

activemq-client/src/main/java/org/apache/activemq/transport/tcp/SslTransport.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
package org.apache.activemq.transport.tcp;
1818

1919
import java.io.IOException;
20+
import java.net.Socket;
21+
import java.net.SocketException;
2022
import java.net.URI;
2123
import java.net.UnknownHostException;
2224
import java.security.cert.X509Certificate;
2325
import java.util.HashMap;
2426

27+
import javax.net.ssl.SSLParameters;
2528
import javax.net.ssl.SSLPeerUnverifiedException;
2629
import javax.net.ssl.SSLSession;
2730
import javax.net.ssl.SSLSocket;
@@ -43,6 +46,8 @@
4346
*/
4447
public class SslTransport extends TcpTransport {
4548

49+
private Boolean verifyHostName = null;
50+
4651
/**
4752
* Connect to a remote node such as a Broker.
4853
*
@@ -73,6 +78,37 @@ public SslTransport(WireFormat wireFormat, SSLSocketFactory socketFactory, URI r
7378
}
7479
}
7580

81+
@Override
82+
protected void initialiseSocket(Socket sock) throws SocketException, IllegalArgumentException {
83+
//This needs to default to null because this transport class is used for both a server transport
84+
//and a client connection and if we default it to a value it might override the transport server setting
85+
//that was configured inside TcpTransportServer
86+
87+
//The idea here is that if this is a server transport then verifyHostName will be set by the setter
88+
//below and not be null (if using transport.verifyHostName) but if a client uses socket.verifyHostName
89+
//then it will be null and we can check socketOptions
90+
91+
//Unfortunately we have to do this to stay consistent because every other SSL option on the client
92+
//side is configured using socket. but this particular option isn't actually part of the socket
93+
//so it makes it tricky
94+
if (verifyHostName == null) {
95+
if (socketOptions != null && socketOptions.containsKey("verifyHostName")) {
96+
verifyHostName = Boolean.parseBoolean(socketOptions.get("verifyHostName").toString());
97+
socketOptions.remove("verifyHostName");
98+
} else {
99+
verifyHostName = true;
100+
}
101+
}
102+
103+
if (verifyHostName) {
104+
SSLParameters sslParams = new SSLParameters();
105+
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
106+
((SSLSocket)this.socket).setSSLParameters(sslParams);
107+
}
108+
109+
super.initialiseSocket(sock);
110+
}
111+
76112
/**
77113
* Initialize from a ServerSocket. No access to needClientAuth is given
78114
* since it is already set within the provided socket.
@@ -108,6 +144,10 @@ public void doConsume(Object command) {
108144
super.doConsume(command);
109145
}
110146

147+
public void setVerifyHostName(Boolean verifyHostName) {
148+
this.verifyHostName = verifyHostName;
149+
}
150+
111151
/**
112152
* @return peer certificate chain associated with the ssl socket
113153
*/

activemq-client/src/main/java/org/apache/activemq/transport/tcp/SslTransportServer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public void setWantClientAuth(boolean wantAuth) {
100100
*
101101
* @throws IOException passed up from TcpTransportServer.
102102
*/
103+
@Override
103104
public void bind() throws IOException {
104105
super.bind();
105106
if (needClientAuth) {
@@ -119,6 +120,7 @@ public void bind() throws IOException {
119120
* @return The newly return (SSL) Transport.
120121
* @throws IOException
121122
*/
123+
@Override
122124
protected Transport createTransport(Socket socket, WireFormat format) throws IOException {
123125
return new SslTransport(format, (SSLSocket)socket);
124126
}

activemq-client/src/main/java/org/apache/activemq/transport/tcp/TcpTransport.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public class TcpTransport extends TransportThreadSupport implements Transport, S
133133
protected final AtomicReference<CountDownLatch> stoppedLatch = new AtomicReference<CountDownLatch>();
134134
protected volatile int receiveCounter;
135135

136-
private Map<String, Object> socketOptions;
136+
protected Map<String, Object> socketOptions;
137137
private int soLinger = Integer.MIN_VALUE;
138138
private Boolean keepAlive;
139139
private Boolean tcpNoDelay;
@@ -751,6 +751,7 @@ private boolean setTrafficClass(Socket sock) throws SocketException,
751751
return true;
752752
}
753753

754+
@Override
754755
public WireFormat getWireFormat() {
755756
return wireFormat;
756757
}

activemq-client/src/main/java/org/apache/activemq/transport/tcp/TcpTransportServer.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import java.util.concurrent.atomic.AtomicInteger;
4141

4242
import javax.net.ServerSocketFactory;
43+
import javax.net.ssl.SSLParameters;
4344
import javax.net.ssl.SSLServerSocket;
4445

4546
import org.apache.activemq.Service;
@@ -79,6 +80,7 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
7980
protected int minmumWireFormatVersion;
8081
protected boolean useQueueForAccept = true;
8182
protected boolean allowLinkStealing;
83+
protected boolean verifyHostName = true;
8284

8385
/**
8486
* trace=true -> the Transport stack where this TcpTransport object will be, will have a TransportLogger layer
@@ -172,6 +174,16 @@ private void configureServerSocket(ServerSocket socket) throws SocketException {
172174
// see: https://issues.apache.org/jira/browse/AMQ-4582
173175
//
174176
if (socket instanceof SSLServerSocket) {
177+
if (transportOptions.containsKey("verifyHostName")) {
178+
verifyHostName = Boolean.parseBoolean(transportOptions.get("verifyHostName").toString());
179+
}
180+
181+
if (verifyHostName) {
182+
SSLParameters sslParams = new SSLParameters();
183+
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
184+
((SSLServerSocket)this.serverSocket).setSSLParameters(sslParams);
185+
}
186+
175187
if (transportOptions.containsKey("enabledCipherSuites")) {
176188
Object cipherSuites = transportOptions.remove("enabledCipherSuites");
177189

@@ -180,6 +192,7 @@ private void configureServerSocket(ServerSocket socket) throws SocketException {
180192
"Invalid transport options {enabledCipherSuites=%s}", cipherSuites));
181193
}
182194
}
195+
183196
}
184197

185198
//AMQ-6599 - don't strip out set properties on the socket as we need to set them

activemq-mqtt/src/test/java/org/apache/activemq/transport/mqtt/auto/MQTTAutoSslAuthTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public static Collection<Object[]> data() {
5555
*/
5656
public MQTTAutoSslAuthTest(String protocol) {
5757
this.protocol = protocol;
58-
protocolConfig = "transport.needClientAuth=true";
58+
protocolConfig = "transport.needClientAuth=true&transport.verifyHostName=false&";
5959
}
6060

6161
@Override

activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompSslAuthTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ protected Socket createSocket() throws IOException {
5454

5555
@Override
5656
public void addOpenWireConnector() throws Exception {
57-
TransportConnector connector = brokerService.addConnector("ssl://0.0.0.0:0?needClientAuth=true");
58-
cf = new ActiveMQConnectionFactory(connector.getPublishableConnectString());
57+
TransportConnector connector = brokerService.addConnector("ssl://0.0.0.0:0?transport.needClientAuth=true&transport.verifyHostName=false");
58+
cf = new ActiveMQConnectionFactory(connector.getPublishableConnectString() + "?socket.verifyHostName=false");
5959
}
6060

6161
@Override
6262
protected String getAdditionalConfig() {
63-
return "?needClientAuth=true";
63+
return "?needClientAuth=true&transport.verifyHostName=false";
6464
}
6565

6666
// NOOP - These operations handled by jaas cert login module

activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/auto/StompAutoSslAuthTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ protected Socket createSocket() throws IOException {
102102

103103
@Override
104104
protected String getAdditionalConfig() {
105-
return "?transport.needClientAuth=true";
105+
return "?transport.needClientAuth=true&transport.verifyHostName=false";
106106
}
107107

108108
@Override

activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ4126Test.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public void testStompNIOSSLWithCertificate() throws Exception {
121121

122122
public void openwireConnectTo(String connectorName, String username, String password) throws Exception {
123123
URI brokerURI = broker.getConnectorByName(connectorName).getConnectUri();
124-
String uri = "ssl://" + brokerURI.getHost() + ":" + brokerURI.getPort();
124+
String uri = "ssl://" + brokerURI.getHost() + ":" + brokerURI.getPort() + "?socket.verifyHostName=false";
125125
ActiveMQSslConnectionFactory cf = new ActiveMQSslConnectionFactory(uri);
126126
cf.setTrustStore("org/apache/activemq/security/broker1.ks");
127127
cf.setTrustStorePassword("password");

activemq-unit-tests/src/test/java/org/apache/activemq/bugs/AMQ6599Test.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public void before() throws Exception {
7171
brokerService.setPersistent(false);
7272

7373
TransportConnector connector = brokerService.addConnector(protocol +
74-
"://localhost:0?transport.soTimeout=3500");
74+
"://localhost:0?transport.soTimeout=3500&transport.verifyHostName=false");
7575
connector.setName("connector");
7676
uri = connector.getPublishableConnectString();
7777

activemq-unit-tests/src/test/java/org/apache/activemq/network/NetworkReconnectSslNioTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ public void testForceReconnect() throws Exception {
4747
remote.setSslContext(sslContext);
4848
remote.setUseJmx(false);
4949
remote.setPersistent(false);
50-
final TransportConnector transportConnector = remote.addConnector("nio+ssl://0.0.0.0:0");
50+
final TransportConnector transportConnector = remote.addConnector("nio+ssl://0.0.0.0:0?transport.verifyHostName=false");
5151
remote.start();
5252

5353
BrokerService local = new BrokerService();
5454
local.setSslContext(sslContext);
5555
local.setUseJmx(false);
5656
local.setPersistent(false);
57-
final NetworkConnector networkConnector = local.addNetworkConnector("static:(" + remote.getTransportConnectorByScheme("nio+ssl").getPublishableConnectString().replace("nio+ssl", "ssl") + ")?useExponentialBackOff=false&initialReconnectDelay=10");
57+
final NetworkConnector networkConnector = local.addNetworkConnector("static:(" + remote.getTransportConnectorByScheme("nio+ssl").getPublishableConnectString().replace("nio+ssl", "ssl") + "?socket.verifyHostName=false" + ")?useExponentialBackOff=false&initialReconnectDelay=10");
5858
local.start();
5959

6060
assertTrue("Bridge created", Wait.waitFor(new Wait.Condition() {

activemq-unit-tests/src/test/java/org/apache/activemq/transport/auto/AutoSslAuthTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public void before() throws Exception {
7575
BrokerService brokerService = new BrokerService();
7676
brokerService.setPersistent(false);
7777

78-
TransportConnector connector = brokerService.addConnector(protocol + "://localhost:0?transport.needClientAuth=true");
78+
TransportConnector connector = brokerService.addConnector(protocol + "://localhost:0?transport.needClientAuth=true&transport.verifyHostName=false");
7979
connector.setName("auto");
8080
uri = connector.getPublishableConnectString();
8181

@@ -126,7 +126,7 @@ public AutoSslAuthTest(String protocol) {
126126
@Test(timeout = 60000)
127127
public void testConnect() throws Exception {
128128
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
129-
factory.setBrokerURL(uri);
129+
factory.setBrokerURL(uri + "?socket.verifyHostName=false");
130130

131131
//Create 5 connections to make sure all are properly set
132132
for (int i = 0; i < 5; i++) {

activemq-unit-tests/src/test/java/org/apache/activemq/transport/auto/AutoTransportConnectionsTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,14 @@ public void tearDown() throws Exception {
103103
}
104104

105105
public void configureConnectorAndStart(String bindAddress) throws Exception {
106+
if (bindAddress.contains("ssl")) {
107+
bindAddress += bindAddress.contains("?") ? "&transport.verifyHostName=false" : "?transport.verifyHostName=false";
108+
}
106109
connector = service.addConnector(bindAddress);
107110
connectionUri = connector.getPublishableConnectString();
111+
if (connectionUri.contains("ssl")) {
112+
connectionUri += connectionUri.contains("?") ? "&socket.verifyHostName=false" : "?socket.verifyHostName=false";
113+
}
108114
service.start();
109115
service.waitUntilStarted();
110116
}

0 commit comments

Comments
 (0)