Merge branch 'fixes'

pull/267/head v1.4.10
Roger A. Light 9 years ago
commit ee1fd1718b

@ -11,7 +11,7 @@ project(mosquitto)
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
# Only for version 3 and up. cmake_policy(SET CMP0042 NEW) # Only for version 3 and up. cmake_policy(SET CMP0042 NEW)
set (VERSION 1.4.9) set (VERSION 1.4.10)
if (WIN32) if (WIN32)
execute_process(COMMAND cmd /c echo %DATE% %TIME% OUTPUT_VARIABLE TIMESTAMP execute_process(COMMAND cmd /c echo %DATE% %TIME% OUTPUT_VARIABLE TIMESTAMP

@ -1,3 +1,29 @@
1.4.10 - 20160816
=================
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.
- 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.
- 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.
- 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.
1.4.9 - 20160603 1.4.9 - 20160603
================ ================

@ -36,7 +36,9 @@ test : mosquitto
install : mosquitto install : mosquitto
set -e; for d in ${DIRS}; do $(MAKE) -C $${d} install; done 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 set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d} install; done
endif
$(INSTALL) -d ${DESTDIR}/etc/mosquitto $(INSTALL) -d ${DESTDIR}/etc/mosquitto
$(INSTALL) -m 644 mosquitto.conf ${DESTDIR}/etc/mosquitto/mosquitto.conf.example $(INSTALL) -m 644 mosquitto.conf ${DESTDIR}/etc/mosquitto/mosquitto.conf.example
$(INSTALL) -m 644 aclfile.example ${DESTDIR}/etc/mosquitto/aclfile.example $(INSTALL) -m 644 aclfile.example ${DESTDIR}/etc/mosquitto/aclfile.example

@ -55,6 +55,7 @@ Michael Hekel
Michael Laing Michael Laing
Michael Rushton Michael Rushton
Mike Bush Mike Bush
Milan Tucic
Neil Bothwick Neil Bothwick
Nicholas Humfrey Nicholas Humfrey
Nicholas O'Leary Nicholas O'Leary

@ -83,7 +83,7 @@ WITH_SOCKS:=yes
# Also bump lib/mosquitto.h, CMakeLists.txt, # Also bump lib/mosquitto.h, CMakeLists.txt,
# installer/mosquitto.nsi, installer/mosquitto-cygwin.nsi # installer/mosquitto.nsi, installer/mosquitto-cygwin.nsi
VERSION=1.4.9 VERSION=1.4.10
TIMESTAMP:=$(shell date "+%F %T%z") TIMESTAMP:=$(shell date "+%F %T%z")
# Client library SO version. Bump if incompatible API/ABI changes are made. # Client library SO version. Bump if incompatible API/ABI changes are made.

@ -7,7 +7,7 @@
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "mosquitto" Name "mosquitto"
!define VERSION 1.4.9 !define VERSION 1.4.10
OutFile "mosquitto-${VERSION}-install-cygwin.exe" OutFile "mosquitto-${VERSION}-install-cygwin.exe"
InstallDir "$PROGRAMFILES\mosquitto" InstallDir "$PROGRAMFILES\mosquitto"

@ -9,7 +9,7 @@
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "mosquitto" Name "mosquitto"
!define VERSION 1.4.9 !define VERSION 1.4.10
OutFile "mosquitto-${VERSION}-install-win32.exe" OutFile "mosquitto-${VERSION}-install-win32.exe"
InstallDir "$PROGRAMFILES\mosquitto" InstallDir "$PROGRAMFILES\mosquitto"

@ -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) 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); return mosquitto_socks5_set(m_mosq, host, port, username, password);
#else
return MOSQ_ERR_NOT_SUPPORTED;
#endif
} }

