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 504a2aad..6fbea90a 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 @@ -36,8 +36,8 @@ import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.ssl.SslHandler; import io.netty.handler.timeout.IdleStateHandler; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; +import java.net.URL; import java.security.KeyStore; import java.util.List; @@ -114,7 +114,12 @@ public class NettyAcceptor implements ServerAcceptor { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); - pipeliner.init(pipeline); + try { + pipeliner.init(pipeline); + } catch (Throwable th) { + LOG.error("Severe error during pipeline creation", th); + throw th; + } } }) .option(ChannelOption.SO_BACKLOG, 128) @@ -215,13 +220,14 @@ public class NettyAcceptor implements ServerAcceptor { int sslPort = Integer.parseInt(sslPortProp); String host = props.getProperty(Constants.HOST_PROPERTY_NAME); + LOG.info("Starting SSL on port {} using keystore at {}", sslPort, jksPath); final NettyMQTTHandler handler = new NettyMQTTHandler(); handler.setMessaging(messaging); initFactory(host, sslPort, new PipelineInitializer() { @Override void init(ChannelPipeline pipeline) throws Exception { - InputStream jksInputStream = getClass().getClassLoader().getResourceAsStream(jksPath); + InputStream jksInputStream = jksDatastore(jksPath); SSLContext serverContext = SSLContext.getInstance("TLS"); final KeyStore ks = KeyStore.getInstance("JKS"); ks.load(jksInputStream, keyStorePassword.toCharArray()); @@ -260,5 +266,21 @@ public class NettyAcceptor implements ServerAcceptor { //LOG.info(String.format("Bytes read: %d, bytes wrote: %d", metrics.readBytes(), metrics.wroteBytes())); LOG.info("Msg read: {}, msg wrote: {}", metrics.messagesRead(), metrics.messagesWrote()); } + + private InputStream jksDatastore(String jksPath) throws FileNotFoundException { + URL jksUrl = getClass().getClassLoader().getResource(jksPath); + if (jksUrl != null) { + LOG.info("Starting with jks at {}, jks normal {}", jksUrl.toExternalForm(), jksUrl); + return getClass().getClassLoader().getResourceAsStream(jksPath); + } + LOG.info("jks not found in bundled resources, try on the filesystem"); + File jksFile = new File(jksPath); + if (jksFile.exists()) { + LOG.info("Using {} ", jksFile.getAbsolutePath()); + return new FileInputStream(jksFile); + } + LOG.warn("File {} doesn't exists", jksFile.getAbsolutePath()); + return null; + } } diff --git a/tools_scripts/integration/sslSimplePublisher.groovy b/tools_scripts/integration/sslSimplePublisher.groovy index e69de29b..8bac459c 100644 --- a/tools_scripts/integration/sslSimplePublisher.groovy +++ b/tools_scripts/integration/sslSimplePublisher.groovy @@ -0,0 +1,53 @@ +//@GrabResolver(name='Paho', root='https://repo.eclipse.org/content/repositories/paho-snapshots/') +//@Grab(group='org.eclipse.paho', module='org.eclipse.paho.client.mqttv3', version='1.0.1-SNAPSHOT') +@GrabResolver(name='Paho', root='https://repo.eclipse.org/content/repositories/paho-releases/') +@Grab(group='org.eclipse.paho', module='mqtt-client', version='0.4.0') + +import org.eclipse.paho.client.mqttv3.MqttClient +import org.eclipse.paho.client.mqttv3.MqttMessage +import org.eclipse.paho.client.mqttv3.MqttConnectOptions +import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence + +import javax.net.ssl.KeyManagerFactory +import javax.net.ssl.SSLContext +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.TrustManager +import javax.net.ssl.TrustManagerFactory +import java.security.KeyStore + +SSLSocketFactory configureSSLSocketFactory() { + KeyStore ks = KeyStore.getInstance("JKS"); + println "using client key store at: " + new File("clientkeystore.jks").absolutePath + InputStream jksInputStream = new FileInputStream("clientkeystore.jks") +// InputStream jksInputStream = getClass().getClassLoader().getResourceAsStream("clientkeystore.jks"); + ks.load(jksInputStream, "passw0rdcli".toCharArray()); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(ks, "passw0rd".toCharArray()); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(ks); + + SSLContext sc = SSLContext.getInstance("TLS"); + TrustManager[] trustManagers = tmf.getTrustManagers(); + sc.init(kmf.getKeyManagers(), trustManagers, null); + + SSLSocketFactory ssf = sc.getSocketFactory(); + return ssf; +} + +String tmpDir = System.getProperty("java.io.tmpdir") +MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(tmpDir) + +MqttClient client = new MqttClient("ssl://localhost:8883", "SSLClientTest", dataStore) +SSLSocketFactory ssf = configureSSLSocketFactory() +MqttConnectOptions options = new MqttConnectOptions() +options.setSocketFactory(ssf) +client.connect(options) +MqttMessage message = new MqttMessage('Hello world!!'.bytes) +message.setQos(2) +print "publishing.." +client.getTopic("log").publish(message) +println "published" +client.disconnect() +println "disconnected" \ No newline at end of file