Merge branch 'master' into develop

pull/418/head
Roger A. Light 9 years ago
commit 91b308a11d

@ -72,6 +72,55 @@ Build:
build and install static versions of the client libraries.
1.4.11 - 20170220
=================
Broker:
- Fix crash when "lazy" type bridge attempts to reconnect. Closes #259.
- maximum_connections now applies to websockets listeners. Closes #271.
- Allow bridges to use TLS with IPv6.
- Don't error on zero length persistence files. Closes #316.
- For http only websockets clients, close files served over http in all cases
when the client disconnects. Closes #354.
- Fix error message when websockets http_dir directory does not exist.
- Improve password utility error message. Closes #379.
Clients:
- Use of --ciphers no longer requires you to also pass --tls-version.
Closes #380.
Client library:
- Clients can now use TLS with IPv6.
- Fix potential socket leakage when reconnecting. Closes #304.
- Fix potential negative timeout being passed to pselect. Closes #329.
1.4.10 - 20160816
=================
Broker:
- Fix TLS operation with websockets listeners and libwebsockts 2.x. Closes
#186.
- Don't disconnect client on HUP before reading the pending data. Closes #7.
- Fix some $SYS messages being incorrectly persisted. Closes #191.
- Support OpenSSL 1.1.0.
- Call fsync after persisting data to ensure it is correctly written. Closes
#189.
- Fix persistence saving of subscription QoS on big-endian machines.
- Fix will retained flag handling on Windows. Closes #222.
- Broker now displays an error if it is unable to open the log file. Closes
#234.
Client library:
- Support OpenSSL 1.1.0.
- Fixed the C++ library not allowing SOCKS support to be used. Closes #198.
- Fix memory leak when verifying a server certificate with a subjectAltName
section. Closes #237.
Build:
- Don't attempt to install docs when WITH_DOCS=no. Closes #184.
1.4.9 - 20160603
================

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

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

@ -902,7 +902,7 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
return 1;
}
# endif
if(cfg->tls_version && mosquitto_tls_opts_set(mosq, 1, cfg->tls_version, cfg->ciphers)){
if((cfg->tls_version || cfg->ciphers) && mosquitto_tls_opts_set(mosq, 1, cfg->tls_version, cfg->ciphers)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS options.\n");
mosquitto_lib_cleanup();
return 1;
@ -972,10 +972,11 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg)
}else{
port = 1883;
}
}else{
}else
#endif
{
port = cfg->port;
}
#endif
#ifdef WITH_SRV
if(cfg->use_srv){

@ -13,6 +13,7 @@
* ============================================================ */
#if defined(_MSC_VER) && _MSC_VER < 1900
# define snprintf sprintf_s
# define EPROTO ECONNABORTED
#endif
#ifdef WIN32
@ -27,6 +28,3 @@
#define uthash_malloc(sz) mosquitto__malloc(sz)
#define uthash_free(ptr,sz) mosquitto__free(ptr)
#ifndef EPROTO
# define EPROTO ECONNABORTED
#endif

@ -86,6 +86,9 @@ WITH_STRIP:=no
# Build static libraries
WITH_STATIC_LIBRARIES:=no
# Build with async dns lookup support for bridges (temporary). Requires glibc.
#WITH_ADNS:=yes
# =============================================================================
# End of user configuration
# =============================================================================
@ -166,6 +169,10 @@ ifeq ($(UNAME),QNX)
LIB_LIBS:=$(LIB_LIBS) -lsocket
endif
ifeq ($(UNAME),Linux)
BROKER_LIBS:=$(BROKER_LIBS) -lanl
endif
ifeq ($(WITH_WRAP),yes)
BROKER_LIBS:=$(BROKER_LIBS) -lwrap
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_WRAP
@ -250,6 +257,11 @@ ifeq ($(WITH_EC),yes)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_EC
endif
ifeq ($(WITH_ADNS),yes)
BROKER_LIBS:=$(BROKER_LIBS) -lanl
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_ADNS
endif
MAKE_ALL:=mosquitto
ifeq ($(WITH_DOCS),yes)
MAKE_ALL:=$(MAKE_ALL) docs

@ -0,0 +1,13 @@
FROM alpine:3.5
MAINTAINER David Audet <david.audet@ca.com>
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"]

@ -0,0 +1,49 @@
#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 <path-to-configuration-file>:/mosquitto/config/mosquitto.conf 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 mosquitto:1.4.10 .
```
##Run
Run a container using the new image:
```
docker run -it -p 1883:1883 -p 9001:9001 -v <path-to-configuration-file>:/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log 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.

@ -0,0 +1,5 @@
#!/bin/ash
set -e
exec "$@"

@ -0,0 +1,13 @@
FROM alpine:3.3
MAINTAINER David Audet <david.audet@ca.com>
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"]

@ -0,0 +1,49 @@
#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 <path-to-configuration-file>:/mosquitto/config/mosquitto.conf 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 mosquitto:1.4.4 .
```
##Run
Run a container using the new image:
```
docker run -it -p 1883:1883 -p 9001:9001 -v <path-to-configuration-file>:/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log 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.

@ -0,0 +1,5 @@
#!/bin/ash
set -e
exec "$@"

@ -0,0 +1,13 @@
FROM alpine:3.4
MAINTAINER David Audet <david.audet@ca.com>
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"]

@ -0,0 +1,49 @@
#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 <path-to-configuration-file>:/mosquitto/config/mosquitto.conf 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 mosquitto:1.4.8 .
```
##Run
Run a container using the new image:
```
docker run -it -p 1883:1883 -p 9001:9001 -v <path-to-configuration-file>:/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log 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.

@ -0,0 +1,5 @@
#!/bin/ash
set -e
exec "$@"

@ -0,0 +1,4 @@
# Docker Images
This directory contains the required files to build Mosquitto Docker images.

@ -13,7 +13,12 @@ if (${WITH_THREADING} STREQUAL ON)
endif (CMAKE_CL_64)
set (PTHREAD_INCLUDE_DIR C:\\pthreads\\Pre-built.2\\include)
else (WIN32)
set (PTHREAD_LIBRARIES pthread)
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)
@ -64,7 +69,10 @@ set(C_SRC
set (LIBRARIES ${OPENSSL_LIBRARIES} ${PTHREAD_LIBRARIES})
if (UNIX AND NOT APPLE)
set (LIBRARIES ${LIBRARIES} rt)
find_library(LIBRT rt)
if (LIBRT)
set (LIBRARIES ${LIBRARIES} rt)
endif (LIBRT)
endif (UNIX AND NOT APPLE)
if (WIN32)

@ -334,11 +334,7 @@ void mosquittopp::user_data_set(void *userdata)
int mosquittopp::socks5_set(const char *host, int port, const char *username, const char *password)
{
#ifdef WITH_SOCKS
return mosquitto_socks5_set(m_mosq, host, port, username, password);
#else
return MOSQ_ERR_NOT_SUPPORTED;
#endif
}

@ -4,18 +4,18 @@ Copyright (c) 2010-2016 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#ifndef _MOSQUITTOPP_H_
#define _MOSQUITTOPP_H_
#ifndef MOSQUITTOPP_H
#define MOSQUITTOPP_H
#ifdef _WIN32
# ifdef mosquittopp_EXPORTS
@ -28,8 +28,8 @@ Contributors:
#endif
#include <cstdlib>
#include <time.h>
#include <mosquitto.h>
#include <time.h>
namespace mosqpp {
@ -122,15 +122,16 @@ class mosqpp_EXPORT mosquittopp {
bool want_write();
int threaded_set(bool threaded=true);
int socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL);
virtual void on_connect(int rc) {return;};
virtual void on_disconnect(int rc) {return;};
virtual void on_publish(int mid) {return;};
virtual void on_message(const struct mosquitto_message *message) {return;};
virtual void on_subscribe(int mid, int qos_count, const int *granted_qos) {return;};
virtual void on_unsubscribe(int mid) {return;};
virtual void on_log(int level, const char *str) {return;};
virtual void on_error() {return;};
// names in the functions commented to prevent unused parameter warning
virtual void on_connect(int /*rc*/) {return;}
virtual void on_disconnect(int /*rc*/) {return;}
virtual void on_publish(int /*mid*/) {return;}
virtual void on_message(const struct mosquitto_message * /*message*/) {return;}
virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;}
virtual void on_unsubscribe(int /*mid*/) {return;}
virtual void on_log(int /*level*/, const char * /*str*/) {return;}
virtual void on_error() {return;}
};
}

