From 5d96c3d7ba16bdfe3c4ed6320497974e9493b253 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 6 Jun 2016 15:53:05 +0100 Subject: [PATCH 01/22] [186] Fix TLS operation with websockets listeners and libwebsockts 2.x. Bug: https://github.com/eclipse/mosquitto/issues/186 --- ChangeLog.txt | 8 ++++++++ src/websockets.c | 3 +++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 88513ab6..1c73526c 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,11 @@ +1.x.x - 2016xxxx +================ + +Broker: +- Fix TLS operation with websockets listeners and libwebsockts 2.x. Closes + #186. + + 1.4.9 - 20160603 ================ diff --git a/src/websockets.c b/src/websockets.c index ee7c5a25..b548b47f 100644 --- a/src/websockets.c +++ b/src/websockets.c @@ -603,6 +603,9 @@ struct libwebsocket_context *mosq_websockets_init(struct _mqtt3_listener *listen #ifndef LWS_IS_OLD info.options |= LWS_SERVER_OPTION_DISABLE_IPV6; #endif +#if LWS_LIBRARY_VERSION_MAJOR>1 + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT +#endif user = _mosquitto_calloc(1, sizeof(struct libws_mqtt_hack)); if(!user){ From 63416e65478971b001ed2233630c48a7b4b6a180 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 6 Jun 2016 16:02:55 +0100 Subject: [PATCH 02/22] ; --- src/websockets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/websockets.c b/src/websockets.c index b548b47f..fbf1bc5c 100644 --- a/src/websockets.c +++ b/src/websockets.c @@ -604,7 +604,7 @@ struct libwebsocket_context *mosq_websockets_init(struct _mqtt3_listener *listen info.options |= LWS_SERVER_OPTION_DISABLE_IPV6; #endif #if LWS_LIBRARY_VERSION_MAJOR>1 - info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; #endif user = _mosquitto_calloc(1, sizeof(struct libws_mqtt_hack)); From 1cd40925b86ca5de1d4f2c694a1cdf0dc4619350 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 6 Jun 2016 16:11:42 +0100 Subject: [PATCH 03/22] [184] Don't attempt to install docs when WITH_DOCS=no. Thanks to minghuadev. Bug: https://github.com/eclipse/mosquitto/issues/184 --- ChangeLog.txt | 3 +++ Makefile | 2 ++ src/Makefile | 2 ++ 3 files changed, 7 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 1c73526c..6ddcdcee 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -5,6 +5,9 @@ Broker: - Fix TLS operation with websockets listeners and libwebsockts 2.x. Closes #186. +Build: +- Don't attempt to install docs when WITH_DOCS=no. Closes #184. + 1.4.9 - 20160603 ================ diff --git a/Makefile b/Makefile index 967ba266..1fc0805d 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,9 @@ test : mosquitto install : mosquitto set -e; for d in ${DIRS}; do $(MAKE) -C $${d} install; done +ifeq ($(WITH_DOCS),yes) set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d} install; done +endif $(INSTALL) -d ${DESTDIR}/etc/mosquitto $(INSTALL) -m 644 mosquitto.conf ${DESTDIR}/etc/mosquitto/mosquitto.conf.example $(INSTALL) -m 644 aclfile.example ${DESTDIR}/etc/mosquitto/aclfile.example diff --git a/src/Makefile b/src/Makefile index 2bc70dec..52dc02c5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -104,8 +104,10 @@ mosquitto_passwd.o : mosquitto_passwd.c install : all $(INSTALL) -d ${DESTDIR}$(prefix)/sbin $(INSTALL) -s --strip-program=${CROSS_COMPILE}${STRIP} mosquitto ${DESTDIR}${prefix}/sbin/mosquitto + $(INSTALL) -d ${DESTDIR}$(prefix)/include $(INSTALL) mosquitto_plugin.h ${DESTDIR}${prefix}/include/mosquitto_plugin.h ifeq ($(WITH_TLS),yes) + $(INSTALL) -d ${DESTDIR}$(prefix)/bin $(INSTALL) -s --strip-program=${CROSS_COMPILE}${STRIP} mosquitto_passwd ${DESTDIR}${prefix}/bin/mosquitto_passwd endif From 6459bc026ebf04c892f532031ce494b687df9d4c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 7 Jun 2016 16:44:52 +0100 Subject: [PATCH 04/22] Bump appveyor openssl version. --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 590ad265..65683db2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,7 @@ os: Visual Studio 2013 environment: CMAKE_ARGS: -DCMAKE_BUILD_TYPE=Release NSIS_ROOT: C:\nsis - SSL_VER: 1_0_2e + SSL_VER: 1_0_2h configuration: - Release From 23113bb5f5c07523dac3a392002c173a1fee5371 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 13 Jun 2016 17:13:44 +0100 Subject: [PATCH 05/22] [7] Don't disconnect client on HUP before reading the pending data. Closes #7. Bug: https://github.com/eclipse/mosquitto/issues/7 --- ChangeLog.txt | 1 + src/loop.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 6ddcdcee..e1dd2f1f 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -4,6 +4,7 @@ Broker: - Fix TLS operation with websockets listeners and libwebsockts 2.x. Closes #186. +- Don't disconnect client on HUP before reading the pending data. Closes #7. Build: - Don't attempt to install docs when WITH_DOCS=no. Closes #184. diff --git a/src/loop.c b/src/loop.c index 2a99ae7d..4470323d 100644 --- a/src/loop.c +++ b/src/loop.c @@ -449,10 +449,6 @@ static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pol } assert(pollfds[context->pollfd_index].fd == context->sock); - if(pollfds[context->pollfd_index].revents & (POLLERR | POLLNVAL | POLLHUP)){ - do_disconnect(db, context); - continue; - } #ifdef WITH_TLS if(pollfds[context->pollfd_index].revents & POLLOUT || context->want_write || @@ -496,6 +492,10 @@ static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pol } }while(SSL_DATA_PENDING(context)); } + if(pollfds[context->pollfd_index].revents & (POLLERR | POLLNVAL | POLLHUP)){ + do_disconnect(db, context); + continue; + } } } From 2c54104ce3b12ad0213a374103bacd04e4f673d8 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 Jun 2016 17:17:23 +0100 Subject: [PATCH 06/22] [191] Fix some $SYS messages being incorrectly persisted. Closes #191. Bug: https://github.com/eclipse/mosquitto/issues/191 --- ChangeLog.txt | 1 + src/persist.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index e1dd2f1f..7821e570 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -5,6 +5,7 @@ Broker: - Fix TLS operation with websockets listeners and libwebsockts 2.x. Closes #186. - Don't disconnect client on HUP before reading the pending data. Closes #7. +- Fix some $SYS messages being incorrectly persisted. Closes #191. Build: - Don't attempt to install docs when WITH_DOCS=no. Closes #184. diff --git a/src/persist.c b/src/persist.c index d71fc04b..f416aeab 100644 --- a/src/persist.c +++ b/src/persist.c @@ -140,7 +140,7 @@ static int mqtt3_db_message_store_write(struct mosquitto_db *db, FILE *db_fptr) stored = db->msg_store; while(stored){ if(stored->topic && !strncmp(stored->topic, "$SYS", 4)){ - if(stored->ref_count == 1 && stored->dest_id_count == 0){ + if(stored->ref_count <= 1 && stored->dest_id_count == 0){ /* $SYS messages that are only retained shouldn't be persisted. */ stored = stored->next; continue; From fff741613eb9dbf462ba7eafe9d9f15f80a9c623 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sun, 26 Jun 2016 22:00:43 +0100 Subject: [PATCH 07/22] Support for openssl 1.1.0. --- ChangeLog.txt | 4 ++++ src/mosquitto_passwd.c | 13 +++++++++++++ src/net.c | 2 +- src/read_handle_server.c | 2 +- src/security_default.c | 18 ++++++++++++++++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 7821e570..9e652ad5 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -6,6 +6,10 @@ Broker: #186. - Don't disconnect client on HUP before reading the pending data. Closes #7. - Fix some $SYS messages being incorrectly persisted. Closes #191. +- Support OpenSSL 1.1.0. + +Client library: +- Support OpenSSL 1.1.0. Build: - Don't attempt to install docs when WITH_DOCS=no. Closes #184. diff --git a/src/mosquitto_passwd.c b/src/mosquitto_passwd.c index a7ad1cca..de9a719a 100644 --- a/src/mosquitto_passwd.c +++ b/src/mosquitto_passwd.c @@ -90,7 +90,11 @@ int output_new_password(FILE *fptr, const char *username, const char *password) unsigned char hash[EVP_MAX_MD_SIZE]; unsigned int hash_len; const EVP_MD *digest; +#if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_MD_CTX context; +#else + EVP_MD_CTX *context; +#endif rc = RAND_bytes(salt, SALT_LEN); if(!rc){ @@ -113,12 +117,21 @@ int output_new_password(FILE *fptr, const char *username, const char *password) return 1; } +#if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_MD_CTX_init(&context); EVP_DigestInit_ex(&context, digest, NULL); EVP_DigestUpdate(&context, password, strlen(password)); EVP_DigestUpdate(&context, salt, SALT_LEN); EVP_DigestFinal_ex(&context, hash, &hash_len); EVP_MD_CTX_cleanup(&context); +#else + context = EVP_MD_CTX_new(); + EVP_DigestInit_ex(context, digest, NULL); + EVP_DigestUpdate(context, password, strlen(password)); + EVP_DigestUpdate(context, salt, SALT_LEN); + EVP_DigestFinal_ex(context, hash, &hash_len); + EVP_MD_CTX_free(context); +#endif rc = base64_encode(hash, hash_len, &hash64); if(rc){ diff --git a/src/net.c b/src/net.c index 5c322df5..ac8c055b 100644 --- a/src/net.c +++ b/src/net.c @@ -302,7 +302,7 @@ static int _mosquitto_tls_server_ctx(struct _mqtt3_listener *listener) #endif #ifdef WITH_EC -#if OPENSSL_VERSION_NUMBER >= 0x10002000L +#if OPENSSL_VERSION_NUMBER >= 0x10002000L && OPENSSL_VERSION_NUMBER < 0x10100000L SSL_CTX_set_ecdh_auto(listener->ssl_ctx, 1); #elif OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10002000L ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); diff --git a/src/read_handle_server.c b/src/read_handle_server.c index d7122193..558adb0c 100644 --- a/src/read_handle_server.c +++ b/src/read_handle_server.c @@ -364,7 +364,7 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) goto handle_connect_error; } name_entry = X509_NAME_get_entry(name, i); - context->username = _mosquitto_strdup((char *)ASN1_STRING_data(name_entry->value)); + context->username = _mosquitto_strdup((char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(name_entry))); if(!context->username){ rc = 1; goto handle_connect_error; diff --git a/src/security_default.c b/src/security_default.c index c64e4568..64ca846b 100644 --- a/src/security_default.c +++ b/src/security_default.c @@ -770,6 +770,7 @@ int mosquitto_psk_key_get_default(struct mosquitto_db *db, const char *hint, con int _pw_digest(const char *password, const unsigned char *salt, unsigned int salt_len, unsigned char *hash, unsigned int *hash_len) { const EVP_MD *digest; +#if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_MD_CTX context; digest = EVP_get_digestbyname("sha512"); @@ -785,6 +786,23 @@ int _pw_digest(const char *password, const unsigned char *salt, unsigned int sal /* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */ EVP_DigestFinal_ex(&context, hash, hash_len); EVP_MD_CTX_cleanup(&context); +#else + EVP_MD_CTX *context; + + digest = EVP_get_digestbyname("sha512"); + if(!digest){ + // FIXME fprintf(stderr, "Error: Unable to create openssl digest.\n"); + return 1; + } + + context = EVP_MD_CTX_new(); + EVP_DigestInit_ex(context, digest, NULL); + EVP_DigestUpdate(context, password, strlen(password)); + EVP_DigestUpdate(context, salt, salt_len); + /* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */ + EVP_DigestFinal_ex(context, hash, hash_len); + EVP_MD_CTX_free(context); +#endif return MOSQ_ERR_SUCCESS; } From 84df2bb9237611221c7962814ac0567c8519cf50 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sun, 26 Jun 2016 22:48:16 +0100 Subject: [PATCH 08/22] [189] Call fsync after persisting data. To ensure it is correctly written. Closes #189. Thanks to thanhvtruong. Bug: https://github.com/eclipse/mosquitto/issues/189 --- ChangeLog.txt | 2 ++ src/persist.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 9e652ad5..64459fa2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,8 @@ Broker: - Don't disconnect client on HUP before reading the pending data. Closes #7. - Fix some $SYS messages being incorrectly persisted. Closes #191. - Support OpenSSL 1.1.0. +- Call fsync after persisting data to ensure it is correctly written. Closes + #189. Client library: - Support OpenSSL 1.1.0. diff --git a/src/persist.c b/src/persist.c index f416aeab..406675f9 100644 --- a/src/persist.c +++ b/src/persist.c @@ -350,6 +350,9 @@ int mqtt3_db_backup(struct mosquitto_db *db, bool shutdown) char err[256]; char *outfile = NULL; int len; +#ifndef WIN32 + int dir_fd; +#endif if(!db || !db->config || !db->config->persistence_filepath) return MOSQ_ERR_INVAL; _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Saving in-memory database to %s.", db->config->persistence_filepath); @@ -395,6 +398,19 @@ int mqtt3_db_backup(struct mosquitto_db *db, bool shutdown) mqtt3_db_client_write(db, db_fptr); mqtt3_db_subs_retain_write(db, db_fptr); +#ifndef WIN32 + fsync(fileno(db_fptr)); + + if(db->config->persistence_location){ + dir_fd = open(db->config->persistence_location, O_DIRECTORY); + }else{ + dir_fd = open(".", O_DIRECTORY); + } + if(dir_fd > 0){ + fsync(dir_fd); + close(dir_fd); + } +#endif fclose(db_fptr); #ifdef WIN32 From eaef3db142494966b4e3b194f4a844b3748efabf Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 27 Jun 2016 20:58:25 +0100 Subject: [PATCH 09/22] O_DIRECTORY not supported everywhere, use O_RDONLY. --- src/persist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/persist.c b/src/persist.c index 406675f9..5ec4fe11 100644 --- a/src/persist.c +++ b/src/persist.c @@ -402,9 +402,9 @@ int mqtt3_db_backup(struct mosquitto_db *db, bool shutdown) fsync(fileno(db_fptr)); if(db->config->persistence_location){ - dir_fd = open(db->config->persistence_location, O_DIRECTORY); + dir_fd = open(db->config->persistence_location, O_RDONLY); }else{ - dir_fd = open(".", O_DIRECTORY); + dir_fd = open(".", O_RDONLY); } if(dir_fd > 0){ fsync(dir_fd); From 1c90a4487c0eb2245a5247bd201047eb3407639a Mon Sep 17 00:00:00 2001 From: jbwdevries Date: Wed, 29 Jun 2016 18:12:20 +0200 Subject: [PATCH 10/22] Fixes a bug where the C++ wrapper would always claim SOCKS was not supported. (#198) The WITH_* flags are not handed over to the C++ wrapper, instead it relies on the actual library to check status. Signed-off-by: Johan de Vries (Ubuntu VM) --- lib/cpp/mosquittopp.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/cpp/mosquittopp.cpp b/lib/cpp/mosquittopp.cpp index 03301812..0a22b80f 100644 --- a/lib/cpp/mosquittopp.cpp +++ b/lib/cpp/mosquittopp.cpp @@ -281,11 +281,7 @@ void mosquittopp::user_data_set(void *userdata) int mosquittopp::socks5_set(const char *host, int port, const char *username, const char *password) { -#ifdef WITH_SOCKS return mosquitto_socks5_set(m_mosq, host, port, username, password); -#else - return MOSQ_ERR_NOT_SUPPORTED; -#endif } From b6385d347ae2bd664661167d9351509815886081 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 Jun 2016 17:14:33 +0100 Subject: [PATCH 11/22] [198] Update Changelog. Closes #198. Bug: https://github.com/eclipse/mosquitto/pull/198 --- ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 64459fa2..24cafe5b 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -12,6 +12,7 @@ Broker: Client library: - Support OpenSSL 1.1.0. +- Fixed the C++ library not allowing SOCKS support to be used. Closes #198. Build: - Don't attempt to install docs when WITH_DOCS=no. Closes #184. From 50b26347d408e539042a40836c6696f47d404a45 Mon Sep 17 00:00:00 2001 From: tucic Date: Tue, 12 Jul 2016 13:34:59 +0200 Subject: [PATCH 12/22] Writing least significant byte of subscription QoS (#210) Signed-off-by: Milan Tucic --- src/persist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/persist.c b/src/persist.c index 5ec4fe11..5b633f28 100644 --- a/src/persist.c +++ b/src/persist.c @@ -261,6 +261,7 @@ static int _db_subs_retain_write(struct mosquitto_db *db, FILE *db_fptr, struct char *thistopic; uint32_t length; uint16_t i16temp; + uint8_t i8temp; dbid_t i64temp; size_t slen; @@ -292,7 +293,8 @@ static int _db_subs_retain_write(struct mosquitto_db *db, FILE *db_fptr, struct write_e(db_fptr, &i16temp, sizeof(uint16_t)); write_e(db_fptr, thistopic, slen); - write_e(db_fptr, &sub->qos, sizeof(uint8_t)); + i8temp = (uint8_t )sub->qos; + write_e(db_fptr, &i8temp, sizeof(uint8_t)); } sub = sub->next; } From 3261b307e34aeb9806d59dc4b3c80ade093d5e32 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 5 Jul 2016 21:38:57 +0100 Subject: [PATCH 13/22] Updated readme.md. --- readme-windows.txt | 7 +++--- readme.md | 62 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/readme-windows.txt b/readme-windows.txt index 7917a90a..d8cd5696 100644 --- a/readme-windows.txt +++ b/readme-windows.txt @@ -11,8 +11,9 @@ separately in the case that they are not already available. Capabilities ------------ -The network support in Windows is severely limited. The broker is limited to approximately -1024 MQTT connections. +Some versions of Windows have limitations on the number of concurrent +connections. Non-server versions have been reported to be limited to +approximately 1024 connections. Websockets @@ -20,7 +21,7 @@ Websockets The broker executables provided in the installers do not have Websockets support enabled. If you wish to have a version of the broker with Websockets support, you will need to compile -libwebsockets version v1.3-chrome37-firefox30 yourself and mosquitto version 1.4 yourself. +libwebsockets version v1.7 onwards because no Windows binaries are provided. Please note that on Windows, libwebsockets limits connections to a maximum of 64 clients. diff --git a/readme.md b/readme.md index 20e20d0d..3f420632 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,11 @@ Mosquitto ========= Mosquitto is an open source implementation of a server for version 3.1 and -3.1.1 of the MQTT protocol. +3.1.1 of the MQTT protocol. It also includes a C and C++ client library, and +the `mosquitto_pub` and `mosquitto_sub` utilities for publishing and +subscribing. + +## Links See the following links for more information on MQTT: @@ -12,10 +16,60 @@ See the following links for more information on MQTT: Mosquitto project information is available at the following locations: - Main homepage: -- Find existing bugs: -- Submit a bug: -- Source code repository: +- Bug reports: +- Source code repository: There is also a public test server available at +## Installing + +See for details on installing binaries for +various platforms. + +## Quick start + +If you have installed a binary package the broker should have been started +automatically. If not, it can be started with a basic configuration: + + mosquitto + +Then use `mosquitto_sub` to subscribe to a topic: + + mosquitto_sub -t 'test/topic' -v + +And to publish a message: + + mosquitto_pub -t 'test/topic' -m 'hello world' + +## Documentation + +Documentation for the broker, clients and client library API can be found in +the man pages, which are available online at . There +are also pages with an introduction to the features of MQTT, the +`mosquitto_passwd` utility for dealing with username/passwords, and a +description of the configuration file options available for the broker. + +Detailed client library API documentation can be found at + +## Building from source + +To build from source the recommended route for end users is to download the +archive from . + +On Windows and Mac, use `cmake` to build. On other platforms, just run `make` +to build. For Windows, see also `readme-windows.md`. + +If you are building from the git repository then the documentation will not +already be built. Use `make binary` to skip building the man pages, or install +`docbook-xsl` on Debian/Ubuntu systems. + +### Build Dependencies + +* c-ares (libc-ares2-dev on Debian based systems) - disable with `make WITH_DNS_SRV=no` +* libuuid (uuid-dev) - disable with `make WITH_UUID=no` +* libwebsockets (libwebsockets-dev) - enable with `make WITH_LIBWEBSOCKETS=yes` +* openssl (libssl-dev on Debian based systems) - disable with `make WITH_TLS=no` + +## Credits + Mosquitto was written by Roger Light From f06a947df2a13eb846f33010f0880c49631b8450 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 12 Jul 2016 12:36:41 +0100 Subject: [PATCH 14/22] Update changelog. --- ChangeLog.txt | 1 + THANKS.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 24cafe5b..34ccbfb5 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -9,6 +9,7 @@ Broker: - Support OpenSSL 1.1.0. - Call fsync after persisting data to ensure it is correctly written. Closes #189. +- Fix persistence saving of subscription QoS on big-endian machines. Client library: - Support OpenSSL 1.1.0. diff --git a/THANKS.txt b/THANKS.txt index 42faea28..7bb1e47e 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -55,6 +55,7 @@ Michael Hekel Michael Laing Michael Rushton Mike Bush +Milan Tucic Neil Bothwick Nicholas Humfrey Nicholas O'Leary From bcfa29cbd16d338c3a9181d5c916f3be50560349 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 22 Jul 2016 10:37:30 +0100 Subject: [PATCH 15/22] [222] Fix will retained flag handling on Windows. Thanks to codami. Bug: https://github.com/eclipse/mosquitto/issues/222 --- ChangeLog.txt | 1 + src/read_handle_server.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 34ccbfb5..6a2466cb 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,7 @@ Broker: - Call fsync after persisting data to ensure it is correctly written. Closes #189. - Fix persistence saving of subscription QoS on big-endian machines. +- Fix will retained flag handling on Windows. Closes #222. Client library: - Support OpenSSL 1.1.0. diff --git a/src/read_handle_server.c b/src/read_handle_server.c index 558adb0c..02fbc974 100644 --- a/src/read_handle_server.c +++ b/src/read_handle_server.c @@ -180,7 +180,7 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; } - will_retain = connect_flags & 0x20; + will_retain = ((connect_flags & 0x20) == 0x20); // Temporary hack because MSVC<1800 doesn't have stdbool.h. password_flag = connect_flags & 0x40; username_flag = connect_flags & 0x80; From 79cc06b1801cad4700aa5eabf1e6ed6f5c9786bf Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 8 Aug 2016 21:49:32 +0100 Subject: [PATCH 16/22] [237] Fix memory leak when verifying a server certificate. Only for certificates with a subjectAltName. Closes #237. Thanks to MrSaturday. Bug: https://github.com/eclipse/mosquitto/issues/237 --- ChangeLog.txt | 2 ++ lib/tls_mosq.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 6a2466cb..696c25e4 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -15,6 +15,8 @@ Broker: Client library: - Support OpenSSL 1.1.0. - Fixed the C++ library not allowing SOCKS support to be used. Closes #198. +- Fix memory leak when verifying a server certificate with a subjectAltName + section. Closes #237. Build: - Don't attempt to install docs when WITH_DOCS=no. Closes #184. diff --git a/lib/tls_mosq.c b/lib/tls_mosq.c index 7fd78a59..20f0d3ae 100644 --- a/lib/tls_mosq.c +++ b/lib/tls_mosq.c @@ -129,6 +129,7 @@ int _mosquitto_verify_certificate_hostname(X509 *cert, const char *hostname) if(nval->type == GEN_DNS){ data = ASN1_STRING_data(nval->d.dNSName); if(data && !mosquitto__cmp_hostname_wildcard((char *)data, hostname)){ + sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free); return 1; } have_san_dns = true; @@ -136,20 +137,24 @@ int _mosquitto_verify_certificate_hostname(X509 *cert, const char *hostname) data = ASN1_STRING_data(nval->d.iPAddress); if(nval->d.iPAddress->length == 4 && ipv4_ok){ if(!memcmp(ipv4_addr, data, 4)){ + sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free); return 1; } }else if(nval->d.iPAddress->length == 16 && ipv6_ok){ if(!memcmp(ipv6_addr, data, 16)){ + sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free); return 1; } } } } + sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free); if(have_san_dns){ /* Only check CN if subjectAltName DNS entry does not exist. */ return 0; } } + subj = X509_get_subject_name(cert); if(X509_NAME_get_text_by_NID(subj, NID_commonName, name, sizeof(name)) > 0){ name[sizeof(name) - 1] = '\0'; From a0d6da16047fa037436d7bc979b3a497ad092825 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 8 Aug 2016 22:14:35 +0100 Subject: [PATCH 17/22] [225] Fix typo in man page. Closes #225. Thanks to Nabytovych. Bug: https://github.com/eclipse/mosquitto/issues/225 --- man/mosquitto_passwd.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/mosquitto_passwd.1.xml b/man/mosquitto_passwd.1.xml index 6a75b8d4..087ed166 100644 --- a/man/mosquitto_passwd.1.xml +++ b/man/mosquitto_passwd.1.xml @@ -41,7 +41,7 @@ Description mosquitto_passwd is a tool for managing - password files the the mosquitto MQTT broker. + password files the mosquitto MQTT broker. Usernames must not contain ":". Passwords are stored in a similar format to crypt3. From 00aa18174915dc48c42910e979dcb83eaa97c782 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 12 Aug 2016 08:00:34 +0100 Subject: [PATCH 18/22] [244] Add note on compiling auth plugin on OSX. Closes #244. Bug: https://github.com/eclipse/mosquitto/issues/244 --- src/mosquitto_plugin.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mosquitto_plugin.h b/src/mosquitto_plugin.h index e6ec5c0b..5b6449c0 100644 --- a/src/mosquitto_plugin.h +++ b/src/mosquitto_plugin.h @@ -34,6 +34,11 @@ struct mosquitto_auth_opt { * shared library. Using gcc this can be achieved as follows: * * gcc -I -fPIC -shared plugin.c -o plugin.so + * + * On Mac OS X: + * + * gcc -I -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so + * */ /* ========================================================================= From 477cd3e39911f639da691f321ce12fd306fc6a4b Mon Sep 17 00:00:00 2001 From: Pierre Fersing Date: Tue, 16 Aug 2016 23:10:41 +0200 Subject: [PATCH 19/22] Fix missing context->listener for websocket client (#239) The context associated with websocket client didn't had listener filled, which caused use_username_as_clientid to be ignored. Signed-off-by: Pierre Fersing --- src/mosquitto_broker.h | 1 + src/websockets.c | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/mosquitto_broker.h b/src/mosquitto_broker.h index 8d197901..7d29e927 100644 --- a/src/mosquitto_broker.h +++ b/src/mosquitto_broker.h @@ -31,6 +31,7 @@ Contributors: # define libwebsocket_write(A, B, C, D) lws_write((A), (B), (C), (D)) # define libwebsocket_get_socket_fd(A) lws_get_socket_fd((A)) # define libwebsockets_return_http_status(A, B, C, D) lws_return_http_status((B), (C), (D)) +# define libwebsocket_get_protocol(A) lws_get_protocol((A)) # define libwebsocket_context lws_context # define libwebsocket_protocols lws_protocols diff --git a/src/websockets.c b/src/websockets.c index fbf1bc5c..c16bde7a 100644 --- a/src/websockets.c +++ b/src/websockets.c @@ -168,7 +168,8 @@ static int callback_mqtt(struct libwebsocket_context *context, struct mosquitto_db *db; struct mosquitto *mosq = NULL; struct _mosquitto_packet *packet; - int count; + int count, i, j; + const struct libwebsocket_protocols *p; struct libws_mqtt_data *u = (struct libws_mqtt_data *)user; size_t pos; uint8_t *buf; @@ -181,6 +182,18 @@ static int callback_mqtt(struct libwebsocket_context *context, case LWS_CALLBACK_ESTABLISHED: mosq = mqtt3_context_init(db, WEBSOCKET_CLIENT); if(mosq){ + p = libwebsocket_get_protocol(wsi); + for (i=0; iconfig->listener_count; i++){ + if (db->config->listeners[i].protocol == mp_websockets) { + for (j=0; db->config->listeners[i].ws_protocol[j].name; j++){ + if (p == &db->config->listeners[i].ws_protocol[j]){ + mosq->listener = &db->config->listeners[i]; + mosq->listener->client_count++; + } + } + } + } + #if !defined(LWS_LIBRARY_VERSION_NUMBER) mosq->ws_context = context; #endif From ba2de8879008f6df90a0d6af5902926483051124 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 16 Aug 2016 22:31:36 +0100 Subject: [PATCH 20/22] Display error if broker unable to open the log file. Thanks to Matthew Treinish. Bug: https://github.com/eclipse/mosquitto/issues/234 --- ChangeLog.txt | 2 ++ src/logging.c | 2 ++ src/mosquitto.c | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 696c25e4..f09e2135 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -11,6 +11,8 @@ Broker: #189. - Fix persistence saving of subscription QoS on big-endian machines. - Fix will retained flag handling on Windows. Closes #222. +- Broker now displays an error if it is unable to open the log file. Closes + #234. Client library: - Support OpenSSL 1.1.0. diff --git a/src/logging.c b/src/logging.c index 79169f90..f1a58111 100644 --- a/src/logging.c +++ b/src/logging.c @@ -71,6 +71,8 @@ int mqtt3_log_init(struct mqtt3_config *config) } config->log_fptr = _mosquitto_fopen(config->log_file, "at"); if(!config->log_fptr){ + log_destinations = MQTT3_LOG_STDERR; + log_priorities = MOSQ_LOG_ERR; _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file); return MOSQ_ERR_INVAL; } diff --git a/src/mosquitto.c b/src/mosquitto.c index 55ff678c..9777ad80 100644 --- a/src/mosquitto.c +++ b/src/mosquitto.c @@ -287,7 +287,10 @@ int main(int argc, char *argv[]) /* Initialise logging only after initialising the database in case we're * logging to topics */ - mqtt3_log_init(&config); + if(mqtt3_log_init(&config)){ + rc = 1; + return rc; + } _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "mosquitto version %s (build date %s) starting", VERSION, TIMESTAMP); if(config.config_file){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Config loaded from %s.", config.config_file); From 7ba3f3d33b5b7de2e7cdb2e207782808f23e9855 Mon Sep 17 00:00:00 2001 From: kcallin Date: Tue, 16 Aug 2016 15:36:58 -0600 Subject: [PATCH 21/22] [189] Mosquitto database corrupted on power-loss. (#206) Mosquitto database writes are not atomic and if power is lost during a write the file will be permanently lost. This commit makes writes as atomic as possible. Signed-off-by: Keegan Callin Bug: https://github.com/eclipse/mosquitto/issues/189 --- src/persist.c | 66 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/src/persist.c b/src/persist.c index 5b633f28..47c27ae7 100644 --- a/src/persist.c +++ b/src/persist.c @@ -352,9 +352,6 @@ int mqtt3_db_backup(struct mosquitto_db *db, bool shutdown) char err[256]; char *outfile = NULL; int len; -#ifndef WIN32 - int dir_fd; -#endif if(!db || !db->config || !db->config->persistence_filepath) return MOSQ_ERR_INVAL; _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Saving in-memory database to %s.", db->config->persistence_filepath); @@ -367,6 +364,36 @@ int mqtt3_db_backup(struct mosquitto_db *db, bool shutdown) } snprintf(outfile, len, "%s.new", db->config->persistence_filepath); outfile[len] = '\0'; + +#ifndef WIN32 + /** + * + * If a system lost power during the rename operation at the + * end of this file the filesystem could potentially be left + * with a directory that looks like this after powerup: + * + * 24094 -rw-r--r-- 2 root root 4099 May 30 16:27 mosquitto.db + * 24094 -rw-r--r-- 2 root root 4099 May 30 16:27 mosquitto.db.new + * + * The 24094 shows that mosquitto.db.new is hard-linked to the + * same file as mosquitto.db. If fopen(outfile, "wb") is naively + * called then mosquitto.db will be truncated and the database + * potentially corrupted. + * + * Any existing mosquitto.db.new file must be removed prior to + * opening to guarantee that it is not hard-linked to + * mosquitto.db. + * + */ + rc = unlink(outfile); + if (rc != 0) { + if (errno != ENOENT) { + _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Error saving in-memory database, unable to remove %s.", outfile); + goto error; + } + } +#endif + db_fptr = _mosquitto_fopen(outfile, "wb"); if(db_fptr == NULL){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Error saving in-memory database, unable to open %s for writing.", outfile); @@ -401,17 +428,30 @@ int mqtt3_db_backup(struct mosquitto_db *db, bool shutdown) mqtt3_db_subs_retain_write(db, db_fptr); #ifndef WIN32 + /** + * + * Closing a file does not guarantee that the contents are + * written to disk. Need to flush to send data from app to OS + * buffers, then fsync to deliver data from OS buffers to disk + * (as well as disk hardware permits). + * + * man close (http://linux.die.net/man/2/close, 2016-06-20): + * + * "successful close does not guarantee that the data has + * been successfully saved to disk, as the kernel defers + * writes. It is not common for a filesystem to flush + * the buffers when the stream is closed. If you need + * to be sure that the data is physically stored, use + * fsync(2). (It will depend on the disk hardware at this + * point." + * + * This guarantees that the new state file will not overwrite + * the old state file before its contents are valid. + * + */ + + fflush(db_fptr); fsync(fileno(db_fptr)); - - if(db->config->persistence_location){ - dir_fd = open(db->config->persistence_location, O_RDONLY); - }else{ - dir_fd = open(".", O_RDONLY); - } - if(dir_fd > 0){ - fsync(dir_fd); - close(dir_fd); - } #endif fclose(db_fptr); From 87b6a746fd63e9919e93ee4365a7275f67033867 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 16 Aug 2016 22:52:22 +0100 Subject: [PATCH 22/22] Bump version number. --- CMakeLists.txt | 2 +- ChangeLog.txt | 4 ++-- config.mk | 2 +- installer/mosquitto-cygwin.nsi | 2 +- installer/mosquitto.nsi | 2 +- lib/mosquitto.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd903e7f..29fb4b45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ project(mosquitto) cmake_minimum_required(VERSION 2.8) # Only for version 3 and up. cmake_policy(SET CMP0042 NEW) -set (VERSION 1.4.9) +set (VERSION 1.4.10) if (WIN32) execute_process(COMMAND cmd /c echo %DATE% %TIME% OUTPUT_VARIABLE TIMESTAMP diff --git a/ChangeLog.txt b/ChangeLog.txt index f09e2135..bec39d77 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,5 +1,5 @@ -1.x.x - 2016xxxx -================ +1.4.10 - 20160816 +================= Broker: - Fix TLS operation with websockets listeners and libwebsockts 2.x. Closes diff --git a/config.mk b/config.mk index be86df2c..087766c5 100644 --- a/config.mk +++ b/config.mk @@ -83,7 +83,7 @@ WITH_SOCKS:=yes # Also bump lib/mosquitto.h, CMakeLists.txt, # installer/mosquitto.nsi, installer/mosquitto-cygwin.nsi -VERSION=1.4.9 +VERSION=1.4.10 TIMESTAMP:=$(shell date "+%F %T%z") # Client library SO version. Bump if incompatible API/ABI changes are made. diff --git a/installer/mosquitto-cygwin.nsi b/installer/mosquitto-cygwin.nsi index 2ce9d8d6..eea6ae42 100644 --- a/installer/mosquitto-cygwin.nsi +++ b/installer/mosquitto-cygwin.nsi @@ -7,7 +7,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "mosquitto" -!define VERSION 1.4.9 +!define VERSION 1.4.10 OutFile "mosquitto-${VERSION}-install-cygwin.exe" InstallDir "$PROGRAMFILES\mosquitto" diff --git a/installer/mosquitto.nsi b/installer/mosquitto.nsi index 44f59b19..7dc4d1f8 100644 --- a/installer/mosquitto.nsi +++ b/installer/mosquitto.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "mosquitto" -!define VERSION 1.4.9 +!define VERSION 1.4.10 OutFile "mosquitto-${VERSION}-install-win32.exe" InstallDir "$PROGRAMFILES\mosquitto" diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 8362065b..a7de2922 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -45,7 +45,7 @@ extern "C" { #define LIBMOSQUITTO_MAJOR 1 #define LIBMOSQUITTO_MINOR 4 -#define LIBMOSQUITTO_REVISION 9 +#define LIBMOSQUITTO_REVISION 10 /* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ #define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION)