diff --git a/lib/net_mosq.c b/lib/net_mosq.c index 25b4ed6f..c80334da 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -51,6 +51,8 @@ Contributors: #endif #ifdef WITH_TLS +#include +#include #include #include #endif @@ -107,6 +109,9 @@ void _mosquitto_net_init(void) void _mosquitto_net_cleanup(void) { #ifdef WITH_TLS + ERR_remove_state(0); + ENGINE_cleanup(); + CONF_modules_unload(1); ERR_free_strings(); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); diff --git a/src/bridge.c b/src/bridge.c index ec2e9d46..804fe9fb 100644 --- a/src/bridge.c +++ b/src/bridge.c @@ -66,7 +66,7 @@ int mqtt3_bridge_new(struct mosquitto_db *db, struct _mqtt3_bridge *bridge) bridge->clientid = id; } if(bridge->local_clientid){ - local_id = bridge->local_clientid; + local_id = _mosquitto_strdup(bridge->local_clientid); }else{ len = strlen(bridge->clientid) + strlen("local.") + 2; local_id = _mosquitto_malloc(len); @@ -111,7 +111,7 @@ int mqtt3_bridge_new(struct mosquitto_db *db, struct _mqtt3_bridge *bridge) bridge->try_private_accepted = true; - HASH_ADD_KEYPTR(hh_bridge, db->contexts_bridge, new_context->id, strlen(new_context->id), new_context); + HASH_ADD_KEYPTR(hh_bridge, db->contexts_bridge, new_context->bridge->local_clientid, strlen(new_context->bridge->local_clientid), new_context); return mqtt3_bridge_connect(db, new_context); } diff --git a/src/conf.c b/src/conf.c index 9c713d96..0fe6d300 100644 --- a/src/conf.c +++ b/src/conf.c @@ -265,9 +265,13 @@ void mqtt3_config_cleanup(struct mqtt3_config *config) _mosquitto_free(config->bridges[i].topics); } if(config->bridges[i].notification_topic) _mosquitto_free(config->bridges[i].notification_topic); +#ifdef WITH_TLS + if(config->bridges[i].tls_version) _mosquitto_free(config->bridges[i].tls_version); + if(config->bridges[i].tls_cafile) _mosquitto_free(config->bridges[i].tls_cafile); #ifdef REAL_WITH_TLS_PSK if(config->bridges[i].tls_psk_identity) _mosquitto_free(config->bridges[i].tls_psk_identity); if(config->bridges[i].tls_psk) _mosquitto_free(config->bridges[i].tls_psk); +#endif #endif } _mosquitto_free(config->bridges); diff --git a/src/context.c b/src/context.c index 0f219471..31a68cec 100644 --- a/src/context.c +++ b/src/context.c @@ -92,6 +92,9 @@ void mqtt3_context_cleanup(struct mosquitto_db *db, struct mosquitto *context, b { struct _mosquitto_packet *packet; struct mosquitto_client_msg *msg, *next; +#ifdef WITH_BRIDGE + struct mosquitto *ctx_tmp; +#endif if(!context) return; @@ -105,12 +108,27 @@ void mqtt3_context_cleanup(struct mosquitto_db *db, struct mosquitto *context, b } #ifdef WITH_BRIDGE if(context->bridge){ + if(context->bridge->local_clientid){ + HASH_FIND(hh_bridge, db->contexts_bridge, context->bridge->local_clientid, strlen(context->bridge->local_clientid), ctx_tmp); + if(ctx_tmp){ + HASH_DELETE(hh_bridge, db->contexts_bridge, context); + } + } if(context->bridge->username){ context->bridge->username = NULL; } if(context->bridge->password){ context->bridge->password = NULL; } + if(context->bridge->local_username){ + context->bridge->local_username = NULL; + } + if(context->bridge->local_password){ + context->bridge->local_password = NULL; + } + if(context->bridge->local_clientid){ + context->bridge->local_clientid = NULL; + } } #endif _mosquitto_socket_close(db, context); diff --git a/src/mosquitto.c b/src/mosquitto.c index fe09509d..8917817a 100644 --- a/src/mosquitto.c +++ b/src/mosquitto.c @@ -333,8 +333,16 @@ int main(int argc, char *argv[]) HASH_ITER(hh_id, int_db.contexts_by_id, ctxt, ctxt_tmp){ mqtt3_context_cleanup(&int_db, ctxt, true); } - HASH_CLEAR(hh_sock, int_db.contexts_by_sock); - HASH_CLEAR(hh_bridge, int_db.contexts_bridge); + HASH_ITER(hh_sock, int_db.contexts_by_sock, ctxt, ctxt_tmp){ + mqtt3_context_cleanup(&int_db, ctxt, true); + } + HASH_ITER(hh_bridge, int_db.contexts_bridge, ctxt, ctxt_tmp){ + mqtt3_context_cleanup(&int_db, ctxt, true); + } + HASH_ITER(hh_for_free, int_db.contexts_for_free, ctxt, ctxt_tmp){ + HASH_DELETE(hh_for_free, int_db.contexts_for_free, ctxt); + mqtt3_context_cleanup(&int_db, ctxt, true); + } mqtt3_db_close(&int_db); if(listensock){ @@ -356,8 +364,8 @@ int main(int argc, char *argv[]) remove(config.pid_file); } - _mosquitto_net_cleanup(); mqtt3_config_cleanup(int_db.config); + _mosquitto_net_cleanup(); return rc; } diff --git a/src/net.c b/src/net.c index 8d7f35c1..d9787b65 100644 --- a/src/net.c +++ b/src/net.c @@ -211,15 +211,22 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned if(!psk_key) return 0; if(mosquitto_psk_key_get(db, psk_hint, identity, psk_key, max_psk_len*2) != MOSQ_ERR_SUCCESS){ + _mosquitto_free(psk_key); return 0; } len = _mosquitto_hex2bin(psk_key, psk, max_psk_len); - if (len < 0) return 0; + if (len < 0){ + _mosquitto_free(psk_key); + return 0; + } if(listener->use_identity_as_username){ context->username = _mosquitto_strdup(identity); - if(!context->username) return 0; + if(!context->username){ + _mosquitto_free(psk_key); + return 0; + } } return len; diff --git a/src/read_handle_server.c b/src/read_handle_server.c index 4b4516a7..dcf2788f 100644 --- a/src/read_handle_server.c +++ b/src/read_handle_server.c @@ -102,20 +102,24 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) /* Don't accept multiple CONNECT commands. */ if(context->state != mosq_cs_new){ - mqtt3_context_disconnect(db, context); - return MOSQ_ERR_PROTOCOL; + rc = MOSQ_ERR_PROTOCOL; + goto handle_connect_error; } if(_mosquitto_read_string(&context->in_packet, &protocol_name)){ - mqtt3_context_disconnect(db, context); + rc = 1; + goto handle_connect_error; return 1; } if(!protocol_name){ - mqtt3_context_disconnect(db, context); + rc = 3; + goto handle_connect_error; return 3; } if(_mosquitto_read_byte(&context->in_packet, &protocol_version)){ - mqtt3_context_disconnect(db, context); + HASH_ADD_KEYPTR(hh_for_free, db->contexts_for_free, context, sizeof(context), context); + rc = 1; + goto handle_connect_error; return 1; } if(!strcmp(protocol_name, PROTOCOL_NAME_v31)){ @@ -125,9 +129,9 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) protocol_version, context->address); } _mosquitto_send_connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION); - mqtt3_context_disconnect(db, context); _mosquitto_free(protocol_name); - return MOSQ_ERR_PROTOCOL; + rc = MOSQ_ERR_PROTOCOL; + goto handle_connect_error; } context->protocol = mosq_p_mqtt31; }else if(!strcmp(protocol_name, PROTOCOL_NAME_v311)){ @@ -137,15 +141,15 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) protocol_version, context->address); } _mosquitto_send_connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION); - mqtt3_context_disconnect(db, context); _mosquitto_free(protocol_name); - return MOSQ_ERR_PROTOCOL; + rc = MOSQ_ERR_PROTOCOL; + goto handle_connect_error; } if((context->in_packet.command&0x0F) != 0x00){ /* Reserved flags not set to 0, must disconnect. */ - mqtt3_context_disconnect(db, context); _mosquitto_free(protocol_name); - return MOSQ_ERR_PROTOCOL; + rc = MOSQ_ERR_PROTOCOL; + goto handle_connect_error; } context->protocol = mosq_p_mqtt311; }else{ @@ -154,14 +158,14 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) protocol_name, context->address); } _mosquitto_free(protocol_name); - mqtt3_context_disconnect(db, context); - return MOSQ_ERR_PROTOCOL; + rc = MOSQ_ERR_PROTOCOL; + goto handle_connect_error; } _mosquitto_free(protocol_name); if(_mosquitto_read_byte(&context->in_packet, &connect_flags)){ - mqtt3_context_disconnect(db, context); - return 1; + rc = 1; + goto handle_connect_error; } clean_session = (connect_flags & 0x02) >> 1; will = connect_flags & 0x04; @@ -169,42 +173,41 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) if(will_qos == 3){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Invalid Will QoS in CONNECT from %s.", context->address); - mqtt3_context_disconnect(db, context); - return MOSQ_ERR_PROTOCOL; + rc = MOSQ_ERR_PROTOCOL; + goto handle_connect_error; } will_retain = connect_flags & 0x20; password_flag = connect_flags & 0x40; username_flag = connect_flags & 0x80; if(_mosquitto_read_uint16(&context->in_packet, &(context->keepalive))){ - mqtt3_context_disconnect(db, context); - return 1; + rc = 1; + goto handle_connect_error; } if(_mosquitto_read_string(&context->in_packet, &client_id)){ - mqtt3_context_disconnect(db, context); - return 1; + rc = 1; + goto handle_connect_error; } slen = strlen(client_id); if(slen == 0){ if(context->protocol == mosq_p_mqtt31){ - _mosquitto_free(client_id); _mosquitto_send_connack(context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED); - mqtt3_context_disconnect(db, context); - return MOSQ_ERR_PROTOCOL; + rc = MOSQ_ERR_PROTOCOL; + goto handle_connect_error; }else{ /* mqtt311 */ _mosquitto_free(client_id); if(clean_session == 0 || db->config->allow_zero_length_clientid == false){ _mosquitto_send_connack(context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED); - mqtt3_context_disconnect(db, context); - return MOSQ_ERR_PROTOCOL; + rc = MOSQ_ERR_PROTOCOL; + goto handle_connect_error; }else{ client_id = client_id_gen(db); if(!client_id){ - mqtt3_context_disconnect(db, context); - return MOSQ_ERR_NOMEM; + rc = MOSQ_ERR_NOMEM; + goto handle_connect_error; } } } @@ -213,52 +216,44 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) /* clientid_prefixes check */ if(db->config->clientid_prefixes){ if(strncmp(db->config->clientid_prefixes, client_id, strlen(db->config->clientid_prefixes))){ - _mosquitto_free(client_id); _mosquitto_send_connack(context, 0, CONNACK_REFUSED_NOT_AUTHORIZED); - mqtt3_context_disconnect(db, context); - return MOSQ_ERR_SUCCESS; + rc = MOSQ_ERR_SUCCESS; + goto handle_connect_error; } } if(will){ will_struct = _mosquitto_calloc(1, sizeof(struct mosquitto_message)); if(!will_struct){ - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_NOMEM; goto handle_connect_error; } if(_mosquitto_read_string(&context->in_packet, &will_topic)){ - mqtt3_context_disconnect(db, context); rc = 1; goto handle_connect_error; } if(strlen(will_topic) == 0){ - mqtt3_context_disconnect(db, context); rc = 1; goto handle_connect_error; } if(_mosquitto_pub_topic_check(will_topic)){ - mqtt3_context_disconnect(db, context); rc = 1; goto handle_connect_error; } if(_mosquitto_read_uint16(&context->in_packet, &will_payloadlen)){ - mqtt3_context_disconnect(db, context); rc = 1; goto handle_connect_error; } if(will_payloadlen > 0){ will_payload = _mosquitto_malloc(will_payloadlen); if(!will_payload){ - mqtt3_context_disconnect(db, context); rc = 1; goto handle_connect_error; } rc = _mosquitto_read_bytes(&context->in_packet, will_payload, will_payloadlen); if(rc){ - mqtt3_context_disconnect(db, context); rc = 1; goto handle_connect_error; } @@ -266,7 +261,6 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) }else{ if(context->protocol == mosq_p_mqtt311){ if(will_qos != 0 || will_retain != 0){ - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; } @@ -286,7 +280,6 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) /* Password flag given, but no password. Ignore. */ password_flag = 0; }else if(context->protocol == mosq_p_mqtt311){ - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; } @@ -300,7 +293,6 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) /* Username flag given, but no username. Ignore. */ username_flag = 0; }else if(context->protocol == mosq_p_mqtt311){ - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; } @@ -309,7 +301,6 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) if(context->protocol == mosq_p_mqtt311){ if(password_flag){ /* username_flag == 0 && password_flag == 1 is forbidden */ - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; } @@ -320,7 +311,6 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) if(context->listener && context->listener->ssl_ctx && context->listener->use_identity_as_username){ if(!context->ssl){ _mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_SUCCESS; goto handle_connect_error; } @@ -329,7 +319,6 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) /* Client should have provided an identity to get this far. */ if(!context->username){ _mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_SUCCESS; goto handle_connect_error; } @@ -338,14 +327,12 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) client_cert = SSL_get_peer_certificate(context->ssl); if(!client_cert){ _mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_SUCCESS; goto handle_connect_error; } name = X509_get_subject_name(client_cert); if(!name){ _mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_SUCCESS; goto handle_connect_error; } @@ -353,7 +340,6 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) i = X509_NAME_get_index_by_NID(name, NID_commonName, -1); if(i == -1){ _mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_SUCCESS; goto handle_connect_error; } @@ -372,7 +358,6 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) rc = mosquitto_unpwd_check(db, username, password); if(rc == MOSQ_ERR_AUTH){ _mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_SUCCESS; goto handle_connect_error; }else if(rc == MOSQ_ERR_INVAL){ @@ -386,7 +371,6 @@ int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context) if(!username_flag && db->config->allow_anonymous == false){ _mosquitto_send_connack(context, 0, CONNACK_REFUSED_NOT_AUTHORIZED); - mqtt3_context_disconnect(db, context); rc = MOSQ_ERR_SUCCESS; goto handle_connect_error; } @@ -558,6 +542,10 @@ handle_connect_error: if(will_payload) _mosquitto_free(will_payload); if(will_topic) _mosquitto_free(will_topic); if(will_struct) _mosquitto_free(will_struct); + if(context){ + mqtt3_context_disconnect(db, context); + HASH_ADD_KEYPTR(hh_for_free, db->contexts_for_free, context, sizeof(context), context); + } return rc; } diff --git a/test/broker/06-bridge-reconnect-local-out.py b/test/broker/06-bridge-reconnect-local-out.py index f72a4858..abd8c19f 100755 --- a/test/broker/06-bridge-reconnect-local-out.py +++ b/test/broker/06-bridge-reconnect-local-out.py @@ -36,6 +36,7 @@ broker = mosq_test.start_broker(filename=os.path.basename(__file__), cmd=cmd) local_cmd = ['../../src/mosquitto', '-c', '06-bridge-reconnect-local-out.conf'] local_broker = mosq_test.start_broker(cmd=local_cmd, filename=os.path.basename(__file__)+'_local1') +time.sleep(0.5) local_broker.terminate() local_broker.wait() local_broker = mosq_test.start_broker(cmd=local_cmd, filename=os.path.basename(__file__)+'_local2') diff --git a/test/broker/08-ssl-connect-cert-auth-crl.conf b/test/broker/08-ssl-connect-cert-auth-crl.conf index 93353d6d..31c36512 100644 --- a/test/broker/08-ssl-connect-cert-auth-crl.conf +++ b/test/broker/08-ssl-connect-cert-auth-crl.conf @@ -1,9 +1,9 @@ -port 1888 +port 1889 +listener 1888 cafile ../ssl/all-ca.crt certfile ../ssl/server.crt keyfile ../ssl/server.key require_certificate true crlfile ../ssl/crl.pem -listener 1889 diff --git a/test/broker/08-ssl-connect-cert-auth-expired.conf b/test/broker/08-ssl-connect-cert-auth-expired.conf index 8c55017a..c85c24fd 100644 --- a/test/broker/08-ssl-connect-cert-auth-expired.conf +++ b/test/broker/08-ssl-connect-cert-auth-expired.conf @@ -1,8 +1,8 @@ -port 1888 +port 1889 +listener 1888 cafile ../ssl/all-ca.crt certfile ../ssl/server.crt keyfile ../ssl/server.key require_certificate true -listener 1889 diff --git a/test/broker/08-ssl-connect-cert-auth-expired.py b/test/broker/08-ssl-connect-cert-auth-expired.py index 2765f743..6761d643 100755 --- a/test/broker/08-ssl-connect-cert-auth-expired.py +++ b/test/broker/08-ssl-connect-cert-auth-expired.py @@ -41,6 +41,7 @@ try: broker.terminate() raise ValueError(err.errno) finally: + time.sleep(0.5) broker.terminate() broker.wait() if rc: diff --git a/test/broker/08-ssl-connect-cert-auth-revoked.py b/test/broker/08-ssl-connect-cert-auth-revoked.py index 65e952c1..0b246550 100755 --- a/test/broker/08-ssl-connect-cert-auth-revoked.py +++ b/test/broker/08-ssl-connect-cert-auth-revoked.py @@ -40,6 +40,7 @@ try: raise ValueError(err.errno) finally: + time.sleep(0.5) broker.terminate() broker.wait() if rc: diff --git a/test/broker/08-ssl-connect-cert-auth-without.py b/test/broker/08-ssl-connect-cert-auth-without.py index 54599fec..a2fdebba 100755 --- a/test/broker/08-ssl-connect-cert-auth-without.py +++ b/test/broker/08-ssl-connect-cert-auth-without.py @@ -41,6 +41,7 @@ except socket.error as err: if err.errno == errno.ECONNRESET: rc = 0 +time.sleep(0.5) broker.terminate() broker.wait() if rc: diff --git a/test/broker/08-ssl-connect-identity.conf b/test/broker/08-ssl-connect-identity.conf index fcc5f1a5..37a59e38 100644 --- a/test/broker/08-ssl-connect-identity.conf +++ b/test/broker/08-ssl-connect-identity.conf @@ -1,9 +1,9 @@ -port 1888 +port 1889 +listener 1888 cafile ../ssl/all-ca.crt certfile ../ssl/server.crt keyfile ../ssl/server.key use_identity_as_username true -listener 1889 diff --git a/test/broker/08-ssl-connect-identity.py b/test/broker/08-ssl-connect-identity.py index c929a922..8119eb7f 100755 --- a/test/broker/08-ssl-connect-identity.py +++ b/test/broker/08-ssl-connect-identity.py @@ -38,6 +38,7 @@ try: ssock.close() finally: + time.sleep(0.5) broker.terminate() broker.wait() if rc: diff --git a/test/broker/08-ssl-connect-no-auth-wrong-ca.conf b/test/broker/08-ssl-connect-no-auth-wrong-ca.conf index dba44524..28de36ac 100644 --- a/test/broker/08-ssl-connect-no-auth-wrong-ca.conf +++ b/test/broker/08-ssl-connect-no-auth-wrong-ca.conf @@ -1,7 +1,7 @@ -port 1888 +port 1889 +listener 1888 cafile ../ssl/all-ca.crt certfile ../ssl/server.crt keyfile ../ssl/server.key -listener 1889 diff --git a/test/broker/08-ssl-connect-no-auth-wrong-ca.py b/test/broker/08-ssl-connect-no-auth-wrong-ca.py index 51005182..dc6e7829 100755 --- a/test/broker/08-ssl-connect-no-auth-wrong-ca.py +++ b/test/broker/08-ssl-connect-no-auth-wrong-ca.py @@ -38,6 +38,7 @@ except ssl.SSLError as err: finally: ssock.close() +time.sleep(0.5) broker.terminate() broker.wait if rc: diff --git a/test/broker/08-ssl-connect-no-identity.conf b/test/broker/08-ssl-connect-no-identity.conf index fcc5f1a5..37a59e38 100644 --- a/test/broker/08-ssl-connect-no-identity.conf +++ b/test/broker/08-ssl-connect-no-identity.conf @@ -1,9 +1,9 @@ -port 1888 +port 1889 +listener 1888 cafile ../ssl/all-ca.crt certfile ../ssl/server.crt keyfile ../ssl/server.key use_identity_as_username true -listener 1889