Merge branch 'master' into debian

pull/684/head
Roger A. Light 8 years ago
commit a0916bdd67

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

@ -1,3 +1,51 @@
1.4.12 - 20170528
=================
Security:
- Fix CVE-2017-7650, which allows clients with username or client id set to
'#' or '+' to bypass pattern based ACLs or third party plugins. The fix
denies message sending or receiving of messages for clients with a '#' or
'+' in their username or client id and if the message is subject to a
pattern ACL check or plugin check.
Patches for other versions are available at
https://mosquitto.org/files/cve/2017-7650/
Broker:
- Fix mosquitto.db from becoming corrupted due to client messages being
persisted with no stored message. Closes #424.
- Fix bridge not restarting properly. Closes #428.
- Fix unitialized memory in gets_quiet on Windows. Closes #426.
- Fix building with WITH_ADNS=no for systems that don't use glibc. Closes
#415.
- Fixes to readme.md.
- Fix deprecation warning for OpenSSL 1.1. PR #416.
- Don't segfault on duplicate bridge names. Closes #446.
- Fix CVE-2017-7650.
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
=================

@ -3,7 +3,7 @@ os: Visual Studio 2013
environment:
CMAKE_ARGS: -DCMAKE_BUILD_TYPE=Release
NSIS_ROOT: C:\nsis
SSL_VER: 1_0_2h
SSL_VER: 1_0_2k
configuration:
- Release

@ -690,7 +690,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;
@ -924,6 +924,10 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url)
port[len] = '\0';
}else{
host = malloc(len + 1);
if(!host){
fprintf(stderr, "Error: Out of memory.\n");
goto cleanup;
}
memcpy(host, &(str[start]), len);
host[len] = '\0';
}

@ -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

@ -76,6 +76,9 @@ WITH_DOCS:=yes
# Build with client support for SOCK5 proxy.
WITH_SOCKS:=yes
# Build with async dns lookup support for bridges (temporary). Requires glibc.
#WITH_ADNS:=yes
# =============================================================================
# End of user configuration
# =============================================================================
@ -83,7 +86,7 @@ WITH_SOCKS:=yes
# Also bump lib/mosquitto.h, CMakeLists.txt,
# installer/mosquitto.nsi, installer/mosquitto-cygwin.nsi
VERSION=1.4.10
VERSION=1.4.12
TIMESTAMP:=$(shell date "+%F %T%z")
# Client library SO version. Bump if incompatible API/ABI changes are made.
@ -235,6 +238,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,23 @@
{
"@context": "https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld",
"@type": "Code",
"author": [
{
"@id": "http://orcid.org/0000-0001-9218-7797",
"@type": "Person",
"email": "",
"name": "Roger A. Light",
"affiliation": ""
}
],
"identifier": "",
"codeRepository": "https://github.com/eclipse/mosquitto",
"datePublished": "2017-05-17",
"dateModified": "2017-05-17",
"dateCreated": "2017-05-17",
"description": "Broker and client implementation of the MQTT protocol.",
"keywords": "IoT, MQTT, messaging, pubsub",
"license": "EPL 2.0 / EDL 2.0",
"title": "Mosquitto",
"version": "v1.4.11"
}