@ -45,7 +45,7 @@ extern "C" {
#define LIBMOSQUITTO_MAJOR 1 #define LIBMOSQUITTO_MAJOR 1
#define LIBMOSQUITTO_MINOR 4 #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. */ /* 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) #define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION)

@ -129,6 +129,7 @@ int _mosquitto_verify_certificate_hostname(X509 *cert, const char *hostname)
if(nval->type == GEN_DNS){ if(nval->type == GEN_DNS){
data = ASN1_STRING_data(nval->d.dNSName); data = ASN1_STRING_data(nval->d.dNSName);
if(data && !mosquitto__cmp_hostname_wildcard((char *)data, hostname)){ if(data && !mosquitto__cmp_hostname_wildcard((char *)data, hostname)){
sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free);
return 1; return 1;
} }
have_san_dns = true; 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); data = ASN1_STRING_data(nval->d.iPAddress);
if(nval->d.iPAddress->length == 4 && ipv4_ok){ if(nval->d.iPAddress->length == 4 && ipv4_ok){
if(!memcmp(ipv4_addr, data, 4)){ if(!memcmp(ipv4_addr, data, 4)){
sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free);
return 1; return 1;
} }
}else if(nval->d.iPAddress->length == 16 && ipv6_ok){ }else if(nval->d.iPAddress->length == 16 && ipv6_ok){
if(!memcmp(ipv6_addr, data, 16)){ if(!memcmp(ipv6_addr, data, 16)){
sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free);
return 1; return 1;
} }
} }
} }
} }
sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free);
if(have_san_dns){ if(have_san_dns){
/* Only check CN if subjectAltName DNS entry does not exist. */ /* Only check CN if subjectAltName DNS entry does not exist. */
return 0; return 0;
} }
} }
subj = X509_get_subject_name(cert); subj = X509_get_subject_name(cert);
if(X509_NAME_get_text_by_NID(subj, NID_commonName, name, sizeof(name)) > 0){ if(X509_NAME_get_text_by_NID(subj, NID_commonName, name, sizeof(name)) > 0){
name[sizeof(name) - 1] = '\0'; name[sizeof(name) - 1] = '\0';

@ -41,7 +41,7 @@
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para><command>mosquitto_passwd</command> is a tool for managing <para><command>mosquitto_passwd</command> is a tool for managing
password files the the mosquitto MQTT broker.</para> password files the mosquitto MQTT broker.</para>
<para>Usernames must not contain ":". Passwords are stored in a similar <para>Usernames must not contain ":". Passwords are stored in a similar
format to format to
<citerefentry><refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para> <citerefentry><refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>

@ -11,8 +11,9 @@ separately in the case that they are not already available.
Capabilities Capabilities
------------ ------------
The network support in Windows is severely limited. The broker is limited to approximately Some versions of Windows have limitations on the number of concurrent
1024 MQTT connections. connections. Non-server versions have been reported to be limited to
approximately 1024 connections.
Websockets Websockets
@ -20,7 +21,7 @@ Websockets
The broker executables provided in the installers do not have Websockets support enabled. 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 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. Please note that on Windows, libwebsockets limits connections to a maximum of 64 clients.

@ -2,7 +2,11 @@ Eclipse Mosquitto
================= =================
Mosquitto is an open source implementation of a server for version 3.1 and 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: See the following links for more information on MQTT:
@ -17,6 +21,57 @@ Mosquitto project information is available at the following locations:
There is also a public test server available at <http://test.mosquitto.org/> There is also a public test server available at <http://test.mosquitto.org/>
## Installing
See <http://mosquitto.org/download/> 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 <http://mosquitto.org/man/>. 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 <http://mosquitto.org/api/>
## Building from source
To build from source the recommended route for end users is to download the
archive from <http://mosquitto.org/download/>.
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 <roger@atchoo.org> Mosquitto was written by Roger Light <roger@atchoo.org>
Master: [![Travis Build Status (master)](https://travis-ci.org/eclipse/mosquitto.svg?branch=master)](https://travis-ci.org/eclipse/mosquitto) Master: [![Travis Build Status (master)](https://travis-ci.org/eclipse/mosquitto.svg?branch=master)](https://travis-ci.org/eclipse/mosquitto)

@ -104,8 +104,10 @@ mosquitto_passwd.o : mosquitto_passwd.c
install : all install : all
$(INSTALL) -d ${DESTDIR}$(prefix)/sbin $(INSTALL) -d ${DESTDIR}$(prefix)/sbin
$(INSTALL) -s --strip-program=${CROSS_COMPILE}${STRIP} mosquitto ${DESTDIR}${prefix}/sbin/mosquitto $(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 $(INSTALL) mosquitto_plugin.h ${DESTDIR}${prefix}/include/mosquitto_plugin.h
ifeq ($(WITH_TLS),yes) ifeq ($(WITH_TLS),yes)
$(INSTALL) -d ${DESTDIR}$(prefix)/bin
$(INSTALL) -s --strip-program=${CROSS_COMPILE}${STRIP} mosquitto_passwd ${DESTDIR}${prefix}/bin/mosquitto_passwd $(INSTALL) -s --strip-program=${CROSS_COMPILE}${STRIP} mosquitto_passwd ${DESTDIR}${prefix}/bin/mosquitto_passwd
endif endif

@ -71,6 +71,8 @@ int mqtt3_log_init(struct mqtt3_config *config)
} }
config->log_fptr = _mosquitto_fopen(config->log_file, "at"); config->log_fptr = _mosquitto_fopen(config->log_file, "at");
if(!config->log_fptr){ 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); _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file);
return MOSQ_ERR_INVAL; return MOSQ_ERR_INVAL;
} }

