diff --git a/ChangeLog.txt b/ChangeLog.txt index 788485f87c..acbd117f09 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,4 +1,4 @@ -1.5 - 2016xxxx +1.5 - 2017xxxx ============== Broker: @@ -72,6 +72,31 @@ Build: build and install static versions of the client libraries. +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 ================= diff --git a/appveyor.yml b/appveyor.yml index 9e2dffa0f6..a38583e8e7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,7 @@ os: Visual Studio 2013 environment: CMAKE_ARGS: -DCMAKE_BUILD_TYPE=Release NSIS_ROOT: C:\nsis - SSL_VER: 1_0_2h + SSL_VER: 1_0_2k configuration: - Release diff --git a/config.mk b/config.mk index 347b711828..584fcbe55e 100644 --- a/config.mk +++ b/config.mk @@ -169,10 +169,6 @@ 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 diff --git a/doc/joss-paper/codemeta.json b/doc/joss-paper/codemeta.json new file mode 100644 index 0000000000..d23c57f059 --- /dev/null +++ b/doc/joss-paper/codemeta.json @@ -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" +} \ No newline at end of file diff --git a/doc/joss-paper/paper.bib b/doc/joss-paper/paper.bib new file mode 100644 index 0000000000..9bdb921cf4 --- /dev/null +++ b/doc/joss-paper/paper.bib @@ -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} +} diff --git a/doc/joss-paper/paper.md b/doc/joss-paper/paper.md new file mode 100644 index 0000000000..ce08ced3bc --- /dev/null +++ b/doc/joss-paper/paper.md @@ -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 + diff --git a/lib/net_mosq.c b/lib/net_mosq.c index 068bfaaba8..9fbeaa1489 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -109,7 +109,9 @@ int net__init(void) void 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(); diff --git a/readme.md b/readme.md index 9515380dff..0ae7587f70 100644 --- a/readme.md +++ b/readme.md @@ -65,9 +65,9 @@ already be built. Use `make binary` to skip building the man pages, or install ### Build Dependencies -* c-ares (libc-ares-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 diff --git a/set-version.sh b/set-version.sh index 75c0b5299c..ee81183d3e 100755 --- a/set-version.sh +++ b/set-version.sh @@ -2,7 +2,7 @@ MAJOR=1 MINOR=4 -REVISION=11 +REVISION=12 sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk diff --git a/src/conf.c b/src/conf.c index 318b3288a2..dfb9c982ea 100644 --- a/src/conf.c +++ b/src/conf.c @@ -953,6 +953,14 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, const if(reload) continue; // FIXME token = strtok_r(NULL, " ", &saveptr); if(token){ + /* Check for existing bridge name. */ + for(i=0; ibridge_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 mosquitto__bridge)); if(!config->bridges){ diff --git a/src/loop.c b/src/loop.c index 4e300f6838..adc089bf7e 100644 --- a/src/loop.c +++ b/src/loop.c @@ -247,7 +247,7 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li }else{ 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; #if defined(__GLIBC__) && defined(WITH_ADNS) if(context->adns){ /* Waiting on DNS lookup */ diff --git a/src/mosquitto_passwd.c b/src/mosquitto_passwd.c index 9689dd8910..aef8cd05f0 100644 --- a/src/mosquitto_passwd.c +++ b/src/mosquitto_passwd.c @@ -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); diff --git a/src/persist.c b/src/persist.c index 91def9a780..c85e59c4bc 100644 --- a/src/persist.c +++ b/src/persist.c @@ -79,6 +79,16 @@ static int persist__client_messages_write(struct mosquitto_db *db, FILE *db_fptr cmsg = queue; 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) + diff --git a/src/security.c b/src/security.c index b1d4f7964f..7b82581250 100644 --- a/src/security.c +++ b/src/security.c @@ -353,6 +353,7 @@ int mosquitto_acl_check(struct mosquitto_db *db, struct mosquitto *context, cons int rc; int i; struct mosquitto_acl_msg msg; + char *username; if(!context->id){ return MOSQ_ERR_ACL_DENIED; @@ -369,10 +370,27 @@ int mosquitto_acl_check(struct mosquitto_db *db, struct mosquitto *context, cons for(i=0; iauth_plugin_count; i++){ memset(&msg, 0, sizeof(msg)); msg.topic = topic; + + username = mosquito_client_username(context); + /* 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; + } + if(db->auth_plugins[i].version == 3){ rc = db->auth_plugins[i].acl_check_v3(db->auth_plugins[i].user_data, access, context, &msg); }else if(db->auth_plugins[i].version == 2){ - rc = db->auth_plugins[i].acl_check_v2(db->auth_plugins[i].user_data, context->id, mosquitto_client_username(context), topic, access); + rc = db->auth_plugins[i].acl_check_v2(db->auth_plugins[i].user_data, context->id, username, topic, access); }else{ rc = MOSQ_ERR_INVAL; } diff --git a/src/security_default.c b/src/security_default.c index 1b50280613..86933a0d9d 100644 --- a/src/security_default.c +++ b/src/security_default.c @@ -263,6 +263,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){