@ -0,0 +1,77 @@
@inproceedings{Schulz_2014,
title = {Real-time animation of equipment in a remote laboratory},
doi = {10.1109/REV.2014.6784247},
booktitle = {2014 11th {International} {Conference} on {Remote} {Engineering} and {Virtual} {Instrumentation} ({REV})},
author = {Schulz, M. and Chen, F. and Payne, L.},
month = feb,
year = {2014},
keywords = {Animation, cameras, client-server systems, computer aided instruction, computer animation, Computer architecture, data path, data streaming, Electron tubes, Engines, equipment animation, Hardware, message server, MIT iLabs shared architecture, MQTT, real-time animation, real-time systems, remote laboratory, servers, software architecture, student experiments, webcam},
pages = {172--176}
}
@inproceedings{Antonic_2015,
title = {Comparison of the {CUPUS} middleware and {MQTT} protocol for smart city services},
doi = {10.1109/ConTEL.2015.7231225},
booktitle = {2015 13th {International} {Conference} on {Telecommunications} ({Con}TEL)},
author = {Antonić, A. and Marjanović, M. and Skočir, P. and Žarko, I. P.},
month = jul,
year = {2015},
keywords = {cloud-based publish-subscribe middleware, cloud computing, CUPUS middleware, Engines, FP7 project OpenIoT platform, Internet of Things, IoT services, message passing, message queue telemetry transport protocol, message queuing solutions, middleware, Mobile communication, mobile computing, mobile devices, Mobile handsets, MQTT protocol, open-source cloud platform, Protocols, public domain software, sensors, smart cities, smart city services, telemetry, transport protocols, wearable sensors, wireless sensor networks, WSNs},
pages = {1--8}
}
@inproceedings{Thangavel_2014,
title = {Performance evaluation of {MQTT} and {CoAP} via a common middleware},
doi = {10.1109/ISSNIP.2014.6827678},
booktitle = {2014 {IEEE} {Ninth} {International} {Conference} on {Intelligent} {Sensors}, {Sensor} {Networks} and {Information} {Processing} ({ISSNIP})},
author = {Thangavel, D. and Ma, X. and Valera, A. and Tan, H. X. and Tan, C. K. Y.},
month = apr,
year = {2014},
keywords = {bandwidth consumption, CoAP, constrained application protocol, data transmission, delays, end-to-end delay, gateways, internetworking, Logic gates, message queue telemetry transport, middleware, MQTT, Packet loss, Protocols, Quality of service, queueing theory, sensor nodes, servers, wireless sensor networks},
pages = {1--6}
}
@inproceedings{Kang_2017,
title = {Room {Temperature} {Control} and {Fire} {Alarm} \#x002F;{Suppression} {IoT} {Service} {Using} {MQTT} on {AWS}},
doi = {10.1109/PlatCon.2017.7883724},
abstract = {In this paper we build an MQTT(Message Queue Telemetry Transportation) broker on Amazon Web Service(AWS). The MQTT broker has been utilized as a platform to provide the Internet of Things(IoT) services which monitor and control room temperatures, and sense, alarm, and suppress fire. Arduino was used as the IoT end device connecting sensors and actuators to the platform via Wi-Fi channel. We created smart home scenario and designed IoT massages satisfying the scenario requirement. We also implemented the smart some system in hardware and software, and verified the system operation. We show that MQTT and AWS are good technical candidates for small IoT business applications.},
booktitle = {2017 {International} {Conference} on {Platform} {Technology} and {Service} ({PlatCon})},
author = {Kang, D. H. and Park, M. S. and Kim, H. S. and Kim, D. y and Kim, S. H. and Son, H. J. and Lee, S. G.},
month = feb,
year = {2017},
note = {00000},
keywords = {Actuators, Amazon web service, AWS, electronic messaging, fire alarm-suppression IoT service, fires, Internet of Things, Internet of Things services, message queue telemetry transportation, MQTT broker, queueing theory, room temperature control, room temperature monitoring, sensors, small IoT business applications, smart home scenario, smart some system, telemetry, temperature 293 K to 298 K, Web services, Wi-Fi channel, wireless LAN},
pages = {1--5}
}
@inproceedings{Fremantle_2014,
title = {Federated {Identity} and {Access} {Management} for the {Internet} of {Things}},
doi = {10.1109/SIoT.2014.8},
abstract = {We examine the use of Federated Identity and Access Management (FIAM) approaches for the Internet of Things (IoT). We look at specific challenges that devices, sensors and actuators have, and look for approaches to address them. OAuth is a widely deployed protocol built on top of HTTP for applying FIAM to Web systems. We explore the use of OAuth for IoT systems that instead use the lightweight MQTT 3.1 protocol. In order to evaluate this area, we built a prototype that uses OAuth 2.0 to enable access control to information distributed via MQTT. We evaluate the results of this prototyping activity, and assess the strengths and weaknesses of this approach, and the benefits of using the FIAM approaches with IoT and Machine to Machine (M2M) scenarios. Finally we outline areas for further research.},
booktitle = {2014 {International} {Workshop} on {Secure} {Internet} of {Things}},
author = {Fremantle, P. and Aziz, B. and Kopecký, J. and Scott, P.},
month = sep,
year = {2014},
note = {00026},
keywords = {access control, Authentication, authorisation, Authorization, federated identity and access management, FIAM, Hip, Internet of Things, IoT, M2M scenarios, machine to machine scenarios, MQTT 3.1 protocol, OAuth 2.0, Protocols, servers},
pages = {10--17}
}
@article{Bellavista_2017,
title = {The {PeRvasive} {Environment} {Sensing} and {Sharing} {Solution}},
volume = {9},
copyright = {http://creativecommons.org/licenses/by/3.0/},
url = {http://www.mdpi.com/2071-1050/9/4/585},
doi = {10.3390/su9040585},
abstract = {to stimulate better user behavior and improve environmental and economic sustainability, it is of paramount importance to make citizens effectively aware of the quality of the environment in which they live every day. in particular, we claim that users could significantly benefit from cost-effective efficient internet-of-things (iot) solutions that provide them with up-to-date live information about air pollution in the areas where they live, suitably adapted to different situations and with different levels of dynamically selected granularities (e.g., at home/district/city levels). our pervasive environment sensing and sharing (press) project has the ambition of increasing users awareness of the natural environment they live in, as a first step towards improved sustainability; the primary target is the efficient provisioning of real-time user-centric information about environmental conditions in the surroundings, and in particular about air pollution. to this purpose, we have designed, implemented, and thoroughly evaluated the press framework, which is capable of achieving good flexibility and scalability while integrating heterogeneous monitoring data, ranging from sensed air pollution to user-provided quality perceptions. among the elements of technical originality, press exploits extended kura iot gateways with novel congestion detection and recovery mechanisms that allow us to optimize bandwidth allocation between in-the-field press components and the cloud. the reported performance results show the feasibility of the proposed solution, by pointing out not only the scalability and efficiency of the adopted message-based solution that uses message queue telemetry transport (mqtt) and websockets, but also the capability of press to quickly identify and manage traffic congestions, thus, ensuring good quality levels to final users.},
language = {en},
number = {4},
urldate = {2017-05-17},
journal = {sustainability},
author = {Bellavista, Paolo and Giannelli, Carlo and Zamagna, Riccardo},
month = apr,
year = {2017},
note = {00000},
keywords = {dynamic extensibility, environmental monitoring, heterogeneous monitoring data, mqtt, scalability, traffic congestion management, websockets},
pages = {585}
}

@ -0,0 +1,49 @@
---
title: 'Mosquitto: server and client implementation of the MQTT protocol'
tags:
- Internet of Things
- MQTT
- Pubsub
- Messaging
authors:
- name: Roger A Light
orcid: 0000-0001-9218-7797
date: 17 May 2017
bibliography: paper.bib
---
# Summary
Mosquitto provides standards compliant server and client implementations of the
[MQTT](http://mqtt.org/) messaging protocol. MQTT uses a publish/subscribe
model, has low network overhead and can be implemented on low power devices
such microcontrollers that might be used in remote Internet of Things sensors.
As such, Mosquitto is intended for use in all situations where there is a need
for lightweight messaging, particularly on constrained devices with limited
resources.
The Mosquitto project is a member of the [Eclipse Foundation](http://eclipse.org/)
There are three parts to the project.
* The main `mosquitto` server
* The `mosquitto_pub` and `mosquitto_sub` client utilities that are one method of communicating with an MQTT server
* An MQTT client library written in C, with a C++ wrapper
Mosquitto allows research directly related to the MQTT protocol itself, such as
comparing the performance of MQTT and the Constrained Application Protocol
(CoAP) [@Thangavel_2014] or investigating the use of OAuth in MQTT
[@Fremantle_2014]. Mosquitto supports other research activities as a useful
block for building larger systems and has been used to evaluate MQTT for use in
Smart City Services [@Antonic_2015], and in the development of an environmental
monitoring system [@Bellavista_2017]. Mosquitto has also been used to support
research less directly as part of a scheme for remote control of an experiment
[@Schulz_2014].
Outside of academia, Mosquitto is used in other open source projects such as
the [openHAB](http://www.openhab.org/) home automation project and
[OwnTracks](http://owntracks.org/), the personal location tracking project, and
has been integrated into commercial products.
# References

@ -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.

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

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

@ -7,7 +7,12 @@ if (${WITH_THREADING} STREQUAL ON)
set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x86\\pthreadVC2.lib)
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)
@ -44,7 +49,10 @@ add_library(libmosquitto SHARED
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)

@ -4,18 +4,18 @@ Copyright (c) 2010-2013 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 {
@ -90,15 +90,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;}
};
}

@ -520,6 +520,10 @@ static int _mosquitto_reconnect(struct mosquitto *mosq, bool blocking)
_mosquitto_messages_reconnect_reset(mosq);
if(mosq->sock != INVALID_SOCKET){
_mosquitto_socket_close(mosq); //close socket
}
#ifdef WITH_SOCKS
if(mosq->socks5_host){
rc = _mosquitto_socket_connect(mosq, mosq->socks5_host, mosq->socks5_port, mosq->bind_address, blocking);
@ -912,6 +916,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;

@ -14,8 +14,8 @@ Contributors:
Roger Light - initial implementation and documentation.
*/
#ifndef _MOSQUITTO_H_
#define _MOSQUITTO_H_
#ifndef MOSQUITTO_H
#define MOSQUITTO_H
#ifdef __cplusplus
extern "C" {
@ -45,7 +45,7 @@ extern "C" {
#define LIBMOSQUITTO_MAJOR 1
#define LIBMOSQUITTO_MINOR 4
#define LIBMOSQUITTO_REVISION 10
#define LIBMOSQUITTO_REVISION 12
/* 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)

@ -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>
@ -111,7 +114,9 @@ void _mosquitto_net_init(void)
void _mosquitto_net_cleanup(void)
{
#ifdef WITH_TLS
ERR_remove_state(0);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
ERR_remove_state(0);
#endif
ENGINE_cleanup();
CONF_modules_unload(1);
ERR_free_strings();
@ -268,6 +273,96 @@ 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 _mosquitto_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 _mosquitto_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(_mosquitto_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(_mosquitto_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 _mosquitto_try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mosq_sock_t *sock, const char *bind_address, bool blocking)
{
struct addrinfo hints;
@ -281,14 +376,7 @@ int _mosquitto_try_connect(struct mosquitto *mosq, const char *host, uint16_t po
*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;
@ -310,7 +398,7 @@ int _mosquitto_try_connect(struct mosquitto *mosq, const char *host, uint16_t po
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){
@ -403,24 +491,13 @@ int mosquitto__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 _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking)
int _mosquitto_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 = _mosquitto_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
@ -432,7 +509,7 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t
mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
}else{
_mosquitto_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
@ -440,13 +517,13 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t
mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
}else{
_mosquitto_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){
_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context.");
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
return MOSQ_ERR_TLS;
}
@ -463,7 +540,7 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t
ret = SSL_CTX_set_cipher_list(mosq->ssl_ctx, mosq->tls_ciphers);
if(ret == 0){
_mosquitto_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);
return MOSQ_ERR_TLS;
}
}
@ -487,7 +564,7 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t
_mosquitto_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);
return MOSQ_ERR_TLS;
}
if(mosq->tls_cert_reqs == 0){
@ -509,7 +586,7 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t
#else
_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile);
#endif
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
return MOSQ_ERR_TLS;
}
}
@ -521,13 +598,13 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t
#else
_mosquitto_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);
return MOSQ_ERR_TLS;
}
ret = SSL_CTX_check_private_key(mosq->ssl_ctx);
if(ret != 1){
_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent.");
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
return MOSQ_ERR_TLS;
}
}
@ -539,26 +616,43 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t
mosq->ssl = SSL_new(mosq->ssl_ctx);
if(!mosq->ssl){
COMPAT_CLOSE(sock);
COMPAT_CLOSE(mosq->sock);
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);
return MOSQ_ERR_TLS;
}
SSL_set_bio(mosq->ssl, bio, bio);
mosq->sock = sock;
if(mosquitto__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 _mosquitto_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 = _mosquitto_try_connect(mosq, host, port, &sock, bind_address, blocking);
if(rc > 0) return rc;
mosq->sock = sock;
rc = _mosquitto_socket_connect_step3(mosq, host, port, bind_address, blocking);
return rc;
}

@ -61,6 +61,9 @@ int _mosquitto_socket_close(struct mosquitto_db *db, struct mosquitto *mosq);
int _mosquitto_socket_close(struct mosquitto *mosq);
#endif
int _mosquitto_try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mosq_sock_t *sock, const char *bind_address, bool blocking);
int _mosquitto_try_connect_step1(struct mosquitto *mosq, const char *host);
int _mosquitto_try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *sock);
int _mosquitto_socket_connect_step3(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking);
int _mosquitto_socket_nonblock(mosq_sock_t sock);
int _mosquitto_socketpair(mosq_sock_t *sp1, mosq_sock_t *sp2);

@ -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

@ -65,9 +65,9 @@ already be built. Use `make binary` to skip building the man pages, or install
### Build Dependencies
* c-ares (libc-ares2-dev on Debian based systems) - disable with `make WITH_DNS_SRV=no`
* c-ares (libc-ares-dev on Debian based systems) - disable with `make WITH_SRV=no`
* libuuid (uuid-dev) - disable with `make WITH_UUID=no`
* libwebsockets (libwebsockets-dev) - enable with `make WITH_LIBWEBSOCKETS=yes`
* libwebsockets (libwebsockets-dev) - enable with `make WITH_WEBSOCKETS=yes`
* openssl (libssl-dev on Debian based systems) - disable with `make WITH_TLS=no`
## Credits

@ -2,7 +2,7 @@
MAJOR=1
MINOR=4
REVISION=9
REVISION=12
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*

@ -82,11 +82,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)

@ -131,9 +131,166 @@ int mqtt3_bridge_new(struct mosquitto_db *db, struct _mqtt3_bridge *bridge)
return MOSQ_ERR_NOMEM;
}
#if defined(__GLIBC__) && defined(WITH_ADNS)
new_context->bridge->restart_t = 1; /* force quick restart of bridge */
return mqtt3_bridge_connect_step1(db, new_context);
#else
return mqtt3_bridge_connect(db, new_context);
#endif
}
#if defined(__GLIBC__) && defined(WITH_ADNS)
int mqtt3_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 mqtt3_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 mqtt3_bridge_connect(struct mosquitto_db *db, struct mosquitto *context)
{
int rc;
@ -244,6 +401,8 @@ int mqtt3_bridge_connect(struct mosquitto_db *db, struct mosquitto *context)
return rc;
}
}
#endif
void mqtt3_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.h>
@ -309,7 +309,7 @@ void mqtt3_config_cleanup(struct mqtt3_config *config)
static void print_usage(void)
{
printf("mosquitto version %s (build date %s)\n\n", VERSION, TIMESTAMP);
printf("mosquitto is an MQTT v3.1 broker.\n\n");
printf("mosquitto is an MQTT v3.1.1/v3.1 broker.\n\n");
printf("Usage: mosquitto [-c config_file] [-d] [-h] [-p port]\n\n");
printf(" -c : specify the broker config file.\n");
printf(" -d : put the broker into the background after starting.\n");
@ -916,6 +916,14 @@ int _config_read_file_core(struct mqtt3_config *config, bool reload, const char
if(reload) continue; // FIXME
token = strtok_r(NULL, " ", &saveptr);
if(token){
/* Check for existing bridge name. */
for(i=0; i<config->bridge_count; i++){
if(!strcmp(config->bridges[i].name, token)){
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Duplicate bridge name \"%s\".", token);
return MOSQ_ERR_INVAL;
}
}
config->bridge_count++;
config->bridges = _mosquitto_realloc(config->bridges, config->bridge_count*sizeof(struct _mqtt3_bridge));
if(!config->bridges){

@ -244,36 +244,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 = mqtt3_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_automatic && now > context->bridge->restart_t){
if((context->bridge->start_type == bst_lazy && context->bridge->lazy_reconnect)
|| (context->bridge->start_type == bst_automatic && now > context->bridge->restart_t)){
context->bridge->restart_t = 0;
rc = mqtt3_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;
#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 = mqtt3_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;
}
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 = mqtt3_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 = mqtt3_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
}
}
}

@ -31,7 +31,7 @@ Contributors:
# define libwebsocket_write(A, B, C, D) lws_write((A), (B), (C), (D))
# define libwebsocket_get_socket_fd(A) lws_get_socket_fd((A))
# define libwebsockets_return_http_status(A, B, C, D) lws_return_http_status((B), (C), (D))
# define libwebsocket_get_protocol(A) lws_get_protocol((A))
# define libwebsockets_get_protocol(A) lws_get_protocol((A))
# define libwebsocket_context lws_context
# define libwebsocket_protocols lws_protocols
@ -466,6 +466,8 @@ int _mosquitto_log_printf(struct mosquitto *mosq, int level, const char *fmt, ..
#ifdef WITH_BRIDGE
int mqtt3_bridge_new(struct mosquitto_db *db, struct _mqtt3_bridge *bridge);
int mqtt3_bridge_connect(struct mosquitto_db *db, struct mosquitto *context);
int mqtt3_bridge_connect_step1(struct mosquitto_db *db, struct mosquitto *context);
int mqtt3_bridge_connect_step2(struct mosquitto_db *db, struct mosquitto *context);
void mqtt3_bridge_packet_cleanup(struct mosquitto *context);
#endif

@ -230,6 +230,7 @@ int gets_quiet(char *s, int len)
memset(s, 0, len);
h = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(h, &con_orig);
con_quiet = con_orig;
con_quiet &= ~ENABLE_ECHO_INPUT;
con_quiet |= ENABLE_LINE_INPUT;
SetConsoleMode(h, con_quiet);
@ -377,35 +378,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;

@ -79,6 +79,16 @@ static int mqtt3_db_client_messages_write(struct mosquitto_db *db, FILE *db_fptr
cmsg = context->msgs;
while(cmsg){
if(!strncmp(cmsg->store->topic, "$SYS", 4)
&& cmsg->store->ref_count <= 1
&& cmsg->store->dest_id_count == 0){
/* This $SYS message won't have been persisted, so we can't persist
* this client message. */
cmsg = cmsg->next;
continue;
}
slen = strlen(context->id);
length = htonl(sizeof(dbid_t) + sizeof(uint16_t) + sizeof(uint8_t) +
@ -813,7 +823,14 @@ int mqtt3_db_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);
_mosquitto_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));

@ -233,6 +233,21 @@ int mosquitto_acl_check(struct mosquitto_db *db, struct mosquitto *context, cons
{
username = context->username;
}
/* Check whether the client id or username contains a +, # or / and if
* so deny access.
*
* Do this check for every message regardless, we have to protect the
* plugins against possible pattern based attacks.
*/
if(username && strpbrk(username, "+#/")){
_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "ACL denying access to client with dangerous username \"%s\"", username);
return MOSQ_ERR_ACL_DENIED;
}
if(context->id && strpbrk(context->id, "+#/")){
_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "ACL denying access to client with dangerous client id \"%s\"", context->id);
return MOSQ_ERR_ACL_DENIED;
}
return db->auth_plugin.acl_check(db->auth_plugin.user_data, context->id, username, topic, access);
}
}

@ -261,6 +261,26 @@ int mosquitto_acl_check_default(struct mosquitto_db *db, struct mosquitto *conte
}
acl_root = db->acl_patterns;
if(acl_root){
/* We are using pattern based acls. Check whether the username or
* client id contains a +, # or / and if so deny access.
*
* Without this, a malicious client may configure its username/client
* id to bypass ACL checks (or have a username/client id that cannot
* publish or receive messages to its own place in the hierarchy).
*/
if(context->username && strpbrk(context->username, "+#/")){
_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "ACL denying access to client with dangerous username \"%s\"", context->username);
return MOSQ_ERR_ACL_DENIED;
}
if(context->id && strpbrk(context->id, "+#/")){
_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "ACL denying access to client with dangerous client id \"%s\"", context->id);
return MOSQ_ERR_ACL_DENIED;
}
}
/* Loop through all pattern ACLs. */
clen = strlen(context->id);
while(acl_root){

@ -182,7 +182,7 @@ static int callback_mqtt(struct libwebsocket_context *context,
case LWS_CALLBACK_ESTABLISHED:
mosq = mqtt3_context_init(db, WEBSOCKET_CLIENT);
if(mosq){
p = libwebsocket_get_protocol(wsi);
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++){
@ -193,7 +193,10 @@ static int callback_mqtt(struct libwebsocket_context *context,
}
}
}
if(!mosq->listener){
_mosquitto_free(mosq);
return -1;
}
#if !defined(LWS_LIBRARY_VERSION_NUMBER)
mosq->ws_context = context;
#endif
@ -209,6 +212,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){
_mosquitto_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:
@ -495,6 +504,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
@ -503,6 +513,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;
}
@ -512,6 +524,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);
@ -537,6 +550,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);
@ -557,6 +571,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;
#endif
default:
@ -636,7 +660,7 @@ struct libwebsocket_context *mosq_websockets_init(struct _mqtt3_listener *listen
if(!user->http_dir){
_mosquitto_free(user);
_mosquitto_free(p);
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open http dir \"%s\".", user->http_dir);
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open http dir \"%s\".", listener->http_dir);
return NULL;
}
}

Loading…
Cancel
Save