Move control functions to common, and use in the broker.

This commit is contained in:
Roger A. Light
2022-12-31 14:34:26 +00:00
parent 611c43e537
commit 4199e7b2d3
14 changed files with 356 additions and 469 deletions
@@ -1,6 +1,6 @@
#include "config.h"
#include "plugin_common.h"
#include "control_common.h"
#include "json_help.h"
#include <mqtt_protocol.h>
#include <mosquitto_broker.h>
@@ -8,7 +8,7 @@
#include <stdlib.h>
#include <string.h>
void plugin__command_reply(struct plugin_cmd *cmd, const char *error)
void control__command_reply(struct control_cmd *cmd, const char *error)
{
cJSON *j_response;
@@ -27,7 +27,7 @@ void plugin__command_reply(struct plugin_cmd *cmd, const char *error)
cJSON_AddItemToArray(cmd->j_responses, j_response);
}
void plugin__send_response(cJSON *tree, const char *topic)
void control__send_response(cJSON *tree, const char *topic)
{
char *payload;
size_t payload_len;
@@ -45,7 +45,7 @@ void plugin__send_response(cJSON *tree, const char *topic)
}
static int plugin__generic_handle_commands(struct plugin_cmd *cmd, struct mosquitto *context, cJSON *commands, void *userdata, int (*cmd_cb)(struct plugin_cmd *cmd, struct mosquitto *context, const char *command, void *userdata))
static int control__generic_handle_commands(struct control_cmd *cmd, struct mosquitto *context, cJSON *commands, void *userdata, int (*cmd_cb)(struct control_cmd *cmd, struct mosquitto *context, const char *command, void *userdata))
{
cJSON *aiter;
char *command;
@@ -59,29 +59,29 @@ static int plugin__generic_handle_commands(struct plugin_cmd *cmd, struct mosqui
cmd->command_name = command;
if(json_get_string(aiter, "correlationData", &cmd->correlation_data, true) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid correlationData data type.");
control__command_reply(cmd, "Invalid correlationData data type.");
return MOSQ_ERR_INVAL;
}
cmd_cb(cmd, context, command, userdata);
}else{
plugin__command_reply(cmd, "Missing command");
control__command_reply(cmd, "Missing command");
return MOSQ_ERR_INVAL;
}
}else{
plugin__command_reply(cmd, "Command not an object");
control__command_reply(cmd, "Command not an object");
return MOSQ_ERR_INVAL;
}
}
return MOSQ_ERR_SUCCESS;
}
int plugin__generic_control_callback(struct mosquitto_evt_control *event_data, const char *response_topic, void *userdata,
int (*cmd_cb)(struct plugin_cmd *cmd, struct mosquitto *context, const char *command, void *userdata))
int control__generic_control_callback(struct mosquitto_evt_control *event_data, const char *response_topic, void *userdata,
int (*cmd_cb)(struct control_cmd *cmd, struct mosquitto *context, const char *command, void *userdata))
{
struct mosquitto_evt_control *ed = event_data;
struct plugin_cmd cmd;
struct control_cmd cmd;
cJSON *tree, *commands;
cJSON *j_response_tree;
@@ -113,23 +113,23 @@ int plugin__generic_control_callback(struct mosquitto_evt_control *event_data, c
tree = cJSON_ParseWithLength(ed->payload, ed->payloadlen);
#endif
if(tree == NULL){
plugin__command_reply(&cmd, "Payload not valid JSON");
plugin__send_response(j_response_tree, response_topic);
control__command_reply(&cmd, "Payload not valid JSON");
control__send_response(j_response_tree, response_topic);
return MOSQ_ERR_SUCCESS;
}
commands = cJSON_GetObjectItem(tree, "commands");
if(commands == NULL || !cJSON_IsArray(commands)){
cJSON_Delete(tree);
plugin__command_reply(&cmd, "Invalid/missing commands");
plugin__send_response(j_response_tree, response_topic);
control__command_reply(&cmd, "Invalid/missing commands");
control__send_response(j_response_tree, response_topic);
return MOSQ_ERR_SUCCESS;
}
/* Handle commands */
plugin__generic_handle_commands(&cmd, ed->client, commands, userdata, cmd_cb);
control__generic_handle_commands(&cmd, ed->client, commands, userdata, cmd_cb);
cJSON_Delete(tree);
plugin__send_response(j_response_tree, response_topic);
control__send_response(j_response_tree, response_topic);
return MOSQ_ERR_SUCCESS;
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef CONTROLLUGIN_COMMON_H
#define CONTROLLUGIN_COMMON_H
#include <cjson/cJSON.h>
#include "mosquitto_broker.h"
struct control_cmd{
cJSON *j_responses;
cJSON *j_command;
char *correlation_data;
const char *command_name;
};
void control__command_reply(struct control_cmd *cmd, const char *error);
void control__send_response(cJSON *tree, const char* topic);
int control__generic_control_callback(struct mosquitto_evt_control *event_data, const char *response_topic, void *userdata,
int (*cmd_cb)(struct control_cmd *cmd, struct mosquitto *context, const char *command, void *userdata));
#endif
-19
View File
@@ -1,19 +0,0 @@
#ifndef PLUGIN_COMMON_H
#define PLUGIN_COMMON_H
#include <cjson/cJSON.h>
#include "mosquitto_broker.h"
struct plugin_cmd{
cJSON *j_responses;
cJSON *j_command;
char *correlation_data;
const char *command_name;
};
void plugin__command_reply(struct plugin_cmd *cmd, const char *error);
void plugin__send_response(cJSON *tree, const char* topic);
int plugin__generic_control_callback(struct mosquitto_evt_control *event_data, const char *response_topic, void *userdata,
int (*cmd_cb)(struct plugin_cmd *cmd, struct mosquitto *context, const char *command, void *userdata));
#endif
+1 -1
View File
@@ -21,6 +21,7 @@ if(CJSON_FOUND AND WITH_TLS)
config.c
config_init.c
control.c
../../common/control_common.c ../../common/control_common.h
default_acl.c
dynamic_security.h
groups.c
@@ -31,7 +32,6 @@ if(CJSON_FOUND AND WITH_TLS)
../../common/misc_mosq.c ../../common/misc_mosq.h
../../common/password_mosq.c ../../common/password_mosq.h
plugin.c
../common/plugin_common.c ../common/plugin_common.h
roles.c
rolelist.c
tick.c
+2 -2
View File
@@ -18,6 +18,7 @@ OBJS= \
config.o \
config_init.o \
control.o \
control_common.o \
default_acl.o \
groups.o \
grouplist.o \
@@ -27,7 +28,6 @@ OBJS= \
misc_mosq.o \
password_mosq.o \
plugin.o \
plugin_common.o \
roles.o \
rolelist.o \
tick.o
@@ -99,7 +99,7 @@ password_mosq.o : ${R}/common/password_mosq.c ${R}/common/password_mosq.h
plugin.o : plugin.c dynamic_security.h
${CROSS_COMPILE}${CC} $(LOCAL_CPPFLAGS) $(PLUGIN_CPPFLAGS) $(PLUGIN_CFLAGS) -c $< -o $@
plugin_common.o : ${R}/plugins/common/plugin_common.c ${R}/plugins/common/plugin_common.h
control_common.o : ${R}/common/control_common.c ${R}/common/control_common.h
${CROSS_COMPILE}${CC} $(LOCAL_CPPFLAGS) $(PLUGIN_CPPFLAGS) $(PLUGIN_CFLAGS) -c $< -o $@
roles.o : roles.c dynamic_security.h
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -35,7 +35,7 @@ Contributors:
#define RESPONSE_TOPIC "$CONTROL/dynamic-security/v1/response"
static int dynsec__handle_command(struct plugin_cmd *cmd, struct mosquitto *context, const char *command, void *userdata)
static int dynsec__handle_command(struct control_cmd *cmd, struct mosquitto *context, const char *command, void *userdata)
{
struct dynsec__data *data = userdata;
int rc = MOSQ_ERR_SUCCESS;
@@ -112,7 +112,7 @@ static int dynsec__handle_command(struct plugin_cmd *cmd, struct mosquitto *cont
/* Unknown */
}else{
plugin__command_reply(cmd, "Unknown command");
control__command_reply(cmd, "Unknown command");
rc = MOSQ_ERR_INVAL;
}
@@ -129,7 +129,7 @@ int dynsec_control_callback(int event, void *event_data, void *userdata)
UNUSED(event);
data->need_save = false;
rc = plugin__generic_control_callback(ed, RESPONSE_TOPIC, userdata, dynsec__handle_command);
rc = control__generic_control_callback(ed, RESPONSE_TOPIC, userdata, dynsec__handle_command);
if(rc == MOSQ_ERR_SUCCESS && data->need_save){
dynsec__config_save(data);
}
+7 -7
View File
@@ -30,11 +30,11 @@ Contributors:
#include "mosquitto_broker.h"
#include "mosquitto_plugin.h"
#include "mqtt_protocol.h"
#include "plugin_common.h"
#include "control_common.h"
#include "dynamic_security.h"
int dynsec__process_set_default_acl_access(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context)
int dynsec__process_set_default_acl_access(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context)
{
cJSON *j_actions, *j_action, *j_acltype, *j_allow;
bool allow;
@@ -42,7 +42,7 @@ int dynsec__process_set_default_acl_access(struct dynsec__data *data, struct plu
j_actions = cJSON_GetObjectItem(cmd->j_command, "acls");
if(j_actions == NULL || !cJSON_IsArray(j_actions)){
plugin__command_reply(cmd, "Missing/invalid actions array");
control__command_reply(cmd, "Missing/invalid actions array");
return MOSQ_ERR_INVAL;
}
@@ -72,19 +72,19 @@ int dynsec__process_set_default_acl_access(struct dynsec__data *data, struct plu
}
dynsec__config_batch_save(data);
plugin__command_reply(cmd, NULL);
control__command_reply(cmd, NULL);
return MOSQ_ERR_SUCCESS;
}
int dynsec__process_get_default_acl_access(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context)
int dynsec__process_get_default_acl_access(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context)
{
cJSON *tree, *jtmp, *j_data, *j_acls, *j_acl;
const char *admin_clientid, *admin_username;
tree = cJSON_CreateObject();
if(tree == NULL){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
@@ -170,6 +170,6 @@ int dynsec__process_get_default_acl_access(struct dynsec__data *data, struct plu
internal_error:
cJSON_Delete(tree);
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
+32 -32
View File
@@ -23,7 +23,7 @@ Contributors:
#include "mosquitto.h"
#include "password_mosq.h"
#include "base64_mosq.h"
#include "plugin_common.h"
#include "control_common.h"
/* ################################################################
* #
@@ -178,8 +178,8 @@ int dynsec_control_callback(int event, void *event_data, void *userdata);
* ################################################################ */
int dynsec__acl_check_callback(int event, void *event_data, void *userdata);
int dynsec__process_set_default_acl_access(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec__process_get_default_acl_access(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec__process_set_default_acl_access(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec__process_get_default_acl_access(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
/* ################################################################
@@ -201,17 +201,17 @@ int dynsec_auth__basic_auth_callback(int event, void *event_data, void *userdata
void dynsec_clients__cleanup(struct dynsec__data *data);
int dynsec_clients__config_load(struct dynsec__data *data, cJSON *tree);
int dynsec_clients__config_save(struct dynsec__data *data, cJSON *tree);
int dynsec_clients__process_add_role(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_create(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_delete(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_disable(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_enable(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_get(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_list(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_modify(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_remove_role(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_set_id(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_set_password(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_add_role(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_create(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_delete(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_disable(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_enable(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_get(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_list(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_modify(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_remove_role(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_set_id(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_clients__process_set_password(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
struct dynsec__client *dynsec_clients__find(struct dynsec__data *data, const char *username);
@@ -238,17 +238,17 @@ void dynsec_groups__cleanup(struct dynsec__data *data);
int dynsec_groups__config_load(struct dynsec__data *data, cJSON *tree);
int dynsec_groups__add_client(struct dynsec__data *data, const char *username, const char *groupname, int priority, bool update_config);
int dynsec_groups__config_save(struct dynsec__data *data, cJSON *tree);
int dynsec_groups__process_add_client(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_add_role(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_create(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_delete(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_get(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_list(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_modify(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_remove_client(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_remove_role(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_get_anonymous_group(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_set_anonymous_group(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_add_client(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_add_role(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_create(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_delete(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_get(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_list(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_modify(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_remove_client(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_remove_role(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_get_anonymous_group(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__process_set_anonymous_group(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_groups__remove_client(struct dynsec__data *data, const char *username, const char *groupname, bool update_config);
struct dynsec__group *dynsec_groups__find(struct dynsec__data *data, const char *groupname);
@@ -274,13 +274,13 @@ void dynsec_grouplist__remove(struct dynsec__grouplist **base_grouplist, struct
void dynsec_roles__cleanup(struct dynsec__data *data);
int dynsec_roles__config_load(struct dynsec__data *data, cJSON *tree);
int dynsec_roles__config_save(struct dynsec__data *data, cJSON *tree);
int dynsec_roles__process_add_acl(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_create(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_delete(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_get(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_list(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_modify(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_remove_acl(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_add_acl(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_create(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_delete(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_get(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_list(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_modify(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
int dynsec_roles__process_remove_acl(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context);
struct dynsec__role *dynsec_roles__find(struct dynsec__data *data, const char *rolename);
File diff suppressed because it is too large Load Diff
+60 -60
View File
@@ -331,7 +331,7 @@ int dynsec_roles__config_load(struct dynsec__data *data, cJSON *tree)
}
int dynsec_roles__process_create(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context)
int dynsec_roles__process_create(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context)
{
char *rolename;
char *text_name, *text_description;
@@ -343,50 +343,50 @@ int dynsec_roles__process_create(struct dynsec__data *data, struct plugin_cmd *c
size_t rolename_len;
if(json_get_string(cmd->j_command, "rolename", &rolename, false) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid/missing rolename");
control__command_reply(cmd, "Invalid/missing rolename");
return MOSQ_ERR_INVAL;
}
rolename_len = strlen(rolename);
if(rolename_len == 0){
plugin__command_reply(cmd, "Empty rolename");
control__command_reply(cmd, "Empty rolename");
return MOSQ_ERR_INVAL;
}
if(mosquitto_validate_utf8(rolename, (int)rolename_len) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Role name not valid UTF-8");
control__command_reply(cmd, "Role name not valid UTF-8");
return MOSQ_ERR_INVAL;
}
if(json_get_string(cmd->j_command, "textname", &text_name, true) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid/missing textname");
control__command_reply(cmd, "Invalid/missing textname");
return MOSQ_ERR_INVAL;
}
if(json_get_string(cmd->j_command, "textdescription", &text_description, true) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid/missing textdescription");
control__command_reply(cmd, "Invalid/missing textdescription");
return MOSQ_ERR_INVAL;
}
if(json_get_bool(cmd->j_command, "allowwildcardsubs", &allow_wildcard_subs, true, true) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid allowwildcardsubs");
control__command_reply(cmd, "Invalid allowwildcardsubs");
return MOSQ_ERR_INVAL;
}
role = dynsec_roles__find(data, rolename);
if(role){
plugin__command_reply(cmd, "Role already exists");
control__command_reply(cmd, "Role already exists");
return MOSQ_ERR_SUCCESS;
}
role = mosquitto_calloc(1, sizeof(struct dynsec__role) + rolename_len + 1);
if(role == NULL){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
strncpy(role->rolename, rolename, rolename_len+1);
if(text_name){
role->text_name = mosquitto_strdup(text_name);
if(role->text_name == NULL){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
rc = MOSQ_ERR_NOMEM;
goto error;
}
@@ -394,7 +394,7 @@ int dynsec_roles__process_create(struct dynsec__data *data, struct plugin_cmd *c
if(text_description){
role->text_description = mosquitto_strdup(text_description);
if(role->text_description == NULL){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
rc = MOSQ_ERR_NOMEM;
goto error;
}
@@ -412,7 +412,7 @@ int dynsec_roles__process_create(struct dynsec__data *data, struct plugin_cmd *c
|| dynsec_roles__acl_load(j_acls, ACL_TYPE_UNSUB_PATTERN, &role->acls.unsubscribe_pattern) != 0
){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
rc = MOSQ_ERR_NOMEM;
goto error;
}
@@ -423,7 +423,7 @@ int dynsec_roles__process_create(struct dynsec__data *data, struct plugin_cmd *c
dynsec__config_batch_save(data);
plugin__command_reply(cmd, NULL);
control__command_reply(cmd, NULL);
admin_clientid = mosquitto_client_id(context);
admin_username = mosquitto_client_username(context);
@@ -464,18 +464,18 @@ static void role__remove_all_groups(struct dynsec__data *data, struct dynsec__ro
}
}
int dynsec_roles__process_delete(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context)
int dynsec_roles__process_delete(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context)
{
char *rolename;
struct dynsec__role *role;
const char *admin_clientid, *admin_username;
if(json_get_string(cmd->j_command, "rolename", &rolename, false) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid/missing rolename");
control__command_reply(cmd, "Invalid/missing rolename");
return MOSQ_ERR_INVAL;
}
if(mosquitto_validate_utf8(rolename, (int)strlen(rolename)) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Role name not valid UTF-8");
control__command_reply(cmd, "Role name not valid UTF-8");
return MOSQ_ERR_INVAL;
}
@@ -485,7 +485,7 @@ int dynsec_roles__process_delete(struct dynsec__data *data, struct plugin_cmd *c
role__remove_all_groups(data, role);
role__free_item(data, role, true);
dynsec__config_batch_save(data);
plugin__command_reply(cmd, NULL);
control__command_reply(cmd, NULL);
admin_clientid = mosquitto_client_id(context);
admin_username = mosquitto_client_username(context);
@@ -494,7 +494,7 @@ int dynsec_roles__process_delete(struct dynsec__data *data, struct plugin_cmd *c
return MOSQ_ERR_SUCCESS;
}else{
plugin__command_reply(cmd, "Role not found");
control__command_reply(cmd, "Role not found");
return MOSQ_ERR_SUCCESS;
}
}
@@ -532,7 +532,7 @@ static cJSON *add_role_to_json(struct dynsec__role *role, bool verbose)
return j_role;
}
int dynsec_roles__process_list(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context)
int dynsec_roles__process_list(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context)
{
bool verbose;
struct dynsec__role *role, *role_tmp = NULL;
@@ -546,7 +546,7 @@ int dynsec_roles__process_list(struct dynsec__data *data, struct plugin_cmd *cmd
tree = cJSON_CreateObject();
if(tree == NULL){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
@@ -558,7 +558,7 @@ int dynsec_roles__process_list(struct dynsec__data *data, struct plugin_cmd *cmd
){
cJSON_Delete(tree);
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
@@ -568,7 +568,7 @@ int dynsec_roles__process_list(struct dynsec__data *data, struct plugin_cmd *cmd
j_role = add_role_to_json(role, verbose);
if(j_role == NULL){
cJSON_Delete(tree);
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToArray(j_roles, j_role);
@@ -594,7 +594,7 @@ int dynsec_roles__process_list(struct dynsec__data *data, struct plugin_cmd *cmd
}
int dynsec_roles__process_add_acl(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context)
int dynsec_roles__process_add_acl(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context)
{
char *rolename;
struct dynsec__role *role;
@@ -605,23 +605,23 @@ int dynsec_roles__process_add_acl(struct dynsec__data *data, struct plugin_cmd *
size_t topic_len;
if(json_get_string(cmd->j_command, "rolename", &rolename, false) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid/missing rolename");
control__command_reply(cmd, "Invalid/missing rolename");
return MOSQ_ERR_INVAL;
}
if(mosquitto_validate_utf8(rolename, (int)strlen(rolename)) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Role name not valid UTF-8");
control__command_reply(cmd, "Role name not valid UTF-8");
return MOSQ_ERR_INVAL;
}
role = dynsec_roles__find(data, rolename);
if(role == NULL){
plugin__command_reply(cmd, "Role not found");
control__command_reply(cmd, "Role not found");
return MOSQ_ERR_SUCCESS;
}
j_acltype = cJSON_GetObjectItem(cmd->j_command, "acltype");
if(j_acltype == NULL || !cJSON_IsString(j_acltype)){
plugin__command_reply(cmd, "Invalid/missing acltype");
control__command_reply(cmd, "Invalid/missing acltype");
return MOSQ_ERR_SUCCESS;
}
if(!strcasecmp(j_acltype->valuestring, ACL_TYPE_PUB_C_SEND)){
@@ -637,7 +637,7 @@ int dynsec_roles__process_add_acl(struct dynsec__data *data, struct plugin_cmd *
}else if(!strcasecmp(j_acltype->valuestring, ACL_TYPE_UNSUB_PATTERN)){
acllist = &role->acls.unsubscribe_pattern;
}else{
plugin__command_reply(cmd, "Unknown acltype");
control__command_reply(cmd, "Unknown acltype");
return MOSQ_ERR_SUCCESS;
}
@@ -645,28 +645,28 @@ int dynsec_roles__process_add_acl(struct dynsec__data *data, struct plugin_cmd *
if(j_topic && cJSON_IsString(j_topic)){
topic_len = strlen(j_topic->valuestring);
if(mosquitto_validate_utf8(j_topic->valuestring, (int)topic_len) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Topic not valid UTF-8");
control__command_reply(cmd, "Topic not valid UTF-8");
return MOSQ_ERR_INVAL;
}
rc = mosquitto_sub_topic_check(j_topic->valuestring);
if(rc != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid ACL topic");
control__command_reply(cmd, "Invalid ACL topic");
return MOSQ_ERR_INVAL;
}
}else{
plugin__command_reply(cmd, "Invalid/missing topic");
control__command_reply(cmd, "Invalid/missing topic");
return MOSQ_ERR_SUCCESS;
}
HASH_FIND(hh, *acllist, j_topic->valuestring, topic_len, acl);
if(acl){
plugin__command_reply(cmd, "ACL with this topic already exists");
control__command_reply(cmd, "ACL with this topic already exists");
return MOSQ_ERR_SUCCESS;
}
acl = mosquitto_calloc(1, sizeof(struct dynsec__acl) + topic_len + 1);
if(acl == NULL){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_SUCCESS;
}
strncpy(acl->topic, j_topic->valuestring, topic_len+1);
@@ -676,7 +676,7 @@ int dynsec_roles__process_add_acl(struct dynsec__data *data, struct plugin_cmd *
HASH_ADD_INORDER(hh, *acllist, topic, topic_len, acl, insert_acl_cmp);
dynsec__config_batch_save(data);
plugin__command_reply(cmd, NULL);
control__command_reply(cmd, NULL);
role__kick_all(data, role);
@@ -689,7 +689,7 @@ int dynsec_roles__process_add_acl(struct dynsec__data *data, struct plugin_cmd *
}
int dynsec_roles__process_remove_acl(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context)
int dynsec_roles__process_remove_acl(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context)
{
char *rolename;
struct dynsec__role *role;
@@ -700,23 +700,23 @@ int dynsec_roles__process_remove_acl(struct dynsec__data *data, struct plugin_cm
const char *admin_clientid, *admin_username;
if(json_get_string(cmd->j_command, "rolename", &rolename, false) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid/missing rolename");
control__command_reply(cmd, "Invalid/missing rolename");
return MOSQ_ERR_INVAL;
}
if(mosquitto_validate_utf8(rolename, (int)strlen(rolename)) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Role name not valid UTF-8");
control__command_reply(cmd, "Role name not valid UTF-8");
return MOSQ_ERR_INVAL;
}
role = dynsec_roles__find(data, rolename);
if(role == NULL){
plugin__command_reply(cmd, "Role not found");
control__command_reply(cmd, "Role not found");
return MOSQ_ERR_SUCCESS;
}
j_acltype = cJSON_GetObjectItem(cmd->j_command, "acltype");
if(j_acltype == NULL || !cJSON_IsString(j_acltype)){
plugin__command_reply(cmd, "Invalid/missing acltype");
control__command_reply(cmd, "Invalid/missing acltype");
return MOSQ_ERR_SUCCESS;
}
if(!strcasecmp(j_acltype->valuestring, ACL_TYPE_PUB_C_SEND)){
@@ -732,21 +732,21 @@ int dynsec_roles__process_remove_acl(struct dynsec__data *data, struct plugin_cm
}else if(!strcasecmp(j_acltype->valuestring, ACL_TYPE_UNSUB_PATTERN)){
acllist = &role->acls.unsubscribe_pattern;
}else{
plugin__command_reply(cmd, "Unknown acltype");
control__command_reply(cmd, "Unknown acltype");
return MOSQ_ERR_SUCCESS;
}
if(json_get_string(cmd->j_command, "topic", &topic, false)){
plugin__command_reply(cmd, "Invalid/missing topic");
control__command_reply(cmd, "Invalid/missing topic");
return MOSQ_ERR_SUCCESS;
}
if(mosquitto_validate_utf8(topic, (int)strlen(topic)) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Topic not valid UTF-8");
control__command_reply(cmd, "Topic not valid UTF-8");
return MOSQ_ERR_INVAL;
}
rc = mosquitto_sub_topic_check(topic);
if(rc != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid ACL topic");
control__command_reply(cmd, "Invalid ACL topic");
return MOSQ_ERR_INVAL;
}
@@ -754,7 +754,7 @@ int dynsec_roles__process_remove_acl(struct dynsec__data *data, struct plugin_cm
if(acl){
role__free_acl(acllist, acl);
dynsec__config_batch_save(data);
plugin__command_reply(cmd, NULL);
control__command_reply(cmd, NULL);
role__kick_all(data, role);
@@ -764,14 +764,14 @@ int dynsec_roles__process_remove_acl(struct dynsec__data *data, struct plugin_cm
admin_clientid, admin_username, rolename, j_acltype->valuestring, topic);
}else{
plugin__command_reply(cmd, "ACL not found");
control__command_reply(cmd, "ACL not found");
}
return MOSQ_ERR_SUCCESS;
}
int dynsec_roles__process_get(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context)
int dynsec_roles__process_get(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context)
{
char *rolename;
struct dynsec__role *role;
@@ -779,23 +779,23 @@ int dynsec_roles__process_get(struct dynsec__data *data, struct plugin_cmd *cmd,
const char *admin_clientid, *admin_username;
if(json_get_string(cmd->j_command, "rolename", &rolename, false) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid/missing rolename");
control__command_reply(cmd, "Invalid/missing rolename");
return MOSQ_ERR_INVAL;
}
if(mosquitto_validate_utf8(rolename, (int)strlen(rolename)) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Role name not valid UTF-8");
control__command_reply(cmd, "Role name not valid UTF-8");
return MOSQ_ERR_INVAL;
}
role = dynsec_roles__find(data, rolename);
if(role == NULL){
plugin__command_reply(cmd, "Role not found");
control__command_reply(cmd, "Role not found");
return MOSQ_ERR_SUCCESS;
}
tree = cJSON_CreateObject();
if(tree == NULL){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
@@ -805,14 +805,14 @@ int dynsec_roles__process_get(struct dynsec__data *data, struct plugin_cmd *cmd,
){
cJSON_Delete(tree);
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
j_role = add_role_to_json(role, true);
if(j_role == NULL){
cJSON_Delete(tree);
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToObject(j_data, "role", j_role);
@@ -827,7 +827,7 @@ int dynsec_roles__process_get(struct dynsec__data *data, struct plugin_cmd *cmd,
}
int dynsec_roles__process_modify(struct dynsec__data *data, struct plugin_cmd *cmd, struct mosquitto *context)
int dynsec_roles__process_modify(struct dynsec__data *data, struct control_cmd *cmd, struct mosquitto *context)
{
char *rolename;
char *text_name, *text_description;
@@ -842,24 +842,24 @@ int dynsec_roles__process_modify(struct dynsec__data *data, struct plugin_cmd *c
const char *admin_clientid, *admin_username;
if(json_get_string(cmd->j_command, "rolename", &rolename, false) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Invalid/missing rolename");
control__command_reply(cmd, "Invalid/missing rolename");
return MOSQ_ERR_INVAL;
}
if(mosquitto_validate_utf8(rolename, (int)strlen(rolename)) != MOSQ_ERR_SUCCESS){
plugin__command_reply(cmd, "Role name not valid UTF-8");
control__command_reply(cmd, "Role name not valid UTF-8");
return MOSQ_ERR_INVAL;
}
role = dynsec_roles__find(data, rolename);
if(role == NULL){
plugin__command_reply(cmd, "Role does not exist");
control__command_reply(cmd, "Role does not exist");
return MOSQ_ERR_INVAL;
}
if(json_get_string(cmd->j_command, "textname", &text_name, false) == MOSQ_ERR_SUCCESS){
str = mosquitto_strdup(text_name);
if(str == NULL){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
mosquitto_free(role->text_name);
@@ -869,7 +869,7 @@ int dynsec_roles__process_modify(struct dynsec__data *data, struct plugin_cmd *c
if(json_get_string(cmd->j_command, "textdescription", &text_description, false) == MOSQ_ERR_SUCCESS){
str = mosquitto_strdup(text_description);
if(str == NULL){
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
mosquitto_free(role->text_description);
@@ -901,7 +901,7 @@ int dynsec_roles__process_modify(struct dynsec__data *data, struct plugin_cmd *c
role__free_all_acls(&tmp_unsubscribe_literal);
role__free_all_acls(&tmp_unsubscribe_pattern);
plugin__command_reply(cmd, "Internal error");
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
@@ -926,7 +926,7 @@ int dynsec_roles__process_modify(struct dynsec__data *data, struct plugin_cmd *c
}
dynsec__config_batch_save(data);
plugin__command_reply(cmd, NULL);
control__command_reply(cmd, NULL);
admin_clientid = mosquitto_client_id(context);
admin_username = mosquitto_client_username(context);
+1
View File
@@ -7,6 +7,7 @@ set (MOSQ_SRCS
conf_includedir.c
context.c
control.c
../common/control_common.c
database.c
handle_auth.c
handle_connack.c
+4
View File
@@ -15,6 +15,7 @@ OBJS= mosquitto.o \
conf_includedir.o \
context.o \
control.o \
control_common.o \
database.o \
handle_auth.o \
handle_connack.o \
@@ -142,6 +143,9 @@ context.o : context.c mosquitto_broker_internal.h
control.o : control.c mosquitto_broker_internal.h
${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@
control_common.o : ${R}/common/control_common.c ${R}/common/control_common.h
${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@
database.o : database.c mosquitto_broker_internal.h
${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@
+30 -148
View File
@@ -35,51 +35,11 @@ Contributors:
#include "mosquitto_plugin.h"
#include "memory_mosq.h"
#include "mqtt_protocol.h"
#include "control_common.h"
static mosquitto_plugin_id_t plg_id;
static int broker__handle_control(cJSON *j_responses, struct mosquitto *context, cJSON *commands);
static void broker__command_reply(cJSON *j_responses, struct mosquitto *context, const char *command, const char *error, const char *correlation_data)
{
cJSON *j_response;
UNUSED(context);
j_response = cJSON_CreateObject();
if(j_response == NULL) return;
if(cJSON_AddStringToObject(j_response, "command", command) == NULL
|| (error && cJSON_AddStringToObject(j_response, "error", error) == NULL)
|| (correlation_data && cJSON_AddStringToObject(j_response, "correlationData", correlation_data) == NULL)
){
cJSON_Delete(j_response);
return;
}
cJSON_AddItemToArray(j_responses, j_response);
}
static void send_response(cJSON *tree)
{
char *payload;
size_t payload_len;
payload = cJSON_PrintUnformatted(tree);
cJSON_Delete(tree);
if(payload == NULL) return;
payload_len = strlen(payload);
if(payload_len > MQTT_MAX_PAYLOAD){
SAFE_FREE(payload);
return;
}
mosquitto_broker_publish(NULL, "$CONTROL/broker/v1/response",
(int)payload_len, payload, 0, 0, NULL);
}
static int broker__handle_control(struct control_cmd *cmd, struct mosquitto *context, const char *command, void *userdata);
static int add_plugin_info(cJSON *j_plugins, mosquitto_plugin_id_t *pid)
{
@@ -109,6 +69,7 @@ static int add_plugin_info(cJSON *j_plugins, mosquitto_plugin_id_t *pid)
j_ep = cJSON_CreateString(ep->topic);
if(j_ep == NULL){
cJSON_Delete(j_plugin);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToArray(j_eps, j_ep);
}
@@ -118,17 +79,15 @@ static int add_plugin_info(cJSON *j_plugins, mosquitto_plugin_id_t *pid)
}
static int broker__process_list_plugins(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data)
static int broker__process_list_plugins(struct control_cmd *cmd, struct mosquitto *context)
{
cJSON *tree, *jtmp, *j_data, *j_plugins;
cJSON *tree, *j_data, *j_plugins;
const char *admin_clientid, *admin_username;
int i;
UNUSED(command);
tree = cJSON_CreateObject();
if(tree == NULL){
broker__command_reply(j_responses, context, "listPlugins", "Internal error", correlation_data);
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
@@ -138,9 +97,10 @@ static int broker__process_list_plugins(cJSON *j_responses, struct mosquitto *co
admin_clientid, admin_username);
if(cJSON_AddStringToObject(tree, "command", "listPlugins") == NULL
|| ((j_data = cJSON_AddObjectToObject(tree, "data")) == NULL)
|| ((j_data = cJSON_AddObjectToObject(tree, "data")) == NULL)
|| (cmd->correlation_data && cJSON_AddStringToObject(tree, "correlationData", cmd->correlation_data) == NULL)
){
goto internal_error;
}
@@ -155,20 +115,13 @@ static int broker__process_list_plugins(cJSON *j_responses, struct mosquitto *co
}
}
cJSON_AddItemToArray(j_responses, tree);
if(correlation_data){
jtmp = cJSON_AddStringToObject(tree, "correlationData", correlation_data);
if(jtmp == NULL){
goto internal_error;
}
}
cJSON_AddItemToArray(cmd->j_responses, tree);
return MOSQ_ERR_SUCCESS;
internal_error:
cJSON_Delete(tree);
broker__command_reply(j_responses, context, "listPlugins", "Internal error", correlation_data);
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
@@ -213,17 +166,15 @@ static int add_listener(cJSON *j_listeners, struct mosquitto__listener *listener
}
static int broker__process_list_listeners(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data)
static int broker__process_list_listeners(struct control_cmd *cmd, struct mosquitto *context)
{
cJSON *tree, *jtmp, *j_data, *j_listeners;
cJSON *tree, *j_data, *j_listeners;
const char *admin_clientid, *admin_username;
int i;
UNUSED(command);
tree = cJSON_CreateObject();
if(tree == NULL){
broker__command_reply(j_responses, context, "listListeners", "Internal error", correlation_data);
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
@@ -233,9 +184,10 @@ static int broker__process_list_listeners(cJSON *j_responses, struct mosquitto *
admin_clientid, admin_username);
if(cJSON_AddStringToObject(tree, "command", "listListeners") == NULL
|| ((j_data = cJSON_AddObjectToObject(tree, "data")) == NULL)
|| ((j_data = cJSON_AddObjectToObject(tree, "data")) == NULL)
|| (cmd->correlation_data && cJSON_AddStringToObject(tree, "correlationData", cmd->correlation_data) == NULL)
){
goto internal_error;
}
@@ -250,20 +202,13 @@ static int broker__process_list_listeners(cJSON *j_responses, struct mosquitto *
}
}
cJSON_AddItemToArray(j_responses, tree);
if(correlation_data){
jtmp = cJSON_AddStringToObject(tree, "correlationData", correlation_data);
if(jtmp == NULL){
goto internal_error;
}
}
cJSON_AddItemToArray(cmd->j_responses, tree);
return MOSQ_ERR_SUCCESS;
internal_error:
cJSON_Delete(tree);
broker__command_reply(j_responses, context, "listListeners", "Internal error", correlation_data);
control__command_reply(cmd, "Internal error");
return MOSQ_ERR_NOMEM;
}
@@ -271,54 +216,10 @@ internal_error:
static int broker_control_callback(int event, void *event_data, void *userdata)
{
struct mosquitto_evt_control *ed = event_data;
cJSON *tree, *commands;
cJSON *j_response_tree, *j_responses;
UNUSED(event);
UNUSED(userdata);
/* Create object for responses */
j_response_tree = cJSON_CreateObject();
if(j_response_tree == NULL){
return MOSQ_ERR_NOMEM;
}
j_responses = cJSON_CreateArray();
if(j_responses == NULL){
cJSON_Delete(j_response_tree);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToObject(j_response_tree, "responses", j_responses);
/* Parse cJSON tree.
* Using cJSON_ParseWithLength() is the best choice here, but Mosquitto
* always adds an extra 0 to the end of the payload memory, so using
* cJSON_Parse() on its own will still not overrun. */
#if CJSON_VERSION_FULL < 1007013
tree = cJSON_Parse(ed->payload);
#else
tree = cJSON_ParseWithLength(ed->payload, ed->payloadlen);
#endif
if(tree == NULL){
broker__command_reply(j_responses, ed->client, "Unknown command", "Payload not valid JSON", NULL);
send_response(j_response_tree);
return MOSQ_ERR_SUCCESS;
}
commands = cJSON_GetObjectItem(tree, "commands");
if(commands == NULL || !cJSON_IsArray(commands)){
cJSON_Delete(tree);
broker__command_reply(j_responses, ed->client, "Unknown command", "Invalid/missing commands", NULL);
send_response(j_response_tree);
return MOSQ_ERR_SUCCESS;
}
/* Handle commands */
broker__handle_control(j_responses, ed->client, commands);
cJSON_Delete(tree);
send_response(j_response_tree);
return MOSQ_ERR_SUCCESS;
return control__generic_control_callback(ed, "$CONTROL/broker/v1/response", userdata, broker__handle_control);
}
@@ -351,41 +252,22 @@ void broker_control__reload(void)
* #
* ################################################################ */
static int broker__handle_control(cJSON *j_responses, struct mosquitto *context, cJSON *commands)
static int broker__handle_control(struct control_cmd *cmd, struct mosquitto *context, const char *command, void *userdata)
{
int rc = MOSQ_ERR_SUCCESS;
cJSON *aiter;
char *command;
char *correlation_data = NULL;
cJSON_ArrayForEach(aiter, commands){
if(cJSON_IsObject(aiter)){
if(json_get_string(aiter, "command", &command, false) == MOSQ_ERR_SUCCESS){
if(json_get_string(aiter, "correlationData", &correlation_data, true) != MOSQ_ERR_SUCCESS){
broker__command_reply(j_responses, context, command, "Invalid correlationData data type.", NULL);
return MOSQ_ERR_INVAL;
}
UNUSED(userdata);
if(!strcasecmp(command, "listPlugins")){
rc = broker__process_list_plugins(j_responses, context, aiter, correlation_data);
}else if(!strcasecmp(command, "listListeners")){
rc = broker__process_list_listeners(j_responses, context, aiter, correlation_data);
if(!strcasecmp(command, "listPlugins")){
rc = broker__process_list_plugins(cmd, context);
}else if(!strcasecmp(command, "listListeners")){
rc = broker__process_list_listeners(cmd, context);
/* Unknown */
}else{
broker__command_reply(j_responses, context, command, "Unknown command", correlation_data);
rc = MOSQ_ERR_INVAL;
}
}else{
broker__command_reply(j_responses, context, "Unknown command", "Missing command", correlation_data);
rc = MOSQ_ERR_INVAL;
}
}else{
broker__command_reply(j_responses, context, "Unknown command", "Command not an object", correlation_data);
rc = MOSQ_ERR_INVAL;
}
/* Unknown */
}else{
control__command_reply(cmd, "Unknown command");
rc = MOSQ_ERR_INVAL;
}
return rc;
}
#endif