diff --git a/nodes/core/io/05-tls.html b/nodes/core/io/05-tls.html
new file mode 100644
index 000000000..05015f3ec
--- /dev/null
+++ b/nodes/core/io/05-tls.html
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
diff --git a/nodes/core/io/05-tls.js b/nodes/core/io/05-tls.js
new file mode 100644
index 000000000..9914438dc
--- /dev/null
+++ b/nodes/core/io/05-tls.js
@@ -0,0 +1,69 @@
+/**
+ * Copyright 2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+var fs = require('fs');
+module.exports = function(RED) {
+ "use strict";
+
+ function TLSConfig(n) {
+ RED.nodes.createNode(this,n);
+ this.valid = true;
+ var certPath = n.cert.trim();
+ var keyPath = n.key.trim();
+ var caPath = n.ca.trim();
+
+ if ( (certPath.length > 0) !== (keyPath.length > 0)) {
+ this.valid = false;
+ this.error(RED._("tls.error.missing-file"));
+ return;
+ }
+ this.verifyservercert = n.verifyservercert;
+
+ try {
+ if (certPath) {
+ this.cert = fs.readFileSync(certPath);
+ }
+ if (keyPath) {
+ this.key = fs.readFileSync(keyPath);
+ }
+ if (caPath) {
+ this.ca = fs.readFileSync(caPath);
+ }
+ } catch(err) {
+ this.valid = false;
+ this.error(err.toString());
+ return;
+ }
+ }
+ RED.nodes.registerType("tls-config",TLSConfig);
+
+ TLSConfig.prototype.addTLSOptions = function(opts) {
+ if (this.valid) {
+ if (this.key) {
+ opts.key = this.key;
+ }
+ if (this.cert) {
+ opts.cert = this.cert;
+ }
+ if (this.ca) {
+ opts.ca = this.ca;
+ }
+ opts.rejectUnauthorized = this.verifyservercert;
+ }
+ return opts;
+ }
+
+}
diff --git a/nodes/core/io/10-mqtt.html b/nodes/core/io/10-mqtt.html
index 65674f6bc..c80818c26 100644
--- a/nodes/core/io/10-mqtt.html
+++ b/nodes/core/io/10-mqtt.html
@@ -150,11 +150,17 @@
+
@@ -240,6 +238,7 @@
defaults: {
broker: {value:"",required:true},
port: {value:1883,required:true,validate:RED.validators.number()},
+ tls: {type:"tls-config",required: false},
clientid: { value:"", validate: function(v) {
if ($("#node-config-input-clientid").length) {
// Currently editing the node
@@ -303,10 +302,6 @@
this.usetls = false;
$("#node-config-input-usetls").prop("checked",false);
}
- if (typeof this.verifyservercert === 'undefined'){
- this.verifyservercert = true;
- $("#node-config-input-verifyservercert").prop("checked",true);
- }
if (typeof this.compatmode === 'undefined'){
this.compatmode = true;
$("#node-config-input-compatmode").prop('checked', true);
@@ -326,11 +321,9 @@
function updateTLSOptions() {
if ($("#node-config-input-usetls").is(':checked')) {
- $("#node-config-input-verifyservercert").prop("disabled", false);
- $("#node-config-input-verifyservercert").next().css("color","");
+ $("#node-config-row-tls").show();
} else {
- $("#node-config-input-verifyservercert").prop("disabled", true);
- $("#node-config-input-verifyservercert").next().css("color","#aaa");
+ $("#node-config-row-tls").hide();
}
}
updateTLSOptions();
@@ -350,6 +343,11 @@
$("#node-config-input-cleansession").on("click",function() {
updateClientId();
});
+ },
+ oneditsave: function() {
+ if (!$("#node-config-input-usetls").is(':checked')) {
+ $("#node-config-input-tls").val("");
+ }
}
});
diff --git a/nodes/core/io/10-mqtt.js b/nodes/core/io/10-mqtt.js
index 99b1a4244..365cdf099 100644
--- a/nodes/core/io/10-mqtt.js
+++ b/nodes/core/io/10-mqtt.js
@@ -114,8 +114,18 @@ module.exports = function(RED) {
this.options.protocolId = 'MQIsdp';
this.options.protocolVersion = 3;
}
-
- this.options.rejectUnauthorized = (this.verifyservercert == "true" || this.verifyservercert === true)
+ if (this.usetls && n.tls) {
+ var tlsNode = RED.nodes.getNode(n.tls);
+ if (tlsNode) {
+ tlsNode.addTLSOptions(this.options);
+ }
+ }
+ // If there's no rejectUnauthorized already, then this could be an
+ // old config where this option was provided on the broker node and
+ // not the tls node
+ if (typeof this.options.rejectUnauthorized === 'undefined') {
+ this.options.rejectUnauthorized = (this.verifyservercert == "true" || this.verifyservercert === true);
+ }
if (n.willTopic) {
this.options.will = {
@@ -284,6 +294,9 @@ module.exports = function(RED) {
done();
});
this.client.end();
+ } if (this.connecting) {
+ node.client.end();
+ done();
} else {
done();
}
diff --git a/nodes/core/io/21-httprequest.html b/nodes/core/io/21-httprequest.html
index 9bfaff2ce..32efa12a2 100644
--- a/nodes/core/io/21-httprequest.html
+++ b/nodes/core/io/21-httprequest.html
@@ -1,5 +1,5 @@