From 8795f063d4e8959f2fb6d0a79cf1fe8b8c2051d9 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 11 Aug 2017 22:15:37 +0100 Subject: [PATCH] Add ability to deny access to SUBSCRIBE messages. This is as well as the current read/write accesses. Currently for auth plugins only. --- ChangeLog.txt | 2 ++ src/handle_subscribe.c | 16 +--------------- src/mosquitto_plugin.h | 14 +++++++++++++- src/security.c | 3 +++ src/security_default.c | 1 + 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 851544f6..e60e5462 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -2,6 +2,8 @@ ============== Broker: +- Add ability to deny access to SUBSCRIBE messages as well as the current + read/write accesses. Currently for auth plugins only. - Reduce calls to malloc through the use of UHPA. - Outgoing messages with QoS>1 are no longer retried after a timeout period. Messages will be retried when a client reconnects. This change in behaviour diff --git a/src/handle_subscribe.c b/src/handle_subscribe.c index f57b89a2..52cfa2b7 100644 --- a/src/handle_subscribe.c +++ b/src/handle_subscribe.c @@ -110,21 +110,8 @@ int handle__subscribe(struct mosquitto_db *db, struct mosquitto *context) } log__printf(NULL, MOSQ_LOG_DEBUG, "\t%s (QoS %d)", sub, qos); -#if 0 - /* FIXME - * This section has been disabled temporarily. mosquitto_acl_check - * calls mosquitto_topic_matches_sub, which can't cope with - * checking subscriptions that have wildcards against ACLs that - * have wildcards. Bug #1374291 is related. - * - * It's a very difficult problem when an ACL looks like foo/+/bar - * and a subscription request to foo/# is made. - * - * This should be changed to using MOSQ_ACL_SUBSCRIPTION in the - * future anyway. - */ if(context->protocol == mosq_p_mqtt311){ - rc = mosquitto_acl_check(db, context, sub, MOSQ_ACL_READ); + rc = mosquitto_acl_check(db, context, sub, MOSQ_ACL_SUBSCRIBE); switch(rc){ case MOSQ_ERR_SUCCESS: break; @@ -136,7 +123,6 @@ int handle__subscribe(struct mosquitto_db *db, struct mosquitto *context) return rc; } } -#endif if(qos != 0x80){ rc2 = sub__add(db, context, sub, qos, &db->subs); diff --git a/src/mosquitto_plugin.h b/src/mosquitto_plugin.h index 7dee2246..bd80639f 100644 --- a/src/mosquitto_plugin.h +++ b/src/mosquitto_plugin.h @@ -199,7 +199,19 @@ int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *opts, * Function: mosquitto_auth_acl_check * * Called by the broker when topic access must be checked. access will be one - * of MOSQ_ACL_READ (for subscriptions) or MOSQ_ACL_WRITE (for publish). + * of: + * MOSQ_ACL_SUBSCRIBE when a client is asking to subscribe to a topic string. + * This differs from MOSQ_ACL_READ in that it allows you to + * deny access to topic strings rather than by pattern. For + * example, you may use MOSQ_ACL_SUBSCRIBE to deny + * subscriptions to '#', but allow all topics in + * MOSQ_ACL_READ. This allows clients to subscribe to any + * topic they want, but not discover what topics are in use + * on the server. + * MOSQ_ACL_READ when a message is about to be sent to a client (i.e. whether + * it can read that topic or not). + * MOSQ_ACL_WRITE when a message has been received from a client (i.e. whether + * it can write to that topic or not). * * Return: * MOSQ_ERR_SUCCESS if access was granted. diff --git a/src/security.c b/src/security.c index f4a02572..1f4ab01d 100644 --- a/src/security.c +++ b/src/security.c @@ -392,6 +392,9 @@ int mosquitto_acl_check(struct mosquitto_db *db, struct mosquitto *context, cons if(db->auth_plugins[i].version == 3){ rc = db->auth_plugins[i].acl_check_v3(db->auth_plugins[i].user_data, access, context, &msg); }else if(db->auth_plugins[i].version == 2){ + if(access == MOSQ_ACL_SUBSCRIBE){ + return MOSQ_ERR_SUCCESS; + } rc = db->auth_plugins[i].acl_check_v2(db->auth_plugins[i].user_data, context->id, username, topic, access); }else{ rc = MOSQ_ERR_INVAL; diff --git a/src/security_default.c b/src/security_default.c index 29183deb..af940562 100644 --- a/src/security_default.c +++ b/src/security_default.c @@ -238,6 +238,7 @@ int mosquitto_acl_check_default(struct mosquitto_db *db, struct mosquitto *conte if(!db || !context || !topic) return MOSQ_ERR_INVAL; if(!db->acl_list && !db->acl_patterns) return MOSQ_ERR_PLUGIN_DEFER; if(context->bridge) return MOSQ_ERR_SUCCESS; + if(access == MOSQ_ACL_SUBSCRIBE) return MOSQ_ERR_SUCCESS; /* FIXME - implement ACL subscription strings. */ if(!context->acl_list && !db->acl_patterns) return MOSQ_ERR_ACL_DENIED; if(context->acl_list){