From 69b0d4948ca934d22e6e88f1eca02678f0d45355 Mon Sep 17 00:00:00 2001 From: Jan-Piet Mens Date: Tue, 17 Nov 2015 14:44:20 +0100 Subject: [PATCH] Add TLS support addresses #1265 protect for newer libmosquitto address octo's comments --- src/collectd.conf.pod | 27 ++++++++++++++++++++++++++ src/mqtt.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 8a508089..ee05c3a8 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -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, i.e. all topics beneath the B branch. +=item B I + +Path to the PEM-encoded CA certificate file. Setting this option enables TLS +communication with the MQTT broker, and as such, B should be the TLS-enabled +port of the MQTT broker. + +=item B I + +Path to the PEM-encoded certificate file to use as client certificate when +connecting to the MQTT broker. Requires B + +=item B I + +Path to the unencrypted PEM-encoded key file corresponding to B. + +=item B I + +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 I + +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 diff --git a/src/mqtt.c b/src/mqtt.c index 1b71d423..403b0d31 100644 --- a/src/mqtt.c +++ b/src/mqtt.c @@ -24,6 +24,7 @@ * Authors: * Marc Falzon * Florian octo Forster + * Jan-Piet Mens **/ // 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 * */ 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); } -- 2.11.0