@ -15,6 +15,7 @@ Contributors:
*/
#include <assert.h>
#include <string.h>
#include "mosquitto.h"
#include "mosquitto_internal.h"

@ -507,6 +507,10 @@ static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking)
message__reconnect_reset(mosq);
if(mosq->sock != INVALID_SOCKET){
net__socket_close(mosq); //close socket
}
#ifdef WITH_SOCKS
if(mosq->socks5_host){
rc = net__socket_connect(mosq, mosq->socks5_host, mosq->socks5_port, mosq->bind_address, blocking);
@ -891,6 +895,12 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
timeout = (mosq->next_msg_out - now)*1000;
}
if(timeout < 0){
/* There has been a delay somewhere which means we should have already
* sent a message. */
timeout = 0;
}
local_timeout.tv_sec = timeout/1000;
#ifdef HAVE_PSELECT
local_timeout.tv_nsec = (timeout-local_timeout.tv_sec*1000)*1e6;

@ -56,6 +56,9 @@ Contributors:
#include "mosquitto.h"
#include "time_mosq.h"
#ifdef WITH_BROKER
# ifdef __linux__
# include <netdb.h>
# endif
# include "uthash.h"
struct mosquitto_client_msg;
#endif
@ -151,6 +154,9 @@ struct mosquitto {
mosq_sock_t sock;
#ifndef WITH_BROKER
mosq_sock_t sockpairR, sockpairW;
#endif
#if defined(__GLIBC__) && defined(WITH_ADNS)
struct gaicb *adns; /* For getaddrinfo_a */
#endif
enum mosquitto__protocol protocol;
char *address;

@ -14,12 +14,15 @@ Contributors:
Roger Light - initial implementation and documentation.
*/
#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#ifndef WIN32
#define _GNU_SOURCE
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
@ -198,6 +201,95 @@ static unsigned int psk_client_callback(SSL *ssl, const char *hint,
}
#endif
#if defined(WITH_BROKER) && defined(__GLIBC__) && defined(WITH_ADNS)
/* Async connect, part 1 (dns lookup) */
int net__try_connect_step1(struct mosquitto *mosq, const char *host)
{
int s;
void *sevp = NULL;
if(mosq->adns){
mosquitto__free(mosq->adns);
}
mosq->adns = mosquitto__calloc(1, sizeof(struct gaicb));
if(!mosq->adns){
return MOSQ_ERR_NOMEM;
}
mosq->adns->ar_name = host;
s = getaddrinfo_a(GAI_NOWAIT, &mosq->adns, 1, sevp);
if(s){
errno = s;
mosquitto__free(mosq->adns);
mosq->adns = NULL;
return MOSQ_ERR_EAI;
}
return MOSQ_ERR_SUCCESS;
}
/* Async connect part 2, the connection. */
int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *sock)
{
struct addrinfo *ainfo, *rp;
int rc;
ainfo = mosq->adns->ar_result;
for(rp = ainfo; rp != NULL; rp = rp->ai_next){
*sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if(*sock == INVALID_SOCKET) continue;
if(rp->ai_family == PF_INET){
((struct sockaddr_in *)rp->ai_addr)->sin_port = htons(port);
}else if(rp->ai_family == PF_INET6){
((struct sockaddr_in6 *)rp->ai_addr)->sin6_port = htons(port);
}else{
COMPAT_CLOSE(*sock);
continue;
}
/* Set non-blocking */
if(net__socket_nonblock(*sock)){
COMPAT_CLOSE(*sock);
continue;
}
rc = connect(*sock, rp->ai_addr, rp->ai_addrlen);
#ifdef WIN32
errno = WSAGetLastError();
#endif
if(rc == 0 || errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK){
if(rc < 0 && (errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK)){
rc = MOSQ_ERR_CONN_PENDING;
}
/* Set non-blocking */
if(net__socket_nonblock(*sock)){
COMPAT_CLOSE(*sock);
continue;
}
break;
}
COMPAT_CLOSE(*sock);
*sock = INVALID_SOCKET;
}
freeaddrinfo(mosq->adns->ar_result);
mosq->adns->ar_result = NULL;
mosquitto__free(mosq->adns);
mosq->adns = NULL;
if(!rp){
return MOSQ_ERR_ERRNO;
}
return rc;
}
#endif
int net__try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mosq_sock_t *sock, const char *bind_address, bool blocking)
{
@ -212,14 +304,7 @@ int net__try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mo
*sock = INVALID_SOCKET;
memset(&hints, 0, sizeof(struct addrinfo));
#ifdef WITH_TLS
if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){
hints.ai_family = PF_INET;
}else
#endif
{
hints.ai_family = PF_UNSPEC;
}
hints.ai_family = PF_UNSPEC;
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_socktype = SOCK_STREAM;
@ -241,7 +326,7 @@ int net__try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mo
for(rp = ainfo; rp != NULL; rp = rp->ai_next){
*sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if(*sock == INVALID_SOCKET) continue;
if(rp->ai_family == PF_INET){
((struct sockaddr_in *)rp->ai_addr)->sin_port = htons(port);
}else if(rp->ai_family == PF_INET6){
@ -321,8 +406,6 @@ void net__print_ssl_error(struct mosquitto *mosq)
int net__socket_connect_tls(struct mosquitto *mosq)
{
int ret, err;
unsigned long e;
char ebuf[256];
ret = SSL_connect(mosq->ssl);
if(ret != 1) {
@ -354,25 +437,13 @@ int net__socket_connect_tls(struct mosquitto *mosq)
}
#endif
/* Create a socket and connect it to 'ip' on port 'port'.
* Returns -1 on failure (ip is NULL, socket creation/connection error)
* Returns sock number on success.
*/
int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking)
int net__socket_connect_step3(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking)
{
mosq_sock_t sock = INVALID_SOCKET;
int rc;
#ifdef WITH_TLS
int ret;
BIO *bio;
#endif
if(!mosq || !host || !port) return MOSQ_ERR_INVAL;
rc = net__try_connect(mosq, host, port, &sock, bind_address, blocking);
if(rc > 0) return rc;
#ifdef WITH_TLS
if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
@ -386,7 +457,7 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port,
mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
}else{
log__printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version);
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
return MOSQ_ERR_INVAL;
}
#else
@ -394,13 +465,13 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port,
mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
}else{
log__printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version);
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
return MOSQ_ERR_INVAL;
}
#endif
if(!mosq->ssl_ctx){
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context.");
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
net__print_ssl_error(mosq);
return MOSQ_ERR_TLS;
}
@ -418,7 +489,7 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port,
ret = SSL_CTX_set_cipher_list(mosq->ssl_ctx, mosq->tls_ciphers);
if(ret == 0){
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", mosq->tls_ciphers);
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
net__print_ssl_error(mosq);
return MOSQ_ERR_TLS;
}
@ -443,7 +514,7 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port,
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath);
}
#endif
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
net__print_ssl_error(mosq);
return MOSQ_ERR_TLS;
}
@ -466,7 +537,7 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port,
#else
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile);
#endif
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
net__print_ssl_error(mosq);
return MOSQ_ERR_TLS;
}
@ -479,14 +550,14 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port,
#else
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile);
#endif
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
net__print_ssl_error(mosq);
return MOSQ_ERR_TLS;
}
ret = SSL_CTX_check_private_key(mosq->ssl_ctx);
if(ret != 1){
log__printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent.");
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
net__print_ssl_error(mosq);
return MOSQ_ERR_TLS;
}
@ -499,28 +570,45 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port,
mosq->ssl = SSL_new(mosq->ssl_ctx);
if(!mosq->ssl){
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
net__print_ssl_error(mosq);
return MOSQ_ERR_TLS;
}
SSL_set_ex_data(mosq->ssl, tls_ex_index_mosq, mosq);
bio = BIO_new_socket(sock, BIO_NOCLOSE);
bio = BIO_new_socket(mosq->sock, BIO_NOCLOSE);
if(!bio){
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
net__print_ssl_error(mosq);
return MOSQ_ERR_TLS;
}
SSL_set_bio(mosq->ssl, bio, bio);
mosq->sock = sock;
if(net__socket_connect_tls(mosq)){
return MOSQ_ERR_TLS;
}
}
#endif
return MOSQ_ERR_SUCCESS;
}
/* Create a socket and connect it to 'ip' on port 'port'.
* Returns -1 on failure (ip is NULL, socket creation/connection error)
* Returns sock number on success.
*/
int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking)
{
mosq_sock_t sock = INVALID_SOCKET;
int rc;
if(!mosq || !host || !port) return MOSQ_ERR_INVAL;
rc = net__try_connect(mosq, host, port, &sock, bind_address, blocking);
if(rc > 0) return rc;
mosq->sock = sock;
rc = net__socket_connect_step3(mosq, host, port, bind_address, blocking);
return rc;
}
@ -612,7 +700,7 @@ ssize_t net__write(struct mosquitto *mosq, void *buf, size_t count)
}
int net__socket_nonblock(int sock)
int net__socket_nonblock(mosq_sock_t sock)
{
#ifndef WIN32
int opt;

@ -59,6 +59,9 @@ int net__socket_close(struct mosquitto_db *db, struct mosquitto *mosq);
int net__socket_close(struct mosquitto *mosq);
#endif
int net__try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mosq_sock_t *sock, const char *bind_address, bool blocking);
int net__try_connect_step1(struct mosquitto *mosq, const char *host);
int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *sock);
int net__socket_connect_step3(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking);
int net__socket_nonblock(mosq_sock_t sock);
int net__socketpair(mosq_sock_t *sp1, mosq_sock_t *sp2);

