MOSQ_EVT_ACL_CHECK event is now passed message properties where possible.

Closes #3176.
This commit is contained in:
Roger A. Light
2026-01-12 23:51:02 +00:00
parent f3feafb91a
commit 8ad81a9917
19 changed files with 87 additions and 17 deletions

View File

@@ -227,6 +227,7 @@ void context__send_will(struct mosquitto *ctxt)
ctxt->will->msg.payload,
(uint8_t)ctxt->will->msg.qos,
ctxt->will->msg.retain,
ctxt->will->properties,
MOSQ_ACL_WRITE) == MOSQ_ERR_SUCCESS){
/* Unexpected disconnect, queue the client will. */

View File

@@ -1321,7 +1321,8 @@ static void db__client_messages_check_acl(struct mosquitto *context, struct mosq
}
if(mosquitto_acl_check(context, base_msg->data.topic,
base_msg->data.payloadlen, base_msg->data.payload,
base_msg->data.qos, base_msg->data.retain, access) != MOSQ_ERR_SUCCESS){
base_msg->data.qos, base_msg->data.retain,
base_msg->data.properties, access) != MOSQ_ERR_SUCCESS){
DL_DELETE((*head), client_msg);
decrement_stats_fn(msg_data, client_msg);

View File

@@ -357,7 +357,10 @@ int handle__publish(struct mosquitto *context)
}
/* Check for topic access */
rc = mosquitto_acl_check(context, base_msg->data.topic, base_msg->data.payloadlen, base_msg->data.payload, base_msg->data.qos, base_msg->data.retain, MOSQ_ACL_WRITE);
rc = mosquitto_acl_check(context,
base_msg->data.topic, base_msg->data.payloadlen, base_msg->data.payload,
base_msg->data.qos, base_msg->data.retain, base_msg->data.properties,
MOSQ_ACL_WRITE);
if(rc == MOSQ_ERR_ACL_DENIED){
log__printf(NULL, MOSQ_LOG_DEBUG,
"Denied PUBLISH from %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))",

View File

@@ -187,7 +187,7 @@ int handle__subscribe(struct mosquitto *context)
}
allowed = true;
rc2 = mosquitto_acl_check(context, sub.topic_filter, 0, NULL, qos, false, MOSQ_ACL_SUBSCRIBE);
rc2 = mosquitto_acl_check(context, sub.topic_filter, 0, NULL, qos, false, properties, MOSQ_ACL_SUBSCRIBE);
switch(rc2){
case MOSQ_ERR_SUCCESS:
break;

View File

@@ -120,7 +120,7 @@ int handle__unsubscribe(struct mosquitto *context)
/* ACL check */
allowed = true;
rc = mosquitto_acl_check(context, sub.topic_filter, 0, NULL, 0, false, MOSQ_ACL_UNSUBSCRIBE);
rc = mosquitto_acl_check(context, sub.topic_filter, 0, NULL, 0, false, properties, MOSQ_ACL_UNSUBSCRIBE);
switch(rc){
case MOSQ_ERR_SUCCESS:
break;

View File

@@ -357,7 +357,7 @@ static int check_access(struct mosquitto__listener *listener, struct MHD_Connect
/* Authentication */
auth_rc = mosquitto_basic_auth(&context);
if(auth_rc == MOSQ_ERR_SUCCESS){
acl_rc = mosquitto_acl_check(&context, url, 0, NULL, 0, false, MOSQ_ACL_READ);
acl_rc = mosquitto_acl_check(&context, url, 0, NULL, 0, false, NULL, MOSQ_ACL_READ);
}
MHD_free(context.username);
MHD_free(context.password);

View File

@@ -911,7 +911,7 @@ int config__plugin_add_secopt(mosquitto_plugin_id_t *plugin, struct mosquitto__s
int mosquitto_security_init(bool reload);
int mosquitto_security_cleanup(bool reload);
int mosquitto_acl_check(struct mosquitto *context, const char *topic, uint32_t payloadlen, void *payload, uint8_t qos, bool retain, int access);
int mosquitto_acl_check(struct mosquitto *context, const char *topic, uint32_t payloadlen, void *payload, uint8_t qos, bool retain, mosquitto_property *properties, int access);
int mosquitto_basic_auth(struct mosquitto *context);
int mosquitto_psk_key_get(struct mosquitto *context, const char *hint, const char *identity, char *key, int max_key_len);

View File

@@ -102,7 +102,7 @@ static int acl__check_dollar(const char *topic, int access)
}
static int plugin__acl_check(struct mosquitto__security_options *opts, struct mosquitto *context, const char *topic, uint32_t payloadlen, void *payload, uint8_t qos, bool retain, int access)
static int plugin__acl_check(struct mosquitto__security_options *opts, struct mosquitto *context, const char *topic, uint32_t payloadlen, void *payload, uint8_t qos, bool retain, mosquitto_property *properties, int access)
{
int rc = MOSQ_ERR_PLUGIN_DEFER;
struct mosquitto_acl_msg msg;
@@ -127,7 +127,7 @@ static int plugin__acl_check(struct mosquitto__security_options *opts, struct mo
event_data.payload = payload;
event_data.qos = qos;
event_data.retain = retain;
event_data.properties = NULL;
event_data.properties = properties;
rc = cb_base->cb(MOSQ_EVT_ACL_CHECK, &event_data, cb_base->userdata);
if(rc != MOSQ_ERR_PLUGIN_DEFER && rc != MOSQ_ERR_PLUGIN_IGNORE){
return rc;
@@ -138,7 +138,7 @@ static int plugin__acl_check(struct mosquitto__security_options *opts, struct mo
}
int mosquitto_acl_check(struct mosquitto *context, const char *topic, uint32_t payloadlen, void *payload, uint8_t qos, bool retain, int access)
int mosquitto_acl_check(struct mosquitto *context, const char *topic, uint32_t payloadlen, void *payload, uint8_t qos, bool retain, mosquitto_property *properties, int access)
{
int rc;
int rc_final;
@@ -164,7 +164,7 @@ int mosquitto_acl_check(struct mosquitto *context, const char *topic, uint32_t p
* If per listener_settings is false, these are global and listener plugins. */
if(db.config->security_options.plugin_callbacks.acl_check){
rc = plugin__acl_check(&db.config->security_options, context, topic, payloadlen,
payload, qos, retain, access);
payload, qos, retain, properties, access);
if(rc == MOSQ_ERR_PLUGIN_IGNORE){
/* Do nothing, this is as if the plugin doesn't exist */
@@ -179,7 +179,7 @@ int mosquitto_acl_check(struct mosquitto *context, const char *topic, uint32_t p
if(context->listener){
if(context->listener->security_options->plugin_callbacks.acl_check){
rc = plugin__acl_check(context->listener->security_options, context, topic, payloadlen,
payload, qos, retain, access);
payload, qos, retain, properties, access);
if(rc == MOSQ_ERR_PLUGIN_IGNORE){
/* Do nothing, this is as if the plugin doesn't exist */

View File

@@ -402,6 +402,7 @@ static void check_subscription_acls(struct mosquitto *context)
NULL,
0, /* FIXME */
false,
NULL,
MOSQ_ACL_SUBSCRIBE);
if(rc != MOSQ_ERR_SUCCESS){

View File

@@ -237,7 +237,7 @@ static int retain__process(struct mosquitto__retainhier *branch, struct mosquitt
retained = branch->retained;
rc = mosquitto_acl_check(context, retained->data.topic, retained->data.payloadlen, retained->data.payload,
retained->data.qos, retained->data.retain, MOSQ_ACL_READ);
retained->data.qos, retained->data.retain, retained->data.properties, MOSQ_ACL_READ);
if(rc == MOSQ_ERR_ACL_DENIED){
return MOSQ_ERR_SUCCESS;
}else if(rc != MOSQ_ERR_SUCCESS){
@@ -254,7 +254,7 @@ static int retain__process(struct mosquitto__retainhier *branch, struct mosquitt
retain_ctxt.listener = retained->source_listener;
rc = mosquitto_acl_check(&retain_ctxt, retained->data.topic, retained->data.payloadlen, retained->data.payload,
retained->data.qos, retained->data.retain, MOSQ_ACL_WRITE);
retained->data.qos, retained->data.retain, retained->data.properties, MOSQ_ACL_WRITE);
if(rc == MOSQ_ERR_ACL_DENIED){
return MOSQ_ERR_SUCCESS;
}else if(rc != MOSQ_ERR_SUCCESS){

View File

@@ -73,7 +73,7 @@ static int subs__send(struct mosquitto__subleaf *leaf, const char *topic, uint8_
int rc2;
/* Check for ACL topic access. */
rc2 = mosquitto_acl_check(leaf->context, topic, stored->data.payloadlen, stored->data.payload, stored->data.qos, stored->data.retain, MOSQ_ACL_READ);
rc2 = mosquitto_acl_check(leaf->context, topic, stored->data.payloadlen, stored->data.payload, stored->data.qos, stored->data.retain, stored->data.properties, MOSQ_ACL_READ);
if(rc2 == MOSQ_ERR_ACL_DENIED){
return MOSQ_ERR_SUCCESS;
}else if(rc2 == MOSQ_ERR_SUCCESS){