This commit is contained in:
Clebert Suconic 2018-05-25 12:30:16 -04:00
commit fbcee58e8c
4 changed files with 212 additions and 28 deletions

View File

@ -130,8 +130,10 @@ public class NettyConnector extends AbstractConnector {
// Constants -----------------------------------------------------
public static final String JAVAX_KEYSTORE_PATH_PROP_NAME = "javax.net.ssl.keyStore";
public static final String JAVAX_KEYSTORE_PASSWORD_PROP_NAME = "javax.net.ssl.keyStorePassword";
public static final String JAVAX_KEYSTORE_PROVIDER_PROP_NAME = "javax.net.ssl.keyStoreType";
public static final String JAVAX_TRUSTSTORE_PATH_PROP_NAME = "javax.net.ssl.trustStore";
public static final String JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME = "javax.net.ssl.trustStorePassword";
public static final String JAVAX_TRUSTSTORE_PROVIDER_PROP_NAME = "javax.net.ssl.trustStoreType";
public static final String ACTIVEMQ_KEYSTORE_PROVIDER_PROP_NAME = "org.apache.activemq.ssl.keyStoreProvider";
public static final String ACTIVEMQ_KEYSTORE_PATH_PROP_NAME = "org.apache.activemq.ssl.keyStore";
public static final String ACTIVEMQ_KEYSTORE_PASSWORD_PROP_NAME = "org.apache.activemq.ssl.keyStorePassword";
@ -224,6 +226,8 @@ public class NettyConnector extends AbstractConnector {
private boolean trustAll;
private boolean forceSSLParameters;
private String sniHost;
private String kerb5Config;
@ -358,6 +362,8 @@ public class NettyConnector extends AbstractConnector {
trustAll = ConfigurationHelper.getBooleanProperty(TransportConstants.TRUST_ALL_PROP_NAME, TransportConstants.DEFAULT_TRUST_ALL, configuration);
forceSSLParameters = ConfigurationHelper.getBooleanProperty(TransportConstants.FORCE_SSL_PARAMETERS, TransportConstants.DEFAULT_FORCE_SSL_PARAMETERS, configuration);
sslProvider = ConfigurationHelper.getStringProperty(TransportConstants.SSL_PROVIDER, TransportConstants.DEFAULT_SSL_PROVIDER, configuration);
sniHost = ConfigurationHelper.getStringProperty(TransportConstants.SNIHOST_PROP_NAME, TransportConstants.DEFAULT_SNIHOST_CONFIG, configuration);
@ -500,13 +506,14 @@ public class NettyConnector extends AbstractConnector {
if (sslEnabled) {
// HORNETQ-680 - override the server-side config if client-side system properties are set
realKeyStorePath = Stream.of(System.getProperty(JAVAX_KEYSTORE_PATH_PROP_NAME), System.getProperty(ACTIVEMQ_KEYSTORE_PATH_PROP_NAME), keyStorePath).map(v -> useDefaultSslContext ? keyStorePath : v).filter(Objects::nonNull).findFirst().orElse(null);
realKeyStorePassword = Stream.of(System.getProperty(JAVAX_KEYSTORE_PASSWORD_PROP_NAME), System.getProperty(ACTIVEMQ_KEYSTORE_PASSWORD_PROP_NAME), keyStorePassword).map(v -> useDefaultSslContext ? keyStorePassword : v).filter(Objects::nonNull).findFirst().orElse(null);
realKeyStoreProvider = Stream.of(System.getProperty(ACTIVEMQ_KEYSTORE_PROVIDER_PROP_NAME), keyStoreProvider).map(v -> useDefaultSslContext ? keyStoreProvider : v).filter(Objects::nonNull).findFirst().orElse(null);
realKeyStorePath = forceSSLParameters && keyStorePath != null ? keyStorePath : Stream.of(System.getProperty(JAVAX_KEYSTORE_PATH_PROP_NAME), System.getProperty(ACTIVEMQ_KEYSTORE_PATH_PROP_NAME), keyStorePath).map(v -> useDefaultSslContext ? keyStorePath : v).filter(Objects::nonNull).findFirst().orElse(null);
realKeyStorePassword = forceSSLParameters && keyStorePassword != null ? keyStorePassword : Stream.of(System.getProperty(JAVAX_KEYSTORE_PASSWORD_PROP_NAME), System.getProperty(ACTIVEMQ_KEYSTORE_PASSWORD_PROP_NAME), keyStorePassword).map(v -> useDefaultSslContext ? keyStorePassword : v).filter(Objects::nonNull).findFirst().orElse(null);
realKeyStoreProvider = forceSSLParameters && keyStoreProvider != null ? keyStoreProvider : Stream.of(System.getProperty(JAVAX_KEYSTORE_PROVIDER_PROP_NAME),System.getProperty(ACTIVEMQ_KEYSTORE_PROVIDER_PROP_NAME), keyStoreProvider).map(v -> useDefaultSslContext ? keyStoreProvider : v).filter(Objects::nonNull).findFirst().orElse(null);
realTrustStorePath = forceSSLParameters && trustStorePath != null ? trustStorePath : Stream.of(System.getProperty(JAVAX_TRUSTSTORE_PATH_PROP_NAME), System.getProperty(ACTIVEMQ_TRUSTSTORE_PATH_PROP_NAME), trustStorePath).map(v -> useDefaultSslContext ? trustStorePath : v).filter(Objects::nonNull).findFirst().orElse(null);
realTrustStorePassword = forceSSLParameters && trustStorePassword != null ? trustStorePassword : Stream.of(System.getProperty(JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME), System.getProperty(ACTIVEMQ_TRUSTSTORE_PASSWORD_PROP_NAME), trustStorePassword).map(v -> useDefaultSslContext ? trustStorePassword : v).filter(Objects::nonNull).findFirst().orElse(null);
realTrustStoreProvider = forceSSLParameters && trustStoreProvider != null ? trustStoreProvider : Stream.of(System.getProperty(JAVAX_TRUSTSTORE_PROVIDER_PROP_NAME), System.getProperty(ACTIVEMQ_TRUSTSTORE_PROVIDER_PROP_NAME), trustStoreProvider).map(v -> useDefaultSslContext ? trustStoreProvider : v).filter(Objects::nonNull).findFirst().orElse(null);
realTrustStorePath = Stream.of(System.getProperty(JAVAX_TRUSTSTORE_PATH_PROP_NAME), System.getProperty(ACTIVEMQ_TRUSTSTORE_PATH_PROP_NAME), trustStorePath).map(v -> useDefaultSslContext ? trustStorePath : v).filter(Objects::nonNull).findFirst().orElse(null);
realTrustStorePassword = Stream.of(System.getProperty(JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME), System.getProperty(ACTIVEMQ_TRUSTSTORE_PASSWORD_PROP_NAME), trustStorePassword).map(v -> useDefaultSslContext ? trustStorePassword : v).filter(Objects::nonNull).findFirst().orElse(null);
realTrustStoreProvider = Stream.of(System.getProperty(ACTIVEMQ_TRUSTSTORE_PROVIDER_PROP_NAME), trustStoreProvider).map(v -> useDefaultSslContext ? trustStoreProvider : v).filter(Objects::nonNull).findFirst().orElse(null);
} else {
realKeyStorePath = null;
realKeyStoreProvider = null;

View File

@ -109,6 +109,8 @@ public class TransportConstants {
public static final String TRUST_ALL_PROP_NAME = "trustAll";
public static final String FORCE_SSL_PARAMETERS = "forceSSLParameters";
public static final String SNIHOST_PROP_NAME = "sniHost";
public static final String BACKLOG_PROP_NAME = "backlog";
@ -213,6 +215,8 @@ public class TransportConstants {
public static final boolean DEFAULT_TRUST_ALL = false;
public static final boolean DEFAULT_FORCE_SSL_PARAMETERS = false;
public static final boolean DEFAULT_USE_DEFAULT_SSL_CONTEXT = false;
public static final boolean DEFAULT_TCP_NODELAY = true;
@ -361,6 +365,7 @@ public class TransportConstants {
allowableConnectorKeys.add(TransportConstants.ENABLED_PROTOCOLS_PROP_NAME);
allowableConnectorKeys.add(TransportConstants.VERIFY_HOST_PROP_NAME);
allowableConnectorKeys.add(TransportConstants.TRUST_ALL_PROP_NAME);
allowableConnectorKeys.add(TransportConstants.FORCE_SSL_PARAMETERS);
allowableConnectorKeys.add(TransportConstants.TCP_NODELAY_PROPNAME);
allowableConnectorKeys.add(TransportConstants.TCP_SENDBUFFER_SIZE_PROPNAME);
allowableConnectorKeys.add(TransportConstants.TCP_RECEIVEBUFFER_SIZE_PROPNAME);

View File

@ -443,6 +443,14 @@ following additional properties:
primarily for testing purposes only and should not be used in production.
Valid values are `true` or `false`. Default is `false`.
- `forceSSLParameters`
When used on a `connector` any SSL settings that are set as parameters on the connector will
be used instead of JVM system properties including both javax.net.ssl and ActiveMQ system properties
to configure the SSL context for this connector.
Valid values are `true` or `false`. Default is `false`.
- `useDefaultSslContext`

View File

@ -18,13 +18,17 @@ package org.apache.activemq.artemis.tests.unit.core.remoting.impl.netty;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector;
import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
import org.apache.activemq.artemis.core.server.ActiveMQComponent;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.spi.core.remoting.BufferHandler;
import org.apache.activemq.artemis.spi.core.remoting.ClientConnectionLifeCycleListener;
import org.apache.activemq.artemis.spi.core.remoting.ClientProtocolManager;
@ -32,10 +36,40 @@ import org.apache.activemq.artemis.spi.core.remoting.Connection;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class NettyConnectorTest extends ActiveMQTestBase {
private ActiveMQServer server;
private ExecutorService executorService;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
executorService = Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory());
Map<String, Object> params = new HashMap<>();
params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
params.put(TransportConstants.SSL_PROVIDER, TransportConstants.OPENSSL_PROVIDER);
params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, "openssl-server-side-keystore.jks");
params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, "secureexample");
params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, "openssl-server-side-truststore.jks");
params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample");
params.put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
ConfigurationImpl config = createBasicConfig().addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params, "nettySSL"));
server = createServer(false, config);
server.start();
waitForServerToStart(server);
}
@Override
public void tearDown() throws Exception {
executorService.shutdown();
super.tearDown();
}
private ClientConnectionLifeCycleListener listener = new ClientConnectionLifeCycleListener() {
@Override
public void connectionException(final Object connectionID, final ActiveMQException me) {
@ -99,61 +133,191 @@ public class NettyConnectorTest extends ActiveMQTestBase {
}
}
/**
* that java system properties are read
*/
@Test
public void testJavaSystemPropertyOverrides() throws Exception {
public void testJavaSystemProperty() throws Exception {
BufferHandler handler = new BufferHandler() {
@Override
public void bufferReceived(final Object connectionID, final ActiveMQBuffer buffer) {
}
};
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PATH_PROP_NAME, "openssl-client-side-keystore.jks");
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PASSWORD_PROP_NAME, "secureexample");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PATH_PROP_NAME, "openssl-client-side-truststore.jks");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample");
Map<String, Object> params = new HashMap<>();
params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, "bad path");
params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, "bad password");
params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, "bad path");
params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, "bad password");
NettyConnector connector = new NettyConnector(params, handler, listener, Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newScheduledThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory()));
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PATH_PROP_NAME, "client-side-keystore.jks");
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PASSWORD_PROP_NAME, "secureexample");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PATH_PROP_NAME, "client-side-truststore.jks");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample");
NettyConnector connector = new NettyConnector(params, handler, listener, executorService, Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newScheduledThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory()));
connector.start();
Assert.assertTrue(connector.isStarted());
Connection c = connector.createConnection();
assertNotNull(c);
c.close();
connector.close();
Assert.assertFalse(connector.isStarted());
}
@Test
public void testActiveMQSystemPropertyOverrides() throws Exception {
public void testOverridesJavaSystemPropertyFail() throws Exception {
BufferHandler handler = new BufferHandler() {
@Override
public void bufferReceived(final Object connectionID, final ActiveMQBuffer buffer) {
}
};
Map<String, Object> params = new HashMap<>();
params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, "bad path");
params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, "bad password");
params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, "bad path");
params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, "bad password");
NettyConnector connector = new NettyConnector(params, handler, listener, Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newScheduledThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory()));
//bad system properties will override the transport constants
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PATH_PROP_NAME, "bad path");
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PASSWORD_PROP_NAME, "bad password");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PATH_PROP_NAME, "bad path");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME, "bad password");
System.setProperty(NettyConnector.ACTIVEMQ_KEYSTORE_PATH_PROP_NAME, "client-side-keystore.jks");
Map<String, Object> params = new HashMap<>();
params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, "openssl-client-side-keystore.jks");
params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, "secureexample");
params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME,"openssl-client-side-truststore.jks");
params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample");
NettyConnector connector = new NettyConnector(params, handler, listener, executorService, Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newScheduledThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory()));
connector.start();
Assert.assertTrue(connector.isStarted());
Connection c = connector.createConnection();
//Should have failed because SSL props override transport config options
assertNull(c);
connector.close();
Assert.assertFalse(connector.isStarted());
}
@Test
public void testOverridesJavaSystemProperty() throws Exception {
BufferHandler handler = new BufferHandler() {
@Override
public void bufferReceived(final Object connectionID, final ActiveMQBuffer buffer) {
}
};
//system properties will override the bad transport constants
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PATH_PROP_NAME, "openssl-client-side-keystore.jks");
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PASSWORD_PROP_NAME, "secureexample");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PATH_PROP_NAME, "openssl-client-side-truststore.jks");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample");
Map<String, Object> params = new HashMap<>();
params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, "bad path");
params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, "bad password");
params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, "bad path");
params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, "bad password");
NettyConnector connector = new NettyConnector(params, handler, listener, executorService, Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newScheduledThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory()));
connector.start();
Assert.assertTrue(connector.isStarted());
Connection c = connector.createConnection();
//Should not fail because SSL props override transport config options
assertNotNull(c);
c.close();
connector.close();
Assert.assertFalse(connector.isStarted());
}
@Test
public void testOverridesJavaSystemPropertyForceSSLParameters() throws Exception {
BufferHandler handler = new BufferHandler() {
@Override
public void bufferReceived(final Object connectionID, final ActiveMQBuffer buffer) {
}
};
//bad system properties will override the transport constants
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PATH_PROP_NAME, "bad path");
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PASSWORD_PROP_NAME, "bad password");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PATH_PROP_NAME, "bad path");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME, "bad password");
Map<String, Object> params = new HashMap<>();
params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
params.put(TransportConstants.FORCE_SSL_PARAMETERS, true);
params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, "openssl-client-side-keystore.jks");
params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, "secureexample");
params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME,"openssl-client-side-truststore.jks");
params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample");
NettyConnector connector = new NettyConnector(params, handler, listener, executorService, Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newScheduledThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory()));
connector.start();
Assert.assertTrue(connector.isStarted());
Connection c = connector.createConnection();
//Should not fail because forceSSLParameters is set
assertNotNull(c);
c.close();
connector.close();
Assert.assertFalse(connector.isStarted());
}
@Test
public void tesActiveMQSystemProperties() throws Exception {
BufferHandler handler = new BufferHandler() {
@Override
public void bufferReceived(final Object connectionID, final ActiveMQBuffer buffer) {
}
};
Map<String, Object> params = new HashMap<>();
params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
NettyConnector connector = new NettyConnector(params, handler, listener, executorService, Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newScheduledThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory()));
System.setProperty(NettyConnector.ACTIVEMQ_KEYSTORE_PATH_PROP_NAME, "openssl-client-side-keystore.jks");
System.setProperty(NettyConnector.ACTIVEMQ_KEYSTORE_PASSWORD_PROP_NAME, "secureexample");
System.setProperty(NettyConnector.ACTIVEMQ_TRUSTSTORE_PATH_PROP_NAME, "client-side-truststore.jks");
System.setProperty(NettyConnector.ACTIVEMQ_TRUSTSTORE_PATH_PROP_NAME, "openssl-client-side-truststore.jks");
System.setProperty(NettyConnector.ACTIVEMQ_TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample");
connector.start();
Assert.assertTrue(connector.isStarted());
Connection c = connector.createConnection();
assertNotNull(c);
connector.close();
Assert.assertFalse(connector.isStarted());
}
@Test
public void testSystemPropertyOverridesActiveMQ() throws Exception {
BufferHandler handler = new BufferHandler() {
@Override
public void bufferReceived(final Object connectionID, final ActiveMQBuffer buffer) {
}
};
Map<String, Object> params = new HashMap<>();
params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
NettyConnector connector = new NettyConnector(params, handler, listener, executorService, Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory()), Executors.newScheduledThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory()));
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PATH_PROP_NAME, "openssl-client-side-keystore.jks");
System.setProperty(NettyConnector.JAVAX_KEYSTORE_PASSWORD_PROP_NAME, "secureexample");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PATH_PROP_NAME, "openssl-client-side-truststore.jks");
System.setProperty(NettyConnector.JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample");
System.setProperty(NettyConnector.ACTIVEMQ_KEYSTORE_PATH_PROP_NAME, "bad path");
System.setProperty(NettyConnector.ACTIVEMQ_KEYSTORE_PASSWORD_PROP_NAME, "bad password");
System.setProperty(NettyConnector.ACTIVEMQ_TRUSTSTORE_PATH_PROP_NAME, "bad path");
System.setProperty(NettyConnector.ACTIVEMQ_TRUSTSTORE_PASSWORD_PROP_NAME, "bad password");
connector.start();
Assert.assertTrue(connector.isStarted());
Connection c = connector.createConnection();
assertNotNull(c);
connector.close();
Assert.assertFalse(connector.isStarted());
}