diff --git a/ChangeLog.txt b/ChangeLog.txt index e5390dfd7..f766a9cf2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -77,6 +77,7 @@ Broker: - Add suport for PROXY protocol v1 and v2. - Log message if a client attempts to connect with TLS to a non-TLS listener. - Add `listener_allow_anonymous` option. +- Add `listener_auto_id_prefix` ` option. Plugins / plugin interface: - Add persist-sqlite plugin. diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index adcfd7c2c..fc6296941 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -361,6 +361,9 @@ prefix + + This option is deprecated, please use instead. + If is true, this option allows you to set a string that will be prefixed to the @@ -1419,6 +1422,19 @@ accept_protocol_versions 3, 4 Not reloaded on reload signal. + + prefix + + + This option allows you to set a string that will be prefixed + to the automatically generated client ids (i.e. for when a + client connects without providing a client id) to aid + visibility in logs. Defaults to . + + + Not reloaded on reload signal. + + count diff --git a/mosquitto.conf b/mosquitto.conf index 5d4ffd1be..5ae4d900a 100644 --- a/mosquitto.conf +++ b/mosquitto.conf @@ -22,7 +22,7 @@ # acl_file # allow_anonymous - use listener_allow_anonymous instead # allow_zero_length_clientid -# auto_id_prefix +# auto_id_prefix - use listener_auto_id_prefix instead # password_file # plugin - use plugin_load and plugin_use instead # plugin_opt_* @@ -325,6 +325,12 @@ # value set by listener_allow_anonymous will always take priority. #listener_allow_anonymous +# This option allows you to set a prefix to automatically generated client ids +# (i.e. for when a client connects without providing a client id) to aid +# visibility in logs. +# Defaults to 'auto-' +#listener_auto_id_prefix auto- + # Set use_username_as_clientid to true to replace the clientid that a client # connected with with its username. This allows authentication to be tied to # the clientid, which means that it is possible to prevent one client diff --git a/src/conf.c b/src/conf.c index 21dc19b7f..2dfe32ac8 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1137,6 +1137,7 @@ static int config__read_file_core(struct mosquitto__config *config, bool reload, if(config__plugin_add_secopt(cur_plugin, cur_listener->security_options)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "auto_id_prefix")){ REQUIRE_LISTENER_IF_PER_LISTENER(token); + OPTION_DEPRECATED(token, "Please use 'listener_auto_id_prefix' instead."); conf__set_cur_security_options(config, &cur_listener, &cur_security_options, token); if(conf__parse_string(&token, "auto_id_prefix", &cur_security_options->auto_id_prefix, &saveptr)) return MOSQ_ERR_INVAL; if(cur_security_options->auto_id_prefix){ @@ -1794,6 +1795,14 @@ static int config__read_file_core(struct mosquitto__config *config, bool reload, }else if(!strcmp(token, "listener_allow_anonymous")){ REQUIRE_LISTENER(token); if(conf__parse_bool(&token, "listener_allow_anonymous", (bool *)&cur_listener->security_options->allow_anonymous, &saveptr)) return MOSQ_ERR_INVAL; + }else if(!strcmp(token, "listener_auto_id_prefix")){ + REQUIRE_LISTENER(token); + if(conf__parse_string(&token, "listener_auto_id_prefix", &cur_listener->security_options->auto_id_prefix, &saveptr)) return MOSQ_ERR_INVAL; + if(cur_listener->security_options->auto_id_prefix){ + cur_listener->security_options->auto_id_prefix_len = (uint16_t)strlen(cur_listener->security_options->auto_id_prefix); + }else{ + cur_listener->security_options->auto_id_prefix_len = 0; + } }else if(!strcmp(token, "local_clientid")){ #ifdef WITH_BRIDGE REQUIRE_BRIDGE(token); @@ -2555,24 +2564,24 @@ static int config__check(struct mosquitto__config *config) { /* Checks that are easy to make after the config has been loaded. */ + const char *id_prefix; + int id_prefix_len; + if(config->security_options.auto_id_prefix){ + id_prefix = config->security_options.auto_id_prefix; + id_prefix_len = config->security_options.auto_id_prefix_len; + }else{ + id_prefix = "auto-"; + id_prefix_len = strlen("auto-"); + } + /* Default to auto_id_prefix = 'auto-' if none set. */ - if(config->per_listener_settings){ - for(int i=0; ilistener_count; i++){ + for(int i=0; ilistener_count; i++){ + if(!config->listeners[i].security_options->auto_id_prefix){ + config->listeners[i].security_options->auto_id_prefix = mosquitto_strdup(id_prefix); if(!config->listeners[i].security_options->auto_id_prefix){ - config->listeners[i].security_options->auto_id_prefix = mosquitto_strdup("auto-"); - if(!config->listeners[i].security_options->auto_id_prefix){ - return MOSQ_ERR_NOMEM; - } - config->listeners[i].security_options->auto_id_prefix_len = (uint16_t)strlen("auto-"); - } - } - }else{ - if(!config->security_options.auto_id_prefix){ - config->security_options.auto_id_prefix = mosquitto_strdup("auto-"); - if(!config->security_options.auto_id_prefix){ return MOSQ_ERR_NOMEM; } - config->security_options.auto_id_prefix_len = (uint16_t)strlen("auto-"); + config->listeners[i].security_options->auto_id_prefix_len = (uint16_t)id_prefix_len; } } diff --git a/src/handle_connect.c b/src/handle_connect.c index ed8cd8c7d..7ce3aa425 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -801,11 +801,7 @@ int handle__connect(struct mosquitto *context) rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; }else{ - if(db.config->per_listener_settings){ - clientid = clientid_gen(&slen, context->listener->security_options->auto_id_prefix, context->listener->security_options->auto_id_prefix_len); - }else{ - clientid = clientid_gen(&slen, db.config->security_options.auto_id_prefix, db.config->security_options.auto_id_prefix_len); - } + clientid = clientid_gen(&slen, context->listener->security_options->auto_id_prefix, context->listener->security_options->auto_id_prefix_len); if(!clientid){ rc = MOSQ_ERR_NOMEM; goto handle_connect_error; diff --git a/test/broker/01-connect-auto-id.py b/test/broker/01-connect-auto-id.py new file mode 100755 index 000000000..63f5e3dea --- /dev/null +++ b/test/broker/01-connect-auto-id.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 + +from mosq_test_helper import * + +def write_config1(filename, port1, port2): + with open(filename, 'w') as f: + f.write(f"listener {port2}\n") + f.write("allow_anonymous true\n") + f.write(f"listener {port1}\n") + f.write("allow_anonymous true\n") + +def write_config2(filename, port1, port2): + with open(filename, 'w') as f: + f.write("auto_id_prefix new-\n") + f.write(f"listener {port2}\n") + f.write("allow_anonymous true\n") + f.write(f"listener {port1}\n") + f.write("allow_anonymous true\n") + +def write_config3(filename, port1, port2): + with open(filename, 'w') as f: + f.write(f"listener {port2}\n") + f.write("listener_auto_id_prefix port2-\n") + f.write("allow_anonymous true\n") + f.write(f"listener {port1}\n") + f.write("allow_anonymous true\n") + +def write_config4(filename, port1, port2): + with open(filename, 'w') as f: + f.write(f"listener {port2}\n") + f.write("listener_auto_id_prefix port2-\n") + f.write("allow_anonymous true\n") + f.write(f"listener {port1}\n") + f.write("listener_auto_id_prefix port1-\n") + f.write("allow_anonymous true\n") + +def write_config5(filename, port1, port2): + with open(filename, 'w') as f: + f.write("auto_id_prefix global-\n") + f.write(f"listener {port2}\n") + f.write("listener_auto_id_prefix port2-\n") + f.write("allow_anonymous true\n") + f.write(f"listener {port1}\n") + f.write("listener_auto_id_prefix port1-\n") + f.write("allow_anonymous true\n") + +def write_config6(filename, port1, port2): + with open(filename, 'w') as f: + f.write("auto_id_prefix global-\n") + f.write(f"listener {port2}\n") + f.write("allow_anonymous true\n") + f.write(f"listener {port1}\n") + f.write("listener_auto_id_prefix port1-\n") + f.write("allow_anonymous true\n") + + +def do_test(config_func, client_port, auto_id): + conf_file = os.path.basename(__file__).replace('.py', '.conf') + config_func(conf_file, port1, port2) + + rc = 1 + connect_packet = mosq_test.gen_connect("", proto_ver=5) + props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_ASSIGNED_CLIENT_IDENTIFIER, f"{auto_id}xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") + connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5, properties=props) + # Remove the "xxxx" part - this means the front part of the packet + # is correct (so remaining length etc. is correct), but we don't + # need to match against the random id. + connack_packet = connack_packet[:-39] + + broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port1, use_conf=True) + + try: + sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=client_port) + sock.close() + rc = 0 + except mosq_test.TestError: + pass + finally: + broker.terminate() + if mosq_test.wait_for_subprocess(broker): + print("broker not terminated") + if rc == 0: rc=1 + (stdo, stde) = broker.communicate() + os.remove(conf_file) + if rc: + print(stde.decode('utf-8')) + exit(rc) + + +(port1, port2) = mosq_test.get_port(2) + +do_test(config_func=write_config1, client_port=port1, auto_id="auto-") +do_test(config_func=write_config1, client_port=port2, auto_id="auto-") +do_test(config_func=write_config2, client_port=port1, auto_id="new-") +do_test(config_func=write_config2, client_port=port2, auto_id="new-") +do_test(config_func=write_config3, client_port=port1, auto_id="auto-") +do_test(config_func=write_config3, client_port=port2, auto_id="port2-") +do_test(config_func=write_config4, client_port=port1, auto_id="port1-") +do_test(config_func=write_config4, client_port=port2, auto_id="port2-") +do_test(config_func=write_config5, client_port=port1, auto_id="port1-") +do_test(config_func=write_config5, client_port=port2, auto_id="port2-") +do_test(config_func=write_config6, client_port=port1, auto_id="port1-") +do_test(config_func=write_config6, client_port=port2, auto_id="global-") + +exit(0) diff --git a/test/broker/Makefile b/test/broker/Makefile index 87a7607f7..3aeca36ce 100644 --- a/test/broker/Makefile +++ b/test/broker/Makefile @@ -28,6 +28,7 @@ msg_sequence_test: ./01-connect-575314.py ./01-connect-accept-protocol.py ./01-connect-allow-anonymous.py + ./01-connect-auto-id.py ./01-connect-disconnect-v5.py ./01-connect-global-max-clients.py ./01-connect-global-max-connections.py diff --git a/test/broker/test.py b/test/broker/test.py index e802612be..c0b627750 100755 --- a/test/broker/test.py +++ b/test/broker/test.py @@ -9,6 +9,7 @@ (1, './01-connect-575314.py'), (1, './01-connect-accept-protocol.py'), (1, './01-connect-allow-anonymous.py'), + (2, './01-connect-auto-id.py'), (1, './01-connect-disconnect-v5.py'), (1, './01-connect-global-max-clients.py'), (1, './01-connect-global-max-connections.py'),