@ -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); 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 #ifdef WITH_TLS
if(pollfds[context->pollfd_index].revents & POLLOUT || if(pollfds[context->pollfd_index].revents & POLLOUT ||
context->want_write || 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)); }while(SSL_DATA_PENDING(context));
} }
if(pollfds[context->pollfd_index].revents & (POLLERR | POLLNVAL | POLLHUP)){
do_disconnect(db, context);
continue;
}
} }
} }

@ -287,7 +287,10 @@ int main(int argc, char *argv[])
/* Initialise logging only after initialising the database in case we're /* Initialise logging only after initialising the database in case we're
* logging to topics */ * 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); _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "mosquitto version %s (build date %s) starting", VERSION, TIMESTAMP);
if(config.config_file){ if(config.config_file){
_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Config loaded from %s.", config.config_file); _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Config loaded from %s.", config.config_file);

@ -31,6 +31,7 @@ Contributors:
# define libwebsocket_write(A, B, C, D) lws_write((A), (B), (C), (D)) # 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 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 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_context lws_context
# define libwebsocket_protocols lws_protocols # define libwebsocket_protocols lws_protocols

@ -90,7 +90,11 @@ int output_new_password(FILE *fptr, const char *username, const char *password)
unsigned char hash[EVP_MAX_MD_SIZE]; unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int hash_len; unsigned int hash_len;
const EVP_MD *digest; const EVP_MD *digest;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_MD_CTX context; EVP_MD_CTX context;
#else
EVP_MD_CTX *context;
#endif
rc = RAND_bytes(salt, SALT_LEN); rc = RAND_bytes(salt, SALT_LEN);
if(!rc){ if(!rc){
@ -113,12 +117,21 @@ int output_new_password(FILE *fptr, const char *username, const char *password)
return 1; return 1;
} }
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_MD_CTX_init(&context); EVP_MD_CTX_init(&context);
EVP_DigestInit_ex(&context, digest, NULL); EVP_DigestInit_ex(&context, digest, NULL);
EVP_DigestUpdate(&context, password, strlen(password)); EVP_DigestUpdate(&context, password, strlen(password));
EVP_DigestUpdate(&context, salt, SALT_LEN); EVP_DigestUpdate(&context, salt, SALT_LEN);
EVP_DigestFinal_ex(&context, hash, &hash_len); EVP_DigestFinal_ex(&context, hash, &hash_len);
EVP_MD_CTX_cleanup(&context); 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); rc = base64_encode(hash, hash_len, &hash64);
if(rc){ if(rc){

@ -34,6 +34,11 @@ struct mosquitto_auth_opt {
* shared library. Using gcc this can be achieved as follows: * shared library. Using gcc this can be achieved as follows:
* *
* gcc -I<path to mosquitto_plugin.h> -fPIC -shared plugin.c -o plugin.so * gcc -I<path to mosquitto_plugin.h> -fPIC -shared plugin.c -o plugin.so
*
* On Mac OS X:
*
* gcc -I<path to mosquitto_plugin.h> -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so
*
*/ */
/* ========================================================================= /* =========================================================================

@ -302,7 +302,7 @@ static int _mosquitto_tls_server_ctx(struct _mqtt3_listener *listener)
#endif #endif
#ifdef WITH_EC #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); SSL_CTX_set_ecdh_auto(listener->ssl_ctx, 1);
#elif OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10002000L #elif OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10002000L
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);

@ -140,7 +140,7 @@ static int mqtt3_db_message_store_write(struct mosquitto_db *db, FILE *db_fptr)
stored = db->msg_store; stored = db->msg_store;
while(stored){ while(stored){
if(stored->topic && !strncmp(stored->topic, "$SYS", 4)){ 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. */ /* $SYS messages that are only retained shouldn't be persisted. */
stored = stored->next; stored = stored->next;
continue; continue;
@ -261,6 +261,7 @@ static int _db_subs_retain_write(struct mosquitto_db *db, FILE *db_fptr, struct
char *thistopic; char *thistopic;
uint32_t length; uint32_t length;
uint16_t i16temp; uint16_t i16temp;
uint8_t i8temp;
dbid_t i64temp; dbid_t i64temp;
size_t slen; 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, &i16temp, sizeof(uint16_t));
write_e(db_fptr, thistopic, slen); 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; sub = sub->next;
} }
@ -362,6 +364,36 @@ int mqtt3_db_backup(struct mosquitto_db *db, bool shutdown)
} }
snprintf(outfile, len, "%s.new", db->config->persistence_filepath); snprintf(outfile, len, "%s.new", db->config->persistence_filepath);
outfile[len] = '\0'; 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"); db_fptr = _mosquitto_fopen(outfile, "wb");
if(db_fptr == NULL){ if(db_fptr == NULL){
_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Error saving in-memory database, unable to open %s for writing.", outfile); _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Error saving in-memory database, unable to open %s for writing.", outfile);
@ -395,6 +427,32 @@ int mqtt3_db_backup(struct mosquitto_db *db, bool shutdown)
mqtt3_db_client_write(db, db_fptr); mqtt3_db_client_write(db, db_fptr);
mqtt3_db_subs_retain_write(db, db_fptr); 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));
#endif
fclose(db_fptr); fclose(db_fptr);
#ifdef WIN32 #ifdef WIN32

