Coverage Report

Created: 2023-06-07 06:10

/src/mosquitto/plugins/dynamic-security/default_acl.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright (c) 2020-2021 Roger Light <roger@atchoo.org>
3
4
All rights reserved. This program and the accompanying materials
5
are made available under the terms of the Eclipse Public License 2.0
6
and Eclipse Distribution License v1.0 which accompany this distribution.
7
8
The Eclipse Public License is available at
9
   https://www.eclipse.org/legal/epl-2.0/
10
and the Eclipse Distribution License is available at
11
  http://www.eclipse.org/org/documents/edl-v10.php.
12
13
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
14
15
Contributors:
16
   Roger Light - initial implementation and documentation.
17
*/
18
19
#include "config.h"
20
21
#include <cjson/cJSON.h>
22
#include <errno.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <sys/stat.h>
27
28
#include "json_help.h"
29
#include "mosquitto.h"
30
#include "mosquitto_broker.h"
31
#include "mosquitto_plugin.h"
32
#include "mqtt_protocol.h"
33
34
#include "dynamic_security.h"
35
36
int dynsec__process_set_default_acl_access(struct dynsec__data *data, struct mosquitto_control_cmd *cmd, struct mosquitto *context)
37
0
{
38
0
  cJSON *j_actions, *j_action;
39
0
  bool allow;
40
0
  const char *admin_clientid, *admin_username;
41
0
  const char *acltype;
42
43
0
  j_actions = cJSON_GetObjectItem(cmd->j_command, "acls");
44
0
  if(j_actions == NULL || !cJSON_IsArray(j_actions)){
45
0
    mosquitto_control_command_reply(cmd, "Missing/invalid actions array");
46
0
    return MOSQ_ERR_INVAL;
47
0
  }
48
49
0
  admin_clientid = mosquitto_client_id(context);
50
0
  admin_username = mosquitto_client_username(context);
51
52
0
  cJSON_ArrayForEach(j_action, j_actions){
53
0
    if(json_get_string(j_action, "acltype", &acltype, false) == MOSQ_ERR_SUCCESS
54
0
        && json_get_bool(j_action, "allow", &allow, false, false) == MOSQ_ERR_SUCCESS){
55
56
0
      if(!strcasecmp(acltype, ACL_TYPE_PUB_C_SEND)){
57
0
        data->default_access.publish_c_send = allow;
58
0
      }else if(!strcasecmp(acltype, ACL_TYPE_PUB_C_RECV)){
59
0
        data->default_access.publish_c_recv = allow;
60
0
      }else if(!strcasecmp(acltype, ACL_TYPE_SUB_GENERIC)){
61
0
        data->default_access.subscribe = allow;
62
0
      }else if(!strcasecmp(acltype, ACL_TYPE_UNSUB_GENERIC)){
63
0
        data->default_access.unsubscribe = allow;
64
0
      }
65
0
      mosquitto_log_printf(MOSQ_LOG_INFO, "dynsec: %s/%s | setDefaultACLAccess | acltype=%s | allow=%s",
66
0
          admin_clientid, admin_username, acltype, allow?"true":"false");
67
0
    }
68
0
  }
69
70
0
  dynsec__config_batch_save(data);
71
0
  mosquitto_control_command_reply(cmd, NULL);
72
0
  return MOSQ_ERR_SUCCESS;
73
0
}
74
75
76
int dynsec__process_get_default_acl_access(struct dynsec__data *data, struct mosquitto_control_cmd *cmd, struct mosquitto *context)
77
0
{
78
0
  cJSON *tree, *jtmp, *j_data, *j_acls, *j_acl;
79
0
  const char *admin_clientid, *admin_username;
80
81
0
  tree = cJSON_CreateObject();
82
0
  if(tree == NULL){
83
0
    mosquitto_control_command_reply(cmd, "Internal error");
84
0
    return MOSQ_ERR_NOMEM;
85
0
  }
86
87
0
  admin_clientid = mosquitto_client_id(context);
88
0
  admin_username = mosquitto_client_username(context);
89
0
  mosquitto_log_printf(MOSQ_LOG_INFO, "dynsec: %s/%s | getDefaultACLAccess",
90
0
      admin_clientid, admin_username);
91
92
0
  if(cJSON_AddStringToObject(tree, "command", "getDefaultACLAccess") == NULL
93
0
    || ((j_data = cJSON_AddObjectToObject(tree, "data")) == NULL)
94
95
0
      ){
96
0
    goto internal_error;
97
0
  }
98
99
0
  j_acls = cJSON_AddArrayToObject(j_data, "acls");
100
0
  if(j_acls == NULL){
101
0
    goto internal_error;
102
0
  }
103
104
  /* publishClientSend */
105
0
  j_acl = cJSON_CreateObject();
106
0
  if(j_acl == NULL){
107
0
    goto internal_error;
108
0
  }
109
0
  cJSON_AddItemToArray(j_acls, j_acl);
110
0
  if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_PUB_C_SEND) == NULL
111
0
      || cJSON_AddBoolToObject(j_acl, "allow", data->default_access.publish_c_send) == NULL
112
0
      ){
113
114
0
    goto internal_error;
115
0
  }
116
117
  /* publishClientReceive */
118
0
  j_acl = cJSON_CreateObject();
119
0
  if(j_acl == NULL){
120
0
    goto internal_error;
121
0
  }
122
0
  cJSON_AddItemToArray(j_acls, j_acl);
123
0
  if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_PUB_C_RECV) == NULL
124
0
      || cJSON_AddBoolToObject(j_acl, "allow", data->default_access.publish_c_recv) == NULL
125
0
      ){
126
127
0
    goto internal_error;
128
0
  }
129
130
  /* subscribe */
131
0
  j_acl = cJSON_CreateObject();
132
0
  if(j_acl == NULL){
133
0
    goto internal_error;
134
0
  }
135
0
  cJSON_AddItemToArray(j_acls, j_acl);
136
0
  if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_SUB_GENERIC) == NULL
137
0
      || cJSON_AddBoolToObject(j_acl, "allow", data->default_access.subscribe) == NULL
138
0
      ){
139
140
0
    goto internal_error;
141
0
  }
142
143
  /* unsubscribe */
144
0
  j_acl = cJSON_CreateObject();
145
0
  if(j_acl == NULL){
146
0
    goto internal_error;
147
0
  }
148
0
  cJSON_AddItemToArray(j_acls, j_acl);
149
0
  if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_UNSUB_GENERIC) == NULL
150
0
      || cJSON_AddBoolToObject(j_acl, "allow", data->default_access.unsubscribe) == NULL
151
0
      ){
152
153
0
    goto internal_error;
154
0
  }
155
156
0
  cJSON_AddItemToArray(cmd->j_responses, tree);
157
158
0
  if(cmd->correlation_data){
159
0
    jtmp = cJSON_AddStringToObject(tree, "correlationData", cmd->correlation_data);
160
0
    if(jtmp == NULL){
161
0
      goto internal_error;
162
0
    }
163
0
  }
164
165
0
  return MOSQ_ERR_SUCCESS;
166
167
0
internal_error:
168
0
  cJSON_Delete(tree);
169
0
  mosquitto_control_command_reply(cmd, "Internal error");
170
0
  return MOSQ_ERR_NOMEM;
171
0
}