@ -16,6 +16,7 @@ Contributors:
#include <assert.h>
#include <errno.h>
#include <string.h>
#ifdef WITH_BROKER
# include "mosquitto_broker_internal.h"

@ -15,6 +15,7 @@ Contributors:
*/
#include <assert.h>
#include <string.h>
#include "logging_mosq.h"
#include "memory_mosq.h"

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

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg4136"
version="1.1"
inkscape:version="0.91 r13725"
xml:space="preserve"
width="152.76344"
height="152.76344"
viewBox="0 0 152.76344 152.76344"
sodipodi:docname="mosquitto-logo-min.svg"
inkscape:export-filename="/home/ral/src/mqtt/mosquitto/logo/mosquitto-14x14.png"
inkscape:export-xdpi="8.25"
inkscape:export-ydpi="8.25"><metadata
id="metadata4142"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs4140" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="995"
id="namedview4138"
showgrid="false"
inkscape:zoom="2.4369022"
inkscape:cx="79.546492"
inkscape:cy="59.284918"
inkscape:window-x="1280"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g4144"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" /><g
id="g4144"
inkscape:groupmode="layer"
inkscape:label="mosquitto"
transform="matrix(1.25,0,0,-1.25,-458.46439,514.07261)"><g
id="g3366"
transform="translate(-8.0273435e-7,5.3788908)"><path
sodipodi:nodetypes="cccsssccc"
inkscape:connector-curvature="0"
id="path4160"
style="fill:#f3771c;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="m 427.87689,289.04733 4.33447,42.80506 1.28833,9.39302 c 5.1916,2.194 8.8356,7.3344 8.8356,13.324 0,7.9837 -6.4746,14.4584 -14.4584,14.4584 -7.9838,0 -14.4584,-6.4747 -14.4584,-14.4584 0,-5.9896 3.6439,-11.13 8.8356,-13.324 l 1.12419,-9.14681 z" /><path
sodipodi:nodetypes="cccccccsccsccccccsccccccccccccscc"
inkscape:connector-curvature="0"
id="path4162"
style="fill:#3c5280;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="m 382.10766,315.26637 c 0,0 -4.36735,5.20003 -7.72292,9.81394 -13.7812,24.8958 -8.5306,56.3422 13.1394,75.42 l 9.4666,-8.4844 8.4197,-7.5492 8.7333,-7.8288 c -3.2664,-2.048 -6.0429,-4.8044 -8.1148,-8.0538 -2.5602,-4.0158 -4.0439,-8.7843 -4.0439,-13.8982 0,-11.4001 7.3721,-21.0816 17.6077,-24.5373 l 0.8807,-12.0308 c -17.0538,3.435 -29.9009,18.5037 -29.9009,36.5681 0,8.0438 2.5472,15.4941 6.8791,21.5875 l -8.356,7.4922 -0.0315,0.0284 c -13.6984,-18.1953 -12.852,-43.4563 1.899,-60.7045 z m 54.05308,14.88224 c 10.2356,3.4557 17.6076,13.1375 17.6076,24.5373 0,5.1139 -1.4836,9.8824 -4.0436,13.8979 -2.0718,3.2494 -4.8484,6.0061 -8.1144,8.0538 l 8.7329,7.8288 8.4206,7.5486 -8e-4,9e-4 9.4666,8.4844 c 21.67,-19.0778 26.9206,-50.5242 13.1394,-75.42 l -7.44339,-10.23339 c -9.13531,8.24259 0,0 -9.13531,8.24259 14.7512,17.2482 15.5976,42.5092 1.8992,60.7045 l -0.0317,-0.0284 -8.356,-7.4922 c 4.3319,-6.0936 6.8791,-13.5439 6.8791,-21.5875 0,-18.0644 -12.8472,-33.1328 -29.9007,-36.5681 z" /></g></g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

