Dynsec: Don't allow duplicate c/g/r when loading config

This commit is contained in:
Roger A. Light 2023-06-13 17:07:43 +01:00
parent 8bc047511a
commit b76c3c7820
4 changed files with 45 additions and 24 deletions

View File

@ -28,6 +28,8 @@ Broker:
- Fix any possible case where a json string might be incorrectly loaded. This - 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 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. 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: Client library:
- Use CLOCK_BOOTTIME when available, to keep track of time. This solves the - Use CLOCK_BOOTTIME when available, to keep track of time. This solves the

View File

@ -124,18 +124,24 @@ int dynsec_clients__config_load(cJSON *tree)
cJSON_ArrayForEach(j_client, j_clients){ cJSON_ArrayForEach(j_client, j_clients){
if(cJSON_IsObject(j_client) == true){ if(cJSON_IsObject(j_client) == true){
/* Username */
char *username;
json_get_string(j_client, "username", &username, false);
if(!username){
continue;
}
client = dynsec_clients__find(username);
if(client){
continue;
}
client = mosquitto_calloc(1, sizeof(struct dynsec__client)); client = mosquitto_calloc(1, sizeof(struct dynsec__client));
if(client == NULL){ if(client == NULL){
return MOSQ_ERR_NOMEM; return MOSQ_ERR_NOMEM;
} }
/* Username */
char *username;
json_get_string(j_client, "username", &username, false);
if(!username){
mosquitto_free(client);
continue;
}
client->username = mosquitto_strdup(username); client->username = mosquitto_strdup(username);
if(client->username == NULL){ if(client->username == NULL){
mosquitto_free(client); mosquitto_free(client);

View File

@ -214,16 +214,20 @@ int dynsec_groups__config_load(cJSON *tree)
cJSON_ArrayForEach(j_group, j_groups){ cJSON_ArrayForEach(j_group, j_groups){
if(cJSON_IsObject(j_group) == true){ 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)); group = mosquitto_calloc(1, sizeof(struct dynsec__group));
if(group == NULL){ if(group == NULL){
return MOSQ_ERR_NOMEM; 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); group->groupname = strdup(groupname);
if(group->groupname == NULL){ if(group->groupname == NULL){
mosquitto_free(group); mosquitto_free(group);

View File

@ -220,10 +220,19 @@ static int dynsec_roles__acl_load(cJSON *j_acls, const char *key, struct dynsec_
cJSON_ArrayForEach(j_acl, j_acls){ cJSON_ArrayForEach(j_acl, j_acls){
char *acltype; char *acltype;
char *topic;
json_get_string(j_acl, "acltype", &acltype, false); 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; continue;
} }
HASH_FIND(hh, *acllist, topic, strlen(topic), acl);
if(acl){
continue;
}
acl = mosquitto_calloc(1, sizeof(struct dynsec__acl)); acl = mosquitto_calloc(1, sizeof(struct dynsec__acl));
if(acl == NULL){ if(acl == NULL){
return 1; return 1;
@ -237,11 +246,7 @@ static int dynsec_roles__acl_load(cJSON *j_acls, const char *key, struct dynsec_
acl->allow = allow; 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){ if(acl->topic == NULL){
mosquitto_free(acl); mosquitto_free(acl);
continue; continue;
@ -270,17 +275,21 @@ int dynsec_roles__config_load(cJSON *tree)
cJSON_ArrayForEach(j_role, j_roles){ cJSON_ArrayForEach(j_role, j_roles){
if(cJSON_IsObject(j_role) == true){ if(cJSON_IsObject(j_role) == true){
/* Role name */
char *rolename;
if(json_get_string(j_role, "rolename", &rolename, false) != MOSQ_ERR_SUCCESS){
continue;
}
role = dynsec_roles__find(rolename);
if(role){
continue;
}
role = mosquitto_calloc(1, sizeof(struct dynsec__role)); role = mosquitto_calloc(1, sizeof(struct dynsec__role));
if(role == NULL){ if(role == NULL){
return MOSQ_ERR_NOMEM; 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->rolename = mosquitto_strdup(rolename); role->rolename = mosquitto_strdup(rolename);
if(role->rolename == NULL){ if(role->rolename == NULL){
mosquitto_free(role); mosquitto_free(role);