|
|
|
@ -22,8 +22,13 @@ Contributors:
|
|
|
|
|
#include "memory_mosq.h"
|
|
|
|
|
#include "utlist.h"
|
|
|
|
|
|
|
|
|
|
struct should_free {
|
|
|
|
|
bool topic;
|
|
|
|
|
bool payload;
|
|
|
|
|
bool properties;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int plugin__handle_message_single(struct mosquitto__security_options *opts, struct mosquitto *context, struct mosquitto__base_msg *stored)
|
|
|
|
|
static int plugin__handle_message_single(struct mosquitto__callback *callbacks, enum mosquitto_plugin_event ev_type, struct should_free *to_free, struct mosquitto *context, struct mosquitto_base_msg *stored)
|
|
|
|
|
{
|
|
|
|
|
struct mosquitto_evt_message event_data;
|
|
|
|
|
struct mosquitto__callback *cb_base;
|
|
|
|
@ -31,44 +36,78 @@ static int plugin__handle_message_single(struct mosquitto__security_options *opt
|
|
|
|
|
|
|
|
|
|
memset(&event_data, 0, sizeof(event_data));
|
|
|
|
|
event_data.client = context;
|
|
|
|
|
event_data.topic = stored->data.topic;
|
|
|
|
|
event_data.payloadlen = stored->data.payloadlen;
|
|
|
|
|
event_data.payload = stored->data.payload;
|
|
|
|
|
event_data.qos = stored->data.qos;
|
|
|
|
|
event_data.retain = stored->data.retain;
|
|
|
|
|
event_data.properties = stored->data.properties;
|
|
|
|
|
|
|
|
|
|
DL_FOREACH(opts->plugin_callbacks.message, cb_base){
|
|
|
|
|
rc = cb_base->cb(MOSQ_EVT_MESSAGE, &event_data, cb_base->userdata);
|
|
|
|
|
event_data.topic = stored->topic;
|
|
|
|
|
event_data.payloadlen = stored->payloadlen;
|
|
|
|
|
event_data.payload = stored->payload;
|
|
|
|
|
event_data.qos = stored->qos;
|
|
|
|
|
event_data.retain = stored->retain;
|
|
|
|
|
event_data.properties = stored->properties;
|
|
|
|
|
|
|
|
|
|
DL_FOREACH(callbacks, cb_base){
|
|
|
|
|
rc = cb_base->cb(ev_type, &event_data, cb_base->userdata);
|
|
|
|
|
if(rc != MOSQ_ERR_SUCCESS){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(stored->topic != event_data.topic){
|
|
|
|
|
if(to_free->topic) mosquitto__FREE(stored->topic);
|
|
|
|
|
stored->topic = event_data.topic;
|
|
|
|
|
to_free->topic = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(stored->payload != event_data.payload){
|
|
|
|
|
if(to_free->payload) mosquitto__FREE(stored->payload);
|
|
|
|
|
stored->payload = event_data.payload;
|
|
|
|
|
stored->payloadlen = event_data.payloadlen;
|
|
|
|
|
to_free->payload = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(stored->properties != event_data.properties){
|
|
|
|
|
if(to_free->properties) mosquitto_property_free_all(&stored->properties);
|
|
|
|
|
stored->properties = event_data.properties;
|
|
|
|
|
to_free->properties = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stored->retain = event_data.retain;
|
|
|
|
|
if(ev_type == MOSQ_EVT_MESSAGE_READ){
|
|
|
|
|
stored->qos = event_data.qos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stored->data.topic = event_data.topic;
|
|
|
|
|
if(stored->data.payload != event_data.payload){
|
|
|
|
|
mosquitto__FREE(stored->data.payload);
|
|
|
|
|
stored->data.payload = event_data.payload;
|
|
|
|
|
stored->data.payloadlen = event_data.payloadlen;
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int plugin__handle_message_read(struct mosquitto *context, struct mosquitto_base_msg *stored)
|
|
|
|
|
{
|
|
|
|
|
int rc = MOSQ_ERR_SUCCESS;
|
|
|
|
|
struct should_free to_free = {false, false, false}; /* in msg_read, original data will be freed later */
|
|
|
|
|
|
|
|
|
|
/* Global plugins */
|
|
|
|
|
rc = plugin__handle_message_single(db.config->security_options.plugin_callbacks.message_read,
|
|
|
|
|
MOSQ_EVT_MESSAGE_READ, &to_free, context, stored);
|
|
|
|
|
if(rc) return rc;
|
|
|
|
|
|
|
|
|
|
if(db.config->per_listener_settings && context->listener){
|
|
|
|
|
rc = plugin__handle_message_single(context->listener->security_options->plugin_callbacks.message_read,
|
|
|
|
|
MOSQ_EVT_MESSAGE_READ, &to_free, context, stored);
|
|
|
|
|
}
|
|
|
|
|
stored->data.retain = event_data.retain;
|
|
|
|
|
stored->data.properties = event_data.properties;
|
|
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int plugin__handle_message(struct mosquitto *context, struct mosquitto__base_msg *stored)
|
|
|
|
|
int plugin__handle_message_write(struct mosquitto *context, struct mosquitto_base_msg *stored)
|
|
|
|
|
{
|
|
|
|
|
int rc = MOSQ_ERR_SUCCESS;
|
|
|
|
|
struct should_free to_free = {true, true, true}; /* in msg_write, original data should be freed */
|
|
|
|
|
|
|
|
|
|
/* Global plugins */
|
|
|
|
|
rc = plugin__handle_message_single(&db.config->security_options,
|
|
|
|
|
context, stored);
|
|
|
|
|
rc = plugin__handle_message_single(db.config->security_options.plugin_callbacks.message_write,
|
|
|
|
|
MOSQ_EVT_MESSAGE_WRITE, &to_free, context, stored);
|
|
|
|
|
if(rc) return rc;
|
|
|
|
|
|
|
|
|
|
if(db.config->per_listener_settings && context->listener){
|
|
|
|
|
rc = plugin__handle_message_single(context->listener->security_options,
|
|
|
|
|
context, stored);
|
|
|
|
|
rc = plugin__handle_message_single(context->listener->security_options->plugin_callbacks.message_write,
|
|
|
|
|
MOSQ_EVT_MESSAGE_WRITE, &to_free, context, stored);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|