Coverage Report

Created: 2025-10-24 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mosquitto/plugins/dynamic-security/default_acl.c
Line
Count
Source
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 "dynamic_security.h"
29
#include "json_help.h"
30
31
32
int dynsec__process_set_default_acl_access(struct dynsec__data *data, struct mosquitto_control_cmd *cmd)
33
0
{
34
0
  cJSON *j_actions, *j_action;
35
0
  bool allow;
36
0
  const char *admin_clientid, *admin_username;
37
0
  const char *acltype;
38
39
0
  j_actions = cJSON_GetObjectItem(cmd->j_command, "acls");
40
0
  if(j_actions == NULL || !cJSON_IsArray(j_actions)){
41
0
    mosquitto_control_command_reply(cmd, "Missing/invalid actions array");
42
0
    return MOSQ_ERR_INVAL;
43
0
  }
44
45
0
  admin_clientid = mosquitto_client_id(cmd->client);
46
0
  admin_username = mosquitto_client_username(cmd->client);
47
48
0
  cJSON_ArrayForEach(j_action, j_actions){
49
0
    if(json_get_string(j_action, "acltype", &acltype, false) == MOSQ_ERR_SUCCESS
50
0
        && json_get_bool(j_action, "allow", &allow, false, false) == MOSQ_ERR_SUCCESS){
51
52
0
      if(!strcasecmp(acltype, ACL_TYPE_PUB_C_SEND)){
53
0
        data->default_access.publish_c_send = allow;
54
0
      }else if(!strcasecmp(acltype, ACL_TYPE_PUB_C_RECV)){
55
0
        data->default_access.publish_c_recv = allow;
56
0
      }else if(!strcasecmp(acltype, ACL_TYPE_SUB_GENERIC)){
57
0
        data->default_access.subscribe = allow;
58
0
      }else if(!strcasecmp(acltype, ACL_TYPE_UNSUB_GENERIC)){
59
0
        data->default_access.unsubscribe = allow;
60
0
      }
61
0
      mosquitto_log_printf(MOSQ_LOG_INFO, "dynsec: %s/%s | setDefaultACLAccess | acltype=%s | allow=%s",
62
0
          admin_clientid, admin_username, acltype, allow?"true":"false");
63
0
    }
64
0
  }
65
66
0
  dynsec__config_batch_save(data);
67
0
  mosquitto_control_command_reply(cmd, NULL);
68
0
  return MOSQ_ERR_SUCCESS;
69
0
}
70
71
72
int dynsec__process_get_default_acl_access(struct dynsec__data *data, struct mosquitto_control_cmd *cmd)
73
0
{
74
0
  cJSON *tree, *jtmp, *j_data, *j_acls, *j_acl;
75
0
  const char *admin_clientid, *admin_username;
76
77
0
  tree = cJSON_CreateObject();
78
0
  if(tree == NULL){
79
0
    mosquitto_control_command_reply(cmd, "Internal error");
80
0
    return MOSQ_ERR_NOMEM;
81
0
  }
82
83
0
  admin_clientid = mosquitto_client_id(cmd->client);
84
0
  admin_username = mosquitto_client_username(cmd->client);
85
0
  mosquitto_log_printf(MOSQ_LOG_INFO, "dynsec: %s/%s | getDefaultACLAccess",
86
0
      admin_clientid, admin_username);
87
88
0
  if(cJSON_AddStringToObject(tree, "command", "getDefaultACLAccess") == NULL
89
0
      || ((j_data = cJSON_AddObjectToObject(tree, "data")) == NULL)
90
91
0
      ){
92
0
    goto internal_error;
93
0
  }
94
95
0
  j_acls = cJSON_AddArrayToObject(j_data, "acls");
96
0
  if(j_acls == NULL){
97
0
    goto internal_error;
98
0
  }
99
100
  /* publishClientSend */
101
0
  j_acl = cJSON_CreateObject();
102
0
  if(j_acl == NULL){
103
0
    goto internal_error;
104
0
  }
105
0
  cJSON_AddItemToArray(j_acls, j_acl);
106
0
  if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_PUB_C_SEND) == NULL
107
0
      || cJSON_AddBoolToObject(j_acl, "allow", data->default_access.publish_c_send) == NULL
108
0
      ){
109
110
0
    goto internal_error;
111
0
  }
112
113
  /* publishClientReceive */
114
0
  j_acl = cJSON_CreateObject();
115
0
  if(j_acl == NULL){
116
0
    goto internal_error;
117
0
  }
118
0
  cJSON_AddItemToArray(j_acls, j_acl);
119
0
  if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_PUB_C_RECV) == NULL
120
0
      || cJSON_AddBoolToObject(j_acl, "allow", data->default_access.publish_c_recv) == NULL
121
0
      ){
122
123
0
    goto internal_error;
124
0
  }
125
126
  /* subscribe */
127
0
  j_acl = cJSON_CreateObject();
128
0
  if(j_acl == NULL){
129
0
    goto internal_error;
130
0
  }
131
0
  cJSON_AddItemToArray(j_acls, j_acl);
132
0
  if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_SUB_GENERIC) == NULL
133
0
      || cJSON_AddBoolToObject(j_acl, "allow", data->default_access.subscribe) == NULL
134
0
      ){
135
136
0
    goto internal_error;
137
0
  }
138
139
  /* unsubscribe */
140
0
  j_acl = cJSON_CreateObject();
141
0
  if(j_acl == NULL){
142
0
    goto internal_error;
143
0
  }
144
0
  cJSON_AddItemToArray(j_acls, j_acl);
145
0
  if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_UNSUB_GENERIC) == NULL
146
0
      || cJSON_AddBoolToObject(j_acl, "allow", data->default_access.unsubscribe) == NULL
147
0
      ){
148
149
0
    goto internal_error;
150
0
  }
151
152
0
  cJSON_AddItemToArray(cmd->j_responses, tree);
153
154
0
  if(cmd->correlation_data){
155
0
    jtmp = cJSON_AddStringToObject(tree, "correlationData", cmd->correlation_data);
156
0
    if(jtmp == NULL){
157
0
      goto internal_error;
158
0
    }
159
0
  }
160
161
0
  return MOSQ_ERR_SUCCESS;
162
163
0
internal_error:
164
0
  cJSON_Delete(tree);
165
0
  mosquitto_control_command_reply(cmd, "Internal error");
166
0
  return MOSQ_ERR_NOMEM;
167
0
}