Skip to content

Commit 3704151

Browse files
committed
Introduce SSLEngine configuration hook for NIO
Can be useful to pass in SSLParameters to the SSLEngine (e.g. for SNI support). This is specific to NIO, as SSLParameters can be passed in to the SSLSocket with the SocketConfigurator in blocking IO mode. Fixes #274
1 parent 03194db commit 3704151

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) 2017-Present Pivotal Software, Inc. All rights reserved.
2+
//
3+
// This software, the RabbitMQ Java client library, is triple-licensed under the
4+
// Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2
5+
// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
6+
// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL,
7+
// please see LICENSE-APACHE2.
8+
//
9+
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
10+
// either express or implied. See the LICENSE file for specific language governing
11+
// rights and limitations of this software.
12+
//
13+
// If you have any questions regarding licensing, please contact us at
14+
// info@rabbitmq.com.
15+
16+
package com.rabbitmq.client;
17+
18+
import javax.net.ssl.SSLEngine;
19+
import java.io.IOException;
20+
21+
public interface SslEngineConfigurator {
22+
23+
/**
24+
* Provides a hook to insert custom configuration of the {@link SSLEngine}s
25+
* used to connect to an AMQP server before they connect.
26+
* Note this is used only when NIO are in use.
27+
*/
28+
void configure(SSLEngine sslEngine) throws IOException;
29+
30+
}

src/main/java/com/rabbitmq/client/impl/nio/NioParams.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
import com.rabbitmq.client.DefaultSocketChannelConfigurator;
1919
import com.rabbitmq.client.SocketChannelConfigurator;
20+
import com.rabbitmq.client.SslEngineConfigurator;
2021

22+
import javax.net.ssl.SSLEngine;
23+
import java.io.IOException;
2124
import java.util.concurrent.ExecutorService;
2225
import java.util.concurrent.ThreadFactory;
2326

@@ -51,6 +54,12 @@ public class NioParams {
5154
/** the hook to configure the socket channel before it's open */
5255
private SocketChannelConfigurator socketChannelConfigurator = new DefaultSocketChannelConfigurator();
5356

57+
/** the hook to configure the SSL engine before the connection is open */
58+
private SslEngineConfigurator sslEngineConfigurator = new SslEngineConfigurator() {
59+
@Override
60+
public void configure(SSLEngine sslEngine) throws IOException { }
61+
};
62+
5463
public NioParams() {
5564
}
5665

@@ -62,6 +71,7 @@ public NioParams(NioParams nioParams) {
6271
setWriteQueueCapacity(nioParams.getWriteQueueCapacity());
6372
setNioExecutor(nioParams.getNioExecutor());
6473
setThreadFactory(nioParams.getThreadFactory());
74+
setSslEngineConfigurator(nioParams.getSslEngineConfigurator());
6575
}
6676

6777
public int getReadByteBufferSize() {
@@ -248,4 +258,21 @@ public void setSocketChannelConfigurator(SocketChannelConfigurator configurator)
248258
public SocketChannelConfigurator getSocketChannelConfigurator() {
249259
return socketChannelConfigurator;
250260
}
261+
262+
/**
263+
* Set the {@link SSLEngine} configurator.
264+
* This gets a change to "configure" the SSL engine
265+
* before the connection has been opened. This can be
266+
* used e.g. to set {@link javax.net.ssl.SSLParameters}.
267+
* The default implementation doesn't do anything.
268+
*
269+
* @param configurator the configurator to use
270+
*/
271+
public void setSslEngineConfigurator(SslEngineConfigurator configurator) {
272+
this.sslEngineConfigurator = configurator;
273+
}
274+
275+
public SslEngineConfigurator getSslEngineConfigurator() {
276+
return sslEngineConfigurator;
277+
}
251278
}

src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerFactory.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ public FrameHandler create(Address addr) throws IOException {
7070
if (ssl) {
7171
sslEngine = sslContext.createSSLEngine(addr.getHost(), portNumber);
7272
sslEngine.setUseClientMode(true);
73+
if (nioParams.getSslEngineConfigurator() != null) {
74+
nioParams.getSslEngineConfigurator().configure(sslEngine);
75+
}
7376
}
7477

7578
SocketAddress address = new InetSocketAddress(addr.getHost(), portNumber);

src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,17 @@
1616
package com.rabbitmq.client.test.ssl;
1717

1818
import com.rabbitmq.client.*;
19+
import com.rabbitmq.client.impl.nio.NioParams;
1920
import com.rabbitmq.client.test.BrokerTestCase;
20-
import org.junit.Assert;
2121
import org.junit.Test;
2222
import org.slf4j.LoggerFactory;
2323

24+
import javax.net.ssl.SSLEngine;
2425
import java.io.IOException;
2526
import java.util.concurrent.CountDownLatch;
2627
import java.util.concurrent.TimeUnit;
2728
import java.util.concurrent.TimeoutException;
29+
import java.util.concurrent.atomic.AtomicBoolean;
2830

2931
import static org.junit.Assert.assertTrue;
3032
import static org.junit.Assert.fail;
@@ -66,6 +68,32 @@ public void connectionGetConsume() throws Exception {
6668
assertTrue("Message has not been received", messagesReceived);
6769
}
6870

71+
@Test public void socketChannelConfigurator() throws Exception {
72+
ConnectionFactory connectionFactory = new ConnectionFactory();
73+
connectionFactory.useNio();
74+
connectionFactory.useSslProtocol();
75+
NioParams nioParams = new NioParams();
76+
final AtomicBoolean sslEngineHasBeenCalled = new AtomicBoolean(false);
77+
nioParams.setSslEngineConfigurator(new SslEngineConfigurator() {
78+
@Override
79+
public void configure(SSLEngine sslEngine) throws IOException {
80+
sslEngineHasBeenCalled.set(true);
81+
}
82+
});
83+
84+
connectionFactory.setNioParams(nioParams);
85+
86+
Connection connection = null;
87+
try {
88+
connection = connectionFactory.newConnection();
89+
assertTrue("The SSL engine configurator should have called", sslEngineHasBeenCalled.get());
90+
} finally {
91+
if (connection != null) {
92+
connection.close();
93+
}
94+
}
95+
}
96+
6997
private Connection basicGetBasicConsume(Connection connection, String queue, final CountDownLatch latch)
7098
throws IOException, TimeoutException {
7199
Channel channel = connection.createChannel();

0 commit comments

Comments
 (0)