@ -180,7 +180,7 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context)
rc = MOSQ_ERR_PROTOCOL; rc = MOSQ_ERR_PROTOCOL;
goto handle_connect_error; 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; password_flag = connect_flags & 0x40;
username_flag = connect_flags & 0x80; username_flag = connect_flags & 0x80;
@ -364,7 +364,7 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context)
goto handle_connect_error; goto handle_connect_error;
} }
name_entry = X509_NAME_get_entry(name, i); 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){ if(!context->username){
rc = 1; rc = 1;
goto handle_connect_error; goto handle_connect_error;

@ -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) 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; const EVP_MD *digest;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_MD_CTX context; EVP_MD_CTX context;
digest = EVP_get_digestbyname("sha512"); 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. */ /* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */
EVP_DigestFinal_ex(&context, hash, hash_len); EVP_DigestFinal_ex(&context, hash, hash_len);
EVP_MD_CTX_cleanup(&context); 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; return MOSQ_ERR_SUCCESS;
} }

@ -168,7 +168,8 @@ static int callback_mqtt(struct libwebsocket_context *context,
struct mosquitto_db *db; struct mosquitto_db *db;
struct mosquitto *mosq = NULL; struct mosquitto *mosq = NULL;
struct _mosquitto_packet *packet; 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; struct libws_mqtt_data *u = (struct libws_mqtt_data *)user;
size_t pos; size_t pos;
uint8_t *buf; uint8_t *buf;
@ -181,6 +182,18 @@ static int callback_mqtt(struct libwebsocket_context *context,
case LWS_CALLBACK_ESTABLISHED: case LWS_CALLBACK_ESTABLISHED:
mosq = mqtt3_context_init(db, WEBSOCKET_CLIENT); mosq = mqtt3_context_init(db, WEBSOCKET_CLIENT);
if(mosq){ if(mosq){
p = libwebsocket_get_protocol(wsi);
for (i=0; i<db->config->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) #if !defined(LWS_LIBRARY_VERSION_NUMBER)
mosq->ws_context = context; mosq->ws_context = context;
#endif #endif
@ -603,6 +616,9 @@ struct libwebsocket_context *mosq_websockets_init(struct _mqtt3_listener *listen
#ifndef LWS_IS_OLD #ifndef LWS_IS_OLD
info.options |= LWS_SERVER_OPTION_DISABLE_IPV6; info.options |= LWS_SERVER_OPTION_DISABLE_IPV6;
#endif #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)); user = _mosquitto_calloc(1, sizeof(struct libws_mqtt_hack));
if(!user){ if(!user){

Loading…
Cancel
Save