diff --git a/CMakeLists.txt b/CMakeLists.txt index d9a86362bd..265c106d9c 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.5.3) +set (VERSION 1.5.5) add_definitions (-DCMAKE -DVERSION=\"${VERSION}\") @@ -73,6 +73,30 @@ endif (${WITH_SOCKS} STREQUAL ON) option(WITH_SRV "Include SRV lookup support?" OFF) +option(WITH_THREADING "Include client library threading support?" ON) +if (${WITH_THREADING} STREQUAL ON) + add_definitions("-DWITH_THREADING") + if (WIN32) + if (CMAKE_CL_64) + set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x64\\pthreadVC2.lib) + else (CMAKE_CL_64) + set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x86\\pthreadVC2.lib) + endif (CMAKE_CL_64) + set (PTHREAD_INCLUDE_DIR C:\\pthreads\\Pre-built.2\\include) + else (WIN32) + find_library(LIBPTHREAD pthread) + if (LIBPTHREAD) + set (PTHREAD_LIBRARIES pthread) + else (LIBPTHREAD) + set (PTHREAD_LIBRARIES "") + endif() + set (PTHREAD_INCLUDE_DIR "") + endif (WIN32) +else (${WITH_THREADING} STREQUAL ON) + set (PTHREAD_LIBRARIES "") + set (PTHREAD_INCLUDE_DIR "") +endif (${WITH_THREADING} STREQUAL ON) + option(DOCUMENTATION "Build documentation?" ON) # ======================================== diff --git a/ChangeLog.txt b/ChangeLog.txt index 27be9d4632..7b83dd4953 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -18,6 +18,78 @@ Client features: session without requiring a message to be received. +1.5.5 - 20181211 +================ + +Security: +- If `per_listener_settings` is set to true, then the `acl_file` setting was + ignored for the "default listener" only. This has been fixed. This does not + affect any listeners defined with the `listener` option. Closes #1073. + +Broker: +- Add `socket_domain` option to allow listeners to disable IPv6 support. + This is required to work around a problem in libwebsockets that means + sockets only listen on IPv6 by default if IPv6 support is compiled in. + Closes #1004. +- When using ADNS, don't ask for all network protocols when connecting, + because this can lead to confusing "Protocol not supported" errors if the + network is down. Closes #1062. +- Fix outgoing retained messages not being sent by bridges on initial + connection. Closes #1040. +- Don't reload auth_opt_ options on reload, to match the behaviour of the + other plugin options. Closes #1068. +- Print message on error when installing/uninstalling as a Windows service. +- All non-error connect/disconnect messages are controlled by the + `connection_messages` option. Closes #772. Closes #613. Closes #537. + +Library: +- Fix reconnect delay backoff behaviour. Closes #1027. +- Don't call on_disconnect() twice if keepalive tests fail. Closes #1067. + +Client: +- Always print leading zeros in mosquitto_sub when output format is hex. + Closes #1066. + +Build: +- Fix building where TLS-PSK is not available. Closes #68. + + +1.5.4 - 20181108 +================ + +Security: +- When using a TLS enabled websockets listener with "require_certificate" + enabled, the mosquitto broker does not correctly verify client certificates. + This is now fixed. All other security measures operate as expected, and in + particular non-websockets listeners are not affected by this. Closes #996. + +Broker: +- Process all pending messages even when a client has disconnected. This means + a client that send a PUBLISH then DISCONNECT quickly, then disconnects will + have its DISCONNECT message processed properly and so no Will will be sent. + Closes #7. +- $SYS/broker/clients/disconnected should never be negative. Closes #287. +- Give better error message if a client sends a password without a username. + Closes #1015. +- Fix bridge not honoring restart_timeout. Closes #1019. +- Don't disconnect a client if an auth plugin denies access to SUBSCRIBE. + Closes #1016. + +Library: +- Fix memory leak that occurred if mosquitto_reconnect() was used when TLS + errors were present. Closes #592. +- Fix TLS connections when using an external event loop with + mosquitto_loop_read() and mosquitto_write(). Closes #990. + +Build: +- Fix clients not being compiled with threading support when using CMake. + Closes #983. +- Header fixes for FreeBSD. Closes #977. +- Use _GNU_SOURCE to fix build errors in websockets and getaddrinfo usage. + Closes #862 and #933. +- Fix builds on QNX 7.0.0. Closes #1018. + + 1.5.3 - 20180925 ================ @@ -36,6 +108,8 @@ Broker: removed. Closes #645. - Fix Windows version not starting if include_dir did not contain any files. Closes #566. +- When an authentication plugin denied access to a SUBSCRIBE, the client would + be disconnected incorrectly. This has been fixed. Closes #1016. Build: - Various fixes to ease building. diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index d53772ed71..85b0eb631a 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -1,5 +1,5 @@ include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/lib - ${STDBOOL_H_PATH} ${STDINT_H_PATH}) + ${STDBOOL_H_PATH} ${STDINT_H_PATH} ${PTHREAD_INCLUDE_DIR}) link_directories(${mosquitto_BINARY_DIR}/lib) set(shared_src client_shared.c client_shared.h client_props.c) @@ -11,8 +11,14 @@ endif (${WITH_SRV} STREQUAL ON) add_executable(mosquitto_pub pub_client.c pub_shared.c ${shared_src}) add_executable(mosquitto_sub sub_client.c sub_client_output.c ${shared_src}) + target_link_libraries(mosquitto_pub libmosquitto) target_link_libraries(mosquitto_sub libmosquitto) +if (QNX) + target_link_libraries(mosquitto_pub socket) + target_link_libraries(mosquitto_sub socket) +endif() + install(TARGETS mosquitto_pub RUNTIME DESTINATION "${BINDIR}" LIBRARY DESTINATION "${LIBDIR}") install(TARGETS mosquitto_sub RUNTIME DESTINATION "${BINDIR}" LIBRARY DESTINATION "${LIBDIR}") diff --git a/client/Makefile b/client/Makefile index 39310b973f..7bc7cc8a5e 100644 --- a/client/Makefile +++ b/client/Makefile @@ -2,7 +2,19 @@ include ../config.mk .PHONY: all install uninstall reallyclean clean static static_pub static_sub -all : mosquitto_pub mosquitto_sub +ifeq ($(WITH_SHARED_LIBRARIES),yes) +SHARED_DEP:=../lib/libmosquitto.so.${SOVERSION} +endif + +ifeq ($(WITH_SHARED_LIBRARIES),yes) +ALL_DEPS:= mosquitto_pub mosquitto_sub +else +ifeq ($(WITH_STATIC_LIBRARIES),yes) +ALL_DEPS:= static_pub static_sub +endif +endif + +all : ${ALL_DEPS} static : static_pub static_sub # This makes mosquitto_pub/sub versions that are statically linked with @@ -20,16 +32,16 @@ mosquitto_pub : pub_client.o pub_shared.o client_shared.o client_props.o mosquitto_sub : sub_client.o sub_client_output.o client_shared.o client_props.o ${CROSS_COMPILE}${CC} $^ -o $@ ${CLIENT_LDFLAGS} -pub_client.o : pub_client.c ../lib/libmosquitto.so.${SOVERSION} +pub_client.o : pub_client.c ${SHARED_DEP} ${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS} -pub_shared.o : pub_shared.c ../lib/libmosquitto.so.${SOVERSION} +pub_shared.o : pub_shared.c ${SHARED_DEP} ${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS} -sub_client.o : sub_client.c ../lib/libmosquitto.so.${SOVERSION} +sub_client.o : sub_client.c ${SHARED_DEP} ${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS} -sub_client_output.o : sub_client_output.c ../lib/libmosquitto.so.${SOVERSION} +sub_client_output.o : sub_client_output.c ${SHARED_DEP} ${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS} client_shared.o : client_shared.c client_shared.h diff --git a/client/client_shared.c b/client/client_shared.c index b37d3067d4..517a6a6f78 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -152,7 +152,7 @@ void client_config_cleanup(struct mosq_config *cfg) free(cfg->keyfile); free(cfg->ciphers); free(cfg->tls_version); -# ifdef WITH_TLS_PSK +# ifdef FINAL_WITH_TLS_PSK free(cfg->psk); free(cfg->psk_identity); # endif @@ -316,7 +316,7 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * return 1; } #endif -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK if((cfg->cafile || cfg->capath) && cfg->psk){ if(!cfg->quiet) fprintf(stderr, "Error: Only one of --psk or --cafile/--capath may be used at once.\n"); return 1; @@ -734,7 +734,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c i++; } #endif -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK }else if(!strcmp(argv[i], "--psk")){ if(i==argc-1){ fprintf(stderr, "Error: --psk argument given but no key specified.\n\n"); @@ -977,7 +977,7 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg) mosquitto_lib_cleanup(); return 1; } -# ifdef WITH_TLS_PSK +# ifdef FINAL_WITH_TLS_PSK if(cfg->psk && mosquitto_tls_psk_set(mosq, cfg->psk, cfg->psk_identity, NULL)){ if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS-PSK options.\n"); mosquitto_lib_cleanup(); @@ -1038,14 +1038,18 @@ int client_id_generate(struct mosq_config *cfg, const char *id_base) int client_connect(struct mosquitto *mosq, struct mosq_config *cfg) { +#ifndef WIN32 + char *err; +#else char err[1024]; +#endif int rc; int port; if(cfg->port < 0){ #ifdef WITH_TLS if(cfg->cafile || cfg->capath -# ifdef WITH_TLS_PSK +# ifdef FINAL_WITH_TLS_PSK || cfg->psk # endif ){ @@ -1072,7 +1076,7 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg) if(!cfg->quiet){ if(rc == MOSQ_ERR_ERRNO){ #ifndef WIN32 - strerror_r(errno, err, 1024); + err = strerror(errno); #else FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errno, 0, (LPTSTR)&err, 1024, NULL); #endif diff --git a/client/client_shared.h b/client/client_shared.h index 1a8ad2800e..554f19e227 100644 --- a/client/client_shared.h +++ b/client/client_shared.h @@ -66,7 +66,7 @@ struct mosq_config { char *ciphers; bool insecure; char *tls_version; -# ifdef WITH_TLS_PSK +# ifdef FINAL_WITH_TLS_PSK char *psk; char *psk_identity; # endif diff --git a/client/pub_client.c b/client/pub_client.c index bede0032fc..4c9c75d558 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -123,7 +123,7 @@ void print_usage(void) #ifdef WITH_TLS printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n"); printf(" [--ciphers ciphers] [--insecure]]\n"); -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n"); #endif #endif @@ -183,7 +183,7 @@ void print_usage(void) printf(" hostname. Using this option means that you cannot be sure that the\n"); printf(" remote host is the server you wish to connect to and so is insecure.\n"); printf(" Do not use this option in a production environment.\n"); -# ifdef WITH_TLS_PSK +# ifdef FINAL_WITH_TLS_PSK printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n"); printf(" --psk-identity : client identity string for TLS-PSK mode.\n"); # endif diff --git a/client/sub_client.c b/client/sub_client.c index 62d91ca757..6cbf76f903 100644 --- a/client/sub_client.c +++ b/client/sub_client.c @@ -152,7 +152,7 @@ void print_usage(void) #ifdef WITH_TLS printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n"); printf(" [--ciphers ciphers] [--insecure]]\n"); -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n"); #endif #endif @@ -218,7 +218,7 @@ void print_usage(void) printf(" hostname. Using this option means that you cannot be sure that the\n"); printf(" remote host is the server you wish to connect to and so is insecure.\n"); printf(" Do not use this option in a production environment.\n"); -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n"); printf(" --psk-identity : client identity string for TLS-PSK mode.\n"); #endif diff --git a/client/sub_client_output.c b/client/sub_client_output.c index ab3f5e963a..4aeb8c3966 100644 --- a/client/sub_client_output.c +++ b/client/sub_client_output.c @@ -85,11 +85,11 @@ static void write_payload(const unsigned char *payload, int payloadlen, int hex) (void)fwrite(payload, 1, payloadlen, stdout); }else if(hex == 1){ for(i=0; i +# if defined(WITH_TLS_PSK) && !defined(OPENSSL_NO_PSK) +# define FINAL_WITH_TLS_PSK +# endif +#endif + #endif diff --git a/config.mk b/config.mk index f7a030dbc4..74844c114d 100644 --- a/config.mk +++ b/config.mk @@ -82,6 +82,9 @@ WITH_STRIP:=no # Build static libraries WITH_STATIC_LIBRARIES:=no +# Build shared libraries +WITH_SHARED_LIBRARIES:=yes + # Build with async dns lookup support for bridges (temporary). Requires glibc. #WITH_ADNS:=yes @@ -101,7 +104,7 @@ WITH_COVERAGE:=no # Also bump lib/mosquitto.h, CMakeLists.txt, # installer/mosquitto.nsi, installer/mosquitto64.nsi -VERSION=1.5.3 +VERSION=1.5.5 # Client library SO version. Bump if incompatible API/ABI changes are made. SOVERSION=1 @@ -146,7 +149,10 @@ ifeq ($(UNAME),Linux) LIB_LIBS:=$(LIB_LIBS) -lrt endif -CLIENT_LDFLAGS:=$(LDFLAGS) -L../lib ../lib/libmosquitto.so.${SOVERSION} +CLIENT_LDFLAGS:=$(LDFLAGS) -L../lib +ifeq ($(WITH_SHARED_LIBRARIES),yes) + CLIENT_LDFLAGS:=${CLIENT_LDFLAGS} ../lib/libmosquitto.so.${SOVERSION} +endif ifeq ($(UNAME),SunOS) ifeq ($(CC),cc) diff --git a/docker/1.4.10/Dockerfile b/docker/1.4.10/Dockerfile deleted file mode 100644 index 3101650b9f..0000000000 --- a/docker/1.4.10/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM alpine:3.5 -MAINTAINER David Audet - -LABEL Description="Eclipse Mosquitto MQTT Broker" - -RUN apk --no-cache add mosquitto=1.4.10-r2 && \ - mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \ - cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \ - chown -R mosquitto:mosquitto /mosquitto - -COPY docker-entrypoint.sh / -ENTRYPOINT ["/docker-entrypoint.sh"] -CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] diff --git a/docker/1.4.10/README.md b/docker/1.4.10/README.md deleted file mode 100644 index 98bb150dfe..0000000000 --- a/docker/1.4.10/README.md +++ /dev/null @@ -1,49 +0,0 @@ -#Eclipse Mosquitto v1.4.10 Docker Image - -##Mount Points - -Three mount points have been created in the image to be used for configuration, persistent storage and logs. -``` -/mosquitto/config -/mosquitto/data -/mosquitto/log -``` - - -##Configuration - -When running the image, the default configuration values are used. -To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` -``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.10 -``` - -Configuration can be changed to: - -* persist data to `/mosquitto/data` -* log to `/mosquitto/log/mosquitto.log` - -i.e. add the following to `mosquitto.conf`: -``` -persistence true -persistence_location /mosquitto/data/ - -log_dest file /mosquitto/log/mosquitto.log -``` - -**Note**: If a volume is used, the data will persist between containers. - -##Build -Build the image: -``` -docker build -t eclipse-mosquitto:1.4.10 . -``` - -##Run -Run a container using the new image: -``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto:1.4.10 -``` -:boom: if the mosquitto configuration (mosquitto.conf) was modified -to use non-default ports, the docker run command will need to be updated -to expose the ports that have been configured. diff --git a/docker/1.4.10/docker-entrypoint.sh b/docker/1.4.10/docker-entrypoint.sh deleted file mode 100755 index 1a9fc8d05f..0000000000 --- a/docker/1.4.10/docker-entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/ash - -set -e -exec "$@" - diff --git a/docker/1.4.14/Dockerfile b/docker/1.4.14/Dockerfile deleted file mode 100644 index 359cde1b48..0000000000 --- a/docker/1.4.14/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM alpine:edge -MAINTAINER David Audet - -LABEL Description="Eclipse Mosquitto MQTT Broker" - -RUN apk --no-cache add mosquitto=1.4.14-r0 && \ - mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \ - cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \ - chown -R mosquitto:mosquitto /mosquitto - -COPY docker-entrypoint.sh / -ENTRYPOINT ["/docker-entrypoint.sh"] -CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] diff --git a/docker/1.4.4/Dockerfile b/docker/1.4.4/Dockerfile deleted file mode 100644 index bd757e3b4a..0000000000 --- a/docker/1.4.4/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM alpine:3.3 -MAINTAINER David Audet - -LABEL Description="Eclipse Mosquitto MQTT Broker" - -RUN apk --no-cache add mosquitto=1.4.4-r0 && \ - mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \ - cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \ - chown -R mosquitto:mosquitto /mosquitto - -COPY docker-entrypoint.sh / -ENTRYPOINT ["/docker-entrypoint.sh"] -CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] diff --git a/docker/1.4.4/README.md b/docker/1.4.4/README.md deleted file mode 100644 index 4f01fee9ed..0000000000 --- a/docker/1.4.4/README.md +++ /dev/null @@ -1,49 +0,0 @@ -#Eclipse Mosquitto v1.4.4 Docker Image - -##Mount Points - -Three mount points have been created in the image to be used for configuration, persistent storage and logs. -``` -/mosquitto/config -/mosquitto/data -/mosquitto/log -``` - - -##Configuration - -When running the image, the default configuration values are used. -To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` -``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.4 -``` - -Configuration can be changed to: - -* persist data to `/mosquitto/data` -* log to `/mosquitto/log/mosquitto.log` - -i.e. add the following to `mosquitto.conf`: -``` -persistence true -persistence_location /mosquitto/data/ - -log_dest file /mosquitto/log/mosquitto.log -``` - -**Note**: If a volume is used, the data will persist between containers. - -##Build -Build the image: -``` -docker build -t eclipse-mosquitto:1.4.4 . -``` - -##Run -Run a container using the new image: -``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto:1.4.4 -``` -:boom: if the mosquitto configuration (mosquitto.conf) was modified -to use non-default ports, the docker run command will need to be updated -to expose the ports that have been configured. \ No newline at end of file diff --git a/docker/1.4.8/Dockerfile b/docker/1.4.8/Dockerfile deleted file mode 100644 index a9027a7895..0000000000 --- a/docker/1.4.8/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM alpine:3.4 -MAINTAINER David Audet - -LABEL Description="Eclipse Mosquitto MQTT Broker" - -RUN apk --no-cache add mosquitto=1.4.8-r2 && \ - mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \ - cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \ - chown -R mosquitto:mosquitto /mosquitto - -COPY docker-entrypoint.sh / -ENTRYPOINT ["/docker-entrypoint.sh"] -CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] diff --git a/docker/1.4.8/README.md b/docker/1.4.8/README.md deleted file mode 100644 index d78f517fb2..0000000000 --- a/docker/1.4.8/README.md +++ /dev/null @@ -1,49 +0,0 @@ -#Eclipse Mosquitto v1.4.8 Docker Image - -##Mount Points - -Three mount points have been created in the image to be used for configuration, persistent storage and logs. -``` -/mosquitto/config -/mosquitto/data -/mosquitto/log -``` - - -##Configuration - -When running the image, the default configuration values are used. -To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` -``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.8 -``` - -Configuration can be changed to: - -* persist data to `/mosquitto/data` -* log to `/mosquitto/log/mosquitto.log` - -i.e. add the following to `mosquitto.conf`: -``` -persistence true -persistence_location /mosquitto/data/ - -log_dest file /mosquitto/log/mosquitto.log -``` - -**Note**: If a volume is used, the data will persist between containers. - -##Build -Build the image: -``` -docker build -t eclipse-mosquitto:1.4.8 . -``` - -##Run -Run a container using the new image: -``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto:1.4.8 -``` -:boom: if the mosquitto configuration (mosquitto.conf) was modified -to use non-default ports, the docker run command will need to be updated -to expose the ports that have been configured. diff --git a/docker/1.4.8/docker-entrypoint.sh b/docker/1.4.8/docker-entrypoint.sh deleted file mode 100755 index 1a9fc8d05f..0000000000 --- a/docker/1.4.8/docker-entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/ash - -set -e -exec "$@" - diff --git a/docker/1.5/Dockerfile b/docker/1.5/Dockerfile new file mode 100644 index 0000000000..2c9b15c67f --- /dev/null +++ b/docker/1.5/Dockerfile @@ -0,0 +1,88 @@ +FROM alpine:3.8 + +LABEL maintainer="Roger Light " \ + description="Eclipse Mosquitto MQTT Broker" + +ENV VERSION=1.5.5 \ + DOWNLOAD_SHA256=fcdb47e340864c545146681af7253399cc292e41775afd76400fda5b0d23d668 \ + GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \ + LWS_VERSION=2.4.2 + +RUN set -x && \ + apk --no-cache add --virtual build-deps \ + build-base \ + cmake \ + gnupg \ + libressl-dev \ + util-linux-dev && \ + wget https://github.com/warmcat/libwebsockets/archive/v${LWS_VERSION}.tar.gz -O /tmp/lws.tar.gz && \ + mkdir -p /build/lws && \ + tar --strip=1 -xf /tmp/lws.tar.gz -C /build/lws && \ + rm /tmp/lws.tar.gz && \ + cd /build/lws && \ + cmake . \ + -DCMAKE_BUILD_TYPE=MinSizeRel \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DLWS_IPV6=ON \ + -DLWS_WITHOUT_BUILTIN_GETIFADDRS=ON \ + -DLWS_WITHOUT_CLIENT=ON \ + -DLWS_WITHOUT_EXTENSIONS=ON \ + -DLWS_WITHOUT_TESTAPPS=ON \ + -DLWS_WITH_SHARED=OFF \ + -DLWS_WITH_ZIP_FOPS=OFF \ + -DLWS_WITH_ZLIB=OFF && \ + make -j "$(nproc)" && \ + rm -rf /root/.cmake && \ + wget https://mosquitto.org/files/source/mosquitto-${VERSION}.tar.gz -O /tmp/mosq.tar.gz && \ + echo "$DOWNLOAD_SHA256 /tmp/mosq.tar.gz" | sha256sum -c - && \ + wget https://mosquitto.org/files/source/mosquitto-${VERSION}.tar.gz.asc -O /tmp/mosq.tar.gz.asc && \ + export GNUPGHOME="$(mktemp -d)" && \ + found=''; \ + for server in \ + ha.pool.sks-keyservers.net \ + hkp://keyserver.ubuntu.com:80 \ + hkp://p80.pool.sks-keyservers.net:80 \ + pgp.mit.edu \ + ; do \ + echo "Fetching GPG key $GPG_KEYS from $server"; \ + gpg --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$GPG_KEYS" && found=yes && break; \ + done; \ + test -z "$found" && echo >&2 "error: failed to fetch GPG key $GPG_KEYS" && exit 1; \ + gpg --batch --verify /tmp/mosq.tar.gz.asc /tmp/mosq.tar.gz && \ + gpgconf --kill all && \ + rm -rf "$GNUPGHOME" /tmp/mosq.tar.gz.asc && \ + mkdir -p /build/mosq && \ + tar --strip=1 -xf /tmp/mosq.tar.gz -C /build/mosq && \ + rm /tmp/mosq.tar.gz && \ + make -C /build/mosq -j "$(nproc)" \ + CFLAGS="-Wall -O2 -I/build/lws/include -flto" \ + LDFLAGS="-L/build/lws/lib -flto" \ + WITH_ADNS=no \ + WITH_DOCS=no \ + WITH_MEMORY_TRACKING=no \ + WITH_SHARED_LIBRARIES=no \ + WITH_SRV=no \ + WITH_STRIP=yes \ + WITH_TLS_PSK=no \ + WITH_WEBSOCKETS=yes \ + prefix=/usr \ + binary && \ + addgroup -S -g 1883 mosquitto 2>/dev/null && \ + adduser -S -u 1883 -D -H -h /var/empty -s /sbin/nologin -G mosquitto -g mosquitto mosquitto 2>/dev/null && \ + mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \ + install -d /usr/sbin/ && \ + install -s -m755 /build/mosq/src/mosquitto /usr/sbin/mosquitto && \ + install -s -m755 /build/mosq/src/mosquitto_passwd /usr/bin/mosquitto_passwd && \ + install -m644 /build/mosq/mosquitto.conf /mosquitto/config/mosquitto.conf && \ + chown -R mosquitto:mosquitto /mosquitto && \ + apk --no-cache add \ + libuuid && \ + apk del build-deps && \ + rm -rf /build + +VOLUME ["/mosquitto/data", "/mosquitto/log"] + +# Set up the entry point script and default command +COPY docker-entrypoint.sh / +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] diff --git a/docker/1.5/README.md b/docker/1.5/README.md new file mode 100644 index 0000000000..27b05904c9 --- /dev/null +++ b/docker/1.5/README.md @@ -0,0 +1,49 @@ +# Eclipse Mosquitto Docker Image +Containers built with this Dockerfile build as source from published tarballs. + +## Mount Points +A docker mount point has been created in the image to be used for configuration. +``` +/mosquitto/config +``` + +Two docker volumes have been created in the image to be used for persistent storage and logs. +``` +/mosquitto/data +/mosquitto/log +``` + +## User/Group + +The image runs mosqutto under the mosquitto user and group, which are created +with a uid and gid of 1883. + +## Configuration +When creating a container from the image, the default configuration values are used. +To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` +``` +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +``` + +:boom: if the mosquitto configuration (mosquitto.conf) was modified +to use non-default ports, the docker run command will need to be updated +to expose the ports that have been configured, for example: + +``` +docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +``` + +Configuration can be changed to: + +* persist data to `/mosquitto/data` +* log to `/mosquitto/log/mosquitto.log` + +i.e. add the following to `mosquitto.conf`: +``` +persistence true +persistence_location /mosquitto/data/ + +log_dest file /mosquitto/log/mosquitto.log +``` + +**Note**: For any volume used, the data will be persistent between containers. diff --git a/docker/1.4.14/docker-entrypoint.sh b/docker/1.5/docker-entrypoint.sh similarity index 96% rename from docker/1.4.14/docker-entrypoint.sh rename to docker/1.5/docker-entrypoint.sh index 1a9fc8d05f..b381ac5775 100755 --- a/docker/1.4.14/docker-entrypoint.sh +++ b/docker/1.5/docker-entrypoint.sh @@ -1,5 +1,4 @@ #!/bin/ash - set -e -exec "$@" +exec "$@" diff --git a/docker/README.md b/docker/README.md index 6fe5506c99..06db82b1f1 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,4 +1,19 @@ # Docker Images -This directory contains the required files to build Mosquitto Docker images. +This directory contains Docker files for Mosquitto. + +The `1.5` directory contains the latest version of Mosquitto for +that series, and provide the basis of the official image. + +`1.4.12` is the version using Alpine packaged Mosquitto, which will be removed +at the next minor release. + +The `generic` directory contains a generic Dockerfile that can be used to build +arbitrary versions of Mosquitto based on the released tarballs as follows: + +``` +cd generic +docker build -t eclipse-mosquitto:1.5.1 --build-arg VERSION="1.5.1" . +docker run --rm -it eclipse-mosquitto:1.5.1 +``` diff --git a/docker/generic/Dockerfile b/docker/generic/Dockerfile new file mode 100644 index 0000000000..51c1d18154 --- /dev/null +++ b/docker/generic/Dockerfile @@ -0,0 +1,70 @@ +FROM alpine:latest AS build + +# A released dist version, like "1.2.3" +ARG VERSION +RUN test -n "${VERSION}" + +RUN apk --no-cache add \ + build-base \ + libressl-dev \ + c-ares-dev \ + curl \ + util-linux-dev \ + libwebsockets-dev \ + libxslt \ + python2 + +# This build procedure is based on: +# https://github.com/alpinelinux/aports/blob/master/main/mosquitto/APKBUILD +# +# If this step fails, double check the version build-arg and make sure its +# a valid published tarball at https://mosquitto.org/files/source/ +RUN mkdir -p /build /install && \ + curl -SL https://mosquitto.org/files/source/mosquitto-${VERSION}.tar.gz \ + | tar --strip=1 -xzC /build && \ + make -C /build \ + WITH_MEMORY_TRACKING=no \ + WITH_WEBSOCKETS=yes \ + WITH_SRV=yes \ + WITH_TLS_PSK=no \ + WITH_ADNS=no \ + prefix=/usr \ + binary && \ + make -C /build \ + prefix=/usr \ + DESTDIR="/install" \ + install && \ + mv /install/etc/mosquitto/mosquitto.conf.example /install/etc/mosquitto/mosquitto.conf && \ + sed -i -e 's/#log_dest stderr/log_dest syslog/' /install/etc/mosquitto/mosquitto.conf + + +# Single-layer image for the mosquitto distribution +FROM alpine:latest +LABEL maintainer="Jonathan Hanson " \ + description="Eclipse Mosquitto MQTT Broker" + +# Install the run-time dependencies +RUN apk --no-cache add \ + busybox \ + libcrypto1.0 \ + libssl1.0 \ + libuuid \ + libwebsockets \ + musl + +# Copy over the built install from the earlier image layer +COPY --from=build /install / + +# Set up the mosquitto directories and the mosquitto user +RUN addgroup -S mosquitto 2>/dev/null && \ + adduser -S -D -H -h /var/empty -s /sbin/nologin -G mosquitto -g mosquitto mosquitto 2>/dev/null && \ + mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \ + cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \ + chown -R mosquitto:mosquitto /mosquitto + +VOLUME ["/mosquitto/config", "/mosquitto/data", "/mosquitto/log"] + +# Set up the entry point script and default command +COPY docker-entrypoint.sh / +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] diff --git a/docker/1.4.14/README.md b/docker/generic/README.md similarity index 51% rename from docker/1.4.14/README.md rename to docker/generic/README.md index 206f8d3139..421cb91d90 100644 --- a/docker/1.4.14/README.md +++ b/docker/generic/README.md @@ -1,21 +1,19 @@ -#Eclipse Mosquitto v1.4.14 Docker Image +# Eclipse Mosquitto Docker Image +Containers built with this Dockerfile build as source from published tarballs. -##Mount Points - -Three mount points have been created in the image to be used for configuration, persistent storage and logs. +## Mount Points +Three docker volumes have been created in the image to be used for configuration, persistent storage and logs. ``` /mosquitto/config /mosquitto/data /mosquitto/log ``` - -##Configuration - -When running the image, the default configuration values are used. +## Configuration +When creating a container from the image, the default configuration values are used. To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.14 +docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: ``` Configuration can be changed to: @@ -31,18 +29,18 @@ persistence_location /mosquitto/data/ log_dest file /mosquitto/log/mosquitto.log ``` -**Note**: If a volume is used, the data will persist between containers. +**Note**: For any volume used, the data will be persistent between containers. -##Build -Build the image: +## Build +Build and tag the docker image for a specific version: ``` -docker build -t eclipse-mosquitto:1.4.14 . +docker build -t eclipse-mosquitto: --build-arg VERSION="" . ``` -##Run +## Run Run a container using the new image: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto:1.4.14 +docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto: ``` :boom: if the mosquitto configuration (mosquitto.conf) was modified to use non-default ports, the docker run command will need to be updated diff --git a/docker/1.4.4/docker-entrypoint.sh b/docker/generic/docker-entrypoint.sh similarity index 96% rename from docker/1.4.4/docker-entrypoint.sh rename to docker/generic/docker-entrypoint.sh index 1a9fc8d05f..b381ac5775 100755 --- a/docker/1.4.4/docker-entrypoint.sh +++ b/docker/generic/docker-entrypoint.sh @@ -1,5 +1,4 @@ #!/bin/ash - set -e -exec "$@" +exec "$@" diff --git a/installer/mosquitto.nsi b/installer/mosquitto.nsi index b97f6f3a33..0574e0b10e 100644 --- a/installer/mosquitto.nsi +++ b/installer/mosquitto.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.5.3 +!define VERSION 1.5.5 OutFile "mosquitto-${VERSION}-install-windows-x86.exe" InstallDir "$PROGRAMFILES\mosquitto" @@ -18,8 +18,7 @@ InstallDir "$PROGRAMFILES\mosquitto" ; Installer pages !insertmacro MUI_PAGE_WELCOME -Page custom DependencyPage -!insertmacro MUI_PAGE_COMPONENTS +;!insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH @@ -55,8 +54,8 @@ Section "Files" SecInstall File "..\readme.md" File "..\readme-windows.txt" ;File "C:\pthreads\Pre-built.2\dll\x86\pthreadVC2.dll" - ;File "C:\OpenSSL-Win32\bin\libssl_1-1.dll" - ;File "C:\OpenSSL-Win32\bin\libcrypto_1-1.dll" + File "C:\OpenSSL-Win32\bin\libssl-1_1.dll" + File "C:\OpenSSL-Win32\bin\libcrypto-1_1.dll" File "..\edl-v10" File "..\epl-v10" @@ -96,8 +95,8 @@ Section "Uninstall" Delete "$INSTDIR\readme.txt" Delete "$INSTDIR\readme-windows.txt" ;Delete "$INSTDIR\pthreadVC2.dll" - ;Delete "$INSTDIR\libssl_1-1.dll" - ;Delete "$INSTDIR\libcrypto_1-1.dll" + Delete "$INSTDIR\libssl-1_1.dll" + Delete "$INSTDIR\libcrypto-1_1.dll" Delete "$INSTDIR\edl-v10" Delete "$INSTDIR\epl-v10" @@ -120,28 +119,3 @@ LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation." !insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall) !insertmacro MUI_FUNCTION_DESCRIPTION_END -Var Dialog -Var OSSLLink -Var PTHLink - -Function DependencyPage - nsDialogs::Create 1018 - Pop $Dialog - - ${If} $Dialog == error - Abort - ${EndIf} - - ${NSD_CreateLabel} 0 0 100% 12u "OpenSSL - install 'Win32 OpenSSL v1.1.0* Light' then copy libssl_1-1.dll and libcrypto_1-1.dll to the mosquitto directory" - ${NSD_CreateLink} 13u 13u 100% 12u "http://slproweb.com/products/Win32OpenSSL.html" - Pop $OSSLLink - ${NSD_OnClick} $OSSLLink OnClick_OSSL - - !insertmacro MUI_HEADER_TEXT_PAGE "Dependencies" "This page lists packages that must be installed if not already present" - nsDialogs::Show -FunctionEnd - -Function OnClick_OSSL - Pop $0 - ExecShell "open" "http://slproweb.com/products/Win32OpenSSL.html" -FunctionEnd diff --git a/installer/mosquitto64.nsi b/installer/mosquitto64.nsi index 59acea1a10..5e9706c4b5 100644 --- a/installer/mosquitto64.nsi +++ b/installer/mosquitto64.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.5.3 +!define VERSION 1.5.5 OutFile "mosquitto-${VERSION}-install-windows-x64.exe" !include "x64.nsh" @@ -19,8 +19,7 @@ InstallDir "$PROGRAMFILES64\mosquitto" ; Installer pages !insertmacro MUI_PAGE_WELCOME -Page custom DependencyPage -!insertmacro MUI_PAGE_COMPONENTS +;!insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH @@ -56,8 +55,8 @@ Section "Files" SecInstall File "..\readme.md" File "..\readme-windows.txt" ;File "C:\pthreads\Pre-built.2\dll\x64\pthreadVC2.dll" - ;File "C:\OpenSSL-Win64\bin\libssl_1-1-x64.dll" - ;File "C:\OpenSSL-Win64\bin\libcrypto_1-1-x64.dll" + File "C:\OpenSSL-Win64\bin\libssl-1_1-x64.dll" + File "C:\OpenSSL-Win64\bin\libcrypto-1_1-x64.dll" File "..\edl-v10" File "..\epl-v10" @@ -97,8 +96,8 @@ Section "Uninstall" Delete "$INSTDIR\readme.txt" Delete "$INSTDIR\readme-windows.txt" ;Delete "$INSTDIR\pthreadVC2.dll" - ;Delete "$INSTDIR\libssl_1-1-x64.dll" - ;Delete "$INSTDIR\libcrypto_1-1-x64.dll" + Delete "$INSTDIR\libssl-1_1-x64.dll" + Delete "$INSTDIR\libcrypto-1_1-x64.dll" Delete "$INSTDIR\edl-v10" Delete "$INSTDIR\epl-v10" @@ -121,28 +120,3 @@ LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation." !insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall) !insertmacro MUI_FUNCTION_DESCRIPTION_END -Var Dialog -Var OSSLLink -Var PTHLink - -Function DependencyPage - nsDialogs::Create 1018 - Pop $Dialog - - ${If} $Dialog == error - Abort - ${EndIf} - - ${NSD_CreateLabel} 0 0 100% 12u "OpenSSL - install 'Win64 OpenSSL v1.1.0* Light' then copy libssl_1-1-x64.dll and libcrypto_1-1-x64.dll to the mosquitto directory" - ${NSD_CreateLink} 13u 13u 100% 12u "http://slproweb.com/products/Win32OpenSSL.html" - Pop $OSSLLink - ${NSD_OnClick} $OSSLLink OnClick_OSSL - - !insertmacro MUI_HEADER_TEXT_PAGE "Dependencies" "This page lists packages that must be installed if not already present" - nsDialogs::Show -FunctionEnd - -Function OnClick_OSSL - Pop $0 - ExecShell "open" "http://slproweb.com/products/Win32OpenSSL.html" -FunctionEnd diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index da5164800a..7b22c44d1b 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -2,30 +2,6 @@ option(WITH_STATIC_LIBRARIES "Build static versions of the libmosquitto/pp libra option(WITH_PIC "Build the static library with PIC (Position Independent Code) enabled archives?" OFF) add_subdirectory(cpp) -option(WITH_THREADING "Include client library threading support?" ON) -if (${WITH_THREADING} STREQUAL ON) - add_definitions("-DWITH_THREADING") - if (WIN32) - if (CMAKE_CL_64) - set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x64\\pthreadVC2.lib) - else (CMAKE_CL_64) - set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x86\\pthreadVC2.lib) - endif (CMAKE_CL_64) - set (PTHREAD_INCLUDE_DIR C:\\pthreads\\Pre-built.2\\include) - else (WIN32) - find_library(LIBPTHREAD pthread) - if (LIBPTHREAD) - set (PTHREAD_LIBRARIES pthread) - else (LIBPTHREAD) - set (PTHREAD_LIBRARIES "") - endif() - set (PTHREAD_INCLUDE_DIR "") - endif (WIN32) -else (${WITH_THREADING} STREQUAL ON) - set (PTHREAD_LIBRARIES "") - set (PTHREAD_INCLUDE_DIR "") -endif (${WITH_THREADING} STREQUAL ON) - include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/lib ${STDBOOL_H_PATH} ${STDINT_H_PATH} ${OPENSSL_INCLUDE_DIR} ${PTHREAD_INCLUDE_DIR}) diff --git a/lib/Makefile b/lib/Makefile index 8e310e6119..efce2c9843 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -43,19 +43,27 @@ MOSQ_OBJS=mosquitto.o \ util_topic.o \ will_mosq.o -ALL_DEPS=libmosquitto.so.${SOVERSION} +ALL_DEPS:= + +ifeq ($(WITH_SHARED_LIBRARIES),yes) + ALL_DEPS+=libmosquitto.so.${SOVERSION} +endif ifeq ($(WITH_STATIC_LIBRARIES),yes) ALL_DEPS+=libmosquitto.a endif all : ${ALL_DEPS} +ifeq ($(WITH_SHARED_LIBRARIES),yes) $(MAKE) -C cpp +endif install : all $(INSTALL) -d "${DESTDIR}${libdir}/" +ifeq ($(WITH_SHARED_LIBRARIES),yes) $(INSTALL) ${STRIP_OPTS} libmosquitto.so.${SOVERSION} "${DESTDIR}${libdir}/libmosquitto.so.${SOVERSION}" ln -sf libmosquitto.so.${SOVERSION} "${DESTDIR}${libdir}/libmosquitto.so" +endif ifeq ($(WITH_STATIC_LIBRARIES),yes) $(INSTALL) ${STRIP_OPTS} libmosquitto.a "${DESTDIR}${libdir}/libmosquitto.a" endif @@ -64,7 +72,9 @@ endif $(INSTALL) -d "${DESTDIR}${libdir}/pkgconfig" $(INSTALL) -m644 ../libmosquitto.pc.in "${DESTDIR}${libdir}/pkgconfig/libmosquitto.pc" sed -i -e "s#@CMAKE_INSTALL_PREFIX@#${prefix}#" -e "s#@VERSION@#${VERSION}#" "${DESTDIR}${libdir}/pkgconfig/libmosquitto.pc" +ifeq ($(WITH_SHARED_LIBRARIES),yes) $(MAKE) -C cpp install +endif uninstall : -rm -f "${DESTDIR}${libdir}/libmosquitto.so.${SOVERSION}" diff --git a/lib/loop.c b/lib/loop.c index 628d7d12dd..d3ee0c5262 100644 --- a/lib/loop.c +++ b/lib/loop.c @@ -147,19 +147,9 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets) }else{ if(mosq->sock != INVALID_SOCKET){ if(FD_ISSET(mosq->sock, &readfds)){ -#ifdef WITH_TLS - if(mosq->want_connect){ - rc = net__socket_connect_tls(mosq); - if(rc) return rc; - }else -#endif - { - do{ - rc = mosquitto_loop_read(mosq, max_packets); - if(rc || mosq->sock == INVALID_SOCKET){ - return rc; - } - }while(SSL_DATA_PENDING(mosq)); + rc = mosquitto_loop_read(mosq, max_packets); + if(rc || mosq->sock == INVALID_SOCKET){ + return rc; } } if(mosq->sockpairR != INVALID_SOCKET && FD_ISSET(mosq->sockpairR, &readfds)){ @@ -253,8 +243,12 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) }else{ pthread_mutex_unlock(&mosq->state_mutex); - if(mosq->reconnect_delay > 0 && mosq->reconnect_exponential_backoff){ - reconnect_delay = mosq->reconnect_delay*reconnects*reconnects; + if(mosq->reconnect_delay_max > mosq->reconnect_delay){ + if(mosq->reconnect_exponential_backoff){ + reconnect_delay = mosq->reconnect_delay*(reconnects+1)*(reconnects+1); + }else{ + reconnect_delay = mosq->reconnect_delay*(reconnects+1); + } }else{ reconnect_delay = mosq->reconnect_delay; } @@ -292,42 +286,10 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) int mosquitto_loop_misc(struct mosquitto *mosq) { - time_t now; - int rc; - if(!mosq) return MOSQ_ERR_INVAL; if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; - mosquitto__check_keepalive(mosq); - now = mosquitto_time(); - - if(mosq->ping_t && now - mosq->ping_t >= mosq->keepalive){ - /* mosq->ping_t != 0 means we are waiting for a pingresp. - * This hasn't happened in the keepalive time so we should disconnect. - */ - net__socket_close(mosq); - pthread_mutex_lock(&mosq->state_mutex); - if(mosq->state == mosq_cs_disconnecting){ - rc = MOSQ_ERR_SUCCESS; - }else{ - rc = MOSQ_ERR_KEEPALIVE; - } - pthread_mutex_unlock(&mosq->state_mutex); - pthread_mutex_lock(&mosq->callback_mutex); - if(mosq->on_disconnect){ - mosq->in_callback = true; - mosq->on_disconnect(mosq, mosq->userdata, rc); - mosq->in_callback = false; - } - if(mosq->on_disconnect_v5){ - mosq->in_callback = true; - mosq->on_disconnect_v5(mosq, mosq->userdata, rc, NULL); - mosq->in_callback = false; - } - pthread_mutex_unlock(&mosq->callback_mutex); - return MOSQ_ERR_CONN_LOST; - } - return MOSQ_ERR_SUCCESS; + return mosquitto__check_keepalive(mosq); } @@ -364,6 +326,12 @@ int mosquitto_loop_read(struct mosquitto *mosq, int max_packets) int i; if(max_packets < 1) return MOSQ_ERR_INVAL; +#ifdef WITH_TLS + if(mosq->want_connect){ + return net__socket_connect_tls(mosq); + } +#endif + pthread_mutex_lock(&mosq->out_message_mutex); max_packets = mosq->out_queue_len; pthread_mutex_unlock(&mosq->out_message_mutex); @@ -376,7 +344,7 @@ int mosquitto_loop_read(struct mosquitto *mosq, int max_packets) /* Queue len here tells us how many messages are awaiting processing and * have QoS > 0. We should try to deal with that many in this loop in order * to keep up. */ - for(i=0; isocks5_host){ rc = socks5__read(mosq); diff --git a/lib/mosquitto.h b/lib/mosquitto.h index bb1524bd0d..1c91d7fb80 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -48,7 +48,7 @@ extern "C" { #define LIBMOSQUITTO_MAJOR 1 #define LIBMOSQUITTO_MINOR 5 -#define LIBMOSQUITTO_REVISION 3 +#define LIBMOSQUITTO_REVISION 5 /* 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) diff --git a/lib/net_mosq.c b/lib/net_mosq.c index e7dc8aeb98..2fb6b16792 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -183,7 +183,7 @@ int net__socket_close(struct mosquitto *mosq) } -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) @@ -208,21 +208,39 @@ int net__try_connect_step1(struct mosquitto *mosq, const char *host) { int s; void *sevp = NULL; + struct addrinfo *hints; if(mosq->adns){ + gai_cancel(mosq->adns); + mosquitto__free((struct addrinfo *)mosq->adns->ar_request); mosquitto__free(mosq->adns); } mosq->adns = mosquitto__calloc(1, sizeof(struct gaicb)); if(!mosq->adns){ return MOSQ_ERR_NOMEM; } + + hints = mosquitto__calloc(1, sizeof(struct addrinfo)); + if(!hints){ + mosquitto__free(mosq->adns); + mosq->adns = NULL; + return MOSQ_ERR_NOMEM; + } + + hints->ai_family = AF_UNSPEC; + hints->ai_socktype = SOCK_STREAM; + mosq->adns->ar_name = host; + mosq->adns->ar_request = hints; s = getaddrinfo_a(GAI_NOWAIT, &mosq->adns, 1, sevp); if(s){ errno = s; - mosquitto__free(mosq->adns); - mosq->adns = NULL; + if(mosq->adns){ + mosquitto__free((struct addrinfo *)mosq->adns->ar_request); + mosquitto__free(mosq->adns); + mosq->adns = NULL; + } return MOSQ_ERR_EAI; } @@ -278,6 +296,7 @@ int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *s freeaddrinfo(mosq->adns->ar_result); mosq->adns->ar_result = NULL; + mosquitto__free((struct addrinfo *)mosq->adns->ar_request); mosquitto__free(mosq->adns); mosq->adns = NULL; @@ -575,7 +594,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) return MOSQ_ERR_TLS; } } -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK }else if(mosq->tls_psk){ SSL_CTX_set_psk_client_callback(mosq->ssl_ctx, psk_client_callback); #endif @@ -596,6 +615,9 @@ int net__socket_connect_step3(struct mosquitto *mosq, const char *host, uint16_t if(rc) return rc; if(mosq->ssl_ctx){ + if(mosq->ssl){ + SSL_free(mosq->ssl); + } mosq->ssl = SSL_new(mosq->ssl_ctx); if(!mosq->ssl){ COMPAT_CLOSE(mosq->sock); diff --git a/lib/options.c b/lib/options.c index 7f18993e6b..85a9cba1a2 100644 --- a/lib/options.c +++ b/lib/options.c @@ -91,6 +91,8 @@ int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect { if(!mosq) return MOSQ_ERR_INVAL; + if(reconnect_delay == 0) reconnect_delay = 1; + mosq->reconnect_delay = reconnect_delay; mosq->reconnect_delay_max = reconnect_delay_max; mosq->reconnect_exponential_backoff = reconnect_exponential_backoff; @@ -236,7 +238,7 @@ int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value) int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers) { -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK if(!mosq || !psk || !identity) return MOSQ_ERR_INVAL; /* Check for hex only digits */ diff --git a/lib/socks_mosq.c b/lib/socks_mosq.c index 5f43d16aa7..f0e4c8d219 100644 --- a/lib/socks_mosq.c +++ b/lib/socks_mosq.c @@ -21,9 +21,16 @@ and the Eclipse Distribution License is available at #include #ifdef WIN32 # include +#elif __QNX__ +# include +# include #else # include #endif +#ifdef __FreeBSD__ +# include +# include +#endif #include "mosquitto_internal.h" #include "memory_mosq.h" diff --git a/lib/util_mosq.c b/lib/util_mosq.c index e67eaa1533..07ba6afb9b 100644 --- a/lib/util_mosq.c +++ b/lib/util_mosq.c @@ -46,9 +46,9 @@ and the Eclipse Distribution License is available at #endif #ifdef WITH_BROKER -void mosquitto__check_keepalive(struct mosquitto_db *db, struct mosquitto *mosq) +int mosquitto__check_keepalive(struct mosquitto_db *db, struct mosquitto *mosq) #else -void mosquitto__check_keepalive(struct mosquitto *mosq) +int mosquitto__check_keepalive(struct mosquitto *mosq) #endif { time_t next_msg_out; @@ -67,7 +67,7 @@ void mosquitto__check_keepalive(struct mosquitto *mosq) log__printf(NULL, MOSQ_LOG_NOTICE, "Bridge connection %s has exceeded idle timeout, disconnecting.", mosq->id); net__socket_close(db, mosq); - return; + return MOSQ_ERR_SUCCESS; } #endif pthread_mutex_lock(&mosq->msgtime_mutex); @@ -113,9 +113,12 @@ void mosquitto__check_keepalive(struct mosquitto *mosq) mosq->in_callback = false; } pthread_mutex_unlock(&mosq->callback_mutex); + + return rc; #endif } } + return MOSQ_ERR_SUCCESS; } uint16_t mosquitto__mid_generate(struct mosquitto *mosq) @@ -140,7 +143,7 @@ uint16_t mosquitto__mid_generate(struct mosquitto *mosq) } -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK int mosquitto__hex2bin(const char *hex, unsigned char *bin, int bin_max_len) { BIGNUM *bn = NULL; diff --git a/lib/util_mosq.h b/lib/util_mosq.h index 0e65dd9889..d94661e7aa 100644 --- a/lib/util_mosq.h +++ b/lib/util_mosq.h @@ -26,14 +26,14 @@ and the Eclipse Distribution License is available at #endif #ifdef WITH_BROKER -void mosquitto__check_keepalive(struct mosquitto_db *db, struct mosquitto *mosq); +int mosquitto__check_keepalive(struct mosquitto_db *db, struct mosquitto *mosq); #else -void mosquitto__check_keepalive(struct mosquitto *mosq); +int mosquitto__check_keepalive(struct mosquitto *mosq); #endif uint16_t mosquitto__mid_generate(struct mosquitto *mosq); FILE *mosquitto__fopen(const char *path, const char *mode, bool restrict_read); -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK int mosquitto__hex2bin(const char *hex, unsigned char *bin, int bin_max_len); #endif diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index dbfce513a2..97509b0544 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -842,6 +842,27 @@ Not reloaded on reload signal. + + [ ipv4 | ipv6 ] + + By default, a listener will attempt to listen on + all supported IP protocol versions. If you do not + have an IPv4 or IPv6 interface you may wish to + disable support for either of those protocol + versions. In particular, note that due to the + limitations of the websockets library, it will only + ever attempt to open IPv6 sockets if IPv6 support + is compiled in, and so will fail if IPv6 is not + available. + Set to to force the + listener to only use IPv4, or set to + to force the listener to only + use IPv6. If you want support for both IPv4 and + IPv6, then do not use the + option. + Not reloaded on reload signal. + + [ true | false ] diff --git a/set-version.sh b/set-version.sh index 522dfa1d39..ec105f6bdb 100755 --- a/set-version.sh +++ b/set-version.sh @@ -2,7 +2,7 @@ MAJOR=1 MINOR=5 -REVISION=3 +REVISION=5 sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 7ce01902b3..b6ede932e0 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: mosquitto -version: 1.5.3 +version: 1.5.5 summary: Eclipse Mosquitto MQTT broker description: This is a message broker that supports version 3.1 and 3.1.1 of the MQTT protocol. @@ -26,6 +26,9 @@ apps: command: usr/bin/mosquitto_sub plugs: [network] + passwd: + command: usr/bin/mosquitto_passwd + parts: script: @@ -61,9 +64,13 @@ parts: - usr/sbin/mosquitto - usr/bin/mosquitto_pub - usr/bin/mosquitto_sub + - usr/bin/mosquitto_passwd - usr/lib/libmosquitto.so* - lib/*-linux-gnu/libcrypto.so* - lib/*-linux-gnu/libssl.so* + - usr/include/mosquitto.h + - usr/include/mosquitto_broker.h + - usr/include/mosquitto_plugin.h lws: plugin: cmake diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 960b263a2f..274f102e81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -131,17 +131,18 @@ if (HAVE_GETADDRINFO_A) endif (HAVE_GETADDRINFO_A) - if (UNIX) if (APPLE) set (MOSQ_LIBS ${MOSQ_LIBS} dl m) - else (APPLE) - set (MOSQ_LIBS ${MOSQ_LIBS} dl m) - find_library(LIBRT rt) - if (LIBRT) - set (MOSQ_LIBS ${MOSQ_LIBS} rt) - endif (LIBRT) - endif (APPLE) + elseif(QNX) + set(MOSQ_LIBS ${MOSQ_LIBS} m socket) + else(APPLE) + set (MOSQ_LIBS ${MOSQ_LIBS} dl m) + find_library(LIBRT rt) + if (LIBRT) + set (MOSQ_LIBS ${MOSQ_LIBS} rt) + endif (LIBRT) + endif (APPLE) endif (UNIX) if (WIN32) diff --git a/src/bridge.c b/src/bridge.c index 8006c2d938..365658e602 100644 --- a/src/bridge.c +++ b/src/bridge.c @@ -83,7 +83,7 @@ int bridge__new(struct mosquitto_db *db, struct mosquitto__bridge *bridge) new_context->tls_cert_reqs = SSL_VERIFY_PEER; new_context->tls_version = new_context->bridge->tls_version; new_context->tls_insecure = new_context->bridge->tls_insecure; -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK new_context->tls_psk_identity = new_context->bridge->tls_psk_identity; new_context->tls_psk = new_context->bridge->tls_psk; #endif diff --git a/src/conf.c b/src/conf.c index 9053f22888..b18af7b176 100644 --- a/src/conf.c +++ b/src/conf.c @@ -343,7 +343,7 @@ void config__cleanup(struct mosquitto__config *config) #ifdef WITH_TLS mosquitto__free(config->bridges[i].tls_version); mosquitto__free(config->bridges[i].tls_cafile); -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK mosquitto__free(config->bridges[i].tls_psk_identity); mosquitto__free(config->bridges[i].tls_psk); #endif @@ -448,6 +448,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config || config->default_listener.max_connections != -1 || config->default_listener.mount_point || config->default_listener.protocol != mp_mqtt + || config->default_listener.socket_domain || config->default_listener.security_options.password_file || config->default_listener.security_options.psk_file || config->default_listener.security_options.auth_plugin_config_count @@ -478,6 +479,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config } config->listeners[config->listener_count-1].max_connections = config->default_listener.max_connections; config->listeners[config->listener_count-1].protocol = config->default_listener.protocol; + config->listeners[config->listener_count-1].socket_domain = config->default_listener.socket_domain; config->listeners[config->listener_count-1].client_count = 0; config->listeners[config->listener_count-1].socks = NULL; config->listeners[config->listener_count-1].sock_count = 0; @@ -497,6 +499,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config config->listeners[config->listener_count-1].use_identity_as_username = config->default_listener.use_identity_as_username; config->listeners[config->listener_count-1].use_subject_as_username = config->default_listener.use_subject_as_username; #endif + config->listeners[config->listener_count-1].security_options.acl_file = config->default_listener.security_options.acl_file; config->listeners[config->listener_count-1].security_options.password_file = config->default_listener.security_options.password_file; config->listeners[config->listener_count-1].security_options.psk_file = config->default_listener.security_options.psk_file; config->listeners[config->listener_count-1].security_options.auth_plugin_configs = config->default_listener.security_options.auth_plugin_configs; @@ -686,7 +689,7 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; } -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK if(config->bridges[i].tls_psk && !config->bridges[i].tls_psk_identity){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration: missing bridge_identity.\n"); return MOSQ_ERR_INVAL; @@ -818,6 +821,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct conf__set_cur_security_options(config, cur_listener, &cur_security_options); if(conf__parse_bool(&token, "allow_zero_length_clientid", &cur_security_options->allow_zero_length_clientid, saveptr)) return MOSQ_ERR_INVAL; }else if(!strncmp(token, "auth_opt_", 9)){ + if(reload) continue; // Auth plugin not currently valid for reloading. if(!cur_auth_plugin_config){ log__printf(NULL, MOSQ_LOG_ERR, "Error: An auth_opt_ option exists in the config file without an auth_plugin."); return MOSQ_ERR_INVAL; @@ -919,7 +923,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; } -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK if(cur_bridge->tls_psk_identity || cur_bridge->tls_psk){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single bridge."); return MOSQ_ERR_INVAL; @@ -936,7 +940,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; } -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK if(cur_bridge->tls_psk_identity || cur_bridge->tls_psk){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single bridge."); return MOSQ_ERR_INVAL; @@ -953,7 +957,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; } -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK if(cur_bridge->tls_psk_identity || cur_bridge->tls_psk){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single bridge."); return MOSQ_ERR_INVAL; @@ -964,7 +968,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge and/or TLS support not available."); #endif }else if(!strcmp(token, "bridge_identity")){ -#if defined(WITH_BRIDGE) && defined(WITH_TLS_PSK) +#if defined(WITH_BRIDGE) && defined(FINAL_WITH_TLS_PSK) if(reload) continue; // FIXME if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); @@ -999,7 +1003,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; } -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK if(cur_bridge->tls_psk_identity || cur_bridge->tls_psk){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single bridge."); return MOSQ_ERR_INVAL; @@ -1034,7 +1038,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge support not available."); #endif }else if(!strcmp(token, "bridge_psk")){ -#if defined(WITH_BRIDGE) && defined(WITH_TLS_PSK) +#if defined(WITH_BRIDGE) && defined(FINAL_WITH_TLS_PSK) if(reload) continue; // FIXME if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); @@ -1697,7 +1701,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty protocol value in configuration."); } }else if(!strcmp(token, "psk_file")){ -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK conf__set_cur_security_options(config, cur_listener, &cur_security_options); if(reload){ mosquitto__free(cur_security_options->psk_file); @@ -1708,7 +1712,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS/TLS-PSK support not available."); #endif }else if(!strcmp(token, "psk_hint")){ -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK if(reload) continue; // Listeners not valid for reloading. if(conf__parse_string(&token, "psk_hint", &cur_listener->psk_hint, saveptr)) return MOSQ_ERR_INVAL; #else @@ -1784,6 +1788,22 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge support not available."); #endif + }else if(!strcmp(token, "socket_domain")){ + if(reload) continue; // Listeners not valid for reloading. + token = strtok_r(NULL, " ", &saveptr); + if(token){ + if(!strcmp(token, "ipv4")){ + cur_listener->socket_domain = AF_INET; + }else if(!strcmp(token, "ipv6")){ + cur_listener->socket_domain = AF_INET6; + }else{ + log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid socket_domain value \"%s\" in configuration.", token); + return MOSQ_ERR_INVAL; + } + }else{ + log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty socket_domain value in configuration."); + return MOSQ_ERR_INVAL; + } }else if(!strcmp(token, "store_clean_interval")){ log__printf(NULL, MOSQ_LOG_WARNING, "Warning: store_clean_interval is no longer needed."); }else if(!strcmp(token, "sys_interval")){ @@ -2161,6 +2181,7 @@ static int conf__parse_bool(char **token, const char *name, bool *value, char *s *value = true; }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid %s value (%s).", name, *token); + return MOSQ_ERR_INVAL; } }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty %s value in configuration.", name); diff --git a/src/conf_includedir.c b/src/conf_includedir.c index 4fc04a282d..11e60ccdc5 100644 --- a/src/conf_includedir.c +++ b/src/conf_includedir.c @@ -36,7 +36,7 @@ and the Eclipse Distribution License is available at # include #endif -#if !defined(WIN32) && !defined(__CYGWIN__) +#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__QNX__) # include #endif diff --git a/src/context.c b/src/context.c index 164969dbef..c7fa9da39d 100644 --- a/src/context.c +++ b/src/context.c @@ -198,6 +198,13 @@ void context__cleanup(struct mosquitto_db *db, struct mosquitto *context, bool d context->queued_msgs = NULL; context->last_queued_msg = NULL; } +#if defined(WITH_BROKER) && defined(__GLIBC__) && defined(WITH_ADNS) + if(context->adns){ + gai_cancel(context->adns); + mosquitto__free((struct addrinfo *)context->adns->ar_request); + mosquitto__free(context->adns); + } +#endif if(do_free){ mosquitto__free(context); } diff --git a/src/handle_connack.c b/src/handle_connack.c index 20ac526a9c..bc6e37a879 100644 --- a/src/handle_connack.c +++ b/src/handle_connack.c @@ -100,6 +100,20 @@ int handle__connack(struct mosquitto_db *db, struct mosquitto *context) } } } + for(i=0; ibridge->topic_count; i++){ + if(context->bridge->topics[i].direction == bd_out || context->bridge->topics[i].direction == bd_both){ + log__printf(NULL, MOSQ_LOG_DEBUG, "Bridge %s doing local SUBSCRIBE on topic %s", context->id, context->bridge->topics[i].local_topic); + if(sub__add(db, + context, + context->bridge->topics[i].local_topic, + context->bridge->topics[i].qos, + MQTT_SUB_OPT_NO_LOCAL | MQTT_SUB_OPT_RETAIN_AS_PUBLISHED, + &db->subs)) return 1; + sub__retain_queue(db, context, + context->bridge->topics[i].local_topic, + context->bridge->topics[i].qos); + } + } } context->state = mosq_cs_connected; return MOSQ_ERR_SUCCESS; diff --git a/src/handle_connect.c b/src/handle_connect.c index c1634eb74e..342cac566b 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -466,6 +466,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){ if(password_flag){ /* username_flag == 0 && password_flag == 1 is forbidden */ + log__printf(NULL, MOSQ_LOG_ERR, "Protocol error from %s: password without username, closing connection.", client_id); rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; } @@ -490,7 +491,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) rc = 1; goto handle_connect_error; } -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK if(context->listener->psk_hint){ /* Client should have provided an identity to get this far. */ if(!context->username){ @@ -499,7 +500,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) goto handle_connect_error; } }else{ -#endif /* WITH_TLS_PSK */ +#endif /* FINAL_WITH_TLS_PSK */ client_cert = SSL_get_peer_certificate(context->ssl); if(!client_cert){ send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL); @@ -527,7 +528,11 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) rc = 1; goto handle_connect_error; } +#if OPENSSL_VERSION_NUMBER < 0x10100000L context->username = mosquitto__strdup((char *) ASN1_STRING_data(name_asn1)); +#else + context->username = mosquitto__strdup((char *) ASN1_STRING_get0_data(name_asn1)); +#endif if(!context->username){ send__connack(db, context, 0, CONNACK_REFUSED_SERVER_UNAVAILABLE, NULL); rc = MOSQ_ERR_NOMEM; @@ -562,9 +567,9 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) } X509_free(client_cert); client_cert = NULL; -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK } -#endif /* WITH_TLS_PSK */ +#endif /* FINAL_WITH_TLS_PSK */ }else{ #endif /* WITH_TLS */ if(username_flag){ diff --git a/src/loop.c b/src/loop.c index dd6b21394c..cd0df9d26b 100644 --- a/src/loop.c +++ b/src/loop.c @@ -87,7 +87,9 @@ static void temp__expire_websockets_clients(struct mosquitto_db *db) }else{ id = ""; } - log__printf(NULL, MOSQ_LOG_NOTICE, "Client %s has exceeded timeout, disconnecting.", id); + if(db->config->connection_messages == true){ + log__printf(NULL, MOSQ_LOG_NOTICE, "Client %s has exceeded timeout, disconnecting.", id); + } } /* Client has exceeded keepalive*1.5 */ do_disconnect(db, context); @@ -408,6 +410,10 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li context->bridge->restart_t = 0; } }else{ +#ifdef WITH_EPOLL + /* clean any events triggered in previous connection */ + context->events = 0; +#endif rc = bridge__connect_step1(db, context); if(rc){ context->bridge->cur_address++; @@ -422,8 +428,8 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li #else { rc = bridge__connect(db, context); + context->bridge->restart_t = 0; if(rc == MOSQ_ERR_SUCCESS){ - context->bridge->restart_t = 0; if(context->bridge->round_robin == false && context->bridge->cur_address != 0){ context->bridge->primary_retry = now + 5; } @@ -638,9 +644,11 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context) context->sock = INVALID_SOCKET; context->pollfd_index = -1; } - HASH_DELETE(hh_id, db->contexts_by_id, context); - context->old_id = context->id; - context->id = NULL; + if(context->id){ + HASH_DELETE(hh_id, db->contexts_by_id, context); + context->old_id = context->id; + context->id = NULL; + } }else #endif { @@ -660,7 +668,9 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context) } #ifdef WITH_EPOLL if (context->sock != INVALID_SOCKET && epoll_ctl(db->epollfd, EPOLL_CTL_DEL, context->sock, &ev) == -1) { - log__printf(NULL, MOSQ_LOG_DEBUG, "Error in epoll disconnecting: %s", strerror(errno)); + if(db->config->connection_messages == true){ + log__printf(NULL, MOSQ_LOG_DEBUG, "Error in epoll disconnecting: %s", strerror(errno)); + } } #endif context__disconnect(db, context); @@ -811,14 +821,15 @@ static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pol continue; } }while(SSL_DATA_PENDING(context)); - } + }else{ #ifdef WITH_EPOLL - if(events & (EPOLLERR | EPOLLHUP)){ + if(events & (EPOLLERR | EPOLLHUP)){ #else - if(context->pollfd_index >= 0 && pollfds[context->pollfd_index].revents & (POLLERR | POLLNVAL | POLLHUP)){ + if(context->pollfd_index >= 0 && pollfds[context->pollfd_index].revents & (POLLERR | POLLNVAL | POLLHUP)){ #endif - do_disconnect(db, context); - continue; + do_disconnect(db, context); + continue; + } } } } diff --git a/src/mosquitto.c b/src/mosquitto.c index eb90260ca7..768d5c102e 100644 --- a/src/mosquitto.c +++ b/src/mosquitto.c @@ -91,7 +91,7 @@ int drop_privileges(struct mosquitto__config *config, bool temporary) { #if !defined(__CYGWIN__) && !defined(WIN32) struct passwd *pwd; - char err[256]; + char *err; int rc; const char *snap = getenv("SNAP_NAME"); @@ -108,7 +108,7 @@ int drop_privileges(struct mosquitto__config *config, bool temporary) return 1; } if(initgroups(config->user, pwd->pw_gid) == -1){ - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error setting groups whilst dropping privileges: %s.", err); return 1; } @@ -118,7 +118,7 @@ int drop_privileges(struct mosquitto__config *config, bool temporary) rc = setgid(pwd->pw_gid); } if(rc == -1){ - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error setting gid whilst dropping privileges: %s.", err); return 1; } @@ -128,7 +128,7 @@ int drop_privileges(struct mosquitto__config *config, bool temporary) rc = setuid(pwd->pw_uid); } if(rc == -1){ - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error setting uid whilst dropping privileges: %s.", err); return 1; } @@ -144,19 +144,19 @@ int drop_privileges(struct mosquitto__config *config, bool temporary) int restore_privileges(void) { #if !defined(__CYGWIN__) && !defined(WIN32) - char err[256]; + char *err; int rc; if(getuid() == 0){ rc = setegid(0); if(rc == -1){ - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error setting gid whilst restoring privileges: %s.", err); return 1; } rc = seteuid(0); if(rc == -1){ - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error setting uid whilst restoring privileges: %s.", err); return 1; } @@ -169,12 +169,12 @@ int restore_privileges(void) void mosquitto__daemonise(void) { #ifndef WIN32 - char err[256]; + char *err; pid_t pid; pid = fork(); if(pid < 0){ - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error in fork: %s", err); exit(1); } @@ -182,7 +182,7 @@ void mosquitto__daemonise(void) exit(0); } if(setsid() < 0){ - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error in setsid: %s", err); exit(1); } diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index d80accceeb..9cf0246e6d 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -218,6 +218,7 @@ struct mosquitto__listener { int sock_count; int client_count; enum mosquitto_protocol protocol; + int socket_domain; bool use_username_as_clientid; #ifdef WITH_TLS char *cafile; @@ -468,7 +469,7 @@ struct mosquitto__bridge{ char *tls_certfile; char *tls_keyfile; char *tls_version; -# ifdef WITH_TLS_PSK +# ifdef FINAL_WITH_TLS_PSK char *tls_psk_identity; char *tls_psk; # endif diff --git a/src/net.c b/src/net.c index 12e80e9e49..35ad123ba2 100644 --- a/src/net.c +++ b/src/net.c @@ -81,18 +81,16 @@ void net__broker_cleanup(void) static void net__print_error(int log, const char *format_str) { -#ifdef WIN32 char *buf; +#ifdef WIN32 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, WSAGetLastError(), LANG_NEUTRAL, &buf, 0, NULL); log__printf(NULL, log, format_str, buf); LocalFree(buf); #else - char buf[256]; - - strerror_r(errno, buf, 256); + buf = strerror(errno); log__printf(NULL, log, format_str, buf); #endif } @@ -154,8 +152,10 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock) fromhost(&wrap_req); if(!hosts_access(&wrap_req)){ /* Access is denied */ - if(!net__socket_get_address(new_sock, address, 1024)){ - log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied access by tcpd.", address); + if(db->config->connection_messages == true){ + if(!net__socket_get_address(new_sock, address, 1024)){ + log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied access by tcpd.", address); + } } COMPAT_CLOSE(new_sock); return -1; @@ -189,7 +189,9 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock) } if(new_context->listener->max_connections > 0 && new_context->listener->client_count > new_context->listener->max_connections){ - log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", new_context->address); + if(db->config->connection_messages == true){ + log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", new_context->address); + } context__cleanup(db, new_context, true); return -1; } @@ -219,12 +221,14 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock) }else if(rc == SSL_ERROR_WANT_WRITE){ new_context->want_write = true; }else{ - e = ERR_get_error(); - while(e){ - log__printf(NULL, MOSQ_LOG_NOTICE, - "Client connection from %s failed: %s.", - new_context->address, ERR_error_string(e, ebuf)); + if(db->config->connection_messages == true){ e = ERR_get_error(); + while(e){ + log__printf(NULL, MOSQ_LOG_NOTICE, + "Client connection from %s failed: %s.", + new_context->address, ERR_error_string(e, ebuf)); + e = ERR_get_error(); + } } context__cleanup(db, new_context, true); return -1; @@ -236,7 +240,9 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock) } #endif - log__printf(NULL, MOSQ_LOG_NOTICE, "New connection from %s on port %d.", new_context->address, new_context->listener->port); + if(db->config->connection_messages == true){ + log__printf(NULL, MOSQ_LOG_NOTICE, "New connection from %s on port %d.", new_context->address, new_context->listener->port); + } return new_sock; } @@ -249,7 +255,7 @@ static int client_certificate_verify(int preverify_ok, X509_STORE_CTX *ctx) } #endif -#ifdef WITH_TLS_PSK +#ifdef FINAL_WITH_TLS_PSK static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk, unsigned int max_psk_len) { struct mosquitto_db *db; @@ -393,7 +399,11 @@ int net__socket_listen(struct mosquitto__listener *listener) snprintf(service, 10, "%d", listener->port); memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; + if(listener->socket_domain){ + hints.ai_family = listener->socket_domain; + }else{ + hints.ai_family = AF_UNSPEC; + } hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; @@ -518,7 +528,7 @@ int net__socket_listen(struct mosquitto__listener *listener) X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK); } -# ifdef WITH_TLS_PSK +# ifdef FINAL_WITH_TLS_PSK }else if(listener->psk_hint){ if(tls_ex_index_context == -1){ tls_ex_index_context = SSL_get_ex_new_index(0, "client context", NULL, NULL, NULL); @@ -541,7 +551,7 @@ int net__socket_listen(struct mosquitto__listener *listener) return 1; } } -# endif /* WITH_TLS_PSK */ +# endif /* FINAL_WITH_TLS_PSK */ } #endif /* WITH_TLS */ return 0; diff --git a/src/persist.c b/src/persist.c index 8cc2de5fff..b8b3e4b86b 100644 --- a/src/persist.c +++ b/src/persist.c @@ -287,7 +287,7 @@ static int persist__subs_retain_write(struct mosquitto_db *db, FILE *db_fptr, st sub = node->subs; while(sub){ - if(sub->context->clean_start == false){ + if(sub->context->clean_start == false && sub->context->id){ length = htonl(2+strlen(sub->context->id) + 2+strlen(thistopic) + sizeof(uint8_t)); i16temp = htons(DB_CHUNK_SUB); @@ -356,7 +356,7 @@ int persist__backup(struct mosquitto_db *db, bool shutdown) uint32_t i32temp; uint16_t i16temp; uint8_t i8temp; - char err[256]; + char *err; char *outfile = NULL; int len; @@ -477,7 +477,7 @@ int persist__backup(struct mosquitto_db *db, bool shutdown) return rc; error: mosquitto__free(outfile); - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err); if(db_fptr) fclose(db_fptr); return 1; @@ -596,7 +596,7 @@ static int persist__client_msg_chunk_restore(struct mosquitto_db *db, FILE *db_f uint8_t qos, retain, direction, state, dup; char *client_id = NULL; int rc; - char err[256]; + char *err; read_e(db_fptr, &i16temp, sizeof(uint16_t)); slen = ntohs(i16temp); @@ -631,7 +631,7 @@ static int persist__client_msg_chunk_restore(struct mosquitto_db *db, FILE *db_f return rc; error: - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err); fclose(db_fptr); mosquitto__free(client_id); @@ -650,7 +650,7 @@ static int persist__msg_store_chunk_restore(struct mosquitto_db *db, FILE *db_fp int rc = 0; struct mosquitto_msg_store *stored = NULL; struct mosquitto_msg_store_load *load; - char err[256]; + char *err; payload.ptr = NULL; @@ -734,7 +734,7 @@ static int persist__msg_store_chunk_restore(struct mosquitto_db *db, FILE *db_fp return rc; } error: - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err); fclose(db_fptr); mosquitto__free(source_id); @@ -747,10 +747,10 @@ static int persist__retain_chunk_restore(struct mosquitto_db *db, FILE *db_fptr) { dbid_t i64temp, store_id; struct mosquitto_msg_store_load *load; - char err[256]; + char *err; if(fread(&i64temp, sizeof(dbid_t), 1, db_fptr) != 1){ - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err); fclose(db_fptr); return 1; @@ -773,7 +773,7 @@ static int persist__sub_chunk_restore(struct mosquitto_db *db, FILE *db_fptr) char *client_id; char *topic; int rc = 0; - char err[256]; + char *err; read_e(db_fptr, &i16temp, sizeof(uint16_t)); slen = ntohs(i16temp); @@ -807,7 +807,7 @@ static int persist__sub_chunk_restore(struct mosquitto_db *db, FILE *db_fptr) return rc; error: - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err); fclose(db_fptr); return 1; @@ -824,7 +824,7 @@ int persist__restore(struct mosquitto_db *db) uint16_t i16temp, chunk; uint8_t i8temp; ssize_t rlen; - char err[256]; + char *err; struct mosquitto_msg_store_load *load, *load_tmp; assert(db); @@ -919,7 +919,7 @@ int persist__restore(struct mosquitto_db *db) } return rc; error: - strerror_r(errno, err, 256); + err = strerror(errno); log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err); if(fptr) fclose(fptr); return 1; diff --git a/src/service.c b/src/service.c index 11b4b018a8..c0fdc68a2c 100644 --- a/src/service.c +++ b/src/service.c @@ -27,6 +27,18 @@ SERVICE_STATUS_HANDLE service_handle = 0; static SERVICE_STATUS service_status; int main(int argc, char *argv[]); +static void print_error(void) +{ + char *buf; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, GetLastError(), LANG_NEUTRAL, &buf, 0, NULL); + + fprintf(stderr, "Error: %s\n", buf); + LocalFree(buf); +} + + /* Service control callback */ void __stdcall service_handler(DWORD fdwControl) { @@ -112,8 +124,12 @@ void service_install(void) svc_desc.lpDescription = "MQTT v3.1.1 broker"; ChangeServiceConfig2(svc_handle, SERVICE_CONFIG_DESCRIPTION, &svc_desc); CloseServiceHandle(svc_handle); + }else{ + print_error(); } CloseServiceHandle(sc_manager); + } else { + print_error(); } } @@ -132,8 +148,12 @@ void service_uninstall(void) } } CloseServiceHandle(svc_handle); + }else{ + print_error(); } CloseServiceHandle(sc_manager); + }else{ + print_error(); } } diff --git a/src/sys_tree.c b/src/sys_tree.c index 582e8f540f..0baf82a53b 100644 --- a/src/sys_tree.c +++ b/src/sys_tree.c @@ -60,8 +60,8 @@ static void sys_tree__update_clients(struct mosquitto_db *db, char *buf) static unsigned int client_count = -1; static int clients_expired = -1; static unsigned int client_max = 0; - static unsigned int disconnected_count = -1; - static unsigned int connected_count = -1; + static int disconnected_count = -1; + static int connected_count = -1; unsigned int count_total, count_by_sock; @@ -82,6 +82,13 @@ static void sys_tree__update_clients(struct mosquitto_db *db, char *buf) if(disconnected_count != count_total-count_by_sock){ disconnected_count = count_total-count_by_sock; + if(disconnected_count < 0){ + /* If a client has connected but not sent a CONNECT at this point, + * then it is possible that count_by_sock will be bigger than + * count_total, causing a negative number. This situation should + * not last for long, so just cap at zero and ignore. */ + disconnected_count = 0; + } snprintf(buf, BUFLEN, "%d", disconnected_count); db__messages_easy_queue(db, NULL, "$SYS/broker/clients/inactive", SYS_TREE_QOS, strlen(buf), buf, 1, NULL); db__messages_easy_queue(db, NULL, "$SYS/broker/clients/disconnected", SYS_TREE_QOS, strlen(buf), buf, 1, NULL); diff --git a/src/websockets.c b/src/websockets.c index 4815fbd5ac..d1218ebe1c 100644 --- a/src/websockets.c +++ b/src/websockets.c @@ -229,7 +229,9 @@ static int callback_mqtt(struct libwebsocket_context *context, return -1; } if(mosq->listener->max_connections > 0 && mosq->listener->client_count > mosq->listener->max_connections){ - log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", mosq->address); + if(db->config->connection_messages == true){ + log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", mosq->address); + } mosquitto__free(mosq); u->mosq = NULL; return -1; @@ -665,6 +667,14 @@ static int callback_http(struct libwebsocket_context *context, } break; +#ifdef WITH_TLS + case LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: + if(!len || (SSL_get_verify_result((SSL*)in) != X509_V_OK)){ + return 1; + } + break; +#endif + default: return 0; } @@ -721,6 +731,9 @@ struct libwebsocket_context *mosq_websockets_init(struct mosquitto__listener *li #if LWS_LIBRARY_VERSION_MAJOR>1 info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; #endif + if(listener->socket_domain == AF_INET){ + info.options |= LWS_SERVER_OPTION_DISABLE_IPV6; + } user = mosquitto__calloc(1, sizeof(struct libws_mqtt_hack)); if(!user){ diff --git a/test/broker/09-plugin-auth-acl-sub-denied.py b/test/broker/09-plugin-auth-acl-sub-denied.py new file mode 100755 index 0000000000..83726653a3 --- /dev/null +++ b/test/broker/09-plugin-auth-acl-sub-denied.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +# Test topic subscription. All SUBSCRIBE requests are denied. Check this +# produces the correct response, and check the client isn't disconnected (ref: +# issue #1016). + +import inspect, os, sys +# From http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder +cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],".."))) +if cmd_subfolder not in sys.path: + sys.path.insert(0, cmd_subfolder) + +import mosq_test + +def write_config(filename, port): + with open(filename, 'w') as f: + f.write("port %d\n" % (port)) + f.write("auth_plugin c/auth_plugin_acl_sub_denied.so\n") + f.write("allow_anonymous false\n") + +port = mosq_test.get_port() +conf_file = os.path.basename(__file__).replace('.py', '.conf') +write_config(conf_file, port) + +rc = 1 +keepalive = 10 +connect_packet = mosq_test.gen_connect("sub-denied-test", keepalive=keepalive, username="denied") +connack_packet = mosq_test.gen_connack(rc=0) + +mid = 53 +subscribe_packet = mosq_test.gen_subscribe(mid, "qos0/test", 0) +suback_packet = mosq_test.gen_suback(mid, 128) + +mid_pub = 54 +publish_packet = mosq_test.gen_publish("topic", qos=1, payload="test", mid=mid_pub) +puback_packet = mosq_test.gen_puback(mid_pub) + +broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port) + +try: + sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port) + mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback") + + mosq_test.do_send_receive(sock, publish_packet, puback_packet, "puback") + + rc = 0 + + sock.close() +finally: + os.remove(conf_file) + broker.terminate() + broker.wait() + (stdo, stde) = broker.communicate() + if rc: + print(stde) + + +exit(rc) diff --git a/test/broker/Makefile b/test/broker/Makefile index 1d80d79d9a..681387e6af 100644 --- a/test/broker/Makefile +++ b/test/broker/Makefile @@ -125,6 +125,7 @@ endif ./09-plugin-auth-unpwd-success.py ./09-plugin-auth-unpwd-fail.py ./09-plugin-auth-acl-sub.py + ./09-plugin-auth-acl-sub-denied.py ./09-plugin-auth-v2-unpwd-success.py ./09-plugin-auth-v2-unpwd-fail.py ./09-plugin-auth-defer-unpwd-success.py diff --git a/test/broker/c/Makefile b/test/broker/c/Makefile index 2005270df3..326318998c 100644 --- a/test/broker/c/Makefile +++ b/test/broker/c/Makefile @@ -6,6 +6,7 @@ PLUGIN_SRC = \ auth_plugin.c \ auth_plugin_pwd.c \ auth_plugin_acl.c \ + auth_plugin_acl_sub_denied.c \ auth_plugin_v2.c \ auth_plugin_context_params.c \ auth_plugin_msg_params.c diff --git a/test/broker/c/auth_plugin_acl_sub_denied.c b/test/broker/c/auth_plugin_acl_sub_denied.c new file mode 100644 index 0000000000..4c5a26fab5 --- /dev/null +++ b/test/broker/c/auth_plugin_acl_sub_denied.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include + +int mosquitto_auth_plugin_version(void) +{ + return MOSQ_AUTH_PLUGIN_VERSION; +} + +int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *auth_opts, int auth_opt_count) +{ + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count) +{ + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload) +{ + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload) +{ + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_auth_acl_check(void *user_data, int access, const struct mosquitto *client, const struct mosquitto_acl_msg *msg) +{ + if(access == MOSQ_ACL_SUBSCRIBE){ + return MOSQ_ERR_ACL_DENIED; + }else{ + return MOSQ_ERR_SUCCESS; + } +} + +int mosquitto_auth_unpwd_check(void *user_data, const struct mosquitto *client, const char *username, const char *password) +{ + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_auth_psk_key_get(void *user_data, const struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len) +{ + return MOSQ_ERR_AUTH; +} diff --git a/test/broker/ptest.py b/test/broker/ptest.py index 68f1ed25f6..42ca336f65 100755 --- a/test/broker/ptest.py +++ b/test/broker/ptest.py @@ -97,6 +97,7 @@ (1, './09-plugin-auth-unpwd-success.py'), (1, './09-plugin-auth-unpwd-fail.py'), (1, './09-plugin-auth-acl-sub.py'), + (1, './09-plugin-auth-acl-sub-denied.py'), (1, './09-plugin-auth-v2-unpwd-success.py'), (1, './09-plugin-auth-v2-unpwd-fail.py'), (1, './09-plugin-auth-defer-unpwd-success.py'), diff --git a/test/ssl/gen.sh b/test/ssl/gen.sh index 7a49631caa..a52159c1e4 100755 --- a/test/ssl/gen.sh +++ b/test/ssl/gen.sh @@ -31,42 +31,42 @@ openssl req -new -x509 -days 3650 -key test-fake-root-ca.key -out test-fake-root # An intermediate CA, signed by the root CA, used to sign server/client csrs. openssl genrsa -out test-signing-ca.key 1024 openssl req -out test-signing-ca.csr -key test-signing-ca.key -new -config openssl.cnf -subj "${BASESUBJ}/CN=Signing CA/" -openssl ca -config openssl.cnf -name CA_root -extensions v3_ca -out test-signing-ca.crt -infiles test-signing-ca.csr +openssl ca -batch -config openssl.cnf -name CA_root -extensions v3_ca -out test-signing-ca.crt -infiles test-signing-ca.csr # An alternative intermediate CA, signed by the root CA, not used to sign anything. openssl genrsa -out test-alt-ca.key 1024 openssl req -out test-alt-ca.csr -key test-alt-ca.key -new -config openssl.cnf -subj "${BASESUBJ}/CN=Alternative Signing CA/" -openssl ca -config openssl.cnf -name CA_root -extensions v3_ca -out test-alt-ca.crt -infiles test-alt-ca.csr +openssl ca -batch -config openssl.cnf -name CA_root -extensions v3_ca -out test-alt-ca.crt -infiles test-alt-ca.csr # Valid server key and certificate. openssl genrsa -out server.key 1024 openssl req -new -key server.key -out server.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=localhost/" -openssl ca -config openssl.cnf -name CA_signing -out server.crt -infiles server.csr +openssl ca -batch -config openssl.cnf -name CA_signing -out server.crt -infiles server.csr # Expired server certificate, based on the above server key. openssl req -new -days 1 -key server.key -out server-expired.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=localhost/" -openssl ca -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out server-expired.crt -infiles server-expired.csr +openssl ca -batch -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out server-expired.crt -infiles server-expired.csr # Valid client key and certificate. openssl genrsa -out client.key 1024 openssl req -new -key client.key -out client.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client/" -openssl ca -config openssl.cnf -name CA_signing -out client.crt -infiles client.csr +openssl ca -batch -config openssl.cnf -name CA_signing -out client.crt -infiles client.csr # Expired client certificate, based on the above client key. openssl req -new -days 1 -key client.key -out client-expired.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client expired/" -openssl ca -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out client-expired.crt -infiles client-expired.csr +openssl ca -batch -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out client-expired.crt -infiles client-expired.csr # Revoked client certificate, based on a new client key. openssl genrsa -out client-revoked.key 1024 openssl req -new -days 1 -key client-revoked.key -out client-revoked.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client revoked/" -openssl ca -config openssl.cnf -name CA_signing -out client-revoked.crt -infiles client-revoked.csr -openssl ca -config openssl.cnf -name CA_signing -revoke client-revoked.crt -openssl ca -config openssl.cnf -name CA_signing -gencrl -out crl.pem +openssl ca -batch -config openssl.cnf -name CA_signing -out client-revoked.crt -infiles client-revoked.csr +openssl ca -batch -config openssl.cnf -name CA_signing -revoke client-revoked.crt +openssl ca -batch -config openssl.cnf -name CA_signing -gencrl -out crl.pem # Valid client key and certificate, encrypted (use "password" as password) -openssl genrsa -des3 -out client-encrypted.key 1024 -openssl req -new -key client-encrypted.key -out client-encrypted.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client encrypted/" -openssl ca -config openssl.cnf -name CA_signing -out client-encrypted.crt -infiles client-encrypted.csr +openssl genrsa -des3 -out client-encrypted.key -passout pass:password 1024 +openssl req -new -key client-encrypted.key -out client-encrypted.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client encrypted/" -passin pass:password +openssl ca -batch -config openssl.cnf -name CA_signing -out client-encrypted.crt -infiles client-encrypted.csr cat test-signing-ca.crt test-root-ca.crt > all-ca.crt #mkdir certs diff --git a/www/README.md b/www/README.md new file mode 100644 index 0000000000..923f54bfec --- /dev/null +++ b/www/README.md @@ -0,0 +1,3 @@ +This is the mosquitto website, it can be built with `nikola`: + +`nikola build` \ No newline at end of file diff --git a/www/conf.py b/www/conf.py index b41452372a..7b5f4ded55 100644 --- a/www/conf.py +++ b/www/conf.py @@ -87,6 +87,7 @@ #("/sponsoring/", "Sponsoring"), ( ( + ("/roadmap/", "Roadmap"), ("/api/", "API"), ("/man/libmosquitto-3.html", "libmosquitto"), ("/man/mosquitto-8.html", "mosquitto"), diff --git a/www/pages/download.md b/www/pages/download.md index 51c1b90c42..2aceb0a53a 100644 --- a/www/pages/download.md +++ b/www/pages/download.md @@ -11,11 +11,11 @@ # Source -* [mosquitto-1.5.3.tar.gz](http://mosquitto.org/files/source/mosquitto-1.5.3.tar.gz) (319kB) ([GPG signature](http://mosquitto.org/files/source/mosquitto-1.5.3.tar.gz.asc)) -* [mosquitto-1.5.3.tar.gz](http://www.eclipse.org/downloads/download.php?file=/mosquitto/source/mosquitto-1.5.3.tar.gz) (via Eclipse) +* [mosquitto-1.5.5.tar.gz](https://mosquitto.org/files/source/mosquitto-1.5.5.tar.gz) (319kB) ([GPG signature](https://mosquitto.org/files/source/mosquitto-1.5.5.tar.gz.asc)) +* [mosquitto-1.5.4.tar.gz](https://www.eclipse.org/downloads/download.php?file=/mosquitto/source/mosquitto-1.5.4.tar.gz) (via Eclipse) * [Git source code repository](https://github.com/eclipse/mosquitto) (github.com) -Older downloads are available at [http://mosquitto.org/files/](../files/) +Older downloads are available at [https://mosquitto.org/files/](../files/) # Binary Installation @@ -25,14 +25,14 @@ distributions. ## Windows -* [mosquitto-1.5.3-install-windows-x64.exe](http://www.eclipse.org/downloads/download.php?file=/mosquitto/binary/win64/mosquitto-1.5.3-install-windows-x64.exe) (~360 kB) (64-bit build, Windows Vista and up, built with Visual Studio Community 2017) -* [mosquitto-1.5.3-install-windows-x32.exe](http://www.eclipse.org/downloads/download.php?file=/mosquitto/binary/win32/mosquitto-1.5.3-install-windows-x86.exe) (~360 kB) (32-bit build, Windows Vista and up, built with Visual Studio Community 2017) +* [mosquitto-1.5.4-install-windows-x64.exe](https://www.eclipse.org/downloads/download.php?file=/mosquitto/binary/win64/mosquitto-1.5.4-install-windows-x64.exe) (~360 kB) (64-bit build, Windows Vista and up, built with Visual Studio Community 2017) +* [mosquitto-1.5.4-install-windows-x32.exe](https://www.eclipse.org/downloads/download.php?file=/mosquitto/binary/win32/mosquitto-1.5.4-install-windows-x86.exe) (~360 kB) (32-bit build, Windows Vista and up, built with Visual Studio Community 2017) See also readme-windows.txt after installing. ## Mac Mosquitto can be installed from the homebrew project. See -[brew.sh](http://brew.sh/) and then use `brew install mosquitto` +[brew.sh](https://brew.sh/) and then use `brew install mosquitto` ## Linux distributions with snap support @@ -42,30 +42,20 @@ Mosquitto can be installed from the homebrew project. See Download the repository config file for your CentOS version from below and copy it to /etc/yum.repos.d/ You'll now be able to install and keep mosquitto up to date using the normal package management tools. The available packages are: mosquitto, mosquitto-clients, libmosquitto1, libmosquitto-devel, libmosquittopp1, libmosquittopp-devel, python-mosquitto. -* [CentOS 7](http://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-7/home:oojah:mqtt.repo) -* [CentOS 6](http://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-6/home:oojah:mqtt.repo) +* [CentOS 7](https://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-7/home:oojah:mqtt.repo) +* [CentOS 6](https://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-6/home:oojah:mqtt.repo) ## Debian * Mosquitto is now in Debian proper. There will be a short delay between a new release and it appearing in Debian as part of the normal Debian procedures. * There are also Debian repositories provided by the mosquitto project, as - described at - -## openSUSE -Download the repository config file for your openSUSE version from below and -copy it to /etc/zypp/repos.d/ You'll now be able to install and keep mosquitto -up to date using the normal package management tools. - -The available packages are: mosquitto, mosquitto-clients, libmosquitto1, libmosquitto-devel, libmosquittopp1, libmosquittopp-devel, python-mosquitto. - -* [openSUSE 13.2]http://download.opensuse.org/repositories/home:/oojah:/mqtt/openSUSE_13.2/home:oojah:mqtt.repo) -* [openSUSE 13.1]http://download.opensuse.org/repositories/home:/oojah:/mqtt/openSUSE_13.1/home:oojah:mqtt.repo) + described at ## Raspberry Pi Mosquitto is available through the main repository. There are also Debian repositories provided by the mosquitto project, as -described at +described at ## Redhat Enterprise Linux Download the repository config file for your RHEL version from below and copy @@ -73,23 +63,14 @@ it to /etc/yum.repos.d/ You'll now be able to install and keep mosquitto up to date using the normal package management tools. The available packages are: mosquitto, mosquitto-clients, libmosquitto1, libmosquitto-devel, libmosquittopp1, libmosquittopp-devel, python-mosquitto. -* [RHEL 7](http://download.opensuse.org/repositories/home:/oojah:/mqtt/RedHat_RHEL-7/home:oojah:mqtt.repo) -* [RHEL 6](http://download.opensuse.org/repositories/home:/oojah:/mqtt/RedHat_RHEL-6/home:oojah:mqtt.repo) - -## SUSE Linux Enterprise Server -Add the appropriate repository to your package config from the list below, then install mosquitto from your normal package management tools. - -* [SLE 15](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_15/) -* [SLE 12 SP3](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_12_SP3/) -* [SLE 12 SP2](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_12_SP2/) -* [SLE 12 SP1](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_12_SP1/) -* [SLE 12](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_123/) +* [RHEL 7](https://download.opensuse.org/repositories/home:/oojah:/mqtt/RedHat_RHEL-7/home:oojah:mqtt.repo) +* [RHEL 6](https://download.opensuse.org/repositories/home:/oojah:/mqtt/RedHat_RHEL-6/home:oojah:mqtt.repo) ## Ubuntu Mosquitto is available in the Ubuntu repositories so you can install as with any other package. If you are on an earlier version of Ubuntu or want a more recent version of mosquitto, add the [mosquitto-dev -PPA](http://launchpad.net/%7Emosquitto-dev/+archive/mosquitto-ppa/) to your +PPA](https://launchpad.net/%7Emosquitto-dev/+archive/mosquitto-ppa/) to your repositories list - see the link for details. mosquitto can then be installed from your package manager. @@ -98,24 +79,9 @@ from your package manager. # Other packages known to exist -## Arch Linux -* Mosquitto can be found in the community repository. - -## Fedora -Mosquitto is now available from Fedora directly. Use `yum install mosquitto`, -or search for "mosquitto" to find the related packages. - -## FreeBSD -Mosquitto is available for FreeBSD: http://www.freshports.org/net/mosquitto/ - -## Gentoo -Use `emerge mosquitto` - -## OpenWrt -If you're using a trunk snapshot use `opkg update; opkg install mosquitto` - -Karl Palsson maintains a set of feeds that may be more up to date than the -current OpenWrt version: - -* https://github.com/remakeelectric/owrt_pub_feeds - +* Arch Linux +* Fedora +* FreeBSD +* Gentoo +* OpenWrt +* OpenSUSE diff --git a/www/pages/index.html b/www/pages/index.html index d31fb9a29f..e269d72c67 100644 --- a/www/pages/index.html +++ b/www/pages/index.html @@ -26,9 +26,9 @@ implementing MQTT clients, and the very popular mosquitto_pub and mosquitto_sub command line MQTT clients.

-

Mosquitto is part of the Eclipse +

Mosquitto is part of the Eclipse Foundation and is an iot.eclipse.org project.

+ href="https://iot.eclipse.org/">iot.eclipse.org project.

@@ -52,10 +52,10 @@

Test

You can have your own instance of Mosquitto running in minutes, but to make testing even easier, the Mosquitto Project runs a test server at test.mosquitto.org where + href="https://test.mosquitto.org/">test.mosquitto.org where you can test your clients in a variety of ways: plain MQTT, MQTT over TLS, MQTT over TLS (with client certificate, + href="https://test.mosquitto.org/ssl/">client certificate, MQTT over WebSockets and MQTT over WebSockets with TLS.

platforms.

diff --git a/www/pages/roadmap.md b/www/pages/roadmap.md new file mode 100644 index 0000000000..7e607cf7f0 --- /dev/null +++ b/www/pages/roadmap.md @@ -0,0 +1,81 @@ + + +# Roadmap + +## Version 1.6 + +The next minor release. The focus of this release is on providing support for +version 5 of the MQTT protocol. + +This release will provide a feature complete implementation, but does not +represent the final interface for all features. In particular, functions are +being added to libmosquitto to provide support for MQTT 5 features, but these +will be consolidated with the API changes planned for version 2.0. + +### Deprecation notices + +#### libmosquittopp + +libmosquittopp, the C++ wrapper around libmosquitto is now deprecated and will +be removed in the next major release (2.0). The wrapper came about by an +external request and at the time it was created there were no other C++ +solutions for MQTT. This has changed in the past years and this wrapper +provides no benefit over true C++ libraries or using the pure C libmosquitto. + +#### libmosquitto API changes + +The Mosquitto project has maintained API and ABI compatibility in libmosquitto +since version 1.0, and has dealt with the introduction of new specification +features by adding new functions which duplicate the behaviour of existing +functions, but with additional arguments to support the new features. +Particularly with regards to adding support for MQTT version 5, this has lead +to a proliferation of functions which offer small variations on a theme. + +The libmosquitto functions listed below (which includes some new functions +included in 1.6) are going to be updated for version 2.0. Functions not listed +here should still be considered at risk of being updated. + +* mosquitto\_will\_set +* mosquitto\_connect\* +* mosquitto\_reconnect\* +* mosquitto\_disconnect +* mosquitto\_publish\* +* mosquitto\_subscribe\* +* mosquitto\_unsubscribe\* +* mosquitto\_loop\* +* mosquitto\_\*\_callback\_set +* All callbacks +* mosquitto\_\*\_topic\_check\* + + +## Version 2.0 + +This is the next major release and includes breaking changes. Other features +planned include: + +## Disk persistence improvements + +A new disk persistence interface will be created to allow persistence to occur +immediately, rather than periodically. This will allow queued messages for +disconnected clients to be removed from memory, and reduce the periodic pause +caused when writing the persistence file. + +## Breaking changes + +### libmosquitto + +The libmosquitto API is being consolidated to better support the new MQTT 5 +features whilst reducing the number of function variants. + +### libmosquittopp + +The C++ wrapper around libmosquitto will be removed in this release. diff --git a/www/pages/security.md b/www/pages/security.md index c31eb3006f..43618a25a3 100644 --- a/www/pages/security.md +++ b/www/pages/security.md @@ -19,6 +19,10 @@ follow the steps on [Eclipse Security] page to report it. Listed with most recent first. Further information on security related issues can be found in the [security category]. +* December 2018: No CVE assigned. Affecting versions **1.5** to **1.5.4** + inclusive, fixed in **1.5.5.**. More details at [version-155-released]. +* November 2018: No CVE assigned. Affecting versions **1.4** to **1.5.3** + inclusive, fixed in **1.5.4**. More details at [version-154-released]. * September 2018: [CVE-2018-12543] affecting versions **1.5** to **1.5.2** inclusive, fixed in **1.5.3**. * April 2018: [CVE-2017-7655] affecting versions **1.0** to **1.4.15** @@ -41,7 +45,8 @@ can be found in the [security category]. inclusive, fixed in **1.4.12**. More details at [security-advisory-cve-2017-7650]. - +[version-155-released]: /2018/11/version-155-released/ +[version-154-released]: /2018/11/version-154-released/ [security-advisory-cve-2018-12543]: /2018/09/security-advisory-cve-2018-12543/ [security-advisory-cve-2017-7651-cve-2017-7652]: /2018/02/security-advisory-cve-2017-7651-cve-2017-7652/ [security-advisory-cve-2017-7650]: /2017/05/security-advisory-cve-2017-7650/ diff --git a/www/posts/2018/11/mqtt5-progress.md b/www/posts/2018/11/mqtt5-progress.md new file mode 100644 index 0000000000..2b27e82172 --- /dev/null +++ b/www/posts/2018/11/mqtt5-progress.md @@ -0,0 +1,59 @@ + + +Development of support for MQTT 5 is ongoing and making good progress, but has +been substantially delayed due to other non-Mosquitto work having to take +priority. + +It is possible to test the current state of MQTT 5 support by using the `mqtt5` +branch of the [repository]. Please note that this is very much a work in +progress, so parts are incomplete and interfaces may yet change. The client +library in particular has had to have an increase in functions available in +order to provide the features needed whilst providing backwards compatibility. +Part of the plan for the 2.0 release, which will follow after 1.6, is to +consolidate the libmosquitto API with breaking changes. There are more details +on the [roadmap]. + +Current features include: + +* Support for all incoming and outgoing packets, although not everything is + processed. +* Support for sending and receiving all properties, with not all properties + processed. +* Client support for setting properties +* Request/response support (client cannot process incoming correlation data) +* Retain availability +* Message expiry interval support +* Server support for assigned client identifiers +* Payload format indicator support +* Content-type support +* Basic topic alias support from client to broker +* Lots of new tests + +Both `mosquitto_pub` and `mosquitto_sub` support setting properties on the +command line, for example: + +``` +mosquitto_sub -t topic -v -D connect session-expiry-interval 60 -D connect user-property key value -D subscribe user-property sub-key sub-value +``` + +``` +mosquitto_pub -t topic -m '{"key":"value"}' -D publish content-type "application/json" +``` + +``` +./sensor_read.sh | mosquitto_pub -t topic -l -D publish topic-alias 1 +``` + +Further updates will be posted when more features are available. + +[repository]: https://github.com/eclipse/mosquitto/tree/mqtt5 +[roadmap]: https://mosquitto.org/roadmap/ \ No newline at end of file diff --git a/www/posts/2018/11/version-154-released.md b/www/posts/2018/11/version-154-released.md new file mode 100644 index 0000000000..7d0c9dd544 --- /dev/null +++ b/www/posts/2018/11/version-154-released.md @@ -0,0 +1,59 @@ + + +This is a bugfix and security release. + +# Version 1.5.4 changes + +## Security +- When using a TLS enabled websockets listener with `require_certificate` + enabled, the mosquitto broker does not correctly verify client certificates. + This is now fixed. All other security measures operate as expected, and in + particular non-websockets listeners are not affected by this. Closes [#996]. + +## Broker +- Process all pending messages even when a client has disconnected. This means + a client that send a PUBLISH then DISCONNECT quickly, then disconnects will + have its DISCONNECT message processed properly and so no Will will be sent. + Closes [#7]. +- $SYS/broker/clients/disconnected should never be negative. Closes [#287]. +- Give better error message if a client sends a password without a username. + Closes [#1015]. +- Fix bridge not honoring `restart_timeout`. Closes [#1019]. +- Don't disconnect a client if an auth plugin denies access to SUBSCRIBE. + Closes [#1016]. + +## Library +- Fix memory leak that occurred if `mosquitto_reconnect()` was used when TLS + errors were present. Closes [#592]. +- Fix TLS connections when using an external event loop with + `mosquitto_loop_read()` and `mosquitto_write()`. Closes [#990]. + +## Build +- Fix clients not being compiled with threading support when using CMake. + Closes [#983]. +- Header fixes for FreeBSD. Closes [#977]. +- Use `_GNU_SOURCE` to fix build errors in websockets and getaddrinfo usage. + Closes [#862] and [#933]. +- Fix builds on QNX 7.0.0. Closes [#1018]. + +[#7]: https://github.com/eclipse/mosquitto/issues/7 +[#287]: https://github.com/eclipse/mosquitto/issues/287 +[#592]: https://github.com/eclipse/mosquitto/issues/592 +[#933]: https://github.com/eclipse/mosquitto/issues/933 +[#977]: https://github.com/eclipse/mosquitto/issues/977 +[#983]: https://github.com/eclipse/mosquitto/issues/983 +[#990]: https://github.com/eclipse/mosquitto/issues/990 +[#996]: https://github.com/eclipse/mosquitto/issues/996 +[#1015]: https://github.com/eclipse/mosquitto/issues/1015 +[#1016]: https://github.com/eclipse/mosquitto/issues/1016 +[#1018]: https://github.com/eclipse/mosquitto/issues/1018 +[#1019]: https://github.com/eclipse/mosquitto/issues/1019 diff --git a/www/posts/2018/12/version-155-released.md b/www/posts/2018/12/version-155-released.md new file mode 100644 index 0000000000..ca01171581 --- /dev/null +++ b/www/posts/2018/12/version-155-released.md @@ -0,0 +1,60 @@ + + +This is a bugfix and security release. + +# Version 1.5.5 changes + +## Security +- If `per_listener_settings` is set to true, then the `acl_file` setting was + ignored for the "default listener" only. This has been fixed. This does not + affect any listeners defined with the `listener` option. Closes [#1073]. + +## Broker +- Add `socket_domain` option to allow listeners to disable IPv6 support. + This is required to work around a problem in libwebsockets that means + sockets only listen on IPv6 by default if IPv6 support is compiled in. + Closes [#1004]. +- When using ADNS, don't ask for all network protocols when connecting, + because this can lead to confusing "Protocol not supported" errors if the + network is down. Closes [#1062]. +- Fix outgoing retained messages not being sent by bridges on initial + connection. Closes [#1040]. +- Don't reload `auth_opt_` options on reload, to match the behaviour of the + other plugin options. Closes [#1068]. +- Print message on error when installing/uninstalling as a Windows service. +- All non-error connect/disconnect messages are controlled by the + `connection_messages` option. Closes [#772]. Closes [#613]. Closes [#537]. + +## Library +- Fix reconnect delay backoff behaviour. Closes [#1027]. +- Don't call `on_disconnect()` twice if keepalive tests fail. Closes [#1067]. + +## Client +- Always print leading zeros in `mosquitto_sub` when output format is hex. + Closes [#1066]. + +## Build +- Fix building where TLS-PSK is not available. Closes [#68]. + + +[#68]: https://github.com/eclipse/mosquitto/issues/68 +[#537]: https://github.com/eclipse/mosquitto/issues/537 +[#613]: https://github.com/eclipse/mosquitto/issues/613 +[#772]: https://github.com/eclipse/mosquitto/issues/772 +[#1004]: https://github.com/eclipse/mosquitto/issues/1004 +[#1027]: https://github.com/eclipse/mosquitto/issues/1027 +[#1040]: https://github.com/eclipse/mosquitto/issues/1040 +[#1062]: https://github.com/eclipse/mosquitto/issues/1062 +[#1066]: https://github.com/eclipse/mosquitto/issues/1066 +[#1067]: https://github.com/eclipse/mosquitto/issues/1067 +[#1068]: https://github.com/eclipse/mosquitto/issues/1068 +[#1073]: https://github.com/eclipse/mosquitto/issues/1073