Fix possible crash when using pattern ACLs.
Crash may occur for ACLs that do not include a %u and clients that connect without a username. Thanks to Karl Palsson.
This commit is contained in:
parent
9ff56eefd0
commit
ab15557931
@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
Broker:
|
Broker:
|
||||||
- Ensure that bridges verify certificates by default when using TLS.
|
- Ensure that bridges verify certificates by default when using TLS.
|
||||||
|
- Fix possible crash when using pattern ACLs that do not include a %u and
|
||||||
|
clients that connect without a username.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Client library:
|
Client library:
|
||||||
- Fix topic matching edge case.
|
- Fix topic matching edge case.
|
||||||
|
@ -164,6 +164,8 @@ struct _mosquitto_acl{
|
|||||||
struct _mosquitto_acl *next;
|
struct _mosquitto_acl *next;
|
||||||
char *topic;
|
char *topic;
|
||||||
int access;
|
int access;
|
||||||
|
int ucount;
|
||||||
|
int ccount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _mosquitto_acl_user{
|
struct _mosquitto_acl_user{
|
||||||
|
@ -165,6 +165,7 @@ int _add_acl_pattern(struct mosquitto_db *db, const char *topic, int access)
|
|||||||
{
|
{
|
||||||
struct _mosquitto_acl *acl, *acl_tail;
|
struct _mosquitto_acl *acl, *acl_tail;
|
||||||
char *local_topic;
|
char *local_topic;
|
||||||
|
char *s;
|
||||||
|
|
||||||
if(!db || !topic) return MOSQ_ERR_INVAL;
|
if(!db || !topic) return MOSQ_ERR_INVAL;
|
||||||
|
|
||||||
@ -179,6 +180,26 @@ int _add_acl_pattern(struct mosquitto_db *db, const char *topic, int access)
|
|||||||
acl->topic = local_topic;
|
acl->topic = local_topic;
|
||||||
acl->next = NULL;
|
acl->next = NULL;
|
||||||
|
|
||||||
|
acl->ccount = 0;
|
||||||
|
s = local_topic;
|
||||||
|
while(s){
|
||||||
|
s = strstr(s, "%c");
|
||||||
|
if(s){
|
||||||
|
acl->ccount++;
|
||||||
|
s+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acl->ccount = 0;
|
||||||
|
s = local_topic;
|
||||||
|
while(s){
|
||||||
|
s = strstr(s, "%u");
|
||||||
|
if(s){
|
||||||
|
acl->ucount++;
|
||||||
|
s+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(db->acl_patterns){
|
if(db->acl_patterns){
|
||||||
acl_tail = db->acl_patterns;
|
acl_tail = db->acl_patterns;
|
||||||
while(acl_tail->next){
|
while(acl_tail->next){
|
||||||
@ -199,7 +220,6 @@ int mosquitto_acl_check_default(struct mosquitto_db *db, struct mosquitto *conte
|
|||||||
bool result;
|
bool result;
|
||||||
int i;
|
int i;
|
||||||
int len, tlen, clen, ulen;
|
int len, tlen, clen, ulen;
|
||||||
int ccount, ucount;
|
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
if(!db || !context || !topic) return MOSQ_ERR_INVAL;
|
if(!db || !context || !topic) return MOSQ_ERR_INVAL;
|
||||||
@ -238,32 +258,17 @@ int mosquitto_acl_check_default(struct mosquitto_db *db, struct mosquitto *conte
|
|||||||
while(acl_root){
|
while(acl_root){
|
||||||
tlen = strlen(acl_root->topic);
|
tlen = strlen(acl_root->topic);
|
||||||
|
|
||||||
ccount = 0;
|
if(acl_root->ucount && !context->username){
|
||||||
s = acl_root->topic;
|
|
||||||
while(s){
|
|
||||||
s = strstr(s, "%c");
|
|
||||||
if(s){
|
|
||||||
ccount++;
|
|
||||||
s+=2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ucount = 0;
|
|
||||||
s = acl_root->topic;
|
|
||||||
while(s){
|
|
||||||
s = strstr(s, "%u");
|
|
||||||
if(s){
|
|
||||||
ucount++;
|
|
||||||
s+=2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ucount && !context->username){
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulen = strlen(context->username);
|
if(context->username){
|
||||||
len = tlen + ccount*(clen-2) + ucount*(ulen-2);
|
ulen = strlen(context->username);
|
||||||
|
len = tlen + acl_root->ccount*(clen-2) + acl_root->ucount*(ulen-2);
|
||||||
|
}else{
|
||||||
|
ulen = 0;
|
||||||
|
len = tlen + acl_root->ccount*(clen-2);
|
||||||
|
}
|
||||||
local_acl = malloc(len+1);
|
local_acl = malloc(len+1);
|
||||||
if(!local_acl) return 1; // FIXME
|
if(!local_acl) return 1; // FIXME
|
||||||
s = local_acl;
|
s = local_acl;
|
||||||
@ -274,7 +279,7 @@ int mosquitto_acl_check_default(struct mosquitto_db *db, struct mosquitto *conte
|
|||||||
strncpy(s, context->id, clen);
|
strncpy(s, context->id, clen);
|
||||||
s+=clen;
|
s+=clen;
|
||||||
continue;
|
continue;
|
||||||
}else if(acl_root->topic[i+1] == 'u'){
|
}else if(context->username && acl_root->topic[i+1] == 'u'){
|
||||||
i++;
|
i++;
|
||||||
strncpy(s, context->username, ulen);
|
strncpy(s, context->username, ulen);
|
||||||
s+=ulen;
|
s+=ulen;
|
||||||
|
Loading…
Reference in New Issue
Block a user