@ -14,8 +14,8 @@
inkscape:version="0.91 r13725"
xml:space="preserve"
width="278.23288"
height="212.13112"
viewBox="0 0 278.23288 212.13112"
height="278.23288"
viewBox="0 0 278.23288 278.23288"
sodipodi:docname="mosquitto-logo-only.svg"><metadata
id="metadata4142"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
@ -29,15 +29,15 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1366"
inkscape:window-height="706"
inkscape:window-width="1280"
inkscape:window-height="995"
id="namedview4138"
showgrid="false"
inkscape:zoom="1.7899063"
inkscape:cx="139.11627"
inkscape:cx="67.324802"
inkscape:cy="84.142768"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-x="1280"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g4144"
fit-margin-top="0"
@ -47,12 +47,14 @@
id="g4144"
inkscape:groupmode="layer"
inkscape:label="mosquitto"
transform="matrix(1.25,0,0,-1.25,-387.06488,509.61263)"><path
d="m 420.9449,237.9852 3.1034,42.3947 2.5194,34.4248 c 5.1916,2.194 8.8356,7.3344 8.8356,13.324 0,7.9837 -6.4746,14.4584 -14.4584,14.4584 -7.9838,0 -14.4584,-6.4747 -14.4584,-14.4584 0,-5.9896 3.6439,-11.13 8.8356,-13.324 l 2.5194,-34.4248 3.1034,-42.3947 z"
style="fill:#f3771c;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path4160"
inkscape:connector-curvature="0" /><path
d="m 322.2003,328.1839 c 0,-24.4581 8.9422,-47.3527 24.4508,-65.0437 l -9.347,-8.3787 c -17.5008,19.9159 -27.6522,45.7824 -27.6522,73.4224 0,31.144 12.801,59.3037 33.4258,79.5062 l 0.47,-0.4215 27.6474,-24.7845 C 345.2111,358.664 339.8298,319.926 357.9086,290.084 l 9.5443,8.5556 c -13.7812,24.8958 -8.5306,56.3422 13.1394,75.42 l 9.4666,-8.4844 8.4197,-7.5492 8.7333,-7.8288 c -3.2664,-2.048 -6.0429,-4.8044 -8.1148,-8.0538 -2.5602,-4.0158 -4.0439,-8.7843 -4.0439,-13.8982 0,-11.4001 7.3721,-21.0816 17.6077,-24.5373 l 0.8807,-12.0308 c -17.0538,3.435 -29.9009,18.5037 -29.9009,36.5681 0,8.0438 2.5472,15.4941 6.8791,21.5875 l -8.356,7.4922 -0.0315,0.0284 c -13.6984,-18.1953 -12.852,-43.4563 1.899,-60.7045 L 355.9969,271.518 c -27.6004,31.6071 -28.3884,78.5191 -1.9533,111.0143 l -9.3515,8.3835 c -12.907,-15.6702 -21.0804,-35.3849 -22.3254,-56.9549 l -0.057,-0.0637 0.0507,-0.0454 c -0.1063,-1.876 -0.1601,-3.7655 -0.1601,-5.6679 z m 107.0286,-24.476 c 10.2356,3.4557 17.6076,13.1375 17.6076,24.5373 0,5.1139 -1.4836,9.8824 -4.0436,13.8979 -2.0718,3.2494 -4.8484,6.0061 -8.1144,8.0538 l 8.7329,7.8288 8.4206,7.5486 -8e-4,9e-4 9.4666,8.4844 c 21.67,-19.0778 26.9206,-50.5242 13.1394,-75.42 l 9.5442,-8.5556 c 18.0786,29.842 12.6976,68.58 -13.2865,92.4001 l 27.6486,24.7856 0.4688,0.4204 c 20.6249,-20.2025 33.4259,-48.3622 33.4259,-79.5062 0,-27.64 -10.1515,-53.5065 -27.6523,-73.4224 l -9.3469,8.3787 c 15.5083,17.691 24.4505,40.5856 24.4505,65.0437 0,1.9024 -0.0536,3.7919 -0.1599,5.6679 l 0.0507,0.0454 -0.0569,0.0637 c -1.245,21.57 -9.4184,41.2847 -22.3257,56.9549 l -9.3512,-8.3835 c 26.435,-32.4952 25.6467,-79.4072 -1.9534,-111.0143 l -28.0346,25.1308 c 14.7512,17.2482 15.5976,42.5092 1.8992,60.7045 l -0.0317,-0.0284 -8.356,-7.4922 c 4.3319,-6.0936 6.8791,-13.5439 6.8791,-21.5875 0,-18.0644 -12.8472,-33.1328 -29.9007,-36.5681 l 0.8805,12.0308 z"
style="fill:#3c5280;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path4162"
inkscape:connector-curvature="0" /></g></svg>
transform="matrix(1.25,0,0,-1.25,-387.06488,575.71439)"><g
id="g3377"
transform="translate(0,26.44071)"><path
inkscape:connector-curvature="0"
id="path4160"
style="fill:#f3771c;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="m 420.9449,237.9852 3.1034,42.3947 2.5194,34.4248 c 5.1916,2.194 8.8356,7.3344 8.8356,13.324 0,7.9837 -6.4746,14.4584 -14.4584,14.4584 -7.9838,0 -14.4584,-6.4747 -14.4584,-14.4584 0,-5.9896 3.6439,-11.13 8.8356,-13.324 l 2.5194,-34.4248 3.1034,-42.3947 z" /><path
inkscape:connector-curvature="0"
id="path4162"
style="fill:#3c5280;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="m 322.2003,328.1839 c 0,-24.4581 8.9422,-47.3527 24.4508,-65.0437 l -9.347,-8.3787 c -17.5008,19.9159 -27.6522,45.7824 -27.6522,73.4224 0,31.144 12.801,59.3037 33.4258,79.5062 l 0.47,-0.4215 27.6474,-24.7845 C 345.2111,358.664 339.8298,319.926 357.9086,290.084 l 9.5443,8.5556 c -13.7812,24.8958 -8.5306,56.3422 13.1394,75.42 l 9.4666,-8.4844 8.4197,-7.5492 8.7333,-7.8288 c -3.2664,-2.048 -6.0429,-4.8044 -8.1148,-8.0538 -2.5602,-4.0158 -4.0439,-8.7843 -4.0439,-13.8982 0,-11.4001 7.3721,-21.0816 17.6077,-24.5373 l 0.8807,-12.0308 c -17.0538,3.435 -29.9009,18.5037 -29.9009,36.5681 0,8.0438 2.5472,15.4941 6.8791,21.5875 l -8.356,7.4922 -0.0315,0.0284 c -13.6984,-18.1953 -12.852,-43.4563 1.899,-60.7045 L 355.9969,271.518 c -27.6004,31.6071 -28.3884,78.5191 -1.9533,111.0143 l -9.3515,8.3835 c -12.907,-15.6702 -21.0804,-35.3849 -22.3254,-56.9549 l -0.057,-0.0637 0.0507,-0.0454 c -0.1063,-1.876 -0.1601,-3.7655 -0.1601,-5.6679 z m 107.0286,-24.476 c 10.2356,3.4557 17.6076,13.1375 17.6076,24.5373 0,5.1139 -1.4836,9.8824 -4.0436,13.8979 -2.0718,3.2494 -4.8484,6.0061 -8.1144,8.0538 l 8.7329,7.8288 8.4206,7.5486 -8e-4,9e-4 9.4666,8.4844 c 21.67,-19.0778 26.9206,-50.5242 13.1394,-75.42 l 9.5442,-8.5556 c 18.0786,29.842 12.6976,68.58 -13.2865,92.4001 l 27.6486,24.7856 0.4688,0.4204 c 20.6249,-20.2025 33.4259,-48.3622 33.4259,-79.5062 0,-27.64 -10.1515,-53.5065 -27.6523,-73.4224 l -9.3469,8.3787 c 15.5083,17.691 24.4505,40.5856 24.4505,65.0437 0,1.9024 -0.0536,3.7919 -0.1599,5.6679 l 0.0507,0.0454 -0.0569,0.0637 c -1.245,21.57 -9.4184,41.2847 -22.3257,56.9549 l -9.3512,-8.3835 c 26.435,-32.4952 25.6467,-79.4072 -1.9534,-111.0143 l -28.0346,25.1308 c 14.7512,17.2482 15.5976,42.5092 1.8992,60.7045 l -0.0317,-0.0284 -8.356,-7.4922 c 4.3319,-6.0936 6.8791,-13.5439 6.8791,-21.5875 0,-18.0644 -12.8472,-33.1328 -29.9007,-36.5681 l 0.8805,12.0308 z" /></g></g></svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

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

@ -11,8 +11,9 @@ separately in the case that they are not already available.
Capabilities
------------
The network support in Windows is severely limited. The broker is limited to approximately
1024 MQTT connections.
Some versions of Windows have limitations on the number of concurrent
connections. Non-server versions have been reported to be limited to
approximately 1024 connections.
Websockets
@ -20,7 +21,7 @@ Websockets
The broker executables provided in the installers do not have Websockets support enabled.
If you wish to have a version of the broker with Websockets support, you will need to compile
libwebsockets version v1.3-chrome37-firefox30 yourself and mosquitto version 1.4 yourself.
libwebsockets version v1.7 onwards because no Windows binaries are provided.
Please note that on Windows, libwebsockets limits connections to a maximum of 64 clients.

