From 4663fa507bbe7a847c2f876668d2a0788b32e721 Mon Sep 17 00:00:00 2001 From: andrea Date: Tue, 30 Jun 2015 22:44:22 +0200 Subject: [PATCH] Introduced WSS to fix issue #8 --- .../moquette/server/netty/NettyAcceptor.java | 59 +++++++++++++++---- distribution/src/main/resources/moquette.conf | 27 ++++++++- .../eclipse/moquette/commons/Constants.java | 1 + 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/broker/src/main/java/org/eclipse/moquette/server/netty/NettyAcceptor.java b/broker/src/main/java/org/eclipse/moquette/server/netty/NettyAcceptor.java index 1c8a37e5..f9879c63 100644 --- a/broker/src/main/java/org/eclipse/moquette/server/netty/NettyAcceptor.java +++ b/broker/src/main/java/org/eclipse/moquette/server/netty/NettyAcceptor.java @@ -104,7 +104,17 @@ public class NettyAcceptor implements ServerAcceptor { initializePlainTCPTransport(messaging, props); initializeWebSocketTransport(messaging, props); - initializeSSLTCPTransport(messaging, props); + String sslTcpPortProp = props.getProperty(Constants.SSL_PORT_PROPERTY_NAME); + String wssPortProp = props.getProperty(Constants.WSS_PORT_PROPERTY_NAME); + if (sslTcpPortProp != null || wssPortProp != null) { + SslHandler sslHandler = initSSLHandler(props); + if (sslHandler == null) { + LOG.error("Can't initialize SSLHandler layer! Exiting, check your configuration of jks"); + return; + } + initializeSSLTCPTransport(messaging, props, sslHandler); + initializeWSSTransport(messaging, props, sslHandler); + } } private void initFactory(String host, int port, final PipelineInitializer pipeliner) { @@ -191,8 +201,7 @@ public class NettyAcceptor implements ServerAcceptor { }); } - - private void initializeSSLTCPTransport(IMessaging messaging, Properties props) throws IOException { + private void initializeSSLTCPTransport(IMessaging messaging, Properties props, final SslHandler sslHandler) throws IOException { String sslPortProp = props.getProperty(Constants.SSL_PORT_PROPERTY_NAME); if (sslPortProp == null) { //Do nothing no SSL configured @@ -201,11 +210,7 @@ public class NettyAcceptor implements ServerAcceptor { } int sslPort = Integer.parseInt(sslPortProp); - final SslHandler sslHandler = initSSLHandler(sslPort, props); - if (sslHandler == null) { - LOG.error("Can't initialize SSLHandler layer! Exiting, check your configuration of jks"); - return; - } + LOG.info("Starting SSL on port {}", sslPort); final NettyMQTTHandler handler = new NettyMQTTHandler(); handler.setMessaging(messaging); @@ -226,6 +231,38 @@ public class NettyAcceptor implements ServerAcceptor { }); } + private void initializeWSSTransport(IMessaging messaging, Properties props, final SslHandler sslHandler) throws IOException { + String sslPortProp = props.getProperty(Constants.WSS_PORT_PROPERTY_NAME); + if (sslPortProp == null) { + //Do nothing no SSL configured + LOG.info("SSL is disabled"); + return; + } + int sslPort = Integer.parseInt(sslPortProp); + final NettyMQTTHandler handler = new NettyMQTTHandler(); + handler.setMessaging(messaging); + String host = props.getProperty(Constants.HOST_PROPERTY_NAME); + initFactory(host, sslPort, new PipelineInitializer() { + @Override + void init(ChannelPipeline pipeline) throws Exception { + pipeline.addLast("ssl", sslHandler); + pipeline.addLast("httpEncoder", new HttpResponseEncoder()); + pipeline.addLast("httpDecoder", new HttpRequestDecoder()); + pipeline.addLast("aggregator", new HttpObjectAggregator(65536)); + pipeline.addLast("webSocketHandler", new WebSocketServerProtocolHandler("/mqtt", "mqttv3.1, mqttv3.1.1")); + pipeline.addLast("ws2bytebufDecoder", new WebSocketFrameToByteBufDecoder()); + pipeline.addLast("bytebuf2wsEncoder", new ByteBufToWebSocketFrameEncoder()); + pipeline.addFirst("idleStateHandler", new IdleStateHandler(0, 0, Constants.DEFAULT_CONNECT_TIMEOUT)); + pipeline.addAfter("idleStateHandler", "idleEventHandler", new MoquetteIdleTimoutHandler()); + pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector)); + pipeline.addLast("decoder", new MQTTDecoder()); + pipeline.addLast("encoder", new MQTTEncoder()); + pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector)); + pipeline.addLast("handler", handler); + } + }); + } + public void close() { if (m_workerGroup == null) { throw new IllegalStateException("Invoked close on an Acceptor that wasn't initialized"); @@ -244,9 +281,9 @@ public class NettyAcceptor implements ServerAcceptor { } - private SslHandler initSSLHandler(int sslPort, Properties props) { + private SslHandler initSSLHandler(Properties props) { final String jksPath = props.getProperty(Constants.JKS_PATH_PROPERTY_NAME); - LOG.info("Starting SSL on port {} using keystore at {}", sslPort, jksPath); + LOG.info("Starting SSL using keystore at {}", jksPath); if (jksPath == null || jksPath.isEmpty()) { //key_store_password or key_manager_password are empty LOG.warn("You have configured the SSL port but not the jks_path, SSL not started"); @@ -268,8 +305,6 @@ public class NettyAcceptor implements ServerAcceptor { return null; } - LOG.info("Starting SSL on port {} using keystore at {}", sslPort, jksPath); - try { InputStream jksInputStream = jksDatastore(jksPath); SSLContext serverContext = SSLContext.getInstance("TLS"); diff --git a/distribution/src/main/resources/moquette.conf b/distribution/src/main/resources/moquette.conf index 43193e76..ab7a1c23 100644 --- a/distribution/src/main/resources/moquette.conf +++ b/distribution/src/main/resources/moquette.conf @@ -9,6 +9,31 @@ port 1883 websocket_port 8080 +#********************************************************************* +# Secure Websocket port (wss) +# decommend this to enable wss +#********************************************************************* +# secure_websocket_port 8883 + +#********************************************************************* +# SSL tcp part +# jks_path: define the file that contains the Java Key Store, +# relative to the current broker home +# +# key_store_password: is the password used to open the keystore +# +# key_manager_password: is the password used to manage the alias in the +# keystore +#********************************************************************* +# ssl_port 8883 +#jks_path serverkeystore.jks +#key_store_password passw0rdsrv +#key_manager_password passw0rdsrv + +#********************************************************************* +# The interface to bind the server +# 0.0.0.0 means "any" +#********************************************************************* host 0.0.0.0 #********************************************************************* @@ -33,4 +58,4 @@ allow_anonymous true # authenticated client connection. It's relative to moquette home dir # defined by the system property moquette.path #********************************************************************* -password_file config/password_file.conf \ No newline at end of file +password_file config/password_file.conf diff --git a/parser_commons/src/main/java/org/eclipse/moquette/commons/Constants.java b/parser_commons/src/main/java/org/eclipse/moquette/commons/Constants.java index 46008caf..26ad4759 100644 --- a/parser_commons/src/main/java/org/eclipse/moquette/commons/Constants.java +++ b/parser_commons/src/main/java/org/eclipse/moquette/commons/Constants.java @@ -32,6 +32,7 @@ public class Constants { public static final String PORT_PROPERTY_NAME = "port"; public static final String HOST_PROPERTY_NAME = "host"; public static final String WEB_SOCKET_PORT_PROPERTY_NAME = "websocket_port"; + public static final String WSS_PORT_PROPERTY_NAME = "secure_websocket_port"; public static final String SSL_PORT_PROPERTY_NAME = "ssl_port"; public static final String JKS_PATH_PROPERTY_NAME = "jks_path"; public static final String KEY_STORE_PASSWORD_PROPERTY_NAME = "key_store_password";