Code

Add TLS support
authorJan-Piet Mens <jpmens@gmail.com>
Tue, 17 Nov 2015 13:44:20 +0000 (14:44 +0100)
committerJan-Piet Mens <jpmens@gmail.com>
Wed, 18 Nov 2015 18:12:59 +0000 (19:12 +0100)
addresses #1265
protect for newer libmosquitto
address octo's comments

src/collectd.conf.pod
src/mqtt.c

index 8a508089d2589ba35994f159fef1098d7c128563..ee05c3a8ee8cdebc7279fa29aafac38b9b014820 100644 (file)
@@ -3347,6 +3347,33 @@ Configures the topic(s) to subscribe to. You can use the single level C<+> and
 multi level C<#> wildcards. Defaults to B<collectd/#>, i.e. all topics beneath
 the B<collectd> branch.
 
+=item B<CACertificateFile> I<file>
+
+Path to the PEM-encoded CA certificate file. Setting this option enables TLS
+communication with the MQTT broker, and as such, B<Port> should be the TLS-enabled
+port of the MQTT broker.
+
+=item B<CertificateFile> I<file>
+
+Path to the PEM-encoded certificate file to use as client certificate when
+connecting to the MQTT broker. Requires B<CertificateFile>
+
+=item B<CertificateKeyFile> I<file>
+
+Path to the unencrypted PEM-encoded key file corresponding to B<CertificateFile>. 
+
+=item B<TLSprotocol> I<protocol>
+
+If configured, this specifies the string protocol version (e.g. tlsv1, tlsv1.2) to
+use for the TLS connection to the broker. If not set a default version is used which
+depends on the version of OpenSSL the Mosquitto library was linked against.
+
+=item B<CipherSuite> I<ciphersuite>
+
+A string describing the ciphers available for use. See the "openssl ciphers" utility
+for more information. If unset, the default ciphers will be used.
+
+
 =back
 
 =head2 Plugin C<mysql>
index 1b71d423d458109247e095cd8b5ce97de30b0ce4..403b0d31e2a38ccdc2c26e5cf29516236249ee3b 100644 (file)
@@ -24,6 +24,7 @@
  * Authors:
  *   Marc Falzon <marc at baha dot mu>
  *   Florian octo Forster <octo at collectd.org>
+ *   Jan-Piet Mens <jpmens at gmail.com>
  **/
 
 // Reference: http://mosquitto.org/api/files/mosquitto-h.html
@@ -48,6 +49,9 @@
 #ifndef MQTT_KEEPALIVE
 # define MQTT_KEEPALIVE 60
 #endif
+#ifndef SSL_VERIFY_PEER
+# define SSL_VERIFY_PEER  1
+#endif
 
 
 /*
@@ -67,6 +71,11 @@ struct mqtt_client_conf
     char               *username;
     char               *password;
     int                 qos;
+    char                *cacertificatefile;
+    char                *certificatefile;
+    char                *certificatekeyfile;
+    char                *tlsprotocol;
+    char                *ciphersuite;
 
     /* For publishing */
     char               *topic_prefix;
@@ -277,6 +286,35 @@ static int mqtt_connect (mqtt_client_conf_t *conf)
         return (-1);
     }
 
+#if LIBMOSQUITTO_MAJOR != 0
+    if (conf->cacertificatefile) {
+        status = mosquitto_tls_set(conf->mosq, conf->cacertificatefile, NULL,
+                                  conf->certificatefile, conf->certificatekeyfile, /* pw_callback */NULL);
+        if (status != MOSQ_ERR_SUCCESS) {
+            ERROR ("mqtt plugin: cannot mosquitto_tls_set: %s", mosquitto_strerror(status));
+            mosquitto_destroy (conf->mosq);
+            conf->mosq = NULL;
+            return (-1);
+        }
+
+        status = mosquitto_tls_opts_set(conf->mosq, SSL_VERIFY_PEER, conf->tlsprotocol, conf->ciphersuite);
+        if (status != MOSQ_ERR_SUCCESS) {
+            ERROR ("mqtt plugin: cannot mosquitto_tls_opts_set: %s", mosquitto_strerror(status));
+            mosquitto_destroy (conf->mosq);
+            conf->mosq = NULL;
+            return (-1);
+        }
+
+        status = mosquitto_tls_insecure_set(conf->mosq, false);
+        if (status != MOSQ_ERR_SUCCESS) {
+            ERROR ("mqtt plugin: cannot mosquitto_tls_insecure_set: %s", mosquitto_strerror(status));
+            mosquitto_destroy (conf->mosq);
+            conf->mosq = NULL;
+            return (-1);
+        }
+    }
+#endif
+
     if (conf->username && conf->password)
     {
         status = mosquitto_username_pw_set (conf->mosq, conf->username, conf->password);
@@ -494,6 +532,10 @@ static int mqtt_write (const data_set_t *ds, const value_list_t *vl,
  *   StoreRates true
  *   Retain false
  *   QoS 0
+ *   CACertificateFile "ca.pem"                        Enables TLS if set
+ *   CertificateFile "client-cert.pem"         optional
+ *   CertificateKeyFile "client-key.pem"               optional
+ *   TLSprotocol "tlsv1.2"             optional
  * </Publish>
  */
 static int mqtt_config_publisher (oconfig_item_t *ci)
@@ -570,6 +612,16 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
             cf_util_get_boolean (child, &conf->store_rates);
         else if (strcasecmp ("Retain", child->key) == 0)
             cf_util_get_boolean (child, &conf->retain);
+        else if (strcasecmp ("CACertificateFile", child->key) == 0)
+            cf_util_get_string (child, &conf->cacertificatefile);
+        else if (strcasecmp ("CertificateFile", child->key) == 0)
+            cf_util_get_string (child, &conf->certificatefile);
+        else if (strcasecmp ("CertificateKeyFile", child->key) == 0)
+            cf_util_get_string (child, &conf->certificatekeyfile);
+        else if (strcasecmp ("TLSprotocol", child->key) == 0)
+            cf_util_get_string (child, &conf->tlsprotocol);
+        else if (strcasecmp ("CipherSuite", child->key) == 0)
+            cf_util_get_string (child, &conf->ciphersuite);
         else
             ERROR ("mqtt plugin: Unknown config option: %s", child->key);
     }