From 0928797e57b11739c6b697ff9ed6092c0bfada00 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 2 May 2019 16:22:42 +0000 Subject: [PATCH 01/52] lib: fix missing openssl/ui.h include. Signed-off-by: Karl Palsson --- lib/net_mosq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/net_mosq.c b/lib/net_mosq.c index 745b1709..bdcaa19c 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -50,6 +50,7 @@ Contributors: #include #include #include +#include #include #endif From 22303848e2ad5e2ce8883c0b74011003c0f8f336 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 2 May 2019 16:37:03 +0000 Subject: [PATCH 02/52] ssl: support openssl with ENGINE support disabled. Alternatively, just drop support for this config. Signed-off-by: Karl Palsson --- lib/net_mosq.c | 16 ++++++++++++++++ lib/options.c | 2 ++ src/net.c | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/lib/net_mosq.c b/lib/net_mosq.c index bdcaa19c..f207e32a 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -141,7 +141,9 @@ int net__init(void) | OPENSSL_INIT_ADD_ALL_DIGESTS \ | OPENSSL_INIT_LOAD_CONFIG, NULL); # endif +#if !defined(OPENSSL_NO_ENGINE) ENGINE_load_builtin_engines(); +#endif setup_ui_method(); if(tls_ex_index_mosq == -1){ tls_ex_index_mosq = SSL_get_ex_new_index(0, "client context", NULL, NULL, NULL); @@ -599,6 +601,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) SSL_CTX_set_mode(mosq->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); #endif +#if !defined(OPENSSL_NO_ENGINE) if(mosq->tls_engine){ engine = ENGINE_by_id(mosq->tls_engine); if(!engine){ @@ -615,12 +618,15 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) ENGINE_set_default(engine, ENGINE_METHOD_ALL); ENGINE_free(engine); /* release the structural reference from ENGINE_by_id() */ } +#endif if(mosq->tls_ciphers){ 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); +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif COMPAT_CLOSE(mosq->sock); mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); @@ -647,7 +653,9 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath); } #endif +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif COMPAT_CLOSE(mosq->sock); mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); @@ -672,7 +680,9 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) #else log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile); #endif +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif COMPAT_CLOSE(mosq->sock); mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); @@ -681,6 +691,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) } if(mosq->tls_keyfile){ if(mosq->tls_keyform == mosq_k_engine){ +#if !defined(OPENSSL_NO_ENGINE) UI_METHOD *ui_method = net__get_ui_method(); if(mosq->tls_engine_kpass_sha1){ if(!ENGINE_ctrl_cmd(engine, ENGINE_SECRET_MODE, ENGINE_SECRET_MODE_SHA, NULL, NULL, 0)){ @@ -714,6 +725,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) net__print_ssl_error(mosq); return MOSQ_ERR_TLS; } +#endif }else{ ret = SSL_CTX_use_PrivateKey_file(mosq->ssl_ctx, mosq->tls_keyfile, SSL_FILETYPE_PEM); if(ret != 1){ @@ -722,7 +734,9 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) #else log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile); #endif +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif COMPAT_CLOSE(mosq->sock); mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); @@ -732,7 +746,9 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) ret = SSL_CTX_check_private_key(mosq->ssl_ctx); if(ret != 1){ log__printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent."); +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif COMPAT_CLOSE(mosq->sock); mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); diff --git a/lib/options.c b/lib/options.c index 005b7810..6dc42629 100644 --- a/lib/options.c +++ b/lib/options.c @@ -255,6 +255,7 @@ int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, cons switch(option){ case MOSQ_OPT_TLS_ENGINE: #ifdef WITH_TLS +# if !defined(OPENSSL_NO_ENGINE) eng = ENGINE_by_id(value); if(!eng){ return MOSQ_ERR_INVAL; @@ -265,6 +266,7 @@ int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, cons return MOSQ_ERR_NOMEM; } return MOSQ_ERR_SUCCESS; +#endif #else return MOSQ_ERR_NOT_SUPPORTED; #endif diff --git a/src/net.c b/src/net.c index 74b4ee83..495f8b2f 100644 --- a/src/net.c +++ b/src/net.c @@ -534,6 +534,7 @@ int net__socket_listen(struct mosquitto__listener *listener) return 1; } if(listener->tls_engine){ +#if !defined(OPENSSL_NO_ENGINE) engine = ENGINE_by_id(listener->tls_engine); if(!engine){ log__printf(NULL, MOSQ_LOG_ERR, "Error loading %s engine\n", listener->tls_engine); @@ -548,6 +549,7 @@ int net__socket_listen(struct mosquitto__listener *listener) } ENGINE_set_default(engine, ENGINE_METHOD_ALL); ENGINE_free(engine); /* release the structural reference from ENGINE_by_id() */ +#endif } /* FIXME user data? */ if(listener->require_certificate){ @@ -560,10 +562,13 @@ int net__socket_listen(struct mosquitto__listener *listener) log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server certificate \"%s\". Check certfile.", listener->certfile); net__print_error(MOSQ_LOG_ERR, "Error: %s"); COMPAT_CLOSE(sock); +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif return 1; } if(listener->tls_keyform == mosq_k_engine){ +#if !defined(OPENSSL_NO_ENGINE) UI_METHOD *ui_method = net__get_ui_method(); if(listener->tls_engine_kpass_sha1){ if(!ENGINE_ctrl_cmd(engine, ENGINE_SECRET_MODE, ENGINE_SECRET_MODE_SHA, NULL, NULL, 0)){ @@ -593,13 +598,16 @@ int net__socket_listen(struct mosquitto__listener *listener) ENGINE_FINISH(engine); return 1; } +#endif }else{ rc = SSL_CTX_use_PrivateKey_file(listener->ssl_ctx, listener->keyfile, SSL_FILETYPE_PEM); if(rc != 1){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server key file \"%s\". Check keyfile.", listener->keyfile); net__print_error(MOSQ_LOG_ERR, "Error: %s"); COMPAT_CLOSE(sock); +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif return 1; } } @@ -608,7 +616,9 @@ int net__socket_listen(struct mosquitto__listener *listener) log__printf(NULL, MOSQ_LOG_ERR, "Error: Server certificate/key are inconsistent."); net__print_error(MOSQ_LOG_ERR, "Error: %s"); COMPAT_CLOSE(sock); +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif return 1; } /* Load CRLs if they exist. */ @@ -618,7 +628,9 @@ int net__socket_listen(struct mosquitto__listener *listener) log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to obtain TLS store."); net__print_error(MOSQ_LOG_ERR, "Error: %s"); COMPAT_CLOSE(sock); +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif return 1; } lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); @@ -627,7 +639,9 @@ int net__socket_listen(struct mosquitto__listener *listener) log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load certificate revocation file \"%s\". Check crlfile.", listener->crlfile); net__print_error(MOSQ_LOG_ERR, "Error: %s"); COMPAT_CLOSE(sock); +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif return 1; } X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK); @@ -644,7 +658,9 @@ int net__socket_listen(struct mosquitto__listener *listener) if(mosquitto__tls_server_ctx(listener)){ COMPAT_CLOSE(sock); +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif return 1; } SSL_CTX_set_psk_server_callback(listener->ssl_ctx, psk_server_callback); @@ -654,7 +670,9 @@ int net__socket_listen(struct mosquitto__listener *listener) log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS PSK hint."); net__print_error(MOSQ_LOG_ERR, "Error: %s"); COMPAT_CLOSE(sock); +#if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); +#endif return 1; } } From cd3877e628ea72f0787d14380b66e5133e376c55 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 8 May 2019 11:10:03 +0100 Subject: [PATCH 03/52] Fix detection of incoming v3.1/v3.1.1 bridges. Closes #1263. Thanks to vrst37. --- ChangeLog.txt | 7 +++++ src/handle_connect.c | 7 +++++ test/broker/06-bridge-no-local.py | 52 +++++++++++++++++++++++++++++++ test/broker/Makefile | 1 + test/broker/test.py | 7 +++-- 5 files changed, 71 insertions(+), 3 deletions(-) create mode 100755 test/broker/06-bridge-no-local.py diff --git a/ChangeLog.txt b/ChangeLog.txt index 9fe1fe96..6532ffa8 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,10 @@ +1.6.3 - 201905xx +================ + +Broker: +- Fix detection of incoming v3.1/v3.1.1 bridges. Closes #1263. + + 1.6.2 - 20190430 ================ diff --git a/src/handle_connect.c b/src/handle_connect.c index 0cedbc6b..7ca3f338 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -426,9 +426,16 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) goto handle_connect_error; } context->protocol = mosq_p_mqtt31; + if((protocol_version&0x80) == 0x80){ + context->is_bridge = true; + } }else if(!strcmp(protocol_name, PROTOCOL_NAME)){ if((protocol_version&0x7F) == PROTOCOL_VERSION_v311){ context->protocol = mosq_p_mqtt311; + + if((protocol_version&0x80) == 0x80){ + context->is_bridge = true; + } }else if((protocol_version&0x7F) == PROTOCOL_VERSION_v5){ context->protocol = mosq_p_mqtt5; }else{ diff --git a/test/broker/06-bridge-no-local.py b/test/broker/06-bridge-no-local.py new file mode 100755 index 00000000..362f34aa --- /dev/null +++ b/test/broker/06-bridge-no-local.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +# Check whether an incoming bridge connection receives its own messages. It +# shouldn't because for v3.1 and v3.1.1 we have no-local set for all bridges. + +from mosq_test_helper import * + +port = mosq_test.get_port() + +def do_test(proto_ver_connect, proto_ver_msgs, sub_opts): + rc = 1 + keepalive = 60 + connect_packet = mosq_test.gen_connect("bridge-test", keepalive=keepalive, proto_ver=proto_ver_connect) + connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver_msgs) + + mid = 1 + subscribe_packet = mosq_test.gen_subscribe(mid, "loop/test", 0 | sub_opts, proto_ver=proto_ver_msgs) + suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=proto_ver_msgs) + + publish_packet = mosq_test.gen_publish("loop/test", qos=0, payload="message", proto_ver=proto_ver_msgs) + + pingreq_packet = mosq_test.gen_pingreq() + pingresp_packet = mosq_test.gen_pingresp() + + port = mosq_test.get_port() + broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) + + try: + sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port) + + mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback") + + sock.send(publish_packet) + mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + rc = 0 + + sock.close() + finally: + broker.terminate() + broker.wait() + (stdo, stde) = broker.communicate() + if rc: + print(stde.decode('utf-8')) + exit(rc) + +do_test(128+3, 3, 0) +do_test(128+4, 4, 0) +do_test(5, 5, mqtt5_opts.MQTT_SUB_OPT_NO_LOCAL) + +exit(0) + + diff --git a/test/broker/Makefile b/test/broker/Makefile index 292f0f82..5ea42c0b 100644 --- a/test/broker/Makefile +++ b/test/broker/Makefile @@ -129,6 +129,7 @@ endif ./06-bridge-br2b-remapping.py ./06-bridge-fail-persist-resend-qos1.py ./06-bridge-fail-persist-resend-qos2.py + ./06-bridge-no-local.py ./06-bridge-per-listener-settings.py ./06-bridge-reconnect-local-out.py diff --git a/test/broker/test.py b/test/broker/test.py index 77bad2c1..eac2d54c 100755 --- a/test/broker/test.py +++ b/test/broker/test.py @@ -96,16 +96,17 @@ tests = [ (2, './06-bridge-b2br-disconnect-qos1.py'), (2, './06-bridge-b2br-disconnect-qos2.py'), + (2, './06-bridge-b2br-late-connection-retain.py'), + (2, './06-bridge-b2br-late-connection.py'), (2, './06-bridge-b2br-remapping.py'), (2, './06-bridge-br2b-disconnect-qos1.py'), (2, './06-bridge-br2b-disconnect-qos2.py'), (2, './06-bridge-br2b-remapping.py'), (2, './06-bridge-fail-persist-resend-qos1.py'), (2, './06-bridge-fail-persist-resend-qos2.py'), - (2, './06-bridge-reconnect-local-out.py'), + (1, './06-bridge-no-local.py'), (3, './06-bridge-per-listener-settings.py'), - (2, './06-bridge-b2br-late-connection.py'), - (2, './06-bridge-b2br-late-connection-retain.py'), + (2, './06-bridge-reconnect-local-out.py'), (1, './07-will-delay-reconnect.py'), (1, './07-will-delay-recover.py'), From 8518d08ff3c5864c8d8009f949ee5b1e716f8ddb Mon Sep 17 00:00:00 2001 From: Till Zimmermann Date: Thu, 9 May 2019 13:08:19 +0200 Subject: [PATCH 04/52] Fixed Segmentation Fault / NULLptr dereference Signed-off-by: Till Zimmermann --- client/client_shared.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/client_shared.c b/client/client_shared.c index 8569651d..b1cbd7bb 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -662,6 +662,10 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c return 1; } topic = strchr(url, '/'); + if(!topic){ + fprintf(stderr, "Error: invalid URL for -L argument specified.\n\n"); + return 1; + } *topic++ = 0; if(cfg_add_topic(cfg, pub_or_sub, topic, "-L topic")) From a47da316793cf84b3b4bd82f09985460b8d0c10f Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 10 May 2019 07:25:49 +0100 Subject: [PATCH 05/52] Update changelog, improve warning message from last commit. --- ChangeLog.txt | 3 +++ client/client_shared.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 6532ffa8..1910d056 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -4,6 +4,9 @@ Broker: - Fix detection of incoming v3.1/v3.1.1 bridges. Closes #1263. +Clients: +- Fix -L url parsing when `/topic` part is missing. + 1.6.2 - 20190430 ================ diff --git a/client/client_shared.c b/client/client_shared.c index b1cbd7bb..94510154 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -663,7 +663,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c } topic = strchr(url, '/'); if(!topic){ - fprintf(stderr, "Error: invalid URL for -L argument specified.\n\n"); + fprintf(stderr, "Error: Invalid URL for -L argument specified - topic missing.\n"); return 1; } *topic++ = 0; From 41cb9bf7506986ccf6b88587ed80650c8c98a708 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 13 May 2019 21:17:04 +0100 Subject: [PATCH 06/52] Simplify ping checking in tests. --- .../01-connect-uname-password-denied-no-will.py | 5 +---- .../broker/02-subpub-qos1-message-expiry-retain.py | 3 --- test/broker/03-publish-b2c-qos1-len.py | 5 +---- test/broker/03-publish-b2c-qos2-len.py | 5 +---- test/broker/03-publish-c2b-qos2-len.py | 5 +---- .../04-retain-check-source-persist-diff-port.py | 5 +---- test/broker/04-retain-check-source-persist.py | 5 +---- test/broker/04-retain-check-source.py | 5 +---- test/broker/04-retain-qos0-clear.py | 13 ++++++------- .../06-bridge-b2br-late-connection-retain.py | 5 +---- test/broker/06-bridge-br2b-remapping.py | 14 ++++---------- test/broker/06-bridge-no-local.py | 5 +---- test/broker/07-will-delay-reconnect.py | 5 +---- test/broker/07-will-delay-recover.py | 5 +---- test/broker/09-acl-access-variants.py | 4 +--- test/broker/09-acl-change.py | 5 +---- test/broker/09-acl-empty-file.py | 5 +---- test/broker/09-extended-auth-change-username.py | 7 ++----- test/broker/09-extended-auth-multistep-reauth.py | 7 ++----- test/broker/09-plugin-auth-acl-pub.py | 5 +---- .../12-prop-maximum-packet-size-publish-qos1.py | 5 +---- .../12-prop-maximum-packet-size-publish-qos2.py | 5 +---- test/broker/12-prop-maximum-packet-size-publish.py | 7 ++----- test/mosq_test.py | 4 ++++ 24 files changed, 37 insertions(+), 102 deletions(-) diff --git a/test/broker/01-connect-uname-password-denied-no-will.py b/test/broker/01-connect-uname-password-denied-no-will.py index b32b91b3..88888024 100755 --- a/test/broker/01-connect-uname-password-denied-no-will.py +++ b/test/broker/01-connect-uname-password-denied-no-will.py @@ -31,9 +31,6 @@ mid = 1 subscribe_packet = mosq_test.gen_subscribe(mid, topic="will/test", qos=0) suback_packet = mosq_test.gen_suback(mid, 0) -pingreq_packet = mosq_test.gen_pingreq() -pingresp_packet = mosq_test.gen_pingresp() - connect2_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="user", password="password9") connack2_packet = mosq_test.gen_connack(rc=5) @@ -47,7 +44,7 @@ try: sock2.close() # If we receive a will here, this is an error - mosq_test.do_send_receive(sock1, pingreq_packet, pingresp_packet) + mosq_test.do_ping(sock1) sock1.close() rc = 0 diff --git a/test/broker/02-subpub-qos1-message-expiry-retain.py b/test/broker/02-subpub-qos1-message-expiry-retain.py index e475c0f3..6974a505 100755 --- a/test/broker/02-subpub-qos1-message-expiry-retain.py +++ b/test/broker/02-subpub-qos1-message-expiry-retain.py @@ -42,9 +42,6 @@ mid=1 publish2r_packet = mosq_test.gen_publish("subpub/kept", mid=mid, qos=1, retain=True, payload="message2", proto_ver=5) puback2r_packet = mosq_test.gen_puback(mid, proto_ver=5, reason_code=mqtt5_rc.MQTT_RC_NO_MATCHING_SUBSCRIBERS) -pingreq_packet = mosq_test.gen_pingreq() -pingresp_packet = mosq_test.gen_pingresp() - port = mosq_test.get_port() broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) diff --git a/test/broker/03-publish-b2c-qos1-len.py b/test/broker/03-publish-b2c-qos1-len.py index f0d44d0b..a9fe7c6a 100755 --- a/test/broker/03-publish-b2c-qos1-len.py +++ b/test/broker/03-publish-b2c-qos1-len.py @@ -20,9 +20,6 @@ def len_test(test, puback_packet): mid = 1 publish_packet = mosq_test.gen_publish("qos1/len/test", qos=1, mid=mid, payload="len-message", proto_ver=5) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) try: @@ -38,7 +35,7 @@ def len_test(test, puback_packet): if mosq_test.expect_packet(sock, "publish", publish_packet): sock.send(puback_packet) - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingreq") + mosq_test.do_ping(sock) rc = 0 sock.close() diff --git a/test/broker/03-publish-b2c-qos2-len.py b/test/broker/03-publish-b2c-qos2-len.py index 05ce9207..a354749f 100755 --- a/test/broker/03-publish-b2c-qos2-len.py +++ b/test/broker/03-publish-b2c-qos2-len.py @@ -21,9 +21,6 @@ def len_test(test, pubrec_packet, pubcomp_packet): publish_packet = mosq_test.gen_publish("qos2/len/test", qos=2, mid=mid, payload="len-message", proto_ver=5) pubrel_packet = mosq_test.gen_pubrel(mid) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) try: @@ -40,7 +37,7 @@ def len_test(test, pubrec_packet, pubcomp_packet): mosq_test.do_send_receive(sock, pubrec_packet, pubrel_packet, "pubrel") sock.send(pubcomp_packet) - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) rc = 0 sock.close() diff --git a/test/broker/03-publish-c2b-qos2-len.py b/test/broker/03-publish-c2b-qos2-len.py index 47b8e3e6..3febae64 100755 --- a/test/broker/03-publish-c2b-qos2-len.py +++ b/test/broker/03-publish-c2b-qos2-len.py @@ -19,9 +19,6 @@ def len_test(test, pubrel_packet): pubrec_packet = mosq_test.gen_pubrec(mid) pubcomp_packet = mosq_test.gen_pubcomp(mid) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) try: @@ -30,7 +27,7 @@ def len_test(test, pubrel_packet): mosq_test.do_send_receive(sock, publish_packet, pubrec_packet, "pubrec") mosq_test.do_send_receive(sock, pubrel_packet, pubcomp_packet, "pubcomp") - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) rc = 0 sock.close() diff --git a/test/broker/04-retain-check-source-persist-diff-port.py b/test/broker/04-retain-check-source-persist-diff-port.py index 356d769d..aa6fc246 100755 --- a/test/broker/04-retain-check-source-persist-diff-port.py +++ b/test/broker/04-retain-check-source-persist-diff-port.py @@ -62,9 +62,6 @@ def do_test(per_listener, username): subscribe_packet = mosq_test.gen_subscribe(mid, "test/topic", 0) suback_packet = mosq_test.gen_suback(mid, 0) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port1) try: @@ -88,7 +85,7 @@ def do_test(per_listener, username): sock = mosq_test.do_client_connect(connect2_packet, connack2_packet, port=port2) mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback 2") # If we receive the retained message here, it is a failure. - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) rc = 0 sock.close() diff --git a/test/broker/04-retain-check-source-persist.py b/test/broker/04-retain-check-source-persist.py index 4876e033..0fbd475b 100755 --- a/test/broker/04-retain-check-source-persist.py +++ b/test/broker/04-retain-check-source-persist.py @@ -51,9 +51,6 @@ def do_test(per_listener, username): subscribe_packet = mosq_test.gen_subscribe(mid, "test/topic", 0) suback_packet = mosq_test.gen_suback(mid, 0) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port) try: @@ -77,7 +74,7 @@ def do_test(per_listener, username): sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port) mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback 2") # If we receive the retained message here, it is a failure. - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) rc = 0 sock.close() diff --git a/test/broker/04-retain-check-source.py b/test/broker/04-retain-check-source.py index 373309d0..b3adecb4 100755 --- a/test/broker/04-retain-check-source.py +++ b/test/broker/04-retain-check-source.py @@ -39,9 +39,6 @@ def do_test(per_listener): subscribe_packet = mosq_test.gen_subscribe(mid, "test/topic", 0) suback_packet = mosq_test.gen_suback(mid, 0) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port) try: @@ -62,7 +59,7 @@ def do_test(per_listener): sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port) mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback 2") # If we receive the retained message here, it is a failure. - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) rc = 0 sock.close() diff --git a/test/broker/04-retain-qos0-clear.py b/test/broker/04-retain-qos0-clear.py index e71ae1c6..48ca6036 100755 --- a/test/broker/04-retain-qos0-clear.py +++ b/test/broker/04-retain-qos0-clear.py @@ -41,13 +41,12 @@ try: # Subscribe to topic, we shouldn't get anything back apart # from the SUBACK. mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback") - try: - retain_clear = sock.recv(256) - except socket.timeout: - # This is the expected event - rc = 0 - else: - print("FAIL: Received unexpected message.") + time.sleep(1) + # If we do get something back, it should be before this ping, so if + # this succeeds then we're ok. + mosq_test.do_ping(sock) + # This is the expected event + rc = 0 sock.close() finally: diff --git a/test/broker/06-bridge-b2br-late-connection-retain.py b/test/broker/06-bridge-b2br-late-connection-retain.py index 6625cbdf..ba646217 100755 --- a/test/broker/06-bridge-b2br-late-connection-retain.py +++ b/test/broker/06-bridge-b2br-late-connection-retain.py @@ -40,9 +40,6 @@ mid = 1 publish_packet = mosq_test.gen_publish("bridge/test", qos=1, mid=mid, payload="message", retain=True) puback_packet = mosq_test.gen_puback(mid) -pingreq_packet = mosq_test.gen_pingreq() -pingresp_packet = mosq_test.gen_pingresp() - ssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ssock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) ssock.settimeout(40) @@ -75,7 +72,7 @@ try: # Guard against multiple retained messages of the same type by # sending a pingreq to give us something to expect back. If we get # a publish, it's a fail. - mosq_test.do_send_receive(bridge, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(bridge) rc = 0 bridge.close() diff --git a/test/broker/06-bridge-br2b-remapping.py b/test/broker/06-bridge-br2b-remapping.py index 62092a08..ab29a08b 100755 --- a/test/broker/06-bridge-br2b-remapping.py +++ b/test/broker/06-bridge-br2b-remapping.py @@ -79,17 +79,11 @@ def test(bridge, sock): )) return 1 else: - bridge.settimeout(3) - try: - bridge.recv(1) - print("FAIL: Received data when nothing is expected") - print("Fail on cases local_topic=%r, remote_topic=%r" % ( - local_topic, remote_topic, + time.sleep(1) + mosq_test.do_ping(bridge, + "FAIL: Received data when nothing is expected\nFail on cases local_topic=%r, remote_topic=%r" % ( + local_topic, remote_topic, )) - return 1 - except socket.timeout: - pass - bridge.settimeout(20) return 0 try: diff --git a/test/broker/06-bridge-no-local.py b/test/broker/06-bridge-no-local.py index 362f34aa..7b54a14e 100755 --- a/test/broker/06-bridge-no-local.py +++ b/test/broker/06-bridge-no-local.py @@ -19,9 +19,6 @@ def do_test(proto_ver_connect, proto_ver_msgs, sub_opts): publish_packet = mosq_test.gen_publish("loop/test", qos=0, payload="message", proto_ver=proto_ver_msgs) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - port = mosq_test.get_port() broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) @@ -31,7 +28,7 @@ def do_test(proto_ver_connect, proto_ver_msgs, sub_opts): mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback") sock.send(publish_packet) - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) rc = 0 sock.close() diff --git a/test/broker/07-will-delay-reconnect.py b/test/broker/07-will-delay-reconnect.py index 1e3b82f8..2f435f36 100755 --- a/test/broker/07-will-delay-reconnect.py +++ b/test/broker/07-will-delay-reconnect.py @@ -25,9 +25,6 @@ def do_test(): subscribe_packet = mosq_test.gen_subscribe(mid, "will/test", 0, proto_ver=5) suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - port = mosq_test.get_port() broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) @@ -47,7 +44,7 @@ def do_test(): # whether we get the old will. We should not. sock2.close() - mosq_test.do_send_receive(sock1, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock1) rc = 0 sock1.close() diff --git a/test/broker/07-will-delay-recover.py b/test/broker/07-will-delay-recover.py index 20320833..852c5499 100755 --- a/test/broker/07-will-delay-recover.py +++ b/test/broker/07-will-delay-recover.py @@ -26,9 +26,6 @@ def do_test(clean_session): subscribe_packet = mosq_test.gen_subscribe(mid, "will/test", 0, proto_ver=5) suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - port = mosq_test.get_port() broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) @@ -45,7 +42,7 @@ def do_test(clean_session): # The client2 has reconnected within the will delay interval, which has now # passed. We should not have received the will at this point. - mosq_test.do_send_receive(sock1, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock1) rc = 0 sock1.close() diff --git a/test/broker/09-acl-access-variants.py b/test/broker/09-acl-access-variants.py index 03ec9be5..f20a5eed 100755 --- a/test/broker/09-acl-access-variants.py +++ b/test/broker/09-acl-access-variants.py @@ -45,14 +45,12 @@ def single_test(port, per_listener, username, topic, expect_deny): mid=1 publish1r_packet = mosq_test.gen_publish(topic=topic, mid=mid, qos=1, payload="message") - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port) mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback") mosq_test.do_send_receive(sock, publish1s_packet, puback1s_packet, "puback") if expect_deny: - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) else: mosq_test.expect_packet(sock, "publish1r", publish1r_packet) sock.close() diff --git a/test/broker/09-acl-change.py b/test/broker/09-acl-change.py index 435dc705..09d16f6b 100755 --- a/test/broker/09-acl-change.py +++ b/test/broker/09-acl-change.py @@ -62,9 +62,6 @@ mid = 3 publish4s_packet = mosq_test.gen_publish(topic="topic/two", mid=mid, qos=1, payload="message4") puback4s_packet = mosq_test.gen_puback(mid) -pingreq_packet = mosq_test.gen_pingreq() -pingresp_packet = mosq_test.gen_pingresp() - rc = 1 port = mosq_test.get_port() @@ -108,7 +105,7 @@ try: mosq_test.do_send_receive(sock, publish4s_packet, puback4s_packet, "puback4") # Check for non delivery with a ping - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) sock.close() rc = 0 diff --git a/test/broker/09-acl-empty-file.py b/test/broker/09-acl-empty-file.py index d970f497..ab02c248 100755 --- a/test/broker/09-acl-empty-file.py +++ b/test/broker/09-acl-empty-file.py @@ -34,9 +34,6 @@ def do_test(port, per_listener): subscribe_packet = mosq_test.gen_subscribe(mid, "test/topic", 0) suback_packet = mosq_test.gen_suback(mid, 0) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port) try: @@ -46,7 +43,7 @@ def do_test(port, per_listener): sock.send(publish_packet) # If we receive the message, this will fail. - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) rc = 0 sock.close() diff --git a/test/broker/09-extended-auth-change-username.py b/test/broker/09-extended-auth-change-username.py index 05b4447a..89b4a823 100755 --- a/test/broker/09-extended-auth-change-username.py +++ b/test/broker/09-extended-auth-change-username.py @@ -37,9 +37,6 @@ def do_test(per_listener): publish1_packet = mosq_test.gen_publish("topic/one", qos=1, mid=mid, payload="message", proto_ver=5) puback1_packet = mosq_test.gen_puback(mid, proto_ver=5, reason_code=mqtt5_rc.MQTT_RC_NOT_AUTHORIZED) - pingreq_packet = mosq_test.gen_pingreq() - pingresp_packet = mosq_test.gen_pingresp() - # Connect without a username, but have the plugin change it props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_AUTHENTICATION_METHOD, "change") connect2_packet = mosq_test.gen_connect("client-params-test2", keepalive=42, proto_ver=5, properties=props) @@ -59,14 +56,14 @@ def do_test(per_listener): sock = mosq_test.do_client_connect(connect1_packet, connack1_packet, timeout=20, port=port) mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback1") mosq_test.do_send_receive(sock, publish1_packet, puback1_packet, "puback1") - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) sock.close() sock = mosq_test.do_client_connect(connect2_packet, connack2_packet, timeout=20, port=port) mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback2") mosq_test.do_send_receive(sock, publish2s_packet, puback2s_packet, "puback2") if mosq_test.expect_packet(sock, "publish2", publish2r_packet): - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) rc = 0 sock.close() diff --git a/test/broker/09-extended-auth-multistep-reauth.py b/test/broker/09-extended-auth-multistep-reauth.py index a9991d3b..0f3ae978 100755 --- a/test/broker/09-extended-auth-multistep-reauth.py +++ b/test/broker/09-extended-auth-multistep-reauth.py @@ -62,19 +62,16 @@ reauth3_packet = mosq_test.gen_auth(reason_code=mqtt5_rc.MQTT_RC_REAUTHENTICATE, disconnect3_packet = mosq_test.gen_disconnect(reason_code=mqtt5_rc.MQTT_RC_PROTOCOL_ERROR, proto_ver=5) -pingreq_packet = mosq_test.gen_pingreq() -pingresp_packet = mosq_test.gen_pingresp() - broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port) try: sock = mosq_test.do_client_connect(connect1_packet, auth1_1_packet, timeout=20, port=port, connack_error="auth1") mosq_test.do_send_receive(sock, auth1_2_packet, connack1_packet, "connack1") - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp1") + mosq_test.do_ping(sock, "pingresp1") mosq_test.do_send_receive(sock, reauth2_packet, auth2_1_packet, "auth2_1") mosq_test.do_send_receive(sock, auth2_2_packet, auth2_3_packet, "auth2_3") - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp2") + mosq_test.do_ping(sock, "pingresp2") mosq_test.do_send_receive(sock, reauth3_packet, disconnect3_packet, "disconnect3") diff --git a/test/broker/09-plugin-auth-acl-pub.py b/test/broker/09-plugin-auth-acl-pub.py index 1e5d07dc..d546f95f 100755 --- a/test/broker/09-plugin-auth-acl-pub.py +++ b/test/broker/09-plugin-auth-acl-pub.py @@ -37,9 +37,6 @@ mid = 2 publish2_packet = mosq_test.gen_publish("writeable", qos=1, mid=mid, payload="message") puback2_packet = mosq_test.gen_puback(mid) -pingreq_packet = mosq_test.gen_pingreq() -pingresp_packet = mosq_test.gen_pingresp() - broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port) try: @@ -51,7 +48,7 @@ try: sock = mosq_test.do_client_connect(connect2_packet, connack2_packet, timeout=20, port=port) mosq_test.do_send_receive(sock, publish2_packet, puback2_packet, "puback2") - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet, "pingresp") + mosq_test.do_ping(sock) rc = 0 diff --git a/test/broker/12-prop-maximum-packet-size-publish-qos1.py b/test/broker/12-prop-maximum-packet-size-publish-qos1.py index bded92ce..4fee7c76 100755 --- a/test/broker/12-prop-maximum-packet-size-publish-qos1.py +++ b/test/broker/12-prop-maximum-packet-size-publish-qos1.py @@ -24,9 +24,6 @@ mid=2 publish2_packet = mosq_test.gen_publish(topic="test/topic", mid=mid, qos=1, payload="7890", proto_ver=5) puback2_packet = mosq_test.gen_puback(mid, proto_ver=5) -pingreq_packet = mosq_test.gen_pingreq() -pingresp_packet = mosq_test.gen_pingresp() - port = mosq_test.get_port() broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) @@ -37,7 +34,7 @@ try: mosq_test.do_send_receive(sock, publish1_packet, puback1_packet, "puback 1") # We shouldn't receive the publish here because it is > MAXIMUM_PACKET_SIZE - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet) + mosq_test.do_ping(sock) mosq_test.do_send_receive(sock, publish2_packet, puback2_packet, "puback 2") diff --git a/test/broker/12-prop-maximum-packet-size-publish-qos2.py b/test/broker/12-prop-maximum-packet-size-publish-qos2.py index 834acf70..d7895202 100755 --- a/test/broker/12-prop-maximum-packet-size-publish-qos2.py +++ b/test/broker/12-prop-maximum-packet-size-publish-qos2.py @@ -28,9 +28,6 @@ pubrec2_packet = mosq_test.gen_pubrec(mid, proto_ver=5) pubrel2_packet = mosq_test.gen_pubrel(mid, proto_ver=5) pubcomp2_packet = mosq_test.gen_pubcomp(mid, proto_ver=5) -pingreq_packet = mosq_test.gen_pingreq() -pingresp_packet = mosq_test.gen_pingresp() - port = mosq_test.get_port() broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) @@ -42,7 +39,7 @@ try: mosq_test.do_send_receive(sock, pubrel1_packet, pubcomp1_packet, "pubcomp 1") # We shouldn't receive the publish here because it is > MAXIMUM_PACKET_SIZE - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet) + mosq_test.do_ping(sock) mosq_test.do_send_receive(sock, publish2_packet, pubrec2_packet, "pubrec 2") mosq_test.do_send_receive(sock, pubrel2_packet, pubcomp2_packet, "pubcomp 2") diff --git a/test/broker/12-prop-maximum-packet-size-publish.py b/test/broker/12-prop-maximum-packet-size-publish.py index f3d739a7..dca9e34e 100755 --- a/test/broker/12-prop-maximum-packet-size-publish.py +++ b/test/broker/12-prop-maximum-packet-size-publish.py @@ -19,9 +19,6 @@ suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) publish1_packet = mosq_test.gen_publish(topic="test/topic", qos=0, payload="12345678901234567890", proto_ver=5) publish2_packet = mosq_test.gen_publish(topic="test/topic", qos=0, payload="67890", proto_ver=5) -pingreq_packet = mosq_test.gen_pingreq() -pingresp_packet = mosq_test.gen_pingresp() - port = mosq_test.get_port() broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) @@ -30,9 +27,9 @@ try: mosq_test.do_send_receive(sock, subscribe_packet, suback_packet) sock.send(publish1_packet) # We shouldn't receive the publish here because it is > MAXIMUM_PACKET_SIZE - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet) + mosq_test.do_ping(sock, "pingresp1") mosq_test.do_send_receive(sock, publish2_packet, publish2_packet) - mosq_test.do_send_receive(sock, pingreq_packet, pingresp_packet) + mosq_test.do_ping(sock, "pingresp2") rc = 0 finally: broker.terminate() diff --git a/test/mosq_test.py b/test/mosq_test.py index faba32cb..2093e326 100644 --- a/test/mosq_test.py +++ b/test/mosq_test.py @@ -603,6 +603,10 @@ def get_lib_port(): return 1888 +def do_ping(sock, error_string="pingresp"): + do_send_receive(sock, gen_pingreq(), gen_pingresp(), error_string) + + @atexit.register def test_cleanup(): global vg_logfiles From ef3e52d40b0ce09a6a5a7032571ed340f208585c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 16 May 2019 14:03:39 +0100 Subject: [PATCH 07/52] Fix default max_topic_alias listener config not being used. This was not being copied to the in-use listener when compiled without TLS support. --- ChangeLog.txt | 2 ++ src/conf.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 1910d056..9dbc0e3d 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -3,6 +3,8 @@ Broker: - Fix detection of incoming v3.1/v3.1.1 bridges. Closes #1263. +- Fix default max_topic_alias listener config not being copied to the in-use + listener when compiled without TLS support. Clients: - Fix -L url parsing when `/topic` part is missing. diff --git a/src/conf.c b/src/conf.c index 4fe05cf5..53c622cf 100644 --- a/src/conf.c +++ b/src/conf.c @@ -504,12 +504,12 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config config->listeners[config->listener_count-1].client_count = 0; config->listeners[config->listener_count-1].use_username_as_clientid = config->default_listener.use_username_as_clientid; config->listeners[config->listener_count-1].maximum_qos = config->default_listener.maximum_qos; + config->listeners[config->listener_count-1].max_topic_alias = config->default_listener.max_topic_alias; #ifdef WITH_TLS config->listeners[config->listener_count-1].tls_version = config->default_listener.tls_version; config->listeners[config->listener_count-1].tls_engine = config->default_listener.tls_engine; config->listeners[config->listener_count-1].tls_keyform = config->default_listener.tls_keyform; config->listeners[config->listener_count-1].tls_engine_kpass_sha1 = config->default_listener.tls_engine_kpass_sha1; - config->listeners[config->listener_count-1].max_topic_alias = config->default_listener.max_topic_alias; config->listeners[config->listener_count-1].cafile = config->default_listener.cafile; config->listeners[config->listener_count-1].capath = config->default_listener.capath; config->listeners[config->listener_count-1].certfile = config->default_listener.certfile; From b1298dff5420990a14333bae952f27461982b8e4 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 16 May 2019 15:03:40 +0100 Subject: [PATCH 08/52] Fix use of getrandom() for Linux and WITH_TLS=no. --- ChangeLog.txt | 4 ++++ lib/util_mosq.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 9dbc0e3d..c6f9525e 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -5,6 +5,10 @@ Broker: - Fix detection of incoming v3.1/v3.1.1 bridges. Closes #1263. - Fix default max_topic_alias listener config not being copied to the in-use listener when compiled without TLS support. +- Fix random number generation if compiling using WITH_TLS=no and on Linux + with glibc >= 2.25. Without this fix, no random numbers would be generated + for e.g. on broker client id generation, and so clients connecting expecting + this feature would be unable to connect. Clients: - Fix -L url parsing when `/topic` part is missing. diff --git a/lib/util_mosq.c b/lib/util_mosq.c index 8f3610a8..7c0b6724 100644 --- a/lib/util_mosq.c +++ b/lib/util_mosq.c @@ -326,7 +326,7 @@ int util__random_bytes(void *bytes, int count) rc = MOSQ_ERR_SUCCESS; } #elif defined(__GLIBC__) && __GLIBC_PREREQ(2, 25) - if(getrandom(bytes, count, 0) == 0){ + if(getrandom(bytes, count, 0) == count){ rc = MOSQ_ERR_SUCCESS; } #elif defined(WIN32) From d05bd958813b7ead344f66653ce9b13b00e67595 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 16 May 2019 22:12:18 +0100 Subject: [PATCH 09/52] Fix compilation problem related to getrandom() on non-glibc systems. --- ChangeLog.txt | 1 + lib/util_mosq.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index c6f9525e..173b9b4c 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -9,6 +9,7 @@ Broker: with glibc >= 2.25. Without this fix, no random numbers would be generated for e.g. on broker client id generation, and so clients connecting expecting this feature would be unable to connect. +- Fix compilation problem related to getrandom() on non-glibc systems. Clients: - Fix -L url parsing when `/topic` part is missing. diff --git a/lib/util_mosq.c b/lib/util_mosq.c index 7c0b6724..ce903e79 100644 --- a/lib/util_mosq.c +++ b/lib/util_mosq.c @@ -28,9 +28,10 @@ Contributors: # include #endif -#if !defined(WITH_TLS) && defined(__linux__) -# if defined(__GLIBC__) && __GLIBC_PREREQ(2, 25) +#if !defined(WITH_TLS) && defined(__linux__) && defined(__GLIBC__) +# if __GLIBC_PREREQ(2, 25) # include +# define HAVE_GETRANDOM 1 # endif #endif @@ -325,7 +326,7 @@ int util__random_bytes(void *bytes, int count) if(RAND_bytes(bytes, count) == 1){ rc = MOSQ_ERR_SUCCESS; } -#elif defined(__GLIBC__) && __GLIBC_PREREQ(2, 25) +#elif defined(HAVE_GETRANDOM) if(getrandom(bytes, count, 0) == count){ rc = MOSQ_ERR_SUCCESS; } From 7a33a129d63757087ae81c8371a6279e9030a7e1 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 11:23:00 +0100 Subject: [PATCH 10/52] Stop some error messages being printed even when `--quiet` was used. Thanks to Rob de Jonge. Closes #1284. --- ChangeLog.txt | 2 + client/client_shared.c | 108 +++++++++++++++++++------------------ client/client_shared.h | 2 + client/pub_client.c | 66 +++++++++++------------ client/pub_shared.c | 14 ++--- client/rr_client.c | 16 +++--- client/sub_client.c | 12 ++--- client/sub_client_output.c | 39 +++++++------- 8 files changed, 133 insertions(+), 126 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 173b9b4c..eeaa2332 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -13,6 +13,8 @@ Broker: Clients: - Fix -L url parsing when `/topic` part is missing. +- Stop some error messages being printed even when `--quiet` was used. + Closes #1284. 1.6.2 - 20190430 diff --git a/client/client_shared.c b/client/client_shared.c index 94510154..0205ce8d 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -18,6 +18,7 @@ Contributors: #include #include +#include #include #include #include @@ -229,7 +230,7 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * len = strlen(env) + strlen("/mosquitto_pub") + 1; loc = malloc(len); if(!loc){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); return 1; } if(pub_or_sub == CLIENT_PUB){ @@ -246,7 +247,7 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * len = strlen(env) + strlen("/.config/mosquitto_pub") + 1; loc = malloc(len); if(!loc){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); return 1; } if(pub_or_sub == CLIENT_PUB){ @@ -257,8 +258,6 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * snprintf(loc, len, "%s/.config/mosquitto_rr", env); } loc[len-1] = '\0'; - }else{ - fprintf(stderr, "Warning: Unable to locate configuration directory, default config not loaded.\n"); } } @@ -268,7 +267,7 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * len = strlen(env) + strlen("\\mosquitto_pub.conf") + 1; loc = malloc(len); if(!loc){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); return 1; } if(pub_or_sub == CLIENT_PUB){ @@ -279,8 +278,6 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * snprintf(loc, len, "%s\\mosquitto_rr.conf", env); } loc[len-1] = '\0'; - }else{ - fprintf(stderr, "Warning: Unable to locate configuration directory, default config not loaded.\n"); } #endif @@ -329,7 +326,7 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * return 1; } if(cfg->password && !cfg->username){ - if(!cfg->quiet) fprintf(stderr, "Warning: Not using password since username not set.\n"); + err_printf(cfg, "Warning: Not using password since username not set.\n"); } #ifdef WITH_TLS if((cfg->certfile && !cfg->keyfile) || (cfg->keyfile && !cfg->certfile)){ @@ -347,23 +344,23 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * #endif #ifdef FINAL_WITH_TLS_PSK if((cfg->cafile || cfg->capath) && cfg->psk){ - if(!cfg->quiet) fprintf(stderr, "Error: Only one of --psk or --cafile/--capath may be used at once.\n"); + fprintf(stderr, "Error: Only one of --psk or --cafile/--capath may be used at once.\n"); return 1; } if(cfg->psk && !cfg->psk_identity){ - if(!cfg->quiet) fprintf(stderr, "Error: --psk-identity required if --psk used.\n"); + fprintf(stderr, "Error: --psk-identity required if --psk used.\n"); return 1; } #endif if(cfg->clean_session == false && (cfg->id_prefix || !cfg->id)){ - if(!cfg->quiet) fprintf(stderr, "Error: You must provide a client id if you are using the -c option.\n"); + fprintf(stderr, "Error: You must provide a client id if you are using the -c option.\n"); return 1; } if(pub_or_sub == CLIENT_SUB){ if(cfg->topic_count == 0){ - if(!cfg->quiet) fprintf(stderr, "Error: You must specify a topic to subscribe to.\n"); + fprintf(stderr, "Error: You must specify a topic to subscribe to.\n"); return 1; } } @@ -371,39 +368,39 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * if(!cfg->host){ cfg->host = strdup("localhost"); if(!cfg->host){ - if(!cfg->quiet) fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); return 1; } } rc = mosquitto_property_check_all(CMD_CONNECT, cfg->connect_props); if(rc){ - if(!cfg->quiet) fprintf(stderr, "Error in CONNECT properties: %s\n", mosquitto_strerror(rc)); + err_printf(cfg, "Error in CONNECT properties: %s\n", mosquitto_strerror(rc)); return 1; } rc = mosquitto_property_check_all(CMD_PUBLISH, cfg->publish_props); if(rc){ - if(!cfg->quiet) fprintf(stderr, "Error in PUBLISH properties: %s\n", mosquitto_strerror(rc)); + err_printf(cfg, "Error in PUBLISH properties: %s\n", mosquitto_strerror(rc)); return 1; } rc = mosquitto_property_check_all(CMD_SUBSCRIBE, cfg->subscribe_props); if(rc){ - if(!cfg->quiet) fprintf(stderr, "Error in SUBSCRIBE properties: %s\n", mosquitto_strerror(rc)); + err_printf(cfg, "Error in SUBSCRIBE properties: %s\n", mosquitto_strerror(rc)); return 1; } rc = mosquitto_property_check_all(CMD_UNSUBSCRIBE, cfg->unsubscribe_props); if(rc){ - if(!cfg->quiet) fprintf(stderr, "Error in UNSUBSCRIBE properties: %s\n", mosquitto_strerror(rc)); + err_printf(cfg, "Error in UNSUBSCRIBE properties: %s\n", mosquitto_strerror(rc)); return 1; } rc = mosquitto_property_check_all(CMD_DISCONNECT, cfg->disconnect_props); if(rc){ - if(!cfg->quiet) fprintf(stderr, "Error in DISCONNECT properties: %s\n", mosquitto_strerror(rc)); + err_printf(cfg, "Error in DISCONNECT properties: %s\n", mosquitto_strerror(rc)); return 1; } rc = mosquitto_property_check_all(CMD_WILL, cfg->will_props); if(rc){ - if(!cfg->quiet) fprintf(stderr, "Error in Will properties: %s\n", mosquitto_strerror(rc)); + err_printf(cfg, "Error in Will properties: %s\n", mosquitto_strerror(rc)); return 1; } @@ -436,7 +433,7 @@ int cfg_add_topic(struct mosq_config *cfg, int type, char *topic, const char *ar cfg->topic_count++; cfg->topics = realloc(cfg->topics, cfg->topic_count*sizeof(char *)); if(!cfg->topics){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); return 1; } cfg->topics[cfg->topic_count-1] = strdup(topic); @@ -551,7 +548,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c cfg->pub_mode = MSGMODE_FILE; cfg->file_input = strdup(argv[i+1]); if(!cfg->file_input){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); return 1; } } @@ -1081,14 +1078,14 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg) cfg->will_payloadlen, cfg->will_payload, cfg->will_qos, cfg->will_retain, cfg->will_props)){ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting will.\n"); + err_printf(cfg, "Error: Problem setting will.\n"); mosquitto_lib_cleanup(); return 1; } cfg->will_props = NULL; if(cfg->username && mosquitto_username_pw_set(mosq, cfg->username, cfg->password)){ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting username and password.\n"); + err_printf(cfg, "Error: Problem setting username and password.\n"); mosquitto_lib_cleanup(); return 1; } @@ -1097,48 +1094,48 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg) rc = mosquitto_tls_set(mosq, cfg->cafile, cfg->capath, cfg->certfile, cfg->keyfile, NULL); if(rc){ if(rc == MOSQ_ERR_INVAL){ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS options: File not found.\n"); + err_printf(cfg, "Error: Problem setting TLS options: File not found.\n"); }else{ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS options: %s.\n", mosquitto_strerror(rc)); + err_printf(cfg, "Error: Problem setting TLS options: %s.\n", mosquitto_strerror(rc)); } mosquitto_lib_cleanup(); return 1; } } if(cfg->insecure && mosquitto_tls_insecure_set(mosq, true)){ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS insecure option.\n"); + err_printf(cfg, "Error: Problem setting TLS insecure option.\n"); mosquitto_lib_cleanup(); return 1; } if(cfg->tls_engine && mosquitto_string_option(mosq, MOSQ_OPT_TLS_ENGINE, cfg->tls_engine)){ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS engine, is %s a valid engine?\n", cfg->tls_engine); + err_printf(cfg, "Error: Problem setting TLS engine, is %s a valid engine?\n", cfg->tls_engine); mosquitto_lib_cleanup(); return 1; } if(cfg->keyform && mosquitto_string_option(mosq, MOSQ_OPT_TLS_KEYFORM, cfg->keyform)){ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting key form, it must be one of 'pem' or 'engine'.\n"); + err_printf(cfg, "Error: Problem setting key form, it must be one of 'pem' or 'engine'.\n"); mosquitto_lib_cleanup(); return 1; } if(cfg->tls_engine_kpass_sha1 && mosquitto_string_option(mosq, MOSQ_OPT_TLS_ENGINE_KPASS_SHA1, cfg->tls_engine_kpass_sha1)){ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS engine key pass sha, is it a 40 character hex string?\n"); + err_printf(cfg, "Error: Problem setting TLS engine key pass sha, is it a 40 character hex string?\n"); mosquitto_lib_cleanup(); return 1; } if(cfg->tls_alpn && mosquitto_string_option(mosq, MOSQ_OPT_TLS_ALPN, cfg->tls_alpn)){ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS ALPN protocol.\n"); + err_printf(cfg, "Error: Problem setting TLS ALPN protocol.\n"); mosquitto_lib_cleanup(); return 1; } # ifdef FINAL_WITH_TLS_PSK if(cfg->psk && mosquitto_tls_psk_set(mosq, cfg->psk, cfg->psk_identity, NULL)){ - if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS-PSK options.\n"); + err_printf(cfg, "Error: Problem setting TLS-PSK options.\n"); mosquitto_lib_cleanup(); return 1; } # endif 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, check the options are valid.\n"); + err_printf(cfg, "Error: Problem setting TLS options, check the options are valid.\n"); mosquitto_lib_cleanup(); return 1; } @@ -1161,7 +1158,7 @@ int client_id_generate(struct mosq_config *cfg) if(cfg->id_prefix){ cfg->id = malloc(strlen(cfg->id_prefix)+10); if(!cfg->id){ - if(!cfg->quiet) fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); mosquitto_lib_cleanup(); return 1; } @@ -1207,17 +1204,15 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg) rc = mosquitto_connect_bind_v5(mosq, cfg->host, port, cfg->keepalive, cfg->bind_address, cfg->connect_props); #endif if(rc>0){ - if(!cfg->quiet){ - if(rc == MOSQ_ERR_ERRNO){ + if(rc == MOSQ_ERR_ERRNO){ #ifndef WIN32 - err = strerror(errno); + err = strerror(errno); #else - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errno, 0, (LPTSTR)&err, 1024, NULL); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errno, 0, (LPTSTR)&err, 1024, NULL); #endif - fprintf(stderr, "Error: %s\n", err); - }else{ - fprintf(stderr, "Unable to connect (%s).\n", mosquitto_strerror(rc)); - } + err_printf(cfg, "Error: %s\n", err); + }else{ + err_printf(cfg, "Unable to connect (%s).\n", mosquitto_strerror(rc)); } mosquitto_lib_cleanup(); return rc; @@ -1284,7 +1279,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) if(!strncmp(url, "socks5h://", strlen("socks5h://"))){ str = url + strlen("socks5h://"); }else{ - fprintf(stderr, "Error: Unsupported proxy protocol: %s\n", url); + err_printf(cfg, "Error: Unsupported proxy protocol: %s\n", url); return 1; } @@ -1311,7 +1306,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) len = i-start; host = malloc(len + 1); if(!host){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); goto cleanup; } memcpy(host, &(str[start]), len); @@ -1324,7 +1319,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) len = i-start; username_or_host = malloc(len + 1); if(!username_or_host){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); goto cleanup; } memcpy(username_or_host, &(str[start]), len); @@ -1344,7 +1339,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) len = i-start; password = malloc(len + 1); if(!password){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); goto cleanup; } memcpy(password, &(str[start]), len); @@ -1360,7 +1355,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) len = i-start; username = malloc(len + 1); if(!username){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); goto cleanup; } memcpy(username, &(str[start]), len); @@ -1378,7 +1373,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) * socks5h://username[:password]@host:port */ port = malloc(len + 1); if(!port){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); goto cleanup; } memcpy(port, &(str[start]), len); @@ -1390,7 +1385,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) username_or_host = NULL; port = malloc(len + 1); if(!port){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); goto cleanup; } memcpy(port, &(str[start]), len); @@ -1398,7 +1393,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) }else{ host = malloc(len + 1); if(!host){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(cfg, "Error: Out of memory.\n"); goto cleanup; } memcpy(host, &(str[start]), len); @@ -1407,7 +1402,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) } if(!host){ - fprintf(stderr, "Error: Invalid proxy.\n"); + err_printf(cfg, "Error: Invalid proxy.\n"); goto cleanup; } @@ -1420,7 +1415,7 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url) if(port){ port_int = atoi(port); if(port_int < 1 || port_int > 65535){ - fprintf(stderr, "Error: Invalid proxy port %d\n", port_int); + err_printf(cfg, "Error: Invalid proxy port %d\n", port_int); goto cleanup; } free(port); @@ -1443,4 +1438,15 @@ cleanup: return 1; } +void err_printf(const struct mosq_config *cfg, const char *fmt, ...) +{ + va_list va; + + if(cfg->quiet) return; + + va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); +} + #endif diff --git a/client/client_shared.h b/client/client_shared.h index 7e65f3d1..232fa909 100644 --- a/client/client_shared.h +++ b/client/client_shared.h @@ -126,4 +126,6 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg); int cfg_parse_property(struct mosq_config *cfg, int argc, char *argv[], int *idx); +void err_printf(const struct mosq_config *cfg, const char *fmt, ...); + #endif diff --git a/client/pub_client.c b/client/pub_client.c index cdf89741..60d652a3 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -142,36 +142,34 @@ void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flag break; } if(rc){ - if(!cfg.quiet){ - switch(rc){ - case MOSQ_ERR_INVAL: - fprintf(stderr, "Error: Invalid input. Does your topic contain '+' or '#'?\n"); - break; - case MOSQ_ERR_NOMEM: - fprintf(stderr, "Error: Out of memory when trying to publish message.\n"); - break; - case MOSQ_ERR_NO_CONN: - fprintf(stderr, "Error: Client not connected when trying to publish.\n"); - break; - case MOSQ_ERR_PROTOCOL: - fprintf(stderr, "Error: Protocol error when communicating with broker.\n"); - break; - case MOSQ_ERR_PAYLOAD_SIZE: - fprintf(stderr, "Error: Message payload is too large.\n"); - break; - case MOSQ_ERR_QOS_NOT_SUPPORTED: - fprintf(stderr, "Error: Message QoS not supported on broker, try a lower QoS.\n"); - break; - } + switch(rc){ + case MOSQ_ERR_INVAL: + err_printf(&cfg, "Error: Invalid input. Does your topic contain '+' or '#'?\n"); + break; + case MOSQ_ERR_NOMEM: + err_printf(&cfg, "Error: Out of memory when trying to publish message.\n"); + break; + case MOSQ_ERR_NO_CONN: + err_printf(&cfg, "Error: Client not connected when trying to publish.\n"); + break; + case MOSQ_ERR_PROTOCOL: + err_printf(&cfg, "Error: Protocol error when communicating with broker.\n"); + break; + case MOSQ_ERR_PAYLOAD_SIZE: + err_printf(&cfg, "Error: Message payload is too large.\n"); + break; + case MOSQ_ERR_QOS_NOT_SUPPORTED: + err_printf(&cfg, "Error: Message QoS not supported on broker, try a lower QoS.\n"); + break; } mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props); } }else{ - if(result && !cfg.quiet){ + if(result){ if(cfg.protocol_version == MQTT_PROTOCOL_V5){ - fprintf(stderr, "%s\n", mosquitto_reason_string(result)); + err_printf(&cfg, "%s\n", mosquitto_reason_string(result)); }else{ - fprintf(stderr, "%s\n", mosquitto_connack_string(result)); + err_printf(&cfg, "%s\n", mosquitto_connack_string(result)); } } } @@ -185,7 +183,7 @@ void my_publish_callback(struct mosquitto *mosq, void *obj, int mid, int reason_ last_mid_sent = mid; if(reason_code > 127){ - if(!cfg.quiet) fprintf(stderr, "Warning: Publish %d failed: %s.\n", mid, mosquitto_reason_string(reason_code)); + err_printf(&cfg, "Warning: Publish %d failed: %s.\n", mid, mosquitto_reason_string(reason_code)); } publish_count++; @@ -208,7 +206,7 @@ int pub_shared_init(void) { line_buf = malloc(line_buf_len); if(!line_buf){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(&cfg, "Error: Out of memory.\n"); return 1; } return 0; @@ -246,7 +244,7 @@ int pub_shared_loop(struct mosquitto *mosq) line_buf[buf_len_actual-1] = '\0'; rc2 = my_publish(mosq, &mid_sent, cfg.topic, buf_len_actual-1, line_buf, cfg.qos, cfg.retain); if(rc2){ - if(!cfg.quiet) fprintf(stderr, "Error: Publish returned %d, disconnecting.\n", rc2); + err_printf(&cfg, "Error: Publish returned %d, disconnecting.\n", rc2); mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props); } break; @@ -256,7 +254,7 @@ int pub_shared_loop(struct mosquitto *mosq) read_len = 1024; buf2 = realloc(line_buf, line_buf_len); if(!buf2){ - fprintf(stderr, "Error: Out of memory.\n"); + err_printf(&cfg, "Error: Out of memory.\n"); return MOSQ_ERR_NOMEM; } line_buf = buf2; @@ -305,7 +303,7 @@ int pub_shared_loop(struct mosquitto *mosq) break; } if(rc){ - fprintf(stderr, "Error sending repeat publish: %s", mosquitto_strerror(rc)); + err_printf(&cfg, "Error sending repeat publish: %s", mosquitto_strerror(rc)); } } } @@ -457,12 +455,12 @@ int main(int argc, char *argv[]) if(cfg.pub_mode == MSGMODE_STDIN_FILE){ if(load_stdin()){ - fprintf(stderr, "Error loading input from stdin.\n"); + err_printf(&cfg, "Error loading input from stdin.\n"); goto cleanup; } }else if(cfg.file_input){ if(load_file(cfg.file_input)){ - fprintf(stderr, "Error loading input file \"%s\".\n", cfg.file_input); + err_printf(&cfg, "Error loading input file \"%s\".\n", cfg.file_input); goto cleanup; } } @@ -482,10 +480,10 @@ int main(int argc, char *argv[]) if(!mosq){ switch(errno){ case ENOMEM: - if(!cfg.quiet) fprintf(stderr, "Error: Out of memory.\n"); + err_printf(&cfg, "Error: Out of memory.\n"); break; case EINVAL: - if(!cfg.quiet) fprintf(stderr, "Error: Invalid id.\n"); + err_printf(&cfg, "Error: Invalid id.\n"); break; } goto cleanup; @@ -517,7 +515,7 @@ int main(int argc, char *argv[]) pub_shared_cleanup(); if(rc){ - fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc)); + err_printf(&cfg, "Error: %s\n", mosquitto_strerror(rc)); } return rc; diff --git a/client/pub_shared.c b/client/pub_shared.c index ead86a34..e1de3f0a 100644 --- a/client/pub_shared.c +++ b/client/pub_shared.c @@ -61,7 +61,7 @@ int load_stdin(void) rlen = fread(buf, 1, 1024, stdin); aux_message = realloc(cfg.message, pos+rlen); if(!aux_message){ - if(!cfg.quiet) fprintf(stderr, "Error: Out of memory.\n"); + err_printf(&cfg, "Error: Out of memory.\n"); free(cfg.message); return 1; } else @@ -74,7 +74,7 @@ int load_stdin(void) cfg.msglen = pos; if(!cfg.msglen){ - if(!cfg.quiet) fprintf(stderr, "Error: Zero length input.\n"); + err_printf(&cfg, "Error: Zero length input.\n"); return 1; } @@ -88,7 +88,7 @@ int load_file(const char *filename) fptr = fopen(filename, "rb"); if(!fptr){ - if(!cfg.quiet) fprintf(stderr, "Error: Unable to open file \"%s\".\n", filename); + err_printf(&cfg, "Error: Unable to open file \"%s\".\n", filename); return 1; } cfg.pub_mode = MSGMODE_FILE; @@ -96,22 +96,22 @@ int load_file(const char *filename) cfg.msglen = ftell(fptr); if(cfg.msglen > 268435455){ fclose(fptr); - if(!cfg.quiet) fprintf(stderr, "Error: File \"%s\" is too large (>268,435,455 bytes).\n", filename); + err_printf(&cfg, "Error: File \"%s\" is too large (>268,435,455 bytes).\n", filename); return 1; }else if(cfg.msglen == 0){ fclose(fptr); - if(!cfg.quiet) fprintf(stderr, "Error: File \"%s\" is empty.\n", filename); + err_printf(&cfg, "Error: File \"%s\" is empty.\n", filename); return 1; }else if(cfg.msglen < 0){ fclose(fptr); - if(!cfg.quiet) fprintf(stderr, "Error: Unable to determine size of file \"%s\".\n", filename); + err_printf(&cfg, "Error: Unable to determine size of file \"%s\".\n", filename); return 1; } fseek(fptr, 0, SEEK_SET); cfg.message = malloc(cfg.msglen); if(!cfg.message){ fclose(fptr); - if(!cfg.quiet) fprintf(stderr, "Error: Out of memory.\n"); + err_printf(&cfg, "Error: Out of memory.\n"); return 1; } pos = 0; diff --git a/client/rr_client.c b/client/rr_client.c index 5ecd3093..cbd32d5e 100644 --- a/client/rr_client.c +++ b/client/rr_client.c @@ -121,8 +121,8 @@ void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flag mosquitto_subscribe_v5(mosq, NULL, cfg.response_topic, cfg.qos, 0, cfg.subscribe_props); }else{ client_state = rr_s_disconnect; - if(result && !cfg.quiet){ - fprintf(stderr, "%s\n", mosquitto_connack_string(result)); + if(result){ + err_printf(&cfg, "%s\n", mosquitto_connack_string(result)); } mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props); } @@ -135,10 +135,8 @@ void my_subscribe_callback(struct mosquitto *mosq, void *obj, int mid, int qos_c client_state = rr_s_ready_to_publish; }else{ client_state = rr_s_disconnect; - if(!cfg.quiet){ - fprintf(stderr, "%s\n", mosquitto_reason_string(granted_qos[0])); - mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props); - } + err_printf(&cfg, "%s\n", mosquitto_reason_string(granted_qos[0])); + mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props); } } @@ -282,7 +280,7 @@ int main(int argc, char *argv[]) } rc = mosquitto_property_check_all(CMD_PUBLISH, cfg.publish_props); if(rc){ - if(!cfg.quiet) fprintf(stderr, "Error in PUBLISH properties: Duplicate response topic.\n"); + err_printf(&cfg, "Error in PUBLISH properties: Duplicate response topic.\n"); goto cleanup; } @@ -294,10 +292,10 @@ int main(int argc, char *argv[]) if(!mosq){ switch(errno){ case ENOMEM: - if(!cfg.quiet) fprintf(stderr, "Error: Out of memory.\n"); + err_printf(&cfg, "Error: Out of memory.\n"); break; case EINVAL: - if(!cfg.quiet) fprintf(stderr, "Error: Invalid id and/or clean_session.\n"); + err_printf(&cfg, "Error: Invalid id and/or clean_session.\n"); break; } goto cleanup; diff --git a/client/sub_client.c b/client/sub_client.c index c970537c..a10757c6 100644 --- a/client/sub_client.c +++ b/client/sub_client.c @@ -35,7 +35,7 @@ Contributors: #include #include "client_shared.h" -static struct mosq_config cfg; +struct mosq_config cfg; bool process_messages = true; int msg_count = 0; struct mosquitto *mosq = NULL; @@ -124,11 +124,11 @@ void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flag mosquitto_unsubscribe_v5(mosq, NULL, cfg.unsub_topics[i], cfg.unsubscribe_props); } }else{ - if(result && !cfg.quiet){ + if(result){ if(cfg.protocol_version == MQTT_PROTOCOL_V5){ - fprintf(stderr, "%s\n", mosquitto_reason_string(result)); + err_printf(&cfg, "%s\n", mosquitto_reason_string(result)); }else{ - fprintf(stderr, "%s\n", mosquitto_connack_string(result)); + err_printf(&cfg, "%s\n", mosquitto_connack_string(result)); } } mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props); @@ -307,10 +307,10 @@ int main(int argc, char *argv[]) if(!mosq){ switch(errno){ case ENOMEM: - if(!cfg.quiet) fprintf(stderr, "Error: Out of memory.\n"); + err_printf(&cfg, "Error: Out of memory.\n"); break; case EINVAL: - if(!cfg.quiet) fprintf(stderr, "Error: Invalid id and/or clean_session.\n"); + err_printf(&cfg, "Error: Invalid id and/or clean_session.\n"); break; } goto cleanup; diff --git a/client/sub_client_output.c b/client/sub_client_output.c index c4ff376a..a7cdefb2 100644 --- a/client/sub_client_output.c +++ b/client/sub_client_output.c @@ -37,6 +37,7 @@ Contributors: #include #include "client_shared.h" +extern struct mosq_config cfg; static int get_time(struct tm **ti, long *ns) { @@ -60,7 +61,7 @@ static int get_time(struct tm **ti, long *ns) *ns = tv.tv_usec*1000; #else if(clock_gettime(CLOCK_REALTIME, &ts) != 0){ - fprintf(stderr, "Error obtaining system time.\n"); + err_printf(&cfg, "Error obtaining system time.\n"); return 1; } s = ts.tv_sec; @@ -69,7 +70,7 @@ static int get_time(struct tm **ti, long *ns) *ti = localtime(&s); if(!(*ti)){ - fprintf(stderr, "Error obtaining system time.\n"); + err_printf(&cfg, "Error obtaining system time.\n"); return 1; } @@ -130,7 +131,7 @@ static void json_print(const struct mosquitto_message *message, const struct tm } -static void formatted_print(const struct mosq_config *cfg, const struct mosquitto_message *message) +static void formatted_print(const struct mosq_config *lcfg, const struct mosquitto_message *message) { int len; int i; @@ -139,13 +140,13 @@ static void formatted_print(const struct mosq_config *cfg, const struct mosquitt char strf[3]; char buf[100]; - len = strlen(cfg->format); + len = strlen(lcfg->format); for(i=0; iformat[i] == '%'){ + if(lcfg->format[i] == '%'){ if(i < len-1){ i++; - switch(cfg->format[i]){ + switch(lcfg->format[i]){ case '%': fputc('%', stdout); break; @@ -153,7 +154,7 @@ static void formatted_print(const struct mosq_config *cfg, const struct mosquitt case 'I': if(!ti){ if(get_time(&ti, &ns)){ - fprintf(stderr, "Error obtaining system time.\n"); + err_printf(lcfg, "Error obtaining system time.\n"); return; } } @@ -165,7 +166,7 @@ static void formatted_print(const struct mosq_config *cfg, const struct mosquitt case 'j': if(!ti){ if(get_time(&ti, &ns)){ - fprintf(stderr, "Error obtaining system time.\n"); + err_printf(lcfg, "Error obtaining system time.\n"); return; } } @@ -175,7 +176,7 @@ static void formatted_print(const struct mosq_config *cfg, const struct mosquitt case 'J': if(!ti){ if(get_time(&ti, &ns)){ - fprintf(stderr, "Error obtaining system time.\n"); + err_printf(lcfg, "Error obtaining system time.\n"); return; } } @@ -213,7 +214,7 @@ static void formatted_print(const struct mosq_config *cfg, const struct mosquitt case 'U': if(!ti){ if(get_time(&ti, &ns)){ - fprintf(stderr, "Error obtaining system time.\n"); + err_printf(lcfg, "Error obtaining system time.\n"); return; } } @@ -231,24 +232,24 @@ static void formatted_print(const struct mosq_config *cfg, const struct mosquitt break; } } - }else if(cfg->format[i] == '@'){ + }else if(lcfg->format[i] == '@'){ if(i < len-1){ i++; - if(cfg->format[i] == '@'){ + if(lcfg->format[i] == '@'){ fputc('@', stdout); }else{ if(!ti){ if(get_time(&ti, &ns)){ - fprintf(stderr, "Error obtaining system time.\n"); + err_printf(lcfg, "Error obtaining system time.\n"); return; } } strf[0] = '%'; - strf[1] = cfg->format[i]; + strf[1] = lcfg->format[i]; strf[2] = 0; - if(cfg->format[i] == 'N'){ + if(lcfg->format[i] == 'N'){ printf("%09ld", ns); }else{ if(strftime(buf, 100, strf, ti) != 0){ @@ -257,10 +258,10 @@ static void formatted_print(const struct mosq_config *cfg, const struct mosquitt } } } - }else if(cfg->format[i] == '\\'){ + }else if(lcfg->format[i] == '\\'){ if(i < len-1){ i++; - switch(cfg->format[i]){ + switch(lcfg->format[i]){ case '\\': fputc('\\', stdout); break; @@ -295,10 +296,10 @@ static void formatted_print(const struct mosq_config *cfg, const struct mosquitt } } }else{ - fputc(cfg->format[i], stdout); + fputc(lcfg->format[i], stdout); } } - if(cfg->eol){ + if(lcfg->eol){ fputc('\n', stdout); } fflush(stdout); From 29cf965b4f258d5b552dff738583203d52c86fba Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 11:39:19 +0100 Subject: [PATCH 11/52] Fix mosquitto_pub exiting with error code 0 when an error occurred. Thanks to janniswarnat. Closes #1285. --- ChangeLog.txt | 2 ++ client/pub_client.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index eeaa2332..62a0a788 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -15,6 +15,8 @@ Clients: - Fix -L url parsing when `/topic` part is missing. - Stop some error messages being printed even when `--quiet` was used. Closes #1284. +- Fix mosquitto_pub exiting with error code 0 when an error occurred. + Closes #1285. 1.6.2 - 20190430 diff --git a/client/pub_client.c b/client/pub_client.c index 60d652a3..96fc8f12 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -312,7 +312,7 @@ int pub_shared_loop(struct mosquitto *mosq) if(mode == MSGMODE_STDIN_LINE){ mosquitto_loop_stop(mosq, false); } - return 0; + return rc; } From 999c478c88679000b4310e3f4d37c0edf9bf2795 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 14:35:43 +0100 Subject: [PATCH 12/52] Fixes for bug #1273 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix Will message for a persistent client incorrectly being sent when the client reconnects after a clean disconnect. * Fix Will message for a persistent client not being sent on disconnect. * Fix mosquitto_pub not using the `-c` option. Thanks to Yannic Schröder. Closes #1273. --- ChangeLog.txt | 9 +++- client/pub_client.c | 2 +- lib/mosquitto_internal.h | 7 +++ src/context.c | 11 ++-- src/handle_auth.c | 7 +-- src/handle_connect.c | 11 ++-- src/handle_disconnect.c | 2 + src/mosquitto_broker_internal.h | 1 + src/will_delay.c | 17 +++--- test/broker/07-will-qos0-helper.py | 18 ------- test/broker/07-will-qos0.py | 68 ++++++++++++++---------- test/broker/07-will-reconnect-1273.py | 75 +++++++++++++++++++++++++++ test/broker/Makefile | 1 + test/broker/test.py | 1 + 14 files changed, 157 insertions(+), 73 deletions(-) delete mode 100755 test/broker/07-will-qos0-helper.py create mode 100755 test/broker/07-will-reconnect-1273.py diff --git a/ChangeLog.txt b/ChangeLog.txt index 62a0a788..24287208 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -5,11 +5,15 @@ Broker: - Fix detection of incoming v3.1/v3.1.1 bridges. Closes #1263. - Fix default max_topic_alias listener config not being copied to the in-use listener when compiled without TLS support. -- Fix random number generation if compiling using WITH_TLS=no and on Linux +- Fix random number generation if compiling using `WITH_TLS=no` and on Linux with glibc >= 2.25. Without this fix, no random numbers would be generated for e.g. on broker client id generation, and so clients connecting expecting this feature would be unable to connect. -- Fix compilation problem related to getrandom() on non-glibc systems. +- Fix compilation problem related to `getrandom()` on non-glibc systems. +- Fix Will message for a persistent client incorrectly being sent when the + client reconnects after a clean disconnect. Closes #1273. +- Fix Will message for a persistent client not being sent on disconnect. + Closes #1273. Clients: - Fix -L url parsing when `/topic` part is missing. @@ -17,6 +21,7 @@ Clients: Closes #1284. - Fix mosquitto_pub exiting with error code 0 when an error occurred. Closes #1285. +- Fix mosquitto_pub not using the `-c` option. Closes #1273. 1.6.2 - 20190430 diff --git a/client/pub_client.c b/client/pub_client.c index 96fc8f12..40310225 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -476,7 +476,7 @@ int main(int argc, char *argv[]) goto cleanup; } - mosq = mosquitto_new(cfg.id, true, NULL); + mosq = mosquitto_new(cfg.id, cfg.clean_session, NULL); if(!mosq){ switch(errno){ case ENOMEM: diff --git a/lib/mosquitto_internal.h b/lib/mosquitto_internal.h index 2c551589..ff656a43 100644 --- a/lib/mosquitto_internal.h +++ b/lib/mosquitto_internal.h @@ -180,6 +180,12 @@ enum mosquitto__keyform { }; #endif +struct will_delay_list { + struct mosquitto *context; + struct will_delay_list *prev; + struct will_delay_list *next; +}; + struct mosquitto_msg_data{ #ifdef WITH_BROKER struct mosquitto_client_msg *inflight; @@ -224,6 +230,7 @@ struct mosquitto { struct mosquitto__packet *out_packet; struct mosquitto_message_all *will; struct mosquitto__alias *aliases; + struct will_delay_list *will_delay_entry; uint32_t maximum_packet_size; int alias_count; uint32_t will_delay_interval; diff --git a/src/context.c b/src/context.c index a78d9f84..f024d171 100644 --- a/src/context.c +++ b/src/context.c @@ -25,6 +25,7 @@ Contributors: #include "packet_mosq.h" #include "property_mosq.h" #include "time_mosq.h" +#include "will_mosq.h" #include "uthash.h" @@ -218,13 +219,7 @@ void context__send_will(struct mosquitto_db *db, struct mosquitto *ctxt) &ctxt->will->properties); } } - if(ctxt->will){ - mosquitto_property_free_all(&ctxt->will->properties); - mosquitto__free(ctxt->will->msg.topic); - mosquitto__free(ctxt->will->msg.payload); - mosquitto__free(ctxt->will); - ctxt->will = NULL; - } + will__clear(ctxt); } @@ -232,8 +227,8 @@ void context__disconnect(struct mosquitto_db *db, struct mosquitto *context) { net__socket_close(db, context); + context__send_will(db, context); if(context->session_expiry_interval == 0){ - context__send_will(db, context); #ifdef WITH_BRIDGE if(!context->bridge) diff --git a/src/handle_auth.c b/src/handle_auth.c index 70b21adf..03bf4771 100644 --- a/src/handle_auth.c +++ b/src/handle_auth.c @@ -25,6 +25,7 @@ Contributors: #include "packet_mosq.h" #include "property_mosq.h" #include "send_mosq.h" +#include "will_mosq.h" int handle__auth(struct mosquitto_db *db, struct mosquitto *context) @@ -119,11 +120,7 @@ int handle__auth(struct mosquitto_db *db, struct mosquitto *context) free(auth_data_out); if(context->state == mosq_cs_authenticating && context->will){ /* Free will without sending if this is our first authentication attempt */ - mosquitto_property_free_all(&context->will->properties); - mosquitto__free(context->will->msg.payload); - mosquitto__free(context->will->msg.topic); - mosquitto__free(context->will); - context->will = NULL; + will__clear(context); } if(rc == MOSQ_ERR_AUTH){ send__connack(db, context, 0, MQTT_RC_NOT_AUTHORIZED, NULL); diff --git a/src/handle_connect.c b/src/handle_connect.c index 7ca3f338..10fd9334 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -30,6 +30,7 @@ Contributors: #include "time_mosq.h" #include "tls_mosq.h" #include "util_mosq.h" +#include "will_mosq.h" #ifdef WITH_WEBSOCKETS # include @@ -160,6 +161,8 @@ int connect__on_authorised(struct mosquitto_db *db, struct mosquitto *context, v } session_expiry__remove(found_context); + will_delay__remove(found_context); + will__clear(found_context); found_context->clean_start = true; found_context->session_expiry_interval = 0; @@ -836,13 +839,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) return rc; }else{ free(auth_data_out); - if(context->will){ - mosquitto_property_free_all(&context->will->properties); - mosquitto__free(context->will->msg.payload); - mosquitto__free(context->will->msg.topic); - mosquitto__free(context->will); - context->will = NULL; - } + will__clear(context); if(rc == MOSQ_ERR_AUTH){ send__connack(db, context, 0, MQTT_RC_NOT_AUTHORIZED, NULL); mosquitto__free(context->id); diff --git a/src/handle_disconnect.c b/src/handle_disconnect.c index 18b0ee80..72db7dd3 100644 --- a/src/handle_disconnect.c +++ b/src/handle_disconnect.c @@ -21,6 +21,7 @@ Contributors: #include "packet_mosq.h" #include "property_mosq.h" #include "send_mosq.h" +#include "will_mosq.h" int handle__disconnect(struct mosquitto_db *db, struct mosquitto *context) @@ -66,6 +67,7 @@ int handle__disconnect(struct mosquitto_db *db, struct mosquitto *context) if(reason_code == MQTT_RC_DISCONNECT_WITH_WILL_MSG){ context__set_state(context, mosq_cs_disconnect_with_will); }else{ + will__clear(context); context__set_state(context, mosq_cs_disconnecting); } do_disconnect(db, context, MOSQ_ERR_SUCCESS); diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index 38cc1360..478aa0f6 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -740,6 +740,7 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context, int reaso int will_delay__add(struct mosquitto *context); void will_delay__check(struct mosquitto_db *db, time_t now); void will_delay__send_all(struct mosquitto_db *db); +void will_delay__remove(struct mosquitto *mosq); #endif diff --git a/src/will_delay.c b/src/will_delay.c index b3ff8670..02754441 100644 --- a/src/will_delay.c +++ b/src/will_delay.c @@ -24,12 +24,6 @@ Contributors: #include "memory_mosq.h" #include "time_mosq.h" -struct will_delay_list { - struct mosquitto *context; - struct will_delay_list *prev; - struct will_delay_list *next; -}; - static struct will_delay_list *delay_list = NULL; static time_t last_check = 0; @@ -48,6 +42,7 @@ int will_delay__add(struct mosquitto *context) if(!item) return MOSQ_ERR_NOMEM; item->context = context; + context->will_delay_entry = item; item->context->will_delay_time = time(NULL) + item->context->will_delay_interval; DL_INSERT_INORDER(delay_list, item, will_delay__cmp); @@ -64,6 +59,7 @@ void will_delay__send_all(struct mosquitto_db *db) DL_FOREACH_SAFE(delay_list, item, tmp){ DL_DELETE(delay_list, item); item->context->will_delay_interval = 0; + item->context->will_delay_entry = NULL; context__send_will(db, item->context); mosquitto__free(item); } @@ -92,3 +88,12 @@ void will_delay__check(struct mosquitto_db *db, time_t now) } + +void will_delay__remove(struct mosquitto *mosq) +{ + if(mosq->will_delay_entry != NULL){ + DL_DELETE(delay_list, mosq->will_delay_entry); + mosq->will_delay_entry = NULL; + } +} + diff --git a/test/broker/07-will-qos0-helper.py b/test/broker/07-will-qos0-helper.py deleted file mode 100755 index 031ed4a6..00000000 --- a/test/broker/07-will-qos0-helper.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python3 - -# Connect a client with a will, then disconnect without DISCONNECT. - -from mosq_test_helper import * - -rc = 1 -keepalive = 60 -connect_packet = mosq_test.gen_connect("test-helper", keepalive=keepalive, will_topic="will/qos0/test", will_payload=b"will-message") -connack_packet = mosq_test.gen_connack(rc=0) - -port = mosq_test.get_port() -sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port) -rc = 0 -sock.close() - -exit(rc) - diff --git a/test/broker/07-will-qos0.py b/test/broker/07-will-qos0.py index 5d73a822..bf284398 100755 --- a/test/broker/07-will-qos0.py +++ b/test/broker/07-will-qos0.py @@ -4,38 +4,54 @@ from mosq_test_helper import * -rc = 1 -mid = 53 -keepalive = 60 -connect_packet = mosq_test.gen_connect("will-qos0-test", keepalive=keepalive) -connack_packet = mosq_test.gen_connack(rc=0) -subscribe_packet = mosq_test.gen_subscribe(mid, "will/qos0/test", 0) -suback_packet = mosq_test.gen_suback(mid, 0) +def do_test(proto_ver, clean_session): + rc = 1 + mid = 53 + keepalive = 60 + connect1_packet = mosq_test.gen_connect("will-qos0-test", keepalive=keepalive, proto_ver=proto_ver) + connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver) -publish_packet = mosq_test.gen_publish("will/qos0/test", qos=0, payload="will-message") + if proto_ver == 5: + props = mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_SESSION_EXPIRY_INTERVAL, 100) + else: + props = None -port = mosq_test.get_port() -broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) + connect2_packet = mosq_test.gen_connect("test-helper", keepalive=keepalive, will_topic="will/qos0/test", will_payload=b"will-message", clean_session=clean_session, proto_ver=proto_ver, properties=props) + connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver) -try: - sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=30, port=port) - mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback") + subscribe_packet = mosq_test.gen_subscribe(mid, "will/qos0/test", 0, proto_ver=proto_ver) + suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=proto_ver) - will = subprocess.Popen(['./07-will-qos0-helper.py', str(port)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - will.wait() - (stdo, stde) = will.communicate() + publish_packet = mosq_test.gen_publish("will/qos0/test", qos=0, payload="will-message", proto_ver=proto_ver) - if mosq_test.expect_packet(sock, "publish", publish_packet): - rc = 0 + port = mosq_test.get_port() + broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) - sock.close() -finally: - broker.terminate() - broker.wait() - (stdo, stde) = broker.communicate() - if rc: - print(stde.decode('utf-8')) + try: + sock = mosq_test.do_client_connect(connect1_packet, connack1_packet, timeout=5, port=port) + mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback") -exit(rc) + sock2 = mosq_test.do_client_connect(connect2_packet, connack2_packet, port=port, timeout=5) + sock2.close() + + if mosq_test.expect_packet(sock, "publish", publish_packet): + rc = 0 + + sock.close() + except Exception as e: + print(e) + finally: + broker.terminate() + broker.wait() + (stdo, stde) = broker.communicate() + if rc: + print(stde.decode('utf-8')) + exit(rc) + +do_test(4, True) +do_test(4, False) +do_test(5, True) +do_test(5, False) +exit(0) diff --git a/test/broker/07-will-reconnect-1273.py b/test/broker/07-will-reconnect-1273.py new file mode 100755 index 00000000..bd8a5a5a --- /dev/null +++ b/test/broker/07-will-reconnect-1273.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +# Test whether a persistent client that disconnects with DISCONNECT has its +# will published when it reconnects. It shouldn't. Bug 1273: +# https://github.com/eclipse/mosquitto/issues/1273 + +from mosq_test_helper import * + + +def do_test(proto_ver): + rc = 1 + keepalive = 60 + + connect1_packet = mosq_test.gen_connect("will-sub", keepalive=keepalive, proto_ver=proto_ver) + connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver) + + mid = 1 + subscribe1_packet = mosq_test.gen_subscribe(mid, "will/test", 0, proto_ver=proto_ver) + suback1_packet = mosq_test.gen_suback(mid, 0, proto_ver=proto_ver) + + if proto_ver == 5: + props = mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_SESSION_EXPIRY_INTERVAL, 100) + else: + props = None + + connect2_packet = mosq_test.gen_connect("will-1273", keepalive=keepalive, will_topic="will/test", will_payload=b"will msg",clean_session=False, proto_ver=proto_ver, properties=props) + connack2a_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver) + connack2b_packet = mosq_test.gen_connack(rc=0, flags=1, proto_ver=proto_ver) + + disconnect_packet = mosq_test.gen_disconnect(proto_ver=proto_ver) + + publish_packet = mosq_test.gen_publish("will/test", qos=0, payload="alive", proto_ver=proto_ver) + + port = mosq_test.get_port() + broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) + + try: + # Connect and subscribe will-sub + sock1 = mosq_test.do_client_connect(connect1_packet, connack1_packet, timeout=30, port=port, connack_error="connack1") + mosq_test.do_send_receive(sock1, subscribe1_packet, suback1_packet, "suback") + + # Connect will-1273 + sock2 = mosq_test.do_client_connect(connect2_packet, connack2a_packet, timeout=30, port=port) + # Publish our "alive" message + sock2.send(publish_packet) + # Clean disconnect + sock2.send(disconnect_packet) + + # will-1273 should get the "alive" + mosq_test.expect_packet(sock1, "publish1", publish_packet) + + sock2.close() + + # Reconnect + sock2 = mosq_test.do_client_connect(connect2_packet, connack2b_packet, timeout=30, port=port, connack_error="connack2") + # will-1273 to publish "alive" again, and will-sub to receive it. + sock2.send(publish_packet) + mosq_test.expect_packet(sock1, "publish2", publish_packet) + # Do a ping to make sure there are no other packets received. + mosq_test.do_ping(sock1) + rc = 0 + + sock1.close() + sock2.close() + finally: + broker.terminate() + broker.wait() + (stdo, stde) = broker.communicate() + if rc: + print(stde.decode('utf-8')) + exit(rc) + +do_test(4) +do_test(5) +exit(0) diff --git a/test/broker/Makefile b/test/broker/Makefile index 5ea42c0b..ba91fb8a 100644 --- a/test/broker/Makefile +++ b/test/broker/Makefile @@ -144,6 +144,7 @@ endif ./07-will-null.py ./07-will-properties.py ./07-will-qos0.py + ./07-will-reconnect-1273.py 08 : ifeq ($(WITH_TLS),yes) diff --git a/test/broker/test.py b/test/broker/test.py index eac2d54c..497e3627 100755 --- a/test/broker/test.py +++ b/test/broker/test.py @@ -118,6 +118,7 @@ tests = [ (1, './07-will-null.py'), (1, './07-will-properties.py'), (1, './07-will-qos0.py'), + (1, './07-will-reconnect-1273.py'), (2, './08-ssl-bridge.py'), (2, './08-ssl-connect-cert-auth-crl.py'), From 3f8f4fc2c81507bc41c574ada6d5a77c9f26e23d Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 18:42:22 +0100 Subject: [PATCH 13/52] Fix typo causing build error on Windows when building without TLS support. Thanks to TimmvonderMehden. Closes #1264. --- ChangeLog.txt | 4 ++++ lib/util_mosq.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 24287208..c4b5c376 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -15,6 +15,10 @@ Broker: - Fix Will message for a persistent client not being sent on disconnect. Closes #1273. +Client library: +- Fix typo causing build error on Windows when building without TLS support. + Closes #1264. + Clients: - Fix -L url parsing when `/topic` part is missing. - Stop some error messages being printed even when `--quiet` was used. diff --git a/lib/util_mosq.c b/lib/util_mosq.c index ce903e79..5e1065e7 100644 --- a/lib/util_mosq.c +++ b/lib/util_mosq.c @@ -331,7 +331,7 @@ int util__random_bytes(void *bytes, int count) rc = MOSQ_ERR_SUCCESS; } #elif defined(WIN32) - HRYPTPROV provider; + HCRYPTPROV provider; if(!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)){ return MOSQ_ERR_UNKNOWN; From 46d5aa968273f68e8db6bc6bda7bfb90b906519f Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 18:50:05 +0100 Subject: [PATCH 14/52] Improve documentation around the upgrading of persistence files. Thanks to jsaak. Closes #1276. --- ChangeLog.txt | 2 ++ man/mosquitto.conf.5.xml | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index c4b5c376..e721d48a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -14,6 +14,8 @@ Broker: client reconnects after a clean disconnect. Closes #1273. - Fix Will message for a persistent client not being sent on disconnect. Closes #1273. +- Improve documentation around the upgrading of persistence files. Closes + #1276. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index 8d09c122..a2145b21 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -686,6 +686,13 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S signal. If false, the data will be stored in memory only. Defaults to false. + The persistence file may change its format in a new + version. The broker can currently read all old formats, + but will only save in the latest format. It should always + be safe to upgrade, but cautious users may wish to take a + copy of the persistence file before installing a new + version so that they can roll back to an earlier version + if necessary. Reloaded on reload signal. From b4dfeb3767b595e3247640b7e8558935eb55d2e4 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 23:56:22 +0100 Subject: [PATCH 15/52] Fix MQTT v5 clients not being able to specify a password without a username. Thanks to Erik Moqvist. Closes #1274. --- ChangeLog.txt | 2 ++ client/client_shared.c | 7 ++----- client/pub_client.c | 2 +- client/rr_client.c | 2 +- client/sub_client.c | 2 +- lib/options.c | 21 ++++++++++++++------- lib/send_connect.c | 29 +++++++++++++++++++--------- man/mosquitto_pub.1.xml | 10 ++++------ man/mosquitto_rr.1.xml | 10 ++++------ man/mosquitto_sub.1.xml | 10 ++++------ src/handle_connect.c | 42 ++++++++++++++++++++--------------------- 11 files changed, 73 insertions(+), 64 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index e721d48a..c64373ea 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -28,6 +28,8 @@ Clients: - Fix mosquitto_pub exiting with error code 0 when an error occurred. Closes #1285. - Fix mosquitto_pub not using the `-c` option. Closes #1273. +- Fix MQTT v5 clients not being able to specify a password without a username. + Closes #1274. 1.6.2 - 20190430 diff --git a/client/client_shared.c b/client/client_shared.c index 0205ce8d..ede8baa1 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -325,9 +325,6 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * fprintf(stderr, "Error: Will retain given, but no will topic given.\n"); return 1; } - if(cfg->password && !cfg->username){ - err_printf(cfg, "Warning: Not using password since username not set.\n"); - } #ifdef WITH_TLS if((cfg->certfile && !cfg->keyfile) || (cfg->keyfile && !cfg->certfile)){ fprintf(stderr, "Error: Both certfile and keyfile must be provided if one of them is set.\n"); @@ -1084,8 +1081,8 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg) } cfg->will_props = NULL; - if(cfg->username && mosquitto_username_pw_set(mosq, cfg->username, cfg->password)){ - err_printf(cfg, "Error: Problem setting username and password.\n"); + if((cfg->username || cfg->password) && mosquitto_username_pw_set(mosq, cfg->username, cfg->password)){ + err_printf(cfg, "Error: Problem setting username and/or password.\n"); mosquitto_lib_cleanup(); return 1; } diff --git a/client/pub_client.c b/client/pub_client.c index 40310225..f5521eac 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -329,7 +329,7 @@ void print_usage(void) mosquitto_lib_version(&major, &minor, &revision); printf("mosquitto_pub is a simple mqtt client that will publish a message on a single topic and exit.\n"); printf("mosquitto_pub version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision); - printf("Usage: mosquitto_pub {[-h host] [-p port] [-u username [-P password]] -t topic | -L URL}\n"); + printf("Usage: mosquitto_pub {[-h host] [-p port] [-u username] [-P password] -t topic | -L URL}\n"); printf(" {-f file | -l | -n | -m message}\n"); printf(" [-c] [-k keepalive] [-q qos] [-r] [--repeat N] [--repeat-delay time]\n"); #ifdef WITH_SRV diff --git a/client/rr_client.c b/client/rr_client.c index cbd32d5e..6444c28e 100644 --- a/client/rr_client.c +++ b/client/rr_client.c @@ -156,7 +156,7 @@ void print_usage(void) printf(" Defaults to MQTT v5, where the Request-Response feature will be used, but v3.1.1 can also be used\n"); printf(" with v3.1.1 brokers.\n"); printf("mosquitto_rr version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision); - printf("Usage: mosquitto_rr {[-h host] [-p port] [-u username [-P password]] -t topic | -L URL} -e response-topic\n"); + printf("Usage: mosquitto_rr {[-h host] [-p port] [-u username] [-P password] -t topic | -L URL} -e response-topic\n"); printf(" [-c] [-k keepalive] [-q qos] [-R]\n"); printf(" [-F format]\n"); #ifndef WIN32 diff --git a/client/sub_client.c b/client/sub_client.c index a10757c6..f57a48cc 100644 --- a/client/sub_client.c +++ b/client/sub_client.c @@ -168,7 +168,7 @@ void print_usage(void) mosquitto_lib_version(&major, &minor, &revision); printf("mosquitto_sub is a simple mqtt client that will subscribe to a set of topics and print all messages it receives.\n"); printf("mosquitto_sub version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision); - printf("Usage: mosquitto_sub {[-h host] [-p port] [-u username [-P password]] -t topic | -L URL [-t topic]}\n"); + printf("Usage: mosquitto_sub {[-h host] [-p port] [-u username] [-P password] -t topic | -L URL [-t topic]}\n"); printf(" [-c] [-k keepalive] [-q qos]\n"); printf(" [-C msg_count] [-E] [-R] [--retained-only] [--remove-retained] [-T filter_out] [-U topic ...]\n"); printf(" [-F format]\n"); diff --git a/lib/options.c b/lib/options.c index 005b7810..06c5de00 100644 --- a/lib/options.c +++ b/lib/options.c @@ -69,6 +69,12 @@ int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, cons { if(!mosq) return MOSQ_ERR_INVAL; + if(mosq->protocol == mosq_p_mqtt311 || mosq->protocol == mosq_p_mqtt31){ + if(password != NULL && username == NULL){ + return MOSQ_ERR_INVAL; + } + } + mosquitto__free(mosq->username); mosq->username = NULL; @@ -81,13 +87,14 @@ int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, cons } mosq->username = mosquitto__strdup(username); if(!mosq->username) return MOSQ_ERR_NOMEM; - if(password){ - mosq->password = mosquitto__strdup(password); - if(!mosq->password){ - mosquitto__free(mosq->username); - mosq->username = NULL; - return MOSQ_ERR_NOMEM; - } + } + + if(password){ + mosq->password = mosquitto__strdup(password); + if(!mosq->password){ + mosquitto__free(mosq->username); + mosq->username = NULL; + return MOSQ_ERR_NOMEM; } } return MOSQ_ERR_SUCCESS; diff --git a/lib/send_connect.c b/lib/send_connect.c index 60c529a5..210f125a 100644 --- a/lib/send_connect.c +++ b/lib/send_connect.c @@ -111,11 +111,21 @@ int send__connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session payloadlen += will_proplen + varbytes; } } + + /* After this check we can be sure that the username and password are + * always valid for the current protocol, so there is no need to check + * username before checking password. */ + if(mosq->protocol == mosq_p_mqtt31 || mosq->protocol == mosq_p_mqtt311){ + if(password != NULL && username == NULL){ + return MOSQ_ERR_INVAL; + } + } + if(username){ payloadlen += 2+strlen(username); - if(password){ - payloadlen += 2+strlen(password); - } + } + if(password){ + payloadlen += 2+strlen(password); } packet->command = CMD_CONNECT; @@ -145,9 +155,9 @@ int send__connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session } if(username){ byte = byte | 0x1<<7; - if(mosq->password){ - byte = byte | 0x1<<6; - } + } + if(mosq->password){ + byte = byte | 0x1<<6; } packet__write_byte(packet, byte); packet__write_uint16(packet, keepalive); @@ -173,11 +183,12 @@ int send__connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session packet__write_string(packet, mosq->will->msg.topic, strlen(mosq->will->msg.topic)); packet__write_string(packet, (const char *)mosq->will->msg.payload, mosq->will->msg.payloadlen); } + if(username){ packet__write_string(packet, username, strlen(username)); - if(password){ - packet__write_string(packet, password, strlen(password)); - } + } + if(password){ + packet__write_string(packet, password, strlen(password)); } mosq->keepalive = keepalive; diff --git a/man/mosquitto_pub.1.xml b/man/mosquitto_pub.1.xml index 46bf09ba..2c1a425c 100644 --- a/man/mosquitto_pub.1.xml +++ b/man/mosquitto_pub.1.xml @@ -21,10 +21,8 @@ hostname port-number - - username - password - + username + password message-topic URL @@ -366,8 +364,8 @@ Provide a password to be used for authenticating with the broker. Using this argument without also specifying - a username is invalid. See also the - option. + a username is invalid when using MQTT v3.1 or v3.1.1. + See also the option. diff --git a/man/mosquitto_rr.1.xml b/man/mosquitto_rr.1.xml index 0828a5a2..5af06af0 100644 --- a/man/mosquitto_rr.1.xml +++ b/man/mosquitto_rr.1.xml @@ -21,10 +21,8 @@ hostname port-number - - username - password - + username + password message-topic @@ -387,8 +385,8 @@ Provide a password to be used for authenticating with the broker. Using this argument without also specifying - a username is invalid. See also the - option. + a username is invalid when using MQTT v3.1 or v3.1.1. + See also the option. diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml index 0547288f..83a500ac 100644 --- a/man/mosquitto_sub.1.xml +++ b/man/mosquitto_sub.1.xml @@ -21,10 +21,8 @@ hostname port-number - - username - password - + username + password message-topic @@ -396,8 +394,8 @@ Provide a password to be used for authenticating with the broker. Using this argument without also specifying - a username is invalid. See also the - option. + a username is invalid when using MQTT v3.1 or v3.1.1. + See also the option. diff --git a/src/handle_connect.c b/src/handle_connect.c index 10fd9334..7fc160e9 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -586,25 +586,10 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) if(username_flag){ rc = packet__read_string(&context->in_packet, &username, &slen); - if(rc == MOSQ_ERR_SUCCESS){ - if(password_flag){ - rc = packet__read_binary(&context->in_packet, (uint8_t **)&password, &slen); - if(rc == MOSQ_ERR_NOMEM){ - rc = MOSQ_ERR_NOMEM; - goto handle_connect_error; - }else if(rc == MOSQ_ERR_PROTOCOL){ - if(context->protocol == mosq_p_mqtt31){ - /* Password flag given, but no password. Ignore. */ - }else{ - rc = MOSQ_ERR_PROTOCOL; - goto handle_connect_error; - } - } - } - }else if(rc == MOSQ_ERR_NOMEM){ + if(rc == MOSQ_ERR_NOMEM){ rc = MOSQ_ERR_NOMEM; goto handle_connect_error; - }else{ + }else if(rc != MOSQ_ERR_SUCCESS){ if(context->protocol == mosq_p_mqtt31){ /* Username flag given, but no username. Ignore. */ username_flag = 0; @@ -614,7 +599,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) } } }else{ - if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){ + if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt31){ if(password_flag){ /* username_flag == 0 && password_flag == 1 is forbidden */ log__printf(NULL, MOSQ_LOG_ERR, "Protocol error from %s: password without username, closing connection.", client_id); @@ -623,6 +608,21 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) } } } + if(password_flag){ + rc = packet__read_binary(&context->in_packet, (uint8_t **)&password, &slen); + if(rc == MOSQ_ERR_NOMEM){ + rc = MOSQ_ERR_NOMEM; + goto handle_connect_error; + }else if(rc == MOSQ_ERR_PROTOCOL){ + if(context->protocol == mosq_p_mqtt31){ + /* Password flag given, but no password. Ignore. */ + }else{ + rc = MOSQ_ERR_PROTOCOL; + goto handle_connect_error; + } + } + } + if(context->in_packet.pos != context->in_packet.remaining_length){ /* Surplus data at end of packet, this must be an error. */ rc = MOSQ_ERR_PROTOCOL; @@ -755,7 +755,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) #endif /* FINAL_WITH_TLS_PSK */ }else{ #endif /* WITH_TLS */ - if(username_flag){ + if(username_flag || password_flag){ /* FIXME - these ensure the mosquitto_client_id() and * mosquitto_client_username() functions work, but is hacky */ context->id = client_id; @@ -786,9 +786,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) context->password = password; username = NULL; /* Avoid free() in error: below. */ password = NULL; - } - - if(!username_flag){ + }else{ if((db->config->per_listener_settings && context->listener->security_options.allow_anonymous == false) || (!db->config->per_listener_settings && db->config->security_options.allow_anonymous == false)){ From bd34d8c9cd01d0e34072f3f1737eff870be03525 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 22 May 2019 09:45:02 +0100 Subject: [PATCH 16/52] Remove old man page references. Thanks to Karl Palsson. Closes #1266. --- ChangeLog.txt | 4 ++++ man/libmosquitto.3.xml | 9 ++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index c64373ea..fa89062a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -31,6 +31,10 @@ Clients: - Fix MQTT v5 clients not being able to specify a password without a username. Closes #1274. +Documentation: +- Remove references to Python binding and C++ wrapper in libmosquitto man + page. Closes #1266. + 1.6.2 - 20190430 ================ diff --git a/man/libmosquitto.3.xml b/man/libmosquitto.3.xml index 0048ee4a..1aa308ad 100644 --- a/man/libmosquitto.3.xml +++ b/man/libmosquitto.3.xml @@ -18,11 +18,10 @@ Description This is an overview of how to use libmosquitto to create MQTT aware client programs. There may be separate man pages on each of the - functions described here in the future. There is also a binding for - libmosquitto for C++ and a Python implementation. They are not - documented here but operate in a similar way. - This is fairly incomplete, please see mosquitto.h for a better - description of the functions. + functions described here in the future. + This man page is woefully incomplete, please see the comments + in mosquitto.h for missing functions and a description of the + functions. From f974b91084c531170870edef6ffce28a360c7c04 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 22 May 2019 13:20:45 +0100 Subject: [PATCH 17/52] Consistent ref counting inc and dec functions. --- src/database.c | 15 ++++++++++----- src/handle_connect.c | 2 +- src/mosquitto_broker_internal.h | 3 ++- src/persist_read.c | 2 +- src/subs.c | 10 +++++----- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/database.c b/src/database.c index 2a32b82c..4d70b73d 100644 --- a/src/database.c +++ b/src/database.c @@ -157,7 +157,7 @@ static void subhier_clean(struct mosquitto_db *db, struct mosquitto__subhier **s leaf = nextleaf; } if(peer->retained){ - db__msg_store_deref(db, &peer->retained); + db__msg_store_ref_dec(db, &peer->retained); } subhier_clean(db, &peer->children); mosquitto__free(peer->topic); @@ -232,7 +232,12 @@ void db__msg_store_clean(struct mosquitto_db *db) } } -void db__msg_store_deref(struct mosquitto_db *db, struct mosquitto_msg_store **store) +void db__msg_store_ref_inc(struct mosquitto_msg_store *store) +{ + store->ref_count++; +} + +void db__msg_store_ref_dec(struct mosquitto_db *db, struct mosquitto_msg_store **store) { (*store)->ref_count--; if((*store)->ref_count == 0){ @@ -271,7 +276,7 @@ static void db__message_remove(struct mosquitto_db *db, struct mosquitto_msg_dat msg_data->msg_count12--; msg_data->msg_bytes12 -= item->store->payloadlen; } - db__msg_store_deref(db, &item->store); + db__msg_store_ref_dec(db, &item->store); } mosquitto_property_free_all(&item->properties); @@ -450,7 +455,7 @@ int db__message_insert(struct mosquitto_db *db, struct mosquitto *context, uint1 msg->prev = NULL; msg->next = NULL; msg->store = stored; - msg->store->ref_count++; + db__msg_store_ref_inc(msg->store); msg->mid = mid; msg->timestamp = mosquitto_time(); msg->direction = dir; @@ -543,7 +548,7 @@ void db__messages_delete_list(struct mosquitto_db *db, struct mosquitto_client_m DL_FOREACH_SAFE(*head, tail, tmp){ DL_DELETE(*head, tail); - db__msg_store_deref(db, &tail->store); + db__msg_store_ref_dec(db, &tail->store); mosquitto_property_free_all(&tail->properties); mosquitto__free(tail); } diff --git a/src/handle_connect.c b/src/handle_connect.c index 7fc160e9..1bd35ace 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -92,7 +92,7 @@ void connection_check_acl(struct mosquitto_db *db, struct mosquitto *context, st msg_tail->store->qos, msg_tail->store->retain, MOSQ_ACL_READ) != MOSQ_ERR_SUCCESS){ DL_DELETE((*head), msg_tail); - db__msg_store_deref(db, &msg_tail->store); + db__msg_store_ref_dec(db, &msg_tail->store); mosquitto_property_free_all(&msg_tail->properties); mosquitto__free(msg_tail); } diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index 478aa0f6..540dbcbe 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -619,7 +619,8 @@ int db__message_store(struct mosquitto_db *db, const struct mosquitto *source, u int db__message_store_find(struct mosquitto *context, uint16_t mid, struct mosquitto_msg_store **stored); void db__msg_store_add(struct mosquitto_db *db, struct mosquitto_msg_store *store); void db__msg_store_remove(struct mosquitto_db *db, struct mosquitto_msg_store *store); -void db__msg_store_deref(struct mosquitto_db *db, struct mosquitto_msg_store **store); +void db__msg_store_ref_inc(struct mosquitto_msg_store *store); +void db__msg_store_ref_dec(struct mosquitto_db *db, struct mosquitto_msg_store **store); void db__msg_store_clean(struct mosquitto_db *db); void db__msg_store_compact(struct mosquitto_db *db); int db__message_reconnect_reset(struct mosquitto_db *db, struct mosquitto *context); diff --git a/src/persist_read.c b/src/persist_read.c index 1ae2f7a6..48437e46 100644 --- a/src/persist_read.c +++ b/src/persist_read.c @@ -138,7 +138,7 @@ static int persist__client_msg_restore(struct mosquitto_db *db, struct P_client_ return 1; } cmsg->store = load->store; - cmsg->store->ref_count++; + db__msg_store_ref_inc(cmsg->store); context = persist__find_or_add_context(db, chunk->client_id, 0); if(!context){ diff --git a/src/subs.c b/src/subs.c index 11093819..91d34266 100644 --- a/src/subs.c +++ b/src/subs.c @@ -146,14 +146,14 @@ static int subs__process(struct mosquitto_db *db, struct mosquitto__subhier *hie } #endif if(hier->retained){ - db__msg_store_deref(db, &hier->retained); + db__msg_store_ref_dec(db, &hier->retained); #ifdef WITH_SYS_TREE db->retained_count--; #endif } if(stored->payloadlen){ hier->retained = stored; - hier->retained->ref_count++; + db__msg_store_ref_inc(hier->retained); #ifdef WITH_SYS_TREE db->retained_count++; #endif @@ -803,7 +803,7 @@ int sub__messages_queue(struct mosquitto_db *db, const char *source_id, const ch clients - this is required because websockets client calls db__message_write(), which could remove the message if ref_count==0. */ - (*stored)->ref_count++; + db__msg_store_ref_inc(*stored); HASH_FIND(hh, db->subs, tokens->topic, tokens->topic_len, subhier); if(subhier){ @@ -818,7 +818,7 @@ int sub__messages_queue(struct mosquitto_db *db, const char *source_id, const ch sub__topic_tokens_free(tokens); /* Remove our reference and free if needed. */ - db__msg_store_deref(db, stored); + db__msg_store_ref_dec(db, stored); return rc; } @@ -981,7 +981,7 @@ static int retain__process(struct mosquitto_db *db, struct mosquitto__subhier *b struct mosquitto_msg_store *retained; if(branch->retained->message_expiry_time > 0 && now > branch->retained->message_expiry_time){ - db__msg_store_deref(db, &branch->retained); + db__msg_store_ref_dec(db, &branch->retained); branch->retained = NULL; #ifdef WITH_SYS_TREE db->retained_count--; From a900e3a1a7adde5ffa0c2678652afc13592fadc3 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 22 May 2019 16:49:04 +0100 Subject: [PATCH 18/52] Mention mosquitto_broker.h in mosquitto_plugin.h. --- src/mosquitto_plugin.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mosquitto_plugin.h b/src/mosquitto_plugin.h index c4b872a1..a07b75b7 100644 --- a/src/mosquitto_plugin.h +++ b/src/mosquitto_plugin.h @@ -77,6 +77,16 @@ struct mosquitto_acl_msg { * denied. */ +/* ========================================================================= + * + * Helper Functions + * + * ========================================================================= */ + +/* There are functions that are available for plugin developers to use in + * mosquitto_broker.h, including logging and accessor functions. + */ + /* ========================================================================= * From 00eee59ad9d58fd2ba28ca40efc79a7ff8b41ffd Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 23 May 2019 11:03:09 +0100 Subject: [PATCH 19/52] Add 'extern "C"' on public headers. mosquitto_broker.h and mosquitto_plugin.h Thanks to Wolfgang Petroschka. Closes #1290. --- ChangeLog.txt | 2 ++ src/mosquitto_broker.h | 8 ++++++++ src/mosquitto_plugin.h | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index fa89062a..39d1329d 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -16,6 +16,8 @@ Broker: Closes #1273. - Improve documentation around the upgrading of persistence files. Closes #1276. +- Add 'extern "C"' on mosquitto_broker.h and mosquitto_plugin.h for C++ plugin + writing. Closes #1290. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/src/mosquitto_broker.h b/src/mosquitto_broker.h index d8e41f73..f6f2cc86 100644 --- a/src/mosquitto_broker.h +++ b/src/mosquitto_broker.h @@ -17,6 +17,10 @@ Contributors: #ifndef MOSQUITTO_BROKER_H #define MOSQUITTO_BROKER_H +#ifdef __cplusplus +extern "C" { +#endif + #include struct mosquitto; @@ -161,4 +165,8 @@ const char *mosquitto_client_username(const struct mosquitto *client); */ int mosquitto_set_username(struct mosquitto *client, const char *username); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/mosquitto_plugin.h b/src/mosquitto_plugin.h index a07b75b7..83e55ebd 100644 --- a/src/mosquitto_plugin.h +++ b/src/mosquitto_plugin.h @@ -17,6 +17,10 @@ Contributors: #ifndef MOSQUITTO_PLUGIN_H #define MOSQUITTO_PLUGIN_H +#ifdef __cplusplus +extern "C" { +#endif + #define MOSQ_AUTH_PLUGIN_VERSION 4 #define MOSQ_ACL_NONE 0x00 @@ -305,4 +309,10 @@ int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const int mosquitto_auth_start(void *user_data, struct mosquitto *client, const char *method, bool reauth, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); int mosquitto_auth_continue(void *user_data, struct mosquitto *client, const char *method, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + + +#ifdef __cplusplus +} +#endif + #endif From 3dd8eb722bd836b67466a0388d6b041488fc7bcd Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 28 May 2019 22:00:11 +0100 Subject: [PATCH 20/52] Colour internal logs for visibility. --- src/logging.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/logging.c b/src/logging.c index d956643d..bcb6a156 100644 --- a/src/logging.c +++ b/src/logging.c @@ -373,10 +373,19 @@ int log__printf(struct mosquitto *mosq, int priority, const char *fmt, ...) void log__internal(const char *fmt, ...) { va_list va; + char buf[200]; + int len; va_start(va, fmt); - log__vprintf(MOSQ_LOG_INTERNAL, fmt, va); + len = vsnprintf(buf, 200, fmt, va); va_end(va); + + if(len >= 200){ + log__printf(NULL, MOSQ_LOG_INTERNAL, "Internal log buffer too short (%d)", len); + return; + } + + log__printf(NULL, MOSQ_LOG_INTERNAL, "%s%s%s", "\e[32m", buf, "\e[0m"); } int mosquitto_log_vprintf(int level, const char *fmt, va_list va) From e43a278652a5ea540fb8297d7d4f1af7e4ebbb43 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 28 May 2019 22:12:13 +0100 Subject: [PATCH 21/52] Fix test compilation. --- test/unit/persist_read_stubs.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/unit/persist_read_stubs.c b/test/unit/persist_read_stubs.c index 7e0d18c4..568016ec 100644 --- a/test/unit/persist_read_stubs.c +++ b/test/unit/persist_read_stubs.c @@ -142,3 +142,9 @@ int sub__messages_queue(struct mosquitto_db *db, const char *source_id, const ch return MOSQ_ERR_SUCCESS; } + +void db__msg_store_ref_inc(struct mosquitto_msg_store *store) +{ + store->ref_count++; +} + From 50882025294a70499173ec9e4dddef944b389185 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 28 May 2019 22:13:22 +0100 Subject: [PATCH 22/52] Fix persistent Websockets clients not receiving messages. This occurs after they reconnect, having sent DISCONNECT on a previous session. Closes #1227. Thanks to usernametaken. --- ChangeLog.txt | 2 ++ src/loop.c | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 39d1329d..33504027 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -18,6 +18,8 @@ Broker: #1276. - Add 'extern "C"' on mosquitto_broker.h and mosquitto_plugin.h for C++ plugin writing. Closes #1290. +- Fix persistent Websockets clients not receiving messages after they + reconnect, having sent DISCONNECT on a previous session. Closes #1227. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/src/loop.c b/src/loop.c index fc18399e..50959599 100644 --- a/src/loop.c +++ b/src/loop.c @@ -614,12 +614,19 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context, int reaso #ifdef WITH_EPOLL struct epoll_event ev; #endif +#ifdef WITH_WEBSOCKETS + bool is_duplicate = false; +#endif if(context->state == mosq_cs_disconnected){ return; } #ifdef WITH_WEBSOCKETS if(context->wsi){ + if(context->state == mosq_cs_duplicate){ + is_duplicate = true; + } + if(context->state != mosq_cs_disconnecting && context->state != mosq_cs_disconnect_with_will){ context__set_state(context, mosq_cs_disconnect_ws); } @@ -636,7 +643,15 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context, int reaso context->sock = INVALID_SOCKET; context->pollfd_index = -1; } - context__remove_from_by_id(db, context); + if(is_duplicate){ + /* This occurs if another client is taking over the same client id. + * It is important to remove this from the by_id hash here, so it + * doesn't leave us with multiple clients in the hash with the same + * id. Websockets doesn't actually close the connection here, + * unlike for normal clients, which means there is extra time when + * there could be two clients with the same id in the hash. */ + context__remove_from_by_id(db, context); + } }else #endif { From 96d0a2690278755230f9388dbef80534083e2cd2 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 28 May 2019 23:37:26 +0100 Subject: [PATCH 23/52] Only add to disused if session expiry is 0. --- src/will_delay.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/will_delay.c b/src/will_delay.c index 02754441..4bed7a87 100644 --- a/src/will_delay.c +++ b/src/will_delay.c @@ -78,8 +78,11 @@ void will_delay__check(struct mosquitto_db *db, time_t now) if(item->context->will_delay_time < now){ DL_DELETE(delay_list, item); item->context->will_delay_interval = 0; + item->context->will_delay_entry = NULL; context__send_will(db, item->context); - context__add_to_disused(db, item->context); + if(item->context->session_expiry_interval == 0){ + context__add_to_disused(db, item->context); + } mosquitto__free(item); }else{ return; From b42bb99ba6da5b89474c415688403cc1ae128e52 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 11:47:18 +0100 Subject: [PATCH 24/52] Disable TLS renegotiation. Client initiated renegotiation is considered to be a potential attack vector against servers. Closes #1257. Thanks to Daniele Sluijters. --- ChangeLog.txt | 2 ++ src/net.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 33504027..5be7af28 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -20,6 +20,8 @@ Broker: writing. Closes #1290. - Fix persistent Websockets clients not receiving messages after they reconnect, having sent DISCONNECT on a previous session. Closes #1227. +- Disable TLS renegotiation. Client initiated renegotiation is considered to + be a potential attack vector against servers. Closes #1257. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/src/net.c b/src/net.c index 495f8b2f..0b57558c 100644 --- a/src/net.c +++ b/src/net.c @@ -368,6 +368,10 @@ static int mosquitto__tls_server_ctx(struct mosquitto__listener *listener) #endif #endif +#ifdef SSL_OP_NO_RENEGOTIATION + SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_RENEGOTIATION); +#endif + snprintf(buf, 256, "mosquitto-%d", listener->port); SSL_CTX_set_session_id_context(listener->ssl_ctx, (unsigned char *)buf, strlen(buf)); From 1c0c6a40fc6538a03f707cb87092b5e305e0a34e Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 15:06:56 +0100 Subject: [PATCH 25/52] CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294. Thanks to Lucas Ramage. --- .github/lock.yml | 35 +++++++++++++++++++++++++++++++++++ ChangeLog.txt | 3 +++ config.mk | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 .github/lock.yml diff --git a/.github/lock.yml b/.github/lock.yml new file mode 100644 index 00000000..916ac1f7 --- /dev/null +++ b/.github/lock.yml @@ -0,0 +1,35 @@ +# Configuration for Lock Threads - https://github.com/dessant/lock-threads + +# Number of days of inactivity before a closed issue or pull request is locked +daysUntilLock: 90 + +# Skip issues and pull requests created before a given timestamp. Timestamp must +# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable +skipCreatedBefore: false + +# Issues and pull requests with these labels will be ignored. Set to `[]` to disable +exemptLabels: [] + +# Label to add before locking, such as `outdated`. Set to `false` to disable +lockLabel: false + +# Comment to post before locking. Set to `false` to disable +lockComment: false + +# Assign `resolved` as the reason for locking. Set to `false` to disable +setLockReason: true + +# Limit to only `issues` or `pulls` +only: issues + +# Optionally, specify configuration settings just for `issues` or `pulls` +# issues: +# exemptLabels: +# - help-wanted +# lockLabel: outdated + +# pulls: +# daysUntilLock: 30 + +# Repository to extend settings from +# _extends: repo diff --git a/ChangeLog.txt b/ChangeLog.txt index 5be7af28..26c8b66f 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -41,6 +41,9 @@ Documentation: - Remove references to Python binding and C++ wrapper in libmosquitto man page. Closes #1266. +Build: +- CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294. + 1.6.2 - 20190430 ================ diff --git a/config.mk b/config.mk index 9c9592a1..6b9660bc 100644 --- a/config.mk +++ b/config.mk @@ -143,7 +143,7 @@ BROKER_LDADD:= CLIENT_CPPFLAGS:=$(CPPFLAGS) -I.. -I../lib CLIENT_CFLAGS:=${CFLAGS} -DVERSION="\"${VERSION}\"" -CLIENT_LDFLAGS:=-L../lib +CLIENT_LDFLAGS:=$(LDFLAGS) -L../lib CLIENT_LDADD:= PASSWD_LDADD:= From e51e40e95cade69f8f9f972db4a2cb3dc255b09a Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 15:40:17 +0100 Subject: [PATCH 26/52] Fix incorrect shared subscription topic of '$shared.' --- ChangeLog.txt | 1 + src/subs.c | 4 ++-- test/broker/02-shared-qos0-v5.py | 28 ++++++++++++++-------------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 26c8b66f..c6cee2b0 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -22,6 +22,7 @@ Broker: reconnect, having sent DISCONNECT on a previous session. Closes #1227. - Disable TLS renegotiation. Client initiated renegotiation is considered to be a potential attack vector against servers. Closes #1257. +- Fix incorrect shared subscription topic '$shared'. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/src/subs.c b/src/subs.c index 91d34266..aae32666 100644 --- a/src/subs.c +++ b/src/subs.c @@ -706,7 +706,7 @@ int sub__add(struct mosquitto_db *db, struct mosquitto *context, const char *sub if(sub__topic_tokenise(sub, &tokens)) return 1; - if(!strcmp(tokens->topic, "$shared")){ + if(!strcmp(tokens->topic, "$share")){ if(!tokens->next || !tokens->next->next){ sub__topic_tokens_free(tokens); return MOSQ_ERR_PROTOCOL; @@ -756,7 +756,7 @@ int sub__remove(struct mosquitto_db *db, struct mosquitto *context, const char * if(sub__topic_tokenise(sub, &tokens)) return 1; - if(!strcmp(tokens->topic, "$shared")){ + if(!strcmp(tokens->topic, "$share")){ if(!tokens->next || !tokens->next->next){ sub__topic_tokens_free(tokens); return MOSQ_ERR_PROTOCOL; diff --git a/test/broker/02-shared-qos0-v5.py b/test/broker/02-shared-qos0-v5.py index 96576c69..eaebcb20 100755 --- a/test/broker/02-shared-qos0-v5.py +++ b/test/broker/02-shared-qos0-v5.py @@ -3,10 +3,10 @@ # Test whether shared subscriptions work # Client 1 subscribes to #, non shared. Should receive everything. -# Client 2 subscribes to $shared/one/share-test -# Client 3 subscribes to $shared/one/share-test and $shared/two/share-test -# Client 4 subscribes to $shared/two/share-test -# Client 5 subscribes to $shared/one/share-test +# Client 2 subscribes to $share/one/share-test +# Client 3 subscribes to $share/one/share-test and $share/two/share-test +# Client 4 subscribes to $share/two/share-test +# Client 5 subscribes to $share/one/share-test # A publish to "share-test" should always go to client 1. # The first publish should also go to client 2 (share one) and client 3 (share two) @@ -37,19 +37,19 @@ connack5_packet = mosq_test.gen_connack(rc=0, proto_ver=5) subscribe1_packet = mosq_test.gen_subscribe(mid, "#", 0, proto_ver=5) suback1_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) -subscribe2_packet = mosq_test.gen_subscribe(mid, "$shared/one/share-test", 0, proto_ver=5) +subscribe2_packet = mosq_test.gen_subscribe(mid, "$share/one/share-test", 0, proto_ver=5) suback2_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) -subscribe3a_packet = mosq_test.gen_subscribe(mid, "$shared/one/share-test", 0, proto_ver=5) +subscribe3a_packet = mosq_test.gen_subscribe(mid, "$share/one/share-test", 0, proto_ver=5) suback3a_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) -subscribe3b_packet = mosq_test.gen_subscribe(mid, "$shared/two/share-test", 0, proto_ver=5) +subscribe3b_packet = mosq_test.gen_subscribe(mid, "$share/two/share-test", 0, proto_ver=5) suback3b_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) -subscribe4_packet = mosq_test.gen_subscribe(mid, "$shared/two/share-test", 0, proto_ver=5) +subscribe4_packet = mosq_test.gen_subscribe(mid, "$share/two/share-test", 0, proto_ver=5) suback4_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) -subscribe5_packet = mosq_test.gen_subscribe(mid, "$shared/one/share-test", 0, proto_ver=5) +subscribe5_packet = mosq_test.gen_subscribe(mid, "$share/one/share-test", 0, proto_ver=5) suback5_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) publish1_packet = mosq_test.gen_publish("share-test", qos=0, payload="message1", proto_ver=5) @@ -60,19 +60,19 @@ mid = 2 unsubscribe1_packet = mosq_test.gen_unsubscribe(mid, "#", proto_ver=5) unsuback1_packet = mosq_test.gen_unsuback(mid, proto_ver=5) -unsubscribe2_packet = mosq_test.gen_unsubscribe(mid, "$shared/one/share-test", proto_ver=5) +unsubscribe2_packet = mosq_test.gen_unsubscribe(mid, "$share/one/share-test", proto_ver=5) unsuback2_packet = mosq_test.gen_unsuback(mid, proto_ver=5) -unsubscribe3a_packet = mosq_test.gen_unsubscribe(mid, "$shared/one/share-test", proto_ver=5) +unsubscribe3a_packet = mosq_test.gen_unsubscribe(mid, "$share/one/share-test", proto_ver=5) unsuback3a_packet = mosq_test.gen_unsuback(mid, proto_ver=5) -unsubscribe3b_packet = mosq_test.gen_unsubscribe(mid, "$shared/two/share-test", proto_ver=5) +unsubscribe3b_packet = mosq_test.gen_unsubscribe(mid, "$share/two/share-test", proto_ver=5) unsuback3b_packet = mosq_test.gen_unsuback(mid, proto_ver=5) -unsubscribe4_packet = mosq_test.gen_unsubscribe(mid, "$shared/two/share-test", proto_ver=5) +unsubscribe4_packet = mosq_test.gen_unsubscribe(mid, "$share/two/share-test", proto_ver=5) unsuback4_packet = mosq_test.gen_unsuback(mid, proto_ver=5) -unsubscribe5_packet = mosq_test.gen_unsubscribe(mid, "$shared/one/share-test", proto_ver=5) +unsubscribe5_packet = mosq_test.gen_unsubscribe(mid, "$share/one/share-test", proto_ver=5) unsuback5_packet = mosq_test.gen_unsuback(mid, proto_ver=5) From de695af8c0fac749fa059f00bce5805749534c15 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 16:07:45 +0100 Subject: [PATCH 27/52] Fix zero length client ids being rejected for MQTT v5 clients. This was happening when clean start was set to true. --- ChangeLog.txt | 2 + src/handle_connect.c | 8 ++- .../12-prop-assigned-client-identifier.py | 61 ++++++++++--------- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index c6cee2b0..509dbaf8 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -23,6 +23,8 @@ Broker: - Disable TLS renegotiation. Client initiated renegotiation is considered to be a potential attack vector against servers. Closes #1257. - Fix incorrect shared subscription topic '$shared'. +- Fix zero length client ids being rejected for MQTT v5 clients with clean + start set to true. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/src/handle_connect.c b/src/handle_connect.c index 1bd35ace..9de98dd9 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -540,8 +540,12 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) }else{ allow_zero_length_clientid = db->config->security_options.allow_zero_length_clientid; } - if(clean_start == 0 || allow_zero_length_clientid == false){ - send__connack(db, context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED, NULL); + if((context->protocol == mosq_p_mqtt311 && clean_start == 0) || allow_zero_length_clientid == false){ + if(context->protocol == mosq_p_mqtt311){ + send__connack(db, context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED, NULL); + }else{ + send__connack(db, context, 0, MQTT_RC_UNSPECIFIED, NULL); + } rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; }else{ diff --git a/test/broker/12-prop-assigned-client-identifier.py b/test/broker/12-prop-assigned-client-identifier.py index 376d10ce..28f5037b 100755 --- a/test/broker/12-prop-assigned-client-identifier.py +++ b/test/broker/12-prop-assigned-client-identifier.py @@ -5,43 +5,48 @@ from mosq_test_helper import * -rc = 1 - -keepalive = 10 -connect_packet = mosq_test.gen_connect(None, proto_ver=5, keepalive=keepalive) -props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_ASSIGNED_CLIENT_IDENTIFIER, "auto-00000000-0000-0000-0000-000000000000") -connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5, properties=props) +def do_test(clean_start): + rc = 1 + keepalive = 10 + connect_packet = mosq_test.gen_connect(None, proto_ver=5, keepalive=keepalive, clean_session=clean_start) -props = mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_SESSION_EXPIRY_INTERVAL, 1) -disconnect_client_packet = mosq_test.gen_disconnect(proto_ver=5, properties=props) + props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_ASSIGNED_CLIENT_IDENTIFIER, "auto-00000000-0000-0000-0000-000000000000") + connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5, properties=props) -disconnect_server_packet = mosq_test.gen_disconnect(proto_ver=5, reason_code=130) + props = mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_SESSION_EXPIRY_INTERVAL, 1) + disconnect_client_packet = mosq_test.gen_disconnect(proto_ver=5, properties=props) -port = mosq_test.get_port() -broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) + disconnect_server_packet = mosq_test.gen_disconnect(proto_ver=5, reason_code=130) -try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.settimeout(10) - sock.connect(("localhost", port)) + port = mosq_test.get_port() + broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) - sock.send(connect_packet) - connack_recvd = sock.recv(len(connack_packet)) + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(10) + sock.connect(("localhost", port)) - if connack_recvd[0:12] == connack_packet[0:12]: - # FIXME - this test could be tightened up a lot - rc = 0 + sock.send(connect_packet) + connack_recvd = sock.recv(len(connack_packet)) + + if connack_recvd[0:12] == connack_packet[0:12]: + # FIXME - this test could be tightened up a lot + rc = 0 - sock.close() -finally: - broker.terminate() - broker.wait() - (stdo, stde) = broker.communicate() - if rc: - print(stde.decode('utf-8')) + sock.close() + finally: + broker.terminate() + broker.wait() + (stdo, stde) = broker.communicate() + if rc: + print(stde.decode('utf-8')) + exit(rc) -exit(rc) + +do_test(True) +do_test(False) +exit(0) From 142d07f45a941a5c6494bb2a1130df2b4f087857 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 16:19:18 +0100 Subject: [PATCH 28/52] Fix MQTT v5 overlapping subscription behaviour. Clients now receive message from all matching subscriptions rather than the first one encountered, which ensures the maximum QoS requirement is met. --- ChangeLog.txt | 3 +++ src/database.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 509dbaf8..a98221a3 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -25,6 +25,9 @@ Broker: - Fix incorrect shared subscription topic '$shared'. - Fix zero length client ids being rejected for MQTT v5 clients with clean start set to true. +- Fix MQTT v5 overlapping subscription behaviour. Clients now receive message + from all matching subscriptions rather than the first one encountered, which + ensures the maximum QoS requirement is met. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/src/database.c b/src/database.c index 4d70b73d..482e210f 100644 --- a/src/database.c +++ b/src/database.c @@ -364,7 +364,8 @@ int db__message_insert(struct mosquitto_db *db, struct mosquitto *context, uint1 * multiple times for overlapping subscriptions, although this is only the * case for SUBSCRIPTION with multiple subs in so is a minor concern. */ - if(db->config->allow_duplicate_messages == false + if(context->protocol != mosq_p_mqtt5 + && db->config->allow_duplicate_messages == false && dir == mosq_md_out && retain == false && stored->dest_ids){ for(i=0; idest_id_count; i++){ From 908d1be6e0a8e66b9982e5b9d70a40a3898c6866 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 17:36:09 +0100 Subject: [PATCH 29/52] Suppress confusing "unknown PUBREL" message. --- lib/handle_pubrel.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/handle_pubrel.c b/lib/handle_pubrel.c index 40a91a64..d4a90652 100644 --- a/lib/handle_pubrel.c +++ b/lib/handle_pubrel.c @@ -83,7 +83,6 @@ int handle__pubrel(struct mosquitto_db *db, struct mosquitto *mosq) }else if(rc != MOSQ_ERR_SUCCESS){ /* Message not found. Still send a PUBCOMP anyway because this could be * due to a repeated PUBREL after a client has reconnected. */ - log__printf(mosq, MOSQ_LOG_WARNING, "Warning: Received PUBREL from %s for an unknown packet identifier %d.", mosq->id, mid); } rc = send__pubcomp(mosq, mid); From 1bafe0ee2e7ce58af294a66d0b944eae33e927f4 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 18:42:38 +0100 Subject: [PATCH 30/52] Fix double free on exit in mosquitto_pub. Closes #1280. Thanks to Lucky Saini. --- ChangeLog.txt | 3 +++ client/pub_client.c | 1 + 2 files changed, 4 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index a98221a3..9f2c31dd 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -43,6 +43,9 @@ Clients: - Fix MQTT v5 clients not being able to specify a password without a username. Closes #1274. +Clients: +- Fix double free on exit in mosquitto_pub. Closes #1280. + Documentation: - Remove references to Python binding and C++ wrapper in libmosquitto man page. Closes #1266. diff --git a/client/pub_client.c b/client/pub_client.c index f5521eac..ea7b61e0 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -508,6 +508,7 @@ int main(int argc, char *argv[]) if(cfg.message && cfg.pub_mode == MSGMODE_FILE){ free(cfg.message); + cfg.message = NULL; } mosquitto_destroy(mosq); mosquitto_lib_cleanup(); From 7d954fa52e5c1ab0ca2a9a173c47d60add3593f3 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 18:49:08 +0100 Subject: [PATCH 31/52] Fix `mosquitto_pub -l` not handling network failures. Closes #1152. Thanks to Dustin Sallings. --- ChangeLog.txt | 1 + client/pub_client.c | 19 ++++++++++++++----- client/pub_shared.h | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 9f2c31dd..9f2f71ea 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -44,6 +44,7 @@ Clients: Closes #1274. Clients: +- Fix `mosquitto_pub -l` not handling network failures. Closes #1152. - Fix double free on exit in mosquitto_pub. Closes #1280. Documentation: diff --git a/client/pub_client.c b/client/pub_client.c index ea7b61e0..31740391 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -42,7 +42,6 @@ static int last_mid = -1; static int last_mid_sent = -1; static char *line_buf = NULL; static int line_buf_len = 1024; -static bool connected = true; static bool disconnect_sent = false; static int publish_count = 0; static bool ready_for_repeat = false; @@ -104,7 +103,7 @@ void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc, const mos UNUSED(rc); UNUSED(properties); - connected = false; + status = STATUS_DISCONNECTED; } int my_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, void *payload, int qos, bool retain) @@ -222,6 +221,7 @@ int pub_shared_loop(struct mosquitto *mosq) int buf_len_actual; int mode; int loop_delay = 1000; + bool stdin_finished = false; if(cfg.repeat_count > 1 && (cfg.repeat_delay.tv_sec == 0 || cfg.repeat_delay.tv_usec != 0)){ loop_delay = cfg.repeat_delay.tv_usec / 2000; @@ -231,6 +231,7 @@ int pub_shared_loop(struct mosquitto *mosq) if(mode == MSGMODE_STDIN_LINE){ mosquitto_loop_start(mosq); + stdin_finished = false; } do{ @@ -238,7 +239,7 @@ int pub_shared_loop(struct mosquitto *mosq) if(status == STATUS_CONNACK_RECVD){ pos = 0; read_len = line_buf_len; - while(connected && fgets(&line_buf[pos], read_len, stdin)){ + while(status == STATUS_CONNACK_RECVD && fgets(&line_buf[pos], read_len, stdin)){ buf_len_actual = strlen(line_buf); if(line_buf[buf_len_actual-1] == '\n'){ line_buf[buf_len_actual-1] = '\0'; @@ -270,6 +271,10 @@ int pub_shared_loop(struct mosquitto *mosq) last_mid = mid_sent; status = STATUS_WAITING; } + stdin_finished = true; + }else if(status == STATUS_DISCONNECTED){ + /* Not end of stdin, so we've lost our connection and must + * reconnect */ } }else if(status == STATUS_WAITING){ if(last_mid_sent == last_mid && disconnect_sent == false){ @@ -307,12 +312,16 @@ int pub_shared_loop(struct mosquitto *mosq) } } } - }while(rc == MOSQ_ERR_SUCCESS && connected); + }while(rc == MOSQ_ERR_SUCCESS && stdin_finished == false); if(mode == MSGMODE_STDIN_LINE){ mosquitto_loop_stop(mosq, false); } - return rc; + if(status == STATUS_DISCONNECTED){ + return MOSQ_ERR_SUCCESS; + }else{ + return rc; + } } diff --git a/client/pub_shared.h b/client/pub_shared.h index fd7331f7..94d5d11c 100644 --- a/client/pub_shared.h +++ b/client/pub_shared.h @@ -20,6 +20,7 @@ Contributors: #define STATUS_CONNACK_RECVD 1 #define STATUS_WAITING 2 #define STATUS_DISCONNECTING 3 +#define STATUS_DISCONNECTED 4 extern int mid_sent; extern int status; From 18b897e5e3581f3d795e4c1ba7b4368ce84232c6 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 21:31:27 +0100 Subject: [PATCH 32/52] Attempt to fix 11-message-expiry for travis. --- test/broker/11-message-expiry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/broker/11-message-expiry.py b/test/broker/11-message-expiry.py index c755e59f..5986e183 100755 --- a/test/broker/11-message-expiry.py +++ b/test/broker/11-message-expiry.py @@ -44,7 +44,7 @@ publish1s_packet = mosq_test.gen_publish("subpub/qos1", mid=mid, qos=1, payload= puback1s_packet = mosq_test.gen_puback(mid) mid=2 -props = mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_MESSAGE_EXPIRY_INTERVAL, 10) +props = mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_MESSAGE_EXPIRY_INTERVAL, 100) publish2s_packet = mosq_test.gen_publish("subpub/qos1", mid=mid, qos=1, payload="message2", proto_ver=5, properties=props) puback2s_packet = mosq_test.gen_puback(mid) @@ -79,7 +79,7 @@ try: sock = mosq_test.do_client_connect(connect_packet, connack2_packet, timeout=20, port=port) packet = sock.recv(len(publish2s_packet)) - for i in range(9, 1, -1): + for i in range(100, 1, -1): props = mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_MESSAGE_EXPIRY_INTERVAL, i) publish2r_packet = mosq_test.gen_publish("subpub/qos1", mid=2, qos=1, payload="message2", proto_ver=5, properties=props) if packet == publish2r_packet: From f14a47c015e3ba44af7aa9f34c9f72249b01aced Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 22:02:40 +0100 Subject: [PATCH 33/52] Further attempt --- test/broker/11-message-expiry.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/broker/11-message-expiry.py b/test/broker/11-message-expiry.py index 5986e183..d7b107c5 100755 --- a/test/broker/11-message-expiry.py +++ b/test/broker/11-message-expiry.py @@ -75,7 +75,10 @@ try: sock.close() broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port) - time.sleep(2) + if os.environ.get('TRAVIS') is not None: + time.sleep(5) + else: + time.sleep(2) sock = mosq_test.do_client_connect(connect_packet, connack2_packet, timeout=20, port=port) packet = sock.recv(len(publish2s_packet)) From 587debc0132f733f6ec33187b4d4ad4a3e007f17 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 31 May 2019 22:36:09 +0100 Subject: [PATCH 34/52] Fix incoming/outgoing quota problems for QoS>0. --- ChangeLog.txt | 1 + src/database.c | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 9f2f71ea..1e17d3d2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -28,6 +28,7 @@ Broker: - Fix MQTT v5 overlapping subscription behaviour. Clients now receive message from all matching subscriptions rather than the first one encountered, which ensures the maximum QoS requirement is met. +- Fix incoming/outgoing quota problems for QoS>0. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/src/database.c b/src/database.c index 482e210f..87daf68c 100644 --- a/src/database.c +++ b/src/database.c @@ -291,6 +291,9 @@ void db__message_dequeue_first(struct mosquitto *context, struct mosquitto_msg_d msg = msg_data->queued; DL_DELETE(msg_data->queued, msg); DL_APPEND(msg_data->inflight, msg); + if(msg_data->inflight_quota > 0){ + msg_data->inflight_quota--; + } } @@ -757,9 +760,7 @@ int db__message_reconnect_reset_outgoing(struct mosquitto_db *db, struct mosquit if(msg->qos > 0){ context->msgs_out.msg_count12++; context->msgs_out.msg_bytes12 += msg->store->payloadlen; - if(context->msgs_out.inflight_quota > 0){ - context->msgs_out.inflight_quota--; - } + util__decrement_receive_quota(context); } switch(msg->qos){ @@ -828,9 +829,7 @@ int db__message_reconnect_reset_incoming(struct mosquitto_db *db, struct mosquit if(msg->qos > 0){ context->msgs_in.msg_count12++; context->msgs_in.msg_bytes12 += msg->store->payloadlen; - if(context->msgs_in.inflight_quota > 0){ - context->msgs_in.inflight_quota--; - } + util__decrement_receive_quota(context); } if(msg->qos != 2){ @@ -1107,7 +1106,7 @@ int db__message_write(struct mosquitto_db *db, struct mosquitto *context) } DL_FOREACH_SAFE(context->msgs_in.queued, tail, tmp){ - if(context->msgs_out.inflight_maximum != 0 && msg_count >= context->msgs_out.inflight_maximum){ + if(context->msgs_out.inflight_maximum != 0 && context->msgs_in.inflight_quota == 0){ break; } @@ -1126,7 +1125,7 @@ int db__message_write(struct mosquitto_db *db, struct mosquitto *context) } DL_FOREACH_SAFE(context->msgs_out.queued, tail, tmp){ - if(context->msgs_out.inflight_maximum != 0 && msg_count >= context->msgs_out.inflight_maximum){ + if(context->msgs_out.inflight_maximum != 0 && context->msgs_out.inflight_quota == 0){ break; } From c6291034c5da039c0013a966f75aba2866836729 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sat, 1 Jun 2019 11:17:45 +0100 Subject: [PATCH 35/52] Disable tests for cmake. --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e58d072c..825953f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,4 +116,3 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libmosquittopp.pc" DESTINATION "${CMA # Testing # ======================================== enable_testing() -add_test("test" make -C ${mosquitto_SOURCE_DIR}/test test) From 24ec29237d42df2582c57e2abe5607c8db83d992 Mon Sep 17 00:00:00 2001 From: Daniel d'Andrada Date: Tue, 4 Jun 2019 10:02:58 +0200 Subject: [PATCH 36/52] Fix #include guard in config.h Signed-off-by: Daniel d'Andrada --- config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/config.h b/config.h index b7a7616d..3225d858 100644 --- a/config.h +++ b/config.h @@ -1,4 +1,5 @@ #ifndef CONFIG_H +#define CONFIG_H /* ============================================================ * Platform options * ============================================================ */ From 097045176261d2a706359120b1ba4ba53310a193 Mon Sep 17 00:00:00 2001 From: Daniel d'Andrada Date: Thu, 6 Jun 2019 15:04:14 +0200 Subject: [PATCH 37/52] pthread_cancel() is not available on Android Thus mosquitto_loop_start() and mosquitto_loop_stop() won't be available there (and mosquitto_connect_async() as a consequence). Signed-off-by: Daniel d'Andrada --- config.h | 5 +++++ lib/mosquitto.c | 2 ++ lib/thread_mosq.c | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/config.h b/config.h index b7a7616d..4fd2ae4d 100644 --- a/config.h +++ b/config.h @@ -60,4 +60,9 @@ #define UNUSED(A) (void)(A) +/* Android Bionic libpthread implementation doesn't have pthread_cancel */ +#ifndef ANDROID +# define HAVE_PTHREAD_CANCEL +#endif + #endif diff --git a/lib/mosquitto.c b/lib/mosquitto.c index ed71604d..4b5768f3 100644 --- a/lib/mosquitto.c +++ b/lib/mosquitto.c @@ -201,11 +201,13 @@ void mosquitto__destroy(struct mosquitto *mosq) if(!mosq) return; #ifdef WITH_THREADING +# ifdef HAVE_PTHREAD_CANCEL if(mosq->threaded == mosq_ts_self && !pthread_equal(mosq->thread_id, pthread_self())){ pthread_cancel(mosq->thread_id); pthread_join(mosq->thread_id, NULL); mosq->threaded = mosq_ts_none; } +# endif if(mosq->id){ /* If mosq->id is not NULL then the client has already been initialised diff --git a/lib/thread_mosq.c b/lib/thread_mosq.c index 39f6e353..7bde453d 100644 --- a/lib/thread_mosq.c +++ b/lib/thread_mosq.c @@ -27,7 +27,7 @@ void *mosquitto__thread_main(void *obj); int mosquitto_loop_start(struct mosquitto *mosq) { -#ifdef WITH_THREADING +#if defined(WITH_THREADING) && defined(HAVE_PTHREAD_CANCEL) if(!mosq || mosq->threaded != mosq_ts_none) return MOSQ_ERR_INVAL; mosq->threaded = mosq_ts_self; @@ -43,7 +43,7 @@ int mosquitto_loop_start(struct mosquitto *mosq) int mosquitto_loop_stop(struct mosquitto *mosq, bool force) { -#ifdef WITH_THREADING +#if defined(WITH_THREADING) && defined(HAVE_PTHREAD_CANCEL) # ifndef WITH_BROKER char sockpair_data = 0; # endif From 4d54a51c62755ebb2c73ecc895698bab8215502d Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 11:23:00 +0100 Subject: [PATCH 38/52] Stop some error messages being printed even when `--quiet` was used. Thanks to Rob de Jonge. Closes #1284. --- ChangeLog.txt | 3 +-- client/client_shared.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 1e17d3d2..8796b5e1 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -43,8 +43,6 @@ Clients: - Fix mosquitto_pub not using the `-c` option. Closes #1273. - Fix MQTT v5 clients not being able to specify a password without a username. Closes #1274. - -Clients: - Fix `mosquitto_pub -l` not handling network failures. Closes #1152. - Fix double free on exit in mosquitto_pub. Closes #1280. @@ -54,6 +52,7 @@ Documentation: Build: - CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294. +======= 1.6.2 - 20190430 diff --git a/client/client_shared.c b/client/client_shared.c index ede8baa1..69d2dc36 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -1081,8 +1081,8 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg) } cfg->will_props = NULL; - if((cfg->username || cfg->password) && mosquitto_username_pw_set(mosq, cfg->username, cfg->password)){ - err_printf(cfg, "Error: Problem setting username and/or password.\n"); + if(cfg->username && mosquitto_username_pw_set(mosq, cfg->username, cfg->password)){ + err_printf(cfg, "Error: Problem setting username and password.\n"); mosquitto_lib_cleanup(); return 1; } From 289de1f8c87ae70c9edfb34dab1aa325ff3c62bc Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 11:39:19 +0100 Subject: [PATCH 39/52] Fix mosquitto_pub exiting with error code 0 when an error occurred. Thanks to janniswarnat. Closes #1285. --- ChangeLog.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 8796b5e1..aee9d648 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -52,7 +52,6 @@ Documentation: Build: - CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294. -======= 1.6.2 - 20190430 From 6d71d4b5c414a7b7f6c5ef1071e51ddd4a673ed3 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 18:42:22 +0100 Subject: [PATCH 40/52] Fix typo causing build error on Windows when building without TLS support. Thanks to TimmvonderMehden. Closes #1264. --- ChangeLog.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index aee9d648..750b8009 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -30,6 +30,10 @@ Broker: ensures the maximum QoS requirement is met. - Fix incoming/outgoing quota problems for QoS>0. +Client library: +- Fix typo causing build error on Windows when building without TLS support. + Closes #1264. + Client library: - Fix typo causing build error on Windows when building without TLS support. Closes #1264. From 3e858c19c1f79c0b3731a1c2206e62143e3b1058 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 18:50:05 +0100 Subject: [PATCH 41/52] Improve documentation around the upgrading of persistence files. Thanks to jsaak. Closes #1276. --- ChangeLog.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 750b8009..aee9d648 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -30,10 +30,6 @@ Broker: ensures the maximum QoS requirement is met. - Fix incoming/outgoing quota problems for QoS>0. -Client library: -- Fix typo causing build error on Windows when building without TLS support. - Closes #1264. - Client library: - Fix typo causing build error on Windows when building without TLS support. Closes #1264. From 31f448f35a7cd5bacd5dcc8c1dcc243fcf222d93 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 21 May 2019 23:56:22 +0100 Subject: [PATCH 42/52] Fix MQTT v5 clients not being able to specify a password without a username. Thanks to Erik Moqvist. Closes #1274. --- client/client_shared.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/client_shared.c b/client/client_shared.c index 69d2dc36..ede8baa1 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -1081,8 +1081,8 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg) } cfg->will_props = NULL; - if(cfg->username && mosquitto_username_pw_set(mosq, cfg->username, cfg->password)){ - err_printf(cfg, "Error: Problem setting username and password.\n"); + if((cfg->username || cfg->password) && mosquitto_username_pw_set(mosq, cfg->username, cfg->password)){ + err_printf(cfg, "Error: Problem setting username and/or password.\n"); mosquitto_lib_cleanup(); return 1; } From 6b6ea3de163c50b89ee3aa7626f1cf87db00921c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 22 May 2019 09:45:02 +0100 Subject: [PATCH 43/52] Remove old man page references. Thanks to Karl Palsson. Closes #1266. --- ChangeLog.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index aee9d648..6f5a8c09 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -53,6 +53,10 @@ Documentation: Build: - CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294. +Documentation: +- Remove references to Python binding and C++ wrapper in libmosquitto man + page. Closes #1266. + 1.6.2 - 20190430 ================ From 85388c01cc050eb81458c71e252f31608808ce9f Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 15:06:56 +0100 Subject: [PATCH 44/52] CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294. Thanks to Lucas Ramage. --- ChangeLog.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 6f5a8c09..6c4b4262 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -57,6 +57,9 @@ Documentation: - Remove references to Python binding and C++ wrapper in libmosquitto man page. Closes #1266. +Build: +- CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294. + 1.6.2 - 20190430 ================ From 1fa182d160db105975d360cadcd7bcf535e53c69 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 29 May 2019 15:40:17 +0100 Subject: [PATCH 45/52] Fix incorrect shared subscription topic of '$shared.' --- ChangeLog.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 6c4b4262..aee9d648 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -53,13 +53,6 @@ Documentation: Build: - CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294. -Documentation: -- Remove references to Python binding and C++ wrapper in libmosquitto man - page. Closes #1266. - -Build: -- CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294. - 1.6.2 - 20190430 ================ From 9dc319c18316cd70f9f49814b6cb292271947667 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 4 Jun 2019 21:48:58 +0100 Subject: [PATCH 46/52] Remove obsolete `store_clean_interval` from documentation. --- ChangeLog.txt | 1 + man/mosquitto.conf.5.xml | 13 ------------- mosquitto.conf | 8 -------- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index aee9d648..4734e6f6 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -29,6 +29,7 @@ Broker: from all matching subscriptions rather than the first one encountered, which ensures the maximum QoS requirement is met. - Fix incoming/outgoing quota problems for QoS>0. +- Remove obsolete `store_clean_interval` from documentation. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index a2145b21..3a9bb7f7 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -813,19 +813,6 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S Reloaded on reload signal. - - seconds - - The integer number of seconds between the internal - message store being cleaned of messages that are no - longer referenced. Lower values will result in lower - memory usage but more processor time, higher values - will have the opposite effect. Setting a value of 0 - means the unreferenced messages will be disposed of as - quickly as possible. Defaults to 10 seconds. - Reloaded on reload signal. - - seconds diff --git a/mosquitto.conf b/mosquitto.conf index a2b845bb..c12193fe 100644 --- a/mosquitto.conf +++ b/mosquitto.conf @@ -178,14 +178,6 @@ # of packets being sent. #set_tcp_nodelay false -# Time in seconds between cleaning the internal message store of -# unreferenced messages. Lower values will result in lower memory -# usage but more processor time, higher values will have the -# opposite effect. -# Setting a value of 0 means the unreferenced messages will be -# disposed of as quickly as possible. -#store_clean_interval 10 - # Time in seconds between updates of the $SYS tree. # Set to 0 to disable the publishing of the $SYS tree. #sys_interval 10 From c685b7ecf4e65df21ea7d3fef242a64d20366a50 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 6 Jun 2019 23:20:16 +0100 Subject: [PATCH 47/52] Fix `mosquitto_pub -l` not handling zero length input. Closes #1302. Thanks to Marcus Watkins. --- ChangeLog.txt | 1 + client/pub_shared.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 4734e6f6..20f79dd6 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -45,6 +45,7 @@ Clients: - Fix MQTT v5 clients not being able to specify a password without a username. Closes #1274. - Fix `mosquitto_pub -l` not handling network failures. Closes #1152. +- Fix `mosquitto_pub -l` not handling zero length input. Closes #1302. - Fix double free on exit in mosquitto_pub. Closes #1280. Documentation: diff --git a/client/pub_shared.c b/client/pub_shared.c index e1de3f0a..008bef4e 100644 --- a/client/pub_shared.c +++ b/client/pub_shared.c @@ -36,7 +36,7 @@ Contributors: /* Global variables for use in callbacks. See sub_client.c for an example of * using a struct to hold variables for use in callbacks. */ -int mid_sent = 0; +int mid_sent = -1; int status = STATUS_CONNECTING; struct mosq_config cfg; From af7760f1b6f401a940404953a91883fa4f303260 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 13 Jun 2019 16:23:55 +0100 Subject: [PATCH 48/52] Fix build for WITH_SOCKS=no. --- client/client_shared.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/client_shared.c b/client/client_shared.c index ede8baa1..7d3ba773 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -1434,6 +1434,7 @@ cleanup: if(port) free(port); return 1; } +#endif void err_printf(const struct mosq_config *cfg, const char *fmt, ...) { @@ -1446,4 +1447,3 @@ void err_printf(const struct mosq_config *cfg, const char *fmt, ...) va_end(va); } -#endif From 1d6aa9f69cf10960baeab21839441578dba05e3a Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 13 Jun 2019 16:24:52 +0100 Subject: [PATCH 49/52] Bump version and web pages. --- CMakeLists.txt | 2 +- ChangeLog.txt | 2 +- config.mk | 2 +- installer/mosquitto.nsi | 2 +- installer/mosquitto64.nsi | 2 +- lib/mosquitto.h | 2 +- set-version.sh | 2 +- snap/snapcraft.yaml | 2 +- www/pages/download.md | 6 +- www/posts/2019/06/version-1-6-3-released.md | 84 +++++++++++++++++++ .../mosquitto/templates/base_helper.tmpl | 10 --- 11 files changed, 95 insertions(+), 21 deletions(-) create mode 100644 www/posts/2019/06/version-1-6-3-released.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 825953f1..e707229b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ project(mosquitto) cmake_minimum_required(VERSION 2.8) # Only for version 3 and up. cmake_policy(SET CMP0042 NEW) -set (VERSION 1.6.2) +set (VERSION 1.6.3) add_definitions (-DCMAKE -DVERSION=\"${VERSION}\") diff --git a/ChangeLog.txt b/ChangeLog.txt index 20f79dd6..103cbe68 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,4 +1,4 @@ -1.6.3 - 201905xx +1.6.3 - 20190613 ================ Broker: diff --git a/config.mk b/config.mk index 6b9660bc..e305d0cd 100644 --- a/config.mk +++ b/config.mk @@ -104,7 +104,7 @@ WITH_COVERAGE:=no # Also bump lib/mosquitto.h, CMakeLists.txt, # installer/mosquitto.nsi, installer/mosquitto64.nsi -VERSION=1.6.2 +VERSION=1.6.3 # Client library SO version. Bump if incompatible API/ABI changes are made. SOVERSION=1 diff --git a/installer/mosquitto.nsi b/installer/mosquitto.nsi index 79d48f97..15cd507d 100644 --- a/installer/mosquitto.nsi +++ b/installer/mosquitto.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.6.2 +!define VERSION 1.6.3 OutFile "mosquitto-${VERSION}-install-windows-x86.exe" InstallDir "$PROGRAMFILES\mosquitto" diff --git a/installer/mosquitto64.nsi b/installer/mosquitto64.nsi index 985c3499..6027fc89 100644 --- a/installer/mosquitto64.nsi +++ b/installer/mosquitto64.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.6.2 +!define VERSION 1.6.3 OutFile "mosquitto-${VERSION}-install-windows-x64.exe" !include "x64.nsh" diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 49217460..09bba66e 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -48,7 +48,7 @@ extern "C" { #define LIBMOSQUITTO_MAJOR 1 #define LIBMOSQUITTO_MINOR 6 -#define LIBMOSQUITTO_REVISION 2 +#define LIBMOSQUITTO_REVISION 3 /* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ #define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) diff --git a/set-version.sh b/set-version.sh index fa0b9e87..0e99da2f 100755 --- a/set-version.sh +++ b/set-version.sh @@ -2,7 +2,7 @@ MAJOR=1 MINOR=6 -REVISION=2 +REVISION=3 sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index ffed4d03..2072c652 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: mosquitto -version: 1.6.2 +version: 1.6.3 summary: Eclipse Mosquitto MQTT broker description: This is a message broker that supports version 3.1 and 3.1.1 of the MQTT protocol. diff --git a/www/pages/download.md b/www/pages/download.md index 3fbe4946..13aa8ddc 100644 --- a/www/pages/download.md +++ b/www/pages/download.md @@ -11,7 +11,7 @@ # Source -* [mosquitto-1.6.2.tar.gz](https://mosquitto.org/files/source/mosquitto-1.6.2.tar.gz) (319kB) ([GPG signature](https://mosquitto.org/files/source/mosquitto-1.6.2.tar.gz.asc)) +* [mosquitto-1.6.3.tar.gz](https://mosquitto.org/files/source/mosquitto-1.6.3.tar.gz) (319kB) ([GPG signature](https://mosquitto.org/files/source/mosquitto-1.6.3.tar.gz.asc)) * [Git source code repository](https://github.com/eclipse/mosquitto) (github.com) Older downloads are available at [https://mosquitto.org/files/](../files/) @@ -24,8 +24,8 @@ distributions. ## Windows -* [mosquitto-1.6.2-install-windows-x64.exe](https://mosquitto.org/files/binary/win64/mosquitto-1.6.2-install-windows-x64.exe) (~360 kB) (64-bit build, Windows Vista and up, built with Visual Studio Community 2017) -* [mosquitto-1.6.2-install-windows-x32.exe](https://mosquitto.org/files/binary/win32/mosquitto-1.6.2-install-windows-x86.exe) (~360 kB) (32-bit build, Windows Vista and up, built with Visual Studio Community 2017) +* [mosquitto-1.6.3-install-windows-x64.exe](https://mosquitto.org/files/binary/win64/mosquitto-1.6.3-install-windows-x64.exe) (~1.4 MB) (64-bit build, Windows Vista and up, built with Visual Studio Community 2017) +* [mosquitto-1.6.3-install-windows-x32.exe](https://mosquitto.org/files/binary/win32/mosquitto-1.6.2-install-windows-x86.exe) (~1.4 MB) (32-bit build, Windows Vista and up, built with Visual Studio Community 2017) See also readme-windows.txt after installing. diff --git a/www/posts/2019/06/version-1-6-3-released.md b/www/posts/2019/06/version-1-6-3-released.md new file mode 100644 index 00000000..b72de4ed --- /dev/null +++ b/www/posts/2019/06/version-1-6-3-released.md @@ -0,0 +1,84 @@ + + +This is a bugfix release. + +## Broker +- Fix detection of incoming v3.1/v3.1.1 bridges. Closes [#1263]. +- Fix default `max_topic_alias` listener config not being copied to the in-use + listener when compiled without TLS support. +- Fix random number generation if compiling using `WITH_TLS=no` and on Linux + with glibc >= 2.25. Without this fix, no random numbers would be generated + for e.g. on broker client id generation, and so clients connecting expecting + this feature would be unable to connect. +- Fix compilation problem related to `getrandom()` on non-glibc systems. +- Fix Will message for a persistent client incorrectly being sent when the + client reconnects after a clean disconnect. Closes [#1273]. +- Fix Will message for a persistent client not being sent on disconnect. + Closes [#1273]. +- Improve documentation around the upgrading of persistence files. Closes + [#1276]. +- Add 'extern "C"' on mosquitto_broker.h and mosquitto_plugin.h for C++ plugin + writing. Closes [#1290]. +- Fix persistent Websockets clients not receiving messages after they + reconnect, having sent DISCONNECT on a previous session. Closes [#1227]. +- Disable TLS renegotiation. Client initiated renegotiation is considered to + be a potential attack vector against servers. Closes [#1257]. +- Fix incorrect shared subscription topic '$shared'. +- Fix zero length client ids being rejected for MQTT v5 clients with clean + start set to true. +- Fix MQTT v5 overlapping subscription behaviour. Clients now receive message + from all matching subscriptions rather than the first one encountered, which + ensures the maximum QoS requirement is met. +- Fix incoming/outgoing quota problems for QoS>0. +- Remove obsolete `store_clean_interval` from documentation. + +## Client library +- Fix typo causing build error on Windows when building without TLS support. + Closes [#1264]. + +## Clients +- Fix -L url parsing when `/topic` part is missing. +- Stop some error messages being printed even when `--quiet` was used. + Closes [#1284]. +- Fix `mosquitto_pub` exiting with error code 0 when an error occurred. + Closes [#1285]. +- Fix `mosquitto_pub` not using the `-c` option. Closes [#1273]. +- Fix MQTT v5 clients not being able to specify a password without a username. + Closes [#1274]. +- Fix `mosquitto_pub -l` not handling network failures. Closes [#1152]. +- Fix `mosquitto_pub -l` not handling zero length input. Closes [#1302]. +- Fix double free on exit in `mosquitto_pub`. Closes [#1280]. + +## Documentation: +- Remove references to Python binding and C++ wrapper in libmosquitto man + page. Closes [#1266]. + +## Build +- CLIENT_LDFLAGS now uses LDFLAGS. Closes [#1294]. + +[#1152]: https://github.com/eclipse/mosquitto/issues/1152 +[#1227]: https://github.com/eclipse/mosquitto/issues/1227 +[#1257]: https://github.com/eclipse/mosquitto/issues/1257 +[#1263]: https://github.com/eclipse/mosquitto/issues/1263 +[#1264]: https://github.com/eclipse/mosquitto/issues/1264 +[#1266]: https://github.com/eclipse/mosquitto/issues/1266 +[#1273]: https://github.com/eclipse/mosquitto/issues/1273 +[#1273]: https://github.com/eclipse/mosquitto/issues/1273 +[#1273]: https://github.com/eclipse/mosquitto/issues/1273 +[#1274]: https://github.com/eclipse/mosquitto/issues/1274 +[#1276]: https://github.com/eclipse/mosquitto/issues/1276 +[#1280]: https://github.com/eclipse/mosquitto/issues/1280 +[#1284]: https://github.com/eclipse/mosquitto/issues/1284 +[#1285]: https://github.com/eclipse/mosquitto/issues/1285 +[#1290]: https://github.com/eclipse/mosquitto/issues/1290 +[#1294]: https://github.com/eclipse/mosquitto/issues/1294 +[#1302]: https://github.com/eclipse/mosquitto/issues/1302 diff --git a/www/themes/mosquitto/templates/base_helper.tmpl b/www/themes/mosquitto/templates/base_helper.tmpl index 98439c1e..d580aa63 100644 --- a/www/themes/mosquitto/templates/base_helper.tmpl +++ b/www/themes/mosquitto/templates/base_helper.tmpl @@ -22,16 +22,6 @@ lang="${lang}"> - - - - % if use_base_tag: % endif From 0a5fbc403ba6d79672ae4ba43d76aea8c29b827b Mon Sep 17 00:00:00 2001 From: Matevz Mihalic Date: Mon, 17 Jun 2019 13:00:27 +0200 Subject: [PATCH 50/52] Fix plugin psk_key_get for v4 Signed-off-by: Matevz Mihalic --- src/security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/security.c b/src/security.c index 8162ae66..2ccd7370 100644 --- a/src/security.c +++ b/src/security.c @@ -752,7 +752,7 @@ int mosquitto_psk_key_get(struct mosquitto_db *db, struct mosquitto *context, co } for(i=0; iauth_plugin_config_count; i++){ - if(opts->auth_plugin_configs[i].plugin.version == 3 + if(opts->auth_plugin_configs[i].plugin.version == 4 && opts->auth_plugin_configs[i].plugin.psk_key_get_v4){ rc = opts->auth_plugin_configs[i].plugin.psk_key_get_v4( From e642bee3364cbd539af0e446fdfe179e7b19ba47 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 18 Jun 2019 11:21:15 +0100 Subject: [PATCH 51/52] Update changelog --- ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 103cbe68..41bab644 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -30,6 +30,7 @@ Broker: ensures the maximum QoS requirement is met. - Fix incoming/outgoing quota problems for QoS>0. - Remove obsolete `store_clean_interval` from documentation. +- Fix v4 authentication plugin never calling psk_key_get. Client library: - Fix typo causing build error on Windows when building without TLS support. From 4f32e94104f34229397550209c2244efb2726285 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 18 Jun 2019 12:44:37 +0100 Subject: [PATCH 52/52] Bump release date. --- ChangeLog.txt | 2 +- www/posts/2019/06/version-1-6-3-released.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 41bab644..6b3f8716 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,4 +1,4 @@ -1.6.3 - 20190613 +1.6.3 - 20190618 ================ Broker: diff --git a/www/posts/2019/06/version-1-6-3-released.md b/www/posts/2019/06/version-1-6-3-released.md index b72de4ed..5edcfff2 100644 --- a/www/posts/2019/06/version-1-6-3-released.md +++ b/www/posts/2019/06/version-1-6-3-released.md @@ -1,7 +1,7 @@