@ -2,7 +2,11 @@ Eclipse Mosquitto
=================
Mosquitto is an open source implementation of a server for version 3.1 and
3.1.1 of the MQTT protocol.
3.1.1 of the MQTT protocol. It also includes a C and C++ client library, and
the `mosquitto_pub` and `mosquitto_sub` utilities for publishing and
subscribing.
## Links
See the following links for more information on MQTT:
@ -17,6 +21,57 @@ Mosquitto project information is available at the following locations:
There is also a public test server available at <http://test.mosquitto.org/>
## Installing
See <http://mosquitto.org/download/> for details on installing binaries for
various platforms.
## Quick start
If you have installed a binary package the broker should have been started
automatically. If not, it can be started with a basic configuration:
mosquitto
Then use `mosquitto_sub` to subscribe to a topic:
mosquitto_sub -t 'test/topic' -v
And to publish a message:
mosquitto_pub -t 'test/topic' -m 'hello world'
## Documentation
Documentation for the broker, clients and client library API can be found in
the man pages, which are available online at <http://mosquitto.org/man/>. There
are also pages with an introduction to the features of MQTT, the
`mosquitto_passwd` utility for dealing with username/passwords, and a
description of the configuration file options available for the broker.
Detailed client library API documentation can be found at <http://mosquitto.org/api/>
## Building from source
To build from source the recommended route for end users is to download the
archive from <http://mosquitto.org/download/>.
On Windows and Mac, use `cmake` to build. On other platforms, just run `make`
to build. For Windows, see also `readme-windows.md`.
If you are building from the git repository then the documentation will not
already be built. Use `make binary` to skip building the man pages, or install
`docbook-xsl` on Debian/Ubuntu systems.
### Build Dependencies
* c-ares (libc-ares-dev on Debian based systems) - disable with `make WITH_DNS_SRV=no`
* libuuid (uuid-dev) - disable with `make WITH_UUID=no`
* libwebsockets (libwebsockets-dev) - enable with `make WITH_LIBWEBSOCKETS=yes`
* openssl (libssl-dev on Debian based systems) - disable with `make WITH_TLS=no`
## Credits
Mosquitto was written by Roger Light <roger@atchoo.org>
Master: [![Travis Build Status (master)](https://travis-ci.org/eclipse/mosquitto.svg?branch=master)](https://travis-ci.org/eclipse/mosquitto)

@ -2,7 +2,7 @@
MAJOR=1
MINOR=4
REVISION=9
REVISION=11
sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk

@ -0,0 +1,3 @@
port 1883
persistence true
user root

@ -0,0 +1,49 @@
name: mosquitto-simple
version: 1.4.11
summary: Eclipse Mosquitto MQTT broker
description: This is a message broker that supports version 3.1 and 3.1.1 of the MQTT
protocol.
MQTT provides a method of carrying out messaging using a publish/subscribe
model. It is lightweight, both in terms of bandwidth usage and ease of
implementation. This makes it particularly useful at the edge of the network
where a sensor or other simple device may be implemented using an arduino for
example.
confinement: strict
apps:
mosquitto:
command: usr/local/sbin/mosquitto -c $SNAP/mosquitto.conf
daemon: simple
restart-condition: always
plugs: [network, network-bind]
parts:
script:
plugin: dump
source: snap/
prime:
- mosquitto.conf
mosquitto:
plugin: make
source: https://github.com/eclipse/mosquitto
source-type: git
build-packages:
- libssl-dev
- uuid-dev
- libc-ares-dev
- xsltproc
- docbook-xsl
stage-packages:
- libssl1.0.0
- libuuid1
- libc-ares2
prime:
- usr/local/sbin/mosquitto
- lib/*-linux-gnu/libcrypto.so*
- lib/*-linux-gnu/libssl.so*
- lib/*-linux-gnu/libuuid.so*

@ -114,11 +114,25 @@ add_executable(mosquitto ${MOSQ_SRCS})
set (MOSQ_LIBS ${MOSQ_LIBS} ${OPENSSL_LIBRARIES})
# Check for getaddrinfo_a
include(CheckLibraryExists)
check_library_exists(anl getaddrinfo_a "" HAVE_GETADDRINFO_A)
if (HAVE_GETADDRINFO_A)
add_definitions(-DHAVE_GETADDRINFO_A)
set (MOSQ_LIBS ${MOSQ_LIBS} anl)
endif (HAVE_GETADDRINFO_A)
if (UNIX)
if (APPLE)
set (MOSQ_LIBS ${MOSQ_LIBS} dl m)
else (APPLE)
set (MOSQ_LIBS ${MOSQ_LIBS} rt dl m)
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)

@ -100,8 +100,165 @@ int bridge__new(struct mosquitto_db *db, struct mosquitto__bridge *bridge)
return MOSQ_ERR_NOMEM;
}
#if defined(__GLIBC__) && defined(WITH_ADNS)
new_context->bridge->restart_t = 1; /* force quick restart of bridge */
return bridge__connect_step1(db, new_context);
#else
return bridge__connect(db, new_context);
#endif
}
#if defined(__GLIBC__) && defined(WITH_ADNS)
int bridge__connect_step1(struct mosquitto_db *db, struct mosquitto *context)
{
int rc;
int i;
char *notification_topic;
int notification_topic_len;
uint8_t notification_payload;
if(!context || !context->bridge) return MOSQ_ERR_INVAL;
context->state = mosq_cs_new;
context->sock = INVALID_SOCKET;
context->last_msg_in = mosquitto_time();
context->next_msg_out = mosquitto_time() + context->bridge->keepalive;
context->keepalive = context->bridge->keepalive;
context->clean_session = context->bridge->clean_session;
context->in_packet.payload = NULL;
context->ping_t = 0;
context->bridge->lazy_reconnect = false;
mqtt3_bridge_packet_cleanup(context);
mqtt3_db_message_reconnect_reset(db, context);
if(context->clean_session){
mqtt3_db_messages_delete(db, context);
}
/* Delete all local subscriptions even for clean_session==false. We don't
* remove any messages and the next loop carries out the resubscription
* anyway. This means any unwanted subs will be removed.
*/
mqtt3_subs_clean_session(db, context);
for(i=0; i<context->bridge->topic_count; i++){
if(context->bridge->topics[i].direction == bd_out || context->bridge->topics[i].direction == bd_both){
_mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Bridge %s doing local SUBSCRIBE on topic %s", context->id, context->bridge->topics[i].local_topic);
if(mqtt3_sub_add(db, context, context->bridge->topics[i].local_topic, context->bridge->topics[i].qos, &db->subs)) return 1;
}
}
if(context->bridge->notifications){
if(context->bridge->notification_topic){
if(!context->bridge->initial_notification_done){
notification_payload = '0';
mqtt3_db_messages_easy_queue(db, context, context->bridge->notification_topic, 1, 1, &notification_payload, 1);
context->bridge->initial_notification_done = true;
}
notification_payload = '0';
rc = _mosquitto_will_set(context, context->bridge->notification_topic, 1, &notification_payload, 1, true);
if(rc != MOSQ_ERR_SUCCESS){
return rc;
}
}else{
notification_topic_len = strlen(context->bridge->remote_clientid)+strlen("$SYS/broker/connection//state");
notification_topic = _mosquitto_malloc(sizeof(char)*(notification_topic_len+1));
if(!notification_topic) return MOSQ_ERR_NOMEM;
snprintf(notification_topic, notification_topic_len+1, "$SYS/broker/connection/%s/state", context->bridge->remote_clientid);
if(!context->bridge->initial_notification_done){
notification_payload = '0';
mqtt3_db_messages_easy_queue(db, context, notification_topic, 1, 1, &notification_payload, 1);
context->bridge->initial_notification_done = true;
}
notification_payload = '0';
rc = _mosquitto_will_set(context, notification_topic, 1, &notification_payload, 1, true);
_mosquitto_free(notification_topic);
if(rc != MOSQ_ERR_SUCCESS){
return rc;
}
}
}
_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Connecting bridge %s (%s:%d)", context->bridge->name, context->bridge->addresses[context->bridge->cur_address].address, context->bridge->addresses[context->bridge->cur_address].port);
rc = _mosquitto_try_connect_step1(context, context->bridge->addresses[context->bridge->cur_address].address);
if(rc > 0 ){
if(rc == MOSQ_ERR_TLS){
_mosquitto_socket_close(db, context);
return rc; /* Error already printed */
}else if(rc == MOSQ_ERR_ERRNO){
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error creating bridge: %s.", strerror(errno));
}else if(rc == MOSQ_ERR_EAI){
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error creating bridge: %s.", gai_strerror(errno));
}
return rc;
}
return MOSQ_ERR_SUCCESS;
}
int bridge__connect_step2(struct mosquitto_db *db, struct mosquitto *context)
{
int rc;
if(!context || !context->bridge) return MOSQ_ERR_INVAL;
_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Connecting bridge %s (%s:%d)", context->bridge->name, context->bridge->addresses[context->bridge->cur_address].address, context->bridge->addresses[context->bridge->cur_address].port);
rc = _mosquitto_try_connect_step2(context, context->bridge->addresses[context->bridge->cur_address].port, &context->sock);
if(rc > 0 ){
if(rc == MOSQ_ERR_TLS){
_mosquitto_socket_close(db, context);
return rc; /* Error already printed */
}else if(rc == MOSQ_ERR_ERRNO){
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error creating bridge: %s.", strerror(errno));
}else if(rc == MOSQ_ERR_EAI){
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error creating bridge: %s.", gai_strerror(errno));
}
return rc;
}
rc = _mosquitto_socket_connect_step3(context, context->bridge->addresses[context->bridge->cur_address].address, context->bridge->addresses[context->bridge->cur_address].port, NULL, false);
if(rc > 0 ){
if(rc == MOSQ_ERR_TLS){
_mosquitto_socket_close(db, context);
return rc; /* Error already printed */
}else if(rc == MOSQ_ERR_ERRNO){
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error creating bridge: %s.", strerror(errno));
}else if(rc == MOSQ_ERR_EAI){
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error creating bridge: %s.", gai_strerror(errno));
}
return rc;
}
HASH_ADD(hh_sock, db->contexts_by_sock, sock, sizeof(context->sock), context);
if(rc == MOSQ_ERR_CONN_PENDING){
context->state = mosq_cs_connect_pending;
}
rc = _mosquitto_send_connect(context, context->keepalive, context->clean_session);
if(rc == MOSQ_ERR_SUCCESS){
return MOSQ_ERR_SUCCESS;
}else if(rc == MOSQ_ERR_ERRNO && errno == ENOTCONN){
return MOSQ_ERR_SUCCESS;
}else{
if(rc == MOSQ_ERR_TLS){
return rc; /* Error already printed */
}else if(rc == MOSQ_ERR_ERRNO){
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error creating bridge: %s.", strerror(errno));
}else if(rc == MOSQ_ERR_EAI){
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error creating bridge: %s.", gai_strerror(errno));
}
_mosquitto_socket_close(db, context);
return rc;
}
}
#else
int bridge__connect(struct mosquitto_db *db, struct mosquitto *context)
{
@ -218,6 +375,8 @@ int bridge__connect(struct mosquitto_db *db, struct mosquitto *context)
return rc;
}
}
#endif
void bridge__packet_cleanup(struct mosquitto *context)
{

@ -36,7 +36,7 @@ Contributors:
#endif
#if !defined(WIN32) && !defined(__CYGWIN__)
# include <sys/syslog.h>
# include <syslog.h>
#endif
#include "mosquitto_broker_internal.h"

@ -205,7 +205,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context)
rc = MOSQ_ERR_PROTOCOL;
goto handle_connect_error;
}
will_retain = connect_flags & 0x20;
will_retain = ((connect_flags & 0x20) == 0x20); // Temporary hack because MSVC<1800 doesn't have stdbool.h.
password_flag = connect_flags & 0x40;
username_flag = connect_flags & 0x80;

