Fix bridge topic remapping when using "" as the topic.

Closes #1749. Thanks to cieslarchristian.
pull/1769/head
Roger A. Light 5 years ago
parent 5a56f066a8
commit 1d66d3e443

@ -6,6 +6,7 @@ Broker:
Closes #821.
- Don't quit with an error if opening the log file isn't possible.
Closes #821.
- Fix bridge topic remapping when using "" as the topic. Closes #1749.
Client library:
- Improved documentation around connect callback return codes. Close #1730.

@ -653,7 +653,7 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool
}
/* Check plugins loaded to see if they have username/password checks enabled */
for(j=0; j<config->listeners[i].security_options.auth_plugin_config_count; j++){
for(j=0; j<config->listeners[i].security_options.auth_plugin_config_count; j++){
plugin = &config->listeners[i].security_options.auth_plugin_configs[j].plugin;
if(plugin->version == 3 || plugin->version == 2){
@ -685,7 +685,7 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool
}
/* Check plugins loaded to see if they have username/password checks enabled */
for(j=0; j<config->security_options.auth_plugin_config_count; j++){
for(j=0; j<config->security_options.auth_plugin_config_count; j++){
plugin = &config->security_options.auth_plugin_configs[j].plugin;
if(plugin->version == 3 || plugin->version == 2){
@ -759,6 +759,76 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool
return MOSQ_ERR_SUCCESS;
}
static int config__create_bridge_remap_topic(const char *prefix, const char *topic, char **remap_topic)
{
int len;
if(prefix){
if(topic){
len = strlen(topic) + strlen(prefix)+1;
*remap_topic = mosquitto__malloc(len+1);
if(!(*remap_topic)){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
snprintf(*remap_topic, len+1, "%s%s", prefix, topic);
(*remap_topic)[len] = '\0';
}else{
*remap_topic = mosquitto__strdup(prefix);
if(!(*remap_topic)){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
}
}else{
*remap_topic = mosquitto__strdup(topic);
if(!(*remap_topic)){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
}
return MOSQ_ERR_SUCCESS;
}
static int config__create_bridge_prefix(char **prefix, const char *topic, const char *token, const char *direction)
{
int len;
if(topic){
len = strlen(topic) + strlen(token) + 1;
}else{
len = strlen(token) + 1;
}
*prefix = malloc(len);
if(*prefix == NULL){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
if(topic){
/* Print prefix+pattern to check for validity */
snprintf(*prefix, len, "%s%s", token, topic);
}else{
snprintf(*prefix, len, "%s", token);
}
if(mosquitto_sub_topic_check(*prefix) != MOSQ_ERR_SUCCESS){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Invalid bridge topic %s prefix and pattern combination '%s'.",
direction, *prefix);
return MOSQ_ERR_INVAL;
}
/* Print just the prefix for storage */
snprintf(*prefix, len, "%s", token);
return MOSQ_ERR_SUCCESS;
}
int config__read_file_core(struct mosquitto__config *config, bool reload, struct config_recurse *cr, int level, int *lineno, FILE *fptr, char **buf, int *buflen)
{
int rc;
@ -769,7 +839,6 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
char *tmp_char;
struct mosquitto__bridge *cur_bridge = NULL;
struct mosquitto__bridge_topic *cur_topic;
int len;
#endif
struct mosquitto__auth_plugin_config *cur_auth_plugin_config = NULL;
@ -2021,22 +2090,12 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge topic local prefix '%s'.", token);
return MOSQ_ERR_INVAL;
}
cur_topic->local_prefix = malloc(strlen(cur_topic->topic) + strlen(token) + 1);
if(cur_topic->local_prefix == NULL){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
/* Print prefix+pattern to check for validity */
snprintf(cur_topic->local_prefix, strlen(cur_topic->topic) + strlen(token)+1,
"%s%s", token, cur_topic->topic);
if(mosquitto_sub_topic_check(cur_topic->local_prefix) != MOSQ_ERR_SUCCESS){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge topic local prefix and pattern combination '%s'.", cur_topic->local_prefix);
if(config__create_bridge_prefix(&cur_topic->local_prefix,
cur_topic->topic, token, "local")){
return MOSQ_ERR_INVAL;
}
/* Print just the prefix for storage */
snprintf(cur_topic->local_prefix, strlen(cur_topic->topic) + strlen(token)+1,
"%s", token);
}
token = strtok_r(NULL, " ", &saveptr);
@ -2048,24 +2107,11 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge topic remote prefix '%s'.", token);
return MOSQ_ERR_INVAL;
}
cur_topic->remote_prefix = malloc(strlen(cur_topic->topic) + strlen(token) + 1);
if(cur_topic == NULL){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
/* Print prefix+pattern to check for validity */
snprintf(cur_topic->remote_prefix, strlen(cur_topic->topic) + strlen(token)+1,
"%s%s", token, cur_topic->topic);
if(mosquitto_sub_topic_check(cur_topic->remote_prefix) != MOSQ_ERR_SUCCESS){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Invalid bridge topic remote prefix and pattern combination '%s'.",
cur_topic->remote_prefix);
if(config__create_bridge_prefix(&cur_topic->remote_prefix,
cur_topic->topic, token, "remote")){
return MOSQ_ERR_INVAL;
}
/* Print just the prefix for storage */
snprintf(cur_topic->remote_prefix, strlen(cur_topic->topic) + strlen(token)+1,
"%s", token);
}
}
}
@ -2077,54 +2123,16 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge remapping.");
return MOSQ_ERR_INVAL;
}
if(cur_topic->local_prefix){
if(cur_topic->topic){
len = strlen(cur_topic->topic) + strlen(cur_topic->local_prefix)+1;
cur_topic->local_topic = mosquitto__malloc(len+1);
if(!cur_topic->local_topic){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
snprintf(cur_topic->local_topic, len+1, "%s%s", cur_topic->local_prefix, cur_topic->topic);
cur_topic->local_topic[len] = '\0';
}else{
cur_topic->local_topic = mosquitto__strdup(cur_topic->local_prefix);
if(!cur_topic->local_topic){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
}
}else{
cur_topic->local_topic = mosquitto__strdup(cur_topic->topic);
if(!cur_topic->local_topic){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
if(config__create_bridge_remap_topic(cur_topic->local_prefix,
cur_topic->topic, &cur_topic->local_topic)){
return MOSQ_ERR_INVAL;
}
if(cur_topic->remote_prefix){
if(cur_topic->topic){
len = strlen(cur_topic->topic) + strlen(cur_topic->remote_prefix)+1;
cur_topic->remote_topic = mosquitto__malloc(len+1);
if(!cur_topic->remote_topic){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
snprintf(cur_topic->remote_topic, len, "%s%s", cur_topic->remote_prefix, cur_topic->topic);
cur_topic->remote_topic[len] = '\0';
}else{
cur_topic->remote_topic = mosquitto__strdup(cur_topic->remote_prefix);
if(!cur_topic->remote_topic){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
}
}else{
cur_topic->remote_topic = mosquitto__strdup(cur_topic->topic);
if(!cur_topic->remote_topic){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
if(config__create_bridge_remap_topic(cur_topic->remote_prefix,
cur_topic->topic, &cur_topic->remote_topic)){
return MOSQ_ERR_INVAL;
}
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge support not available.");

Loading…
Cancel
Save