Dynsec: add getAnonymousGroup and getDefaultACLAccess commands

pull/1874/head
Roger A. Light 5 years ago
parent c9cb10a079
commit df30b6c9d4

@ -31,7 +31,9 @@ void dynsec__print_usage(void)
printf(" mosquitto_ctrl dynsec init <new-config-file> <admin-username> <admin-password> [admin-role]\n");
printf("\nGeneral\n-------\n");
printf("Get ACL default access: getDefaultACLAccess\n");
printf("Set ACL default access: setDefaultACLAccess <acltype> allow|deny\n");
printf("Get group for anonymous clients: getAnonymousGroup\n");
printf("Set group for anonymous clients: setAnonymousGroup <groupname>\n");
printf("\nClients\n-------\n");
@ -82,10 +84,16 @@ static void print_list(cJSON *j_response, const char *arrayname, const char *key
cJSON *j_data, *j_array, *j_elem, *j_name;
j_data = cJSON_GetObjectItem(j_response, "data");
if(j_data == NULL) return;
if(j_data == NULL){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
j_array = cJSON_GetObjectItem(j_data, arrayname);
if(j_array == NULL || !cJSON_IsArray(j_array)) return;
if(j_array == NULL || !cJSON_IsArray(j_array)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
cJSON_ArrayForEach(j_elem, j_array){
if(cJSON_IsObject(j_elem)){
@ -107,16 +115,19 @@ static void print_client(cJSON *j_response)
j_data = cJSON_GetObjectItem(j_response, "data");
if(j_data == NULL || !cJSON_IsObject(j_data)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
j_client = cJSON_GetObjectItem(j_data, "client");
if(j_client == NULL || !cJSON_IsObject(j_client)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
jtmp = cJSON_GetObjectItem(j_client, "username");
if(jtmp == NULL || !cJSON_IsString(jtmp)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
printf("Username: %s\n", jtmp->valuestring);
@ -186,16 +197,19 @@ static void print_group(cJSON *j_response)
j_data = cJSON_GetObjectItem(j_response, "data");
if(j_data == NULL || !cJSON_IsObject(j_data)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
j_group = cJSON_GetObjectItem(j_data, "group");
if(j_group == NULL || !cJSON_IsObject(j_group)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
jtmp = cJSON_GetObjectItem(j_group, "groupname");
if(jtmp == NULL || !cJSON_IsString(jtmp)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
printf("Groupname: %s\n", jtmp->valuestring);
@ -248,16 +262,19 @@ static void print_role(cJSON *j_response)
j_data = cJSON_GetObjectItem(j_response, "data");
if(j_data == NULL || !cJSON_IsObject(j_data)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
j_role = cJSON_GetObjectItem(j_data, "role");
if(j_role == NULL || !cJSON_IsObject(j_role)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
jtmp = cJSON_GetObjectItem(j_role, "rolename");
if(jtmp == NULL || !cJSON_IsString(jtmp)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
printf("Rolename: %s\n", jtmp->valuestring);
@ -296,6 +313,61 @@ static void print_role(cJSON *j_response)
}
static void print_anonymous_group(cJSON *j_response)
{
cJSON *j_data, *j_group, *j_groupname;
j_data = cJSON_GetObjectItem(j_response, "data");
if(j_data == NULL || !cJSON_IsObject(j_data)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
j_group = cJSON_GetObjectItem(j_data, "group");
if(j_group == NULL || !cJSON_IsObject(j_group)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
j_groupname = cJSON_GetObjectItem(j_group, "groupname");
if(j_groupname == NULL || !cJSON_IsString(j_groupname)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
printf("%s\n", j_groupname->valuestring);
}
static void print_default_acl_access(cJSON *j_response)
{
cJSON *j_data, *j_acls, *j_acl, *j_acltype, *j_allow;
j_data = cJSON_GetObjectItem(j_response, "data");
if(j_data == NULL || !cJSON_IsObject(j_data)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
j_acls = cJSON_GetObjectItem(j_data, "acls");
if(j_acls == NULL || !cJSON_IsArray(j_acls)){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
cJSON_ArrayForEach(j_acl, j_acls){
j_acltype = cJSON_GetObjectItem(j_acl, "acltype");
j_allow = cJSON_GetObjectItem(j_acl, "allow");
if(j_acltype == NULL || !cJSON_IsString(j_acltype)
|| j_allow == NULL || !cJSON_IsBool(j_allow)
){
fprintf(stderr, "Error: Invalid response from server.\n");
return;
}
printf("%-20s : %s\n", j_acltype->valuestring, cJSON_IsTrue(j_allow)?"allow":"deny");
}
}
static void dynsec__payload_callback(struct mosq_ctrl *ctrl, long payloadlen, const void *payload)
{
cJSON *tree, *j_responses, *j_response, *j_command, *j_error;
@ -343,6 +415,10 @@ static void dynsec__payload_callback(struct mosq_ctrl *ctrl, long payloadlen, co
print_group(j_response);
}else if(!strcasecmp(j_command->valuestring, "getRole")){
print_role(j_response);
}else if(!strcasecmp(j_command->valuestring, "getDefaultACLAccess")){
print_default_acl_access(j_response);
}else if(!strcasecmp(j_command->valuestring, "getAnonymousGroup")){
print_anonymous_group(j_response);
}else{
//fprintf(stderr, "%s: Success\n", j_command->valuestring);
}
@ -356,7 +432,7 @@ static void dynsec__payload_callback(struct mosq_ctrl *ctrl, long payloadlen, co
* #
* ################################################################ */
static int dynsec__default_acl_access(int argc, char *argv[], cJSON *j_command)
static int dynsec__set_default_acl_access(int argc, char *argv[], cJSON *j_command)
{
char *acltype, *access;
cJSON *j_acls, *j_acl;
@ -403,6 +479,17 @@ static int dynsec__default_acl_access(int argc, char *argv[], cJSON *j_command)
return MOSQ_ERR_SUCCESS;
}
static int dynsec__get_default_acl_access(int argc, char *argv[], cJSON *j_command)
{
if(cJSON_AddStringToObject(j_command, "command", "getDefaultACLAccess") == NULL
){
return MOSQ_ERR_NOMEM;
}
return MOSQ_ERR_SUCCESS;
}
/* ################################################################
* #
* # Init
@ -673,7 +760,9 @@ int dynsec__main(int argc, char *argv[], struct mosq_ctrl *ctrl)
cJSON_AddItemToArray(j_commands, j_command);
if(!strcasecmp(argv[0], "setDefaultACLAccess")){
return dynsec__default_acl_access(argc-1, &argv[1], j_command);
return dynsec__set_default_acl_access(argc-1, &argv[1], j_command);
}else if(!strcasecmp(argv[0], "getDefaultACLAccess")){
return dynsec__get_default_acl_access(argc-1, &argv[1], j_command);
}else if(!strcasecmp(argv[0], "createClient")){
return dynsec_client__create(argc-1, &argv[1], j_command);
@ -708,6 +797,8 @@ int dynsec__main(int argc, char *argv[], struct mosq_ctrl *ctrl)
return dynsec_group__add_remove_client(argc-1, &argv[1], j_command, argv[0]);
}else if(!strcasecmp(argv[0], "setAnonymousGroup")){
return dynsec_group__set_anonymous(argc-1, &argv[1], j_command);
}else if(!strcasecmp(argv[0], "getAnonymousGroup")){
return dynsec_group__get_anonymous(argc-1, &argv[1], j_command);
}else if(!strcasecmp(argv[0], "createRole")){
return dynsec_role__create(argc-1, &argv[1], j_command);

@ -62,6 +62,17 @@ int dynsec_group__delete(int argc, char *argv[], cJSON *j_command)
}
}
int dynsec_group__get_anonymous(int argc, char *argv[], cJSON *j_command)
{
if(cJSON_AddStringToObject(j_command, "command", "getAnonymousGroup") == NULL
){
return MOSQ_ERR_NOMEM;
}else{
return MOSQ_ERR_SUCCESS;
}
}
int dynsec_group__set_anonymous(int argc, char *argv[], cJSON *j_command)
{
char *groupname = NULL;

@ -98,6 +98,7 @@ int dynsec_group__delete(int argc, char *argv[], cJSON *j_command);
int dynsec_group__get(int argc, char *argv[], cJSON *j_command);
int dynsec_group__list_all(int argc, char *argv[], cJSON *j_command);
int dynsec_group__set_anonymous(int argc, char *argv[], cJSON *j_command);
int dynsec_group__get_anonymous(int argc, char *argv[], cJSON *j_command);
int dynsec_role__create(int argc, char *argv[], cJSON *j_command);
int dynsec_role__delete(int argc, char *argv[], cJSON *j_command);

@ -27,7 +27,8 @@ subscribe to.
Sets the default access behaviour for the different ACL types, assuming there
are no matching ACLs for a topic.
By default, all ACL types default to deny.
By default, publishClientSend and subscribe default to deny, and
publishClientReceive and unsubscribe default to allow.
Command:
```
@ -37,9 +38,9 @@ Command:
"command": "setDefaultACLAccess",
"acls":[
{ "acltype": "publishClientSend", "allow": false },
{ "acltype": "publishClientReceive", "allow": false },
{ "acltype": "publishClientReceive", "allow": true },
{ "acltype": "subscribe", "allow": false },
{ "acltype": "unsubscribe", "allow": false }
{ "acltype": "unsubscribe", "allow": true }
]
}
]
@ -51,6 +52,26 @@ mosquitto_ctrl example:
mosquitto_ctrl dynsec setDefaultACLAccess subscribe deny
```
### Get default ACL access
Gets the default access behaviour for the different ACL types.
Command:
```
{
"commands":[
{
"command": "getDefaultACLAccess",
}
]
}
```
mosquitto_ctrl example:
```
mosquitto_ctrl dynsec getDefaultACLAccess
```
## Create Client
Command:
@ -432,6 +453,24 @@ mosquitto_ctrl example:
mosquitto_ctrl dynsec setAnonymousGroup groupname
```
## Get Group for Anonymous Clients
Command:
```
{
"commands":[
{
"command": "getAnonymousGroup",
}
]
}
```
mosquitto_ctrl example:
```
mosquitto_ctrl dynsec getAnonymousGroup
```
## Create Role
Command:

@ -204,6 +204,7 @@ int dynsec_groups__process_list(cJSON *j_responses, struct mosquitto *context, c
int dynsec_groups__process_modify(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_remove_client(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_remove_role(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_get_anonymous_group(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_set_anonymous_group(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__remove_client(const char *username, const char *groupname, bool update_config);
struct dynsec__group *dynsec_groups__find(const char *groupname);

@ -1021,3 +1021,50 @@ int dynsec_groups__process_set_anonymous_group(cJSON *j_responses, struct mosqui
dynsec__command_reply(j_responses, context, "setAnonymousGroup", NULL, correlation_data);
return MOSQ_ERR_SUCCESS;
}
int dynsec_groups__process_get_anonymous_group(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data)
{
cJSON *tree, *jtmp, *j_data, *j_group;
tree = cJSON_CreateObject();
if(tree == NULL){
dynsec__command_reply(j_responses, context, "getAnonymousGroup", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
jtmp = cJSON_CreateString("getAnonymousGroup");
if(jtmp == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getAnonymousGroup", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToObject(tree, "command", jtmp);
j_data = cJSON_CreateObject();
if(j_data == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getAnonymousGroup", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToObject(tree, "data", j_data);
j_group = cJSON_CreateObject();
if(j_group == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getAnonymousGroup", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToObject(j_data, "group", j_group);
if(cJSON_AddStringToObject(j_group, "groupname", dynsec_anonymous_group->groupname) == NULL
){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getAnonymousGroup", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToArray(j_responses, tree);
return MOSQ_ERR_SUCCESS;
}

@ -109,7 +109,7 @@ static int dynsec_control_callback(int event, void *event_data, void *userdata)
return MOSQ_ERR_SUCCESS;
}
int dynsec__process_default_acl_access(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data)
int dynsec__process_set_default_acl_access(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data)
{
cJSON *j_actions, *j_action, *j_acltype, *j_allow;
bool allow;
@ -146,6 +146,113 @@ int dynsec__process_default_acl_access(cJSON *j_responses, struct mosquitto *con
}
int dynsec__process_get_default_acl_access(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data)
{
cJSON *tree, *jtmp, *j_data, *j_acls, *j_acl;
tree = cJSON_CreateObject();
if(tree == NULL){
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
jtmp = cJSON_CreateString("getDefaultACLAccess");
if(jtmp == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToObject(tree, "command", jtmp);
j_data = cJSON_CreateObject();
if(j_data == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToObject(tree, "data", j_data);
j_acls = cJSON_AddArrayToObject(j_data, "acls");
if(j_acls == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
/* publishClientSend */
j_acl = cJSON_CreateObject();
if(j_acl == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_PUB_C_SEND) == NULL
|| cJSON_AddBoolToObject(j_acl, "allow", default_access.publish_c_send) == NULL
){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToArray(j_acls, j_acl);
/* publishClientReceive */
j_acl = cJSON_CreateObject();
if(j_acl == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_PUB_C_RECV) == NULL
|| cJSON_AddBoolToObject(j_acl, "allow", default_access.publish_c_recv) == NULL
){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToArray(j_acls, j_acl);
/* subscribe */
j_acl = cJSON_CreateObject();
if(j_acl == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_SUB_GENERIC) == NULL
|| cJSON_AddBoolToObject(j_acl, "allow", default_access.subscribe) == NULL
){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToArray(j_acls, j_acl);
/* unsubscribe */
j_acl = cJSON_CreateObject();
if(j_acl == NULL){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_UNSUB_GENERIC) == NULL
|| cJSON_AddBoolToObject(j_acl, "allow", default_access.unsubscribe) == NULL
){
cJSON_Delete(tree);
dynsec__command_reply(j_responses, context, "getDefaultACLAccess", "Internal error", correlation_data);
return MOSQ_ERR_NOMEM;
}
cJSON_AddItemToArray(j_acls, j_acl);
cJSON_AddItemToArray(j_responses, tree);
return MOSQ_ERR_SUCCESS;
}
int mosquitto_plugin_version(int supported_version_count, const int *supported_versions)
{
int i;
@ -408,7 +515,9 @@ int dynsec__handle_control(cJSON *j_responses, struct mosquitto *context, cJSON
/* Plugin */
if(!strcasecmp(command, "setDefaultACLAccess")){
rc = dynsec__process_default_acl_access(j_responses, context, aiter, correlation_data);
rc = dynsec__process_set_default_acl_access(j_responses, context, aiter, correlation_data);
}else if(!strcasecmp(command, "getDefaultACLAccess")){
rc = dynsec__process_get_default_acl_access(j_responses, context, aiter, correlation_data);
/* Clients */
}else if(!strcasecmp(command, "createClient")){
@ -449,6 +558,8 @@ int dynsec__handle_control(cJSON *j_responses, struct mosquitto *context, cJSON
rc = dynsec_groups__process_remove_role(j_responses, context, aiter, correlation_data);
}else if(!strcasecmp(command, "setAnonymousGroup")){
rc = dynsec_groups__process_set_anonymous_group(j_responses, context, aiter, correlation_data);
}else if(!strcasecmp(command, "getAnonymousGroup")){
rc = dynsec_groups__process_get_anonymous_group(j_responses, context, aiter, correlation_data);
/* Roles */
}else if(!strcasecmp(command, "createRole")){

Loading…
Cancel
Save