@ -71,6 +71,8 @@ int log__init(struct mosquitto__config *config)
}
config->log_fptr = mosquitto__fopen(config->log_file, "at");
if(!config->log_fptr){
log_destinations = MQTT3_LOG_STDERR;
log_priorities = MOSQ_LOG_ERR;
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file);
return MOSQ_ERR_INVAL;
}

@ -245,36 +245,69 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
context->bridge->primary_retry = now + 5;
}
}else{
if(context->bridge->start_type == bst_lazy && context->bridge->lazy_reconnect){
rc = bridge__connect(db, context);
if(rc){
context->bridge->cur_address++;
if(context->bridge->cur_address == context->bridge->address_count){
context->bridge->cur_address = 0;
if((context->bridge->start_type == bst_lazy && context->bridge->lazy_reconnect)
|| (context->bridge->start_type == bst_automatic && now > context->bridge->restart_t)){
#if defined(__GLIBC__) && defined(WITH_ADNS)
if(context->adns){
/* Waiting on DNS lookup */
rc = gai_error(context->adns);
if(rc == EAI_INPROGRESS){
/* Just keep on waiting */
}else if(rc == 0){
rc = bridge__connect_step2(db, context);
if(rc == MOSQ_ERR_SUCCESS){
pollfds[pollfd_index].fd = context->sock;
pollfds[pollfd_index].events = POLLIN;
pollfds[pollfd_index].revents = 0;
if(context->current_out_packet){
pollfds[pollfd_index].events |= POLLOUT;
}
context->pollfd_index = pollfd_index;
pollfd_index++;
}else{
context->bridge->cur_address++;
if(context->bridge->cur_address == context->bridge->address_count){
context->bridge->cur_address = 0;
}
}
}else{
/* Need to retry */
if(context->adns->ar_result){
freeaddrinfo(context->adns->ar_result);
}
_mosquitto_free(context->adns);
context->adns = NULL;
}
}
}
if(context->bridge->start_type == bst_automatic && now > context->bridge->restart_t){
context->bridge->restart_t = 0;
rc = bridge__connect(db, context);
if(rc == MOSQ_ERR_SUCCESS){
pollfds[pollfd_index].fd = context->sock;
pollfds[pollfd_index].events = POLLIN;
pollfds[pollfd_index].revents = 0;
if(context->current_out_packet){
pollfds[pollfd_index].events |= POLLOUT;
}
context->pollfd_index = pollfd_index;
pollfd_index++;
}else{
/* Retry later. */
context->bridge->restart_t = now+context->bridge->restart_timeout;
context->bridge->cur_address++;
if(context->bridge->cur_address == context->bridge->address_count){
context->bridge->cur_address = 0;
rc = bridge__connect_step1(db, context);
if(rc){
context->bridge->cur_address++;
if(context->bridge->cur_address == context->bridge->address_count){
context->bridge->cur_address = 0;
}
}
}
#else
{
rc = bridge__connect(db, context);
if(rc == MOSQ_ERR_SUCCESS){
pollfds[pollfd_index].fd = context->sock;
pollfds[pollfd_index].events = POLLIN;
pollfds[pollfd_index].revents = 0;
if(context->current_out_packet){
pollfds[pollfd_index].events |= POLLOUT;
}
context->pollfd_index = pollfd_index;
pollfd_index++;
}else{
context->bridge->cur_address++;
if(context->bridge->cur_address == context->bridge->address_count){
context->bridge->cur_address = 0;
}
}
}
#endif
}
}
}
@ -442,10 +475,6 @@ static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pol
}
assert(pollfds[context->pollfd_index].fd == context->sock);
if(pollfds[context->pollfd_index].revents & (POLLERR | POLLNVAL | POLLHUP)){
do_disconnect(db, context);
continue;
}
#ifdef WITH_TLS
if(pollfds[context->pollfd_index].revents & POLLOUT ||
context->want_write ||
@ -489,6 +518,10 @@ static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pol
}
}while(SSL_DATA_PENDING(context));
}
if(pollfds[context->pollfd_index].revents & (POLLERR | POLLNVAL | POLLHUP)){
do_disconnect(db, context);
continue;
}
}
}

