Skip to content

Commit

Permalink
Dynsec: Don't allow duplicate c/g/r when loading config
Browse files Browse the repository at this point in the history
  • Loading branch information
ralight committed Aug 16, 2023
1 parent 8bc0475 commit b76c3c7
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 23 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Broker:
- Fix any possible case where a json string might be incorrectly loaded. This
could have caused a crash if a textname or textdescription field of a role was
not a string, when loading the dynsec config from file only.
- Dynsec plugin will not allow duplicate clients/groups/roles when loading
config from file, which matches the behaviour for when creating them.

Client library:
- Use CLOCK_BOOTTIME when available, to keep track of time. This solves the
Expand Down
18 changes: 12 additions & 6 deletions plugins/dynamic-security/clients.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,24 @@ int dynsec_clients__config_load(cJSON *tree)

cJSON_ArrayForEach(j_client, j_clients){
if(cJSON_IsObject(j_client) == true){
client = mosquitto_calloc(1, sizeof(struct dynsec__client));
if(client == NULL){
return MOSQ_ERR_NOMEM;
}

/* Username */
char *username;
json_get_string(j_client, "username", &username, false);
if(!username){
mosquitto_free(client);
continue;
}

client = dynsec_clients__find(username);
if(client){
continue;
}

client = mosquitto_calloc(1, sizeof(struct dynsec__client));
if(client == NULL){
return MOSQ_ERR_NOMEM;
}


client->username = mosquitto_strdup(username);
if(client->username == NULL){
mosquitto_free(client);
Expand Down
14 changes: 9 additions & 5 deletions plugins/dynamic-security/groups.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,20 @@ int dynsec_groups__config_load(cJSON *tree)

cJSON_ArrayForEach(j_group, j_groups){
if(cJSON_IsObject(j_group) == true){
/* Group name */
if(json_get_string(j_group, "groupname", &groupname, false) != MOSQ_ERR_SUCCESS){
continue;
}
group = dynsec_groups__find(groupname);
if(group){
continue;
}

group = mosquitto_calloc(1, sizeof(struct dynsec__group));
if(group == NULL){
return MOSQ_ERR_NOMEM;
}

/* Group name */
if(json_get_string(j_group, "groupname", &groupname, false) != MOSQ_ERR_SUCCESS){
mosquitto_free(group);
continue;
}
group->groupname = strdup(groupname);
if(group->groupname == NULL){
mosquitto_free(group);
Expand Down
33 changes: 21 additions & 12 deletions plugins/dynamic-security/roles.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,19 @@ static int dynsec_roles__acl_load(cJSON *j_acls, const char *key, struct dynsec_

cJSON_ArrayForEach(j_acl, j_acls){
char *acltype;
char *topic;

json_get_string(j_acl, "acltype", &acltype, false);
if(!acltype || strcasecmp(acltype, key) != 0){
json_get_string(j_acl, "topic", &topic, false);

if(!acltype || strcasecmp(acltype, key) != 0 || !topic){
continue;
}
HASH_FIND(hh, *acllist, topic, strlen(topic), acl);
if(acl){
continue;
}

acl = mosquitto_calloc(1, sizeof(struct dynsec__acl));
if(acl == NULL){
return 1;
Expand All @@ -237,11 +246,7 @@ static int dynsec_roles__acl_load(cJSON *j_acls, const char *key, struct dynsec_
acl->allow = allow;
}

char *topic;
if(json_get_string(j_acl, "topic", &topic, false) == MOSQ_ERR_SUCCESS){
acl->topic = mosquitto_strdup(topic);
}

acl->topic = mosquitto_strdup(topic);
if(acl->topic == NULL){
mosquitto_free(acl);
continue;
Expand Down Expand Up @@ -270,17 +275,21 @@ int dynsec_roles__config_load(cJSON *tree)

cJSON_ArrayForEach(j_role, j_roles){
if(cJSON_IsObject(j_role) == true){
role = mosquitto_calloc(1, sizeof(struct dynsec__role));
if(role == NULL){
return MOSQ_ERR_NOMEM;
}

/* Role name */
char *rolename;
if(json_get_string(j_role, "rolename", &rolename, false) != MOSQ_ERR_SUCCESS){
mosquitto_free(role);
continue;
}
role = dynsec_roles__find(rolename);
if(role){
continue;
}

role = mosquitto_calloc(1, sizeof(struct dynsec__role));
if(role == NULL){
return MOSQ_ERR_NOMEM;
}

role->rolename = mosquitto_strdup(rolename);
if(role->rolename == NULL){
mosquitto_free(role);
Expand Down

0 comments on commit b76c3c7

Please sign in to comment.