@ -264,7 +264,10 @@ int main(int argc, char *argv[])
/* Initialise logging only after initialising the database in case we're
* logging to topics */
log__init(&config);
if(log__init(&config)){
rc = 1;
return rc;
}
log__printf(NULL, MOSQ_LOG_INFO, "mosquitto version %s (build date %s) starting", VERSION, TIMESTAMP);
if(config.config_file){
log__printf(NULL, MOSQ_LOG_INFO, "Config loaded from %s.", config.config_file);

@ -14,8 +14,8 @@ Contributors:
Roger Light - initial implementation and documentation.
*/
#ifndef MQTT3_H
#define MQTT3_H
#ifndef MOSQUITTO_BROKER_INTERNAL_H
#define MOSQUITTO_BROKER_INTERNAL_H
#include "config.h"
#include <stdio.h>
@ -31,6 +31,7 @@ Contributors:
# define libwebsocket_write(A, B, C, D) lws_write((A), (B), (C), (D))
# define libwebsocket_get_socket_fd(A) lws_get_socket_fd((A))
# define libwebsockets_return_http_status(A, B, C, D) lws_return_http_status((B), (C), (D))
# define libwebsockets_get_protocol(A) lws_get_protocol((A))
# define libwebsocket_context lws_context
# define libwebsocket_protocols lws_protocols
@ -570,6 +571,8 @@ int log__printf(struct mosquitto *mosq, int level, const char *fmt, ...) __attri
#ifdef WITH_BRIDGE
int bridge__new(struct mosquitto_db *db, struct mosquitto__bridge *bridge);
int bridge__connect(struct mosquitto_db *db, struct mosquitto *context);
int bridge__connect_step1(struct mosquitto_db *db, struct mosquitto *context);
int bridge__connect_step2(struct mosquitto_db *db, struct mosquitto *context);
void bridge__packet_cleanup(struct mosquitto *context);
#endif

@ -90,7 +90,11 @@ int output_new_password(FILE *fptr, const char *username, const char *password)
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int hash_len;
const EVP_MD *digest;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_MD_CTX context;
#else
EVP_MD_CTX *context;
#endif
rc = RAND_bytes(salt, SALT_LEN);
if(!rc){
@ -113,12 +117,21 @@ int output_new_password(FILE *fptr, const char *username, const char *password)
return 1;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_MD_CTX_init(&context);
EVP_DigestInit_ex(&context, digest, NULL);
EVP_DigestUpdate(&context, password, strlen(password));
EVP_DigestUpdate(&context, salt, SALT_LEN);
EVP_DigestFinal_ex(&context, hash, &hash_len);
EVP_MD_CTX_cleanup(&context);
#else
context = EVP_MD_CTX_new();
EVP_DigestInit_ex(context, digest, NULL);
EVP_DigestUpdate(context, password, strlen(password));
EVP_DigestUpdate(context, salt, SALT_LEN);
EVP_DigestFinal_ex(context, hash, &hash_len);
EVP_MD_CTX_free(context);
#endif
rc = base64_encode(hash, hash_len, &hash64);
if(rc){
@ -364,35 +377,50 @@ int main(int argc, char *argv[])
OpenSSL_add_all_digests();
if(argc == 5){
if(!strcmp(argv[1], "-b")){
batch_mode = true;
}else{
fprintf(stderr, "Error: Unknown option '%s'\n", argv[1]);
if(argc == 1){
print_usage();
return 1;
}
if(!strcmp(argv[1], "-c")){
create_new = true;
if(argc != 4){
fprintf(stderr, "Error: -c argument given but password file or username missing.\n");
return 1;
}else{
password_file_tmp = argv[2];
username = argv[3];
}
password_file_tmp = argv[2];
username = argv[3];
password_cmd = argv[4];
}else if(argc == 4){
if(!strcmp(argv[1], "-c")){
create_new = true;
}else if(!strcmp(argv[1], "-D")){
delete_user = true;
}else if(!strcmp(argv[1], "-D")){
delete_user = true;
if(argc != 4){
fprintf(stderr, "Error: -D argument given but password file or username missing.\n");
return 1;
}else{
fprintf(stderr, "Error: Unknown option '%s'\n", argv[1]);
password_file_tmp = argv[2];
username = argv[3];
}
}else if(!strcmp(argv[1], "-b")){
batch_mode = true;
if(argc != 5){
fprintf(stderr, "Error: -b argument given but password file, username or password missing.\n");
return 1;
}else{
password_file_tmp = argv[2];
username = argv[3];
password_cmd = argv[4];
}
password_file_tmp = argv[2];
username = argv[3];
}else if(argc == 3){
if(!strcmp(argv[1], "-U")){
}else if(!strcmp(argv[1], "-U")){
if(argc != 3){
fprintf(stderr, "Error: -U argument given but password file missing.\n");
return 1;
}else{
do_update_file = true;
password_file_tmp = argv[2];
}else{
password_file_tmp = argv[1];
username = argv[2];
}
}else if(argc == 3){
password_file_tmp = argv[1];
username = argv[2];
}else{
print_usage();
return 1;

@ -53,6 +53,10 @@ struct mosquitto_acl_msg {
*
* gcc -I<path to mosquitto_plugin.h> -fPIC -shared plugin.c -o plugin.so
*
* On Mac OS X:
*
* gcc -I<path to mosquitto_plugin.h> -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so
*
* Authentication plugins can implement one or both of authentication and
* access control. If your plugin does not wish to handle either of
* authentication or access control it should return MOSQ_ERR_PLUGIN_DEFER. In

@ -298,7 +298,7 @@ static int mosquitto__tls_server_ctx(struct mosquitto__listener *listener)
#endif
#ifdef WITH_EC
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
#if OPENSSL_VERSION_NUMBER >= 0x10002000L && OPENSSL_VERSION_NUMBER < 0x10100000L
SSL_CTX_set_ecdh_auto(listener->ssl_ctx, 1);
#elif OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10002000L
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);

@ -140,7 +140,7 @@ static int persist__message_store_write(struct mosquitto_db *db, FILE *db_fptr)
stored = db->msg_store;
while(stored){
if(stored->topic && !strncmp(stored->topic, "$SYS", 4)){
if(stored->ref_count == 1 && stored->dest_id_count == 0){
if(stored->ref_count <= 1 && stored->dest_id_count == 0){
/* $SYS messages that are only retained shouldn't be persisted. */
stored = stored->next;
continue;
@ -262,6 +262,7 @@ static int persist__subs_retain_write(struct mosquitto_db *db, FILE *db_fptr, st
char *thistopic;
uint32_t length;
uint16_t i16temp;
uint8_t i8temp;
dbid_t i64temp;
size_t slen;
@ -293,7 +294,8 @@ static int persist__subs_retain_write(struct mosquitto_db *db, FILE *db_fptr, st
write_e(db_fptr, &i16temp, sizeof(uint16_t));
write_e(db_fptr, thistopic, slen);
write_e(db_fptr, &sub->qos, sizeof(uint8_t));
i8temp = (uint8_t )sub->qos;
write_e(db_fptr, &i8temp, sizeof(uint8_t));
}
sub = sub->next;
}
@ -359,6 +361,36 @@ int persist__backup(struct mosquitto_db *db, bool shutdown)
}
snprintf(outfile, len, "%s.new", db->config->persistence_filepath);
outfile[len] = '\0';
#ifndef WIN32
/**
*
* If a system lost power during the rename operation at the
* end of this file the filesystem could potentially be left
* with a directory that looks like this after powerup:
*
* 24094 -rw-r--r-- 2 root root 4099 May 30 16:27 mosquitto.db
* 24094 -rw-r--r-- 2 root root 4099 May 30 16:27 mosquitto.db.new
*
* The 24094 shows that mosquitto.db.new is hard-linked to the
* same file as mosquitto.db. If fopen(outfile, "wb") is naively
* called then mosquitto.db will be truncated and the database
* potentially corrupted.
*
* Any existing mosquitto.db.new file must be removed prior to
* opening to guarantee that it is not hard-linked to
* mosquitto.db.
*
*/
rc = unlink(outfile);
if (rc != 0) {
if (errno != ENOENT) {
log__printf(NULL, MOSQ_LOG_INFO, "Error saving in-memory database, unable to remove %s.", outfile);
goto error;
}
}
#endif
db_fptr = mosquitto__fopen(outfile, "wb");
if(db_fptr == NULL){
log__printf(NULL, MOSQ_LOG_INFO, "Error saving in-memory database, unable to open %s for writing.", outfile);
@ -392,6 +424,32 @@ int persist__backup(struct mosquitto_db *db, bool shutdown)
persist__client_write(db, db_fptr);
persist__subs_retain_write_all(db, db_fptr);
#ifndef WIN32
/**
*
* Closing a file does not guarantee that the contents are
* written to disk. Need to flush to send data from app to OS
* buffers, then fsync to deliver data from OS buffers to disk
* (as well as disk hardware permits).
*
* man close (http://linux.die.net/man/2/close, 2016-06-20):
*
* "successful close does not guarantee that the data has
* been successfully saved to disk, as the kernel defers
* writes. It is not common for a filesystem to flush
* the buffers when the stream is closed. If you need
* to be sure that the data is physically stored, use
* fsync(2). (It will depend on the disk hardware at this
* point."
*
* This guarantees that the new state file will not overwrite
* the old state file before its contents are valid.
*
*/
fflush(db_fptr);
fsync(fileno(db_fptr));
#endif
fclose(db_fptr);
#ifdef WIN32
@ -767,7 +825,14 @@ int persist__restore(struct mosquitto_db *db)
fptr = mosquitto__fopen(db->config->persistence_filepath, "rb");
if(fptr == NULL) return MOSQ_ERR_SUCCESS;
read_e(fptr, &header, 15);
rlen = fread(&header, 1, 15, fptr);
if(rlen == 0){
fclose(fptr);
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Persistence file is empty.");
return 0;
}else if(rlen != 15){
goto error;
}
if(!memcmp(header, magic, 15)){
// Restore DB as normal
read_e(fptr, &crc, sizeof(uint32_t));

@ -768,6 +768,7 @@ int mosquitto_psk_key_get_default(struct mosquitto_db *db, const char *hint, con
int pw__digest(const char *password, const unsigned char *salt, unsigned int salt_len, unsigned char *hash, unsigned int *hash_len)
{
const EVP_MD *digest;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_MD_CTX context;
digest = EVP_get_digestbyname("sha512");
@ -783,6 +784,23 @@ int pw__digest(const char *password, const unsigned char *salt, unsigned int sal
/* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */
EVP_DigestFinal_ex(&context, hash, hash_len);
EVP_MD_CTX_cleanup(&context);
#else
EVP_MD_CTX *context;
digest = EVP_get_digestbyname("sha512");
if(!digest){
// FIXME fprintf(stderr, "Error: Unable to create openssl digest.\n");
return 1;
}
context = EVP_MD_CTX_new();
EVP_DigestInit_ex(context, digest, NULL);
EVP_DigestUpdate(context, password, strlen(password));
EVP_DigestUpdate(context, salt, salt_len);
/* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */
EVP_DigestFinal_ex(context, hash, hash_len);
EVP_MD_CTX_free(context);
#endif
return MOSQ_ERR_SUCCESS;
}

@ -150,7 +150,8 @@ static int callback_mqtt(struct libwebsocket_context *context,
struct mosquitto_db *db;
struct mosquitto *mosq = NULL;
struct mosquitto__packet *packet;
int count;
int count, i, j;
const struct libwebsocket_protocols *p;
struct libws_mqtt_data *u = (struct libws_mqtt_data *)user;
size_t pos;
uint8_t *buf;
@ -163,6 +164,21 @@ static int callback_mqtt(struct libwebsocket_context *context,
case LWS_CALLBACK_ESTABLISHED:
mosq = context__init(db, WEBSOCKET_CLIENT);
if(mosq){
p = libwebsockets_get_protocol(wsi);
for (i=0; i<db->config->listener_count; i++){
if (db->config->listeners[i].protocol == mp_websockets) {
for (j=0; db->config->listeners[i].ws_protocol[j].name; j++){
if (p == &db->config->listeners[i].ws_protocol[j]){
mosq->listener = &db->config->listeners[i];
mosq->listener->client_count++;
}
}
}
}
if(!mosq->listener){
mosquitto__free(mosq);
return -1;
}
#if !defined(LWS_LIBRARY_VERSION_NUMBER)
mosq->ws_context = context;
#endif
@ -178,6 +194,12 @@ static int callback_mqtt(struct libwebsocket_context *context,
u->mosq = NULL;
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);
mosquitto__free(mosq);
u->mosq = NULL;
return -1;
}
break;
case LWS_CALLBACK_CLOSED:
@ -455,6 +477,7 @@ static int callback_http(struct libwebsocket_context *context,
if(fstat(fileno(u->fptr), &filestat) < 0){
libwebsockets_return_http_status(context, wsi, HTTP_STATUS_INTERNAL_SERVER_ERROR, NULL);
fclose(u->fptr);
u->fptr = NULL;
return -1;
}
#ifdef WIN32
@ -463,6 +486,8 @@ static int callback_http(struct libwebsocket_context *context,
if(!S_ISREG(filestat.st_mode)){
#endif
libwebsockets_return_http_status(context, wsi, HTTP_STATUS_FORBIDDEN, NULL);
fclose(u->fptr);
u->fptr = NULL;
return -1;
}
@ -472,6 +497,7 @@ static int callback_http(struct libwebsocket_context *context,
(unsigned int)filestat.st_size);
if(libwebsocket_write(wsi, buf, buflen, LWS_WRITE_HTTP) < 0){
fclose(u->fptr);
u->fptr = NULL;
return -1;
}
libwebsocket_callback_on_writable(context, wsi);
@ -496,6 +522,7 @@ static int callback_http(struct libwebsocket_context *context,
buflen = fread(buf, 1, sizeof(buf), u->fptr);
if(buflen < 1){
fclose(u->fptr);
u->fptr = NULL;
return -1;
}
wlen = libwebsocket_write(wsi, buf, buflen, LWS_WRITE_HTTP);
@ -516,6 +543,16 @@ static int callback_http(struct libwebsocket_context *context,
}else{
return -1;
}
break;
case LWS_CALLBACK_CLOSED:
case LWS_CALLBACK_CLOSED_HTTP:
case LWS_CALLBACK_HTTP_FILE_COMPLETION:
if(u && u->fptr){
fclose(u->fptr);
u->fptr = NULL;
}
break;
default:
return 0;
@ -570,6 +607,9 @@ struct libwebsocket_context *mosq_websockets_init(struct mosquitto__listener *li
}
#endif
info.options |= LWS_SERVER_OPTION_DISABLE_IPV6;
#if LWS_LIBRARY_VERSION_MAJOR>1
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
#endif
user = mosquitto__calloc(1, sizeof(struct libws_mqtt_hack));
if(!user){
@ -587,7 +627,7 @@ struct libwebsocket_context *mosq_websockets_init(struct mosquitto__listener *li
if(!user->http_dir){
mosquitto__free(user);
mosquitto__free(p);
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open http dir \"%s\".", user->http_dir);
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open http dir \"%s\".", listener->http_dir);
return NULL;
}
}

Loading…
Cancel
Save